浏览代码

Treat pathnames as bytes in the Python 3 C modules

Lele Gaifax 9 年之前
父节点
当前提交
4c0ef6e680
共有 3 个文件被更改,包括 23 次插入24 次删除
  1. 11 22
      dulwich/_diff_tree.c
  2. 5 0
      dulwich/_objects.c
  3. 7 2
      dulwich/_pack.c

+ 11 - 22
dulwich/_diff_tree.c

@@ -140,8 +140,13 @@ static PyObject **tree_entries(char *path, Py_ssize_t path_len, PyObject *tree,
 			memcpy(new_path, PyString_AS_STRING(name), name_len);
 		}
 
+#if PY_MAJOR_VERSION >= 3
+		result[i] = PyObject_CallFunction(tree_entry_cls, "y#OO", new_path,
+			new_path_len, PyTuple_GET_ITEM(old_entry, 1), sha);
+#else
 		result[i] = PyObject_CallFunction(tree_entry_cls, "s#OO", new_path,
 			new_path_len, PyTuple_GET_ITEM(old_entry, 1), sha);
+#endif
 		PyMem_Free(new_path);
 		if (!result[i]) {
 			goto error;
@@ -169,18 +174,8 @@ static int entry_path_cmp(PyObject *entry1, PyObject *entry2)
 	if (!path1)
 		goto done;
 
-#if PY_MAJOR_VERSION >= 3
-	/* XXX: Is FSConverter desiderable here? */
-	if (PyUnicode_Check(path1)) {
-		PyObject *bytes;
-		if (!PyUnicode_FSConverter(path1, &bytes))
-			goto done;
-		Py_DECREF(path1);
-		path1 = bytes;
-	}
-#endif
 	if (!PyString_Check(path1)) {
-		PyErr_SetString(PyExc_TypeError, "path is not a string");
+		PyErr_SetString(PyExc_TypeError, "path is not a (byte)string");
 		goto done;
 	}
 
@@ -188,18 +183,8 @@ static int entry_path_cmp(PyObject *entry1, PyObject *entry2)
 	if (!path2)
 		goto done;
 
-#if PY_MAJOR_VERSION >= 3
-	/* XXX: Is FSConverter desiderable here? */
-	if (PyUnicode_Check(path2)) {
-		PyObject *bytes;
-		if (!PyUnicode_FSConverter(path2, &bytes))
-			goto done;
-		Py_DECREF(path2);
-		path2 = bytes;
-	}
-#endif
 	if (!PyString_Check(path2)) {
-		PyErr_SetString(PyExc_TypeError, "path is not a string");
+		PyErr_SetString(PyExc_TypeError, "path is not a (byte)string");
 		goto done;
 	}
 
@@ -220,7 +205,11 @@ static PyObject *py_merge_entries(PyObject *self, PyObject *args)
 	char *path_str;
 	int cmp;
 
+#if PY_MAJOR_VERSION >= 3
+	if (!PyArg_ParseTuple(args, "y#OO", &path_str, &path_len, &tree1, &tree2))
+#else
 	if (!PyArg_ParseTuple(args, "s#OO", &path_str, &path_len, &tree1, &tree2))
+#endif
 		return NULL;
 
 	entries1 = tree_entries(path_str, path_len, tree1, &n1);

+ 5 - 0
dulwich/_objects.c

@@ -68,8 +68,13 @@ static PyObject *py_parse_tree(PyObject *self, PyObject *args, PyObject *kw)
 	PyObject *ret, *item, *name, *sha, *py_strict = NULL;
 	static char *kwlist[] = {"text", "strict", NULL};
 
+#if PY_MAJOR_VERSION >= 3
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "y#|O", kwlist,
+	                                 &text, &len, &py_strict))
+#else
 	if (!PyArg_ParseTupleAndKeywords(args, kw, "s#|O", kwlist,
 	                                 &text, &len, &py_strict))
+#endif
 		return NULL;
 	strict = py_strict ?  PyObject_IsTrue(py_strict) : 0;
 	/* TODO: currently this returns a list; if memory usage is a concern,

+ 7 - 2
dulwich/_pack.c

@@ -206,8 +206,13 @@ static PyObject *py_bisect_find_sha(PyObject *self, PyObject *args)
 	char *sha;
 	int sha_len;
 	int start, end;
-	if (!PyArg_ParseTuple(args, "iis#O", &start, &end, 
-						  &sha, &sha_len, &unpack_name))
+#if PY_MAJOR_VERSION >= 3
+	if (!PyArg_ParseTuple(args, "iiy#O", &start, &end,
+			      &sha, &sha_len, &unpack_name))
+#else
+	if (!PyArg_ParseTuple(args, "iis#O", &start, &end,
+			      &sha, &sha_len, &unpack_name))
+#endif
 		return NULL;
 
 	if (sha_len != 20) {