Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
cc43b569
Kaydet (Commit)
cc43b569
authored
Şub 19, 2010
tarafından
Fred Drake
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
- apply patch from issue 7005
- add corresponding documentation
üst
c2294dd6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
147 additions
and
42 deletions
+147
-42
configparser.rst
Doc/library/configparser.rst
+46
-4
ConfigParser.py
Lib/ConfigParser.py
+44
-18
test_cfgparser.py
Lib/test/test_cfgparser.py
+57
-20
No files found.
Doc/library/configparser.rst
Dosyayı görüntüle @
cc43b569
...
@@ -62,12 +62,16 @@ dictionary type is passed that sorts its keys, the sections will be sorted on
...
@@ -62,12 +62,16 @@ dictionary type is passed that sorts its keys, the sections will be sorted on
write-back, as will be the keys within each section.
write-back, as will be the keys within each section.
.. class:: RawConfigParser([defaults[, dict_type]])
.. class:: RawConfigParser([defaults[, dict_type
[, allow_no_value]
]])
The basic configuration object. When *defaults* is given, it is initialized
The basic configuration object. When *defaults* is given, it is initialized
into the dictionary of intrinsic defaults. When *dict_type* is given, it will
into the dictionary of intrinsic defaults. When *dict_type* is given, it will
be used to create the dictionary objects for the list of sections, for the
be used to create the dictionary objects for the list of sections, for the
options within a section, and for the default values. This class does not
options within a section, and for the default values. When *allow_no_value*
is true (default: ``False``), options without values are accepted; the value
presented for these is ``None``.
This class does not
support the magical interpolation behavior.
support the magical interpolation behavior.
.. versionadded:: 2.3
.. versionadded:: 2.3
...
@@ -77,9 +81,10 @@ write-back, as will be the keys within each section.
...
@@ -77,9 +81,10 @@ write-back, as will be the keys within each section.
.. versionchanged:: 2.7
.. versionchanged:: 2.7
The default *dict_type* is :class:`collections.OrderedDict`.
The default *dict_type* is :class:`collections.OrderedDict`.
*allow_no_value* was added.
.. class:: ConfigParser([defaults[, dict_type]])
.. class:: ConfigParser([defaults[, dict_type
[, allow_no_value]
]])
Derived class of :class:`RawConfigParser` that implements the magical
Derived class of :class:`RawConfigParser` that implements the magical
interpolation feature and adds optional arguments to the :meth:`get` and
interpolation feature and adds optional arguments to the :meth:`get` and
...
@@ -101,9 +106,10 @@ write-back, as will be the keys within each section.
...
@@ -101,9 +106,10 @@ write-back, as will be the keys within each section.
.. versionchanged:: 2.7
.. versionchanged:: 2.7
The default *dict_type* is :class:`collections.OrderedDict`.
The default *dict_type* is :class:`collections.OrderedDict`.
*allow_no_value* was added.
.. class:: SafeConfigParser([defaults[, dict_type]])
.. class:: SafeConfigParser([defaults[, dict_type
[, allow_no_value]
]])
Derived class of :class:`ConfigParser` that implements a more-sane variant of
Derived class of :class:`ConfigParser` that implements a more-sane variant of
the magical interpolation feature. This implementation is more predictable as
the magical interpolation feature. This implementation is more predictable as
...
@@ -119,6 +125,7 @@ write-back, as will be the keys within each section.
...
@@ -119,6 +125,7 @@ write-back, as will be the keys within each section.
.. versionchanged:: 2.7
.. versionchanged:: 2.7
The default *dict_type* is :class:`collections.OrderedDict`.
The default *dict_type* is :class:`collections.OrderedDict`.
*allow_no_value* was added.
.. exception:: NoSectionError
.. exception:: NoSectionError
...
@@ -484,3 +491,38 @@ The function ``opt_move`` below can be used to move options between sections::
...
@@ -484,3 +491,38 @@ The function ``opt_move`` below can be used to move options between sections::
opt_move(config, section1, section2, option)
opt_move(config, section1, section2, option)
else:
else:
config.remove_option(section1, option)
config.remove_option(section1, option)
Some configuration files are known to include settings without values, but which
otherwise conform to the syntax supported by :mod:`ConfigParser`. The
*allow_no_value* parameter to the constructor can be used to indicate that such
values should be accepted:
.. doctest::
>>> import ConfigParser
>>> import io
>>> sample_config = """
... [mysqld]
... user = mysql
... pid-file = /var/run/mysqld/mysqld.pid
... skip-external-locking
... old_passwords = 1
... skip-bdb
... skip-innodb
... """
>>> config = ConfigParser.RawConfigParser(allow_no_value=True)
>>> config.readfp(io.BytesIO(sample_config))
>>> # Settings with values are treated as before:
>>> config.get("mysqld", "user")
'mysql'
>>> # Settings without values provide None:
>>> config.get("mysqld", "skip-bdb")
>>> # Settings which aren't specified still raise an error:
>>> config.get("mysqld", "does-not-exist")
Traceback (most recent call last):
...
ConfigParser.NoOptionError: No option 'does-not-exist' in section: 'mysqld'
Lib/ConfigParser.py
Dosyayı görüntüle @
cc43b569
...
@@ -221,10 +221,15 @@ class MissingSectionHeaderError(ParsingError):
...
@@ -221,10 +221,15 @@ class MissingSectionHeaderError(ParsingError):
class
RawConfigParser
:
class
RawConfigParser
:
def
__init__
(
self
,
defaults
=
None
,
dict_type
=
_default_dict
):
def
__init__
(
self
,
defaults
=
None
,
dict_type
=
_default_dict
,
allow_no_value
=
False
):
self
.
_dict
=
dict_type
self
.
_dict
=
dict_type
self
.
_sections
=
self
.
_dict
()
self
.
_sections
=
self
.
_dict
()
self
.
_defaults
=
self
.
_dict
()
self
.
_defaults
=
self
.
_dict
()
if
allow_no_value
:
self
.
_optcre
=
self
.
OPTCRE_NV
else
:
self
.
_optcre
=
self
.
OPTCRE
if
defaults
:
if
defaults
:
for
key
,
value
in
defaults
.
items
():
for
key
,
value
in
defaults
.
items
():
self
.
_defaults
[
self
.
optionxform
(
key
)]
=
value
self
.
_defaults
[
self
.
optionxform
(
key
)]
=
value
...
@@ -372,7 +377,7 @@ class RawConfigParser:
...
@@ -372,7 +377,7 @@ class RawConfigParser:
return
(
option
in
self
.
_sections
[
section
]
return
(
option
in
self
.
_sections
[
section
]
or
option
in
self
.
_defaults
)
or
option
in
self
.
_defaults
)
def
set
(
self
,
section
,
option
,
value
):
def
set
(
self
,
section
,
option
,
value
=
None
):
"""Set an option."""
"""Set an option."""
if
not
section
or
section
==
DEFAULTSECT
:
if
not
section
or
section
==
DEFAULTSECT
:
sectdict
=
self
.
_defaults
sectdict
=
self
.
_defaults
...
@@ -394,8 +399,11 @@ class RawConfigParser:
...
@@ -394,8 +399,11 @@ class RawConfigParser:
fp
.
write
(
"[
%
s]
\n
"
%
section
)
fp
.
write
(
"[
%
s]
\n
"
%
section
)
for
(
key
,
value
)
in
self
.
_sections
[
section
]
.
items
():
for
(
key
,
value
)
in
self
.
_sections
[
section
]
.
items
():
if
key
!=
"__name__"
:
if
key
!=
"__name__"
:
fp
.
write
(
"
%
s =
%
s
\n
"
%
if
value
is
None
:
(
key
,
str
(
value
)
.
replace
(
'
\n
'
,
'
\n\t
'
)))
fp
.
write
(
"
%
s
\n
"
%
(
key
))
else
:
fp
.
write
(
"
%
s =
%
s
\n
"
%
(
key
,
str
(
value
)
.
replace
(
'
\n
'
,
'
\n\t
'
)))
fp
.
write
(
"
\n
"
)
fp
.
write
(
"
\n
"
)
def
remove_option
(
self
,
section
,
option
):
def
remove_option
(
self
,
section
,
option
):
...
@@ -436,6 +444,15 @@ class RawConfigParser:
...
@@ -436,6 +444,15 @@ class RawConfigParser:
# by any # space/tab
# by any # space/tab
r'(?P<value>.*)$'
# everything up to eol
r'(?P<value>.*)$'
# everything up to eol
)
)
OPTCRE_NV
=
re
.
compile
(
r'(?P<option>[^:=\s][^:=]*)'
# very permissive!
r'\s*(?:'
# any number of space/tab,
r'(?P<vi>[:=])\s*'
# optionally followed by
# separator (either : or
# =), followed by any #
# space/tab
r'(?P<value>.*))?$'
# everything up to eol
)
def
_read
(
self
,
fp
,
fpname
):
def
_read
(
self
,
fp
,
fpname
):
"""Parse a sectioned setup file.
"""Parse a sectioned setup file.
...
@@ -488,16 +505,19 @@ class RawConfigParser:
...
@@ -488,16 +505,19 @@ class RawConfigParser:
raise
MissingSectionHeaderError
(
fpname
,
lineno
,
line
)
raise
MissingSectionHeaderError
(
fpname
,
lineno
,
line
)
# an option line?
# an option line?
else
:
else
:
mo
=
self
.
OPTCRE
.
match
(
line
)
mo
=
self
.
_optcre
.
match
(
line
)
if
mo
:
if
mo
:
optname
,
vi
,
optval
=
mo
.
group
(
'option'
,
'vi'
,
'value'
)
optname
,
vi
,
optval
=
mo
.
group
(
'option'
,
'vi'
,
'value'
)
if
vi
in
(
'='
,
':'
)
and
';'
in
optval
:
# This check is fine because the OPTCRE cannot
# ';' is a comment delimiter only if it follows
# match if it would set optval to None
# a spacing character
if
optval
is
not
None
:
pos
=
optval
.
find
(
';'
)
if
vi
in
(
'='
,
':'
)
and
';'
in
optval
:
if
pos
!=
-
1
and
optval
[
pos
-
1
]
.
isspace
():
# ';' is a comment delimiter only if it follows
optval
=
optval
[:
pos
]
# a spacing character
optval
=
optval
.
strip
()
pos
=
optval
.
find
(
';'
)
if
pos
!=
-
1
and
optval
[
pos
-
1
]
.
isspace
():
optval
=
optval
[:
pos
]
optval
=
optval
.
strip
()
# allow empty values
# allow empty values
if
optval
==
'""'
:
if
optval
==
'""'
:
optval
=
''
optval
=
''
...
@@ -545,7 +565,7 @@ class ConfigParser(RawConfigParser):
...
@@ -545,7 +565,7 @@ class ConfigParser(RawConfigParser):
except
KeyError
:
except
KeyError
:
raise
NoOptionError
(
option
,
section
)
raise
NoOptionError
(
option
,
section
)
if
raw
:
if
raw
or
value
is
None
:
return
value
return
value
else
:
else
:
return
self
.
_interpolate
(
section
,
option
,
value
,
d
)
return
self
.
_interpolate
(
section
,
option
,
value
,
d
)
...
@@ -588,7 +608,7 @@ class ConfigParser(RawConfigParser):
...
@@ -588,7 +608,7 @@ class ConfigParser(RawConfigParser):
depth
=
MAX_INTERPOLATION_DEPTH
depth
=
MAX_INTERPOLATION_DEPTH
while
depth
:
# Loop through this until it's done
while
depth
:
# Loop through this until it's done
depth
-=
1
depth
-=
1
if
"
%
("
in
value
:
if
value
and
"
%
("
in
value
:
value
=
self
.
_KEYCRE
.
sub
(
self
.
_interpolation_replace
,
value
)
value
=
self
.
_KEYCRE
.
sub
(
self
.
_interpolation_replace
,
value
)
try
:
try
:
value
=
value
%
vars
value
=
value
%
vars
...
@@ -597,7 +617,7 @@ class ConfigParser(RawConfigParser):
...
@@ -597,7 +617,7 @@ class ConfigParser(RawConfigParser):
option
,
section
,
rawval
,
e
.
args
[
0
])
option
,
section
,
rawval
,
e
.
args
[
0
])
else
:
else
:
break
break
if
"
%
("
in
value
:
if
value
and
"
%
("
in
value
:
raise
InterpolationDepthError
(
option
,
section
,
rawval
)
raise
InterpolationDepthError
(
option
,
section
,
rawval
)
return
value
return
value
...
@@ -659,10 +679,16 @@ class SafeConfigParser(ConfigParser):
...
@@ -659,10 +679,16 @@ class SafeConfigParser(ConfigParser):
option
,
section
,
option
,
section
,
"'
%%
' must be followed by '
%%
' or '(', found:
%
r"
%
(
rest
,))
"'
%%
' must be followed by '
%%
' or '(', found:
%
r"
%
(
rest
,))
def
set
(
self
,
section
,
option
,
value
):
def
set
(
self
,
section
,
option
,
value
=
None
):
"""Set an option. Extend ConfigParser.set: check for string values."""
"""Set an option. Extend ConfigParser.set: check for string values."""
if
not
isinstance
(
value
,
basestring
):
# The only legal non-string value if we allow valueless
raise
TypeError
(
"option values must be strings"
)
# options is None, so we need to check if the value is a
# string if:
# - we do not allow valueless options, or
# - we allow valueless options but the value is not None
if
self
.
_optcre
is
self
.
OPTCRE
or
value
:
if
not
isinstance
(
value
,
basestring
):
raise
TypeError
(
"option values must be strings"
)
# check for bad percent signs:
# check for bad percent signs:
# first, replace all "good" interpolations
# first, replace all "good" interpolations
tmp_value
=
value
.
replace
(
'
%%
'
,
''
)
tmp_value
=
value
.
replace
(
'
%%
'
,
''
)
...
...
Lib/test/test_cfgparser.py
Dosyayı görüntüle @
cc43b569
...
@@ -5,6 +5,7 @@ import UserDict
...
@@ -5,6 +5,7 @@ import UserDict
from
test
import
test_support
from
test
import
test_support
class
SortedDict
(
UserDict
.
UserDict
):
class
SortedDict
(
UserDict
.
UserDict
):
def
items
(
self
):
def
items
(
self
):
result
=
self
.
data
.
items
()
result
=
self
.
data
.
items
()
...
@@ -26,12 +27,16 @@ class SortedDict(UserDict.UserDict):
...
@@ -26,12 +27,16 @@ class SortedDict(UserDict.UserDict):
__iter__
=
iterkeys
__iter__
=
iterkeys
def
itervalues
(
self
):
return
iter
(
self
.
values
())
def
itervalues
(
self
):
return
iter
(
self
.
values
())
class
TestCaseBase
(
unittest
.
TestCase
):
class
TestCaseBase
(
unittest
.
TestCase
):
allow_no_value
=
False
def
newconfig
(
self
,
defaults
=
None
):
def
newconfig
(
self
,
defaults
=
None
):
if
defaults
is
None
:
if
defaults
is
None
:
self
.
cf
=
self
.
config_class
()
self
.
cf
=
self
.
config_class
(
allow_no_value
=
self
.
allow_no_value
)
else
:
else
:
self
.
cf
=
self
.
config_class
(
defaults
)
self
.
cf
=
self
.
config_class
(
defaults
,
allow_no_value
=
self
.
allow_no_value
)
return
self
.
cf
return
self
.
cf
def
fromstring
(
self
,
string
,
defaults
=
None
):
def
fromstring
(
self
,
string
,
defaults
=
None
):
...
@@ -41,7 +46,7 @@ class TestCaseBase(unittest.TestCase):
...
@@ -41,7 +46,7 @@ class TestCaseBase(unittest.TestCase):
return
cf
return
cf
def
test_basic
(
self
):
def
test_basic
(
self
):
c
f
=
self
.
fromstring
(
c
onfig_string
=
(
"[Foo Bar]
\n
"
"[Foo Bar]
\n
"
"foo=bar
\n
"
"foo=bar
\n
"
"[Spacey Bar]
\n
"
"[Spacey Bar]
\n
"
...
@@ -61,17 +66,28 @@ class TestCaseBase(unittest.TestCase):
...
@@ -61,17 +66,28 @@ class TestCaseBase(unittest.TestCase):
"key with spaces : value
\n
"
"key with spaces : value
\n
"
"another with spaces = splat!
\n
"
"another with spaces = splat!
\n
"
)
)
if
self
.
allow_no_value
:
config_string
+=
(
"[NoValue]
\n
"
"option-without-value
\n
"
)
cf
=
self
.
fromstring
(
config_string
)
L
=
cf
.
sections
()
L
=
cf
.
sections
()
L
.
sort
()
L
.
sort
()
E
=
[
r'Commented Bar'
,
r'Foo Bar'
,
r'Internationalized Stuff'
,
r'Long Line'
,
r'Section\with$weird
%
characters['
'
\t
'
,
r'Spaces'
,
r'Spacey Bar'
,
]
if
self
.
allow_no_value
:
E
.
append
(
r'NoValue'
)
E
.
sort
()
eq
=
self
.
assertEqual
eq
=
self
.
assertEqual
eq
(
L
,
[
r'Commented Bar'
,
eq
(
L
,
E
)
r'Foo Bar'
,
r'Internationalized Stuff'
,
r'Long Line'
,
r'Section\with$weird
%
characters['
'
\t
'
,
r'Spaces'
,
r'Spacey Bar'
,
])
# The use of spaces in the section names serves as a
# The use of spaces in the section names serves as a
# regression test for SourceForge bug #583248:
# regression test for SourceForge bug #583248:
...
@@ -81,6 +97,8 @@ class TestCaseBase(unittest.TestCase):
...
@@ -81,6 +97,8 @@ class TestCaseBase(unittest.TestCase):
eq
(
cf
.
get
(
'Commented Bar'
,
'foo'
),
'bar'
)
eq
(
cf
.
get
(
'Commented Bar'
,
'foo'
),
'bar'
)
eq
(
cf
.
get
(
'Spaces'
,
'key with spaces'
),
'value'
)
eq
(
cf
.
get
(
'Spaces'
,
'key with spaces'
),
'value'
)
eq
(
cf
.
get
(
'Spaces'
,
'another with spaces'
),
'splat!'
)
eq
(
cf
.
get
(
'Spaces'
,
'another with spaces'
),
'splat!'
)
if
self
.
allow_no_value
:
eq
(
cf
.
get
(
'NoValue'
,
'option-without-value'
),
None
)
self
.
assertNotIn
(
'__name__'
,
cf
.
options
(
"Foo Bar"
),
self
.
assertNotIn
(
'__name__'
,
cf
.
options
(
"Foo Bar"
),
'__name__ "option" should not be exposed by the API!'
)
'__name__ "option" should not be exposed by the API!'
)
...
@@ -152,8 +170,6 @@ class TestCaseBase(unittest.TestCase):
...
@@ -152,8 +170,6 @@ class TestCaseBase(unittest.TestCase):
"[Foo]
\n
extra-spaces: splat
\n
"
)
"[Foo]
\n
extra-spaces: splat
\n
"
)
self
.
parse_error
(
ConfigParser
.
ParsingError
,
self
.
parse_error
(
ConfigParser
.
ParsingError
,
"[Foo]
\n
extra-spaces= splat
\n
"
)
"[Foo]
\n
extra-spaces= splat
\n
"
)
self
.
parse_error
(
ConfigParser
.
ParsingError
,
"[Foo]
\n
option-without-value
\n
"
)
self
.
parse_error
(
ConfigParser
.
ParsingError
,
self
.
parse_error
(
ConfigParser
.
ParsingError
,
"[Foo]
\n
:value-without-option-name
\n
"
)
"[Foo]
\n
:value-without-option-name
\n
"
)
self
.
parse_error
(
ConfigParser
.
ParsingError
,
self
.
parse_error
(
ConfigParser
.
ParsingError
,
...
@@ -220,18 +236,24 @@ class TestCaseBase(unittest.TestCase):
...
@@ -220,18 +236,24 @@ class TestCaseBase(unittest.TestCase):
cf
.
add_section
,
"Foo"
)
cf
.
add_section
,
"Foo"
)
def
test_write
(
self
):
def
test_write
(
self
):
c
f
=
self
.
fromstring
(
c
onfig_string
=
(
"[Long Line]
\n
"
"[Long Line]
\n
"
"foo: this line is much, much longer than my editor
\n
"
"foo: this line is much, much longer than my editor
\n
"
" likes it.
\n
"
" likes it.
\n
"
"[DEFAULT]
\n
"
"[DEFAULT]
\n
"
"foo: another very
\n
"
"foo: another very
\n
"
" long line"
" long line
\n
"
)
if
self
.
allow_no_value
:
config_string
+=
(
"[Valueless]
\n
"
"option-without-value
\n
"
)
)
cf
=
self
.
fromstring
(
config_string
)
output
=
StringIO
.
StringIO
()
output
=
StringIO
.
StringIO
()
cf
.
write
(
output
)
cf
.
write
(
output
)
self
.
assertEqual
(
expect_string
=
(
output
.
getvalue
(),
"[DEFAULT]
\n
"
"[DEFAULT]
\n
"
"foo = another very
\n
"
"foo = another very
\n
"
"
\t
long line
\n
"
"
\t
long line
\n
"
...
@@ -241,6 +263,13 @@ class TestCaseBase(unittest.TestCase):
...
@@ -241,6 +263,13 @@ class TestCaseBase(unittest.TestCase):
"
\t
likes it.
\n
"
"
\t
likes it.
\n
"
"
\n
"
"
\n
"
)
)
if
self
.
allow_no_value
:
expect_string
+=
(
"[Valueless]
\n
"
"option-without-value
\n
"
"
\n
"
)
self
.
assertEqual
(
output
.
getvalue
(),
expect_string
)
def
test_set_string_types
(
self
):
def
test_set_string_types
(
self
):
cf
=
self
.
fromstring
(
"[sect]
\n
"
cf
=
self
.
fromstring
(
"[sect]
\n
"
...
@@ -339,7 +368,7 @@ class ConfigParserTestCase(TestCaseBase):
...
@@ -339,7 +368,7 @@ class ConfigParserTestCase(TestCaseBase):
self
.
get_error
(
ConfigParser
.
InterpolationDepthError
,
"Foo"
,
"bar11"
)
self
.
get_error
(
ConfigParser
.
InterpolationDepthError
,
"Foo"
,
"bar11"
)
def
test_interpolation_missing_value
(
self
):
def
test_interpolation_missing_value
(
self
):
cf
=
self
.
get_interpolation_config
()
self
.
get_interpolation_config
()
e
=
self
.
get_error
(
ConfigParser
.
InterpolationError
,
e
=
self
.
get_error
(
ConfigParser
.
InterpolationError
,
"Interpolation Error"
,
"name"
)
"Interpolation Error"
,
"name"
)
self
.
assertEqual
(
e
.
reference
,
"reference"
)
self
.
assertEqual
(
e
.
reference
,
"reference"
)
...
@@ -459,6 +488,11 @@ class SafeConfigParserTestCase(ConfigParserTestCase):
...
@@ -459,6 +488,11 @@ class SafeConfigParserTestCase(ConfigParserTestCase):
cf
=
self
.
newconfig
()
cf
=
self
.
newconfig
()
self
.
assertRaises
(
ValueError
,
cf
.
add_section
,
"DEFAULT"
)
self
.
assertRaises
(
ValueError
,
cf
.
add_section
,
"DEFAULT"
)
class
SafeConfigParserTestCaseNoValue
(
SafeConfigParserTestCase
):
allow_no_value
=
True
class
SortedTestCase
(
RawConfigParserTestCase
):
class
SortedTestCase
(
RawConfigParserTestCase
):
def
newconfig
(
self
,
defaults
=
None
):
def
newconfig
(
self
,
defaults
=
None
):
self
.
cf
=
self
.
config_class
(
defaults
=
defaults
,
dict_type
=
SortedDict
)
self
.
cf
=
self
.
config_class
(
defaults
=
defaults
,
dict_type
=
SortedDict
)
...
@@ -483,13 +517,16 @@ class SortedTestCase(RawConfigParserTestCase):
...
@@ -483,13 +517,16 @@ class SortedTestCase(RawConfigParserTestCase):
"o3 = 2
\n
"
"o3 = 2
\n
"
"o4 = 1
\n\n
"
)
"o4 = 1
\n\n
"
)
def
test_main
():
def
test_main
():
test_support
.
run_unittest
(
test_support
.
run_unittest
(
ConfigParserTestCase
,
ConfigParserTestCase
,
RawConfigParserTestCase
,
RawConfigParserTestCase
,
SafeConfigParserTestCase
,
SafeConfigParserTestCase
,
SortedTestCase
SortedTestCase
,
)
SafeConfigParserTestCaseNoValue
,
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
test_main
()
test_main
()
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