Issue #10489: removed broken `__name__` support from configparser
This commit is contained in:
parent
b2b2382dc4
commit
5c86339bd0
|
@ -333,10 +333,6 @@ However, there are a few differences that should be taken into account:
|
|||
|
||||
The mapping protocol is implemented on top of the existing legacy API so that
|
||||
subclassing the original interface makes the mappings work as expected as well.
|
||||
One difference is the explicit lack of support for the ``'__name__'`` special
|
||||
key. This is because the existing behavior of ``'__name__'`` is very
|
||||
inconsistent and supporting it would only lead to problems. Details `here
|
||||
<http://mail.python.org/pipermail/python-dev/2010-July/102556.html>`_.
|
||||
|
||||
|
||||
Customizing Parser Behaviour
|
||||
|
@ -947,8 +943,7 @@ The :class:`ConfigParser` class extends some methods of the
|
|||
need interpolation.
|
||||
|
||||
The values in *defaults* must be appropriate for the ``%()s`` string
|
||||
interpolation. Note that ``'__name__'`` is an intrinsic default; its value
|
||||
is the section name, and will override any value provided in *defaults*.
|
||||
interpolation.
|
||||
|
||||
All option names used in interpolation will be passed through the
|
||||
:meth:`optionxform` method just like any other option name reference. For
|
||||
|
|
|
@ -29,8 +29,7 @@ ConfigParser -- responsible for parsing a list of
|
|||
strict=False, empty_lines_in_values=True):
|
||||
Create the parser. When `defaults' is given, it is initialized into the
|
||||
dictionary or intrinsic defaults. The keys must be strings, the values
|
||||
must be appropriate for %()s string interpolation. Note that `__name__'
|
||||
is always an intrinsic default; its value is the section's name.
|
||||
must be appropriate for %()s string interpolation.
|
||||
|
||||
When `dict_type' is given, it will be used to create the dictionary
|
||||
objects for the list of sections, for the options within a section, and
|
||||
|
@ -474,8 +473,6 @@ class RawConfigParser(MutableMapping):
|
|||
except KeyError:
|
||||
raise NoSectionError(section)
|
||||
opts.update(self._defaults)
|
||||
if '__name__' in opts:
|
||||
del opts['__name__']
|
||||
return list(opts.keys())
|
||||
|
||||
def read(self, filenames, encoding=None):
|
||||
|
@ -593,8 +590,6 @@ class RawConfigParser(MutableMapping):
|
|||
d2 = self._dict()
|
||||
d = self._defaults.copy()
|
||||
d.update(d2)
|
||||
if "__name__" in d:
|
||||
del d["__name__"]
|
||||
return d.items()
|
||||
|
||||
def _get(self, section, conv, option, **kwargs):
|
||||
|
@ -675,8 +670,6 @@ class RawConfigParser(MutableMapping):
|
|||
"""Write a single section to the specified `fp'."""
|
||||
fp.write("[{}]\n".format(section_name))
|
||||
for key, value in section_items:
|
||||
if key == "__name__":
|
||||
continue
|
||||
if value is not None or not self._allow_no_value:
|
||||
value = delimiter + str(value).replace('\n', '\n\t')
|
||||
else:
|
||||
|
@ -812,7 +805,6 @@ class RawConfigParser(MutableMapping):
|
|||
cursect = self._defaults
|
||||
else:
|
||||
cursect = self._dict()
|
||||
cursect['__name__'] = sectname
|
||||
self._sections[sectname] = cursect
|
||||
self._proxies[sectname] = SectionProxy(self, sectname)
|
||||
elements_added.add(sectname)
|
||||
|
@ -1008,8 +1000,6 @@ class ConfigParser(RawConfigParser):
|
|||
for key, value in vars.items():
|
||||
d[self.optionxform(key)] = value
|
||||
options = list(d.keys())
|
||||
if "__name__" in options:
|
||||
options.remove("__name__")
|
||||
if raw:
|
||||
return [(option, d[option])
|
||||
for option in options]
|
||||
|
@ -1112,9 +1102,6 @@ class SafeConfigParser(ConfigParser):
|
|||
class SectionProxy(MutableMapping):
|
||||
"""A proxy for a single section from a parser."""
|
||||
|
||||
_noname = ("__name__ special key access and modification "
|
||||
"not supported through the mapping interface.")
|
||||
|
||||
def __init__(self, parser, section_name):
|
||||
"""Creates a view on a section named `section_name` in `parser`."""
|
||||
self._parser = parser
|
||||
|
@ -1130,37 +1117,27 @@ class SectionProxy(MutableMapping):
|
|||
return '<Section: {}>'.format(self._section)
|
||||
|
||||
def __getitem__(self, key):
|
||||
if key == '__name__':
|
||||
raise ValueError(self._noname)
|
||||
if not self._parser.has_option(self._section, key):
|
||||
raise KeyError(key)
|
||||
return self._parser.get(self._section, key)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
if key == '__name__':
|
||||
raise ValueError(self._noname)
|
||||
self._parser._validate_value_type(value)
|
||||
return self._parser.set(self._section, key, value)
|
||||
|
||||
def __delitem__(self, key):
|
||||
if key == '__name__':
|
||||
raise ValueError(self._noname)
|
||||
if not self._parser.has_option(self._section, key):
|
||||
raise KeyError(key)
|
||||
return self._parser.remove_option(self._section, key)
|
||||
|
||||
def __contains__(self, key):
|
||||
if key == '__name__':
|
||||
return False
|
||||
return self._parser.has_option(self._section, key)
|
||||
|
||||
def __len__(self):
|
||||
# __name__ is properly hidden by .options()
|
||||
# XXX weak performance
|
||||
return len(self._parser.options(self._section))
|
||||
|
||||
def __iter__(self):
|
||||
# __name__ is properly hidden by .options()
|
||||
# XXX weak performance
|
||||
# XXX does not break when underlying container state changed
|
||||
return self._parser.options(self._section).__iter__()
|
||||
|
|
|
@ -146,22 +146,6 @@ class BasicTestCase(CfgParserTestCaseClass):
|
|||
if self.allow_no_value:
|
||||
eq(cf['NoValue']['option-without-value'], None)
|
||||
|
||||
# API access
|
||||
self.assertNotIn('__name__', cf.options("Foo Bar"),
|
||||
'__name__ "option" should not be exposed by the API!')
|
||||
|
||||
# mapping access
|
||||
self.assertNotIn('__name__', cf['Foo Bar'],
|
||||
'__name__ "option" should not be exposed by '
|
||||
'mapping protocol access')
|
||||
self.assertFalse('__name__' in cf['Foo Bar'])
|
||||
with self.assertRaises(ValueError):
|
||||
cf['Foo Bar']['__name__']
|
||||
with self.assertRaises(ValueError):
|
||||
del cf['Foo Bar']['__name__']
|
||||
with self.assertRaises(ValueError):
|
||||
cf['Foo Bar']['__name__'] = "can't write to this special name"
|
||||
|
||||
# Make sure the right things happen for remove_option();
|
||||
# added to include check for SourceForge bug #123324:
|
||||
|
||||
|
@ -640,17 +624,15 @@ boolean {0[0]} NO
|
|||
"bar{equals}%(foo)s\n"
|
||||
"\n"
|
||||
"[Interpolation Error]\n"
|
||||
"name{equals}%(reference)s\n".format(equals=self.delimiters[0]),
|
||||
# no definition for 'reference'
|
||||
defaults={"getname": "%(__name__)s"})
|
||||
"name{equals}%(reference)s\n".format(equals=self.delimiters[0]))
|
||||
|
||||
def check_items_config(self, expected):
|
||||
cf = self.fromstring(
|
||||
"[section]\n"
|
||||
"name {0[0]} value\n"
|
||||
"key{0[1]} |%(name)s| \n"
|
||||
"getdefault{0[1]} |%(default)s|\n"
|
||||
"getname{0[1]} |%(__name__)s|".format(self.delimiters),
|
||||
"getdefault{0[1]} |%(default)s|\n".format(self.delimiters),
|
||||
defaults={"default": "<default>"})
|
||||
L = list(cf.items("section"))
|
||||
L.sort()
|
||||
|
@ -673,7 +655,6 @@ class ConfigParserTestCase(BasicTestCase):
|
|||
}
|
||||
cf = self.get_interpolation_config()
|
||||
eq = self.assertEqual
|
||||
eq(cf.get("Foo", "getname"), "Foo")
|
||||
eq(cf.get("Foo", "bar"), "something with interpolation (1 step)")
|
||||
eq(cf.get("Foo", "bar9"),
|
||||
"something with lots of interpolation (9 steps)")
|
||||
|
@ -699,7 +680,6 @@ class ConfigParserTestCase(BasicTestCase):
|
|||
def test_items(self):
|
||||
self.check_items_config([('default', '<default>'),
|
||||
('getdefault', '|<default>|'),
|
||||
('getname', '|section|'),
|
||||
('key', '|value|'),
|
||||
('name', 'value')])
|
||||
|
||||
|
@ -765,7 +745,6 @@ class RawConfigParserTestCase(BasicTestCase):
|
|||
def test_interpolation(self):
|
||||
cf = self.get_interpolation_config()
|
||||
eq = self.assertEqual
|
||||
eq(cf.get("Foo", "getname"), "%(__name__)s")
|
||||
eq(cf.get("Foo", "bar"),
|
||||
"something %(with1)s interpolation (1 step)")
|
||||
eq(cf.get("Foo", "bar9"),
|
||||
|
@ -778,7 +757,6 @@ class RawConfigParserTestCase(BasicTestCase):
|
|||
def test_items(self):
|
||||
self.check_items_config([('default', '<default>'),
|
||||
('getdefault', '|%(default)s|'),
|
||||
('getname', '|%(__name__)s|'),
|
||||
('key', '|%(name)s|'),
|
||||
('name', 'value')])
|
||||
|
||||
|
|
Loading…
Reference in New Issue