Add TreeBuilder.get and remove TreeEntry.to_object

Also, check errors from git_tree_entry_dup
This commit is contained in:
J. David Ibáñez 2013-05-04 00:31:03 +02:00
parent f5082b320b
commit 42aed417d4
7 changed files with 85 additions and 63 deletions

View File

@ -187,7 +187,6 @@ interfaces::
.. autoattribute:: pygit2.TreeEntry.oid
.. autoattribute:: pygit2.TreeEntry.hex
.. autoattribute:: pygit2.TreeEntry.filemode
.. automethod:: pygit2.TreeEntry.to_object
Creating trees

View File

@ -42,7 +42,6 @@ extern PyTypeObject IndexType;
void
TreeEntry_dealloc(TreeEntry *self)
{
Py_CLEAR(self->owner);
git_tree_entry_free((git_tree_entry*)self->entry);
PyObject_Del(self);
}
@ -87,22 +86,6 @@ TreeEntry_hex__get__(TreeEntry *self)
}
PyDoc_STRVAR(TreeEntry_to_object__doc__,
"to_object() -> Object\n"
"\n"
"Look up the corresponding object in the repo.");
PyObject *
TreeEntry_to_object(TreeEntry *self)
{
const git_oid *entry_oid;
Repository *repo;
repo = ((Object*)(self->owner))->repo;
entry_oid = git_tree_entry_id(self->entry);
return lookup_object(repo, entry_oid, GIT_OBJ_ANY);
}
PyGetSetDef TreeEntry_getseters[] = {
GETTER(TreeEntry, filemode),
GETTER(TreeEntry, name),
@ -111,11 +94,6 @@ PyGetSetDef TreeEntry_getseters[] = {
{NULL}
};
PyMethodDef TreeEntry_methods[] = {
METHOD(TreeEntry, to_object, METH_NOARGS),
{NULL}
};
PyDoc_STRVAR(TreeEntry__doc__, "TreeEntry objects.");
@ -147,7 +125,7 @@ PyTypeObject TreeEntryType = {
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
TreeEntry_methods, /* tp_methods */
0, /* tp_methods */
0, /* tp_members */
TreeEntry_getseters, /* tp_getset */
0, /* tp_base */
@ -181,16 +159,14 @@ Tree_contains(Tree *self, PyObject *py_name)
}
TreeEntry *
wrap_tree_entry(const git_tree_entry *entry, Tree *tree)
wrap_tree_entry(const git_tree_entry *entry)
{
TreeEntry *py_entry;
py_entry = PyObject_New(TreeEntry, &TreeEntryType);
if (py_entry) {
if (py_entry)
py_entry->entry = entry;
py_entry->owner = (PyObject*)tree;
Py_INCREF(tree);
}
return py_entry;
}
@ -252,7 +228,14 @@ Tree_getitem_by_index(Tree *self, PyObject *py_index)
PyErr_SetObject(PyExc_IndexError, py_index);
return NULL;
}
return wrap_tree_entry(git_tree_entry_dup(entry), self);
entry = git_tree_entry_dup(entry);
if (entry == NULL) {
PyErr_SetNone(PyExc_MemoryError);
return NULL;
}
return wrap_tree_entry(entry);
}
TreeEntry *
@ -283,7 +266,7 @@ Tree_getitem(Tree *self, PyObject *value)
return (TreeEntry*)Error_set(err);
/* git_tree_entry_dup is already done in git_tree_entry_bypath */
return wrap_tree_entry(entry, self);
return wrap_tree_entry(entry);
}
@ -431,15 +414,20 @@ TreeIter_dealloc(TreeIter *self)
TreeEntry *
TreeIter_iternext(TreeIter *self)
{
const git_tree_entry *tree_entry;
const git_tree_entry *entry;
tree_entry = git_tree_entry_byindex(self->owner->tree, self->i);
if (!tree_entry)
entry = git_tree_entry_byindex(self->owner->tree, self->i);
if (!entry)
return NULL;
self->i += 1;
return (TreeEntry*)wrap_tree_entry(git_tree_entry_dup(tree_entry),
self->owner);
entry = git_tree_entry_dup(entry);
if (entry == NULL) {
PyErr_SetNone(PyExc_MemoryError);
return NULL;
}
return wrap_tree_entry(entry);
}

View File

@ -33,11 +33,11 @@
#include <git2.h>
#include "types.h"
TreeEntry * wrap_tree_entry(const git_tree_entry *entry);
PyObject* TreeEntry_get_filemode(TreeEntry *self);
PyObject* TreeEntry_get_name(TreeEntry *self);
PyObject* TreeEntry_get_oid(TreeEntry *self);
PyObject* TreeEntry_get_hex(TreeEntry *self);
PyObject* TreeEntry_to_object(TreeEntry *self);
TreeEntry* Tree_getitem_by_index(Tree *self, PyObject *py_index);
TreeEntry* Tree_getitem(Tree *self, PyObject *value);

View File

@ -32,6 +32,7 @@
#include "utils.h"
#include "oid.h"
#include "treebuilder.h"
#include "tree.h"
void
@ -44,9 +45,9 @@ TreeBuilder_dealloc(TreeBuilder *self)
PyDoc_STRVAR(TreeBuilder_insert__doc__,
"insert(name, oid, attr)\n"
"\n"
"Insert or replace an entry in the treebuilder.");
"insert(name, oid, attr)\n"
"\n"
"Insert or replace an entry in the treebuilder.");
PyObject *
TreeBuilder_insert(TreeBuilder *self, PyObject *args)
@ -72,9 +73,9 @@ TreeBuilder_insert(TreeBuilder *self, PyObject *args)
PyDoc_STRVAR(TreeBuilder_write__doc__,
"write() -> bytes\n"
"\n"
"Write the tree to the given repository.");
"write() -> bytes\n"
"\n"
"Write the tree to the given repository.");
PyObject *
TreeBuilder_write(TreeBuilder *self)
@ -90,10 +91,38 @@ TreeBuilder_write(TreeBuilder *self)
}
PyDoc_STRVAR(TreeBuilder_get__doc__,
"get(name) -> TreeEntry\n"
"\n"
"Return the TreeEntry for the given name, or None if there is not.");
PyObject *
TreeBuilder_get(TreeBuilder *self, PyObject *py_filename)
{
char *filename;
const git_tree_entry *entry;
filename = py_path_to_c_str(py_filename);
if (filename == NULL)
return NULL;
entry = git_treebuilder_get(self->bld, filename);
if (entry == NULL)
Py_RETURN_NONE;
entry = git_tree_entry_dup(entry);
if (entry == NULL) {
PyErr_SetNone(PyExc_MemoryError);
return NULL;
}
return (PyObject*)wrap_tree_entry(entry);
}
PyDoc_STRVAR(TreeBuilder_remove__doc__,
"remove(name)\n"
"\n"
"Remove an entry from the builder.");
"remove(name)\n"
"\n"
"Remove an entry from the builder.");
PyObject *
TreeBuilder_remove(TreeBuilder *self, PyObject *py_filename)
@ -114,9 +143,9 @@ TreeBuilder_remove(TreeBuilder *self, PyObject *py_filename)
PyDoc_STRVAR(TreeBuilder_clear__doc__,
"clear()\n"
"\n"
"Clear all the entries in the builder.");
"clear()\n"
"\n"
"Clear all the entries in the builder.");
PyObject *
TreeBuilder_clear(TreeBuilder *self)
@ -126,10 +155,11 @@ TreeBuilder_clear(TreeBuilder *self)
}
PyMethodDef TreeBuilder_methods[] = {
METHOD(TreeBuilder, insert, METH_VARARGS),
METHOD(TreeBuilder, write, METH_NOARGS),
METHOD(TreeBuilder, remove, METH_O),
METHOD(TreeBuilder, clear, METH_NOARGS),
METHOD(TreeBuilder, get, METH_O),
METHOD(TreeBuilder, insert, METH_VARARGS),
METHOD(TreeBuilder, remove, METH_O),
METHOD(TreeBuilder, write, METH_NOARGS),
{NULL}
};

View File

@ -130,7 +130,6 @@ SIMPLE_TYPE(TreeBuilder, git_treebuilder, bld)
typedef struct {
PyObject_HEAD
PyObject *owner; /* Tree or TreeBuilder */
const git_tree_entry *entry;
} TreeEntry;

View File

@ -71,23 +71,26 @@ class TreeTest(utils.BareRepoTestCase):
self.assertTreeEntryEqual(tree['c/d'], sha, 'd', 0o0100644)
self.assertRaisesWithArg(KeyError, 'ab/cd', lambda: tree['ab/cd'])
def test_read_subtree(self):
tree = self.repo[TREE_SHA]
subtree_entry = tree['c']
self.assertTreeEntryEqual(subtree_entry, SUBTREE_SHA, 'c', 0o0040000)
subtree = subtree_entry.to_object()
subtree = self.repo[subtree_entry.oid]
self.assertEqual(1, len(subtree))
sha = '297efb891a47de80be0cfe9c639e4b8c9b450989'
self.assertTreeEntryEqual(subtree[0], sha, 'd', 0o0100644)
def test_new_tree(self):
b0 = self.repo.create_blob('1')
b1 = self.repo.create_blob('2')
t = self.repo.TreeBuilder()
repo = self.repo
b0 = repo.create_blob('1')
b1 = repo.create_blob('2')
t = repo.TreeBuilder()
t.insert('x', b0, 0o0100644)
t.insert('y', b1, 0o0100755)
tree = self.repo[t.write()]
tree = repo[t.write()]
self.assertTrue('x' in tree)
self.assertTrue('y' in tree)
@ -97,9 +100,8 @@ class TreeTest(utils.BareRepoTestCase):
self.assertEqual(x.filemode, 0o0100644)
self.assertEqual(y.filemode, 0o0100755)
self.assertEqual(x.to_object().oid, b0)
self.assertEqual(y.to_object().oid, b1)
self.assertEqual(repo[x.oid].oid, b0)
self.assertEqual(repo[y.oid].oid, b1)
def test_modify_tree(self):
@ -107,6 +109,7 @@ class TreeTest(utils.BareRepoTestCase):
self.assertRaises(TypeError, operator.setitem, 'c', tree['a'])
self.assertRaises(TypeError, operator.delitem, 'c')
def test_iterate_tree(self):
"""
Testing that we're able to iterate of a Tree object and that the

View File

@ -63,8 +63,11 @@ class TreeBuilderTest(utils.BareRepoTestCase):
def test_rebuild_treebuilder(self):
tree = self.repo[TREE_SHA]
bld = self.repo.TreeBuilder()
for e in tree:
bld.insert(e.name, e.hex, e.filemode)
for entry in tree:
name = entry.name
self.assertIsNone(bld.get(name))
bld.insert(name, entry.hex, entry.filemode)
self.assertEqual(bld.get(name).oid, entry.oid)
result = bld.write()
self.assertEqual(len(bld), len(tree))