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