Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita05e49d

Browse files
committed
test_repo works
1 parent60e5413 commita05e49d

File tree

13 files changed

+106
-45
lines changed

13 files changed

+106
-45
lines changed

‎doc/source/changes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Changelog
66
========================
77
* Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes.
88
* 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.
9+
* **IMPORTANT**: If you were using the config_writer(), you implicitly relied on __del__ to work as expected to flush changes. To be sure changes are flushed under PY3, you will have to call the new `release()` method to trigger a flush. For some reason, __del__ is not called necessarily anymore when a symbol goes out of scope.
910

1011
0.3.3
1112
=====

‎git/cmd.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
fromgit.compatimport (
2323
text_type,
2424
string_types,
25-
defenc
25+
defenc,
26+
PY3
2627
)
2728

2829
execute_kwargs= ('istream','with_keep_cwd','with_extended_output',
@@ -372,8 +373,8 @@ def execute(self, command,
372373

373374
# Wait for the process to return
374375
status=0
375-
stdout_value=''
376-
stderr_value=''
376+
stdout_value=b''
377+
stderr_value=b''
377378
try:
378379
ifoutput_streamisNone:
379380
stdout_value,stderr_value=proc.communicate()
@@ -388,7 +389,7 @@ def execute(self, command,
388389
stdout_value=output_stream
389390
stderr_value=proc.stderr.read()
390391
# strip trailing "\n"
391-
ifstderr_value.endswith("\n"):
392+
ifstderr_value.endswith(b"\n"):
392393
stderr_value=stderr_value[:-1]
393394
status=proc.wait()
394395
# END stdout handling
@@ -444,15 +445,17 @@ def transform_kwargs(self, split_single_char_options=False, **kwargs):
444445
@classmethod
445446
def__unpack_args(cls,arg_list):
446447
ifnotisinstance(arg_list, (list,tuple)):
447-
ifisinstance(arg_list,text_type):
448+
# This is just required for unicode conversion, as subprocess can't handle it
449+
# However, in any other case, passing strings (usually utf-8 encoded) is totally fine
450+
ifnotPY3andisinstance(arg_list,unicode):
448451
return [arg_list.encode(defenc)]
449452
return [str(arg_list)]
450453

451454
outlist=list()
452455
forarginarg_list:
453456
ifisinstance(arg_list, (list,tuple)):
454457
outlist.extend(cls.__unpack_args(arg))
455-
elifisinstance(arg_list,text_type):
458+
elifnotPY3andisinstance(arg_list,unicode):
456459
outlist.append(arg_list.encode(defenc))
457460
# END recursion
458461
else:
@@ -509,8 +512,8 @@ def _call_process(self, method, *args, **kwargs):
509512

510513
# Prepare the argument list
511514
opt_args=self.transform_kwargs(**kwargs)
512-
513515
ext_args=self.__unpack_args([aforainargsifaisnotNone])
516+
514517
args=opt_args+ext_args
515518

516519
defmake_call():

‎git/config.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,7 @@ def __del__(self):
103103
# Yes, for some reason, we have to call it explicitly for it to work in PY3 !
104104
# Apparently __del__ doesn't get call anymore if refcount becomes 0
105105
# Ridiculous ... .
106-
self._config.__del__()
107-
# del self._config
106+
self._config.release()
108107

109108
def__getattr__(self,attr):
110109
ifattrinself._valid_attrs_:
@@ -121,6 +120,10 @@ def config(self):
121120
"""return: Configparser instance we constrain"""
122121
returnself._config
123122

123+
defrelease(self):
124+
"""Equivalent to GitConfigParser.release(), which is called on our underlying parser instance"""
125+
returnself._config.release()
126+
124127

125128
classGitConfigParser(with_metaclass(MetaParserBuilder,cp.RawConfigParser,object)):
126129

@@ -198,6 +201,13 @@ def __init__(self, file_or_files, read_only=True):
198201

199202
def__del__(self):
200203
"""Write pending changes if required and release locks"""
204+
# NOTE: only consistent in PY2
205+
self.release()
206+
207+
defrelease(self):
208+
"""Flush changes and release the configuration write lock. This instance must not be used anymore afterwards.
209+
In Python 3, it's required to explicitly release locks and flush changes, as __del__ is not called
210+
deterministically anymore."""
201211
# checking for the lock here makes sure we do not raise during write()
202212
# in case an invalid parser was created who could not get a lock
203213
ifself.read_onlyor (self._lockandnotself._lock._has_lock()):

‎git/exc.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
fromgitdb.excimport*# NOQA
99

10+
fromgit.compatimportdefenc
11+
1012

1113
classInvalidGitRepositoryError(Exception):
1214

@@ -32,9 +34,9 @@ def __str__(self):
3234
ret="'%s' returned with exit code %i"% \
3335
(' '.join(str(i)foriinself.command),self.status)
3436
ifself.stderr:
35-
ret+="\nstderr: '%s'"%self.stderr
37+
ret+="\nstderr: '%s'"%self.stderr.decode(defenc)
3638
ifself.stdout:
37-
ret+="\nstdout: '%s'"%self.stdout
39+
ret+="\nstdout: '%s'"%self.stdout.decode(defenc)
3840
returnret
3941

4042

‎git/objects/submodule/base.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
rmtree
1818
)
1919

20-
fromgit.configimportSectionConstraint
20+
fromgit.configimport (
21+
SectionConstraint,
22+
cp
23+
)
2124
fromgit.excimport (
2225
InvalidGitRepositoryError,
2326
NoSuchPathError
@@ -302,6 +305,7 @@ def add(cls, repo, name, path, url=None, branch=None, no_checkout=False):
302305
writer.set_value(cls.k_head_option,br.path)
303306
sm._branch_path=br.path
304307
# END handle path
308+
writer.release()
305309
del(writer)
306310

307311
# we deliberatly assume that our head matches our index !
@@ -419,7 +423,9 @@ def update(self, recursive=False, init=True, to_latest_revision=False, progress=
419423
# the default implementation will be offended and not update the repository
420424
# Maybe this is a good way to assure it doesn't get into our way, but
421425
# we want to stay backwards compatible too ... . Its so redundant !
422-
self.repo.config_writer().set_value(sm_section(self.name),'url',self.url)
426+
writer=self.repo.config_writer()
427+
writer.set_value(sm_section(self.name),'url',self.url)
428+
writer.release()
423429
# END handle dry_run
424430
# END handle initalization
425431

@@ -576,6 +582,7 @@ def move(self, module_path, configuration=True, module=True):
576582
writer=self.config_writer(index=index)# auto-write
577583
writer.set_value('path',module_path)
578584
self.path=module_path
585+
writer.release()
579586
del(writer)
580587
# END handle configuration flag
581588
exceptException:
@@ -700,8 +707,12 @@ def remove(self, module=True, force=False, configuration=True, dry_run=False):
700707

701708
# now git config - need the config intact, otherwise we can't query
702709
# inforamtion anymore
703-
self.repo.config_writer().remove_section(sm_section(self.name))
704-
self.config_writer().remove_section()
710+
writer=self.repo.config_writer()
711+
writer.remove_section(sm_section(self.name))
712+
writer.release()
713+
writer=self.config_writer()
714+
writer.remove_section()
715+
writer.release()
705716
# END delete configuration
706717

707718
# void our data not to delay invalid access
@@ -800,14 +811,18 @@ def exists(self):
800811
"""
801812
:return: True if the submodule exists, False otherwise. Please note that
802813
a submodule may exist (in the .gitmodules file) even though its module
803-
doesn't exist"""
814+
doesn't exist on disk"""
804815
# keep attributes for later, and restore them if we have no valid data
805816
# this way we do not actually alter the state of the object
806817
loc=locals()
807818
forattrinself._cache_attrs:
808-
ifhasattr(self,attr):
809-
loc[attr]=getattr(self,attr)
810-
# END if we have the attribute cache
819+
try:
820+
ifhasattr(self,attr):
821+
loc[attr]=getattr(self,attr)
822+
# END if we have the attribute cache
823+
exceptcp.NoSectionError:
824+
# on PY3, this can happen apparently ... don't know why this doesn't happen on PY2
825+
pass
811826
# END for each attr
812827
self._clear_cache()
813828

‎git/refs/head.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ def set_tracking_branch(self, remote_reference):
148148
writer.set_value(self.k_config_remote,remote_reference.remote_name)
149149
writer.set_value(self.k_config_remote_ref,Head.to_full_path(remote_reference.remote_head))
150150
# END handle ref value
151+
writer.release()
151152

152153
returnself
153154

‎git/repo/base.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ def untracked_files(self):
551551
prefix="?? "
552552
untracked_files=list()
553553
forlineinproc.stdout:
554+
line=line.decode(defenc)
554555
ifnotline.startswith(prefix):
555556
continue
556557
filename=line[len(prefix):].rstrip('\n')
@@ -735,7 +736,7 @@ def _clone(cls, git, url, path, odb_default_type, progress, **kwargs):
735736
writer=repo.remotes[0].config_writer
736737
writer.set_value('url',repo.remotes[0].url.replace("\\\\","\\").replace("\\","/"))
737738
# PY3: be sure cleanup is performed and lock is released
738-
delwriter
739+
writer.release()
739740
# END handle remote repo
740741
returnrepo
741742

@@ -767,7 +768,7 @@ def clone_from(cls, url, to_path, progress=None, **kwargs):
767768

768769
defarchive(self,ostream,treeish=None,prefix=None,**kwargs):
769770
"""Archive the tree at the given revision.
770-
:parm ostream: file compatible stream object to which the archive will be written
771+
:parm ostream: file compatible stream object to which the archive will be written as bytes
771772
:parm treeish: is the treeish name/id, defaults to active branch
772773
:parm prefix: is the optional prefix to prepend to each filename in the archive
773774
:parm kwargs:

‎git/repo/fun.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def to_commit(obj):
150150
defrev_parse(repo,rev):
151151
"""
152152
:return: Object at the given revision, either Commit, Tag, Tree or Blob
153-
:param rev: git-rev-parse compatible revision specification, please see
153+
:param rev: git-rev-parse compatible revision specification as string, please see
154154
http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html
155155
for details
156156
:note: Currently there is no access to the rev-log, rev-specs may only contain

‎git/test/lib/helper.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ def remote_repo_creator(self):
179179
pass
180180
crw.set(section,"receivepack",True)
181181
# release lock
182+
crw.release()
182183
del(crw)
183184

184185
# initialize the remote - first do it as local remote and pull, then

‎git/test/test_index.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ def test_index_mutation(self, rw_repo):
382382
writer=rw_repo.config_writer()
383383
writer.set_value("user","name",uname)
384384
writer.set_value("user","email",umail)
385+
writer.release()
385386

386387
# remove all of the files, provide a wild mix of paths, BaseIndexEntries,
387388
# IndexEntries

‎git/test/test_refs.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,11 @@ def test_heads(self, rwrepo):
105105
tv="testopt"
106106
writer.set_value(tv,1)
107107
assertwriter.get_value(tv)==1
108-
del(writer)
108+
writer.release()
109109
asserthead.config_reader().get_value(tv)==1
110-
head.config_writer().remove_option(tv)
110+
writer=head.config_writer()
111+
writer.remove_option(tv)
112+
writer.release()
111113

112114
# after the clone, we might still have a tracking branch setup
113115
head.set_tracking_branch(None)

‎git/test/test_repo.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
fromgit.utilimportjoin_path_native
3131
fromgit.excimportBadObject
3232
fromgitdb.utilimportbin_to_hex
33-
fromgit.compatimportstring_types
33+
fromgit.compatimport (
34+
string_types,
35+
defenc
36+
)
3437

3538
importos
3639
importsys
@@ -259,13 +262,16 @@ def test_tag(self):
259262
assertself.rorepo.tag('refs/tags/0.1.5').commit
260263

261264
deftest_archive(self):
262-
tmpfile=os.tmpfile()
263-
self.rorepo.archive(tmpfile,'0.1.5')
264-
asserttmpfile.tell()
265+
tmpfile=tempfile.mktemp(suffix='archive-test')
266+
stream=open(tmpfile,'wb')
267+
self.rorepo.archive(stream,'0.1.5')
268+
assertstream.tell()
269+
stream.close()
270+
os.remove(tmpfile)
265271

266272
@patch.object(Git,'_call_process')
267273
deftest_should_display_blame_information(self,git):
268-
git.return_value=fixture('blame')
274+
git.return_value=fixture('blame').decode(defenc)
269275
b=self.rorepo.blame('master','lib/git.py')
270276
assert_equal(13,len(b))
271277
assert_equal(2,len(b[0]))
@@ -336,6 +342,7 @@ def test_config_writer(self):
336342
try:
337343
writer=self.rorepo.config_writer(config_level)
338344
assertnotwriter.read_only
345+
writer.release()
339346
exceptIOError:
340347
# its okay not to get a writer for some configuration files if we
341348
# have no permissions
@@ -350,7 +357,8 @@ def test_creation_deletion(self):
350357

351358
tag=self.rorepo.create_tag("new_tag","HEAD~2")
352359
self.rorepo.delete_tag(tag)
353-
self.rorepo.config_writer()
360+
writer=self.rorepo.config_writer()
361+
writer.release()
354362
remote=self.rorepo.create_remote("new_remote","git@server:repo.git")
355363
self.rorepo.delete_remote(remote)
356364

@@ -365,7 +373,7 @@ def test_git_cmd(self):
365373
l1=b"0123456789\n"
366374
l2=b"abcdefghijklmnopqrstxy\n"
367375
l3=b"z\n"
368-
d=b"%s%s%s\n"% (l1,l2,l3)
376+
d=l1+l2+l3+b"\n"
369377

370378
l1p=l1[:5]
371379

@@ -382,7 +390,7 @@ def mktiny():
382390
# readlines no limit
383391
s=mkfull()
384392
lines=s.readlines()
385-
assertlen(lines)==3andlines[-1].endswith('\n')
393+
assertlen(lines)==3andlines[-1].endswith(b'\n')
386394
asserts._stream.tell()==len(d)# must have scrubbed to the end
387395

388396
# realines line limit
@@ -566,7 +574,7 @@ def test_rev_parse(self):
566574
# try partial parsing
567575
max_items=40
568576
fori,binshainenumerate(self.rorepo.odb.sha_iter()):
569-
assertrev_parse(bin_to_hex(binsha)[:8- (i%2)]).binsha==binsha
577+
assertrev_parse(bin_to_hex(binsha)[:8- (i%2)].decode('ascii')).binsha==binsha
570578
ifi>max_items:
571579
# this is rather slow currently, as rev_parse returns an object
572580
# which requires accessing packs, it has some additional overhead
@@ -645,6 +653,6 @@ def test_git_file(self, rwrepo):
645653
assertos.path.abspath(git_file_repo.git_dir)==real_path_abs
646654

647655
# Test using an absolute gitdir path in the .git file.
648-
open(git_file_path,'wb').write('gitdir: %s\n'%real_path_abs)
656+
open(git_file_path,'wb').write(('gitdir: %s\n'%real_path_abs).encode('ascii'))
649657
git_file_repo=Repo(rwrepo.working_tree_dir)
650658
assertos.path.abspath(git_file_repo.git_dir)==real_path_abs

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp