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 @support.requires_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