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

Commit04357d0

Browse files
committed
Intermediate commit: test_config and test_actor works
Kind of tackling the tasks step by step, picking low-hanging fruit first,or the ones that everyone depends on
1 parentbc8c912 commit04357d0

File tree

8 files changed

+114
-63
lines changed

8 files changed

+114
-63
lines changed

‎doc/source/changes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
Changelog
33
=========
44

5+
0.3.4 - python 3 support
6+
========================
7+
* Internally, hexadecimal SHA1 are treated as ascii encoded strings. Binary SHA1 are treated as bytes.
8+
59
0.3.3
610
=====
711
* When fetching, pulling or pushing, and an error occours, it will not be reported on stdout anymore. However, if there is a fatal error, it will still result in a GitCommandError to be thrown. This goes hand in hand with improved fetch result parsing.

‎git/cmd.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
stream_copy
2020
)
2121
from .excimportGitCommandError
22-
fromgit.compatimporttext_type
22+
fromgit.compatimport (
23+
text_type,
24+
string_types,
25+
defenc
26+
)
2327

2428
execute_kwargs= ('istream','with_keep_cwd','with_extended_output',
2529
'with_exceptions','as_process',
@@ -373,9 +377,9 @@ def execute(self, command,
373377
ifoutput_streamisNone:
374378
stdout_value,stderr_value=proc.communicate()
375379
# strip trailing "\n"
376-
ifstdout_value.endswith("\n"):
380+
ifstdout_value.endswith(b"\n"):
377381
stdout_value=stdout_value[:-1]
378-
ifstderr_value.endswith("\n"):
382+
ifstderr_value.endswith(b"\n"):
379383
stderr_value=stderr_value[:-1]
380384
status=proc.returncode
381385
else:
@@ -394,9 +398,9 @@ def execute(self, command,
394398
ifself.GIT_PYTHON_TRACE=='full':
395399
cmdstr=" ".join(command)
396400
ifstderr_value:
397-
log.info("%s -> %d; stdout: '%s'; stderr: '%s'",cmdstr,status,stdout_value,stderr_value)
401+
log.info("%s -> %d; stdout: '%s'; stderr: '%s'",cmdstr,status,stdout_value.decode(defenc),stderr_value.decode(defenc))
398402
elifstdout_value:
399-
log.info("%s -> %d; stdout: '%s'",cmdstr,status,stdout_value)
403+
log.info("%s -> %d; stdout: '%s'",cmdstr,status,stdout_value.decode(defenc))
400404
else:
401405
log.info("%s -> %d",cmdstr,status)
402406
# END handle debug printing
@@ -436,15 +440,15 @@ def transform_kwargs(self, split_single_char_options=False, **kwargs):
436440
def__unpack_args(cls,arg_list):
437441
ifnotisinstance(arg_list, (list,tuple)):
438442
ifisinstance(arg_list,text_type):
439-
return [arg_list.encode('utf-8')]
443+
return [arg_list.encode(defenc)]
440444
return [str(arg_list)]
441445

442446
outlist=list()
443447
forarginarg_list:
444448
ifisinstance(arg_list, (list,tuple)):
445449
outlist.extend(cls.__unpack_args(arg))
446450
elifisinstance(arg_list,text_type):
447-
outlist.append(arg_list.encode('utf-8'))
451+
outlist.append(arg_list.encode(defenc))
448452
# END recursion
449453
else:
450454
outlist.append(str(arg))
@@ -569,14 +573,20 @@ def _parse_object_header(self, header_line):
569573
raiseValueError("Failed to parse header: %r"%header_line)
570574
return (tokens[0],tokens[1],int(tokens[2]))
571575

572-
def__prepare_ref(self,ref):
573-
# required for command to separate refs on stdin
574-
refstr=str(ref)# could be ref-object
575-
ifrefstr.endswith("\n"):
576-
returnrefstr
577-
returnrefstr+"\n"
576+
def_prepare_ref(self,ref):
577+
# required for command to separate refs on stdin, as bytes
578+
refstr=ref
579+
ifisinstance(ref,bytes):
580+
# Assume 40 bytes hexsha - bin-to-ascii for some reason returns bytes, not text
581+
refstr=ref.decode('ascii')
582+
elifnotisinstance(ref,string_types):
583+
refstr=str(ref)# could be ref-object
584+
585+
ifnotrefstr.endswith("\n"):
586+
refstr+="\n"
587+
returnrefstr.encode(defenc)
578588

579-
def__get_persistent_cmd(self,attr_name,cmd_name,*args,**kwargs):
589+
def_get_persistent_cmd(self,attr_name,cmd_name,*args,**kwargs):
580590
cur_val=getattr(self,attr_name)
581591
ifcur_valisnotNone:
582592
returncur_val
@@ -589,7 +599,7 @@ def __get_persistent_cmd(self, attr_name, cmd_name, *args, **kwargs):
589599
returncmd
590600

591601
def__get_object_header(self,cmd,ref):
592-
cmd.stdin.write(self.__prepare_ref(ref))
602+
cmd.stdin.write(self._prepare_ref(ref))
593603
cmd.stdin.flush()
594604
returnself._parse_object_header(cmd.stdout.readline())
595605

@@ -601,7 +611,7 @@ def get_object_header(self, ref):
601611
once and reuses the command in subsequent calls.
602612
603613
:return: (hexsha, type_string, size_as_int)"""
604-
cmd=self.__get_persistent_cmd("cat_file_header","cat_file",batch_check=True)
614+
cmd=self._get_persistent_cmd("cat_file_header","cat_file",batch_check=True)
605615
returnself.__get_object_header(cmd,ref)
606616

607617
defget_object_data(self,ref):
@@ -618,7 +628,7 @@ def stream_object_data(self, ref):
618628
:return: (hexsha, type_string, size_as_int, stream)
619629
:note: This method is not threadsafe, you need one independent Command instance
620630
per thread to be safe !"""
621-
cmd=self.__get_persistent_cmd("cat_file_all","cat_file",batch=True)
631+
cmd=self._get_persistent_cmd("cat_file_all","cat_file",batch=True)
622632
hexsha,typename,size=self.__get_object_header(cmd,ref)
623633
return (hexsha,typename,size,self.CatFileContentStream(size,cmd.stdout))
624634

‎git/compat.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
"""utilities to help provide compatibility with python 3"""
88
# flake8: noqa
99

10+
importsys
11+
1012
fromgitdb.utils.compatimport (
1113
PY3,
1214
xrange,
@@ -17,11 +19,39 @@
1719
fromgitdb.utils.encodingimport (
1820
string_types,
1921
text_type,
20-
force_bytes
22+
force_bytes,
23+
force_text
2124
)
2225

26+
defenc=sys.getdefaultencoding()
2327
ifPY3:
2428
importio
2529
FileType=io.IOBase
2630
else:
2731
FileType=file
32+
# usually, this is just ascii, which might not enough for our encoding needs
33+
# Unless it's set specifically, we override it to be utf-8
34+
ifdefenc=='ascii':
35+
defenc='utf-8'
36+
37+
38+
defwith_metaclass(meta,*bases):
39+
"""copied from https://github.com/Byron/bcore/blob/master/src/python/butility/future.py#L15"""
40+
classmetaclass(meta):
41+
__call__=type.__call__
42+
__init__=type.__init__
43+
44+
def__new__(cls,name,nbases,d):
45+
ifnbasesisNone:
46+
returntype.__new__(cls,name, (),d)
47+
# There may be clients who rely on this attribute to be set to a reasonable value, which is why
48+
# we set the __metaclass__ attribute explicitly
49+
ifnotPY3and'___metaclass__'notind:
50+
d['__metaclass__']=meta
51+
# end
52+
returnmeta(name,bases,d)
53+
# end
54+
# end metaclass
55+
returnmetaclass(meta.__name__+'Helper',None, {})
56+
# end handle py2
57+

‎git/config.py

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@
1414
importconfigparserascp
1515
importinspect
1616
importlogging
17+
importabc
1718

1819
fromgit.odictimportOrderedDict
1920
fromgit.utilimportLockFile
2021
fromgit.compatimport (
2122
string_types,
22-
FileType
23+
FileType,
24+
defenc,
25+
with_metaclass
2326
)
2427

2528
__all__= ('GitConfigParser','SectionConstraint')
@@ -28,7 +31,7 @@
2831
log=logging.getLogger('git.config')
2932

3033

31-
classMetaParserBuilder(type):
34+
classMetaParserBuilder(abc.ABCMeta):
3235

3336
"""Utlity class wrapping base-class methods into decorators that assure read-only properties"""
3437
def__new__(metacls,name,bases,clsdict):
@@ -39,7 +42,7 @@ def __new__(metacls, name, bases, clsdict):
3942
ifkmminclsdict:
4043
mutating_methods=clsdict[kmm]
4144
forbaseinbases:
42-
methods= (tfortininspect.getmembers(base,inspect.ismethod)ifnott[0].startswith("_"))
45+
methods= (tfortininspect.getmembers(base,inspect.isroutine)ifnott[0].startswith("_"))
4346
forname,methodinmethods:
4447
ifnameinclsdict:
4548
continue
@@ -112,7 +115,7 @@ def config(self):
112115
returnself._config
113116

114117

115-
classGitConfigParser(cp.RawConfigParser,object):
118+
classGitConfigParser(with_metaclass(MetaParserBuilder,cp.RawConfigParser,object)):
116119

117120
"""Implements specifics required to read git style configuration files.
118121
@@ -128,7 +131,6 @@ class GitConfigParser(cp.RawConfigParser, object):
128131
:note:
129132
The config is case-sensitive even when queried, hence section and option names
130133
must match perfectly."""
131-
__metaclass__=MetaParserBuilder
132134

133135
#{ Configuration
134136
# The lock type determines the type of lock to use in new configuration readers.
@@ -150,7 +152,6 @@ class GitConfigParser(cp.RawConfigParser, object):
150152

151153
# list of RawConfigParser methods able to change the instance
152154
_mutating_methods_= ("add_section","remove_section","remove_option","set")
153-
__slots__= ("_sections","_defaults","_file_or_files","_read_only","_is_initialized",'_lock')
154155

155156
def__init__(self,file_or_files,read_only=True):
156157
"""Initialize a configuration reader to read the given file_or_files and to
@@ -162,12 +163,12 @@ def __init__(self, file_or_files, read_only=True):
162163
:param read_only:
163164
If True, the ConfigParser may only read the data , but not change it.
164165
If False, only a single file path or file object may be given."""
165-
super(GitConfigParser,self).__init__()
166-
# initialize base with ordered dictionaries to be sure we write the same
167-
# file back
168-
self._sections=OrderedDict()
169-
self._defaults=OrderedDict()
166+
cp.RawConfigParser.__init__(self,dict_type=OrderedDict)
170167

168+
# Used in python 3, needs to stay in sync with sections for underlying implementation to work
169+
ifnothasattr(self,'_proxies'):
170+
self._proxies=self._dict()
171+
171172
self._file_or_files=file_or_files
172173
self._read_only=read_only
173174
self._is_initialized=False
@@ -222,7 +223,8 @@ def _read(self, fp, fpname):
222223
lineno=0
223224
e=None# None, or an exception
224225
whileTrue:
225-
line=fp.readline()
226+
# we assume to read binary !
227+
line=fp.readline().decode(defenc)
226228
ifnotline:
227229
break
228230
lineno=lineno+1
@@ -242,9 +244,9 @@ def _read(self, fp, fpname):
242244
elifsectname==cp.DEFAULTSECT:
243245
cursect=self._defaults
244246
else:
245-
# THE ONLY LINE WE CHANGED !
246-
cursect=OrderedDict((('__name__',sectname),))
247+
cursect=self._dict((('__name__',sectname),))
247248
self._sections[sectname]=cursect
249+
self._proxies[sectname]=None
248250
# So sections can't start with a continuation line
249251
optname=None
250252
# no section header in the file?
@@ -295,7 +297,7 @@ def read(self):
295297
# assume a path if it is not a file-object
296298
ifnothasattr(file_object,"seek"):
297299
try:
298-
fp=open(file_object)
300+
fp=open(file_object,'rb')
299301
close_fp=True
300302
exceptIOError:
301303
continue
@@ -314,16 +316,17 @@ def _write(self, fp):
314316
"""Write an .ini-format representation of the configuration state in
315317
git compatible format"""
316318
defwrite_section(name,section_dict):
317-
fp.write("[%s]\n"%name)
319+
fp.write(("[%s]\n"%name).encode(defenc))
318320
for (key,value)insection_dict.items():
319321
ifkey!="__name__":
320-
fp.write("\t%s = %s\n"% (key,str(value).replace('\n','\n\t')))
322+
fp.write(("\t%s = %s\n"% (key,str(value).replace('\n','\n\t'))).encode(defenc))
321323
# END if key is not __name__
322324
# END section writing
323325

324326
ifself._defaults:
325327
write_section(cp.DEFAULTSECT,self._defaults)
326-
map(lambdat:write_section(t[0],t[1]),self._sections.items())
328+
forname,valueinself._sections.items():
329+
write_section(name,value)
327330

328331
@needs_values
329332
defwrite(self):
@@ -371,8 +374,7 @@ def _assure_writable(self, method_name):
371374
@set_dirty_and_flush_changes
372375
defadd_section(self,section):
373376
"""Assures added options will stay in order"""
374-
super(GitConfigParser,self).add_section(section)
375-
self._sections[section]=OrderedDict()
377+
returnsuper(GitConfigParser,self).add_section(section)
376378

377379
@property
378380
defread_only(self):

‎git/objects/util.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,17 @@ def get_object_type_by_name(object_type_name):
4646
:param object_type_name: Member of TYPES
4747
4848
:raise ValueError: In case object_type_name is unknown"""
49-
ifobject_type_name=="commit":
50-
importcommit
49+
ifobject_type_name==b"commit":
50+
from .importcommit
5151
returncommit.Commit
52-
elifobject_type_name=="tag":
53-
importtag
52+
elifobject_type_name==b"tag":
53+
from .importtag
5454
returntag.TagObject
55-
elifobject_type_name=="blob":
56-
importblob
55+
elifobject_type_name==b"blob":
56+
from .importblob
5757
returnblob.Blob
58-
elifobject_type_name=="tree":
59-
importtree
58+
elifobject_type_name==b"tree":
59+
from .importtree
6060
returntree.Tree
6161
else:
6262
raiseValueError("Cannot handle unknown object type: %s"%object_type_name)

‎git/refs/symbolic.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
hex_to_bin,
2020
LockedFD
2121
)
22-
fromgit.compatimportstring_types
22+
fromgit.compatimport (
23+
string_types,
24+
)
2325

2426
from .logimportRefLog
2527

@@ -79,10 +81,10 @@ def _get_packed_refs_path(cls, repo):
7981

8082
@classmethod
8183
def_iter_packed_refs(cls,repo):
82-
"""Returns an iterator yielding pairs of sha1/path pairs for the corresponding refs.
84+
"""Returns an iterator yielding pairs of sha1/path pairs(as bytes)for the corresponding refs.
8385
:note: The packed refs file will be kept open as long as we iterate"""
8486
try:
85-
fp=open(cls._get_packed_refs_path(repo),'rb')
87+
fp=open(cls._get_packed_refs_path(repo),'rt')
8688
forlineinfp:
8789
line=line.strip()
8890
ifnotline:
@@ -123,12 +125,12 @@ def dereference_recursive(cls, repo, ref_path):
123125

124126
@classmethod
125127
def_get_ref_info(cls,repo,ref_path):
126-
"""Return: (sha,target_ref_path) if available, the sha the file at
128+
"""Return: (str(sha), str(target_ref_path)) if available, the sha the file at
127129
rela_path points to, or None. target_ref_path is the reference we
128130
point to, or None"""
129131
tokens=None
130132
try:
131-
fp=open(join(repo.git_dir,ref_path),'r')
133+
fp=open(join(repo.git_dir,ref_path),'rt')
132134
value=fp.read().rstrip()
133135
fp.close()
134136
# Don't only split on spaces, but on whitespace, which allows to parse lines like
@@ -141,7 +143,8 @@ def _get_ref_info(cls, repo, ref_path):
141143
forsha,pathincls._iter_packed_refs(repo):
142144
ifpath!=ref_path:
143145
continue
144-
tokens= (sha,path)
146+
# sha will be used as
147+
tokens=sha,path
145148
break
146149
# END for each packed ref
147150
# END handle packed refs

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp