Issue #10489: removed broken `__name__` support from configparser

This commit is contained in:
Łukasz Langa 2010-11-21 13:41:35 +00:00
parent b2b2382dc4
commit 5c86339bd0
3 changed files with 4 additions and 54 deletions

View File

@ -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

View File

@ -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__()

View File

@ -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')])