classification
Title: Incoherent type conversion in configparser
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Adeokkuw, lukasz.langa, remi.lapeyre, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2019-02-10 12:28 by Adeokkuw, last changed 2019-02-19 08:27 by remi.lapeyre.

Pull Requests
URL Status Linked Edit
PR 11918 open remi.lapeyre, 2019-02-18 13:08
Messages (5)
msg335150 - (view) Author: (Adeokkuw) Date: 2019-02-10 12:28
configparser interface implicitly converts all objects to str (read_dict [sic] on line 724 of "Lib/configparser.py") while saving but not while lookup (__getitem__ on line 956).

MWE:

```
config = configparser.ConfigParser()
config[123] = {}
print(config[123])
```
~> KeyError: 123
msg335151 - (view) Author: (Adeokkuw) Date: 2019-02-10 12:46
Btw: The name "read_dict" [1] as well as its docstring say exactly the opposite of what it does. It acts as a "save_dict". Maybe that can be fixed on the go ...

The docstring

""" [...]
All types held in the dictionary are converted to strings during
reading, including section names, option names and keys. [...]
"""

actually implies what is my proposal here: Convert arguments to str during lookup as well.

```
    def __getitem__(self, key):
        if key != self.default_section and not self.has_section(key):
            raise KeyError(key)
        return self._proxies[key]
```

to

```
    def __getitem__(self, key):

        try: key = str(key)
        except (WhateverError, IsRelevantHereError): raise KeyError(key)

        if key != self.default_section and not self.has_section(key):
            raise KeyError(key)
        return self._proxies[key]
```

[1] https://github.com/python/cpython/blob/3.7/Lib/configparser.py
msg335830 - (view) Author: Rémi Lapeyre (remi.lapeyre) * Date: 2019-02-18 13:08
> Btw: The name "read_dict" [1] as well as its docstring say exactly the opposite of what it does. It acts as a "save_dict". Maybe that can be fixed on the go ...


The name `read_dict` is correct, it reads from the dict given as parameter and changing the name would break existing code.

I opened a new PR with the change to convert keys to strings in __getitem__, I did not wrap `key = str(key)` in a try-except as it's not done in read_dict(). This way both __getitem__ and read_dict() will fail the same way.
msg335852 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2019-02-18 17:03
Other methods do not convert key to string too.

What is a use case for having a non-string section name?
msg335900 - (view) Author: Rémi Lapeyre (remi.lapeyre) * Date: 2019-02-19 08:27
Other methods validate explicitly their arguments with _validate_value_types for example.

Here it raises KeyError which does not seem to be the appropriate exception. ConfigParser implementing the mapping protocol it seems weird to me to have

    >>> a = 123
    >>> config[a] = {}
    >>> config[a]
    KeyError: 123

I would have prefered a TypeError to be raised on __setitem__ but this is now documented behavior.
History
Date User Action Args
2019-02-19 08:27:21remi.lapeyresetmessages: + msg335900
2019-02-18 17:03:19serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg335852
2019-02-18 13:08:32remi.lapeyresetmessages: + msg335830
2019-02-18 13:08:20remi.lapeyresetkeywords: + patch
stage: patch review
pull_requests: + pull_request11943
2019-02-10 12:52:35remi.lapeyresetnosy: + remi.lapeyre
2019-02-10 12:52:15xtreaksetnosy: + lukasz.langa
2019-02-10 12:46:09Adeokkuwsetmessages: + msg335151
2019-02-10 12:28:34Adeokkuwcreate