Browse Source

Fix _merge_entries on pypy.

Jelmer Vernooij 10 years ago
parent
commit
b5a39215ba
3 changed files with 10 additions and 15 deletions
  1. 2 4
      NEWS
  2. 7 7
      dulwich/_diff_tree.c
  3. 1 4
      dulwich/diff_tree.py

+ 2 - 4
NEWS

@@ -10,10 +10,8 @@
   * Strip newline from final ACKed SHA while fetching packs.
     (Michael Edgar)
 
-  * The C implementation of `dulwich._diff_tree._merge_entries` is broken
-    on pypy and causes it to segfault. Avoid importing it and fall back
-    to the native implementation for now.
-    (Jelmer Vernooij)
+  * Remove assignment to PyList_SIZE() that was causing segfaults on
+    pypy. (Jelmer Vernooij, #196)
 
  IMPROVEMENTS
 

+ 7 - 7
dulwich/_diff_tree.c

@@ -193,12 +193,9 @@ static PyObject *py_merge_entries(PyObject *self, PyObject *args)
 	if (!entries2)
 		goto error;
 
-	result = PyList_New(n1 + n2);
+	result = PyList_New(0);
 	if (!result)
 		goto error;
-	/* PyList_New sets the len of the list, not its allocated size, so we
-	 * need to trim it to the size we actually use. */
-	Py_SIZE(result) = 0;
 
 	while (i1 < n1 && i2 < n2) {
 		cmp = entry_path_cmp(entries1[i1], entries2[i2]);
@@ -217,20 +214,23 @@ static PyObject *py_merge_entries(PyObject *self, PyObject *args)
 		pair = PyTuple_Pack(2, e1, e2);
 		if (!pair)
 			goto error;
-		PyList_SET_ITEM(result, Py_SIZE(result)++, pair);
+		PyList_Append(result, pair);
+		Py_DECREF(pair);
 	}
 
 	while (i1 < n1) {
 		pair = PyTuple_Pack(2, entries1[i1++], null_entry);
 		if (!pair)
 			goto error;
-		PyList_SET_ITEM(result, Py_SIZE(result)++, pair);
+		PyList_Append(result, pair);
+		Py_DECREF(pair);
 	}
 	while (i2 < n2) {
 		pair = PyTuple_Pack(2, null_entry, entries2[i2++]);
 		if (!pair)
 			goto error;
-		PyList_SET_ITEM(result, Py_SIZE(result)++, pair);
+		PyList_Append(result, pair);
+		Py_DECREF(pair);
 	}
 	goto done;
 

+ 1 - 4
dulwich/diff_tree.py

@@ -590,9 +590,6 @@ _merge_entries_py = _merge_entries
 _count_blocks_py = _count_blocks
 try:
     # Try to import C versions
-    from dulwich._diff_tree import _is_tree, _count_blocks
-    import sys
-    if not '__pypy__' in sys.builtin_module_names:
-        from dulwich._diff_tree import _merge_entries
+    from dulwich._diff_tree import _is_tree, _merge_entries, _count_blocks
 except ImportError:
     pass