8000 Issue #14455: plistlib now supports binary plists and has an updated … · python/cpython@c5cf797 · GitHub
[go: up one dir, main page]

Skip to content

Commit c5cf797

Browse files
Issue #14455: plistlib now supports binary plists and has an updated API.
This patch adds support for binary plists on OSX to plistlib (based on a patch by 'dpounces'). The patch also cleans up the API for the plistlib module.
1 parent 8455723 commit c5cf797

File tree

5 files changed

+1446
-426
lines changed

5 files changed

+1446
-426
lines changed

Doc/library/plistlib.rst

Lines changed: 152 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,21 @@
1616
--------------
1717

1818
This module provides an interface for reading and writing the "property list"
19-
XML files used mainly by Mac OS X.
19+
files used mainly by Mac OS X and supports both binary and XML plist files.
2020

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

25-
To write out and to parse a plist file, use the :func:`writePlist` and
26-
:func:`readPlist` functions.
25+
To write out and to parse a plist file, use the :func:`dump` and
26+
:func:`load` functions.
2727

28-
To work with plist data in bytes objects, use :func:`writePlistToBytes`
29-
and :func:`readPlistFromBytes`.
28+
To work with plist data in bytes objects, use :func:`dumps`
29+
and :func:`loads`.
3030

3131
Values can be strings, integers, floats, booleans, tuples, lists, dictionaries
32-
(but only with string keys), :class:`Data` or :class:`datetime.datetime`
33-
objects. String values (including dictionary keys) have to be unicode strings --
34-
they will be written out as UTF-8.
35-
36-
The ``<data>`` plist type is supported through the :class:`Data` class. This is
37-
a thin wrapper around a Python bytes object. Use :class:`Data` if your strings
38-
contain control characters.
32+
(but only with string keys), :class:`Data`, :class:`bytes`, :class:`bytesarray`
33+
or :class:`datetime.datetime` objects.
3934

4035
.. seealso::
4136

@@ -45,37 +40,145 @@ contain control characters.
4540

4641
This module defines the following functions:
4742

48-
.. function:: readPlist(pathOrFile)
43+
.. function:: load(fp, \*, fmt=None, use_builtin_types=True, dict_type=dict)
4944

50-
Read a plist file. *pathOrFile* may either be a file name or a (readable and
51-
binary) file object. Return the unpacked root object (which usually is a
45+
Read a plist file. *fp* should be a readable and binary file object.
46+
Return the unpacked root object (which usually is a
5247
dictionary).
5348

54-
The XML data is parsed using the Expat parser from :mod:`xml.parsers.expat`
55-
-- see its documentation for possible exceptions on ill-formed XML.
56-
Unknown elements will simply be ignored by the plist parser.
49+
The *fmt* is the format of the file and the following values are valid:
50+
51+
* :data:`None`: Autodetect the file format
52+
53+
* :data:`FMT_XML`: XML file format
54+
55+
* :data:`FMT_BINARY`: Binary plist format
56+
57+
If *use_builtin_types* is True (the default) binary data will be returned
58+
as instances of :class:`bytes`, otherwise it is returned as instances of
59+
:class:`Data`.
60+
61+
The *dict_type* is the type used for dictionaries that are read from the
62+
plist file. The exact structure of the plist can be recovered by using
63+
:class:`collections.OrderedDict` (although the order of keys shouldn't be
64+
important in plist files).
65+
66+
XML data for the :data:`FMT_XML` format is parsed using the Expat parser
67+
from :mod:`xml.parsers.expat` -- see its documentation for possible
68+
exceptions on ill-formed XML. Unknown elements will simply be ignored
69+
by the plist parser.
70+
71+
The parser for the binary format raises :exc:`InvalidFileException`
72+
when the file cannot be parsed.
73+
74+
.. versionadded:: 3.4
75+
76+
77+
.. function:: loads(data, \*, fmt=None, use_builtin_types=True, dict_type=dict)
78+
79+
Load a plist from a bytes object. See :func:`load` for an explanation of
80+
the keyword arguments.
81+
82+
83+
.. function:: dump(value, fp, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False)
84+
85+
Write *value* to a plist file. *Fp* should be a writable, binary
86+
file object.
87+
88+
The *fmt* argument specifies the format of the plist file and can be
89+
one of the following values:
90+
91+
* :data:`FMT_XML`: XML formatted plist file
92+
93+
* :data:`FMT_BINARY`: Binary formatted plist file
94+
95+
When *sort_keys* is true (the default) the keys for dictionaries will be
96+
written to the plist in sorted order, otherwise they will be written in
97+
the iteration order of the dictionary.
98+
99+
When *skipkeys* is false (the default) the function raises :exc:`TypeError`
100+
when a key of a dictionary is not a string, otherwise such keys are skipped.
101+
102+
A :exc:`TypeError` will be raised if the object is of an unsupported type or
103+
a container that contains objects of unsupported types.
104+
105+
.. versionchanged:: 3.4
106+
Added the *fmt*, *sort_keys* and *skipkeys* arguments.
107+
108+
109+
.. function:: dumps(value, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False)
110+
111+
Return *value* as a plist-formatted bytes object. See
112+
the documentation for :func:`dump` for an explanation of the keyword
113+
arguments of this function.
114+
115+
116+
The following functions are deprecated:
117+
118+
.. function:: readPlist(pathOrFile)
119+
120+
Read a plist file. *pathOrFile* may be either a file name or a (readable
121+
and binary) file object. Returns the unpacked root object (which usually
122+
is a dictionary).
123+
124+
This function calls :func:`load` to do the actual work, the the documentation
125+
of :func:`that function <load>` for an explanation of the keyword arguments.
126+
127+
.. note::
128+
129+
Dict values in the result have a ``__getattr__`` method that defers
130+
to ``__getitem_``. This means that you can use attribute access to
131+
access items of these dictionaries.
132+
133+
.. deprecated: 3.4 Use :func:`load` instead.
57134
58135
59136
.. function:: writePlist(rootObject, pathOrFile)
60137

61-
Write *rootObject* to a plist file. *pathOrFile* may either be a file name
62-
or a (writable and binary) file object.
138+
Write *rootObject* to an XML plist file. *pathOrFile* may be either a file name
139+
or a (writable and binary) file object
63140

64-
A :exc:`TypeError` will be raised if the object is of an unsupported type or
65-
a container that contains objects of unsupported types.
141+
.. deprecated: 3.4 Use :func:`dump` instead.
66142
67143
68144
.. function:: readPlistFromBytes(data)
69145

70146
Read a plist data from a bytes object. Return the root object.
71147

148+
See :func:`load` for a description of the keyword arguments.
149+
150+
.. note::
151+
152+
Dict values in the result have a ``__getattr__`` method that defers
153+
to ``__getitem_``. This means that you can use attribute access to
154+
access items of these dictionaries.
155+
156+
.. deprecated:: 3.4 Use :func:`loads` instead.
157+
72158

73159
.. function:: writePlistToBytes(rootObject)
74160

75-
Return *rootObject* as a plist-formatted bytes object.
161+
Return *rootObject* as an XML plist-formatted bytes object.
162+
163+
.. deprecated:: 3.4 Use :func:`dumps` instead.
164+
165+
.. versionchanged:: 3.4
166+
Added the *fmt*, *sort_keys* and *skipkeys* arguments.
167+
76168

169+
The following classes are available:
170+
171+
.. class:: Dict([dict]):
172+
173+
Return an extended mapping object with the same value as dictionary
174+
*dict*.
175+
176+
This class is a subclass of :class:`dict` where attribute access can
177+
be used to access items. That is, ``aDict.key`` is the same as
178+
``aDict['key']`` for getting, setting and deleting items in the mapping.
179+
180+
.. deprecated:: 3.0
77181

78-
The following class is available:
79182

80183
.. class:: Data(data)
81184

@@ -86,6 +189,24 @@ The following class is available:
86189
It has one attribute, :attr:`data`, that can be used to retrieve the Python
87190
bytes object stored in it.
88191

192+
.. deprecated:: 3.4 Use a :class:`bytes` object instead
193+
194+
195+
The following constants are avaiable:
196+
197+
.. data:: FMT_XML
198+
199+
The XML format for plist files.
200+
201+
.. versionadded:: 3.4
202+
203+
204+
.. data:: FMT_BINARY
205+
206+
The binary format for plist files
207+
208+
.. versionadded:: 3.4
209+
89210

90211
Examples
91212
--------
@@ -103,13 +224,15 @@ Generating a plist::
103224
aTrueValue = True,
104225
aFalseValue = False,
105226
),
106-
someData = Data(b"<binary gunk>"),
107-
someMoreData = Data(b"<lots of binary gunk>" * 10),
227+
someData = b"<binary gunk>",
228+
someMoreData = b"<lots of binary gunk>" * 10,
108229
aDate = datetime.datetime.fromtimestamp(time.mktime(time.gmtime())),
109230
)
110-
writePlist(pl, fileName)
231+
with open(fileName, 'wb') as fp:
232+
dump(pl, fp)
111233

112234
Parsing a plist::
113235

114-
pl = readPlist(pathOrFile)
236+
with open(fileName, 'rb') as fp:
237+
pl = load(fp)
115238
print(pl["aKey"])

0 commit comments

Comments
 (0)
0