Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
c264c098
Commit
c264c098
authored
Nov 20, 2010
by
Łukasz Langa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
configparser: the name of the DEFAULT section is now customizable
parent
b357fb7b
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
40 additions
and
33 deletions
+40
-33
Lib/configparser.py
Lib/configparser.py
+19
-17
Lib/test/test_cfgparser.py
Lib/test/test_cfgparser.py
+21
-16
No files found.
Lib/configparser.py
View file @
c264c098
...
...
@@ -406,12 +406,13 @@ class RawConfigParser(MutableMapping):
def __init__(self, defaults=None, dict_type=_default_dict,
allow_no_value=False, *, delimiters=('=', ':'),
comment_prefixes=_COMPATIBLE, strict=False,
empty_lines_in_values=True):
empty_lines_in_values=True,
default_section=DEFAULTSECT):
self._dict = dict_type
self._sections = self._dict()
self._defaults = self._dict()
self._proxies = self._dict()
self._proxies[
DEFAULTSECT] = SectionProxy(self, DEFAULTSECT
)
self._proxies[
default_section] = SectionProxy(self, default_section
)
if defaults:
for key, value in defaults.items():
self._defaults[self.optionxform(key)] = value
...
...
@@ -435,6 +436,7 @@ class RawConfigParser(MutableMapping):
self._strict = strict
self._allow_no_value = allow_no_value
self._empty_lines_in_values = empty_lines_in_values
self._default_section=default_section
def defaults(self):
return self._defaults
...
...
@@ -448,10 +450,9 @@ class RawConfigParser(MutableMapping):
"""Create a new section in the configuration.
Raise DuplicateSectionError if a section by the specified name
already exists. Raise ValueError if name is DEFAULT or any of it's
case-insensitive variants.
already exists. Raise ValueError if name is DEFAULT.
"""
if section
.upper() == DEFAULTSECT
:
if section
== self._default_section
:
raise ValueError('Invalid section name: %s' % section)
if section in self._sections:
...
...
@@ -587,7 +588,7 @@ class RawConfigParser(MutableMapping):
try:
d2 = self._sections[section]
except KeyError:
if section !=
DEFAULTSECT
:
if section !=
self._default_section
:
raise NoSectionError(section)
d2 = self._dict()
d = self._defaults.copy()
...
...
@@ -632,7 +633,7 @@ class RawConfigParser(MutableMapping):
def has_option(self, section, option):
"""Check for the existence of a given option in a given section."""
if not section or section ==
DEFAULTSECT
:
if not section or section ==
self._default_section
:
option = self.optionxform(option)
return option in self._defaults
elif section not in self._sections:
...
...
@@ -644,7 +645,7 @@ class RawConfigParser(MutableMapping):
def set(self, section, option, value=None):
"""Set an option."""
if not section or section ==
DEFAULTSECT
:
if not section or section ==
self._default_section
:
sectdict = self._defaults
else:
try:
...
...
@@ -664,7 +665,8 @@ class RawConfigParser(MutableMapping):
else:
d = self._delimiters[0]
if self._defaults:
self._write_section(fp, DEFAULTSECT, self._defaults.items(), d)
self._write_section(fp, self._default_section,
self._defaults.items(), d)
for section in self._sections:
self._write_section(fp, section,
self._sections[section].items(), d)
...
...
@@ -684,7 +686,7 @@ class RawConfigParser(MutableMapping):
def remove_option(self, section, option):
"""Remove an option."""
if not section or section ==
DEFAULTSECT
:
if not section or section ==
self._default_section
:
sectdict = self._defaults
else:
try:
...
...
@@ -706,7 +708,7 @@ class RawConfigParser(MutableMapping):
return existed
def __getitem__(self, key):
if key !=
DEFAULTSECT
and not self.has_section(key):
if key !=
self._default_section
and not self.has_section(key):
raise KeyError(key)
return self._proxies[key]
...
...
@@ -720,21 +722,21 @@ class RawConfigParser(MutableMapping):
self.read_dict({key: value})
def __delitem__(self, key):
if key ==
DEFAULTSECT
:
if key ==
self._default_section
:
raise ValueError("
Cannot
remove
the
default
section
.
")
if not self.has_section(key):
raise KeyError(key)
self.remove_section(key)
def __contains__(self, key):
return key ==
DEFAULTSECT
or self.has_section(key)
return key ==
self._default_section
or self.has_section(key)
def __len__(self):
return len(self._sections) + 1 # the default section
def __iter__(self):
# XXX does it break when underlying container state changed?
return itertools.chain((
DEFAULTSECT
,), self._sections.keys())
return itertools.chain((
self._default_section
,), self._sections.keys())
def _read(self, fp, fpname):
"""Parse a sectioned configuration file.
...
...
@@ -806,7 +808,7 @@ class RawConfigParser(MutableMapping):
lineno)
cursect = self._sections[sectname]
elements_added.add(sectname)
elif sectname ==
DEFAULTSECT
:
elif sectname ==
self._default_section
:
cursect = self._defaults
else:
cursect = self._dict()
...
...
@@ -877,7 +879,7 @@ class RawConfigParser(MutableMapping):
try:
d.update(self._sections[section])
except KeyError:
if section !=
DEFAULTSECT
:
if section !=
self._default_section
:
raise NoSectionError(section)
# Update with the entry specific variables
if vars:
...
...
@@ -999,7 +1001,7 @@ class ConfigParser(RawConfigParser):
try:
d.update(self._sections[section])
except KeyError:
if section !=
DEFAULTSECT
:
if section !=
self._default_section
:
raise NoSectionError(section)
# Update with the entry specific variables
if vars:
...
...
Lib/test/test_cfgparser.py
View file @
c264c098
...
...
@@ -31,6 +31,7 @@ class CfgParserTestCaseClass(unittest.TestCase):
empty_lines_in_values
=
True
dict_type
=
configparser
.
_default_dict
strict
=
False
default_section
=
configparser
.
DEFAULTSECT
def
newconfig
(
self
,
defaults
=
None
):
arguments
=
dict
(
...
...
@@ -41,6 +42,7 @@ class CfgParserTestCaseClass(unittest.TestCase):
empty_lines_in_values
=
self
.
empty_lines_in_values
,
dict_type
=
self
.
dict_type
,
strict
=
self
.
strict
,
default_section
=
self
.
default_section
,
)
return
self
.
config_class
(
**
arguments
)
...
...
@@ -76,7 +78,7 @@ class BasicTestCase(CfgParserTestCaseClass):
# mapping access
L
=
[
section
for
section
in
cf
]
L
.
sort
()
E
.
append
(
configparser
.
DEFAULTSECT
)
E
.
append
(
self
.
default_section
)
E
.
sort
()
eq
(
L
,
E
)
...
...
@@ -365,7 +367,7 @@ boolean {0[0]} NO
L
.
sort
()
eq
=
self
.
assertEqual
elem_eq
=
self
.
assertItemsEqual
eq
(
L
,
[
"A"
,
"B"
,
configparser
.
DEFAULTSECT
,
"a"
]
)
eq
(
L
,
sorted
([
"A"
,
"B"
,
self
.
default_section
,
"a"
])
)
eq
(
cf
[
"a"
].
keys
(),
{
"b"
})
eq
(
cf
[
"a"
][
"b"
],
"value"
,
"could not locate option, expecting case-insensitive option names"
)
...
...
@@ -399,11 +401,11 @@ boolean {0[0]} NO
def
test_default_case_sensitivity
(
self
):
cf
=
self
.
newconfig
({
"foo"
:
"Bar"
})
self
.
assertEqual
(
cf
.
get
(
"DEFAULT"
,
"Foo"
),
"Bar"
,
cf
.
get
(
self
.
default_section
,
"Foo"
),
"Bar"
,
"could not locate option, expecting case-insensitive option names"
)
cf
=
self
.
newconfig
({
"Foo"
:
"Bar"
})
self
.
assertEqual
(
cf
.
get
(
"DEFAULT"
,
"Foo"
),
"Bar"
,
cf
.
get
(
self
.
default_section
,
"Foo"
),
"Bar"
,
"could not locate option, expecting case-insensitive defaults"
)
def
test_parse_errors
(
self
):
...
...
@@ -530,7 +532,7 @@ boolean {0[0]} NO
"[Long Line]
\
n
"
"foo{0[0]} this line is much, much longer than my editor
\
n
"
" likes it.
\
n
"
"[
DEFAULT
]
\
n
"
"[
{default_section}
]
\
n
"
"foo{0[1]} another very
\
n
"
" long line
\
n
"
"[Long Line - With Comments!]
\
n
"
...
...
@@ -538,7 +540,8 @@ boolean {0[0]} NO
" also {comment} place
\
n
"
" comments {comment} in
\
n
"
" multiline {comment} values"
"
\
n
"
.
format
(
self
.
delimiters
,
comment
=
self
.
comment_prefixes
[
0
])
"
\
n
"
.
format
(
self
.
delimiters
,
comment
=
self
.
comment_prefixes
[
0
],
default_section
=
self
.
default_section
)
)
if
self
.
allow_no_value
:
config_string
+=
(
...
...
@@ -550,7 +553,7 @@ boolean {0[0]} NO
output
=
io
.
StringIO
()
cf
.
write
(
output
)
expect_string
=
(
"[
DEFAULT
]
\
n
"
"[
{default_section}
]
\
n
"
"foo {equals} another very
\
n
"
"
\
t
long line
\
n
"
"
\
n
"
...
...
@@ -563,7 +566,8 @@ boolean {0[0]} NO
"
\
t
also
\
n
"
"
\
t
comments
\
n
"
"
\
t
multiline
\
n
"
"
\
n
"
.
format
(
equals
=
self
.
delimiters
[
0
])
"
\
n
"
.
format
(
equals
=
self
.
delimiters
[
0
],
default_section
=
self
.
default_section
)
)
if
self
.
allow_no_value
:
expect_string
+=
(
...
...
@@ -724,6 +728,9 @@ class ConfigParserTestCaseNonStandardDelimiters(ConfigParserTestCase):
delimiters
=
(
':='
,
'$'
)
comment_prefixes
=
(
'//'
,
'"'
)
class
ConfigParserTestCaseNonStandardDefaultSection
(
ConfigParserTestCase
):
default_section
=
'general'
class
MultilineValuesTestCase
(
BasicTestCase
):
config_class
=
configparser
.
ConfigParser
wonderful_spam
=
(
"I'm having spam spam spam spam "
...
...
@@ -851,13 +858,9 @@ class SafeConfigParserTestCase(ConfigParserTestCase):
self
.
assertRaises
(
TypeError
,
cf
.
set
,
"sect"
,
"option2"
,
1.0
)
self
.
assertRaises
(
TypeError
,
cf
.
set
,
"sect"
,
"option2"
,
object
())
def
test_add_section_default_1
(
self
):
cf
=
self
.
newconfig
()
self
.
assertRaises
(
ValueError
,
cf
.
add_section
,
"default"
)
def
test_add_section_default_2
(
self
):
def
test_add_section_default
(
self
):
cf
=
self
.
newconfig
()
self
.
assertRaises
(
ValueError
,
cf
.
add_section
,
"DEFAULT"
)
self
.
assertRaises
(
ValueError
,
cf
.
add_section
,
self
.
default_section
)
class
SafeConfigParserTestCaseNonStandardDelimiters
(
SafeConfigParserTestCase
):
delimiters
=
(
':='
,
'$'
)
...
...
@@ -884,11 +887,12 @@ class SafeConfigParserTestCaseTrickyFile(CfgParserTestCaseClass):
'no values here'
,
'tricky interpolation'
,
'more interpolation'
])
self
.
assertEqual
(
cf
.
getint
(
'DEFAULT'
,
'go'
,
self
.
assertEqual
(
cf
.
getint
(
self
.
default_section
,
'go'
,
vars
=
{
'interpolate'
:
'-1'
}),
-
1
)
with
self
.
assertRaises
(
ValueError
):
# no interpolation will happen
cf
.
getint
(
'DEFAULT'
,
'go'
,
raw
=
True
,
vars
=
{
'interpolate'
:
'-1'
})
cf
.
getint
(
self
.
default_section
,
'go'
,
raw
=
True
,
vars
=
{
'interpolate'
:
'-1'
})
self
.
assertEqual
(
len
(
cf
.
get
(
'strange'
,
'other'
).
split
(
'
\
n
'
)),
4
)
self
.
assertEqual
(
len
(
cf
.
get
(
'corruption'
,
'value'
).
split
(
'
\
n
'
)),
10
)
longname
=
'yeah, sections can be indented as well'
...
...
@@ -997,6 +1001,7 @@ def test_main():
Issue7005TestCase
,
StrictTestCase
,
CompatibleTestCase
,
ConfigParserTestCaseNonStandardDefaultSection
,
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment