From aaa3d533a82087e6a680e39c55a825dc89e1bc75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Sat, 13 Aug 2011 22:05:43 +0200 Subject: [PATCH 01/12] Drop support for Python 2.5 It still compiles and probably works fine. But unit tests do not run and official support for Python 2.5 has been dropped. --- README.md | 5 +++-- test/utils.py | 6 +----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f24f4cf..a39fdca 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ pygit2 - libgit2 bindings in Python ===================================== -pygit2 is a set of Python 2.5+ bindings to the libgit2 linkable C Git library. +pygit2 is a set of Python bindings to the libgit2 linkable C Git library. +The supported versions of Python are 2.6, 2.7, 3.1 and 3.2 INSTALLING AND RUNNING ======================== @@ -16,7 +17,7 @@ For instance, in Debian-based systems run: $ sudo apt-get install zlib1g-dev libssl-dev -Also, make sure you have Python 2.5+ installed together with the Python development headers. +Also, make sure you have Python 2.6+ installed together with the Python development headers. When those are installed, you can install pygit2: diff --git a/test/utils.py b/test/utils.py index ddc0ce0..f531e45 100644 --- a/test/utils.py +++ b/test/utils.py @@ -29,7 +29,6 @@ __author__ = 'dborowitz@google.com (Dave Borowitz)' import os import shutil -import sys import tarfile import tempfile import unittest @@ -45,10 +44,7 @@ class BaseTestCase(unittest.TestCase): def assertRaisesWithArg(self, exc_class, arg, func, *args, **kwargs): try: func(*args, **kwargs) - except exc_class: - # XXX Use the 'exc_class as exc_value' syntax as soon as we drop - # support for Python 2.5 - exc_value = sys.exc_info()[1] + except exc_class as exc_value: self.assertEqual((arg,), exc_value.args) else: self.fail('%s(%r) not raised' % (exc_class.__name__, arg)) From 7950ee1116e52ef73df5a1f916980ef13ccaa836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Sat, 13 Aug 2011 22:46:54 +0200 Subject: [PATCH 02/12] Use Python 3 string literals for the unit tests Now unit tests are broken. --- test/test_blob.py | 6 ++++-- test/test_commit.py | 6 ++++-- test/test_index.py | 12 +++++++----- test/test_refs.py | 12 ++++++------ test/test_repository.py | 6 ++++-- test/test_revwalk.py | 7 +++++-- test/test_status.py | 6 ++++-- test/test_tag.py | 6 ++++-- test/test_tree.py | 6 ++++-- test/utils.py | 5 +++-- 10 files changed, 45 insertions(+), 27 deletions(-) diff --git a/test/test_blob.py b/test/test_blob.py index 65082af..40a7e06 100644 --- a/test/test_blob.py +++ b/test/test_blob.py @@ -27,13 +27,15 @@ """Tests for Blob objects.""" -__author__ = 'dborowitz@google.com (Dave Borowitz)' - +from __future__ import unicode_literals import unittest import pygit2 import utils + +__author__ = 'dborowitz@google.com (Dave Borowitz)' + BLOB_SHA = 'af431f20fc541ed6d5afede3e2dc7160f6f01f16' diff --git a/test/test_commit.py b/test/test_commit.py index e308961..6834826 100644 --- a/test/test_commit.py +++ b/test/test_commit.py @@ -27,13 +27,15 @@ """Tests for Commit objects.""" -__author__ = 'dborowitz@google.com (Dave Borowitz)' - +from __future__ import unicode_literals import unittest from pygit2 import GIT_OBJ_COMMIT import utils + +__author__ = 'dborowitz@google.com (Dave Borowitz)' + COMMIT_SHA = '5fe808e8953c12735680c257f56600cb0de44b10' diff --git a/test/test_index.py b/test/test_index.py index 0f3b5d1..7ea6045 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -28,14 +28,16 @@ """Tests for Index files.""" -__author__ = 'jdavid@itaapy.com (J. David Ibáñez)' - -import unittest +from __future__ import unicode_literals import os - -import utils +import unittest import pygit2 +import utils + + +__author__ = 'jdavid@itaapy.com (J. David Ibáñez)' + class IndexBareTest(utils.BareRepoTestCase): diff --git a/test/test_refs.py b/test/test_refs.py index 575560e..8b16122 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -28,15 +28,15 @@ """Tests for reference objects.""" +from __future__ import unicode_literals +import unittest + +from pygit2 import GIT_REF_OID, GIT_REF_SYMBOLIC +import utils + __author__ = 'david.versmisse@itaapy.com (David Versmisse)' -import unittest -import utils -from pygit2 import GIT_REF_OID, GIT_REF_SYMBOLIC - - - LAST_COMMIT = '2be5719152d4f82c7302b1c0932d8e5f0a4a0e98' diff --git a/test/test_repository.py b/test/test_repository.py index ed1535b..d34f868 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -27,8 +27,7 @@ """Tests for Repository objects.""" -__author__ = 'dborowitz@google.com (Dave Borowitz)' - +from __future__ import unicode_literals import binascii import unittest import os @@ -38,6 +37,9 @@ from pygit2 import (GitError, GIT_OBJ_ANY, GIT_OBJ_BLOB, GIT_OBJ_COMMIT, init_repository) import utils + +__author__ = 'dborowitz@google.com (Dave Borowitz)' + A_HEX_SHA = 'af431f20fc541ed6d5afede3e2dc7160f6f01f16' A_BIN_SHA = binascii.unhexlify(A_HEX_SHA) diff --git a/test/test_revwalk.py b/test/test_revwalk.py index 4bf5275..5ea2497 100644 --- a/test/test_revwalk.py +++ b/test/test_revwalk.py @@ -28,13 +28,16 @@ """Tests for revision walk.""" -__author__ = 'jdavid@itaapy.com (J. David Ibáñez)' - +from __future__ import unicode_literals import unittest from pygit2 import GIT_SORT_TIME, GIT_SORT_REVERSE import utils + +__author__ = 'jdavid@itaapy.com (J. David Ibáñez)' + + # In the order given by git log log = [ '2be5719152d4f82c7302b1c0932d8e5f0a4a0e98', diff --git a/test/test_status.py b/test/test_status.py index 41dc4db..a01d671 100644 --- a/test/test_status.py +++ b/test/test_status.py @@ -28,13 +28,15 @@ """Tests for revision walk.""" -__author__ = 'mike.perdide@gmail.com (Julien Miotte)' - +from __future__ import unicode_literals import unittest import pygit2 import utils + +__author__ = 'mike.perdide@gmail.com (Julien Miotte)' + EXPECTED = { "current_file": pygit2.GIT_STATUS_CURRENT, "file_deleted": pygit2.GIT_STATUS_WT_DELETED, diff --git a/test/test_tag.py b/test/test_tag.py index 8b3a598..d797c4d 100644 --- a/test/test_tag.py +++ b/test/test_tag.py @@ -27,13 +27,15 @@ """Tests for Tag objects.""" -__author__ = 'dborowitz@google.com (Dave Borowitz)' - +from __future__ import unicode_literals import unittest import pygit2 import utils + +__author__ = 'dborowitz@google.com (Dave Borowitz)' + TAG_SHA = '3d2962987c695a29f1f80b6c3aa4ec046ef44369' diff --git a/test/test_tree.py b/test/test_tree.py index b48308f..96b7e97 100644 --- a/test/test_tree.py +++ b/test/test_tree.py @@ -27,14 +27,16 @@ """Tests for Commit objects.""" -__author__ = 'dborowitz@google.com (Dave Borowitz)' - +from __future__ import unicode_literals import operator import unittest import pygit2 import utils + +__author__ = 'dborowitz@google.com (Dave Borowitz)' + TREE_SHA = '967fce8df97cc71722d3c2a5930ef3e6f1d27b12' SUBTREE_SHA = '614fd9a3094bf618ea938fffc00e7d1a54f89ad0' diff --git a/test/utils.py b/test/utils.py index f531e45..6ccf909 100644 --- a/test/utils.py +++ b/test/utils.py @@ -25,8 +25,6 @@ """Test utilities for libgit2.""" -__author__ = 'dborowitz@google.com (Dave Borowitz)' - import os import shutil import tarfile @@ -36,6 +34,9 @@ import unittest import pygit2 +__author__ = 'dborowitz@google.com (Dave Borowitz)' + + class BaseTestCase(unittest.TestCase): def tearDown(self): From 81bfabea73ffcfbff7198fc4b86520c8cd20dadf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Sat, 13 Aug 2011 23:22:17 +0200 Subject: [PATCH 03/12] Use byte strings for raw-sha and text for hex-sha As suggested by Douglas Morrison in issue 43: https://github.com/libgit2/pygit2/issues/43 (Unit tests still broken.) --- pygit2.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/pygit2.c b/pygit2.c index 487e117..25094b6 100644 --- a/pygit2.c +++ b/pygit2.c @@ -276,26 +276,37 @@ py_str_to_git_oid(PyObject *py_str, git_oid *oid) const char *hex_or_bin; int err; - hex_or_bin = PyString_AsString(py_str); - if (hex_or_bin == NULL) { - Error_set_py_obj(GIT_ENOTOID, py_str); - return 0; - } - - if (PyString_Size(py_str) == 20) { + /* Case 1: raw sha */ + if (PyString_Check(py_str)) { + hex_or_bin = PyString_AsString(py_str); + if (hex_or_bin == NULL) + return 0; git_oid_fromraw(oid, (const unsigned char*)hex_or_bin); - err = 0; + return 1; } - else { + + /* Case 2: hex sha */ + if (PyUnicode_Check(py_str)) { + py_str = PyUnicode_AsASCIIString(py_str); + if (py_str == NULL) + return 0; + hex_or_bin = PyString_AsString(py_str); + Py_DECREF(py_str); + if (hex_or_bin == NULL) + return 0; err = git_oid_fromstr(oid, hex_or_bin); + if (err < 0) { + Error_set_py_obj(err, py_str); + return 0; + } + return 1; } - if (err < 0) { - Error_set_py_obj(err, py_str); - return 0; - } - - return 1; + /* Type error */ + PyErr_Format(PyExc_TypeError, + "Git object id must be byte or a text string, not: %.200s", + Py_TYPE(py_str)->tp_name); + return 0; } static PyObject* From 7f6568038a78dfab98ee6fac71ba5ee4d3692503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Mon, 15 Aug 2011 22:26:53 +0200 Subject: [PATCH 04/12] Fix blob unit tests --- test/test_blob.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_blob.py b/test/test_blob.py index 40a7e06..db01698 100644 --- a/test/test_blob.py +++ b/test/test_blob.py @@ -45,8 +45,8 @@ class BlobTest(utils.BareRepoTestCase): blob = self.repo[BLOB_SHA] self.assertTrue(isinstance(blob, pygit2.Blob)) self.assertEqual(pygit2.GIT_OBJ_BLOB, blob.type) - self.assertEqual('a contents\n', blob.data) - self.assertEqual('a contents\n', blob.read_raw()) + self.assertEqual(b'a contents\n', blob.data) + self.assertEqual(b'a contents\n', blob.read_raw()) if __name__ == '__main__': From caccfb4006f99bdd1cbd1ef74c0ac7235d8dd0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Mon, 15 Aug 2011 22:54:06 +0200 Subject: [PATCH 05/12] Return text strings for hex-sha (like Object.sha) --- pygit2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygit2.c b/pygit2.c index 25094b6..477ceb5 100644 --- a/pygit2.c +++ b/pygit2.c @@ -315,7 +315,7 @@ git_oid_to_py_str(const git_oid *oid) char hex[GIT_OID_HEXSZ]; git_oid_fmt(hex, oid); - return PyString_FromStringAndSize(hex, GIT_OID_HEXSZ); + return PyUnicode_DecodeASCII(hex, GIT_OID_HEXSZ, "strict"); } static int From 18846c1b55ddba680663ea0415216ef55a3a23b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Mon, 15 Aug 2011 23:16:31 +0200 Subject: [PATCH 06/12] Now Commit.message returns a text string --- pygit2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pygit2.c b/pygit2.c index 477ceb5..feb083f 100644 --- a/pygit2.c +++ b/pygit2.c @@ -1037,7 +1037,14 @@ Commit_get_message_encoding(Commit *commit) static PyObject * Commit_get_message(Commit *commit) { - return PyString_FromString(git_commit_message(commit->commit)); + const char *encoding; + const char *message; + int len; + + encoding = git_commit_message_encoding(commit->commit); + message = git_commit_message(commit->commit); + len = strlen(message); + return PyUnicode_Decode(message, (Py_ssize_t)len, encoding, "strict"); } static PyObject * From 5cc4ba23d4212e0f78f59d19b8aa0fa67f8280a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Tue, 16 Aug 2011 22:54:05 +0200 Subject: [PATCH 07/12] tests: replace xrange by range This fixes one test with Python 3. --- test/test_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_index.py b/test/test_index.py index 7ea6045..a006398 100644 --- a/test/test_index.py +++ b/test/test_index.py @@ -100,7 +100,7 @@ class IndexTest(utils.RepoTestCase): self.assertEqual(len(list(index)), n) # Compare SHAs, not IndexEntry object identity - entries = [index[x].sha for x in xrange(n)] + entries = [index[x].sha for x in range(n)] self.assertEqual(list(x.sha for x in index), entries) def test_mode(self): From 323d2e23cda5bac3326e986b7e24f167ce1d0162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Tue, 16 Aug 2011 22:56:45 +0200 Subject: [PATCH 08/12] Fix revision walker --- pygit2.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pygit2.c b/pygit2.c index feb083f..0a9f7a7 100644 --- a/pygit2.c +++ b/pygit2.c @@ -504,11 +504,6 @@ Repository_walk(Repository *self, PyObject *args) if (!PyArg_ParseTuple(args, "OI", &value, &sort)) return NULL; - if (value != Py_None && !PyString_Check(value)) { - PyErr_SetObject(PyExc_TypeError, value); - return NULL; - } - err = git_revwalk_new(&walk, self->repo); if (err < 0) return Error_set(err); From 60f50d9f08ae979cb9cc7e2965a6847b9d0b8a69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Fri, 19 Aug 2011 00:31:37 +0200 Subject: [PATCH 09/12] Support 'index[path]' where path is a text string Encode text strings to UTF-8. --- pygit2.c | 56 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/pygit2.c b/pygit2.c index 0a9f7a7..b68fd3b 100644 --- a/pygit2.c +++ b/pygit2.c @@ -1747,6 +1747,31 @@ Index_write(Index *self) Py_RETURN_NONE; } +char * +py_str_to_c_str(PyObject *value) +{ + char *c_str; + + /* Case 1: byte string */ + if (PyString_Check(value)) + return PyString_AsString(value); + + /* Case 2: text string */ + if (PyUnicode_Check(value)) { + value = PyUnicode_AsUTF8String(value); + if (value == NULL) + return NULL; + c_str = PyString_AsString(value); + Py_DECREF(value); + return c_str; + } + + /* Type error */ + PyErr_Format(PyExc_TypeError, "unexpected %.200s", + Py_TYPE(value)->tp_name); + return NULL; +} + /* This is an internal function, used by Index_getitem and Index_setitem */ static int Index_get_position(Index *self, PyObject *value) @@ -1754,17 +1779,8 @@ Index_get_position(Index *self, PyObject *value) char *path; int idx; - if (PyString_Check(value)) { - path = PyString_AsString(value); - if (!path) - return -1; - idx = git_index_find(self->index, path); - if (idx < 0) { - Error_set_str(idx, path); - return -1; - } - } - else if (PyInt_Check(value)) { + /* Case 1: integer */ + if (PyInt_Check(value)) { idx = (int)PyInt_AsLong(value); if (idx == -1 && PyErr_Occurred()) return -1; @@ -1772,14 +1788,18 @@ Index_get_position(Index *self, PyObject *value) PyErr_SetObject(PyExc_ValueError, value); return -1; } - } - else { - PyErr_Format(PyExc_TypeError, - "Index entry key must be int or str, not %.200s", - Py_TYPE(value)->tp_name); - return -1; + return idx; } + /* Case 2: byte or text string */ + path = py_str_to_c_str(value); + if (!path) + return -1; + idx = git_index_find(self->index, path); + if (idx < 0) { + Error_set_str(idx, path); + return -1; + } return idx; } @@ -1789,7 +1809,7 @@ Index_contains(Index *self, PyObject *value) char *path; int idx; - path = PyString_AsString(value); + path = py_str_to_c_str(value); if (!path) return -1; idx = git_index_find(self->index, path); From 500a14839804999625000658cf15f4d8c32af14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Fri, 19 Aug 2011 00:44:48 +0200 Subject: [PATCH 10/12] tests: fix syntax error on octal literals for Py 3 --- test/test_tree.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test/test_tree.py b/test/test_tree.py index 96b7e97..3864911 100644 --- a/test/test_tree.py +++ b/test/test_tree.py @@ -57,27 +57,27 @@ class TreeTest(utils.BareRepoTestCase): self.assertRaisesWithArg(IndexError, 3, lambda: tree[3]) self.assertEqual(3, len(tree)) - a_sha = '7f129fd57e31e935c6d60a0c794efe4e6927664b' + sha = '7f129fd57e31e935c6d60a0c794efe4e6927664b' self.assertTrue('a' in tree) - self.assertTreeEntryEqual(tree[0], a_sha, 'a', 0100644) - self.assertTreeEntryEqual(tree[-3], a_sha, 'a', 0100644) - self.assertTreeEntryEqual(tree['a'], a_sha, 'a', 0100644) + self.assertTreeEntryEqual(tree[0], sha, 'a', 0o0100644) + self.assertTreeEntryEqual(tree[-3], sha, 'a', 0o0100644) + self.assertTreeEntryEqual(tree['a'], sha, 'a', 0o0100644) - b_sha = '85f120ee4dac60d0719fd51731e4199aa5a37df6' + sha = '85f120ee4dac60d0719fd51731e4199aa5a37df6' self.assertTrue('b' in tree) - self.assertTreeEntryEqual(tree[1], b_sha, 'b', 0100644) - self.assertTreeEntryEqual(tree[-2], b_sha, 'b', 0100644) - self.assertTreeEntryEqual(tree['b'], b_sha, 'b', 0100644) + self.assertTreeEntryEqual(tree[1], sha, 'b', 0o0100644) + self.assertTreeEntryEqual(tree[-2], sha, 'b', 0o0100644) + self.assertTreeEntryEqual(tree['b'], sha, 'b', 0o0100644) def test_read_subtree(self): tree = self.repo[TREE_SHA] subtree_entry = tree['c'] - self.assertTreeEntryEqual(subtree_entry, SUBTREE_SHA, 'c', 0040000) + self.assertTreeEntryEqual(subtree_entry, SUBTREE_SHA, 'c', 0o0040000) subtree = subtree_entry.to_object() self.assertEqual(1, len(subtree)) - self.assertTreeEntryEqual( - subtree[0], '297efb891a47de80be0cfe9c639e4b8c9b450989', 'd', 0100644) + sha = '297efb891a47de80be0cfe9c639e4b8c9b450989' + self.assertTreeEntryEqual(subtree[0], sha, 'd', 0o0100644) # XXX Creating new trees was removed from libgit2 by v0.11.0, we # deactivate this test temporarily, since the feature may come back in @@ -85,15 +85,15 @@ class TreeTest(utils.BareRepoTestCase): def xtest_new_tree(self): tree = pygit2.Tree(self.repo) self.assertEqual(0, len(tree)) - tree.add_entry('1' * 40, 'x', 0100644) - tree.add_entry('2' * 40, 'y', 0100755) + tree.add_entry('1' * 40, 'x', 0o0100644) + tree.add_entry('2' * 40, 'y', 0o0100755) self.assertEqual(2, len(tree)) self.assertTrue('x' in tree) self.assertTrue('y' in tree) self.assertRaisesWithArg(KeyError, '1' * 40, tree['x'].to_object) - tree.add_entry('3' * 40, 'z1', 0100644) - tree.add_entry('4' * 40, 'z2', 0100644) + tree.add_entry('3' * 40, 'z1', 0o0100644) + tree.add_entry('4' * 40, 'z2', 0o0100644) self.assertEqual(4, len(tree)) del tree['z1'] del tree[2] @@ -122,4 +122,4 @@ class TreeTest(utils.BareRepoTestCase): if __name__ == '__main__': - unittest.main() + unittest.main() From 8137dc84b5d41d89feffef9a9f882c122e3c30a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Fri, 19 Aug 2011 08:49:46 +0200 Subject: [PATCH 11/12] Support 'tree[name]' where name is a text string --- pygit2.c | 90 +++++++++++++++++++++++++------------------------------- 1 file changed, 40 insertions(+), 50 deletions(-) diff --git a/pygit2.c b/pygit2.c index b68fd3b..0bd2e8d 100644 --- a/pygit2.c +++ b/pygit2.c @@ -318,6 +318,31 @@ git_oid_to_py_str(const git_oid *oid) return PyUnicode_DecodeASCII(hex, GIT_OID_HEXSZ, "strict"); } +char * +py_str_to_c_str(PyObject *value) +{ + char *c_str; + + /* Case 1: byte string */ + if (PyString_Check(value)) + return PyString_AsString(value); + + /* Case 2: text string */ + if (PyUnicode_Check(value)) { + value = PyUnicode_AsUTF8String(value); + if (value == NULL) + return NULL; + c_str = PyString_AsString(value); + Py_DECREF(value); + return c_str; + } + + /* Type error */ + PyErr_Format(PyExc_TypeError, "unexpected %.200s", + Py_TYPE(value)->tp_name); + return NULL; +} + static int Repository_init(Repository *self, PyObject *args, PyObject *kwds) { @@ -1273,7 +1298,7 @@ Tree_contains(Tree *self, PyObject *py_name) { char *name; - name = PyString_AsString(py_name); + name = py_str_to_c_str(py_name); if (name == NULL) return -1; @@ -1294,21 +1319,6 @@ wrap_tree_entry(const git_tree_entry *entry, Tree *tree) return py_entry; } -static TreeEntry * -Tree_getitem_by_name(Tree *self, PyObject *py_name) -{ - char *name; - const git_tree_entry *entry; - - name = PyString_AS_STRING(py_name); - entry = git_tree_entry_byname(self->tree, name); - if (!entry) { - PyErr_SetObject(PyExc_KeyError, py_name); - return NULL; - } - return wrap_tree_entry(entry, self); -} - static int Tree_fix_index(Tree *self, PyObject *py_index) { @@ -1375,18 +1385,23 @@ Tree_getitem_by_index(Tree *self, PyObject *py_index) static TreeEntry * Tree_getitem(Tree *self, PyObject *value) { - if (PyString_Check(value)) { - return Tree_getitem_by_name(self, value); - } - else if (PyInt_Check(value)) { + char *name; + const git_tree_entry *entry; + + /* Case 1: integer */ + if (PyInt_Check(value)) return Tree_getitem_by_index(self, value); - } - else { - PyErr_Format(PyExc_TypeError, - "Tree entry index must be int or str, not %.200s", - Py_TYPE(value)->tp_name); + + /* Case 2: byte or text string */ + name = py_str_to_c_str(value); + if (name == NULL) + return NULL; + entry = git_tree_entry_byname(self->tree, name); + if (!entry) { + PyErr_SetObject(PyExc_KeyError, value); return NULL; } + return wrap_tree_entry(entry, self); } static PySequenceMethods Tree_as_sequence = { @@ -1747,31 +1762,6 @@ Index_write(Index *self) Py_RETURN_NONE; } -char * -py_str_to_c_str(PyObject *value) -{ - char *c_str; - - /* Case 1: byte string */ - if (PyString_Check(value)) - return PyString_AsString(value); - - /* Case 2: text string */ - if (PyUnicode_Check(value)) { - value = PyUnicode_AsUTF8String(value); - if (value == NULL) - return NULL; - c_str = PyString_AsString(value); - Py_DECREF(value); - return c_str; - } - - /* Type error */ - PyErr_Format(PyExc_TypeError, "unexpected %.200s", - Py_TYPE(value)->tp_name); - return NULL; -} - /* This is an internal function, used by Index_getitem and Index_setitem */ static int Index_get_position(Index *self, PyObject *value) From 585ce44c21912b1fd928b46c99d39056373599b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=2E=20David=20Ib=C3=A1=C3=B1ez?= Date: Fri, 19 Aug 2011 21:38:25 +0200 Subject: [PATCH 12/12] tests: fix last test for Python 2 --- test/test_repository.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_repository.py b/test/test_repository.py index d34f868..63b7676 100644 --- a/test/test_repository.py +++ b/test/test_repository.py @@ -59,7 +59,7 @@ class RepositoryTest(utils.BareRepoTestCase): self.assertEqual((GIT_OBJ_BLOB, 'a contents 2\n'), a2) def test_write(self): - data = "hello world" + data = b"hello world" # invalid object type self.assertRaises(GitError, self.repo.write, GIT_OBJ_ANY, data)