diff -r 4f74452a11e5 Lib/plistlib.py --- a/Lib/plistlib.py Wed Apr 15 23:02:12 2015 -0400 +++ b/Lib/plistlib.py Mon Apr 27 12:59:49 2015 +0200 @@ -341,7 +341,9 @@ def add_object(self, value): if self.current_key is not None: - if not isinstance(self.stack[-1], type({})): + if isinstance(self.stack[-1], list): + # NOTE: ^^^ doesn't test for self._dict_type due to backward + # compatibility concerns raise ValueError("unexpected element at line %d" % self.parser.CurrentLineNumber) self.stack[-1][self.current_key] = value @@ -350,7 +352,7 @@ # this is the root object self.root = value else: - if not isinstance(self.stack[-1], type([])): + if not isinstance(self.stack[-1], list): raise ValueError("unexpected element at line %d" % self.parser.CurrentLineNumber) self.stack[-1].append(value) @@ -374,7 +376,9 @@ self.stack.pop() def end_key(self): - if self.current_key or not isinstance(self.stack[-1], type({})): + if self.current_key or isinstance(self.stack[-1], list): + # NOTE: ^^^ doesn't test for self._dict_type due to backward + # compatibility concerns raise ValueError("unexpected key at line %d" % self.parser.CurrentLineNumber) self.current_key = self.get_data() diff -r 4f74452a11e5 Lib/test/test_plistlib.py --- a/Lib/test/test_plistlib.py Wed Apr 15 23:02:12 2015 -0400 +++ b/Lib/test/test_plistlib.py Mon Apr 27 12:59:49 2015 +0200 @@ -264,6 +264,22 @@ else: self.assertEqual(list(pl2.keys()), ['b', 'a', 'c']) + def test_alternate_dicttype(self): + pl = { + 'a': { 'b': 'c' }, + 'b': 4, + 'c': [ 'x', 'y' ] + } + + for fmt in ALL_FORMATS: + with self.subTest(fmt=fmt): + data = plistlib.dumps(pl, fmt=fmt) + pl2 = plistlib.loads(data, dict_type=collections.UserDict) + self.assertEqual(dict(pl), dict(pl2)) + + self.assertIsInstance(pl2, collections.UserDict) + self.assertIsInstance(pl2['a'], collections.UserDict) + def test_keys_no_string(self): pl = { 42: 'aNumber' }