Author xtreak
Recipients Phil Kang, inada.naoki, lukasz.langa, xtreak
Date 2019-01-28.14:27:27
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
This seems to be a bug with read_dict which is used internally when a dictionary is directly assigned. In read_dict optionxform is called with key [0] to check for duplicate and the transformed value is again passed to self.set which also calls optionxform [1] causing optionxform to be applied twice. A possible fix would be to assign the transformed key to a temporary variable to check for duplicate and then pass the original key to self.set ? My patch gives correct value and no tests fail on master. I can make a PR with test for this if my analysis is correct.

This fixes the below since the key is stored correctly now. 

print(ini['section A']['key 1'])    # OK
print(ini['section A']['(key 1)'])  # Raises KeyError

I think for iterating over the section items [2] need to be used and the reported code can be written as below

for key, value in ini.items('section A'):
    print(key + ', ' + value)


# sample reproducer

import io
import configparser

ini = configparser.ConfigParser()
ini.optionxform = lambda x: '(' + x + ')'
ini.read_dict({'section A': {'key 1': 'value 1'}})

inifile = io.StringIO()

$ ./python.exe ../backups/
[section A]
((key 1)) = value 1

# Possible patch

$ git diff -w | cat
diff --git a/Lib/ b/Lib/
index 79a991084b..1389f4ac08 100644
--- a/Lib/
+++ b/Lib/
@@ -745,13 +745,13 @@ class RawConfigParser(MutableMapping):
             for key, value in keys.items():
-                key = self.optionxform(str(key))
+                option_key = self.optionxform(str(key))
                 if value is not None:
                     value = str(value)
-                if self._strict and (section, key) in elements_added:
-                    raise DuplicateOptionError(section, key, source)
-                elements_added.add((section, key))
-                self.set(section, key, value)
+                if self._strict and (section, option_key) in elements_added:
+                    raise DuplicateOptionError(section, option_key, source)
+                elements_added.add((section, option_key))
+                self.set(section, str(key), value)

     def readfp(self, fp, filename=None):
         """Deprecated, use read_file instead."""

$ ./python.exe ../backups/
[section A]
(key 1) = value 1
Date User Action Args
2019-01-28 14:27:29xtreaksetrecipients: + xtreak, inada.naoki, lukasz.langa, Phil Kang
2019-01-28 14:27:28xtreaksetmessageid: <>
2019-01-28 14:27:28xtreaklinkissue35838 messages
2019-01-28 14:27:27xtreakcreate