Reference: implement peel()
This makes both objects and references peelable via the same interface, simplifying how to get to the wanted type.
This commit is contained in:
		| @@ -28,6 +28,7 @@ The Reference type | ||||
| .. automethod:: pygit2.Reference.delete | ||||
| .. automethod:: pygit2.Reference.rename | ||||
| .. automethod:: pygit2.Reference.resolve | ||||
| .. automethod:: pygit2.Reference.peel | ||||
| .. automethod:: pygit2.Reference.log | ||||
|  | ||||
|    Example:: | ||||
|   | ||||
							
								
								
									
										31
									
								
								src/object.c
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								src/object.c
									
									
									
									
									
								
							| @@ -135,24 +135,6 @@ Object_read_raw(Object *self) | ||||
|     return aux; | ||||
| } | ||||
|  | ||||
| static git_otype | ||||
| py_type_to_git_type(PyTypeObject *py_type) | ||||
| { | ||||
|     git_otype type = GIT_OBJ_BAD; | ||||
|  | ||||
|     if (py_type == &CommitType) { | ||||
|         type = GIT_OBJ_COMMIT; | ||||
|     } else if (py_type == &TreeType) { | ||||
|         type = GIT_OBJ_TREE; | ||||
|     } else if (py_type == &BlobType) { | ||||
|         type = GIT_OBJ_BLOB; | ||||
|     } else if (py_type == &TagType) { | ||||
|         type = GIT_OBJ_TAG; | ||||
|     } | ||||
|  | ||||
|     return type; | ||||
| } | ||||
|  | ||||
| PyDoc_STRVAR(Object_peel__doc__, | ||||
|   "peel(target_type) -> Object\n" | ||||
|   "\n" | ||||
| @@ -164,18 +146,9 @@ Object_peel(Object *self, PyObject *py_type) | ||||
|     int type = -1, err; | ||||
|     git_object *peeled; | ||||
|  | ||||
|     if (PyLong_Check(py_type)) { | ||||
|         type = PyLong_AsLong(py_type); | ||||
|         if (type == -1 && PyErr_Occurred()) | ||||
|             return NULL; | ||||
|     } else if (PyType_Check(py_type)) { | ||||
|         type = py_type_to_git_type((PyTypeObject *) py_type); | ||||
|     } | ||||
|  | ||||
|     if (type == -1) { | ||||
|         PyErr_SetString(PyExc_ValueError, "invalid target type"); | ||||
|     type = py_object_to_object_type(py_type); | ||||
|     if (type == -1) | ||||
|         return NULL; | ||||
|     } | ||||
|  | ||||
|     err = git_object_peel(&peeled, self->obj, (git_otype)type); | ||||
|     if (err < 0) | ||||
|   | ||||
| @@ -384,6 +384,29 @@ Reference_get_object(Reference *self) | ||||
|     return wrap_object(obj, self->repo); | ||||
| } | ||||
|  | ||||
| PyDoc_STRVAR(Reference_peel__doc__, | ||||
|   "peel(type) -> object\n" | ||||
|   "\n" | ||||
|   "Retrieve an object of the given type by recursive peeling."); | ||||
|  | ||||
| PyObject * | ||||
| Reference_peel(Reference *self, PyObject *py_type) | ||||
| { | ||||
|     int err, type; | ||||
|     git_object *obj; | ||||
|  | ||||
|     CHECK_REFERENCE(self); | ||||
|  | ||||
|     type = py_object_to_object_type(py_type); | ||||
|     if (type == -1) | ||||
|         return NULL; | ||||
|  | ||||
|     err = git_reference_peel(&obj, self->reference, type); | ||||
|     if (err < 0) | ||||
|         return Error_set(err); | ||||
|  | ||||
|     return wrap_object(obj, self->repo); | ||||
| } | ||||
|  | ||||
| PyDoc_STRVAR(RefLogEntry_committer__doc__, "Committer."); | ||||
|  | ||||
| @@ -479,6 +502,7 @@ PyMethodDef Reference_methods[] = { | ||||
|     METHOD(Reference, log, METH_NOARGS), | ||||
|     METHOD(Reference, get_object, METH_NOARGS), | ||||
|     METHOD(Reference, set_target, METH_VARARGS | METH_KEYWORDS), | ||||
|     METHOD(Reference, peel, METH_O), | ||||
|     {NULL} | ||||
| }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										42
									
								
								src/utils.c
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								src/utils.c
									
									
									
									
									
								
							| @@ -31,6 +31,10 @@ | ||||
| #include "utils.h" | ||||
|  | ||||
| extern PyTypeObject ReferenceType; | ||||
| extern PyTypeObject TreeType; | ||||
| extern PyTypeObject CommitType; | ||||
| extern PyTypeObject BlobType; | ||||
| extern PyTypeObject TagType; | ||||
|  | ||||
| /** | ||||
|  * py_str_to_c_str() returns a newly allocated C string holding the string | ||||
| @@ -153,3 +157,41 @@ on_error: | ||||
|  | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
| static git_otype | ||||
| py_type_to_git_type(PyTypeObject *py_type) | ||||
| { | ||||
|     git_otype type = GIT_OBJ_BAD; | ||||
|  | ||||
|     if (py_type == &CommitType) { | ||||
|         type = GIT_OBJ_COMMIT; | ||||
|     } else if (py_type == &TreeType) { | ||||
|         type = GIT_OBJ_TREE; | ||||
|     } else if (py_type == &BlobType) { | ||||
|         type = GIT_OBJ_BLOB; | ||||
|     } else if (py_type == &TagType) { | ||||
|         type = GIT_OBJ_TAG; | ||||
|     } | ||||
|  | ||||
|     return type; | ||||
| } | ||||
|  | ||||
| int | ||||
| py_object_to_object_type(PyObject *py_type) | ||||
| { | ||||
|     int type = -1; | ||||
|  | ||||
|     if (PyLong_Check(py_type)) { | ||||
|         type = PyLong_AsLong(py_type); | ||||
|         if (type == -1 && PyErr_Occurred()) | ||||
|             return -1; | ||||
|     } else if (PyType_Check(py_type)) { | ||||
|         type = py_type_to_git_type((PyTypeObject *) py_type); | ||||
|     } | ||||
|  | ||||
|     if (type == -1) { | ||||
|         PyErr_SetString(PyExc_ValueError, "invalid target type"); | ||||
|     } | ||||
|  | ||||
|     return type; | ||||
| } | ||||
|   | ||||
| @@ -119,6 +119,8 @@ const char *py_str_borrow_c_str(PyObject **tvaue, PyObject *value, const char *e | ||||
| PyObject * get_pylist_from_git_strarray(git_strarray *strarray); | ||||
| int get_strarraygit_from_pylist(git_strarray *array, PyObject *pylist); | ||||
|  | ||||
| int py_object_to_object_type(PyObject *py_type); | ||||
|  | ||||
| #define py_path_to_c_str(py_path) \ | ||||
|         py_str_to_c_str(py_path, Py_FileSystemDefaultEncoding) | ||||
|  | ||||
|   | ||||
| @@ -32,6 +32,7 @@ from __future__ import unicode_literals | ||||
| import unittest | ||||
|  | ||||
| from pygit2 import GitError, GIT_REF_OID, GIT_REF_SYMBOLIC, Signature | ||||
| from pygit2 import Commit, Tree | ||||
| from . import utils | ||||
|  | ||||
|  | ||||
| @@ -223,6 +224,11 @@ class ReferencesTest(utils.RepoTestCase): | ||||
|         ref = repo.lookup_reference('refs/heads/master') | ||||
|         self.assertEqual(repo[ref.target].id, ref.get_object().id) | ||||
|  | ||||
|     def test_peel(self): | ||||
|         ref = self.repo.lookup_reference('refs/heads/master') | ||||
|         commit = ref.peel(Commit) | ||||
|         self.assertEqual(commit.tree.id, ref.peel(Tree).id) | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     unittest.main() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Carlos Martín Nieto
					Carlos Martín Nieto