summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2015-01-05 17:59:22 +0100
committerSebastian Thiel <byronimo@gmail.com>2015-01-05 17:59:22 +0100
commite1060a2a8c90c0730c3541811df8f906dac510a7 (patch)
tree1c29ef00a756be7e88aeb43cfa847dbf2e6f3079
parent8a308613467a1510f8dac514624abae4e10c0779 (diff)
downloadgitpython-e1060a2a8c90c0730c3541811df8f906dac510a7.tar.gz
test_commit works once again
-rw-r--r--doc/source/changes.rst1
-rw-r--r--git/cmd.py7
-rw-r--r--git/config.py7
-rw-r--r--git/diff.py2
-rw-r--r--git/objects/base.py7
-rw-r--r--git/objects/commit.py4
-rw-r--r--git/objects/fun.py3
-rw-r--r--git/refs/symbolic.py2
-rw-r--r--git/repo/base.py17
-rw-r--r--git/test/test_commit.py44
10 files changed, 55 insertions, 39 deletions
diff --git a/doc/source/changes.rst b/doc/source/changes.rst
index cf528b28..06a73f41 100644
--- a/doc/source/changes.rst
+++ b/doc/source/changes.rst
@@ -5,6 +5,7 @@ Changelog
0.3.4 - python 3 support
========================
* Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes.
+* Id attribute of Commit objects is now `hexsha`, instead of `binsha`. The latter makes no sense in python 3 and I see no application of it anyway besides its artificial usage in test cases.
0.3.3
=====
diff --git a/git/cmd.py b/git/cmd.py
index c536b43c..2bff3310 100644
--- a/git/cmd.py
+++ b/git/cmd.py
@@ -320,6 +320,7 @@ class Git(LazyMixin):
always be created with a pipe due to issues with subprocess.
This merely is a workaround as data will be copied from the
output pipe to the given output stream directly.
+ Judging from the implementation, you shouldn't use this flag !
:param subprocess_kwargs:
Keyword arguments to be passed to subprocess.Popen. Please note that
@@ -411,9 +412,13 @@ class Git(LazyMixin):
else:
raise GitCommandError(command, status, stderr_value)
+
+ if isinstance(stdout_value, bytes): # could also be output_stream
+ stdout_value = stdout_value.decode(defenc)
+
# Allow access to the command's status code
if with_extended_output:
- return (status, stdout_value, stderr_value)
+ return (status, stdout_value, stderr_value.decode(defenc))
else:
return stdout_value
diff --git a/git/config.py b/git/config.py
index 988547a0..7917bc5a 100644
--- a/git/config.py
+++ b/git/config.py
@@ -201,6 +201,11 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, obje
self.write()
except IOError:
log.error("Exception during destruction of GitConfigParser", exc_info=True)
+ except ReferenceError:
+ # This happens in PY3 ... and usually means that some state cannot be written
+ # as the sections dict cannot be iterated
+ # Usually when shutting down the interpreter, don'y know how to fix this
+ pass
finally:
self._lock._release_lock()
@@ -345,7 +350,7 @@ class GitConfigParser(with_metaclass(MetaParserBuilder, cp.RawConfigParser, obje
# END get lock for physical files
if not hasattr(fp, "seek"):
- fp = open(self._file_or_files, "w")
+ fp = open(self._file_or_files, "wb")
close_fp = True
else:
fp.seek(0)
diff --git a/git/diff.py b/git/diff.py
index b3e7245b..1692d83e 100644
--- a/git/diff.py
+++ b/git/diff.py
@@ -195,7 +195,7 @@ class Diff(object):
""", re.VERBOSE | re.MULTILINE)
# can be used for comparisons
NULL_HEX_SHA = "0" * 40
- NULL_BIN_SHA = "\0" * 20
+ NULL_BIN_SHA = b"\0" * 20
__slots__ = ("a_blob", "b_blob", "a_mode", "b_mode", "new_file", "deleted_file",
"rename_from", "rename_to", "diff")
diff --git a/git/objects/base.py b/git/objects/base.py
index 1f0d5752..004e3981 100644
--- a/git/objects/base.py
+++ b/git/objects/base.py
@@ -21,7 +21,7 @@ class Object(LazyMixin):
"""Implements an Object which may be Blobs, Trees, Commits and Tags"""
NULL_HEX_SHA = '0' * 40
- NULL_BIN_SHA = '\0' * 20
+ NULL_BIN_SHA = b'\0' * 20
TYPES = (dbtyp.str_blob_type, dbtyp.str_tree_type, dbtyp.str_commit_type, dbtyp.str_tag_type)
__slots__ = ("repo", "binsha", "size")
@@ -94,7 +94,7 @@ class Object(LazyMixin):
def __str__(self):
""":return: string of our SHA1 as understood by all git commands"""
- return bin_to_hex(self.binsha)
+ return self.hexsha
def __repr__(self):
""":return: string with pythonic representation of our object"""
@@ -103,7 +103,8 @@ class Object(LazyMixin):
@property
def hexsha(self):
""":return: 40 byte hex version of our 20 byte binary sha"""
- return bin_to_hex(self.binsha)
+ # b2a_hex produces bytes
+ return bin_to_hex(self.binsha).decode('ascii')
@property
def data_stream(self):
diff --git a/git/objects/commit.py b/git/objects/commit.py
index f8b5c969..53af22cd 100644
--- a/git/objects/commit.py
+++ b/git/objects/commit.py
@@ -62,7 +62,7 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
"author", "authored_date", "author_tz_offset",
"committer", "committed_date", "committer_tz_offset",
"message", "parents", "encoding", "gpgsig")
- _id_attribute_ = "binsha"
+ _id_attribute_ = "hexsha"
def __init__(self, repo, binsha, tree=None, author=None, authored_date=None, author_tz_offset=None,
committer=None, committed_date=None, committer_tz_offset=None,
@@ -395,7 +395,7 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
write(("encoding %s\n" % self.encoding).encode('ascii'))
if self.gpgsig:
- write("gpgsig")
+ write(b"gpgsig")
for sigline in self.gpgsig.rstrip("\n").split("\n"):
write((" " + sigline + "\n").encode('ascii'))
diff --git a/git/objects/fun.py b/git/objects/fun.py
index f92a4c06..610bdb5c 100644
--- a/git/objects/fun.py
+++ b/git/objects/fun.py
@@ -2,7 +2,6 @@
from stat import S_ISDIR
from git.compat import (
byte_ord,
- force_bytes,
defenc,
xrange,
text_type
@@ -37,7 +36,7 @@ def tree_to_stream(entries, write):
# takes the input literally, which appears to be utf8 on linux.
if isinstance(name, text_type):
name = name.encode(defenc)
- write(b''.join(mode_str, b' ', name, b'\0', binsha))
+ write(b''.join((mode_str, b' ', name, b'\0', binsha)))
# END for each item
def tree_entries_from_data(data):
diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py
index 1ac9ac65..252462a9 100644
--- a/git/refs/symbolic.py
+++ b/git/refs/symbolic.py
@@ -308,7 +308,7 @@ class SymbolicReference(object):
lfd = LockedFD(fpath)
fd = lfd.open(write=True, stream=True)
- fd.write(write_value)
+ fd.write(write_value.encode('ascii'))
lfd.commit()
# Adjust the reflog
diff --git a/git/repo/base.py b/git/repo/base.py
index f92a85ce..27c640ff 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -47,7 +47,10 @@ from .fun import (
read_gitfile,
touch,
)
-from git.compat import text_type
+from git.compat import (
+ text_type,
+ defenc
+)
import os
import sys
@@ -177,11 +180,11 @@ class Repo(object):
# Description property
def _get_description(self):
filename = join(self.git_dir, 'description')
- return open(filename).read().rstrip()
+ return open(filename, 'rb').read().rstrip().decode(defenc)
def _set_description(self, descr):
filename = join(self.git_dir, 'description')
- open(filename, 'w').write(descr + '\n')
+ open(filename, 'wb').write((descr + '\n').encode(defenc))
description = property(_get_description, _set_description,
doc="the project's description")
@@ -464,8 +467,8 @@ class Repo(object):
if os.path.exists(alternates_path):
try:
- f = open(alternates_path)
- alts = f.read()
+ f = open(alternates_path, 'rb')
+ alts = f.read().decode(defenc)
finally:
f.close()
return alts.strip().splitlines()
@@ -489,8 +492,8 @@ class Repo(object):
os.remove(alternates_path)
else:
try:
- f = open(alternates_path, 'w')
- f.write("\n".join(alts))
+ f = open(alternates_path, 'wb')
+ f.write("\n".join(alts).encode(defenc))
finally:
f.close()
# END file handling
diff --git a/git/test/test_commit.py b/git/test/test_commit.py
index 5f45e59d..37a54092 100644
--- a/git/test/test_commit.py
+++ b/git/test/test_commit.py
@@ -51,7 +51,7 @@ def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False)
stream.seek(0)
istream = rwrepo.odb.store(IStream(Commit.type, streamlen, stream))
- assert istream.hexsha == cm.hexsha
+ assert istream.hexsha == cm.hexsha.encode('ascii')
nc = Commit(rwrepo, Commit.NULL_BIN_SHA, cm.tree,
cm.author, cm.authored_date, cm.author_tz_offset,
@@ -129,7 +129,7 @@ class TestCommit(TestBase):
def test_unicode_actor(self):
# assure we can parse unicode actors correctly
- name = "Üäöß ÄußÉ".decode("utf-8")
+ name = u"Üäöß ÄußÉ"
assert len(name) == 9
special = Actor._from_string(u"%s <something@this.com>" % name)
assert special.name == name
@@ -146,13 +146,13 @@ class TestCommit(TestBase):
# basic branch first, depth first
dfirst = start.traverse(branch_first=False)
bfirst = start.traverse(branch_first=True)
- assert dfirst.next() == p0
- assert dfirst.next() == p00
+ assert next(dfirst) == p0
+ assert next(dfirst) == p00
- assert bfirst.next() == p0
- assert bfirst.next() == p1
- assert bfirst.next() == p00
- assert bfirst.next() == p10
+ assert next(bfirst) == p0
+ assert next(bfirst) == p1
+ assert next(bfirst) == p00
+ assert next(bfirst) == p10
# at some point, both iterations should stop
assert list(bfirst)[-1] == first
@@ -161,19 +161,19 @@ class TestCommit(TestBase):
assert len(l[0]) == 2
# ignore self
- assert start.traverse(ignore_self=False).next() == start
+ assert next(start.traverse(ignore_self=False)) == start
# depth
assert len(list(start.traverse(ignore_self=False, depth=0))) == 1
# prune
- assert start.traverse(branch_first=1, prune=lambda i, d: i == p0).next() == p1
+ assert next(start.traverse(branch_first=1, prune=lambda i, d: i == p0)) == p1
# predicate
- assert start.traverse(branch_first=1, predicate=lambda i, d: i == p1).next() == p1
+ assert next(start.traverse(branch_first=1, predicate=lambda i, d: i == p1)) == p1
# traversal should stop when the beginning is reached
- self.failUnlessRaises(StopIteration, first.traverse().next)
+ self.failUnlessRaises(StopIteration, next, first.traverse())
# parents of the first commit should be empty ( as the only parent has a null
# sha )
@@ -210,7 +210,7 @@ class TestCommit(TestBase):
first_parent=True,
bisect_all=True)
- commits = Commit._iter_from_process_or_stream(self.rorepo, StringProcessAdapter(revs))
+ commits = Commit._iter_from_process_or_stream(self.rorepo, StringProcessAdapter(revs.encode('ascii')))
expected_ids = (
'7156cece3c49544abb6bf7a0c218eb36646fad6d',
'1f66cfbbce58b4b552b041707a12d437cc5f400a',
@@ -224,8 +224,10 @@ class TestCommit(TestBase):
assert self.rorepo.tag('refs/tags/0.1.5').commit.count() == 143
def test_list(self):
+ # This doesn't work anymore, as we will either attempt getattr with bytes, or compare 20 byte string
+ # with actual 20 byte bytes. This usage makes no sense anyway
assert isinstance(Commit.list_items(self.rorepo, '0.1.5', max_count=5)[
- hex_to_bin('5117c9c8a4d3af19a9958677e45cda9269de1541')], Commit)
+ '5117c9c8a4d3af19a9958677e45cda9269de1541'], Commit)
def test_str(self):
commit = Commit(self.rorepo, Commit.NULL_BIN_SHA)
@@ -247,12 +249,12 @@ class TestCommit(TestBase):
c = self.rorepo.commit('0.1.5')
for skip in (0, 1):
piter = c.iter_parents(skip=skip)
- first_parent = piter.next()
+ first_parent = next(piter)
assert first_parent != c
assert first_parent == c.parents[0]
# END for each
- def test_base(self):
+ def test_name_rev(self):
name_rev = self.rorepo.head.commit.name_rev
assert isinstance(name_rev, string_types)
@@ -270,10 +272,10 @@ class TestCommit(TestBase):
assert isinstance(cmt.message, text_type) # it automatically decodes it as such
assert isinstance(cmt.author.name, text_type) # same here
- cmt.message = "üäêèß".decode("utf-8")
+ cmt.message = u"üäêèß"
assert len(cmt.message) == 5
- cmt.author.name = "äüß".decode("utf-8")
+ cmt.author.name = u"äüß"
assert len(cmt.author.name) == 3
cstream = BytesIO()
@@ -292,7 +294,7 @@ class TestCommit(TestBase):
def test_gpgsig(self):
cmt = self.rorepo.commit()
- cmt._deserialize(open(fixture_path('commit_with_gpgsig')))
+ cmt._deserialize(open(fixture_path('commit_with_gpgsig'), 'rb'))
fixture_sig = """-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
@@ -318,7 +320,7 @@ JzJMZDRLQLFvnzqZuCjE
cstream = BytesIO()
cmt._serialize(cstream)
- assert re.search(r"^gpgsig <test\n dummy\n sig>$", cstream.getvalue(), re.MULTILINE)
+ assert re.search(r"^gpgsig <test\n dummy\n sig>$", cstream.getvalue().decode('ascii'), re.MULTILINE)
cstream.seek(0)
cmt.gpgsig = None
@@ -328,4 +330,4 @@ JzJMZDRLQLFvnzqZuCjE
cmt.gpgsig = None
cstream = BytesIO()
cmt._serialize(cstream)
- assert not re.search(r"^gpgsig ", cstream.getvalue(), re.MULTILINE)
+ assert not re.search(r"^gpgsig ", cstream.getvalue().decode('ascii'), re.MULTILINE)