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

Commitaa66d10

Browse files
committed
Merge pull request#183 from kmosher/master
Update the config parser using code from python2.7
2 parents6d3d94c +f72477a commitaa66d10

File tree

3 files changed

+73
-54
lines changed

3 files changed

+73
-54
lines changed

‎git/config.py

Lines changed: 52 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -131,19 +131,20 @@ class GitConfigParser(cp.RawConfigParser, object):
131131

132132
OPTCRE=re.compile(
133133
r'\s*(?P<option>[^:=\s][^:=]*)'# very permissive, incuding leading whitespace
134-
r'\s*(?P<vi>[:=])\s*'# any number of space/tab,
135-
# followed by separator
136-
# (either : or =), followed
137-
# by any # space/tab
138-
r'(?P<value>.*)$'# everything up to eol
139-
)
134+
r'\s*(?:'# any number of space/tab,
135+
r'(?P<vi>[:=])\s*'# optionally followed by
136+
# separator (either : or
137+
# =), followed by any #
138+
# space/tab
139+
r'(?P<value>.*))?$'# everything up to eol
140+
)
140141

141142
# list of RawConfigParser methods able to change the instance
142143
_mutating_methods_= ("add_section","remove_section","remove_option","set")
143144
__slots__= ("_sections","_defaults","_file_or_files","_read_only","_is_initialized",'_lock')
144145

145146
def__init__(self,file_or_files,read_only=True):
146-
"""Initialize a configuration reader to read the given file_or_files and to
147+
"""Initialize a configuration reader to read the given file_or_files and to
147148
possibly allow changes to it by setting read_only False
148149
149150
:param file_or_files:
@@ -198,10 +199,10 @@ def optionxform(self, optionstr):
198199
returnoptionstr
199200

200201
def_read(self,fp,fpname):
201-
"""A direct copy of the py2.4 version of the super class's _read method
202+
"""A direct copy of the py2.7 version of the super class's _read method
202203
to assure it uses ordered dicts. Had to change one line to make it work.
203204
204-
Future versions have this fixed, but in fact its quite embarassing for the
205+
Future versions have this fixed, but in fact its quite embarassing for the
205206
guys not to have done it right in the first place !
206207
207208
Removed big comments to make it more compact.
@@ -222,6 +223,7 @@ def _read(self, fp, fpname):
222223
ifline.split(None,1)[0].lower()=='rem'andline[0]in"rR":
223224
# no leading whitespace
224225
continue
226+
# a section header or option header?
225227
else:
226228
# is it a section header?
227229
mo=self.SECTCRE.match(line.strip())
@@ -245,43 +247,48 @@ def _read(self, fp, fpname):
245247
mo=self.OPTCRE.match(line)
246248
ifmo:
247249
optname,vi,optval=mo.group('option','vi','value')
248-
ifviin ('=',':')and';'inoptval:
249-
pos=optval.find(';')
250-
ifpos!=-1andoptval[pos-1].isspace():
251-
optval=optval[:pos]
252-
optval=optval.strip()
253-
254-
# Remove paired unescaped-quotes
255-
unquoted_optval=''
256-
escaped=False
257-
in_quote=False
258-
forcinoptval:
259-
ifnotescapedandc=='"':
260-
in_quote=notin_quote
261-
else:
262-
escaped= (c=='\\')andnotescaped
263-
unquoted_optval+=c
264-
265-
ifin_quote:
266-
ifnote:
267-
e=cp.ParsingError(fpname)
268-
e.append(lineno,repr(line))
269-
270-
optval=unquoted_optval
271-
272-
optval=optval.replace('\\\\','\\')# Unescape backslashes
273-
optval=optval.replace(r'\"','"')# Unescape quotes
274-
275250
optname=self.optionxform(optname.rstrip())
276-
cursect[optname]=optval
251+
ifoptvalisnotNone:
252+
ifviin ('=',':')and';'inoptval:
253+
# ';' is a comment delimiter only if it follows
254+
# a spacing character
255+
pos=optval.find(';')
256+
ifpos!=-1andoptval[pos-1].isspace():
257+
optval=optval[:pos]
258+
optval=optval.strip()
259+
# allow empty values
260+
ifoptval=='""':
261+
optval=''
262+
# Remove paired unescaped-quotes
263+
unquoted_optval=''
264+
escaped=False
265+
in_quote=False
266+
forcinoptval:
267+
ifnotescapedandc=='"':
268+
in_quote=notin_quote
269+
else:
270+
escaped= (c=='\\')andnotescaped
271+
unquoted_optval+=c
272+
ifin_quote:
273+
ifnote:
274+
e=cp.ParsingError(fpname)
275+
e.append(lineno,repr(line))
276+
277+
optval=unquoted_optval
278+
optval=optval.replace('\\\\','\\')# Unescape backslashes
279+
optval=optval.replace(r'\"','"')# Unescape quotes
280+
cursect[optname]=optval
281+
else:
282+
# valueless option handling
283+
cursect[optname]=optval
277284
else:
285+
# a non-fatal parsing error occurred. set up the
286+
# exception but keep going. the exception will be
287+
# raised at the end of the file and will contain a
288+
# list of all bogus lines
278289
ifnote:
279290
e=cp.ParsingError(fpname)
280291
e.append(lineno,repr(line))
281-
# END
282-
# END ?
283-
# END ?
284-
# END while reading
285292
# if any parsing errors occurred, raise an exception
286293
ife:
287294
raisee
@@ -398,7 +405,7 @@ def get_value(self, section, option, default=None):
398405
:param default:
399406
If not None, the given default value will be returned in case
400407
the option did not exist
401-
:return: a properly typed value, either int, floatorstring
408+
:return: a properly typed value, either int,bool,float, stringorNone
402409
403410
:raise TypeError: in case the value could not be understood
404411
Otherwise the exceptions known to the ConfigParser will be raised."""
@@ -409,6 +416,9 @@ def get_value(self, section, option, default=None):
409416
returndefault
410417
raise
411418

419+
ifvaluestrisNone:
420+
returnvaluestr
421+
412422
types= (long,float)
413423
fornumtypeintypes:
414424
try:

‎git/test/fixtures/git_config

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@
2727
[branch "mainline_performance"]
2828
remote = mainline
2929
merge = refs/heads/master
30+
[filter "indent"]
31+
clean = indent
32+
smudge = cat
33+
# A vauleless option
34+
required

‎git/test/test_config.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,22 @@ def test_base(self):
7777
assertr_config._is_initialized==False
7878
forsectioninr_config.sections():
7979
num_sections+=1
80-
foroptioninr_config.options(section):
81-
num_options+=1
82-
val=r_config.get(section,option)
83-
val_typed=r_config.get_value(section,option)
84-
assertisinstance(val_typed, (bool,long,float,basestring))
85-
assertval
86-
assert"\n"notinoption
87-
assert"\n"notinval
88-
89-
# writing must fail
90-
self.failUnlessRaises(IOError,r_config.set,section,option,None)
91-
self.failUnlessRaises(IOError,r_config.remove_option,section,option)
80+
ifsection!='filter "indent"':
81+
foroptioninr_config.options(section):
82+
num_options+=1
83+
val=r_config.get(section,option)
84+
val_typed=r_config.get_value(section,option)
85+
assertisinstance(val_typed, (bool,long,float,basestring))
86+
assertval
87+
assert"\n"notinoption
88+
assert"\n"notinval
89+
90+
# writing must fail
91+
self.failUnlessRaises(IOError,r_config.set,section,option,None)
92+
self.failUnlessRaises(IOError,r_config.remove_option,section,option)
93+
else:
94+
val=r_config.get(section,'required')
95+
assertvalisNone
9296
# END for each option
9397
self.failUnlessRaises(IOError,r_config.remove_section,section)
9498
# END for each section

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp