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
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
> 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.
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.
This is indeed inconsistent, but it's a minor issue that has been this way for a long time and is easily worked around. IMO changing it would create more problems than leaving it as-is. IMO we should at most clarify in the docs.