dulwich-users team mailing list archive
-
dulwich-users team
-
Mailing list archive
-
Message #00341
[PATCH 16/24] diff_tree: C implementation of _is_tree.
From: Dave Borowitz <dborowitz@xxxxxxxxxx>
Change-Id: I46cb5a7765381c8cd4038d36c6b7ff257f3787e2
---
dulwich/_diff_tree.c | 62 +++++++++++++++++++++++++++++++++++++++
dulwich/diff_tree.py | 9 +++++
dulwich/tests/test_diff_tree.py | 24 ++++++++++----
setup.py | 2 +
4 files changed, 90 insertions(+), 7 deletions(-)
create mode 100644 dulwich/_diff_tree.c
diff --git a/dulwich/_diff_tree.c b/dulwich/_diff_tree.c
new file mode 100644
index 0000000..9b87db4
--- /dev/null
+++ b/dulwich/_diff_tree.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License or (at your option) a later version of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <Python.h>
+#include <sys/stat.h>
+
+static PyObject *py_is_tree(PyObject *self, PyObject *args)
+{
+ PyObject *entry, *mode, *result;
+ long lmode;
+
+ if (!PyArg_ParseTuple(args, "O", &entry))
+ return NULL;
+
+ mode = PyObject_GetAttrString(entry, "mode");
+ if (!mode)
+ return NULL;
+
+ if (mode == Py_None) {
+ result = Py_False;
+ } else {
+ lmode = PyInt_AsLong(mode);
+ if (lmode == -1 && PyErr_Occurred()) {
+ Py_DECREF(mode);
+ return NULL;
+ }
+ result = PyBool_FromLong(S_ISDIR((mode_t)lmode));
+ }
+ Py_INCREF(result);
+ Py_DECREF(mode);
+ return result;
+}
+
+static PyMethodDef py_diff_tree_methods[] = {
+ { "_is_tree", (PyCFunction)py_is_tree, METH_VARARGS, NULL },
+ { NULL, NULL, 0, NULL }
+};
+
+PyMODINIT_FUNC
+init_diff_tree(void)
+{
+ PyObject *m, *objects_mod, *diff_mod;
+ m = Py_InitModule("_diff_tree", py_diff_tree_methods);
+ if (!m)
+ return;
+}
diff --git a/dulwich/diff_tree.py b/dulwich/diff_tree.py
index 7a00731..40c5bc0 100644
--- a/dulwich/diff_tree.py
+++ b/dulwich/diff_tree.py
@@ -392,3 +392,12 @@ class RenameDetector(object):
self._find_exact_renames()
self._find_content_renames()
return self._sorted_changes()
+
+
+# Hold on to the pure-python implementations for testing.
+_is_tree_py = _is_tree
+try:
+ # Try to import C versions
+ from dulwich._diff_tree import _is_tree
+except ImportError:
+ pass
diff --git a/dulwich/tests/test_diff_tree.py b/dulwich/tests/test_diff_tree.py
index 99a444a..1230f2b 100644
--- a/dulwich/tests/test_diff_tree.py
+++ b/dulwich/tests/test_diff_tree.py
@@ -31,6 +31,7 @@ from dulwich.diff_tree import (
_tree_change_key,
RenameDetector,
_is_tree,
+ _is_tree_py
)
from dulwich.index import (
commit_tree,
@@ -48,6 +49,7 @@ from dulwich.objects import (
)
from dulwich.tests import (
TestCase,
+ TestSkipped,
)
from dulwich.tests.utils import (
make_object,
@@ -120,14 +122,22 @@ class TreeChangesTest(DiffTestCase):
(('c', 0100755, blob_c2.id), (None, None, None)),
], _merge_entries('', tree2, tree1))
+ def _do_test_is_tree(self, is_tree):
+ self.assertFalse(is_tree(TreeEntry(None, None, None)))
+ self.assertFalse(is_tree(TreeEntry('a', 0100644, 'a' * 40)))
+ self.assertFalse(is_tree(TreeEntry('a', 0100755, 'a' * 40)))
+ self.assertFalse(is_tree(TreeEntry('a', 0120000, 'a' * 40)))
+ self.assertTrue(is_tree(TreeEntry('a', 0040000, 'a' * 40)))
+ self.assertRaises(TypeError, is_tree, TreeEntry('a', 'x', 'a' * 40))
+ self.assertRaises(AttributeError, is_tree, 1234)
+
def test_is_tree(self):
- self.assertFalse(_is_tree(TreeEntry(None, None, None)))
- self.assertFalse(_is_tree(TreeEntry('a', 0100644, 'a' * 40)))
- self.assertFalse(_is_tree(TreeEntry('a', 0100755, 'a' * 40)))
- self.assertFalse(_is_tree(TreeEntry('a', 0120000, 'a' * 40)))
- self.assertTrue(_is_tree(TreeEntry('a', 0040000, 'a' * 40)))
- self.assertRaises(TypeError, _is_tree, TreeEntry('a', 'x', 'a' * 40))
- self.assertRaises(AttributeError, _is_tree, 1234)
+ self._do_test_is_tree(_is_tree_py)
+
+ def test_is_tree_extension(self):
+ if _is_tree is _is_tree_py:
+ raise TestSkipped('is_tree extension not found')
+ self._do_test_is_tree(_is_tree)
def assertChangesEqual(self, expected, tree1, tree2, **kwargs):
actual = list(tree_changes(self.store, tree1.id, tree2.id, **kwargs))
diff --git a/setup.py b/setup.py
index bd03739..5f9b594 100755
--- a/setup.py
+++ b/setup.py
@@ -54,6 +54,8 @@ setup(name='dulwich',
include_dirs=include_dirs),
Extension('dulwich._pack', ['dulwich/_pack.c'],
include_dirs=include_dirs),
+ Extension('dulwich._diff_tree', ['dulwich/_diff_tree.c'],
+ include_dirs=include_dirs),
],
distclass=DulwichDistribution,
)
--
1.7.3.2.168.gd6b63
References