ยปCore Development>Code coverage>Lib/test/test_plistlib.py

Python code coverage for Lib/test/test_plistlib.py

#countcontent
1n/a# Copyright (C) 2003-2013 Python Software Foundation
2n/a
3n/aimport unittest
4n/aimport plistlib
5n/aimport os
6n/aimport datetime
7n/aimport codecs
8n/aimport binascii
9n/aimport collections
10n/afrom test import support
11n/afrom io import BytesIO
12n/a
13n/aALL_FORMATS=(plistlib.FMT_XML, plistlib.FMT_BINARY)
14n/a
15n/a# The testdata is generated using Mac/Tools/plistlib_generate_testdata.py
16n/a# (which using PyObjC to control the Cocoa classes for generating plists)
17n/aTESTDATA={
18n/a plistlib.FMT_XML: binascii.a2b_base64(b'''
19n/a PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NU
20n/a WVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VO
21n/a IiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4w
22n/a LmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdD4KCTxrZXk+YUJp
23n/a Z0ludDwva2V5PgoJPGludGVnZXI+OTIyMzM3MjAzNjg1NDc3NTc2NDwvaW50
24n/a ZWdlcj4KCTxrZXk+YUJpZ0ludDI8L2tleT4KCTxpbnRlZ2VyPjkyMjMzNzIw
25n/a MzY4NTQ3NzU4NTI8L2ludGVnZXI+Cgk8a2V5PmFEYXRlPC9rZXk+Cgk8ZGF0
26n/a ZT4yMDA0LTEwLTI2VDEwOjMzOjMzWjwvZGF0ZT4KCTxrZXk+YURpY3Q8L2tl
27n/a eT4KCTxkaWN0PgoJCTxrZXk+YUZhbHNlVmFsdWU8L2tleT4KCQk8ZmFsc2Uv
28n/a PgoJCTxrZXk+YVRydWVWYWx1ZTwva2V5PgoJCTx0cnVlLz4KCQk8a2V5PmFV
29n/a bmljb2RlVmFsdWU8L2tleT4KCQk8c3RyaW5nPk3DpHNzaWcsIE1hw588L3N0
30n/a cmluZz4KCQk8a2V5PmFub3RoZXJTdHJpbmc8L2tleT4KCQk8c3RyaW5nPiZs
31n/a dDtoZWxsbyAmYW1wOyAnaGknIHRoZXJlISZndDs8L3N0cmluZz4KCQk8a2V5
32n/a PmRlZXBlckRpY3Q8L2tleT4KCQk8ZGljdD4KCQkJPGtleT5hPC9rZXk+CgkJ
33n/a CTxpbnRlZ2VyPjE3PC9pbnRlZ2VyPgoJCQk8a2V5PmI8L2tleT4KCQkJPHJl
34n/a YWw+MzIuNTwvcmVhbD4KCQkJPGtleT5jPC9rZXk+CgkJCTxhcnJheT4KCQkJ
35n/a CTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8aW50ZWdlcj4yPC9pbnRlZ2Vy
36n/a PgoJCQkJPHN0cmluZz50ZXh0PC9zdHJpbmc+CgkJCTwvYXJyYXk+CgkJPC9k
37n/a aWN0PgoJPC9kaWN0PgoJPGtleT5hRmxvYXQ8L2tleT4KCTxyZWFsPjAuNTwv
38n/a cmVhbD4KCTxrZXk+YUxpc3Q8L2tleT4KCTxhcnJheT4KCQk8c3RyaW5nPkE8
39n/a L3N0cmluZz4KCQk8c3RyaW5nPkI8L3N0cmluZz4KCQk8aW50ZWdlcj4xMjwv
40n/a aW50ZWdlcj4KCQk8cmVhbD4zMi41PC9yZWFsPgoJCTxhcnJheT4KCQkJPGlu
41n/a dGVnZXI+MTwvaW50ZWdlcj4KCQkJPGludGVnZXI+MjwvaW50ZWdlcj4KCQkJ
42n/a PGludGVnZXI+MzwvaW50ZWdlcj4KCQk8L2FycmF5PgoJPC9hcnJheT4KCTxr
43n/a ZXk+YU5lZ2F0aXZlQmlnSW50PC9rZXk+Cgk8aW50ZWdlcj4tODAwMDAwMDAw
44n/a MDA8L2ludGVnZXI+Cgk8a2V5PmFOZWdhdGl2ZUludDwva2V5PgoJPGludGVn
45n/a ZXI+LTU8L2ludGVnZXI+Cgk8a2V5PmFTdHJpbmc8L2tleT4KCTxzdHJpbmc+
46n/a RG9vZGFoPC9zdHJpbmc+Cgk8a2V5PmFuRW1wdHlEaWN0PC9rZXk+Cgk8ZGlj
47n/a dC8+Cgk8a2V5PmFuRW1wdHlMaXN0PC9rZXk+Cgk8YXJyYXkvPgoJPGtleT5h
48n/a bkludDwva2V5PgoJPGludGVnZXI+NzI4PC9pbnRlZ2VyPgoJPGtleT5uZXN0
49n/a ZWREYXRhPC9rZXk+Cgk8YXJyYXk+CgkJPGRhdGE+CgkJUEd4dmRITWdiMlln
50n/a WW1sdVlYSjVJR2QxYm1zK0FBRUNBenhzYjNSeklHOW1JR0pwYm1GeWVTQm5k
51n/a VzVyCgkJUGdBQkFnTThiRzkwY3lCdlppQmlhVzVoY25rZ1ozVnVhejRBQVFJ
52n/a RFBHeHZkSE1nYjJZZ1ltbHVZWEo1CgkJSUdkMWJtcytBQUVDQXp4c2IzUnpJ
53n/a RzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004Ykc5MGN5QnZaaUJpCgkJYVc1
54n/a aGNua2daM1Z1YXo0QUFRSURQR3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMr
55n/a QUFFQ0F6eHNiM1J6CgkJSUc5bUlHSnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOGJH
56n/a OTBjeUJ2WmlCaWFXNWhjbmtnWjNWdWF6NEFBUUlECgkJUEd4dmRITWdiMlln
57n/a WW1sdVlYSjVJR2QxYm1zK0FBRUNBdz09CgkJPC9kYXRhPgoJPC9hcnJheT4K
58n/a CTxrZXk+c29tZURhdGE8L2tleT4KCTxkYXRhPgoJUEdKcGJtRnllU0JuZFc1
59n/a clBnPT0KCTwvZGF0YT4KCTxrZXk+c29tZU1vcmVEYXRhPC9rZXk+Cgk8ZGF0
60n/a YT4KCVBHeHZkSE1nYjJZZ1ltbHVZWEo1SUdkMWJtcytBQUVDQXp4c2IzUnpJ
61n/a RzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004CgliRzkwY3lCdlppQmlhVzVo
62n/a Y25rZ1ozVnVhejRBQVFJRFBHeHZkSE1nYjJZZ1ltbHVZWEo1SUdkMWJtcytB
63n/a QUVDQXp4cwoJYjNSeklHOW1JR0pwYm1GeWVTQm5kVzVyUGdBQkFnTThiRzkw
64n/a Y3lCdlppQmlhVzVoY25rZ1ozVnVhejRBQVFJRFBHeHYKCWRITWdiMllnWW1s
65n/a dVlYSjVJR2QxYm1zK0FBRUNBenhzYjNSeklHOW1JR0pwYm1GeWVTQm5kVzVy
66n/a UGdBQkFnTThiRzkwCgljeUJ2WmlCaWFXNWhjbmtnWjNWdWF6NEFBUUlEUEd4
67n/a dmRITWdiMllnWW1sdVlYSjVJR2QxYm1zK0FBRUNBdz09Cgk8L2RhdGE+Cgk8
68n/a a2V5PsOFYmVucmFhPC9rZXk+Cgk8c3RyaW5nPlRoYXQgd2FzIGEgdW5pY29k
69n/a ZSBrZXkuPC9zdHJpbmc+CjwvZGljdD4KPC9wbGlzdD4K'''),
70n/a plistlib.FMT_BINARY: binascii.a2b_base64(b'''
71n/a YnBsaXN0MDDfEBABAgMEBQYHCAkKCwwNDg8QERITFCgpLzAxMjM0NTc2OFdh
72n/a QmlnSW50WGFCaWdJbnQyVWFEYXRlVWFEaWN0VmFGbG9hdFVhTGlzdF8QD2FO
73n/a ZWdhdGl2ZUJpZ0ludFxhTmVnYXRpdmVJbnRXYVN0cmluZ1thbkVtcHR5RGlj
74n/a dFthbkVtcHR5TGlzdFVhbkludFpuZXN0ZWREYXRhWHNvbWVEYXRhXHNvbWVN
75n/a b3JlRGF0YWcAxQBiAGUAbgByAGEAYRN/////////1BQAAAAAAAAAAIAAAAAA
76n/a AAAsM0GcuX30AAAA1RUWFxgZGhscHR5bYUZhbHNlVmFsdWVaYVRydWVWYWx1
77n/a ZV1hVW5pY29kZVZhbHVlXWFub3RoZXJTdHJpbmdaZGVlcGVyRGljdAgJawBN
78n/a AOQAcwBzAGkAZwAsACAATQBhAN9fEBU8aGVsbG8gJiAnaGknIHRoZXJlIT7T
79n/a HyAhIiMkUWFRYlFjEBEjQEBAAAAAAACjJSYnEAEQAlR0ZXh0Iz/gAAAAAAAA
80n/a pSorLCMtUUFRQhAMoyUmLhADE////+1foOAAE//////////7VkRvb2RhaNCg
81n/a EQLYoTZPEPo8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmlu
82n/a YXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBv
83n/a ZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxs
84n/a b3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4A
85n/a AQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBn
86n/a dW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDTTxiaW5hcnkgZ3Vu
87n/a az5fEBdUaGF0IHdhcyBhIHVuaWNvZGUga2V5LgAIACsAMwA8AEIASABPAFUA
88n/a ZwB0AHwAiACUAJoApQCuALsAygDTAOQA7QD4AQQBDwEdASsBNgE3ATgBTwFn
89n/a AW4BcAFyAXQBdgF/AYMBhQGHAYwBlQGbAZ0BnwGhAaUBpwGwAbkBwAHBAcIB
90n/a xQHHAsQC0gAAAAAAAAIBAAAAAAAAADkAAAAAAAAAAAAAAAAAAALs'''),
91n/a}
92n/a
93n/a
94n/aclass TestPlistlib(unittest.TestCase):
95n/a
96n/a def tearDown(self):
97n/a try:
98n/a os.unlink(support.TESTFN)
99n/a except:
100n/a pass
101n/a
102n/a def _create(self, fmt=None):
103n/a pl = dict(
104n/a aString="Doodah",
105n/a aList=["A", "B", 12, 32.5, [1, 2, 3]],
106n/a aFloat = 0.5,
107n/a anInt = 728,
108n/a aBigInt = 2 ** 63 - 44,
109n/a aBigInt2 = 2 ** 63 + 44,
110n/a aNegativeInt = -5,
111n/a aNegativeBigInt = -80000000000,
112n/a aDict=dict(
113n/a anotherString="<hello & 'hi' there!>",
114n/a aUnicodeValue='M\xe4ssig, Ma\xdf',
115n/a aTrueValue=True,
116n/a aFalseValue=False,
117n/a deeperDict=dict(a=17, b=32.5, c=[1, 2, "text"]),
118n/a ),
119n/a someData = b"<binary gunk>",
120n/a someMoreData = b"<lots of binary gunk>\0\1\2\3" * 10,
121n/a nestedData = [b"<lots of binary gunk>\0\1\2\3" * 10],
122n/a aDate = datetime.datetime(2004, 10, 26, 10, 33, 33),
123n/a anEmptyDict = dict(),
124n/a anEmptyList = list()
125n/a )
126n/a pl['\xc5benraa'] = "That was a unicode key."
127n/a return pl
128n/a
129n/a def test_create(self):
130n/a pl = self._create()
131n/a self.assertEqual(pl["aString"], "Doodah")
132n/a self.assertEqual(pl["aDict"]["aFalseValue"], False)
133n/a
134n/a def test_io(self):
135n/a pl = self._create()
136n/a with open(support.TESTFN, 'wb') as fp:
137n/a plistlib.dump(pl, fp)
138n/a
139n/a with open(support.TESTFN, 'rb') as fp:
140n/a pl2 = plistlib.load(fp)
141n/a
142n/a self.assertEqual(dict(pl), dict(pl2))
143n/a
144n/a self.assertRaises(AttributeError, plistlib.dump, pl, 'filename')
145n/a self.assertRaises(AttributeError, plistlib.load, 'filename')
146n/a
147n/a def test_invalid_type(self):
148n/a pl = [ object() ]
149n/a
150n/a for fmt in ALL_FORMATS:
151n/a with self.subTest(fmt=fmt):
152n/a self.assertRaises(TypeError, plistlib.dumps, pl, fmt=fmt)
153n/a
154n/a def test_int(self):
155n/a for pl in [0, 2**8-1, 2**8, 2**16-1, 2**16, 2**32-1, 2**32,
156n/a 2**63-1, 2**64-1, 1, -2**63]:
157n/a for fmt in ALL_FORMATS:
158n/a with self.subTest(pl=pl, fmt=fmt):
159n/a data = plistlib.dumps(pl, fmt=fmt)
160n/a pl2 = plistlib.loads(data)
161n/a self.assertIsInstance(pl2, int)
162n/a self.assertEqual(pl, pl2)
163n/a data2 = plistlib.dumps(pl2, fmt=fmt)
164n/a self.assertEqual(data, data2)
165n/a
166n/a for fmt in ALL_FORMATS:
167n/a for pl in (2 ** 64 + 1, 2 ** 127-1, -2**64, -2 ** 127):
168n/a with self.subTest(pl=pl, fmt=fmt):
169n/a self.assertRaises(OverflowError, plistlib.dumps,
170n/a pl, fmt=fmt)
171n/a
172n/a def test_bytes(self):
173n/a pl = self._create()
174n/a data = plistlib.dumps(pl)
175n/a pl2 = plistlib.loads(data)
176n/a self.assertNotIsInstance(pl, plistlib._InternalDict)
177n/a self.assertEqual(dict(pl), dict(pl2))
178n/a data2 = plistlib.dumps(pl2)
179n/a self.assertEqual(data, data2)
180n/a
181n/a def test_indentation_array(self):
182n/a data = [[[[[[[[{'test': b'aaaaaa'}]]]]]]]]
183n/a self.assertEqual(plistlib.loads(plistlib.dumps(data)), data)
184n/a
185n/a def test_indentation_dict(self):
186n/a data = {'1': {'2': {'3': {'4': {'5': {'6': {'7': {'8': {'9': b'aaaaaa'}}}}}}}}}
187n/a self.assertEqual(plistlib.loads(plistlib.dumps(data)), data)
188n/a
189n/a def test_indentation_dict_mix(self):
190n/a data = {'1': {'2': [{'3': [[[[[{'test': b'aaaaaa'}]]]]]}]}}
191n/a self.assertEqual(plistlib.loads(plistlib.dumps(data)), data)
192n/a
193n/a def test_appleformatting(self):
194n/a for use_builtin_types in (True, False):
195n/a for fmt in ALL_FORMATS:
196n/a with self.subTest(fmt=fmt, use_builtin_types=use_builtin_types):
197n/a pl = plistlib.loads(TESTDATA[fmt],
198n/a use_builtin_types=use_builtin_types)
199n/a data = plistlib.dumps(pl, fmt=fmt)
200n/a self.assertEqual(data, TESTDATA[fmt],
201n/a "generated data was not identical to Apple's output")
202n/a
203n/a
204n/a def test_appleformattingfromliteral(self):
205n/a self.maxDiff = None
206n/a for fmt in ALL_FORMATS:
207n/a with self.subTest(fmt=fmt):
208n/a pl = self._create(fmt=fmt)
209n/a pl2 = plistlib.loads(TESTDATA[fmt], fmt=fmt)
210n/a self.assertEqual(dict(pl), dict(pl2),
211n/a "generated data was not identical to Apple's output")
212n/a pl2 = plistlib.loads(TESTDATA[fmt])
213n/a self.assertEqual(dict(pl), dict(pl2),
214n/a "generated data was not identical to Apple's output")
215n/a
216n/a def test_bytesio(self):
217n/a for fmt in ALL_FORMATS:
218n/a with self.subTest(fmt=fmt):
219n/a b = BytesIO()
220n/a pl = self._create(fmt=fmt)
221n/a plistlib.dump(pl, b, fmt=fmt)
222n/a pl2 = plistlib.load(BytesIO(b.getvalue()), fmt=fmt)
223n/a self.assertEqual(dict(pl), dict(pl2))
224n/a pl2 = plistlib.load(BytesIO(b.getvalue()))
225n/a self.assertEqual(dict(pl), dict(pl2))
226n/a
227n/a def test_keysort_bytesio(self):
228n/a pl = collections.OrderedDict()
229n/a pl['b'] = 1
230n/a pl['a'] = 2
231n/a pl['c'] = 3
232n/a
233n/a for fmt in ALL_FORMATS:
234n/a for sort_keys in (False, True):
235n/a with self.subTest(fmt=fmt, sort_keys=sort_keys):
236n/a b = BytesIO()
237n/a
238n/a plistlib.dump(pl, b, fmt=fmt, sort_keys=sort_keys)
239n/a pl2 = plistlib.load(BytesIO(b.getvalue()),
240n/a dict_type=collections.OrderedDict)
241n/a
242n/a self.assertEqual(dict(pl), dict(pl2))
243n/a if sort_keys:
244n/a self.assertEqual(list(pl2.keys()), ['a', 'b', 'c'])
245n/a else:
246n/a self.assertEqual(list(pl2.keys()), ['b', 'a', 'c'])
247n/a
248n/a def test_keysort(self):
249n/a pl = collections.OrderedDict()
250n/a pl['b'] = 1
251n/a pl['a'] = 2
252n/a pl['c'] = 3
253n/a
254n/a for fmt in ALL_FORMATS:
255n/a for sort_keys in (False, True):
256n/a with self.subTest(fmt=fmt, sort_keys=sort_keys):
257n/a data = plistlib.dumps(pl, fmt=fmt, sort_keys=sort_keys)
258n/a pl2 = plistlib.loads(data, dict_type=collections.OrderedDict)
259n/a
260n/a self.assertEqual(dict(pl), dict(pl2))
261n/a if sort_keys:
262n/a self.assertEqual(list(pl2.keys()), ['a', 'b', 'c'])
263n/a else:
264n/a self.assertEqual(list(pl2.keys()), ['b', 'a', 'c'])
265n/a
266n/a def test_keys_no_string(self):
267n/a pl = { 42: 'aNumber' }
268n/a
269n/a for fmt in ALL_FORMATS:
270n/a with self.subTest(fmt=fmt):
271n/a self.assertRaises(TypeError, plistlib.dumps, pl, fmt=fmt)
272n/a
273n/a b = BytesIO()
274n/a self.assertRaises(TypeError, plistlib.dump, pl, b, fmt=fmt)
275n/a
276n/a def test_skipkeys(self):
277n/a pl = {
278n/a 42: 'aNumber',
279n/a 'snake': 'aWord',
280n/a }
281n/a
282n/a for fmt in ALL_FORMATS:
283n/a with self.subTest(fmt=fmt):
284n/a data = plistlib.dumps(
285n/a pl, fmt=fmt, skipkeys=True, sort_keys=False)
286n/a
287n/a pl2 = plistlib.loads(data)
288n/a self.assertEqual(pl2, {'snake': 'aWord'})
289n/a
290n/a fp = BytesIO()
291n/a plistlib.dump(
292n/a pl, fp, fmt=fmt, skipkeys=True, sort_keys=False)
293n/a data = fp.getvalue()
294n/a pl2 = plistlib.loads(fp.getvalue())
295n/a self.assertEqual(pl2, {'snake': 'aWord'})
296n/a
297n/a def test_tuple_members(self):
298n/a pl = {
299n/a 'first': (1, 2),
300n/a 'second': (1, 2),
301n/a 'third': (3, 4),
302n/a }
303n/a
304n/a for fmt in ALL_FORMATS:
305n/a with self.subTest(fmt=fmt):
306n/a data = plistlib.dumps(pl, fmt=fmt)
307n/a pl2 = plistlib.loads(data)
308n/a self.assertEqual(pl2, {
309n/a 'first': [1, 2],
310n/a 'second': [1, 2],
311n/a 'third': [3, 4],
312n/a })
313n/a self.assertIsNot(pl2['first'], pl2['second'])
314n/a
315n/a def test_list_members(self):
316n/a pl = {
317n/a 'first': [1, 2],
318n/a 'second': [1, 2],
319n/a 'third': [3, 4],
320n/a }
321n/a
322n/a for fmt in ALL_FORMATS:
323n/a with self.subTest(fmt=fmt):
324n/a data = plistlib.dumps(pl, fmt=fmt)
325n/a pl2 = plistlib.loads(data)
326n/a self.assertEqual(pl2, {
327n/a 'first': [1, 2],
328n/a 'second': [1, 2],
329n/a 'third': [3, 4],
330n/a })
331n/a self.assertIsNot(pl2['first'], pl2['second'])
332n/a
333n/a def test_dict_members(self):
334n/a pl = {
335n/a 'first': {'a': 1},
336n/a 'second': {'a': 1},
337n/a 'third': {'b': 2 },
338n/a }
339n/a
340n/a for fmt in ALL_FORMATS:
341n/a with self.subTest(fmt=fmt):
342n/a data = plistlib.dumps(pl, fmt=fmt)
343n/a pl2 = plistlib.loads(data)
344n/a self.assertEqual(pl2, {
345n/a 'first': {'a': 1},
346n/a 'second': {'a': 1},
347n/a 'third': {'b': 2 },
348n/a })
349n/a self.assertIsNot(pl2['first'], pl2['second'])
350n/a
351n/a def test_controlcharacters(self):
352n/a for i in range(128):
353n/a c = chr(i)
354n/a testString = "string containing %s" % c
355n/a if i >= 32 or c in "\r\n\t":
356n/a # \r, \n and \t are the only legal control chars in XML
357n/a plistlib.dumps(testString, fmt=plistlib.FMT_XML)
358n/a else:
359n/a self.assertRaises(ValueError,
360n/a plistlib.dumps,
361n/a testString)
362n/a
363n/a def test_non_bmp_characters(self):
364n/a pl = {'python': '\U0001f40d'}
365n/a for fmt in ALL_FORMATS:
366n/a with self.subTest(fmt=fmt):
367n/a data = plistlib.dumps(pl, fmt=fmt)
368n/a self.assertEqual(plistlib.loads(data), pl)
369n/a
370n/a def test_nondictroot(self):
371n/a for fmt in ALL_FORMATS:
372n/a with self.subTest(fmt=fmt):
373n/a test1 = "abc"
374n/a test2 = [1, 2, 3, "abc"]
375n/a result1 = plistlib.loads(plistlib.dumps(test1, fmt=fmt))
376n/a result2 = plistlib.loads(plistlib.dumps(test2, fmt=fmt))
377n/a self.assertEqual(test1, result1)
378n/a self.assertEqual(test2, result2)
379n/a
380n/a def test_invalidarray(self):
381n/a for i in ["<key>key inside an array</key>",
382n/a "<key>key inside an array2</key><real>3</real>",
383n/a "<true/><key>key inside an array3</key>"]:
384n/a self.assertRaises(ValueError, plistlib.loads,
385n/a ("<plist><array>%s</array></plist>"%i).encode())
386n/a
387n/a def test_invaliddict(self):
388n/a for i in ["<key><true/>k</key><string>compound key</string>",
389n/a "<key>single key</key>",
390n/a "<string>missing key</string>",
391n/a "<key>k1</key><string>v1</string><real>5.3</real>"
392n/a "<key>k1</key><key>k2</key><string>double key</string>"]:
393n/a self.assertRaises(ValueError, plistlib.loads,
394n/a ("<plist><dict>%s</dict></plist>"%i).encode())
395n/a self.assertRaises(ValueError, plistlib.loads,
396n/a ("<plist><array><dict>%s</dict></array></plist>"%i).encode())
397n/a
398n/a def test_invalidinteger(self):
399n/a self.assertRaises(ValueError, plistlib.loads,
400n/a b"<plist><integer>not integer</integer></plist>")
401n/a
402n/a def test_invalidreal(self):
403n/a self.assertRaises(ValueError, plistlib.loads,
404n/a b"<plist><integer>not real</integer></plist>")
405n/a
406n/a def test_xml_encodings(self):
407n/a base = TESTDATA[plistlib.FMT_XML]
408n/a
409n/a for xml_encoding, encoding, bom in [
410n/a (b'utf-8', 'utf-8', codecs.BOM_UTF8),
411n/a (b'utf-16', 'utf-16-le', codecs.BOM_UTF16_LE),
412n/a (b'utf-16', 'utf-16-be', codecs.BOM_UTF16_BE),
413n/a # Expat does not support UTF-32
414n/a #(b'utf-32', 'utf-32-le', codecs.BOM_UTF32_LE),
415n/a #(b'utf-32', 'utf-32-be', codecs.BOM_UTF32_BE),
416n/a ]:
417n/a
418n/a pl = self._create(fmt=plistlib.FMT_XML)
419n/a with self.subTest(encoding=encoding):
420n/a data = base.replace(b'UTF-8', xml_encoding)
421n/a data = bom + data.decode('utf-8').encode(encoding)
422n/a pl2 = plistlib.loads(data)
423n/a self.assertEqual(dict(pl), dict(pl2))
424n/a
425n/a def test_nonstandard_refs_size(self):
426n/a # Issue #21538: Refs and offsets are 24-bit integers
427n/a data = (b'bplist00'
428n/a b'\xd1\x00\x00\x01\x00\x00\x02QaQb'
429n/a b'\x00\x00\x08\x00\x00\x0f\x00\x00\x11'
430n/a b'\x00\x00\x00\x00\x00\x00'
431n/a b'\x03\x03'
432n/a b'\x00\x00\x00\x00\x00\x00\x00\x03'
433n/a b'\x00\x00\x00\x00\x00\x00\x00\x00'
434n/a b'\x00\x00\x00\x00\x00\x00\x00\x13')
435n/a self.assertEqual(plistlib.loads(data), {'a': 'b'})
436n/a
437n/a def test_large_timestamp(self):
438n/a # Issue #26709: 32-bit timestamp out of range
439n/a for ts in -2**31-1, 2**31:
440n/a with self.subTest(ts=ts):
441n/a d = (datetime.datetime.utcfromtimestamp(0) +
442n/a datetime.timedelta(seconds=ts))
443n/a data = plistlib.dumps(d, fmt=plistlib.FMT_BINARY)
444n/a self.assertEqual(plistlib.loads(data), d)
445n/a
446n/a
447n/aclass TestPlistlibDeprecated(unittest.TestCase):
448n/a def test_io_deprecated(self):
449n/a pl_in = {
450n/a 'key': 42,
451n/a 'sub': {
452n/a 'key': 9,
453n/a 'alt': 'value',
454n/a 'data': b'buffer',
455n/a }
456n/a }
457n/a pl_out = plistlib._InternalDict({
458n/a 'key': 42,
459n/a 'sub': plistlib._InternalDict({
460n/a 'key': 9,
461n/a 'alt': 'value',
462n/a 'data': plistlib.Data(b'buffer'),
463n/a })
464n/a })
465n/a
466n/a self.addCleanup(support.unlink, support.TESTFN)
467n/a with self.assertWarns(DeprecationWarning):
468n/a plistlib.writePlist(pl_in, support.TESTFN)
469n/a
470n/a with self.assertWarns(DeprecationWarning):
471n/a pl2 = plistlib.readPlist(support.TESTFN)
472n/a
473n/a self.assertEqual(pl_out, pl2)
474n/a
475n/a os.unlink(support.TESTFN)
476n/a
477n/a with open(support.TESTFN, 'wb') as fp:
478n/a with self.assertWarns(DeprecationWarning):
479n/a plistlib.writePlist(pl_in, fp)
480n/a
481n/a with open(support.TESTFN, 'rb') as fp:
482n/a with self.assertWarns(DeprecationWarning):
483n/a pl2 = plistlib.readPlist(fp)
484n/a
485n/a self.assertEqual(pl_out, pl2)
486n/a
487n/a def test_bytes_deprecated(self):
488n/a pl = {
489n/a 'key': 42,
490n/a 'sub': {
491n/a 'key': 9,
492n/a 'alt': 'value',
493n/a 'data': b'buffer',
494n/a }
495n/a }
496n/a with self.assertWarns(DeprecationWarning):
497n/a data = plistlib.writePlistToBytes(pl)
498n/a
499n/a with self.assertWarns(DeprecationWarning):
500n/a pl2 = plistlib.readPlistFromBytes(data)
501n/a
502n/a self.assertIsInstance(pl2, plistlib._InternalDict)
503n/a self.assertEqual(pl2, plistlib._InternalDict(
504n/a key=42,
505n/a sub=plistlib._InternalDict(
506n/a key=9,
507n/a alt='value',
508n/a data=plistlib.Data(b'buffer'),
509n/a )
510n/a ))
511n/a
512n/a with self.assertWarns(DeprecationWarning):
513n/a data2 = plistlib.writePlistToBytes(pl2)
514n/a self.assertEqual(data, data2)
515n/a
516n/a def test_dataobject_deprecated(self):
517n/a in_data = { 'key': plistlib.Data(b'hello') }
518n/a out_data = { 'key': b'hello' }
519n/a
520n/a buf = plistlib.dumps(in_data)
521n/a
522n/a cur = plistlib.loads(buf)
523n/a self.assertEqual(cur, out_data)
524n/a self.assertEqual(cur, in_data)
525n/a
526n/a cur = plistlib.loads(buf, use_builtin_types=False)
527n/a self.assertEqual(cur, out_data)
528n/a self.assertEqual(cur, in_data)
529n/a
530n/a with self.assertWarns(DeprecationWarning):
531n/a cur = plistlib.readPlistFromBytes(buf)
532n/a self.assertEqual(cur, out_data)
533n/a self.assertEqual(cur, in_data)
534n/a
535n/a
536n/aclass MiscTestCase(unittest.TestCase):
537n/a def test__all__(self):
538n/a blacklist = {"PlistFormat", "PLISTHEADER"}
539n/a support.check__all__(self, plistlib, blacklist=blacklist)
540n/a
541n/a
542n/adef test_main():
543n/a support.run_unittest(TestPlistlib, TestPlistlibDeprecated, MiscTestCase)
544n/a
545n/a
546n/aif __name__ == '__main__':
547n/a test_main()