Skip to content

Commit bdc34d2

Browse files
committed
Support frozendict in plistlib
1 parent d3b6faf commit bdc34d2

File tree

3 files changed

+32
-13
lines changed

3 files changed

+32
-13
lines changed

Doc/library/plistlib.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ and XML plist files.
1818

1919
The property list (``.plist``) file format is a simple serialization supporting
2020
basic object types, like dictionaries, lists, numbers and strings. Usually the
21-
top level object is a dictionary.
21+
top level object is a dictionary or frozen dictionary.
2222

2323
To write out and to parse a plist file, use the :func:`dump` and
2424
:func:`load` functions.
@@ -183,12 +183,12 @@ Generating a plist::
183183
import datetime
184184
import plistlib
185185

186-
pl = dict(
186+
pl = frozendict(
187187
aString = "Doodah",
188188
aList = ["A", "B", 12, 32.1, [1, 2, 3]],
189189
aFloat = 0.1,
190190
anInt = 728,
191-
aDict = dict(
191+
aDict = frozendict(
192192
anotherString = "<hello & hi there!>",
193193
aThirdString = "M\xe4ssig, Ma\xdf",
194194
aTrueValue = True,

Lib/plistlib.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
The property list (.plist) file format is a simple XML pickle supporting
44
basic object types, like dictionaries, lists, numbers and strings.
5-
Usually the top level object is a dictionary.
5+
Usually the top level object is a dictionary or frozen dictionary.
66
77
To write out a plist file, use the dump(value, file)
88
function. 'value' is the top level object, 'file' is
@@ -24,12 +24,12 @@
2424
import datetime
2525
import plistlib
2626
27-
pl = dict(
27+
pl = frozendict(
2828
aString = "Doodah",
2929
aList = ["A", "B", 12, 32.1, [1, 2, 3]],
3030
aFloat = 0.1,
3131
anInt = 728,
32-
aDict = dict(
32+
aDict = frozendict(
3333
anotherString = "<hello & hi there!>",
3434
aThirdString = "M\xe4ssig, Ma\xdf",
3535
aTrueValue = True,
@@ -357,7 +357,7 @@ def write_value(self, value):
357357
elif isinstance(value, float):
358358
self.simple_element("real", repr(value))
359359

360-
elif isinstance(value, dict):
360+
elif isinstance(value, (dict, frozendict)):
361361
self.write_dict(value)
362362

363363
elif isinstance(value, (bytes, bytearray)):
@@ -715,7 +715,7 @@ def _flatten(self, value):
715715
self._objidtable[id(value)] = refnum
716716

717717
# And finally recurse into containers
718-
if isinstance(value, dict):
718+
if isinstance(value, (dict, frozendict)):
719719
keys = []
720720
values = []
721721
items = value.items()
@@ -836,7 +836,7 @@ def _write_object(self, value):
836836
self._write_size(0xA0, s)
837837
self._fp.write(struct.pack('>' + self._ref_format * s, *refs))
838838

839-
elif isinstance(value, dict):
839+
elif isinstance(value, (dict, frozendict)):
840840
keyRefs, valRefs = [], []
841841

842842
if self._sort_keys:
@@ -869,18 +869,18 @@ def _is_fmt_binary(header):
869869
# Generic bits
870870
#
871871

872-
_FORMATS={
873-
FMT_XML: dict(
872+
_FORMATS=frozendict({
873+
FMT_XML: frozendict(
874874
detect=_is_fmt_xml,
875875
parser=_PlistParser,
876876
writer=_PlistWriter,
877877
),
878-
FMT_BINARY: dict(
878+
FMT_BINARY: frozendict(
879879
detect=_is_fmt_binary,
880880
parser=_BinaryPlistParser,
881881
writer=_BinaryPlistWriter,
882882
)
883-
}
883+
})
884884

885885

886886
def load(fp, *, fmt=None, dict_type=dict, aware_datetime=False):

Lib/test/test_plistlib.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,25 @@ def test_dict_members(self):
792792
})
793793
self.assertIsNot(pl2['first'], pl2['second'])
794794

795+
def test_frozendict(self):
796+
pl = frozendict(
797+
aString="Doodah",
798+
anInt=728,
799+
aDict=frozendict(
800+
anotherString="hello",
801+
aTrueValue=True,
802+
),
803+
aList=["A", "B", 12],
804+
)
805+
806+
for fmt in ALL_FORMATS:
807+
with self.subTest(fmt=fmt):
808+
data = plistlib.dumps(pl, fmt=fmt)
809+
pl2 = plistlib.loads(data)
810+
self.assertEqual(pl2, dict(pl))
811+
self.assertIsInstance(pl2, dict)
812+
self.assertIsInstance(pl2['aDict'], dict)
813+
795814
def test_controlcharacters(self):
796815
for i in range(128):
797816
c = chr(i)

0 commit comments

Comments
 (0)