Skip to content

Commit e1060a2

Browse files
committed
test_commit works once again
1 parent 8a30861 commit e1060a2

File tree

10 files changed

+55
-39
lines changed

10 files changed

+55
-39
lines changed

doc/source/changes.rst

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Changelog
55
0.3.4 - python 3 support
66
========================
77
* Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes.
8+
* 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.
89

910
0.3.3
1011
=====

git/cmd.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ def execute(self, command,
320320
always be created with a pipe due to issues with subprocess.
321321
This merely is a workaround as data will be copied from the
322322
output pipe to the given output stream directly.
323+
Judging from the implementation, you shouldn't use this flag !
323324
324325
:param subprocess_kwargs:
325326
Keyword arguments to be passed to subprocess.Popen. Please note that
@@ -411,9 +412,13 @@ def execute(self, command,
411412
else:
412413
raise GitCommandError(command, status, stderr_value)
413414

415+
416+
if isinstance(stdout_value, bytes): # could also be output_stream
417+
stdout_value = stdout_value.decode(defenc)
418+
414419
# Allow access to the command's status code
415420
if with_extended_output:
416-
return (status, stdout_value, stderr_value)
421+
return (status, stdout_value, stderr_value.decode(defenc))
417422
else:
418423
return stdout_value
419424

git/config.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ def __del__(self):
201201
self.write()
202202
except IOError:
203203
log.error("Exception during destruction of GitConfigParser", exc_info=True)
204+
except ReferenceError:
205+
# This happens in PY3 ... and usually means that some state cannot be written
206+
# as the sections dict cannot be iterated
207+
# Usually when shutting down the interpreter, don'y know how to fix this
208+
pass
204209
finally:
205210
self._lock._release_lock()
206211

@@ -345,7 +350,7 @@ def write(self):
345350
# END get lock for physical files
346351

347352
if not hasattr(fp, "seek"):
348-
fp = open(self._file_or_files, "w")
353+
fp = open(self._file_or_files, "wb")
349354
close_fp = True
350355
else:
351356
fp.seek(0)

git/diff.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ class Diff(object):
195195
""", re.VERBOSE | re.MULTILINE)
196196
# can be used for comparisons
197197
NULL_HEX_SHA = "0" * 40
198-
NULL_BIN_SHA = "\0" * 20
198+
NULL_BIN_SHA = b"\0" * 20
199199

200200
__slots__ = ("a_blob", "b_blob", "a_mode", "b_mode", "new_file", "deleted_file",
201201
"rename_from", "rename_to", "diff")

git/objects/base.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class Object(LazyMixin):
2121

2222
"""Implements an Object which may be Blobs, Trees, Commits and Tags"""
2323
NULL_HEX_SHA = '0' * 40
24-
NULL_BIN_SHA = '\0' * 20
24+
NULL_BIN_SHA = b'\0' * 20
2525

2626
TYPES = (dbtyp.str_blob_type, dbtyp.str_tree_type, dbtyp.str_commit_type, dbtyp.str_tag_type)
2727
__slots__ = ("repo", "binsha", "size")
@@ -94,7 +94,7 @@ def __hash__(self):
9494

9595
def __str__(self):
9696
""":return: string of our SHA1 as understood by all git commands"""
97-
return bin_to_hex(self.binsha)
97+
return self.hexsha
9898

9999
def __repr__(self):
100100
""":return: string with pythonic representation of our object"""
@@ -103,7 +103,8 @@ def __repr__(self):
103103
@property
104104
def hexsha(self):
105105
""":return: 40 byte hex version of our 20 byte binary sha"""
106-
return bin_to_hex(self.binsha)
106+
# b2a_hex produces bytes
107+
return bin_to_hex(self.binsha).decode('ascii')
107108

108109
@property
109110
def data_stream(self):

git/objects/commit.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class Commit(base.Object, Iterable, Diffable, Traversable, Serializable):
6262
"author", "authored_date", "author_tz_offset",
6363
"committer", "committed_date", "committer_tz_offset",
6464
"message", "parents", "encoding", "gpgsig")
65-
_id_attribute_ = "binsha"
65+
_id_attribute_ = "hexsha"
6666

6767
def __init__(self, repo, binsha, tree=None, author=None, authored_date=None, author_tz_offset=None,
6868
committer=None, committed_date=None, committer_tz_offset=None,
@@ -395,7 +395,7 @@ def _serialize(self, stream):
395395
write(("encoding %s\n" % self.encoding).encode('ascii'))
396396

397397
if self.gpgsig:
398-
write("gpgsig")
398+
write(b"gpgsig")
399399
for sigline in self.gpgsig.rstrip("\n").split("\n"):
400400
write((" " + sigline + "\n").encode('ascii'))
401401

git/objects/fun.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
from stat import S_ISDIR
33
from git.compat import (
44
byte_ord,
5-
force_bytes,
65
defenc,
76
xrange,
87
text_type
@@ -37,7 +36,7 @@ def tree_to_stream(entries, write):
3736
# takes the input literally, which appears to be utf8 on linux.
3837
if isinstance(name, text_type):
3938
name = name.encode(defenc)
40-
write(b''.join(mode_str, b' ', name, b'\0', binsha))
39+
write(b''.join((mode_str, b' ', name, b'\0', binsha)))
4140
# END for each item
4241

4342
def tree_entries_from_data(data):

git/refs/symbolic.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ def set_reference(self, ref, logmsg=None):
308308

309309
lfd = LockedFD(fpath)
310310
fd = lfd.open(write=True, stream=True)
311-
fd.write(write_value)
311+
fd.write(write_value.encode('ascii'))
312312
lfd.commit()
313313

314314
# Adjust the reflog

git/repo/base.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@
4747
read_gitfile,
4848
touch,
4949
)
50-
from git.compat import text_type
50+
from git.compat import (
51+
text_type,
52+
defenc
53+
)
5154

5255
import os
5356
import sys
@@ -177,11 +180,11 @@ def __hash__(self):
177180
# Description property
178181
def _get_description(self):
179182
filename = join(self.git_dir, 'description')
180-
return open(filename).read().rstrip()
183+
return open(filename, 'rb').read().rstrip().decode(defenc)
181184

182185
def _set_description(self, descr):
183186
filename = join(self.git_dir, 'description')
184-
open(filename, 'w').write(descr + '\n')
187+
open(filename, 'wb').write((descr + '\n').encode(defenc))
185188

186189
description = property(_get_description, _set_description,
187190
doc="the project's description")
@@ -464,8 +467,8 @@ def _get_alternates(self):
464467

465468
if os.path.exists(alternates_path):
466469
try:
467-
f = open(alternates_path)
468-
alts = f.read()
470+
f = open(alternates_path, 'rb')
471+
alts = f.read().decode(defenc)
469472
finally:
470473
f.close()
471474
return alts.strip().splitlines()
@@ -489,8 +492,8 @@ def _set_alternates(self, alts):
489492
os.remove(alternates_path)
490493
else:
491494
try:
492-
f = open(alternates_path, 'w')
493-
f.write("\n".join(alts))
495+
f = open(alternates_path, 'wb')
496+
f.write("\n".join(alts).encode(defenc))
494497
finally:
495498
f.close()
496499
# END file handling

git/test/test_commit.py

+23-21
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False)
5151
stream.seek(0)
5252

5353
istream = rwrepo.odb.store(IStream(Commit.type, streamlen, stream))
54-
assert istream.hexsha == cm.hexsha
54+
assert istream.hexsha == cm.hexsha.encode('ascii')
5555

5656
nc = Commit(rwrepo, Commit.NULL_BIN_SHA, cm.tree,
5757
cm.author, cm.authored_date, cm.author_tz_offset,
@@ -129,7 +129,7 @@ def check_entries(d):
129129

130130
def test_unicode_actor(self):
131131
# assure we can parse unicode actors correctly
132-
name = "Üäöß ÄußÉ".decode("utf-8")
132+
name = u"Üäöß ÄußÉ"
133133
assert len(name) == 9
134134
special = Actor._from_string(u"%s <[email protected]>" % name)
135135
assert special.name == name
@@ -146,13 +146,13 @@ def test_traversal(self):
146146
# basic branch first, depth first
147147
dfirst = start.traverse(branch_first=False)
148148
bfirst = start.traverse(branch_first=True)
149-
assert dfirst.next() == p0
150-
assert dfirst.next() == p00
149+
assert next(dfirst) == p0
150+
assert next(dfirst) == p00
151151

152-
assert bfirst.next() == p0
153-
assert bfirst.next() == p1
154-
assert bfirst.next() == p00
155-
assert bfirst.next() == p10
152+
assert next(bfirst) == p0
153+
assert next(bfirst) == p1
154+
assert next(bfirst) == p00
155+
assert next(bfirst) == p10
156156

157157
# at some point, both iterations should stop
158158
assert list(bfirst)[-1] == first
@@ -161,19 +161,19 @@ def test_traversal(self):
161161
assert len(l[0]) == 2
162162

163163
# ignore self
164-
assert start.traverse(ignore_self=False).next() == start
164+
assert next(start.traverse(ignore_self=False)) == start
165165

166166
# depth
167167
assert len(list(start.traverse(ignore_self=False, depth=0))) == 1
168168

169169
# prune
170-
assert start.traverse(branch_first=1, prune=lambda i, d: i == p0).next() == p1
170+
assert next(start.traverse(branch_first=1, prune=lambda i, d: i == p0)) == p1
171171

172172
# predicate
173-
assert start.traverse(branch_first=1, predicate=lambda i, d: i == p1).next() == p1
173+
assert next(start.traverse(branch_first=1, predicate=lambda i, d: i == p1)) == p1
174174

175175
# traversal should stop when the beginning is reached
176-
self.failUnlessRaises(StopIteration, first.traverse().next)
176+
self.failUnlessRaises(StopIteration, next, first.traverse())
177177

178178
# parents of the first commit should be empty ( as the only parent has a null
179179
# sha )
@@ -210,7 +210,7 @@ def test_rev_list_bisect_all(self):
210210
first_parent=True,
211211
bisect_all=True)
212212

213-
commits = Commit._iter_from_process_or_stream(self.rorepo, StringProcessAdapter(revs))
213+
commits = Commit._iter_from_process_or_stream(self.rorepo, StringProcessAdapter(revs.encode('ascii')))
214214
expected_ids = (
215215
'7156cece3c49544abb6bf7a0c218eb36646fad6d',
216216
'1f66cfbbce58b4b552b041707a12d437cc5f400a',
@@ -224,8 +224,10 @@ def test_count(self):
224224
assert self.rorepo.tag('refs/tags/0.1.5').commit.count() == 143
225225

226226
def test_list(self):
227+
# This doesn't work anymore, as we will either attempt getattr with bytes, or compare 20 byte string
228+
# with actual 20 byte bytes. This usage makes no sense anyway
227229
assert isinstance(Commit.list_items(self.rorepo, '0.1.5', max_count=5)[
228-
hex_to_bin('5117c9c8a4d3af19a9958677e45cda9269de1541')], Commit)
230+
'5117c9c8a4d3af19a9958677e45cda9269de1541'], Commit)
229231

230232
def test_str(self):
231233
commit = Commit(self.rorepo, Commit.NULL_BIN_SHA)
@@ -247,12 +249,12 @@ def test_iter_parents(self):
247249
c = self.rorepo.commit('0.1.5')
248250
for skip in (0, 1):
249251
piter = c.iter_parents(skip=skip)
250-
first_parent = piter.next()
252+
first_parent = next(piter)
251253
assert first_parent != c
252254
assert first_parent == c.parents[0]
253255
# END for each
254256

255-
def test_base(self):
257+
def test_name_rev(self):
256258
name_rev = self.rorepo.head.commit.name_rev
257259
assert isinstance(name_rev, string_types)
258260

@@ -270,10 +272,10 @@ def test_serialization_unicode_support(self):
270272
assert isinstance(cmt.message, text_type) # it automatically decodes it as such
271273
assert isinstance(cmt.author.name, text_type) # same here
272274

273-
cmt.message = "üäêèß".decode("utf-8")
275+
cmt.message = u"üäêèß"
274276
assert len(cmt.message) == 5
275277

276-
cmt.author.name = "äüß".decode("utf-8")
278+
cmt.author.name = u"äüß"
277279
assert len(cmt.author.name) == 3
278280

279281
cstream = BytesIO()
@@ -292,7 +294,7 @@ def test_serialization_unicode_support(self):
292294

293295
def test_gpgsig(self):
294296
cmt = self.rorepo.commit()
295-
cmt._deserialize(open(fixture_path('commit_with_gpgsig')))
297+
cmt._deserialize(open(fixture_path('commit_with_gpgsig'), 'rb'))
296298

297299
fixture_sig = """-----BEGIN PGP SIGNATURE-----
298300
Version: GnuPG v1.4.11 (GNU/Linux)
@@ -318,7 +320,7 @@ def test_gpgsig(self):
318320

319321
cstream = BytesIO()
320322
cmt._serialize(cstream)
321-
assert re.search(r"^gpgsig <test\n dummy\n sig>$", cstream.getvalue(), re.MULTILINE)
323+
assert re.search(r"^gpgsig <test\n dummy\n sig>$", cstream.getvalue().decode('ascii'), re.MULTILINE)
322324

323325
cstream.seek(0)
324326
cmt.gpgsig = None
@@ -328,4 +330,4 @@ def test_gpgsig(self):
328330
cmt.gpgsig = None
329331
cstream = BytesIO()
330332
cmt._serialize(cstream)
331-
assert not re.search(r"^gpgsig ", cstream.getvalue(), re.MULTILINE)
333+
assert not re.search(r"^gpgsig ", cstream.getvalue().decode('ascii'), re.MULTILINE)

0 commit comments

Comments
 (0)