-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ConfigParser getters not available on SectionProxy #62359
Comments
The configparser.RawConfigParser class implements some but if any of these get overridden on a subclass(with other arguments) or new ones are added (e.g. getlist), there's no way a SectionProxy instance will be able to use them. class DemoParser(ConfigParser):
def getlist(self, section, option):
return self.get(section, option).split()
parser = DemoParser()
parser.read(some_file)
# These 2 lines should be equivalent, like "getint", but the
# second doesn't work because of the SectionProxy instance
parser.getlist('some_section', 'foo')
parser['some_section'].getlist('foo') Reading the code, for SectionProxy, it redefines all the get* methods from RawConfigParser, and that looks pretty bad... A more elegant approach would be to fetch the function on the parser instance and bound to the section name with class SectionProxy(...):
...
def __getattr__(self, attr):
if not attr.startswith('get'):
raise AttributeError(attr)
fn = getattr(self._parser, attr)
return lambda *args, **kw: fn(self._name, *args, **kw) |
This is a reasonable feature request. Overriding __getattr__ doesn't look like the best solution, though. Let me think this over. |
Another idea would be to allow the proxy class to be selectable, but this would require the user to do much more coding for this simple thing... I believe a proxy should be dynamic enough to avoid having to duplicate every function definition. |
There are several reasons why This makes it difficult to automagically support parser >>> cp = ConfigParser()
>>> cp.converters['list'] = lambda value: value.strip().split()
>>> cp.getlist('section', 'l')
['a', 'b', 'c']
>>> cp['section'].getlist('l')
['a', 'b', 'c']
>>> cp.getdict('section', 'd')
Traceback (most recent call last):
...
AttributeError: 'ConfigParser' object has no attribute 'getdict'
>>> cp['section'].getdict('d')
Traceback (most recent call last):
...
AttributeError: 'ConfigParser' object has no attribute 'getdict' This ensures that you can easily add new converters in subclasses or single instances and that the parser-level API and section-level API work like they should. This also makes implementing custom getters easier since there's no logic involved besides the conversion. And if you happen to need custom logic anyway, you can register a converter that is a callable class. |
Was the patch accepted yet? Looks good to me |
ping? |
The reason I didn't commit that patch before was that I wasn't sure whether making this change wouldn't create any unexpected backwards incompatibility. In fact, if I committed the patch as is, it would. I solved this by leaving getint, getfloat and getboolean on the parser class and keeping _get in use. |
The new implementation also automatically covers get*() methods added on subclasses, no need to use converters= in that case. |
New changeset 2c46a4ded259 by Łukasz Langa in branch 'default': New changeset 5eb95d41ee43 by Łukasz Langa in branch 'default': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: