~ubuntu-branches/ubuntu/trusty/python3.4/trusty-proposed

« back to all changes in this revision

Viewing changes to Lib/test/test_plistlib.py

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-25 09:44:27 UTC
  • Revision ID: package-import@ubuntu.com-20131125094427-lzxj8ap5w01lmo7f
Tags: upstream-3.4~b1
ImportĀ upstreamĀ versionĀ 3.4~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2003-2013 Python Software Foundation
 
2
 
 
3
import unittest
 
4
import plistlib
 
5
import os
 
6
import datetime
 
7
import codecs
 
8
import binascii
 
9
import collections
 
10
from test import support
 
11
from io import BytesIO
 
12
 
 
13
ALL_FORMATS=(plistlib.FMT_XML, plistlib.FMT_BINARY)
 
14
 
 
15
# The testdata is generated using Mac/Tools/plistlib_generate_testdata.py
 
16
# (which using PyObjC to control the Cocoa classes for generating plists)
 
17
TESTDATA={
 
18
    plistlib.FMT_XML: binascii.a2b_base64(b'''
 
19
        PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCFET0NU
 
20
        WVBFIHBsaXN0IFBVQkxJQyAiLS8vQXBwbGUvL0RURCBQTElTVCAxLjAvL0VO
 
21
        IiAiaHR0cDovL3d3dy5hcHBsZS5jb20vRFREcy9Qcm9wZXJ0eUxpc3QtMS4w
 
22
        LmR0ZCI+CjxwbGlzdCB2ZXJzaW9uPSIxLjAiPgo8ZGljdD4KCTxrZXk+YURh
 
23
        dGU8L2tleT4KCTxkYXRlPjIwMDQtMTAtMjZUMTA6MzM6MzNaPC9kYXRlPgoJ
 
24
        PGtleT5hRGljdDwva2V5PgoJPGRpY3Q+CgkJPGtleT5hRmFsc2VWYWx1ZTwv
 
25
        a2V5PgoJCTxmYWxzZS8+CgkJPGtleT5hVHJ1ZVZhbHVlPC9rZXk+CgkJPHRy
 
26
        dWUvPgoJCTxrZXk+YVVuaWNvZGVWYWx1ZTwva2V5PgoJCTxzdHJpbmc+TcOk
 
27
        c3NpZywgTWHDnzwvc3RyaW5nPgoJCTxrZXk+YW5vdGhlclN0cmluZzwva2V5
 
28
        PgoJCTxzdHJpbmc+Jmx0O2hlbGxvICZhbXA7ICdoaScgdGhlcmUhJmd0Ozwv
 
29
        c3RyaW5nPgoJCTxrZXk+ZGVlcGVyRGljdDwva2V5PgoJCTxkaWN0PgoJCQk8
 
30
        a2V5PmE8L2tleT4KCQkJPGludGVnZXI+MTc8L2ludGVnZXI+CgkJCTxrZXk+
 
31
        Yjwva2V5PgoJCQk8cmVhbD4zMi41PC9yZWFsPgoJCQk8a2V5PmM8L2tleT4K
 
32
        CQkJPGFycmF5PgoJCQkJPGludGVnZXI+MTwvaW50ZWdlcj4KCQkJCTxpbnRl
 
33
        Z2VyPjI8L2ludGVnZXI+CgkJCQk8c3RyaW5nPnRleHQ8L3N0cmluZz4KCQkJ
 
34
        PC9hcnJheT4KCQk8L2RpY3Q+Cgk8L2RpY3Q+Cgk8a2V5PmFGbG9hdDwva2V5
 
35
        PgoJPHJlYWw+MC41PC9yZWFsPgoJPGtleT5hTGlzdDwva2V5PgoJPGFycmF5
 
36
        PgoJCTxzdHJpbmc+QTwvc3RyaW5nPgoJCTxzdHJpbmc+Qjwvc3RyaW5nPgoJ
 
37
        CTxpbnRlZ2VyPjEyPC9pbnRlZ2VyPgoJCTxyZWFsPjMyLjU8L3JlYWw+CgkJ
 
38
        PGFycmF5PgoJCQk8aW50ZWdlcj4xPC9pbnRlZ2VyPgoJCQk8aW50ZWdlcj4y
 
39
        PC9pbnRlZ2VyPgoJCQk8aW50ZWdlcj4zPC9pbnRlZ2VyPgoJCTwvYXJyYXk+
 
40
        Cgk8L2FycmF5PgoJPGtleT5hU3RyaW5nPC9rZXk+Cgk8c3RyaW5nPkRvb2Rh
 
41
        aDwvc3RyaW5nPgoJPGtleT5hbkVtcHR5RGljdDwva2V5PgoJPGRpY3QvPgoJ
 
42
        PGtleT5hbkVtcHR5TGlzdDwva2V5PgoJPGFycmF5Lz4KCTxrZXk+YW5JbnQ8
 
43
        L2tleT4KCTxpbnRlZ2VyPjcyODwvaW50ZWdlcj4KCTxrZXk+bmVzdGVkRGF0
 
44
        YTwva2V5PgoJPGFycmF5PgoJCTxkYXRhPgoJCVBHeHZkSE1nYjJZZ1ltbHVZ
 
45
        WEo1SUdkMWJtcytBQUVDQXp4c2IzUnpJRzltSUdKcGJtRnllU0JuZFc1cgoJ
 
46
        CVBnQUJBZ004Ykc5MGN5QnZaaUJpYVc1aGNua2daM1Z1YXo0QUFRSURQR3h2
 
47
        ZEhNZ2IyWWdZbWx1WVhKNQoJCUlHZDFibXMrQUFFQ0F6eHNiM1J6SUc5bUlH
 
48
        SnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOGJHOTBjeUJ2WmlCaQoJCWFXNWhjbmtn
 
49
        WjNWdWF6NEFBUUlEUEd4dmRITWdiMllnWW1sdVlYSjVJR2QxYm1zK0FBRUNB
 
50
        enhzYjNSegoJCUlHOW1JR0pwYm1GeWVTQm5kVzVyUGdBQkFnTThiRzkwY3lC
 
51
        dlppQmlhVzVoY25rZ1ozVnVhejRBQVFJRAoJCVBHeHZkSE1nYjJZZ1ltbHVZ
 
52
        WEo1SUdkMWJtcytBQUVDQXc9PQoJCTwvZGF0YT4KCTwvYXJyYXk+Cgk8a2V5
 
53
        PnNvbWVEYXRhPC9rZXk+Cgk8ZGF0YT4KCVBHSnBibUZ5ZVNCbmRXNXJQZz09
 
54
        Cgk8L2RhdGE+Cgk8a2V5PnNvbWVNb3JlRGF0YTwva2V5PgoJPGRhdGE+CglQ
 
55
        R3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMrQUFFQ0F6eHNiM1J6SUc5bUlH
 
56
        SnBibUZ5ZVNCbmRXNXJQZ0FCQWdNOAoJYkc5MGN5QnZaaUJpYVc1aGNua2da
 
57
        M1Z1YXo0QUFRSURQR3h2ZEhNZ2IyWWdZbWx1WVhKNUlHZDFibXMrQUFFQ0F6
 
58
        eHMKCWIzUnpJRzltSUdKcGJtRnllU0JuZFc1clBnQUJBZ004Ykc5MGN5QnZa
 
59
        aUJpYVc1aGNua2daM1Z1YXo0QUFRSURQR3h2CglkSE1nYjJZZ1ltbHVZWEo1
 
60
        SUdkMWJtcytBQUVDQXp4c2IzUnpJRzltSUdKcGJtRnllU0JuZFc1clBnQUJB
 
61
        Z004Ykc5MAoJY3lCdlppQmlhVzVoY25rZ1ozVnVhejRBQVFJRFBHeHZkSE1n
 
62
        YjJZZ1ltbHVZWEo1SUdkMWJtcytBQUVDQXc9PQoJPC9kYXRhPgoJPGtleT7D
 
63
        hWJlbnJhYTwva2V5PgoJPHN0cmluZz5UaGF0IHdhcyBhIHVuaWNvZGUga2V5
 
64
        Ljwvc3RyaW5nPgo8L2RpY3Q+CjwvcGxpc3Q+Cg=='''),
 
65
    plistlib.FMT_BINARY: binascii.a2b_base64(b'''
 
66
        YnBsaXN0MDDcAQIDBAUGBwgJCgsMDQ4iIykqKywtLy4wVWFEYXRlVWFEaWN0
 
67
        VmFGbG9hdFVhTGlzdFdhU3RyaW5nW2FuRW1wdHlEaWN0W2FuRW1wdHlMaXN0
 
68
        VWFuSW50Wm5lc3RlZERhdGFYc29tZURhdGFcc29tZU1vcmVEYXRhZwDFAGIA
 
69
        ZQBuAHIAYQBhM0GcuX30AAAA1Q8QERITFBUWFxhbYUZhbHNlVmFsdWVaYVRy
 
70
        dWVWYWx1ZV1hVW5pY29kZVZhbHVlXWFub3RoZXJTdHJpbmdaZGVlcGVyRGlj
 
71
        dAgJawBNAOQAcwBzAGkAZwAsACAATQBhAN9fEBU8aGVsbG8gJiAnaGknIHRo
 
72
        ZXJlIT7TGRobHB0eUWFRYlFjEBEjQEBAAAAAAACjHyAhEAEQAlR0ZXh0Iz/g
 
73
        AAAAAAAApSQlJh0nUUFRQhAMox8gKBADVkRvb2RhaNCgEQLYoS5PEPo8bG90
 
74
        cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAEC
 
75
        Azxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vu
 
76
        az4AAQIDPGxvdHMgb2YgYmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFy
 
77
        eSBndW5rPgABAgM8bG90cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDPGxvdHMgb2Yg
 
78
        YmluYXJ5IGd1bms+AAECAzxsb3RzIG9mIGJpbmFyeSBndW5rPgABAgM8bG90
 
79
        cyBvZiBiaW5hcnkgZ3Vuaz4AAQIDTTxiaW5hcnkgZ3Vuaz5fEBdUaGF0IHdh
 
80
        cyBhIHVuaWNvZGUga2V5LgAIACEAJwAtADQAOgBCAE4AWgBgAGsAdACBAJAA
 
81
        mQCkALAAuwDJANcA4gDjAOQA+wETARoBHAEeASABIgErAS8BMQEzATgBQQFH
 
82
        AUkBSwFNAVEBUwFaAVsBXAFfAWECXgJsAAAAAAAAAgEAAAAAAAAAMQAAAAAA
 
83
        AAAAAAAAAAAAAoY='''),
 
84
}
 
85
 
 
86
 
 
87
class TestPlistlib(unittest.TestCase):
 
88
 
 
89
    def tearDown(self):
 
90
        try:
 
91
            os.unlink(support.TESTFN)
 
92
        except:
 
93
            pass
 
94
 
 
95
    def _create(self, fmt=None):
 
96
        pl = dict(
 
97
            aString="Doodah",
 
98
            aList=["A", "B", 12, 32.5, [1, 2, 3]],
 
99
            aFloat = 0.5,
 
100
            anInt = 728,
 
101
            aDict=dict(
 
102
                anotherString="<hello & 'hi' there!>",
 
103
                aUnicodeValue='M\xe4ssig, Ma\xdf',
 
104
                aTrueValue=True,
 
105
                aFalseValue=False,
 
106
                deeperDict=dict(a=17, b=32.5, c=[1, 2, "text"]),
 
107
            ),
 
108
            someData = b"<binary gunk>",
 
109
            someMoreData = b"<lots of binary gunk>\0\1\2\3" * 10,
 
110
            nestedData = [b"<lots of binary gunk>\0\1\2\3" * 10],
 
111
            aDate = datetime.datetime(2004, 10, 26, 10, 33, 33),
 
112
            anEmptyDict = dict(),
 
113
            anEmptyList = list()
 
114
        )
 
115
        pl['\xc5benraa'] = "That was a unicode key."
 
116
        return pl
 
117
 
 
118
    def test_create(self):
 
119
        pl = self._create()
 
120
        self.assertEqual(pl["aString"], "Doodah")
 
121
        self.assertEqual(pl["aDict"]["aFalseValue"], False)
 
122
 
 
123
    def test_io(self):
 
124
        pl = self._create()
 
125
        with open(support.TESTFN, 'wb') as fp:
 
126
            plistlib.dump(pl, fp)
 
127
 
 
128
        with open(support.TESTFN, 'rb') as fp:
 
129
            pl2 = plistlib.load(fp)
 
130
 
 
131
        self.assertEqual(dict(pl), dict(pl2))
 
132
 
 
133
        self.assertRaises(AttributeError, plistlib.dump, pl, 'filename')
 
134
        self.assertRaises(AttributeError, plistlib.load, 'filename')
 
135
 
 
136
 
 
137
    def test_bytes(self):
 
138
        pl = self._create()
 
139
        data = plistlib.dumps(pl)
 
140
        pl2 = plistlib.loads(data)
 
141
        self.assertNotIsInstance(pl, plistlib._InternalDict)
 
142
        self.assertEqual(dict(pl), dict(pl2))
 
143
        data2 = plistlib.dumps(pl2)
 
144
        self.assertEqual(data, data2)
 
145
 
 
146
    def test_indentation_array(self):
 
147
        data = [[[[[[[[{'test': b'aaaaaa'}]]]]]]]]
 
148
        self.assertEqual(plistlib.loads(plistlib.dumps(data)), data)
 
149
 
 
150
    def test_indentation_dict(self):
 
151
        data = {'1': {'2': {'3': {'4': {'5': {'6': {'7': {'8': {'9': b'aaaaaa'}}}}}}}}}
 
152
        self.assertEqual(plistlib.loads(plistlib.dumps(data)), data)
 
153
 
 
154
    def test_indentation_dict_mix(self):
 
155
        data = {'1': {'2': [{'3': [[[[[{'test': b'aaaaaa'}]]]]]}]}}
 
156
        self.assertEqual(plistlib.loads(plistlib.dumps(data)), data)
 
157
 
 
158
    def test_appleformatting(self):
 
159
        for use_builtin_types in (True, False):
 
160
            for fmt in ALL_FORMATS:
 
161
                with self.subTest(fmt=fmt, use_builtin_types=use_builtin_types):
 
162
                    pl = plistlib.loads(TESTDATA[fmt],
 
163
                        use_builtin_types=use_builtin_types)
 
164
                    data = plistlib.dumps(pl, fmt=fmt)
 
165
                    self.assertEqual(data, TESTDATA[fmt],
 
166
                        "generated data was not identical to Apple's output")
 
167
 
 
168
 
 
169
    def test_appleformattingfromliteral(self):
 
170
        self.maxDiff = None
 
171
        for fmt in ALL_FORMATS:
 
172
            with self.subTest(fmt=fmt):
 
173
                pl = self._create(fmt=fmt)
 
174
                pl2 = plistlib.loads(TESTDATA[fmt])
 
175
                self.assertEqual(dict(pl), dict(pl2),
 
176
                    "generated data was not identical to Apple's output")
 
177
 
 
178
    def test_bytesio(self):
 
179
        for fmt in ALL_FORMATS:
 
180
            with self.subTest(fmt=fmt):
 
181
                b = BytesIO()
 
182
                pl = self._create(fmt=fmt)
 
183
                plistlib.dump(pl, b, fmt=fmt)
 
184
                pl2 = plistlib.load(BytesIO(b.getvalue()))
 
185
                self.assertEqual(dict(pl), dict(pl2))
 
186
 
 
187
    def test_keysort_bytesio(self):
 
188
        pl = collections.OrderedDict()
 
189
        pl['b'] = 1
 
190
        pl['a'] = 2
 
191
        pl['c'] = 3
 
192
 
 
193
        for fmt in ALL_FORMATS:
 
194
            for sort_keys in (False, True):
 
195
                with self.subTest(fmt=fmt, sort_keys=sort_keys):
 
196
                    b = BytesIO()
 
197
 
 
198
                    plistlib.dump(pl, b, fmt=fmt, sort_keys=sort_keys)
 
199
                    pl2 = plistlib.load(BytesIO(b.getvalue()),
 
200
                        dict_type=collections.OrderedDict)
 
201
 
 
202
                    self.assertEqual(dict(pl), dict(pl2))
 
203
                    if sort_keys:
 
204
                        self.assertEqual(list(pl2.keys()), ['a', 'b', 'c'])
 
205
                    else:
 
206
                        self.assertEqual(list(pl2.keys()), ['b', 'a', 'c'])
 
207
 
 
208
    def test_keysort(self):
 
209
        pl = collections.OrderedDict()
 
210
        pl['b'] = 1
 
211
        pl['a'] = 2
 
212
        pl['c'] = 3
 
213
 
 
214
        for fmt in ALL_FORMATS:
 
215
            for sort_keys in (False, True):
 
216
                with self.subTest(fmt=fmt, sort_keys=sort_keys):
 
217
                    data = plistlib.dumps(pl, fmt=fmt, sort_keys=sort_keys)
 
218
                    pl2 = plistlib.loads(data, dict_type=collections.OrderedDict)
 
219
 
 
220
                    self.assertEqual(dict(pl), dict(pl2))
 
221
                    if sort_keys:
 
222
                        self.assertEqual(list(pl2.keys()), ['a', 'b', 'c'])
 
223
                    else:
 
224
                        self.assertEqual(list(pl2.keys()), ['b', 'a', 'c'])
 
225
 
 
226
    def test_keys_no_string(self):
 
227
        pl = { 42: 'aNumber' }
 
228
 
 
229
        for fmt in ALL_FORMATS:
 
230
            with self.subTest(fmt=fmt):
 
231
                self.assertRaises(TypeError, plistlib.dumps, pl, fmt=fmt)
 
232
 
 
233
                b = BytesIO()
 
234
                self.assertRaises(TypeError, plistlib.dump, pl, b, fmt=fmt)
 
235
 
 
236
    def test_skipkeys(self):
 
237
        pl = {
 
238
            42: 'aNumber',
 
239
            'snake': 'aWord',
 
240
        }
 
241
 
 
242
        for fmt in ALL_FORMATS:
 
243
            with self.subTest(fmt=fmt):
 
244
                data = plistlib.dumps(
 
245
                    pl, fmt=fmt, skipkeys=True, sort_keys=False)
 
246
 
 
247
                pl2 = plistlib.loads(data)
 
248
                self.assertEqual(pl2, {'snake': 'aWord'})
 
249
 
 
250
                fp = BytesIO()
 
251
                plistlib.dump(
 
252
                    pl, fp, fmt=fmt, skipkeys=True, sort_keys=False)
 
253
                data = fp.getvalue()
 
254
                pl2 = plistlib.loads(fp.getvalue())
 
255
                self.assertEqual(pl2, {'snake': 'aWord'})
 
256
 
 
257
    def test_tuple_members(self):
 
258
        pl = {
 
259
            'first': (1, 2),
 
260
            'second': (1, 2),
 
261
            'third': (3, 4),
 
262
        }
 
263
 
 
264
        for fmt in ALL_FORMATS:
 
265
            with self.subTest(fmt=fmt):
 
266
                data = plistlib.dumps(pl, fmt=fmt)
 
267
                pl2 = plistlib.loads(data)
 
268
                self.assertEqual(pl2, {
 
269
                    'first': [1, 2],
 
270
                    'second': [1, 2],
 
271
                    'third': [3, 4],
 
272
                })
 
273
                self.assertIsNot(pl2['first'], pl2['second'])
 
274
 
 
275
    def test_list_members(self):
 
276
        pl = {
 
277
            'first': [1, 2],
 
278
            'second': [1, 2],
 
279
            'third': [3, 4],
 
280
        }
 
281
 
 
282
        for fmt in ALL_FORMATS:
 
283
            with self.subTest(fmt=fmt):
 
284
                data = plistlib.dumps(pl, fmt=fmt)
 
285
                pl2 = plistlib.loads(data)
 
286
                self.assertEqual(pl2, {
 
287
                    'first': [1, 2],
 
288
                    'second': [1, 2],
 
289
                    'third': [3, 4],
 
290
                })
 
291
                self.assertIsNot(pl2['first'], pl2['second'])
 
292
 
 
293
    def test_dict_members(self):
 
294
        pl = {
 
295
            'first': {'a': 1},
 
296
            'second': {'a': 1},
 
297
            'third': {'b': 2 },
 
298
        }
 
299
 
 
300
        for fmt in ALL_FORMATS:
 
301
            with self.subTest(fmt=fmt):
 
302
                data = plistlib.dumps(pl, fmt=fmt)
 
303
                pl2 = plistlib.loads(data)
 
304
                self.assertEqual(pl2, {
 
305
                    'first': {'a': 1},
 
306
                    'second': {'a': 1},
 
307
                    'third': {'b': 2 },
 
308
                })
 
309
                self.assertIsNot(pl2['first'], pl2['second'])
 
310
 
 
311
    def test_controlcharacters(self):
 
312
        for i in range(128):
 
313
            c = chr(i)
 
314
            testString = "string containing %s" % c
 
315
            if i >= 32 or c in "\r\n\t":
 
316
                # \r, \n and \t are the only legal control chars in XML
 
317
                plistlib.dumps(testString, fmt=plistlib.FMT_XML)
 
318
            else:
 
319
                self.assertRaises(ValueError,
 
320
                                  plistlib.dumps,
 
321
                                  testString)
 
322
 
 
323
    def test_nondictroot(self):
 
324
        for fmt in ALL_FORMATS:
 
325
            with self.subTest(fmt=fmt):
 
326
                test1 = "abc"
 
327
                test2 = [1, 2, 3, "abc"]
 
328
                result1 = plistlib.loads(plistlib.dumps(test1, fmt=fmt))
 
329
                result2 = plistlib.loads(plistlib.dumps(test2, fmt=fmt))
 
330
                self.assertEqual(test1, result1)
 
331
                self.assertEqual(test2, result2)
 
332
 
 
333
    def test_invalidarray(self):
 
334
        for i in ["<key>key inside an array</key>",
 
335
                  "<key>key inside an array2</key><real>3</real>",
 
336
                  "<true/><key>key inside an array3</key>"]:
 
337
            self.assertRaises(ValueError, plistlib.loads,
 
338
                              ("<plist><array>%s</array></plist>"%i).encode())
 
339
 
 
340
    def test_invaliddict(self):
 
341
        for i in ["<key><true/>k</key><string>compound key</string>",
 
342
                  "<key>single key</key>",
 
343
                  "<string>missing key</string>",
 
344
                  "<key>k1</key><string>v1</string><real>5.3</real>"
 
345
                  "<key>k1</key><key>k2</key><string>double key</string>"]:
 
346
            self.assertRaises(ValueError, plistlib.loads,
 
347
                              ("<plist><dict>%s</dict></plist>"%i).encode())
 
348
            self.assertRaises(ValueError, plistlib.loads,
 
349
                              ("<plist><array><dict>%s</dict></array></plist>"%i).encode())
 
350
 
 
351
    def test_invalidinteger(self):
 
352
        self.assertRaises(ValueError, plistlib.loads,
 
353
                          b"<plist><integer>not integer</integer></plist>")
 
354
 
 
355
    def test_invalidreal(self):
 
356
        self.assertRaises(ValueError, plistlib.loads,
 
357
                          b"<plist><integer>not real</integer></plist>")
 
358
 
 
359
    def test_xml_encodings(self):
 
360
        base = TESTDATA[plistlib.FMT_XML]
 
361
 
 
362
        for xml_encoding, encoding, bom in [
 
363
                    (b'utf-8', 'utf-8', codecs.BOM_UTF8),
 
364
                    (b'utf-16', 'utf-16-le', codecs.BOM_UTF16_LE),
 
365
                    (b'utf-16', 'utf-16-be', codecs.BOM_UTF16_BE),
 
366
                    # Expat does not support UTF-32
 
367
                    #(b'utf-32', 'utf-32-le', codecs.BOM_UTF32_LE),
 
368
                    #(b'utf-32', 'utf-32-be', codecs.BOM_UTF32_BE),
 
369
                ]:
 
370
 
 
371
            pl = self._create(fmt=plistlib.FMT_XML)
 
372
            with self.subTest(encoding=encoding):
 
373
                data = base.replace(b'UTF-8', xml_encoding)
 
374
                data = bom + data.decode('utf-8').encode(encoding)
 
375
                pl2 = plistlib.loads(data)
 
376
                self.assertEqual(dict(pl), dict(pl2))
 
377
 
 
378
 
 
379
class TestPlistlibDeprecated(unittest.TestCase):
 
380
    def test_io_deprecated(self):
 
381
        pl_in = {
 
382
            'key': 42,
 
383
            'sub': {
 
384
                'key': 9,
 
385
                'alt': 'value',
 
386
                'data': b'buffer',
 
387
            }
 
388
        }
 
389
        pl_out = plistlib._InternalDict({
 
390
            'key': 42,
 
391
            'sub': plistlib._InternalDict({
 
392
                'key': 9,
 
393
                'alt': 'value',
 
394
                'data': plistlib.Data(b'buffer'),
 
395
            })
 
396
        })
 
397
 
 
398
        self.addCleanup(support.unlink, support.TESTFN)
 
399
        with self.assertWarns(DeprecationWarning):
 
400
            plistlib.writePlist(pl_in, support.TESTFN)
 
401
 
 
402
        with self.assertWarns(DeprecationWarning):
 
403
            pl2 = plistlib.readPlist(support.TESTFN)
 
404
 
 
405
        self.assertEqual(pl_out, pl2)
 
406
 
 
407
        os.unlink(support.TESTFN)
 
408
 
 
409
        with open(support.TESTFN, 'wb') as fp:
 
410
            with self.assertWarns(DeprecationWarning):
 
411
                plistlib.writePlist(pl_in, fp)
 
412
 
 
413
        with open(support.TESTFN, 'rb') as fp:
 
414
            with self.assertWarns(DeprecationWarning):
 
415
                pl2 = plistlib.readPlist(fp)
 
416
 
 
417
        self.assertEqual(pl_out, pl2)
 
418
 
 
419
    def test_bytes_deprecated(self):
 
420
        pl = {
 
421
            'key': 42,
 
422
            'sub': {
 
423
                'key': 9,
 
424
                'alt': 'value',
 
425
                'data': b'buffer',
 
426
            }
 
427
        }
 
428
        with self.assertWarns(DeprecationWarning):
 
429
            data = plistlib.writePlistToBytes(pl)
 
430
 
 
431
        with self.assertWarns(DeprecationWarning):
 
432
            pl2 = plistlib.readPlistFromBytes(data)
 
433
 
 
434
        self.assertIsInstance(pl2, plistlib._InternalDict)
 
435
        self.assertEqual(pl2, plistlib._InternalDict(
 
436
            key=42,
 
437
            sub=plistlib._InternalDict(
 
438
                key=9,
 
439
                alt='value',
 
440
                data=plistlib.Data(b'buffer'),
 
441
            )
 
442
        ))
 
443
 
 
444
        with self.assertWarns(DeprecationWarning):
 
445
            data2 = plistlib.writePlistToBytes(pl2)
 
446
        self.assertEqual(data, data2)
 
447
 
 
448
    def test_dataobject_deprecated(self):
 
449
        in_data = { 'key': plistlib.Data(b'hello') }
 
450
        out_data = { 'key': b'hello' }
 
451
 
 
452
        buf = plistlib.dumps(in_data)
 
453
 
 
454
        cur = plistlib.loads(buf)
 
455
        self.assertEqual(cur, out_data)
 
456
        self.assertNotEqual(cur, in_data)
 
457
 
 
458
        cur = plistlib.loads(buf, use_builtin_types=False)
 
459
        self.assertNotEqual(cur, out_data)
 
460
        self.assertEqual(cur, in_data)
 
461
 
 
462
        with self.assertWarns(DeprecationWarning):
 
463
            cur = plistlib.readPlistFromBytes(buf)
 
464
        self.assertNotEqual(cur, out_data)
 
465
        self.assertEqual(cur, in_data)
 
466
 
 
467
 
 
468
def test_main():
 
469
    support.run_unittest(TestPlistlib, TestPlistlibDeprecated)
 
470
 
 
471
 
 
472
if __name__ == '__main__':
 
473
    test_main()