• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import unittest.mock
2from test import support
3import builtins
4import contextlib
5import copy
6import io
7import os
8import pickle
9import shutil
10import subprocess
11import sys
12import weakref
13from unittest import mock
14
15py_uuid = support.import_fresh_module('uuid', blocked=['_uuid'])
16c_uuid = support.import_fresh_module('uuid', fresh=['_uuid'])
17
18
19def importable(name):
20    try:
21        __import__(name)
22        return True
23    except:
24        return False
25
26
27class BaseTestUUID:
28    uuid = None
29
30    def test_UUID(self):
31        equal = self.assertEqual
32        ascending = []
33        for (string, curly, hex, bytes, bytes_le, fields, integer, urn,
34             time, clock_seq, variant, version) in [
35            ('00000000-0000-0000-0000-000000000000',
36             '{00000000-0000-0000-0000-000000000000}',
37             '00000000000000000000000000000000',
38             b'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
39             b'\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0',
40             (0, 0, 0, 0, 0, 0),
41             0,
42             'urn:uuid:00000000-0000-0000-0000-000000000000',
43             0, 0, self.uuid.RESERVED_NCS, None),
44            ('00010203-0405-0607-0809-0a0b0c0d0e0f',
45             '{00010203-0405-0607-0809-0a0b0c0d0e0f}',
46             '000102030405060708090a0b0c0d0e0f',
47             b'\0\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\x0d\x0e\x0f',
48             b'\x03\x02\x01\0\x05\x04\x07\x06\x08\t\n\x0b\x0c\x0d\x0e\x0f',
49             (0x00010203, 0x0405, 0x0607, 8, 9, 0x0a0b0c0d0e0f),
50             0x000102030405060708090a0b0c0d0e0f,
51             'urn:uuid:00010203-0405-0607-0809-0a0b0c0d0e0f',
52             0x607040500010203, 0x809, self.uuid.RESERVED_NCS, None),
53            ('02d9e6d5-9467-382e-8f9b-9300a64ac3cd',
54             '{02d9e6d5-9467-382e-8f9b-9300a64ac3cd}',
55             '02d9e6d59467382e8f9b9300a64ac3cd',
56             b'\x02\xd9\xe6\xd5\x94\x67\x38\x2e\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd',
57             b'\xd5\xe6\xd9\x02\x67\x94\x2e\x38\x8f\x9b\x93\x00\xa6\x4a\xc3\xcd',
58             (0x02d9e6d5, 0x9467, 0x382e, 0x8f, 0x9b, 0x9300a64ac3cd),
59             0x02d9e6d59467382e8f9b9300a64ac3cd,
60             'urn:uuid:02d9e6d5-9467-382e-8f9b-9300a64ac3cd',
61             0x82e946702d9e6d5, 0xf9b, self.uuid.RFC_4122, 3),
62            ('12345678-1234-5678-1234-567812345678',
63             '{12345678-1234-5678-1234-567812345678}',
64             '12345678123456781234567812345678',
65             b'\x12\x34\x56\x78'*4,
66             b'\x78\x56\x34\x12\x34\x12\x78\x56\x12\x34\x56\x78\x12\x34\x56\x78',
67             (0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678),
68             0x12345678123456781234567812345678,
69             'urn:uuid:12345678-1234-5678-1234-567812345678',
70             0x678123412345678, 0x1234, self.uuid.RESERVED_NCS, None),
71            ('6ba7b810-9dad-11d1-80b4-00c04fd430c8',
72             '{6ba7b810-9dad-11d1-80b4-00c04fd430c8}',
73             '6ba7b8109dad11d180b400c04fd430c8',
74             b'\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
75             b'\x10\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
76             (0x6ba7b810, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8),
77             0x6ba7b8109dad11d180b400c04fd430c8,
78             'urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8',
79             0x1d19dad6ba7b810, 0xb4, self.uuid.RFC_4122, 1),
80            ('6ba7b811-9dad-11d1-80b4-00c04fd430c8',
81             '{6ba7b811-9dad-11d1-80b4-00c04fd430c8}',
82             '6ba7b8119dad11d180b400c04fd430c8',
83             b'\x6b\xa7\xb8\x11\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
84             b'\x11\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
85             (0x6ba7b811, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8),
86             0x6ba7b8119dad11d180b400c04fd430c8,
87             'urn:uuid:6ba7b811-9dad-11d1-80b4-00c04fd430c8',
88             0x1d19dad6ba7b811, 0xb4, self.uuid.RFC_4122, 1),
89            ('6ba7b812-9dad-11d1-80b4-00c04fd430c8',
90             '{6ba7b812-9dad-11d1-80b4-00c04fd430c8}',
91             '6ba7b8129dad11d180b400c04fd430c8',
92             b'\x6b\xa7\xb8\x12\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
93             b'\x12\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
94             (0x6ba7b812, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8),
95             0x6ba7b8129dad11d180b400c04fd430c8,
96             'urn:uuid:6ba7b812-9dad-11d1-80b4-00c04fd430c8',
97             0x1d19dad6ba7b812, 0xb4, self.uuid.RFC_4122, 1),
98            ('6ba7b814-9dad-11d1-80b4-00c04fd430c8',
99             '{6ba7b814-9dad-11d1-80b4-00c04fd430c8}',
100             '6ba7b8149dad11d180b400c04fd430c8',
101             b'\x6b\xa7\xb8\x14\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
102             b'\x14\xb8\xa7\x6b\xad\x9d\xd1\x11\x80\xb4\x00\xc0\x4f\xd4\x30\xc8',
103             (0x6ba7b814, 0x9dad, 0x11d1, 0x80, 0xb4, 0x00c04fd430c8),
104             0x6ba7b8149dad11d180b400c04fd430c8,
105             'urn:uuid:6ba7b814-9dad-11d1-80b4-00c04fd430c8',
106             0x1d19dad6ba7b814, 0xb4, self.uuid.RFC_4122, 1),
107            ('7d444840-9dc0-11d1-b245-5ffdce74fad2',
108             '{7d444840-9dc0-11d1-b245-5ffdce74fad2}',
109             '7d4448409dc011d1b2455ffdce74fad2',
110             b'\x7d\x44\x48\x40\x9d\xc0\x11\xd1\xb2\x45\x5f\xfd\xce\x74\xfa\xd2',
111             b'\x40\x48\x44\x7d\xc0\x9d\xd1\x11\xb2\x45\x5f\xfd\xce\x74\xfa\xd2',
112             (0x7d444840, 0x9dc0, 0x11d1, 0xb2, 0x45, 0x5ffdce74fad2),
113             0x7d4448409dc011d1b2455ffdce74fad2,
114             'urn:uuid:7d444840-9dc0-11d1-b245-5ffdce74fad2',
115             0x1d19dc07d444840, 0x3245, self.uuid.RFC_4122, 1),
116            ('e902893a-9d22-3c7e-a7b8-d6e313b71d9f',
117             '{e902893a-9d22-3c7e-a7b8-d6e313b71d9f}',
118             'e902893a9d223c7ea7b8d6e313b71d9f',
119             b'\xe9\x02\x89\x3a\x9d\x22\x3c\x7e\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f',
120             b'\x3a\x89\x02\xe9\x22\x9d\x7e\x3c\xa7\xb8\xd6\xe3\x13\xb7\x1d\x9f',
121             (0xe902893a, 0x9d22, 0x3c7e, 0xa7, 0xb8, 0xd6e313b71d9f),
122             0xe902893a9d223c7ea7b8d6e313b71d9f,
123             'urn:uuid:e902893a-9d22-3c7e-a7b8-d6e313b71d9f',
124             0xc7e9d22e902893a, 0x27b8, self.uuid.RFC_4122, 3),
125            ('eb424026-6f54-4ef8-a4d0-bb658a1fc6cf',
126             '{eb424026-6f54-4ef8-a4d0-bb658a1fc6cf}',
127             'eb4240266f544ef8a4d0bb658a1fc6cf',
128             b'\xeb\x42\x40\x26\x6f\x54\x4e\xf8\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf',
129             b'\x26\x40\x42\xeb\x54\x6f\xf8\x4e\xa4\xd0\xbb\x65\x8a\x1f\xc6\xcf',
130             (0xeb424026, 0x6f54, 0x4ef8, 0xa4, 0xd0, 0xbb658a1fc6cf),
131             0xeb4240266f544ef8a4d0bb658a1fc6cf,
132             'urn:uuid:eb424026-6f54-4ef8-a4d0-bb658a1fc6cf',
133             0xef86f54eb424026, 0x24d0, self.uuid.RFC_4122, 4),
134            ('f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
135             '{f81d4fae-7dec-11d0-a765-00a0c91e6bf6}',
136             'f81d4fae7dec11d0a76500a0c91e6bf6',
137             b'\xf8\x1d\x4f\xae\x7d\xec\x11\xd0\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6',
138             b'\xae\x4f\x1d\xf8\xec\x7d\xd0\x11\xa7\x65\x00\xa0\xc9\x1e\x6b\xf6',
139             (0xf81d4fae, 0x7dec, 0x11d0, 0xa7, 0x65, 0x00a0c91e6bf6),
140             0xf81d4fae7dec11d0a76500a0c91e6bf6,
141             'urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6',
142             0x1d07decf81d4fae, 0x2765, self.uuid.RFC_4122, 1),
143            ('fffefdfc-fffe-fffe-fffe-fffefdfcfbfa',
144             '{fffefdfc-fffe-fffe-fffe-fffefdfcfbfa}',
145             'fffefdfcfffefffefffefffefdfcfbfa',
146             b'\xff\xfe\xfd\xfc\xff\xfe\xff\xfe\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa',
147             b'\xfc\xfd\xfe\xff\xfe\xff\xfe\xff\xff\xfe\xff\xfe\xfd\xfc\xfb\xfa',
148             (0xfffefdfc, 0xfffe, 0xfffe, 0xff, 0xfe, 0xfffefdfcfbfa),
149             0xfffefdfcfffefffefffefffefdfcfbfa,
150             'urn:uuid:fffefdfc-fffe-fffe-fffe-fffefdfcfbfa',
151             0xffefffefffefdfc, 0x3ffe, self.uuid.RESERVED_FUTURE, None),
152            ('ffffffff-ffff-ffff-ffff-ffffffffffff',
153             '{ffffffff-ffff-ffff-ffff-ffffffffffff}',
154             'ffffffffffffffffffffffffffffffff',
155             b'\xff'*16,
156             b'\xff'*16,
157             (0xffffffff, 0xffff, 0xffff, 0xff, 0xff, 0xffffffffffff),
158             0xffffffffffffffffffffffffffffffff,
159             'urn:uuid:ffffffff-ffff-ffff-ffff-ffffffffffff',
160             0xfffffffffffffff, 0x3fff, self.uuid.RESERVED_FUTURE, None),
161            ]:
162            equivalents = []
163            # Construct each UUID in several different ways.
164            for u in [self.uuid.UUID(string), self.uuid.UUID(curly), self.uuid.UUID(hex),
165                      self.uuid.UUID(bytes=bytes), self.uuid.UUID(bytes_le=bytes_le),
166                      self.uuid.UUID(fields=fields), self.uuid.UUID(int=integer),
167                      self.uuid.UUID(urn)]:
168                # Test all conversions and properties of the UUID object.
169                equal(str(u), string)
170                equal(int(u), integer)
171                equal(u.bytes, bytes)
172                equal(u.bytes_le, bytes_le)
173                equal(u.fields, fields)
174                equal(u.time_low, fields[0])
175                equal(u.time_mid, fields[1])
176                equal(u.time_hi_version, fields[2])
177                equal(u.clock_seq_hi_variant, fields[3])
178                equal(u.clock_seq_low, fields[4])
179                equal(u.node, fields[5])
180                equal(u.hex, hex)
181                equal(u.int, integer)
182                equal(u.urn, urn)
183                equal(u.time, time)
184                equal(u.clock_seq, clock_seq)
185                equal(u.variant, variant)
186                equal(u.version, version)
187                equivalents.append(u)
188
189            # Different construction methods should give the same UUID.
190            for u in equivalents:
191                for v in equivalents:
192                    equal(u, v)
193
194            # Bug 7380: "bytes" and "bytes_le" should give the same type.
195            equal(type(u.bytes), builtins.bytes)
196            equal(type(u.bytes_le), builtins.bytes)
197
198            ascending.append(u)
199
200        # Test comparison of UUIDs.
201        for i in range(len(ascending)):
202            for j in range(len(ascending)):
203                equal(i < j, ascending[i] < ascending[j])
204                equal(i <= j, ascending[i] <= ascending[j])
205                equal(i == j, ascending[i] == ascending[j])
206                equal(i > j, ascending[i] > ascending[j])
207                equal(i >= j, ascending[i] >= ascending[j])
208                equal(i != j, ascending[i] != ascending[j])
209
210        # Test sorting of UUIDs (above list is in ascending order).
211        resorted = ascending[:]
212        resorted.reverse()
213        resorted.sort()
214        equal(ascending, resorted)
215
216    def test_exceptions(self):
217        badvalue = lambda f: self.assertRaises(ValueError, f)
218        badtype = lambda f: self.assertRaises(TypeError, f)
219
220        # Badly formed hex strings.
221        badvalue(lambda: self.uuid.UUID(''))
222        badvalue(lambda: self.uuid.UUID('abc'))
223        badvalue(lambda: self.uuid.UUID('1234567812345678123456781234567'))
224        badvalue(lambda: self.uuid.UUID('123456781234567812345678123456789'))
225        badvalue(lambda: self.uuid.UUID('123456781234567812345678z2345678'))
226
227        # Badly formed bytes.
228        badvalue(lambda: self.uuid.UUID(bytes='abc'))
229        badvalue(lambda: self.uuid.UUID(bytes='\0'*15))
230        badvalue(lambda: self.uuid.UUID(bytes='\0'*17))
231
232        # Badly formed bytes_le.
233        badvalue(lambda: self.uuid.UUID(bytes_le='abc'))
234        badvalue(lambda: self.uuid.UUID(bytes_le='\0'*15))
235        badvalue(lambda: self.uuid.UUID(bytes_le='\0'*17))
236
237        # Badly formed fields.
238        badvalue(lambda: self.uuid.UUID(fields=(1,)))
239        badvalue(lambda: self.uuid.UUID(fields=(1, 2, 3, 4, 5)))
240        badvalue(lambda: self.uuid.UUID(fields=(1, 2, 3, 4, 5, 6, 7)))
241
242        # Field values out of range.
243        badvalue(lambda: self.uuid.UUID(fields=(-1, 0, 0, 0, 0, 0)))
244        badvalue(lambda: self.uuid.UUID(fields=(0x100000000, 0, 0, 0, 0, 0)))
245        badvalue(lambda: self.uuid.UUID(fields=(0, -1, 0, 0, 0, 0)))
246        badvalue(lambda: self.uuid.UUID(fields=(0, 0x10000, 0, 0, 0, 0)))
247        badvalue(lambda: self.uuid.UUID(fields=(0, 0, -1, 0, 0, 0)))
248        badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0x10000, 0, 0, 0)))
249        badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, -1, 0, 0)))
250        badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0x100, 0, 0)))
251        badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0, -1, 0)))
252        badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0, 0x100, 0)))
253        badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0, 0, -1)))
254        badvalue(lambda: self.uuid.UUID(fields=(0, 0, 0, 0, 0, 0x1000000000000)))
255
256        # Version number out of range.
257        badvalue(lambda: self.uuid.UUID('00'*16, version=0))
258        badvalue(lambda: self.uuid.UUID('00'*16, version=6))
259
260        # Integer value out of range.
261        badvalue(lambda: self.uuid.UUID(int=-1))
262        badvalue(lambda: self.uuid.UUID(int=1<<128))
263
264        # Must supply exactly one of hex, bytes, fields, int.
265        h, b, f, i = '00'*16, b'\0'*16, (0, 0, 0, 0, 0, 0), 0
266        self.uuid.UUID(h)
267        self.uuid.UUID(hex=h)
268        self.uuid.UUID(bytes=b)
269        self.uuid.UUID(bytes_le=b)
270        self.uuid.UUID(fields=f)
271        self.uuid.UUID(int=i)
272
273        # Wrong number of arguments (positional).
274        badtype(lambda: self.uuid.UUID())
275        badtype(lambda: self.uuid.UUID(h, b))
276        badtype(lambda: self.uuid.UUID(h, b, b))
277        badtype(lambda: self.uuid.UUID(h, b, b, f))
278        badtype(lambda: self.uuid.UUID(h, b, b, f, i))
279
280        # Duplicate arguments.
281        for hh in [[], [('hex', h)]]:
282            for bb in [[], [('bytes', b)]]:
283                for bble in [[], [('bytes_le', b)]]:
284                    for ii in [[], [('int', i)]]:
285                        for ff in [[], [('fields', f)]]:
286                            args = dict(hh + bb + bble + ii + ff)
287                            if len(args) != 0:
288                                badtype(lambda: self.uuid.UUID(h, **args))
289                            if len(args) != 1:
290                                badtype(lambda: self.uuid.UUID(**args))
291
292        # Immutability.
293        u = self.uuid.UUID(h)
294        badtype(lambda: setattr(u, 'hex', h))
295        badtype(lambda: setattr(u, 'bytes', b))
296        badtype(lambda: setattr(u, 'bytes_le', b))
297        badtype(lambda: setattr(u, 'fields', f))
298        badtype(lambda: setattr(u, 'int', i))
299        badtype(lambda: setattr(u, 'time_low', 0))
300        badtype(lambda: setattr(u, 'time_mid', 0))
301        badtype(lambda: setattr(u, 'time_hi_version', 0))
302        badtype(lambda: setattr(u, 'time_hi_version', 0))
303        badtype(lambda: setattr(u, 'clock_seq_hi_variant', 0))
304        badtype(lambda: setattr(u, 'clock_seq_low', 0))
305        badtype(lambda: setattr(u, 'node', 0))
306
307        # Comparison with a non-UUID object
308        badtype(lambda: u < object())
309        badtype(lambda: u > object())
310
311    def test_getnode(self):
312        node1 = self.uuid.getnode()
313        self.assertTrue(0 < node1 < (1 << 48), '%012x' % node1)
314
315        # Test it again to ensure consistency.
316        node2 = self.uuid.getnode()
317        self.assertEqual(node1, node2, '%012x != %012x' % (node1, node2))
318
319    def test_pickle_roundtrip(self):
320        def check(actual, expected):
321            self.assertEqual(actual, expected)
322            self.assertEqual(actual.is_safe, expected.is_safe)
323
324        with support.swap_item(sys.modules, 'uuid', self.uuid):
325            for is_safe in self.uuid.SafeUUID:
326                u = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5',
327                                   is_safe=is_safe)
328                check(copy.copy(u), u)
329                check(copy.deepcopy(u), u)
330                for proto in range(pickle.HIGHEST_PROTOCOL + 1):
331                    with self.subTest(protocol=proto):
332                        check(pickle.loads(pickle.dumps(u, proto)), u)
333
334    def test_unpickle_previous_python_versions(self):
335        def check(actual, expected):
336            self.assertEqual(actual, expected)
337            self.assertEqual(actual.is_safe, expected.is_safe)
338
339        pickled_uuids = [
340            # Python 2.7, protocol 0
341            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
342            b'tR(dS\'int\'\nL287307832597519156748809049798316161701L\nsb.',
343            # Python 2.7, protocol 1
344            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
345            b'tR}U\x03intL287307832597519156748809049798316161701L\nsb.',
346            # Python 2.7, protocol 2
347            b'\x80\x02cuuid\nUUID\n)\x81}U\x03int\x8a\x11\xa5z\xecz\nI\xdf}'
348            b'\xde\xa0Bf\xcey%\xd8\x00sb.',
349            # Python 3.6, protocol 0
350            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
351            b'tR(dVint\nL287307832597519156748809049798316161701L\nsb.',
352            # Python 3.6, protocol 1
353            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
354            b'tR}X\x03\x00\x00\x00intL287307832597519156748809049798316161701L'
355            b'\nsb.',
356            # Python 3.6, protocol 2
357            b'\x80\x02cuuid\nUUID\n)\x81}X\x03\x00\x00\x00int\x8a\x11\xa5z\xec'
358            b'z\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00sb.',
359            # Python 3.6, protocol 3
360            b'\x80\x03cuuid\nUUID\n)\x81}X\x03\x00\x00\x00int\x8a\x11\xa5z\xec'
361            b'z\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00sb.',
362            # Python 3.6, protocol 4
363            b'\x80\x04\x95+\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x8c\x04UUI'
364            b'D\x93)\x81}\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0Bf\xcey%'
365            b'\xd8\x00sb.',
366            # Python 3.7, protocol 0
367            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
368            b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n'
369            b'cuuid\nSafeUUID\n(NtRsb.',
370            # Python 3.7, protocol 1
371            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
372            b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701'
373            b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(NtRub.',
374            # Python 3.7, protocol 2
375            b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
376            b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
377            b'id\nSafeUUID\nN\x85Rub.',
378            # Python 3.7, protocol 3
379            b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
380            b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
381            b'id\nSafeUUID\nN\x85Rub.',
382            # Python 3.7, protocol 4
383            b'\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c'
384            b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0'
385            b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93N\x85Rub'
386            b'.',
387        ]
388        pickled_uuids_safe = [
389            # Python 3.7, protocol 0
390            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
391            b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n'
392            b'cuuid\nSafeUUID\n(I0\ntRsb.',
393            # Python 3.7, protocol 1
394            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
395            b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701'
396            b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(K\x00tRub.',
397            # Python 3.7, protocol 2
398            b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
399            b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
400            b'id\nSafeUUID\nK\x00\x85Rub.',
401            # Python 3.7, protocol 3
402            b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
403            b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
404            b'id\nSafeUUID\nK\x00\x85Rub.',
405            # Python 3.7, protocol 4
406            b'\x80\x04\x95G\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c'
407            b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0'
408            b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93K\x00'
409            b'\x85Rub.',
410        ]
411        pickled_uuids_unsafe = [
412            # Python 3.7, protocol 0
413            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
414            b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n'
415            b'cuuid\nSafeUUID\n(I-1\ntRsb.',
416            # Python 3.7, protocol 1
417            b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN'
418            b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701'
419            b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(J\xff\xff\xff\xfftR'
420            b'ub.',
421            # Python 3.7, protocol 2
422            b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
423            b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
424            b'id\nSafeUUID\nJ\xff\xff\xff\xff\x85Rub.',
425            # Python 3.7, protocol 3
426            b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z'
427            b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu'
428            b'id\nSafeUUID\nJ\xff\xff\xff\xff\x85Rub.',
429            # Python 3.7, protocol 4
430            b'\x80\x04\x95J\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c'
431            b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0'
432            b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93J\xff'
433            b'\xff\xff\xff\x85Rub.',
434        ]
435
436        u = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5')
437        u_safe = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5',
438                                is_safe=self.uuid.SafeUUID.safe)
439        u_unsafe = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5',
440                                  is_safe=self.uuid.SafeUUID.unsafe)
441
442        with support.swap_item(sys.modules, 'uuid', self.uuid):
443            for pickled in pickled_uuids:
444                # is_safe was added in 3.7.  When unpickling values from older
445                # versions, is_safe will be missing, so it should be set to
446                # SafeUUID.unknown.
447                check(pickle.loads(pickled), u)
448            for pickled in pickled_uuids_safe:
449                check(pickle.loads(pickled), u_safe)
450            for pickled in pickled_uuids_unsafe:
451                check(pickle.loads(pickled), u_unsafe)
452
453    # bpo-32502: UUID1 requires a 48-bit identifier, but hardware identifiers
454    # need not necessarily be 48 bits (e.g., EUI-64).
455    def test_uuid1_eui64(self):
456        # Confirm that uuid.getnode ignores hardware addresses larger than 48
457        # bits. Mock out each platform's *_getnode helper functions to return
458        # something just larger than 48 bits to test. This will cause
459        # uuid.getnode to fall back on uuid._random_getnode, which will
460        # generate a valid value.
461        too_large_getter = lambda: 1 << 48
462        with unittest.mock.patch.multiple(
463            self.uuid,
464            _node=None,  # Ignore any cached node value.
465            _GETTERS=[too_large_getter],
466        ):
467            node = self.uuid.getnode()
468        self.assertTrue(0 < node < (1 << 48), '%012x' % node)
469
470        # Confirm that uuid1 can use the generated node, i.e., the that
471        # uuid.getnode fell back on uuid._random_getnode() rather than using
472        # the value from too_large_getter above.
473        try:
474            self.uuid.uuid1(node=node)
475        except ValueError as e:
476            self.fail('uuid1 was given an invalid node ID')
477
478    def test_uuid1(self):
479        equal = self.assertEqual
480
481        # Make sure uuid1() generates UUIDs that are actually version 1.
482        for u in [self.uuid.uuid1() for i in range(10)]:
483            equal(u.variant, self.uuid.RFC_4122)
484            equal(u.version, 1)
485            self.assertIn(u.is_safe, {self.uuid.SafeUUID.safe,
486                                      self.uuid.SafeUUID.unsafe,
487                                      self.uuid.SafeUUID.unknown})
488
489        # Make sure the generated UUIDs are actually unique.
490        uuids = {}
491        for u in [self.uuid.uuid1() for i in range(1000)]:
492            uuids[u] = 1
493        equal(len(uuids.keys()), 1000)
494
495        # Make sure the supplied node ID appears in the UUID.
496        u = self.uuid.uuid1(0)
497        equal(u.node, 0)
498        u = self.uuid.uuid1(0x123456789abc)
499        equal(u.node, 0x123456789abc)
500        u = self.uuid.uuid1(0xffffffffffff)
501        equal(u.node, 0xffffffffffff)
502
503        # Make sure the supplied clock sequence appears in the UUID.
504        u = self.uuid.uuid1(0x123456789abc, 0)
505        equal(u.node, 0x123456789abc)
506        equal(((u.clock_seq_hi_variant & 0x3f) << 8) | u.clock_seq_low, 0)
507        u = self.uuid.uuid1(0x123456789abc, 0x1234)
508        equal(u.node, 0x123456789abc)
509        equal(((u.clock_seq_hi_variant & 0x3f) << 8) |
510                         u.clock_seq_low, 0x1234)
511        u = self.uuid.uuid1(0x123456789abc, 0x3fff)
512        equal(u.node, 0x123456789abc)
513        equal(((u.clock_seq_hi_variant & 0x3f) << 8) |
514                         u.clock_seq_low, 0x3fff)
515
516    # bpo-29925: On Mac OS X Tiger, self.uuid.uuid1().is_safe returns
517    # self.uuid.SafeUUID.unknown
518    @support.requires_mac_ver(10, 5)
519    @unittest.skipUnless(os.name == 'posix', 'POSIX-only test')
520    def test_uuid1_safe(self):
521        if not self.uuid._has_uuid_generate_time_safe:
522            self.skipTest('requires uuid_generate_time_safe(3)')
523
524        u = self.uuid.uuid1()
525        # uuid_generate_time_safe() may return 0 or -1 but what it returns is
526        # dependent on the underlying platform support.  At least it cannot be
527        # unknown (unless I suppose the platform is buggy).
528        self.assertNotEqual(u.is_safe, self.uuid.SafeUUID.unknown)
529
530    @contextlib.contextmanager
531    def mock_generate_time_safe(self, safe_value):
532        """
533        Mock uuid._generate_time_safe() to return a given *safe_value*.
534        """
535        if os.name != 'posix':
536            self.skipTest('POSIX-only test')
537        self.uuid._load_system_functions()
538        f = self.uuid._generate_time_safe
539        if f is None:
540            self.skipTest('need uuid._generate_time_safe')
541        with unittest.mock.patch.object(self.uuid, '_generate_time_safe',
542                                        lambda: (f()[0], safe_value)):
543            yield
544
545    @unittest.skipUnless(os.name == 'posix', 'POSIX-only test')
546    def test_uuid1_unknown(self):
547        # Even if the platform has uuid_generate_time_safe(), let's mock it to
548        # be uuid_generate_time() and ensure the safety is unknown.
549        with self.mock_generate_time_safe(None):
550            u = self.uuid.uuid1()
551            self.assertEqual(u.is_safe, self.uuid.SafeUUID.unknown)
552
553    @unittest.skipUnless(os.name == 'posix', 'POSIX-only test')
554    def test_uuid1_is_safe(self):
555        with self.mock_generate_time_safe(0):
556            u = self.uuid.uuid1()
557            self.assertEqual(u.is_safe, self.uuid.SafeUUID.safe)
558
559    @unittest.skipUnless(os.name == 'posix', 'POSIX-only test')
560    def test_uuid1_is_unsafe(self):
561        with self.mock_generate_time_safe(-1):
562            u = self.uuid.uuid1()
563            self.assertEqual(u.is_safe, self.uuid.SafeUUID.unsafe)
564
565    @unittest.skipUnless(os.name == 'posix', 'POSIX-only test')
566    def test_uuid1_bogus_return_value(self):
567        with self.mock_generate_time_safe(3):
568            u = self.uuid.uuid1()
569            self.assertEqual(u.is_safe, self.uuid.SafeUUID.unknown)
570
571    def test_uuid1_time(self):
572        with mock.patch.object(self.uuid, '_has_uuid_generate_time_safe', False), \
573             mock.patch.object(self.uuid, '_generate_time_safe', None), \
574             mock.patch.object(self.uuid, '_last_timestamp', None), \
575             mock.patch.object(self.uuid, 'getnode', return_value=93328246233727), \
576             mock.patch('time.time_ns', return_value=1545052026752910643), \
577             mock.patch('random.getrandbits', return_value=5317): # guaranteed to be random
578            u = self.uuid.uuid1()
579            self.assertEqual(u, self.uuid.UUID('a7a55b92-01fc-11e9-94c5-54e1acf6da7f'))
580
581        with mock.patch.object(self.uuid, '_has_uuid_generate_time_safe', False), \
582             mock.patch.object(self.uuid, '_generate_time_safe', None), \
583             mock.patch.object(self.uuid, '_last_timestamp', None), \
584             mock.patch('time.time_ns', return_value=1545052026752910643):
585            u = self.uuid.uuid1(node=93328246233727, clock_seq=5317)
586            self.assertEqual(u, self.uuid.UUID('a7a55b92-01fc-11e9-94c5-54e1acf6da7f'))
587
588    def test_uuid3(self):
589        equal = self.assertEqual
590
591        # Test some known version-3 UUIDs.
592        for u, v in [(self.uuid.uuid3(self.uuid.NAMESPACE_DNS, 'python.org'),
593                      '6fa459ea-ee8a-3ca4-894e-db77e160355e'),
594                     (self.uuid.uuid3(self.uuid.NAMESPACE_URL, 'http://python.org/'),
595                      '9fe8e8c4-aaa8-32a9-a55c-4535a88b748d'),
596                     (self.uuid.uuid3(self.uuid.NAMESPACE_OID, '1.3.6.1'),
597                      'dd1a1cef-13d5-368a-ad82-eca71acd4cd1'),
598                     (self.uuid.uuid3(self.uuid.NAMESPACE_X500, 'c=ca'),
599                      '658d3002-db6b-3040-a1d1-8ddd7d189a4d'),
600                    ]:
601            equal(u.variant, self.uuid.RFC_4122)
602            equal(u.version, 3)
603            equal(u, self.uuid.UUID(v))
604            equal(str(u), v)
605
606    def test_uuid4(self):
607        equal = self.assertEqual
608
609        # Make sure uuid4() generates UUIDs that are actually version 4.
610        for u in [self.uuid.uuid4() for i in range(10)]:
611            equal(u.variant, self.uuid.RFC_4122)
612            equal(u.version, 4)
613
614        # Make sure the generated UUIDs are actually unique.
615        uuids = {}
616        for u in [self.uuid.uuid4() for i in range(1000)]:
617            uuids[u] = 1
618        equal(len(uuids.keys()), 1000)
619
620    def test_uuid5(self):
621        equal = self.assertEqual
622
623        # Test some known version-5 UUIDs.
624        for u, v in [(self.uuid.uuid5(self.uuid.NAMESPACE_DNS, 'python.org'),
625                      '886313e1-3b8a-5372-9b90-0c9aee199e5d'),
626                     (self.uuid.uuid5(self.uuid.NAMESPACE_URL, 'http://python.org/'),
627                      '4c565f0d-3f5a-5890-b41b-20cf47701c5e'),
628                     (self.uuid.uuid5(self.uuid.NAMESPACE_OID, '1.3.6.1'),
629                      '1447fa61-5277-5fef-a9b3-fbc6e44f4af3'),
630                     (self.uuid.uuid5(self.uuid.NAMESPACE_X500, 'c=ca'),
631                      'cc957dd1-a972-5349-98cd-874190002798'),
632                    ]:
633            equal(u.variant, self.uuid.RFC_4122)
634            equal(u.version, 5)
635            equal(u, self.uuid.UUID(v))
636            equal(str(u), v)
637
638    @unittest.skipUnless(os.name == 'posix', 'requires Posix')
639    def testIssue8621(self):
640        # On at least some versions of OSX self.uuid.uuid4 generates
641        # the same sequence of UUIDs in the parent and any
642        # children started using fork.
643        fds = os.pipe()
644        pid = os.fork()
645        if pid == 0:
646            os.close(fds[0])
647            value = self.uuid.uuid4()
648            os.write(fds[1], value.hex.encode('latin-1'))
649            os._exit(0)
650
651        else:
652            os.close(fds[1])
653            self.addCleanup(os.close, fds[0])
654            parent_value = self.uuid.uuid4().hex
655            os.waitpid(pid, 0)
656            child_value = os.read(fds[0], 100).decode('latin-1')
657
658            self.assertNotEqual(parent_value, child_value)
659
660    def test_uuid_weakref(self):
661        # bpo-35701: check that weak referencing to a UUID object can be created
662        strong = self.uuid.uuid4()
663        weak = weakref.ref(strong)
664        self.assertIs(strong, weak())
665
666class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase):
667    uuid = py_uuid
668
669@unittest.skipUnless(c_uuid, 'requires the C _uuid module')
670class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
671    uuid = c_uuid
672
673
674class BaseTestInternals:
675    _uuid = py_uuid
676
677    @unittest.skipUnless(os.name == 'posix', 'requires Posix')
678    def test_find_mac(self):
679        data = '''
680fake hwaddr
681cscotun0  Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
682eth0      Link encap:Ethernet  HWaddr 12:34:56:78:90:ab
683'''
684
685        popen = unittest.mock.MagicMock()
686        popen.stdout = io.BytesIO(data.encode())
687
688        with unittest.mock.patch.object(shutil, 'which',
689                                        return_value='/sbin/ifconfig'):
690            with unittest.mock.patch.object(subprocess, 'Popen',
691                                            return_value=popen):
692                mac = self.uuid._find_mac(
693                    command='ifconfig',
694                    args='',
695                    hw_identifiers=[b'hwaddr'],
696                    get_index=lambda x: x + 1,
697                )
698
699        self.assertEqual(mac, 0x1234567890ab)
700
701    def check_node(self, node, requires=None):
702        if requires and node is None:
703            self.skipTest('requires ' + requires)
704        hex = '%012x' % node
705        if support.verbose >= 2:
706            print(hex, end=' ')
707        self.assertTrue(0 < node < (1 << 48),
708                        "%s is not an RFC 4122 node ID" % hex)
709
710    @unittest.skipUnless(_uuid._ifconfig_getnode in _uuid._GETTERS,
711        "ifconfig is not used for introspection on this platform")
712    def test_ifconfig_getnode(self):
713        node = self.uuid._ifconfig_getnode()
714        self.check_node(node, 'ifconfig')
715
716    @unittest.skipUnless(_uuid._ip_getnode in _uuid._GETTERS,
717        "ip is not used for introspection on this platform")
718    def test_ip_getnode(self):
719        node = self.uuid._ip_getnode()
720        self.check_node(node, 'ip')
721
722    @unittest.skipUnless(_uuid._arp_getnode in _uuid._GETTERS,
723        "arp is not used for introspection on this platform")
724    def test_arp_getnode(self):
725        node = self.uuid._arp_getnode()
726        self.check_node(node, 'arp')
727
728    @unittest.skipUnless(_uuid._lanscan_getnode in _uuid._GETTERS,
729        "lanscan is not used for introspection on this platform")
730    def test_lanscan_getnode(self):
731        node = self.uuid._lanscan_getnode()
732        self.check_node(node, 'lanscan')
733
734    @unittest.skipUnless(_uuid._netstat_getnode in _uuid._GETTERS,
735        "netstat is not used for introspection on this platform")
736    def test_netstat_getnode(self):
737        node = self.uuid._netstat_getnode()
738        self.check_node(node, 'netstat')
739
740    @unittest.skipUnless(os.name == 'nt', 'requires Windows')
741    def test_ipconfig_getnode(self):
742        node = self.uuid._ipconfig_getnode()
743        self.check_node(node, 'ipconfig')
744
745    @unittest.skipUnless(importable('win32wnet'), 'requires win32wnet')
746    @unittest.skipUnless(importable('netbios'), 'requires netbios')
747    def test_netbios_getnode(self):
748        node = self.uuid._netbios_getnode()
749        self.check_node(node)
750
751    def test_random_getnode(self):
752        node = self.uuid._random_getnode()
753        # The multicast bit, i.e. the least significant bit of first octet,
754        # must be set for randomly generated MAC addresses.  See RFC 4122,
755        # $4.1.6.
756        self.assertTrue(node & (1 << 40), '%012x' % node)
757        self.check_node(node)
758
759        node2 = self.uuid._random_getnode()
760        self.assertNotEqual(node2, node, '%012x' % node)
761
762    @unittest.skipUnless(os.name == 'posix', 'requires Posix')
763    def test_unix_getnode(self):
764        if not importable('_uuid') and not importable('ctypes'):
765            self.skipTest("neither _uuid extension nor ctypes available")
766        try: # Issues 1481, 3581: _uuid_generate_time() might be None.
767            node = self.uuid._unix_getnode()
768        except TypeError:
769            self.skipTest('requires uuid_generate_time')
770        self.check_node(node, 'unix')
771
772    @unittest.skipUnless(os.name == 'nt', 'requires Windows')
773    @unittest.skipUnless(importable('ctypes'), 'requires ctypes')
774    def test_windll_getnode(self):
775        node = self.uuid._windll_getnode()
776        self.check_node(node)
777
778
779class TestInternalsWithoutExtModule(BaseTestInternals, unittest.TestCase):
780    uuid = py_uuid
781
782@unittest.skipUnless(c_uuid, 'requires the C _uuid module')
783class TestInternalsWithExtModule(BaseTestInternals, unittest.TestCase):
784    uuid = c_uuid
785
786
787if __name__ == '__main__':
788    unittest.main()
789