|
2 | 2 | from test import support |
3 | 3 | import builtins |
4 | 4 | import contextlib |
| 5 | +import copy |
5 | 6 | import io |
6 | 7 | import os |
| 8 | +import pickle |
7 | 9 | import shutil |
8 | 10 | import subprocess |
| 11 | +import sys |
9 | 12 |
|
10 | 13 | py_uuid = support.import_fresh_module('uuid', blocked=['_uuid']) |
11 | 14 | c_uuid = support.import_fresh_module('uuid', fresh=['_uuid']) |
@@ -311,6 +314,140 @@ def test_getnode(self): |
311 | 314 | node2 = self.uuid.getnode() |
312 | 315 | self.assertEqual(node1, node2, '%012x != %012x' % (node1, node2)) |
313 | 316 |
|
| 317 | + def test_pickle_roundtrip(self): |
| 318 | + def check(actual, expected): |
| 319 | + self.assertEqual(actual, expected) |
| 320 | + self.assertEqual(actual.is_safe, expected.is_safe) |
| 321 | + |
| 322 | + with support.swap_item(sys.modules, 'uuid', self.uuid): |
| 323 | + for is_safe in self.uuid.SafeUUID: |
| 324 | + u = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5', |
| 325 | + is_safe=is_safe) |
| 326 | + check(copy.copy(u), u) |
| 327 | + check(copy.deepcopy(u), u) |
| 328 | + for proto in range(pickle.HIGHEST_PROTOCOL + 1): |
| 329 | + with self.subTest(protocol=proto): |
| 330 | + check(pickle.loads(pickle.dumps(u, proto)), u) |
| 331 | + |
| 332 | + def test_unpickle_previous_python_versions(self): |
| 333 | + def check(actual, expected): |
| 334 | + self.assertEqual(actual, expected) |
| 335 | + self.assertEqual(actual.is_safe, expected.is_safe) |
| 336 | + |
| 337 | + pickled_uuids = [ |
| 338 | + # Python 2.7, protocol 0 |
| 339 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 340 | + b'tR(dS\'int\'\nL287307832597519156748809049798316161701L\nsb.', |
| 341 | + # Python 2.7, protocol 1 |
| 342 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 343 | + b'tR}U\x03intL287307832597519156748809049798316161701L\nsb.', |
| 344 | + # Python 2.7, protocol 2 |
| 345 | + b'\x80\x02cuuid\nUUID\n)\x81}U\x03int\x8a\x11\xa5z\xecz\nI\xdf}' |
| 346 | + b'\xde\xa0Bf\xcey%\xd8\x00sb.', |
| 347 | + # Python 3.6, protocol 0 |
| 348 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 349 | + b'tR(dVint\nL287307832597519156748809049798316161701L\nsb.', |
| 350 | + # Python 3.6, protocol 1 |
| 351 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 352 | + b'tR}X\x03\x00\x00\x00intL287307832597519156748809049798316161701L' |
| 353 | + b'\nsb.', |
| 354 | + # Python 3.6, protocol 2 |
| 355 | + b'\x80\x02cuuid\nUUID\n)\x81}X\x03\x00\x00\x00int\x8a\x11\xa5z\xec' |
| 356 | + b'z\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00sb.', |
| 357 | + # Python 3.6, protocol 3 |
| 358 | + b'\x80\x03cuuid\nUUID\n)\x81}X\x03\x00\x00\x00int\x8a\x11\xa5z\xec' |
| 359 | + b'z\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00sb.', |
| 360 | + # Python 3.6, protocol 4 |
| 361 | + b'\x80\x04\x95+\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x8c\x04UUI' |
| 362 | + b'D\x93)\x81}\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0Bf\xcey%' |
| 363 | + b'\xd8\x00sb.', |
| 364 | + # Python 3.7, protocol 0 |
| 365 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 366 | + b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n' |
| 367 | + b'cuuid\nSafeUUID\n(NtRsb.', |
| 368 | + # Python 3.7, protocol 1 |
| 369 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 370 | + b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701' |
| 371 | + b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(NtRub.', |
| 372 | + # Python 3.7, protocol 2 |
| 373 | + b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' |
| 374 | + b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' |
| 375 | + b'id\nSafeUUID\nN\x85Rub.', |
| 376 | + # Python 3.7, protocol 3 |
| 377 | + b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' |
| 378 | + b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' |
| 379 | + b'id\nSafeUUID\nN\x85Rub.', |
| 380 | + # Python 3.7, protocol 4 |
| 381 | + b'\x80\x04\x95F\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c' |
| 382 | + b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0' |
| 383 | + b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93N\x85Rub' |
| 384 | + b'.', |
| 385 | + ] |
| 386 | + pickled_uuids_safe = [ |
| 387 | + # Python 3.7, protocol 0 |
| 388 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 389 | + b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n' |
| 390 | + b'cuuid\nSafeUUID\n(I0\ntRsb.', |
| 391 | + # Python 3.7, protocol 1 |
| 392 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 393 | + b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701' |
| 394 | + b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(K\x00tRub.', |
| 395 | + # Python 3.7, protocol 2 |
| 396 | + b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' |
| 397 | + b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' |
| 398 | + b'id\nSafeUUID\nK\x00\x85Rub.', |
| 399 | + # Python 3.7, protocol 3 |
| 400 | + b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' |
| 401 | + b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' |
| 402 | + b'id\nSafeUUID\nK\x00\x85Rub.', |
| 403 | + # Python 3.7, protocol 4 |
| 404 | + b'\x80\x04\x95G\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c' |
| 405 | + b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0' |
| 406 | + b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93K\x00' |
| 407 | + b'\x85Rub.', |
| 408 | + ] |
| 409 | + pickled_uuids_unsafe = [ |
| 410 | + # Python 3.7, protocol 0 |
| 411 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 412 | + b'tR(dVint\nL287307832597519156748809049798316161701L\nsVis_safe\n' |
| 413 | + b'cuuid\nSafeUUID\n(I-1\ntRsb.', |
| 414 | + # Python 3.7, protocol 1 |
| 415 | + b'ccopy_reg\n_reconstructor\n(cuuid\nUUID\nc__builtin__\nobject\nN' |
| 416 | + b'tR}(X\x03\x00\x00\x00intL287307832597519156748809049798316161701' |
| 417 | + b'L\nX\x07\x00\x00\x00is_safecuuid\nSafeUUID\n(J\xff\xff\xff\xfftR' |
| 418 | + b'ub.', |
| 419 | + # Python 3.7, protocol 2 |
| 420 | + b'\x80\x02cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' |
| 421 | + b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' |
| 422 | + b'id\nSafeUUID\nJ\xff\xff\xff\xff\x85Rub.', |
| 423 | + # Python 3.7, protocol 3 |
| 424 | + b'\x80\x03cuuid\nUUID\n)\x81}(X\x03\x00\x00\x00int\x8a\x11\xa5z' |
| 425 | + b'\xecz\nI\xdf}\xde\xa0Bf\xcey%\xd8\x00X\x07\x00\x00\x00is_safecuu' |
| 426 | + b'id\nSafeUUID\nJ\xff\xff\xff\xff\x85Rub.', |
| 427 | + # Python 3.7, protocol 4 |
| 428 | + b'\x80\x04\x95J\x00\x00\x00\x00\x00\x00\x00\x8c\x04uuid\x94\x8c' |
| 429 | + b'\x04UUID\x93)\x81}(\x8c\x03int\x8a\x11\xa5z\xecz\nI\xdf}\xde\xa0' |
| 430 | + b'Bf\xcey%\xd8\x00\x8c\x07is_safeh\x00\x8c\x08SafeUUID\x93J\xff' |
| 431 | + b'\xff\xff\xff\x85Rub.', |
| 432 | + ] |
| 433 | + |
| 434 | + u = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5') |
| 435 | + u_safe = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5', |
| 436 | + is_safe=self.uuid.SafeUUID.safe) |
| 437 | + u_unsafe = self.uuid.UUID('d82579ce6642a0de7ddf490a7aec7aa5', |
| 438 | + is_safe=self.uuid.SafeUUID.unsafe) |
| 439 | + |
| 440 | + with support.swap_item(sys.modules, 'uuid', self.uuid): |
| 441 | + for pickled in pickled_uuids: |
| 442 | + # is_safe was added in 3.7. When unpickling values from older |
| 443 | + # versions, is_safe will be missing, so it should be set to |
| 444 | + # SafeUUID.unknown. |
| 445 | + check(pickle.loads(pickled), u) |
| 446 | + for pickled in pickled_uuids_safe: |
| 447 | + check(pickle.loads(pickled), u_safe) |
| 448 | + for pickled in pickled_uuids_unsafe: |
| 449 | + check(pickle.loads(pickled), u_unsafe) |
| 450 | + |
314 | 451 | # bpo-32502: UUID1 requires a 48-bit identifier, but hardware identifiers |
315 | 452 | # need not necessarily be 48 bits (e.g., EUI-64). |
316 | 453 | def test_uuid1_eui64(self): |
|
0 commit comments