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