Issue #14455: Fix some issues with plistlib
* Negative integer support in binary plists was broken * Better exception for invalid data * Fix the versionadded/versionchanged markup in the documentation * Add the interface cleanup to what's new for 3.4
This commit is contained in:
parent
4a714d48ad
commit
6db6653bbc
|
@ -79,6 +79,8 @@ This module defines the following functions:
|
||||||
Load a plist from a bytes object. See :func:`load` for an explanation of
|
Load a plist from a bytes object. See :func:`load` for an explanation of
|
||||||
the keyword arguments.
|
the keyword arguments.
|
||||||
|
|
||||||
|
.. versionadded:: 3.4
|
||||||
|
|
||||||
|
|
||||||
.. function:: dump(value, fp, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False)
|
.. function:: dump(value, fp, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False)
|
||||||
|
|
||||||
|
@ -102,8 +104,17 @@ This module defines the following functions:
|
||||||
A :exc:`TypeError` will be raised if the object is of an unsupported type or
|
A :exc:`TypeError` will be raised if the object is of an unsupported type or
|
||||||
a container that contains objects of unsupported types.
|
a container that contains objects of unsupported types.
|
||||||
|
|
||||||
.. versionchanged:: 3.4
|
An :exc:`OverflowError` will be raised for integer values that cannot
|
||||||
Added the *fmt*, *sort_keys* and *skipkeys* arguments.
|
be represented in (binary) plist files.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
For compatibility with Apple's libraries it is possible to write
|
||||||
|
an integer in the range from 2 ** 63 upto (and including) 2 ** 64
|
||||||
|
to binary plists, even though these will be read back as negative
|
||||||
|
values.
|
||||||
|
|
||||||
|
.. versionadded: 3.4
|
||||||
|
|
||||||
|
|
||||||
.. function:: dumps(value, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False)
|
.. function:: dumps(value, \*, fmt=FMT_XML, sort_keys=True, skipkeys=False)
|
||||||
|
@ -112,6 +123,7 @@ This module defines the following functions:
|
||||||
the documentation for :func:`dump` for an explanation of the keyword
|
the documentation for :func:`dump` for an explanation of the keyword
|
||||||
arguments of this function.
|
arguments of this function.
|
||||||
|
|
||||||
|
.. versionadded: 3.4
|
||||||
|
|
||||||
The following functions are deprecated:
|
The following functions are deprecated:
|
||||||
|
|
||||||
|
@ -162,9 +174,6 @@ The following functions are deprecated:
|
||||||
|
|
||||||
.. deprecated:: 3.4 Use :func:`dumps` instead.
|
.. deprecated:: 3.4 Use :func:`dumps` instead.
|
||||||
|
|
||||||
.. versionchanged:: 3.4
|
|
||||||
Added the *fmt*, *sort_keys* and *skipkeys* arguments.
|
|
||||||
|
|
||||||
|
|
||||||
The following classes are available:
|
The following classes are available:
|
||||||
|
|
||||||
|
|
|
@ -132,6 +132,8 @@ Significantly Improved Library Modules:
|
||||||
a new :mod:`~email.message.Message` subclass
|
a new :mod:`~email.message.Message` subclass
|
||||||
(:class:`~email.contentmanager.EmailMessage`) that :ref:`simplify MIME
|
(:class:`~email.contentmanager.EmailMessage`) that :ref:`simplify MIME
|
||||||
handling <whatsnew_email_contentmanager>` (:issue:`18891`).
|
handling <whatsnew_email_contentmanager>` (:issue:`18891`).
|
||||||
|
* :mod:`plistlib` has a cleaned up interface and support for binary
|
||||||
|
plist files (:issue:`14455`)
|
||||||
|
|
||||||
CPython implementation improvements:
|
CPython implementation improvements:
|
||||||
|
|
||||||
|
|
|
@ -478,7 +478,10 @@ class _PlistWriter(_DumbXMLWriter):
|
||||||
self.simple_element("false")
|
self.simple_element("false")
|
||||||
|
|
||||||
elif isinstance(value, int):
|
elif isinstance(value, int):
|
||||||
self.simple_element("integer", "%d" % value)
|
if -1 << 63 <= value < 1 << 64:
|
||||||
|
self.simple_element("integer", "%d" % value)
|
||||||
|
else:
|
||||||
|
raise OverflowError(value)
|
||||||
|
|
||||||
elif isinstance(value, float):
|
elif isinstance(value, float):
|
||||||
self.simple_element("real", repr(value))
|
self.simple_element("real", repr(value))
|
||||||
|
@ -665,7 +668,8 @@ class _BinaryPlistParser:
|
||||||
return b''
|
return b''
|
||||||
|
|
||||||
elif tokenH == 0x10: # int
|
elif tokenH == 0x10: # int
|
||||||
return int.from_bytes(self._fp.read(1 << tokenL), 'big')
|
return int.from_bytes(self._fp.read(1 << tokenL),
|
||||||
|
'big', signed=tokenL >= 3)
|
||||||
|
|
||||||
elif token == 0x22: # real
|
elif token == 0x22: # real
|
||||||
return struct.unpack('>f', self._fp.read(4))[0]
|
return struct.unpack('>f', self._fp.read(4))[0]
|
||||||
|
@ -871,14 +875,22 @@ class _BinaryPlistWriter (object):
|
||||||
self._fp.write(b'\x09')
|
self._fp.write(b'\x09')
|
||||||
|
|
||||||
elif isinstance(value, int):
|
elif isinstance(value, int):
|
||||||
if value < 1 << 8:
|
if value < 0:
|
||||||
|
try:
|
||||||
|
self._fp.write(struct.pack('>Bq', 0x13, value))
|
||||||
|
except struct.error:
|
||||||
|
raise OverflowError(value)
|
||||||
|
elif value < 1 << 8:
|
||||||
self._fp.write(struct.pack('>BB', 0x10, value))
|
self._fp.write(struct.pack('>BB', 0x10, value))
|
||||||
elif value < 1 << 16:
|
elif value < 1 << 16:
|
||||||
self._fp.write(struct.pack('>BH', 0x11, value))
|
self._fp.write(struct.pack('>BH', 0x11, value))
|
||||||
elif value < 1 << 32:
|
elif value < 1 << 32:
|
||||||
self._fp.write(struct.pack('>BL', 0x12, value))
|
self._fp.write(struct.pack('>BL', 0x12, value))
|
||||||
else:
|
else:
|
||||||
self._fp.write(struct.pack('>BQ', 0x13, value))
|
try:
|
||||||
|
self._fp.write(struct.pack('>BQ', 0x13, value))
|
||||||
|
except struct.error:
|
||||||
|
raise OverflowError(value)
|
||||||
|
|
||||||
elif isinstance(value, float):
|
elif isinstance(value, float):
|
||||||
self._fp.write(struct.pack('>Bd', 0x23, value))
|
self._fp.write(struct.pack('>Bd', 0x23, value))
|
||||||
|
@ -933,7 +945,7 @@ class _BinaryPlistWriter (object):
|
||||||
self._fp.write(struct.pack('>' + self._ref_format * s, *valRefs))
|
self._fp.write(struct.pack('>' + self._ref_format * s, *valRefs))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise InvalidFileException()
|
raise TypeError(value)
|
||||||
|
|
||||||
|
|
||||||
def _is_fmt_binary(header):
|
def _is_fmt_binary(header):
|
||||||
|
|
|
@ -7,6 +7,7 @@ import datetime
|
||||||
import codecs
|
import codecs
|
||||||
import binascii
|
import binascii
|
||||||
import collections
|
import collections
|
||||||
|
import struct
|
||||||
from test import support
|
from test import support
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
|
@ -19,68 +20,74 @@ TESTDATA={
|
||||||
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NU
|
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NU
|
||||||
WVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VO
|
WVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VO
|
||||||
IiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4w
|
IiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4w
|
||||||
LmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdD4KCTxrZXk+YURh
|
LmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdD4KCTxrZXk+YUJp
|
||||||
dGU8L2tleT4KCTxkYXRlPjIwMDQtMTAtMjZUMTA6MzM6MzNaPC9kYXRlPgoJ
|
Z0ludDwva2V5PgoJPGludGVnZXI+OTIyMzM3MjAzNjg1NDc3NTc2NDwvaW50
|
||||||
PGtleT5hRGljdDwva2V5PgoJPGRpY3Q+CgkJPGtleT5hRmFsc2VWYWx1ZTwv
|
ZWdlcj4KCTxrZXk+YURhdGU8L2tleT4KCTxkYXRlPjIwMDQtMTAtMjZUMTA6
|
||||||
a2V5PgoJCTxmYWxzZS8+CgkJPGtleT5hVHJ1ZVZhbHVlPC9rZXk+CgkJPHRy
|
MzM6MzNaPC9kYXRlPgoJPGtleT5hRGljdDwva2V5PgoJPGRpY3Q+CgkJPGtl
|
||||||
dWUvPgoJCTxrZXk+YVVuaWNvZGVWYWx1ZTwva2V5PgoJCTxzdHJpbmc+TcOk
|
eT5hRmFsc2VWYWx1ZTwva2V5PgoJCTxmYWxzZS8+CgkJPGtleT5hVHJ1ZVZh
|
||||||
c3NpZywgTWHDnzwvc3RyaW5nPgoJCTxrZXk+YW5vdGhlclN0cmluZzwva2V5
|
bHVlPC9rZXk+CgkJPHRydWUvPgoJCTxrZXk+YVVuaWNvZGVWYWx1ZTwva2V5
|
||||||
PgoJCTxzdHJpbmc+Jmx0O2hlbGxvICZhbXA7ICdoaScgdGhlcmUhJmd0Ozwv
|
PgoJCTxzdHJpbmc+TcOkc3NpZywgTWHDnzwvc3RyaW5nPgoJCTxrZXk+YW5v
|
||||||
c3RyaW5nPgoJCTxrZXk+ZGVlcGVyRGljdDwva2V5PgoJCTxkaWN0PgoJCQk8
|
dGhlclN0cmluZzwva2V5PgoJCTxzdHJpbmc+Jmx0O2hlbGxvICZhbXA7ICdo
|
||||||
a2V5PmE8L2tleT4KCQkJPGludGVnZXI+MTc8L2ludGVnZXI+CgkJCTxrZXk+
|
aScgdGhlcmUhJmd0Ozwvc3RyaW5nPgoJCTxrZXk+ZGVlcGVyRGljdDwva2V5
|
||||||
Yjwva2V5PgoJCQk8cmVhbD4zMi41PC9yZWFsPgoJCQk8a2V5PmM8L2tleT4K
|
PgoJCTxkaWN0PgoJCQk8a2V5PmE8L2tleT4KCQkJPGludGVnZXI+MTc8L2lu
|
||||||
CQkJPGFycmF5PgoJCQkJPGludGVnZXI+MTwvaW50ZWdlcj4KCQkJCTxpbnRl
|
dGVnZXI+CgkJCTxrZXk+Yjwva2V5PgoJCQk8cmVhbD4zMi41PC9yZWFsPgoJ
|
||||||
Z2VyPjI8L2ludGVnZXI+CgkJCQk8c3RyaW5nPnRleHQ8L3N0cmluZz4KCQkJ
|
CQk8a2V5PmM8L2tleT4KCQkJPGFycmF5PgoJCQkJPGludGVnZXI+MTwvaW50
|
||||||
PC9hcnJheT4KCQk8L2RpY3Q+Cgk8L2RpY3Q+Cgk8a2V5PmFGbG9hdDwva2V5
|
ZWdlcj4KCQkJCTxpbnRlZ2VyPjI8L2ludGVnZXI+CgkJCQk8c3RyaW5nPnRl
|
||||||
PgoJPHJlYWw+MC41PC9yZWFsPgoJPGtleT5hTGlzdDwva2V5PgoJPGFycmF5
|
eHQ8L3N0cmluZz4KCQkJPC9hcnJheT4KCQk8L2RpY3Q+Cgk8L2RpY3Q+Cgk8
|
||||||
PgoJCTxzdHJpbmc+QTwvc3RyaW5nPgoJCTxzdHJpbmc+Qjwvc3RyaW5nPgoJ
|
a2V5PmFGbG9hdDwva2V5PgoJPHJlYWw+MC41PC9yZWFsPgoJPGtleT5hTGlz
|
||||||
CTxpbnRlZ2VyPjEyPC9pbnRlZ2VyPgoJCTxyZWFsPjMyLjU8L3JlYWw+CgkJ
|
dDwva2V5PgoJPGFycmF5PgoJCTxzdHJpbmc+QTwvc3RyaW5nPgoJCTxzdHJp
|
||||||
PGFycmF5PgoJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJCQk8aW50ZWdlcj4y
|
bmc+Qjwvc3RyaW5nPgoJCTxpbnRlZ2VyPjEyPC9pbnRlZ2VyPgoJCTxyZWFs
|
||||||
PC9pbnRlZ2VyPgoJCQk8aW50ZWdlcj4zPC9pbnRlZ2VyPgoJCTwvYXJyYXk+
|
PjMyLjU8L3JlYWw+CgkJPGFycmF5PgoJCQk8aW50ZWdlcj4xPC9pbnRlZ2Vy
|
||||||
Cgk8L2FycmF5PgoJPGtleT5hU3RyaW5nPC9rZXk+Cgk8c3RyaW5nPkRvb2Rh
|
PgoJCQk8aW50ZWdlcj4yPC9pbnRlZ2VyPgoJCQk8aW50ZWdlcj4zPC9pbnRl
|
||||||
aDwvc3RyaW5nPgoJPGtleT5hbkVtcHR5RGljdDwva2V5PgoJPGRpY3QvPgoJ
|
Z2VyPgoJCTwvYXJyYXk+Cgk8L2FycmF5PgoJPGtleT5hTmVnYXRpdmVCaWdJ
|
||||||
PGtleT5hbkVtcHR5TGlzdDwva2V5PgoJPGFycmF5Lz4KCTxrZXk+YW5JbnQ8
|
bnQ8L2tleT4KCTxpbnRlZ2VyPi04MDAwMDAwMDAwMDwvaW50ZWdlcj4KCTxr
|
||||||
L2tleT4KCTxpbnRlZ2VyPjcyODwvaW50ZWdlcj4KCTxrZXk+bmVzdGVkRGF0
|
ZXk+YU5lZ2F0aXZlSW50PC9rZXk+Cgk8aW50ZWdlcj4tNTwvaW50ZWdlcj4K
|
||||||
YTwva2V5PgoJPGFycmF5PgoJCTxkYXRhPgoJCVBHeHZkSE1nYjJZZ1ltbHVZ
|
CTxrZXk+YVN0cmluZzwva2V5PgoJPHN0cmluZz5Eb29kYWg8L3N0cmluZz4K
|
||||||
WEo1SUdkMWJtcytBQUVDQXp4c2IzUnpJRzltSUdKcGJtRnllU0JuZFc1cgoJ
|
CTxrZXk+YW5FbXB0eURpY3Q8L2tleT4KCTxkaWN0Lz4KCTxrZXk+YW5FbXB0
|
||||||
CVBnQUJBZ004Ykc5MGN5QnZaaUJpYVc1aGNua2daM1Z1YXo0QUFRSURQR3h2
|
eUxpc3Q8L2tleT4KCTxhcnJheS8+Cgk8a2V5PmFuSW50PC9rZXk+Cgk8aW50
|
||||||
ZEhNZ2IyWWdZbWx1WVhKNQoJCUlHZDFibXMrQUFFQ0F6eHNiM1J6SUc5bUlH
|
ZWdlcj43Mjg8L2ludGVnZXI+Cgk8a2V5Pm5lc3RlZERhdGE8L2tleT4KCTxh
|
||||||
SnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOGJHOTBjeUJ2WmlCaQoJCWFXNWhjbmtn
|
cnJheT4KCQk8ZGF0YT4KCQlQR3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMr
|
||||||
WjNWdWF6NEFBUUlEUEd4dmRITWdiMllnWW1sdVlYSjVJR2QxYm1zK0FBRUNB
|
QUFFQ0F6eHNiM1J6SUc5bUlHSnBibUZ5ZVNCbmRXNXIKCQlQZ0FCQWdNOGJH
|
||||||
enhzYjNSegoJCUlHOW1JR0pwYm1GeWVTQm5kVzVyUGdBQkFnTThiRzkwY3lC
|
OTBjeUJ2WmlCaWFXNWhjbmtnWjNWdWF6NEFBUUlEUEd4dmRITWdiMllnWW1s
|
||||||
dlppQmlhVzVoY25rZ1ozVnVhejRBQVFJRAoJCVBHeHZkSE1nYjJZZ1ltbHVZ
|
dVlYSjUKCQlJR2QxYm1zK0FBRUNBenhzYjNSeklHOW1JR0pwYm1GeWVTQm5k
|
||||||
WEo1SUdkMWJtcytBQUVDQXc9PQoJCTwvZGF0YT4KCTwvYXJyYXk+Cgk8a2V5
|
VzVyUGdBQkFnTThiRzkwY3lCdlppQmkKCQlhVzVoY25rZ1ozVnVhejRBQVFJ
|
||||||
PnNvbWVEYXRhPC9rZXk+Cgk8ZGF0YT4KCVBHSnBibUZ5ZVNCbmRXNXJQZz09
|
RFBHeHZkSE1nYjJZZ1ltbHVZWEo1SUdkMWJtcytBQUVDQXp4c2IzUnoKCQlJ
|
||||||
Cgk8L2RhdGE+Cgk8a2V5PnNvbWVNb3JlRGF0YTwva2V5PgoJPGRhdGE+CglQ
|
RzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004Ykc5MGN5QnZaaUJpYVc1aGNu
|
||||||
R3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMrQUFFQ0F6eHNiM1J6SUc5bUlH
|
a2daM1Z1YXo0QUFRSUQKCQlQR3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMr
|
||||||
SnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOAoJYkc5MGN5QnZaaUJpYVc1aGNua2da
|
QUFFQ0F3PT0KCQk8L2RhdGE+Cgk8L2FycmF5PgoJPGtleT5zb21lRGF0YTwv
|
||||||
M1Z1YXo0QUFRSURQR3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMrQUFFQ0F6
|
a2V5PgoJPGRhdGE+CglQR0pwYm1GeWVTQm5kVzVyUGc9PQoJPC9kYXRhPgoJ
|
||||||
eHMKCWIzUnpJRzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004Ykc5MGN5QnZa
|
PGtleT5zb21lTW9yZURhdGE8L2tleT4KCTxkYXRhPgoJUEd4dmRITWdiMlln
|
||||||
aUJpYVc1aGNua2daM1Z1YXo0QUFRSURQR3h2CglkSE1nYjJZZ1ltbHVZWEo1
|
WW1sdVlYSjVJR2QxYm1zK0FBRUNBenhzYjNSeklHOW1JR0pwYm1GeWVTQm5k
|
||||||
SUdkMWJtcytBQUVDQXp4c2IzUnpJRzltSUdKcGJtRnllU0JuZFc1clBnQUJB
|
VzVyUGdBQkFnTTgKCWJHOTBjeUJ2WmlCaWFXNWhjbmtnWjNWdWF6NEFBUUlE
|
||||||
Z004Ykc5MAoJY3lCdlppQmlhVzVoY25rZ1ozVnVhejRBQVFJRFBHeHZkSE1n
|
UEd4dmRITWdiMllnWW1sdVlYSjVJR2QxYm1zK0FBRUNBenhzCgliM1J6SUc5
|
||||||
YjJZZ1ltbHVZWEo1SUdkMWJtcytBQUVDQXc9PQoJPC9kYXRhPgoJPGtleT7D
|
bUlHSnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOGJHOTBjeUJ2WmlCaWFXNWhjbmtn
|
||||||
hWJlbnJhYTwva2V5PgoJPHN0cmluZz5UaGF0IHdhcyBhIHVuaWNvZGUga2V5
|
WjNWdWF6NEFBUUlEUEd4dgoJZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMrQUFF
|
||||||
Ljwvc3RyaW5nPgo8L2RpY3Q+CjwvcGxpc3Q+Cg=='''),
|
Q0F6eHNiM1J6SUc5bUlHSnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOGJHOTAKCWN5
|
||||||
|
QnZaaUJpYVc1aGNua2daM1Z1YXo0QUFRSURQR3h2ZEhNZ2IyWWdZbWx1WVhK
|
||||||
|
NUlHZDFibXMrQUFFQ0F3PT0KCTwvZGF0YT4KCTxrZXk+w4ViZW5yYWE8L2tl
|
||||||
|
eT4KCTxzdHJpbmc+VGhhdCB3YXMgYSB1bmljb2RlIGtleS48L3N0cmluZz4K
|
||||||
|
PC9kaWN0Pgo8L3BsaXN0Pgo='''),
|
||||||
plistlib.FMT_BINARY: binascii.a2b_base64(b'''
|
plistlib.FMT_BINARY: binascii.a2b_base64(b'''
|
||||||
YnBsaXN0MDDcAQIDBAUGBwgJCgsMDQ4iIykqKywtLy4wVWFEYXRlVWFEaWN0
|
YnBsaXN0MDDfEA8BAgMEBQYHCAkKCwwNDg8QERImJy0uLzAxMjM1NDZXYUJp
|
||||||
VmFGbG9hdFVhTGlzdFdhU3RyaW5nW2FuRW1wdHlEaWN0W2FuRW1wdHlMaXN0
|
Z0ludFVhRGF0ZVVhRGljdFZhRmxvYXRVYUxpc3RfEA9hTmVnYXRpdmVCaWdJ
|
||||||
VWFuSW50Wm5lc3RlZERhdGFYc29tZURhdGFcc29tZU1vcmVEYXRhZwDFAGIA
|
bnRcYU5lZ2F0aXZlSW50V2FTdHJpbmdbYW5FbXB0eURpY3RbYW5FbXB0eUxp
|
||||||
ZQBuAHIAYQBhM0GcuX30AAAA1Q8QERITFBUWFxhbYUZhbHNlVmFsdWVaYVRy
|
c3RVYW5JbnRabmVzdGVkRGF0YVhzb21lRGF0YVxzb21lTW9yZURhdGFnAMUA
|
||||||
dWVWYWx1ZV1hVW5pY29kZVZhbHVlXWFub3RoZXJTdHJpbmdaZGVlcGVyRGlj
|
YgBlAG4AcgBhAGETf////////9QzQZy5ffQAAADVExQVFhcYGRobHFthRmFs
|
||||||
dAgJawBNAOQAcwBzAGkAZwAsACAATQBhAN9fEBU8aGVsbG8gJiAnaGknIHRo
|
c2VWYWx1ZVphVHJ1ZVZhbHVlXWFVbmljb2RlVmFsdWVdYW5vdGhlclN0cmlu
|
||||||
ZXJlIT7TGRobHB0eUWFRYlFjEBEjQEBAAAAAAACjHyAhEAEQAlR0ZXh0Iz/g
|
Z1pkZWVwZXJEaWN0CAlrAE0A5ABzAHMAaQBnACwAIABNAGEA318QFTxoZWxs
|
||||||
AAAAAAAApSQlJh0nUUFRQhAMox8gKBADVkRvb2RhaNCgEQLYoS5PEPo8bG90
|
byAmICdoaScgdGhlcmUhPtMdHh8gISJRYVFiUWMQESNAQEAAAAAAAKMjJCUQ
|
||||||
cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAEC
|
ARACVHRleHQjP+AAAAAAAAClKCkqIStRQVFCEAyjIyQsEAMT////7V+g4AAT
|
||||||
Azxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vu
|
//////////tWRG9vZGFo0KARAtihNE8Q+jxsb3RzIG9mIGJpbmFyeSBndW5r
|
||||||
az4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFy
|
PgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5
|
||||||
eSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2Yg
|
IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBi
|
||||||
YmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90
|
aW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3Rz
|
||||||
cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDTTxiaW5hcnkgZ3Vuaz5fEBdUaGF0IHdh
|
IG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQID
|
||||||
cyBhIHVuaWNvZGUga2V5LgAIACEAJwAtADQAOgBCAE4AWgBgAGsAdACBAJAA
|
PGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5r
|
||||||
mQCkALAAuwDJANcA4gDjAOQA+wETARoBHAEeASABIgErAS8BMQEzATgBQQFH
|
PgABAgNNPGJpbmFyeSBndW5rPl8QF1RoYXQgd2FzIGEgdW5pY29kZSBrZXku
|
||||||
AUkBSwFNAVEBUwFaAVsBXAFfAWECXgJsAAAAAAAAAgEAAAAAAAAAMQAAAAAA
|
AAgAKQAxADcAPQBEAEoAXABpAHEAfQCJAI8AmgCjALAAvwDIANEA3ADoAPMB
|
||||||
AAAAAAAAAAAAAoY='''),
|
AQEPARoBGwEcATMBSwFSAVQBVgFYAVoBYwFnAWkBawFwAXkBfwGBAYMBhQGJ
|
||||||
|
AYsBlAGdAaQBpQGmAakBqwKoArYAAAAAAAACAQAAAAAAAAA3AAAAAAAAAAAA
|
||||||
|
AAAAAAAC0A=='''),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,6 +105,9 @@ class TestPlistlib(unittest.TestCase):
|
||||||
aList=["A", "B", 12, 32.5, [1, 2, 3]],
|
aList=["A", "B", 12, 32.5, [1, 2, 3]],
|
||||||
aFloat = 0.5,
|
aFloat = 0.5,
|
||||||
anInt = 728,
|
anInt = 728,
|
||||||
|
aBigInt = 2 ** 63 - 44,
|
||||||
|
aNegativeInt = -5,
|
||||||
|
aNegativeBigInt = -80000000000,
|
||||||
aDict=dict(
|
aDict=dict(
|
||||||
anotherString="<hello & 'hi' there!>",
|
anotherString="<hello & 'hi' there!>",
|
||||||
aUnicodeValue='M\xe4ssig, Ma\xdf',
|
aUnicodeValue='M\xe4ssig, Ma\xdf',
|
||||||
|
@ -133,6 +143,30 @@ class TestPlistlib(unittest.TestCase):
|
||||||
self.assertRaises(AttributeError, plistlib.dump, pl, 'filename')
|
self.assertRaises(AttributeError, plistlib.dump, pl, 'filename')
|
||||||
self.assertRaises(AttributeError, plistlib.load, 'filename')
|
self.assertRaises(AttributeError, plistlib.load, 'filename')
|
||||||
|
|
||||||
|
def test_invalid_type(self):
|
||||||
|
pl = [ object() ]
|
||||||
|
|
||||||
|
for fmt in ALL_FORMATS:
|
||||||
|
with self.subTest(fmt=fmt):
|
||||||
|
self.assertRaises(TypeError, plistlib.dumps, pl, fmt=fmt)
|
||||||
|
|
||||||
|
def test_int(self):
|
||||||
|
for pl in [0, 2**8-1, 2**8, 2**16-1, 2**16, 2**32-1, 2**32,
|
||||||
|
2**63-1, 1, -2**63]:
|
||||||
|
for fmt in ALL_FORMATS:
|
||||||
|
with self.subTest(pl=pl, fmt=fmt):
|
||||||
|
data = plistlib.dumps(pl, fmt=fmt)
|
||||||
|
pl2 = plistlib.loads(data)
|
||||||
|
self.assertIsInstance(pl2, int)
|
||||||
|
self.assertEqual(pl, pl2)
|
||||||
|
data2 = plistlib.dumps(pl2, fmt=fmt)
|
||||||
|
self.assertEqual(data, data2)
|
||||||
|
|
||||||
|
for fmt in ALL_FORMATS:
|
||||||
|
for pl in (2 ** 64 + 1, 2 ** 127-1, -2**64, -2 ** 127):
|
||||||
|
with self.subTest(pl=pl, fmt=fmt):
|
||||||
|
self.assertRaises(OverflowError, plistlib.dumps,
|
||||||
|
pl, fmt=fmt)
|
||||||
|
|
||||||
def test_bytes(self):
|
def test_bytes(self):
|
||||||
pl = self._create()
|
pl = self._create()
|
||||||
|
|
|
@ -23,7 +23,13 @@ def nsstr(value):
|
||||||
def main():
|
def main():
|
||||||
pl = OrderedDict()
|
pl = OrderedDict()
|
||||||
|
|
||||||
|
# Note: pl is an OrderedDict to control the order
|
||||||
|
# of keys, and hence have some control on the structure
|
||||||
|
# of the output file.
|
||||||
|
# New keys should be added in alphabetical order.
|
||||||
|
|
||||||
seconds = datetime.datetime(2004, 10, 26, 10, 33, 33, tzinfo=datetime.timezone(datetime.timedelta(0))).timestamp()
|
seconds = datetime.datetime(2004, 10, 26, 10, 33, 33, tzinfo=datetime.timezone(datetime.timedelta(0))).timestamp()
|
||||||
|
pl[nsstr('aBigInt')] = 2 ** 63 - 44
|
||||||
pl[nsstr('aDate')] = NSDate.dateWithTimeIntervalSince1970_(seconds)
|
pl[nsstr('aDate')] = NSDate.dateWithTimeIntervalSince1970_(seconds)
|
||||||
|
|
||||||
pl[nsstr('aDict')] = d = OrderedDict()
|
pl[nsstr('aDict')] = d = OrderedDict()
|
||||||
|
@ -52,6 +58,8 @@ def main():
|
||||||
aa.append(2)
|
aa.append(2)
|
||||||
aa.append(3)
|
aa.append(3)
|
||||||
|
|
||||||
|
pl[nsstr('aNegativeBigInt')] = -80000000000
|
||||||
|
pl[nsstr('aNegativeInt')] = -5
|
||||||
pl[nsstr('aString')] = nsstr('Doodah')
|
pl[nsstr('aString')] = nsstr('Doodah')
|
||||||
|
|
||||||
pl[nsstr('anEmptyDict')] = NSMutableDictionary.alloc().init()
|
pl[nsstr('anEmptyDict')] = NSMutableDictionary.alloc().init()
|
||||||
|
|
Loading…
Reference in New Issue