configparser: read-only attributes to get the section name and parser from a SectionProxy instance

This commit is contained in:
Łukasz Langa 2010-11-21 13:56:42 +00:00
parent 5c86339bd0
commit a73dc9d5e8
2 changed files with 34 additions and 17 deletions

View File

@ -1102,42 +1102,52 @@ class SafeConfigParser(ConfigParser):
class SectionProxy(MutableMapping): class SectionProxy(MutableMapping):
"""A proxy for a single section from a parser.""" """A proxy for a single section from a parser."""
def __init__(self, parser, section_name): def __init__(self, parser, name):
"""Creates a view on a section named `section_name` in `parser`.""" """Creates a view on a section of the specified `name` in `parser`."""
self._parser = parser self._parser = parser
self._section = section_name self._name = name
self.getint = functools.partial(self._parser.getint, self.getint = functools.partial(self._parser.getint,
self._section) self._name)
self.getfloat = functools.partial(self._parser.getfloat, self.getfloat = functools.partial(self._parser.getfloat,
self._section) self._name)
self.getboolean = functools.partial(self._parser.getboolean, self.getboolean = functools.partial(self._parser.getboolean,
self._section) self._name)
def __repr__(self): def __repr__(self):
return '<Section: {}>'.format(self._section) return '<Section: {}>'.format(self._name)
def __getitem__(self, key): def __getitem__(self, key):
if not self._parser.has_option(self._section, key): if not self._parser.has_option(self._name, key):
raise KeyError(key) raise KeyError(key)
return self._parser.get(self._section, key) return self._parser.get(self._name, key)
def __setitem__(self, key, value): def __setitem__(self, key, value):
self._parser._validate_value_type(value) self._parser._validate_value_type(value)
return self._parser.set(self._section, key, value) return self._parser.set(self._name, key, value)
def __delitem__(self, key): def __delitem__(self, key):
if not self._parser.has_option(self._section, key): if not self._parser.has_option(self._name, key):
raise KeyError(key) raise KeyError(key)
return self._parser.remove_option(self._section, key) return self._parser.remove_option(self._name, key)
def __contains__(self, key): def __contains__(self, key):
return self._parser.has_option(self._section, key) return self._parser.has_option(self._name, key)
def __len__(self): def __len__(self):
# XXX weak performance # XXX weak performance
return len(self._parser.options(self._section)) return len(self._parser.options(self._name))
def __iter__(self): def __iter__(self):
# XXX weak performance # XXX weak performance
# XXX does not break when underlying container state changed # XXX does not break when underlying container state changed
return self._parser.options(self._section).__iter__() return self._parser.options(self._name).__iter__()
@property
def parser(self):
# The parser object of the proxy is read-only.
return self._parser
@property
def name(self):
# The name of the section on a proxy is read-only.
return self._name

View File

@ -135,8 +135,15 @@ class BasicTestCase(CfgParserTestCaseClass):
# mapping access # mapping access
eq(cf['Foo Bar']['foo'], 'bar1') eq(cf['Foo Bar']['foo'], 'bar1')
eq(cf['Spacey Bar']['foo'], 'bar2') eq(cf['Spacey Bar']['foo'], 'bar2')
eq(cf['Spacey Bar From The Beginning']['foo'], 'bar3') section = cf['Spacey Bar From The Beginning']
eq(cf['Spacey Bar From The Beginning']['baz'], 'qwe') eq(section.name, 'Spacey Bar From The Beginning')
self.assertIs(section.parser, cf)
with self.assertRaises(AttributeError):
section.name = 'Name is read-only'
with self.assertRaises(AttributeError):
section.parser = 'Parser is read-only'
eq(section['foo'], 'bar3')
eq(section['baz'], 'qwe')
eq(cf['Commented Bar']['foo'], 'bar4') eq(cf['Commented Bar']['foo'], 'bar4')
eq(cf['Commented Bar']['baz'], 'qwe') eq(cf['Commented Bar']['baz'], 'qwe')
eq(cf['Spaces']['key with spaces'], 'value') eq(cf['Spaces']['key with spaces'], 'value')