17db96d56Sopenharmony_ciimport builtins 27db96d56Sopenharmony_ciimport collections 37db96d56Sopenharmony_ciimport copyreg 47db96d56Sopenharmony_ciimport dbm 57db96d56Sopenharmony_ciimport io 67db96d56Sopenharmony_ciimport functools 77db96d56Sopenharmony_ciimport os 87db96d56Sopenharmony_ciimport math 97db96d56Sopenharmony_ciimport pickle 107db96d56Sopenharmony_ciimport pickletools 117db96d56Sopenharmony_ciimport shutil 127db96d56Sopenharmony_ciimport struct 137db96d56Sopenharmony_ciimport sys 147db96d56Sopenharmony_ciimport threading 157db96d56Sopenharmony_ciimport types 167db96d56Sopenharmony_ciimport unittest 177db96d56Sopenharmony_ciimport weakref 187db96d56Sopenharmony_cifrom textwrap import dedent 197db96d56Sopenharmony_cifrom http.cookies import SimpleCookie 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_citry: 227db96d56Sopenharmony_ci import _testbuffer 237db96d56Sopenharmony_ciexcept ImportError: 247db96d56Sopenharmony_ci _testbuffer = None 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_cifrom test import support 277db96d56Sopenharmony_cifrom test.support import os_helper 287db96d56Sopenharmony_cifrom test.support import ( 297db96d56Sopenharmony_ci TestFailed, run_with_locale, no_tracing, 307db96d56Sopenharmony_ci _2G, _4G, bigmemtest 317db96d56Sopenharmony_ci ) 327db96d56Sopenharmony_cifrom test.support.import_helper import forget 337db96d56Sopenharmony_cifrom test.support.os_helper import TESTFN 347db96d56Sopenharmony_cifrom test.support import threading_helper 357db96d56Sopenharmony_cifrom test.support.warnings_helper import save_restore_warnings_filters 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_cifrom pickle import bytes_types 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_ci# bpo-41003: Save/restore warnings filters to leave them unchanged. 417db96d56Sopenharmony_ci# Ignore filters installed by numpy. 427db96d56Sopenharmony_citry: 437db96d56Sopenharmony_ci with save_restore_warnings_filters(): 447db96d56Sopenharmony_ci import numpy as np 457db96d56Sopenharmony_ciexcept ImportError: 467db96d56Sopenharmony_ci np = None 477db96d56Sopenharmony_ci 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_cirequires_32b = unittest.skipUnless(sys.maxsize < 2**32, 507db96d56Sopenharmony_ci "test is only meaningful on 32-bit builds") 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci# Tests that try a number of pickle protocols should have a 537db96d56Sopenharmony_ci# for proto in protocols: 547db96d56Sopenharmony_ci# kind of outer loop. 557db96d56Sopenharmony_ciprotocols = range(pickle.HIGHEST_PROTOCOL + 1) 567db96d56Sopenharmony_ci 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci# Return True if opcode code appears in the pickle, else False. 597db96d56Sopenharmony_cidef opcode_in_pickle(code, pickle): 607db96d56Sopenharmony_ci for op, dummy, dummy in pickletools.genops(pickle): 617db96d56Sopenharmony_ci if op.code == code.decode("latin-1"): 627db96d56Sopenharmony_ci return True 637db96d56Sopenharmony_ci return False 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci# Return the number of times opcode code appears in pickle. 667db96d56Sopenharmony_cidef count_opcode(code, pickle): 677db96d56Sopenharmony_ci n = 0 687db96d56Sopenharmony_ci for op, dummy, dummy in pickletools.genops(pickle): 697db96d56Sopenharmony_ci if op.code == code.decode("latin-1"): 707db96d56Sopenharmony_ci n += 1 717db96d56Sopenharmony_ci return n 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_cidef identity(x): 757db96d56Sopenharmony_ci return x 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ciclass UnseekableIO(io.BytesIO): 797db96d56Sopenharmony_ci def peek(self, *args): 807db96d56Sopenharmony_ci raise NotImplementedError 817db96d56Sopenharmony_ci 827db96d56Sopenharmony_ci def seekable(self): 837db96d56Sopenharmony_ci return False 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci def seek(self, *args): 867db96d56Sopenharmony_ci raise io.UnsupportedOperation 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ci def tell(self): 897db96d56Sopenharmony_ci raise io.UnsupportedOperation 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci 927db96d56Sopenharmony_ciclass MinimalIO(object): 937db96d56Sopenharmony_ci """ 947db96d56Sopenharmony_ci A file-like object that doesn't support readinto(). 957db96d56Sopenharmony_ci """ 967db96d56Sopenharmony_ci def __init__(self, *args): 977db96d56Sopenharmony_ci self._bio = io.BytesIO(*args) 987db96d56Sopenharmony_ci self.getvalue = self._bio.getvalue 997db96d56Sopenharmony_ci self.read = self._bio.read 1007db96d56Sopenharmony_ci self.readline = self._bio.readline 1017db96d56Sopenharmony_ci self.write = self._bio.write 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci 1047db96d56Sopenharmony_ci# We can't very well test the extension registry without putting known stuff 1057db96d56Sopenharmony_ci# in it, but we have to be careful to restore its original state. Code 1067db96d56Sopenharmony_ci# should do this: 1077db96d56Sopenharmony_ci# 1087db96d56Sopenharmony_ci# e = ExtensionSaver(extension_code) 1097db96d56Sopenharmony_ci# try: 1107db96d56Sopenharmony_ci# fiddle w/ the extension registry's stuff for extension_code 1117db96d56Sopenharmony_ci# finally: 1127db96d56Sopenharmony_ci# e.restore() 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ciclass ExtensionSaver: 1157db96d56Sopenharmony_ci # Remember current registration for code (if any), and remove it (if 1167db96d56Sopenharmony_ci # there is one). 1177db96d56Sopenharmony_ci def __init__(self, code): 1187db96d56Sopenharmony_ci self.code = code 1197db96d56Sopenharmony_ci if code in copyreg._inverted_registry: 1207db96d56Sopenharmony_ci self.pair = copyreg._inverted_registry[code] 1217db96d56Sopenharmony_ci copyreg.remove_extension(self.pair[0], self.pair[1], code) 1227db96d56Sopenharmony_ci else: 1237db96d56Sopenharmony_ci self.pair = None 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ci # Restore previous registration for code. 1267db96d56Sopenharmony_ci def restore(self): 1277db96d56Sopenharmony_ci code = self.code 1287db96d56Sopenharmony_ci curpair = copyreg._inverted_registry.get(code) 1297db96d56Sopenharmony_ci if curpair is not None: 1307db96d56Sopenharmony_ci copyreg.remove_extension(curpair[0], curpair[1], code) 1317db96d56Sopenharmony_ci pair = self.pair 1327db96d56Sopenharmony_ci if pair is not None: 1337db96d56Sopenharmony_ci copyreg.add_extension(pair[0], pair[1], code) 1347db96d56Sopenharmony_ci 1357db96d56Sopenharmony_ciclass C: 1367db96d56Sopenharmony_ci def __eq__(self, other): 1377db96d56Sopenharmony_ci return self.__dict__ == other.__dict__ 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ciclass D(C): 1407db96d56Sopenharmony_ci def __init__(self, arg): 1417db96d56Sopenharmony_ci pass 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ciclass E(C): 1447db96d56Sopenharmony_ci def __getinitargs__(self): 1457db96d56Sopenharmony_ci return () 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_ci# Simple mutable object. 1487db96d56Sopenharmony_ciclass Object: 1497db96d56Sopenharmony_ci pass 1507db96d56Sopenharmony_ci 1517db96d56Sopenharmony_ci# Hashable immutable key object containing unheshable mutable data. 1527db96d56Sopenharmony_ciclass K: 1537db96d56Sopenharmony_ci def __init__(self, value): 1547db96d56Sopenharmony_ci self.value = value 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ci def __reduce__(self): 1577db96d56Sopenharmony_ci # Shouldn't support the recursion itself 1587db96d56Sopenharmony_ci return K, (self.value,) 1597db96d56Sopenharmony_ci 1607db96d56Sopenharmony_ciimport __main__ 1617db96d56Sopenharmony_ci__main__.C = C 1627db96d56Sopenharmony_ciC.__module__ = "__main__" 1637db96d56Sopenharmony_ci__main__.D = D 1647db96d56Sopenharmony_ciD.__module__ = "__main__" 1657db96d56Sopenharmony_ci__main__.E = E 1667db96d56Sopenharmony_ciE.__module__ = "__main__" 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ciclass myint(int): 1697db96d56Sopenharmony_ci def __init__(self, x): 1707db96d56Sopenharmony_ci self.str = str(x) 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_ciclass initarg(C): 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_ci def __init__(self, a, b): 1757db96d56Sopenharmony_ci self.a = a 1767db96d56Sopenharmony_ci self.b = b 1777db96d56Sopenharmony_ci 1787db96d56Sopenharmony_ci def __getinitargs__(self): 1797db96d56Sopenharmony_ci return self.a, self.b 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ciclass metaclass(type): 1827db96d56Sopenharmony_ci pass 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_ciclass use_metaclass(object, metaclass=metaclass): 1857db96d56Sopenharmony_ci pass 1867db96d56Sopenharmony_ci 1877db96d56Sopenharmony_ciclass pickling_metaclass(type): 1887db96d56Sopenharmony_ci def __eq__(self, other): 1897db96d56Sopenharmony_ci return (type(self) == type(other) and 1907db96d56Sopenharmony_ci self.reduce_args == other.reduce_args) 1917db96d56Sopenharmony_ci 1927db96d56Sopenharmony_ci def __reduce__(self): 1937db96d56Sopenharmony_ci return (create_dynamic_class, self.reduce_args) 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_cidef create_dynamic_class(name, bases): 1967db96d56Sopenharmony_ci result = pickling_metaclass(name, bases, dict()) 1977db96d56Sopenharmony_ci result.reduce_args = (name, bases) 1987db96d56Sopenharmony_ci return result 1997db96d56Sopenharmony_ci 2007db96d56Sopenharmony_ci 2017db96d56Sopenharmony_ciclass ZeroCopyBytes(bytes): 2027db96d56Sopenharmony_ci readonly = True 2037db96d56Sopenharmony_ci c_contiguous = True 2047db96d56Sopenharmony_ci f_contiguous = True 2057db96d56Sopenharmony_ci zero_copy_reconstruct = True 2067db96d56Sopenharmony_ci 2077db96d56Sopenharmony_ci def __reduce_ex__(self, protocol): 2087db96d56Sopenharmony_ci if protocol >= 5: 2097db96d56Sopenharmony_ci return type(self)._reconstruct, (pickle.PickleBuffer(self),), None 2107db96d56Sopenharmony_ci else: 2117db96d56Sopenharmony_ci return type(self)._reconstruct, (bytes(self),) 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_ci def __repr__(self): 2147db96d56Sopenharmony_ci return "{}({!r})".format(self.__class__.__name__, bytes(self)) 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_ci __str__ = __repr__ 2177db96d56Sopenharmony_ci 2187db96d56Sopenharmony_ci @classmethod 2197db96d56Sopenharmony_ci def _reconstruct(cls, obj): 2207db96d56Sopenharmony_ci with memoryview(obj) as m: 2217db96d56Sopenharmony_ci obj = m.obj 2227db96d56Sopenharmony_ci if type(obj) is cls: 2237db96d56Sopenharmony_ci # Zero-copy 2247db96d56Sopenharmony_ci return obj 2257db96d56Sopenharmony_ci else: 2267db96d56Sopenharmony_ci return cls(obj) 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci 2297db96d56Sopenharmony_ciclass ZeroCopyBytearray(bytearray): 2307db96d56Sopenharmony_ci readonly = False 2317db96d56Sopenharmony_ci c_contiguous = True 2327db96d56Sopenharmony_ci f_contiguous = True 2337db96d56Sopenharmony_ci zero_copy_reconstruct = True 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_ci def __reduce_ex__(self, protocol): 2367db96d56Sopenharmony_ci if protocol >= 5: 2377db96d56Sopenharmony_ci return type(self)._reconstruct, (pickle.PickleBuffer(self),), None 2387db96d56Sopenharmony_ci else: 2397db96d56Sopenharmony_ci return type(self)._reconstruct, (bytes(self),) 2407db96d56Sopenharmony_ci 2417db96d56Sopenharmony_ci def __repr__(self): 2427db96d56Sopenharmony_ci return "{}({!r})".format(self.__class__.__name__, bytes(self)) 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci __str__ = __repr__ 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci @classmethod 2477db96d56Sopenharmony_ci def _reconstruct(cls, obj): 2487db96d56Sopenharmony_ci with memoryview(obj) as m: 2497db96d56Sopenharmony_ci obj = m.obj 2507db96d56Sopenharmony_ci if type(obj) is cls: 2517db96d56Sopenharmony_ci # Zero-copy 2527db96d56Sopenharmony_ci return obj 2537db96d56Sopenharmony_ci else: 2547db96d56Sopenharmony_ci return cls(obj) 2557db96d56Sopenharmony_ci 2567db96d56Sopenharmony_ci 2577db96d56Sopenharmony_ciif _testbuffer is not None: 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci class PicklableNDArray: 2607db96d56Sopenharmony_ci # A not-really-zero-copy picklable ndarray, as the ndarray() 2617db96d56Sopenharmony_ci # constructor doesn't allow for it 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_ci zero_copy_reconstruct = False 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_ci def __init__(self, *args, **kwargs): 2667db96d56Sopenharmony_ci self.array = _testbuffer.ndarray(*args, **kwargs) 2677db96d56Sopenharmony_ci 2687db96d56Sopenharmony_ci def __getitem__(self, idx): 2697db96d56Sopenharmony_ci cls = type(self) 2707db96d56Sopenharmony_ci new = cls.__new__(cls) 2717db96d56Sopenharmony_ci new.array = self.array[idx] 2727db96d56Sopenharmony_ci return new 2737db96d56Sopenharmony_ci 2747db96d56Sopenharmony_ci @property 2757db96d56Sopenharmony_ci def readonly(self): 2767db96d56Sopenharmony_ci return self.array.readonly 2777db96d56Sopenharmony_ci 2787db96d56Sopenharmony_ci @property 2797db96d56Sopenharmony_ci def c_contiguous(self): 2807db96d56Sopenharmony_ci return self.array.c_contiguous 2817db96d56Sopenharmony_ci 2827db96d56Sopenharmony_ci @property 2837db96d56Sopenharmony_ci def f_contiguous(self): 2847db96d56Sopenharmony_ci return self.array.f_contiguous 2857db96d56Sopenharmony_ci 2867db96d56Sopenharmony_ci def __eq__(self, other): 2877db96d56Sopenharmony_ci if not isinstance(other, PicklableNDArray): 2887db96d56Sopenharmony_ci return NotImplemented 2897db96d56Sopenharmony_ci return (other.array.format == self.array.format and 2907db96d56Sopenharmony_ci other.array.shape == self.array.shape and 2917db96d56Sopenharmony_ci other.array.strides == self.array.strides and 2927db96d56Sopenharmony_ci other.array.readonly == self.array.readonly and 2937db96d56Sopenharmony_ci other.array.tobytes() == self.array.tobytes()) 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_ci def __ne__(self, other): 2967db96d56Sopenharmony_ci if not isinstance(other, PicklableNDArray): 2977db96d56Sopenharmony_ci return NotImplemented 2987db96d56Sopenharmony_ci return not (self == other) 2997db96d56Sopenharmony_ci 3007db96d56Sopenharmony_ci def __repr__(self): 3017db96d56Sopenharmony_ci return (f"{type(self)}(shape={self.array.shape}," 3027db96d56Sopenharmony_ci f"strides={self.array.strides}, " 3037db96d56Sopenharmony_ci f"bytes={self.array.tobytes()})") 3047db96d56Sopenharmony_ci 3057db96d56Sopenharmony_ci def __reduce_ex__(self, protocol): 3067db96d56Sopenharmony_ci if not self.array.contiguous: 3077db96d56Sopenharmony_ci raise NotImplementedError("Reconstructing a non-contiguous " 3087db96d56Sopenharmony_ci "ndarray does not seem possible") 3097db96d56Sopenharmony_ci ndarray_kwargs = {"shape": self.array.shape, 3107db96d56Sopenharmony_ci "strides": self.array.strides, 3117db96d56Sopenharmony_ci "format": self.array.format, 3127db96d56Sopenharmony_ci "flags": (0 if self.readonly 3137db96d56Sopenharmony_ci else _testbuffer.ND_WRITABLE)} 3147db96d56Sopenharmony_ci pb = pickle.PickleBuffer(self.array) 3157db96d56Sopenharmony_ci if protocol >= 5: 3167db96d56Sopenharmony_ci return (type(self)._reconstruct, 3177db96d56Sopenharmony_ci (pb, ndarray_kwargs)) 3187db96d56Sopenharmony_ci else: 3197db96d56Sopenharmony_ci # Need to serialize the bytes in physical order 3207db96d56Sopenharmony_ci with pb.raw() as m: 3217db96d56Sopenharmony_ci return (type(self)._reconstruct, 3227db96d56Sopenharmony_ci (m.tobytes(), ndarray_kwargs)) 3237db96d56Sopenharmony_ci 3247db96d56Sopenharmony_ci @classmethod 3257db96d56Sopenharmony_ci def _reconstruct(cls, obj, kwargs): 3267db96d56Sopenharmony_ci with memoryview(obj) as m: 3277db96d56Sopenharmony_ci # For some reason, ndarray() wants a list of integers... 3287db96d56Sopenharmony_ci # XXX This only works if format == 'B' 3297db96d56Sopenharmony_ci items = list(m.tobytes()) 3307db96d56Sopenharmony_ci return cls(items, **kwargs) 3317db96d56Sopenharmony_ci 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci# DATA0 .. DATA4 are the pickles we expect under the various protocols, for 3347db96d56Sopenharmony_ci# the object returned by create_data(). 3357db96d56Sopenharmony_ci 3367db96d56Sopenharmony_ciDATA0 = ( 3377db96d56Sopenharmony_ci b'(lp0\nL0L\naL1L\naF2.0\n' 3387db96d56Sopenharmony_ci b'ac__builtin__\ncomple' 3397db96d56Sopenharmony_ci b'x\np1\n(F3.0\nF0.0\ntp2\n' 3407db96d56Sopenharmony_ci b'Rp3\naL1L\naL-1L\naL255' 3417db96d56Sopenharmony_ci b'L\naL-255L\naL-256L\naL' 3427db96d56Sopenharmony_ci b'65535L\naL-65535L\naL-' 3437db96d56Sopenharmony_ci b'65536L\naL2147483647L' 3447db96d56Sopenharmony_ci b'\naL-2147483647L\naL-2' 3457db96d56Sopenharmony_ci b'147483648L\na(Vabc\np4' 3467db96d56Sopenharmony_ci b'\ng4\nccopy_reg\n_recon' 3477db96d56Sopenharmony_ci b'structor\np5\n(c__main' 3487db96d56Sopenharmony_ci b'__\nC\np6\nc__builtin__' 3497db96d56Sopenharmony_ci b'\nobject\np7\nNtp8\nRp9\n' 3507db96d56Sopenharmony_ci b'(dp10\nVfoo\np11\nL1L\ns' 3517db96d56Sopenharmony_ci b'Vbar\np12\nL2L\nsbg9\ntp' 3527db96d56Sopenharmony_ci b'13\nag13\naL5L\na.' 3537db96d56Sopenharmony_ci) 3547db96d56Sopenharmony_ci 3557db96d56Sopenharmony_ci# Disassembly of DATA0 3567db96d56Sopenharmony_ciDATA0_DIS = """\ 3577db96d56Sopenharmony_ci 0: ( MARK 3587db96d56Sopenharmony_ci 1: l LIST (MARK at 0) 3597db96d56Sopenharmony_ci 2: p PUT 0 3607db96d56Sopenharmony_ci 5: L LONG 0 3617db96d56Sopenharmony_ci 9: a APPEND 3627db96d56Sopenharmony_ci 10: L LONG 1 3637db96d56Sopenharmony_ci 14: a APPEND 3647db96d56Sopenharmony_ci 15: F FLOAT 2.0 3657db96d56Sopenharmony_ci 20: a APPEND 3667db96d56Sopenharmony_ci 21: c GLOBAL '__builtin__ complex' 3677db96d56Sopenharmony_ci 42: p PUT 1 3687db96d56Sopenharmony_ci 45: ( MARK 3697db96d56Sopenharmony_ci 46: F FLOAT 3.0 3707db96d56Sopenharmony_ci 51: F FLOAT 0.0 3717db96d56Sopenharmony_ci 56: t TUPLE (MARK at 45) 3727db96d56Sopenharmony_ci 57: p PUT 2 3737db96d56Sopenharmony_ci 60: R REDUCE 3747db96d56Sopenharmony_ci 61: p PUT 3 3757db96d56Sopenharmony_ci 64: a APPEND 3767db96d56Sopenharmony_ci 65: L LONG 1 3777db96d56Sopenharmony_ci 69: a APPEND 3787db96d56Sopenharmony_ci 70: L LONG -1 3797db96d56Sopenharmony_ci 75: a APPEND 3807db96d56Sopenharmony_ci 76: L LONG 255 3817db96d56Sopenharmony_ci 82: a APPEND 3827db96d56Sopenharmony_ci 83: L LONG -255 3837db96d56Sopenharmony_ci 90: a APPEND 3847db96d56Sopenharmony_ci 91: L LONG -256 3857db96d56Sopenharmony_ci 98: a APPEND 3867db96d56Sopenharmony_ci 99: L LONG 65535 3877db96d56Sopenharmony_ci 107: a APPEND 3887db96d56Sopenharmony_ci 108: L LONG -65535 3897db96d56Sopenharmony_ci 117: a APPEND 3907db96d56Sopenharmony_ci 118: L LONG -65536 3917db96d56Sopenharmony_ci 127: a APPEND 3927db96d56Sopenharmony_ci 128: L LONG 2147483647 3937db96d56Sopenharmony_ci 141: a APPEND 3947db96d56Sopenharmony_ci 142: L LONG -2147483647 3957db96d56Sopenharmony_ci 156: a APPEND 3967db96d56Sopenharmony_ci 157: L LONG -2147483648 3977db96d56Sopenharmony_ci 171: a APPEND 3987db96d56Sopenharmony_ci 172: ( MARK 3997db96d56Sopenharmony_ci 173: V UNICODE 'abc' 4007db96d56Sopenharmony_ci 178: p PUT 4 4017db96d56Sopenharmony_ci 181: g GET 4 4027db96d56Sopenharmony_ci 184: c GLOBAL 'copy_reg _reconstructor' 4037db96d56Sopenharmony_ci 209: p PUT 5 4047db96d56Sopenharmony_ci 212: ( MARK 4057db96d56Sopenharmony_ci 213: c GLOBAL '__main__ C' 4067db96d56Sopenharmony_ci 225: p PUT 6 4077db96d56Sopenharmony_ci 228: c GLOBAL '__builtin__ object' 4087db96d56Sopenharmony_ci 248: p PUT 7 4097db96d56Sopenharmony_ci 251: N NONE 4107db96d56Sopenharmony_ci 252: t TUPLE (MARK at 212) 4117db96d56Sopenharmony_ci 253: p PUT 8 4127db96d56Sopenharmony_ci 256: R REDUCE 4137db96d56Sopenharmony_ci 257: p PUT 9 4147db96d56Sopenharmony_ci 260: ( MARK 4157db96d56Sopenharmony_ci 261: d DICT (MARK at 260) 4167db96d56Sopenharmony_ci 262: p PUT 10 4177db96d56Sopenharmony_ci 266: V UNICODE 'foo' 4187db96d56Sopenharmony_ci 271: p PUT 11 4197db96d56Sopenharmony_ci 275: L LONG 1 4207db96d56Sopenharmony_ci 279: s SETITEM 4217db96d56Sopenharmony_ci 280: V UNICODE 'bar' 4227db96d56Sopenharmony_ci 285: p PUT 12 4237db96d56Sopenharmony_ci 289: L LONG 2 4247db96d56Sopenharmony_ci 293: s SETITEM 4257db96d56Sopenharmony_ci 294: b BUILD 4267db96d56Sopenharmony_ci 295: g GET 9 4277db96d56Sopenharmony_ci 298: t TUPLE (MARK at 172) 4287db96d56Sopenharmony_ci 299: p PUT 13 4297db96d56Sopenharmony_ci 303: a APPEND 4307db96d56Sopenharmony_ci 304: g GET 13 4317db96d56Sopenharmony_ci 308: a APPEND 4327db96d56Sopenharmony_ci 309: L LONG 5 4337db96d56Sopenharmony_ci 313: a APPEND 4347db96d56Sopenharmony_ci 314: . STOP 4357db96d56Sopenharmony_cihighest protocol among opcodes = 0 4367db96d56Sopenharmony_ci""" 4377db96d56Sopenharmony_ci 4387db96d56Sopenharmony_ciDATA1 = ( 4397db96d56Sopenharmony_ci b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__' 4407db96d56Sopenharmony_ci b'builtin__\ncomplex\nq\x01' 4417db96d56Sopenharmony_ci b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t' 4427db96d56Sopenharmony_ci b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ' 4437db96d56Sopenharmony_ci b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff' 4447db96d56Sopenharmony_ci b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab' 4457db96d56Sopenharmony_ci b'cq\x04h\x04ccopy_reg\n_reco' 4467db96d56Sopenharmony_ci b'nstructor\nq\x05(c__main' 4477db96d56Sopenharmony_ci b'__\nC\nq\x06c__builtin__\n' 4487db96d56Sopenharmony_ci b'object\nq\x07Ntq\x08Rq\t}q\n(' 4497db96d56Sopenharmony_ci b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar' 4507db96d56Sopenharmony_ci b'q\x0cK\x02ubh\ttq\rh\rK\x05e.' 4517db96d56Sopenharmony_ci) 4527db96d56Sopenharmony_ci 4537db96d56Sopenharmony_ci# Disassembly of DATA1 4547db96d56Sopenharmony_ciDATA1_DIS = """\ 4557db96d56Sopenharmony_ci 0: ] EMPTY_LIST 4567db96d56Sopenharmony_ci 1: q BINPUT 0 4577db96d56Sopenharmony_ci 3: ( MARK 4587db96d56Sopenharmony_ci 4: K BININT1 0 4597db96d56Sopenharmony_ci 6: K BININT1 1 4607db96d56Sopenharmony_ci 8: G BINFLOAT 2.0 4617db96d56Sopenharmony_ci 17: c GLOBAL '__builtin__ complex' 4627db96d56Sopenharmony_ci 38: q BINPUT 1 4637db96d56Sopenharmony_ci 40: ( MARK 4647db96d56Sopenharmony_ci 41: G BINFLOAT 3.0 4657db96d56Sopenharmony_ci 50: G BINFLOAT 0.0 4667db96d56Sopenharmony_ci 59: t TUPLE (MARK at 40) 4677db96d56Sopenharmony_ci 60: q BINPUT 2 4687db96d56Sopenharmony_ci 62: R REDUCE 4697db96d56Sopenharmony_ci 63: q BINPUT 3 4707db96d56Sopenharmony_ci 65: K BININT1 1 4717db96d56Sopenharmony_ci 67: J BININT -1 4727db96d56Sopenharmony_ci 72: K BININT1 255 4737db96d56Sopenharmony_ci 74: J BININT -255 4747db96d56Sopenharmony_ci 79: J BININT -256 4757db96d56Sopenharmony_ci 84: M BININT2 65535 4767db96d56Sopenharmony_ci 87: J BININT -65535 4777db96d56Sopenharmony_ci 92: J BININT -65536 4787db96d56Sopenharmony_ci 97: J BININT 2147483647 4797db96d56Sopenharmony_ci 102: J BININT -2147483647 4807db96d56Sopenharmony_ci 107: J BININT -2147483648 4817db96d56Sopenharmony_ci 112: ( MARK 4827db96d56Sopenharmony_ci 113: X BINUNICODE 'abc' 4837db96d56Sopenharmony_ci 121: q BINPUT 4 4847db96d56Sopenharmony_ci 123: h BINGET 4 4857db96d56Sopenharmony_ci 125: c GLOBAL 'copy_reg _reconstructor' 4867db96d56Sopenharmony_ci 150: q BINPUT 5 4877db96d56Sopenharmony_ci 152: ( MARK 4887db96d56Sopenharmony_ci 153: c GLOBAL '__main__ C' 4897db96d56Sopenharmony_ci 165: q BINPUT 6 4907db96d56Sopenharmony_ci 167: c GLOBAL '__builtin__ object' 4917db96d56Sopenharmony_ci 187: q BINPUT 7 4927db96d56Sopenharmony_ci 189: N NONE 4937db96d56Sopenharmony_ci 190: t TUPLE (MARK at 152) 4947db96d56Sopenharmony_ci 191: q BINPUT 8 4957db96d56Sopenharmony_ci 193: R REDUCE 4967db96d56Sopenharmony_ci 194: q BINPUT 9 4977db96d56Sopenharmony_ci 196: } EMPTY_DICT 4987db96d56Sopenharmony_ci 197: q BINPUT 10 4997db96d56Sopenharmony_ci 199: ( MARK 5007db96d56Sopenharmony_ci 200: X BINUNICODE 'foo' 5017db96d56Sopenharmony_ci 208: q BINPUT 11 5027db96d56Sopenharmony_ci 210: K BININT1 1 5037db96d56Sopenharmony_ci 212: X BINUNICODE 'bar' 5047db96d56Sopenharmony_ci 220: q BINPUT 12 5057db96d56Sopenharmony_ci 222: K BININT1 2 5067db96d56Sopenharmony_ci 224: u SETITEMS (MARK at 199) 5077db96d56Sopenharmony_ci 225: b BUILD 5087db96d56Sopenharmony_ci 226: h BINGET 9 5097db96d56Sopenharmony_ci 228: t TUPLE (MARK at 112) 5107db96d56Sopenharmony_ci 229: q BINPUT 13 5117db96d56Sopenharmony_ci 231: h BINGET 13 5127db96d56Sopenharmony_ci 233: K BININT1 5 5137db96d56Sopenharmony_ci 235: e APPENDS (MARK at 3) 5147db96d56Sopenharmony_ci 236: . STOP 5157db96d56Sopenharmony_cihighest protocol among opcodes = 1 5167db96d56Sopenharmony_ci""" 5177db96d56Sopenharmony_ci 5187db96d56Sopenharmony_ciDATA2 = ( 5197db96d56Sopenharmony_ci b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c' 5207db96d56Sopenharmony_ci b'__builtin__\ncomplex\n' 5217db96d56Sopenharmony_ci b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00' 5227db96d56Sopenharmony_ci b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff' 5237db96d56Sopenharmony_ci b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff' 5247db96d56Sopenharmony_ci b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a' 5257db96d56Sopenharmony_ci b'bcq\x04h\x04c__main__\nC\nq\x05' 5267db96d56Sopenharmony_ci b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01' 5277db96d56Sopenharmony_ci b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh' 5287db96d56Sopenharmony_ci b'\nK\x05e.' 5297db96d56Sopenharmony_ci) 5307db96d56Sopenharmony_ci 5317db96d56Sopenharmony_ci# Disassembly of DATA2 5327db96d56Sopenharmony_ciDATA2_DIS = """\ 5337db96d56Sopenharmony_ci 0: \x80 PROTO 2 5347db96d56Sopenharmony_ci 2: ] EMPTY_LIST 5357db96d56Sopenharmony_ci 3: q BINPUT 0 5367db96d56Sopenharmony_ci 5: ( MARK 5377db96d56Sopenharmony_ci 6: K BININT1 0 5387db96d56Sopenharmony_ci 8: K BININT1 1 5397db96d56Sopenharmony_ci 10: G BINFLOAT 2.0 5407db96d56Sopenharmony_ci 19: c GLOBAL '__builtin__ complex' 5417db96d56Sopenharmony_ci 40: q BINPUT 1 5427db96d56Sopenharmony_ci 42: G BINFLOAT 3.0 5437db96d56Sopenharmony_ci 51: G BINFLOAT 0.0 5447db96d56Sopenharmony_ci 60: \x86 TUPLE2 5457db96d56Sopenharmony_ci 61: q BINPUT 2 5467db96d56Sopenharmony_ci 63: R REDUCE 5477db96d56Sopenharmony_ci 64: q BINPUT 3 5487db96d56Sopenharmony_ci 66: K BININT1 1 5497db96d56Sopenharmony_ci 68: J BININT -1 5507db96d56Sopenharmony_ci 73: K BININT1 255 5517db96d56Sopenharmony_ci 75: J BININT -255 5527db96d56Sopenharmony_ci 80: J BININT -256 5537db96d56Sopenharmony_ci 85: M BININT2 65535 5547db96d56Sopenharmony_ci 88: J BININT -65535 5557db96d56Sopenharmony_ci 93: J BININT -65536 5567db96d56Sopenharmony_ci 98: J BININT 2147483647 5577db96d56Sopenharmony_ci 103: J BININT -2147483647 5587db96d56Sopenharmony_ci 108: J BININT -2147483648 5597db96d56Sopenharmony_ci 113: ( MARK 5607db96d56Sopenharmony_ci 114: X BINUNICODE 'abc' 5617db96d56Sopenharmony_ci 122: q BINPUT 4 5627db96d56Sopenharmony_ci 124: h BINGET 4 5637db96d56Sopenharmony_ci 126: c GLOBAL '__main__ C' 5647db96d56Sopenharmony_ci 138: q BINPUT 5 5657db96d56Sopenharmony_ci 140: ) EMPTY_TUPLE 5667db96d56Sopenharmony_ci 141: \x81 NEWOBJ 5677db96d56Sopenharmony_ci 142: q BINPUT 6 5687db96d56Sopenharmony_ci 144: } EMPTY_DICT 5697db96d56Sopenharmony_ci 145: q BINPUT 7 5707db96d56Sopenharmony_ci 147: ( MARK 5717db96d56Sopenharmony_ci 148: X BINUNICODE 'foo' 5727db96d56Sopenharmony_ci 156: q BINPUT 8 5737db96d56Sopenharmony_ci 158: K BININT1 1 5747db96d56Sopenharmony_ci 160: X BINUNICODE 'bar' 5757db96d56Sopenharmony_ci 168: q BINPUT 9 5767db96d56Sopenharmony_ci 170: K BININT1 2 5777db96d56Sopenharmony_ci 172: u SETITEMS (MARK at 147) 5787db96d56Sopenharmony_ci 173: b BUILD 5797db96d56Sopenharmony_ci 174: h BINGET 6 5807db96d56Sopenharmony_ci 176: t TUPLE (MARK at 113) 5817db96d56Sopenharmony_ci 177: q BINPUT 10 5827db96d56Sopenharmony_ci 179: h BINGET 10 5837db96d56Sopenharmony_ci 181: K BININT1 5 5847db96d56Sopenharmony_ci 183: e APPENDS (MARK at 5) 5857db96d56Sopenharmony_ci 184: . STOP 5867db96d56Sopenharmony_cihighest protocol among opcodes = 2 5877db96d56Sopenharmony_ci""" 5887db96d56Sopenharmony_ci 5897db96d56Sopenharmony_ciDATA3 = ( 5907db96d56Sopenharmony_ci b'\x80\x03]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c' 5917db96d56Sopenharmony_ci b'builtins\ncomplex\nq\x01G' 5927db96d56Sopenharmony_ci b'@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x86q\x02' 5937db96d56Sopenharmony_ci b'Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff' 5947db96d56Sopenharmony_ci b'\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7f' 5957db96d56Sopenharmony_ci b'J\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00abcq' 5967db96d56Sopenharmony_ci b'\x04h\x04c__main__\nC\nq\x05)\x81q' 5977db96d56Sopenharmony_ci b'\x06}q\x07(X\x03\x00\x00\x00barq\x08K\x02X\x03\x00' 5987db96d56Sopenharmony_ci b'\x00\x00fooq\tK\x01ubh\x06tq\nh\nK\x05' 5997db96d56Sopenharmony_ci b'e.' 6007db96d56Sopenharmony_ci) 6017db96d56Sopenharmony_ci 6027db96d56Sopenharmony_ci# Disassembly of DATA3 6037db96d56Sopenharmony_ciDATA3_DIS = """\ 6047db96d56Sopenharmony_ci 0: \x80 PROTO 3 6057db96d56Sopenharmony_ci 2: ] EMPTY_LIST 6067db96d56Sopenharmony_ci 3: q BINPUT 0 6077db96d56Sopenharmony_ci 5: ( MARK 6087db96d56Sopenharmony_ci 6: K BININT1 0 6097db96d56Sopenharmony_ci 8: K BININT1 1 6107db96d56Sopenharmony_ci 10: G BINFLOAT 2.0 6117db96d56Sopenharmony_ci 19: c GLOBAL 'builtins complex' 6127db96d56Sopenharmony_ci 37: q BINPUT 1 6137db96d56Sopenharmony_ci 39: G BINFLOAT 3.0 6147db96d56Sopenharmony_ci 48: G BINFLOAT 0.0 6157db96d56Sopenharmony_ci 57: \x86 TUPLE2 6167db96d56Sopenharmony_ci 58: q BINPUT 2 6177db96d56Sopenharmony_ci 60: R REDUCE 6187db96d56Sopenharmony_ci 61: q BINPUT 3 6197db96d56Sopenharmony_ci 63: K BININT1 1 6207db96d56Sopenharmony_ci 65: J BININT -1 6217db96d56Sopenharmony_ci 70: K BININT1 255 6227db96d56Sopenharmony_ci 72: J BININT -255 6237db96d56Sopenharmony_ci 77: J BININT -256 6247db96d56Sopenharmony_ci 82: M BININT2 65535 6257db96d56Sopenharmony_ci 85: J BININT -65535 6267db96d56Sopenharmony_ci 90: J BININT -65536 6277db96d56Sopenharmony_ci 95: J BININT 2147483647 6287db96d56Sopenharmony_ci 100: J BININT -2147483647 6297db96d56Sopenharmony_ci 105: J BININT -2147483648 6307db96d56Sopenharmony_ci 110: ( MARK 6317db96d56Sopenharmony_ci 111: X BINUNICODE 'abc' 6327db96d56Sopenharmony_ci 119: q BINPUT 4 6337db96d56Sopenharmony_ci 121: h BINGET 4 6347db96d56Sopenharmony_ci 123: c GLOBAL '__main__ C' 6357db96d56Sopenharmony_ci 135: q BINPUT 5 6367db96d56Sopenharmony_ci 137: ) EMPTY_TUPLE 6377db96d56Sopenharmony_ci 138: \x81 NEWOBJ 6387db96d56Sopenharmony_ci 139: q BINPUT 6 6397db96d56Sopenharmony_ci 141: } EMPTY_DICT 6407db96d56Sopenharmony_ci 142: q BINPUT 7 6417db96d56Sopenharmony_ci 144: ( MARK 6427db96d56Sopenharmony_ci 145: X BINUNICODE 'bar' 6437db96d56Sopenharmony_ci 153: q BINPUT 8 6447db96d56Sopenharmony_ci 155: K BININT1 2 6457db96d56Sopenharmony_ci 157: X BINUNICODE 'foo' 6467db96d56Sopenharmony_ci 165: q BINPUT 9 6477db96d56Sopenharmony_ci 167: K BININT1 1 6487db96d56Sopenharmony_ci 169: u SETITEMS (MARK at 144) 6497db96d56Sopenharmony_ci 170: b BUILD 6507db96d56Sopenharmony_ci 171: h BINGET 6 6517db96d56Sopenharmony_ci 173: t TUPLE (MARK at 110) 6527db96d56Sopenharmony_ci 174: q BINPUT 10 6537db96d56Sopenharmony_ci 176: h BINGET 10 6547db96d56Sopenharmony_ci 178: K BININT1 5 6557db96d56Sopenharmony_ci 180: e APPENDS (MARK at 5) 6567db96d56Sopenharmony_ci 181: . STOP 6577db96d56Sopenharmony_cihighest protocol among opcodes = 2 6587db96d56Sopenharmony_ci""" 6597db96d56Sopenharmony_ci 6607db96d56Sopenharmony_ciDATA4 = ( 6617db96d56Sopenharmony_ci b'\x80\x04\x95\xa8\x00\x00\x00\x00\x00\x00\x00]\x94(K\x00K\x01G@' 6627db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x07' 6637db96d56Sopenharmony_ci b'complex\x94\x93\x94G@\x08\x00\x00\x00\x00\x00\x00G' 6647db96d56Sopenharmony_ci b'\x00\x00\x00\x00\x00\x00\x00\x00\x86\x94R\x94K\x01J\xff\xff\xff\xffK' 6657db96d56Sopenharmony_ci b'\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ' 6667db96d56Sopenharmony_ci b'\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(' 6677db96d56Sopenharmony_ci b'\x8c\x03abc\x94h\x06\x8c\x08__main__\x94\x8c' 6687db96d56Sopenharmony_ci b'\x01C\x94\x93\x94)\x81\x94}\x94(\x8c\x03bar\x94K\x02\x8c' 6697db96d56Sopenharmony_ci b'\x03foo\x94K\x01ubh\nt\x94h\x0eK\x05e.' 6707db96d56Sopenharmony_ci) 6717db96d56Sopenharmony_ci 6727db96d56Sopenharmony_ci# Disassembly of DATA4 6737db96d56Sopenharmony_ciDATA4_DIS = """\ 6747db96d56Sopenharmony_ci 0: \x80 PROTO 4 6757db96d56Sopenharmony_ci 2: \x95 FRAME 168 6767db96d56Sopenharmony_ci 11: ] EMPTY_LIST 6777db96d56Sopenharmony_ci 12: \x94 MEMOIZE 6787db96d56Sopenharmony_ci 13: ( MARK 6797db96d56Sopenharmony_ci 14: K BININT1 0 6807db96d56Sopenharmony_ci 16: K BININT1 1 6817db96d56Sopenharmony_ci 18: G BINFLOAT 2.0 6827db96d56Sopenharmony_ci 27: \x8c SHORT_BINUNICODE 'builtins' 6837db96d56Sopenharmony_ci 37: \x94 MEMOIZE 6847db96d56Sopenharmony_ci 38: \x8c SHORT_BINUNICODE 'complex' 6857db96d56Sopenharmony_ci 47: \x94 MEMOIZE 6867db96d56Sopenharmony_ci 48: \x93 STACK_GLOBAL 6877db96d56Sopenharmony_ci 49: \x94 MEMOIZE 6887db96d56Sopenharmony_ci 50: G BINFLOAT 3.0 6897db96d56Sopenharmony_ci 59: G BINFLOAT 0.0 6907db96d56Sopenharmony_ci 68: \x86 TUPLE2 6917db96d56Sopenharmony_ci 69: \x94 MEMOIZE 6927db96d56Sopenharmony_ci 70: R REDUCE 6937db96d56Sopenharmony_ci 71: \x94 MEMOIZE 6947db96d56Sopenharmony_ci 72: K BININT1 1 6957db96d56Sopenharmony_ci 74: J BININT -1 6967db96d56Sopenharmony_ci 79: K BININT1 255 6977db96d56Sopenharmony_ci 81: J BININT -255 6987db96d56Sopenharmony_ci 86: J BININT -256 6997db96d56Sopenharmony_ci 91: M BININT2 65535 7007db96d56Sopenharmony_ci 94: J BININT -65535 7017db96d56Sopenharmony_ci 99: J BININT -65536 7027db96d56Sopenharmony_ci 104: J BININT 2147483647 7037db96d56Sopenharmony_ci 109: J BININT -2147483647 7047db96d56Sopenharmony_ci 114: J BININT -2147483648 7057db96d56Sopenharmony_ci 119: ( MARK 7067db96d56Sopenharmony_ci 120: \x8c SHORT_BINUNICODE 'abc' 7077db96d56Sopenharmony_ci 125: \x94 MEMOIZE 7087db96d56Sopenharmony_ci 126: h BINGET 6 7097db96d56Sopenharmony_ci 128: \x8c SHORT_BINUNICODE '__main__' 7107db96d56Sopenharmony_ci 138: \x94 MEMOIZE 7117db96d56Sopenharmony_ci 139: \x8c SHORT_BINUNICODE 'C' 7127db96d56Sopenharmony_ci 142: \x94 MEMOIZE 7137db96d56Sopenharmony_ci 143: \x93 STACK_GLOBAL 7147db96d56Sopenharmony_ci 144: \x94 MEMOIZE 7157db96d56Sopenharmony_ci 145: ) EMPTY_TUPLE 7167db96d56Sopenharmony_ci 146: \x81 NEWOBJ 7177db96d56Sopenharmony_ci 147: \x94 MEMOIZE 7187db96d56Sopenharmony_ci 148: } EMPTY_DICT 7197db96d56Sopenharmony_ci 149: \x94 MEMOIZE 7207db96d56Sopenharmony_ci 150: ( MARK 7217db96d56Sopenharmony_ci 151: \x8c SHORT_BINUNICODE 'bar' 7227db96d56Sopenharmony_ci 156: \x94 MEMOIZE 7237db96d56Sopenharmony_ci 157: K BININT1 2 7247db96d56Sopenharmony_ci 159: \x8c SHORT_BINUNICODE 'foo' 7257db96d56Sopenharmony_ci 164: \x94 MEMOIZE 7267db96d56Sopenharmony_ci 165: K BININT1 1 7277db96d56Sopenharmony_ci 167: u SETITEMS (MARK at 150) 7287db96d56Sopenharmony_ci 168: b BUILD 7297db96d56Sopenharmony_ci 169: h BINGET 10 7307db96d56Sopenharmony_ci 171: t TUPLE (MARK at 119) 7317db96d56Sopenharmony_ci 172: \x94 MEMOIZE 7327db96d56Sopenharmony_ci 173: h BINGET 14 7337db96d56Sopenharmony_ci 175: K BININT1 5 7347db96d56Sopenharmony_ci 177: e APPENDS (MARK at 13) 7357db96d56Sopenharmony_ci 178: . STOP 7367db96d56Sopenharmony_cihighest protocol among opcodes = 4 7377db96d56Sopenharmony_ci""" 7387db96d56Sopenharmony_ci 7397db96d56Sopenharmony_ci# set([1,2]) pickled from 2.x with protocol 2 7407db96d56Sopenharmony_ciDATA_SET = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.' 7417db96d56Sopenharmony_ci 7427db96d56Sopenharmony_ci# xrange(5) pickled from 2.x with protocol 2 7437db96d56Sopenharmony_ciDATA_XRANGE = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.' 7447db96d56Sopenharmony_ci 7457db96d56Sopenharmony_ci# a SimpleCookie() object pickled from 2.x with protocol 2 7467db96d56Sopenharmony_ciDATA_COOKIE = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key' 7477db96d56Sopenharmony_ci b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U' 7487db96d56Sopenharmony_ci b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07' 7497db96d56Sopenharmony_ci b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U' 7507db96d56Sopenharmony_ci b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b' 7517db96d56Sopenharmony_ci b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.') 7527db96d56Sopenharmony_ci 7537db96d56Sopenharmony_ci# set([3]) pickled from 2.x with protocol 2 7547db96d56Sopenharmony_ciDATA_SET2 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.' 7557db96d56Sopenharmony_ci 7567db96d56Sopenharmony_cipython2_exceptions_without_args = ( 7577db96d56Sopenharmony_ci ArithmeticError, 7587db96d56Sopenharmony_ci AssertionError, 7597db96d56Sopenharmony_ci AttributeError, 7607db96d56Sopenharmony_ci BaseException, 7617db96d56Sopenharmony_ci BufferError, 7627db96d56Sopenharmony_ci BytesWarning, 7637db96d56Sopenharmony_ci DeprecationWarning, 7647db96d56Sopenharmony_ci EOFError, 7657db96d56Sopenharmony_ci EnvironmentError, 7667db96d56Sopenharmony_ci Exception, 7677db96d56Sopenharmony_ci FloatingPointError, 7687db96d56Sopenharmony_ci FutureWarning, 7697db96d56Sopenharmony_ci GeneratorExit, 7707db96d56Sopenharmony_ci IOError, 7717db96d56Sopenharmony_ci ImportError, 7727db96d56Sopenharmony_ci ImportWarning, 7737db96d56Sopenharmony_ci IndentationError, 7747db96d56Sopenharmony_ci IndexError, 7757db96d56Sopenharmony_ci KeyError, 7767db96d56Sopenharmony_ci KeyboardInterrupt, 7777db96d56Sopenharmony_ci LookupError, 7787db96d56Sopenharmony_ci MemoryError, 7797db96d56Sopenharmony_ci NameError, 7807db96d56Sopenharmony_ci NotImplementedError, 7817db96d56Sopenharmony_ci OSError, 7827db96d56Sopenharmony_ci OverflowError, 7837db96d56Sopenharmony_ci PendingDeprecationWarning, 7847db96d56Sopenharmony_ci ReferenceError, 7857db96d56Sopenharmony_ci RuntimeError, 7867db96d56Sopenharmony_ci RuntimeWarning, 7877db96d56Sopenharmony_ci # StandardError is gone in Python 3, we map it to Exception 7887db96d56Sopenharmony_ci StopIteration, 7897db96d56Sopenharmony_ci SyntaxError, 7907db96d56Sopenharmony_ci SyntaxWarning, 7917db96d56Sopenharmony_ci SystemError, 7927db96d56Sopenharmony_ci SystemExit, 7937db96d56Sopenharmony_ci TabError, 7947db96d56Sopenharmony_ci TypeError, 7957db96d56Sopenharmony_ci UnboundLocalError, 7967db96d56Sopenharmony_ci UnicodeError, 7977db96d56Sopenharmony_ci UnicodeWarning, 7987db96d56Sopenharmony_ci UserWarning, 7997db96d56Sopenharmony_ci ValueError, 8007db96d56Sopenharmony_ci Warning, 8017db96d56Sopenharmony_ci ZeroDivisionError, 8027db96d56Sopenharmony_ci) 8037db96d56Sopenharmony_ci 8047db96d56Sopenharmony_ciexception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.' 8057db96d56Sopenharmony_ci 8067db96d56Sopenharmony_ci# UnicodeEncodeError object pickled from 2.x with protocol 2 8077db96d56Sopenharmony_ciDATA_UEERR = (b'\x80\x02cexceptions\nUnicodeEncodeError\n' 8087db96d56Sopenharmony_ci b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01' 8097db96d56Sopenharmony_ci b'U\x03badq\x03tq\x04Rq\x05.') 8107db96d56Sopenharmony_ci 8117db96d56Sopenharmony_ci 8127db96d56Sopenharmony_cidef create_data(): 8137db96d56Sopenharmony_ci c = C() 8147db96d56Sopenharmony_ci c.foo = 1 8157db96d56Sopenharmony_ci c.bar = 2 8167db96d56Sopenharmony_ci x = [0, 1, 2.0, 3.0+0j] 8177db96d56Sopenharmony_ci # Append some integer test cases at cPickle.c's internal size 8187db96d56Sopenharmony_ci # cutoffs. 8197db96d56Sopenharmony_ci uint1max = 0xff 8207db96d56Sopenharmony_ci uint2max = 0xffff 8217db96d56Sopenharmony_ci int4max = 0x7fffffff 8227db96d56Sopenharmony_ci x.extend([1, -1, 8237db96d56Sopenharmony_ci uint1max, -uint1max, -uint1max-1, 8247db96d56Sopenharmony_ci uint2max, -uint2max, -uint2max-1, 8257db96d56Sopenharmony_ci int4max, -int4max, -int4max-1]) 8267db96d56Sopenharmony_ci y = ('abc', 'abc', c, c) 8277db96d56Sopenharmony_ci x.append(y) 8287db96d56Sopenharmony_ci x.append(y) 8297db96d56Sopenharmony_ci x.append(5) 8307db96d56Sopenharmony_ci return x 8317db96d56Sopenharmony_ci 8327db96d56Sopenharmony_ci 8337db96d56Sopenharmony_ciclass AbstractUnpickleTests: 8347db96d56Sopenharmony_ci # Subclass must define self.loads. 8357db96d56Sopenharmony_ci 8367db96d56Sopenharmony_ci _testdata = create_data() 8377db96d56Sopenharmony_ci 8387db96d56Sopenharmony_ci def assert_is_copy(self, obj, objcopy, msg=None): 8397db96d56Sopenharmony_ci """Utility method to verify if two objects are copies of each others. 8407db96d56Sopenharmony_ci """ 8417db96d56Sopenharmony_ci if msg is None: 8427db96d56Sopenharmony_ci msg = "{!r} is not a copy of {!r}".format(obj, objcopy) 8437db96d56Sopenharmony_ci self.assertEqual(obj, objcopy, msg=msg) 8447db96d56Sopenharmony_ci self.assertIs(type(obj), type(objcopy), msg=msg) 8457db96d56Sopenharmony_ci if hasattr(obj, '__dict__'): 8467db96d56Sopenharmony_ci self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg) 8477db96d56Sopenharmony_ci self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg) 8487db96d56Sopenharmony_ci if hasattr(obj, '__slots__'): 8497db96d56Sopenharmony_ci self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg) 8507db96d56Sopenharmony_ci for slot in obj.__slots__: 8517db96d56Sopenharmony_ci self.assertEqual( 8527db96d56Sopenharmony_ci hasattr(obj, slot), hasattr(objcopy, slot), msg=msg) 8537db96d56Sopenharmony_ci self.assertEqual(getattr(obj, slot, None), 8547db96d56Sopenharmony_ci getattr(objcopy, slot, None), msg=msg) 8557db96d56Sopenharmony_ci 8567db96d56Sopenharmony_ci def check_unpickling_error(self, errors, data): 8577db96d56Sopenharmony_ci with self.subTest(data=data), \ 8587db96d56Sopenharmony_ci self.assertRaises(errors): 8597db96d56Sopenharmony_ci try: 8607db96d56Sopenharmony_ci self.loads(data) 8617db96d56Sopenharmony_ci except BaseException as exc: 8627db96d56Sopenharmony_ci if support.verbose > 1: 8637db96d56Sopenharmony_ci print('%-32r - %s: %s' % 8647db96d56Sopenharmony_ci (data, exc.__class__.__name__, exc)) 8657db96d56Sopenharmony_ci raise 8667db96d56Sopenharmony_ci 8677db96d56Sopenharmony_ci def test_load_from_data0(self): 8687db96d56Sopenharmony_ci self.assert_is_copy(self._testdata, self.loads(DATA0)) 8697db96d56Sopenharmony_ci 8707db96d56Sopenharmony_ci def test_load_from_data1(self): 8717db96d56Sopenharmony_ci self.assert_is_copy(self._testdata, self.loads(DATA1)) 8727db96d56Sopenharmony_ci 8737db96d56Sopenharmony_ci def test_load_from_data2(self): 8747db96d56Sopenharmony_ci self.assert_is_copy(self._testdata, self.loads(DATA2)) 8757db96d56Sopenharmony_ci 8767db96d56Sopenharmony_ci def test_load_from_data3(self): 8777db96d56Sopenharmony_ci self.assert_is_copy(self._testdata, self.loads(DATA3)) 8787db96d56Sopenharmony_ci 8797db96d56Sopenharmony_ci def test_load_from_data4(self): 8807db96d56Sopenharmony_ci self.assert_is_copy(self._testdata, self.loads(DATA4)) 8817db96d56Sopenharmony_ci 8827db96d56Sopenharmony_ci def test_load_classic_instance(self): 8837db96d56Sopenharmony_ci # See issue5180. Test loading 2.x pickles that 8847db96d56Sopenharmony_ci # contain an instance of old style class. 8857db96d56Sopenharmony_ci for X, args in [(C, ()), (D, ('x',)), (E, ())]: 8867db96d56Sopenharmony_ci xname = X.__name__.encode('ascii') 8877db96d56Sopenharmony_ci # Protocol 0 (text mode pickle): 8887db96d56Sopenharmony_ci """ 8897db96d56Sopenharmony_ci 0: ( MARK 8907db96d56Sopenharmony_ci 1: i INST '__main__ X' (MARK at 0) 8917db96d56Sopenharmony_ci 13: p PUT 0 8927db96d56Sopenharmony_ci 16: ( MARK 8937db96d56Sopenharmony_ci 17: d DICT (MARK at 16) 8947db96d56Sopenharmony_ci 18: p PUT 1 8957db96d56Sopenharmony_ci 21: b BUILD 8967db96d56Sopenharmony_ci 22: . STOP 8977db96d56Sopenharmony_ci """ 8987db96d56Sopenharmony_ci pickle0 = (b"(i__main__\n" 8997db96d56Sopenharmony_ci b"X\n" 9007db96d56Sopenharmony_ci b"p0\n" 9017db96d56Sopenharmony_ci b"(dp1\nb.").replace(b'X', xname) 9027db96d56Sopenharmony_ci self.assert_is_copy(X(*args), self.loads(pickle0)) 9037db96d56Sopenharmony_ci 9047db96d56Sopenharmony_ci # Protocol 1 (binary mode pickle) 9057db96d56Sopenharmony_ci """ 9067db96d56Sopenharmony_ci 0: ( MARK 9077db96d56Sopenharmony_ci 1: c GLOBAL '__main__ X' 9087db96d56Sopenharmony_ci 13: q BINPUT 0 9097db96d56Sopenharmony_ci 15: o OBJ (MARK at 0) 9107db96d56Sopenharmony_ci 16: q BINPUT 1 9117db96d56Sopenharmony_ci 18: } EMPTY_DICT 9127db96d56Sopenharmony_ci 19: q BINPUT 2 9137db96d56Sopenharmony_ci 21: b BUILD 9147db96d56Sopenharmony_ci 22: . STOP 9157db96d56Sopenharmony_ci """ 9167db96d56Sopenharmony_ci pickle1 = (b'(c__main__\n' 9177db96d56Sopenharmony_ci b'X\n' 9187db96d56Sopenharmony_ci b'q\x00oq\x01}q\x02b.').replace(b'X', xname) 9197db96d56Sopenharmony_ci self.assert_is_copy(X(*args), self.loads(pickle1)) 9207db96d56Sopenharmony_ci 9217db96d56Sopenharmony_ci # Protocol 2 (pickle2 = b'\x80\x02' + pickle1) 9227db96d56Sopenharmony_ci """ 9237db96d56Sopenharmony_ci 0: \x80 PROTO 2 9247db96d56Sopenharmony_ci 2: ( MARK 9257db96d56Sopenharmony_ci 3: c GLOBAL '__main__ X' 9267db96d56Sopenharmony_ci 15: q BINPUT 0 9277db96d56Sopenharmony_ci 17: o OBJ (MARK at 2) 9287db96d56Sopenharmony_ci 18: q BINPUT 1 9297db96d56Sopenharmony_ci 20: } EMPTY_DICT 9307db96d56Sopenharmony_ci 21: q BINPUT 2 9317db96d56Sopenharmony_ci 23: b BUILD 9327db96d56Sopenharmony_ci 24: . STOP 9337db96d56Sopenharmony_ci """ 9347db96d56Sopenharmony_ci pickle2 = (b'\x80\x02(c__main__\n' 9357db96d56Sopenharmony_ci b'X\n' 9367db96d56Sopenharmony_ci b'q\x00oq\x01}q\x02b.').replace(b'X', xname) 9377db96d56Sopenharmony_ci self.assert_is_copy(X(*args), self.loads(pickle2)) 9387db96d56Sopenharmony_ci 9397db96d56Sopenharmony_ci def test_maxint64(self): 9407db96d56Sopenharmony_ci maxint64 = (1 << 63) - 1 9417db96d56Sopenharmony_ci data = b'I' + str(maxint64).encode("ascii") + b'\n.' 9427db96d56Sopenharmony_ci got = self.loads(data) 9437db96d56Sopenharmony_ci self.assert_is_copy(maxint64, got) 9447db96d56Sopenharmony_ci 9457db96d56Sopenharmony_ci # Try too with a bogus literal. 9467db96d56Sopenharmony_ci data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.' 9477db96d56Sopenharmony_ci self.check_unpickling_error(ValueError, data) 9487db96d56Sopenharmony_ci 9497db96d56Sopenharmony_ci def test_unpickle_from_2x(self): 9507db96d56Sopenharmony_ci # Unpickle non-trivial data from Python 2.x. 9517db96d56Sopenharmony_ci loaded = self.loads(DATA_SET) 9527db96d56Sopenharmony_ci self.assertEqual(loaded, set([1, 2])) 9537db96d56Sopenharmony_ci loaded = self.loads(DATA_XRANGE) 9547db96d56Sopenharmony_ci self.assertEqual(type(loaded), type(range(0))) 9557db96d56Sopenharmony_ci self.assertEqual(list(loaded), list(range(5))) 9567db96d56Sopenharmony_ci loaded = self.loads(DATA_COOKIE) 9577db96d56Sopenharmony_ci self.assertEqual(type(loaded), SimpleCookie) 9587db96d56Sopenharmony_ci self.assertEqual(list(loaded.keys()), ["key"]) 9597db96d56Sopenharmony_ci self.assertEqual(loaded["key"].value, "value") 9607db96d56Sopenharmony_ci 9617db96d56Sopenharmony_ci # Exception objects without arguments pickled from 2.x with protocol 2 9627db96d56Sopenharmony_ci for exc in python2_exceptions_without_args: 9637db96d56Sopenharmony_ci data = exception_pickle.replace(b'?', exc.__name__.encode("ascii")) 9647db96d56Sopenharmony_ci loaded = self.loads(data) 9657db96d56Sopenharmony_ci self.assertIs(type(loaded), exc) 9667db96d56Sopenharmony_ci 9677db96d56Sopenharmony_ci # StandardError is mapped to Exception, test that separately 9687db96d56Sopenharmony_ci loaded = self.loads(exception_pickle.replace(b'?', b'StandardError')) 9697db96d56Sopenharmony_ci self.assertIs(type(loaded), Exception) 9707db96d56Sopenharmony_ci 9717db96d56Sopenharmony_ci loaded = self.loads(DATA_UEERR) 9727db96d56Sopenharmony_ci self.assertIs(type(loaded), UnicodeEncodeError) 9737db96d56Sopenharmony_ci self.assertEqual(loaded.object, "foo") 9747db96d56Sopenharmony_ci self.assertEqual(loaded.encoding, "ascii") 9757db96d56Sopenharmony_ci self.assertEqual(loaded.start, 0) 9767db96d56Sopenharmony_ci self.assertEqual(loaded.end, 1) 9777db96d56Sopenharmony_ci self.assertEqual(loaded.reason, "bad") 9787db96d56Sopenharmony_ci 9797db96d56Sopenharmony_ci def test_load_python2_str_as_bytes(self): 9807db96d56Sopenharmony_ci # From Python 2: pickle.dumps('a\x00\xa0', protocol=0) 9817db96d56Sopenharmony_ci self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.", 9827db96d56Sopenharmony_ci encoding="bytes"), b'a\x00\xa0') 9837db96d56Sopenharmony_ci # From Python 2: pickle.dumps('a\x00\xa0', protocol=1) 9847db96d56Sopenharmony_ci self.assertEqual(self.loads(b'U\x03a\x00\xa0.', 9857db96d56Sopenharmony_ci encoding="bytes"), b'a\x00\xa0') 9867db96d56Sopenharmony_ci # From Python 2: pickle.dumps('a\x00\xa0', protocol=2) 9877db96d56Sopenharmony_ci self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.', 9887db96d56Sopenharmony_ci encoding="bytes"), b'a\x00\xa0') 9897db96d56Sopenharmony_ci 9907db96d56Sopenharmony_ci def test_load_python2_unicode_as_str(self): 9917db96d56Sopenharmony_ci # From Python 2: pickle.dumps(u'π', protocol=0) 9927db96d56Sopenharmony_ci self.assertEqual(self.loads(b'V\\u03c0\n.', 9937db96d56Sopenharmony_ci encoding='bytes'), 'π') 9947db96d56Sopenharmony_ci # From Python 2: pickle.dumps(u'π', protocol=1) 9957db96d56Sopenharmony_ci self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.', 9967db96d56Sopenharmony_ci encoding="bytes"), 'π') 9977db96d56Sopenharmony_ci # From Python 2: pickle.dumps(u'π', protocol=2) 9987db96d56Sopenharmony_ci self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.', 9997db96d56Sopenharmony_ci encoding="bytes"), 'π') 10007db96d56Sopenharmony_ci 10017db96d56Sopenharmony_ci def test_load_long_python2_str_as_bytes(self): 10027db96d56Sopenharmony_ci # From Python 2: pickle.dumps('x' * 300, protocol=1) 10037db96d56Sopenharmony_ci self.assertEqual(self.loads(pickle.BINSTRING + 10047db96d56Sopenharmony_ci struct.pack("<I", 300) + 10057db96d56Sopenharmony_ci b'x' * 300 + pickle.STOP, 10067db96d56Sopenharmony_ci encoding='bytes'), b'x' * 300) 10077db96d56Sopenharmony_ci 10087db96d56Sopenharmony_ci def test_constants(self): 10097db96d56Sopenharmony_ci self.assertIsNone(self.loads(b'N.')) 10107db96d56Sopenharmony_ci self.assertIs(self.loads(b'\x88.'), True) 10117db96d56Sopenharmony_ci self.assertIs(self.loads(b'\x89.'), False) 10127db96d56Sopenharmony_ci self.assertIs(self.loads(b'I01\n.'), True) 10137db96d56Sopenharmony_ci self.assertIs(self.loads(b'I00\n.'), False) 10147db96d56Sopenharmony_ci 10157db96d56Sopenharmony_ci def test_empty_bytestring(self): 10167db96d56Sopenharmony_ci # issue 11286 10177db96d56Sopenharmony_ci empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r') 10187db96d56Sopenharmony_ci self.assertEqual(empty, '') 10197db96d56Sopenharmony_ci 10207db96d56Sopenharmony_ci def test_short_binbytes(self): 10217db96d56Sopenharmony_ci dumped = b'\x80\x03C\x04\xe2\x82\xac\x00.' 10227db96d56Sopenharmony_ci self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00') 10237db96d56Sopenharmony_ci 10247db96d56Sopenharmony_ci def test_binbytes(self): 10257db96d56Sopenharmony_ci dumped = b'\x80\x03B\x04\x00\x00\x00\xe2\x82\xac\x00.' 10267db96d56Sopenharmony_ci self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00') 10277db96d56Sopenharmony_ci 10287db96d56Sopenharmony_ci @requires_32b 10297db96d56Sopenharmony_ci def test_negative_32b_binbytes(self): 10307db96d56Sopenharmony_ci # On 32-bit builds, a BINBYTES of 2**31 or more is refused 10317db96d56Sopenharmony_ci dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.' 10327db96d56Sopenharmony_ci self.check_unpickling_error((pickle.UnpicklingError, OverflowError), 10337db96d56Sopenharmony_ci dumped) 10347db96d56Sopenharmony_ci 10357db96d56Sopenharmony_ci @requires_32b 10367db96d56Sopenharmony_ci def test_negative_32b_binunicode(self): 10377db96d56Sopenharmony_ci # On 32-bit builds, a BINUNICODE of 2**31 or more is refused 10387db96d56Sopenharmony_ci dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.' 10397db96d56Sopenharmony_ci self.check_unpickling_error((pickle.UnpicklingError, OverflowError), 10407db96d56Sopenharmony_ci dumped) 10417db96d56Sopenharmony_ci 10427db96d56Sopenharmony_ci def test_short_binunicode(self): 10437db96d56Sopenharmony_ci dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.' 10447db96d56Sopenharmony_ci self.assertEqual(self.loads(dumped), '\u20ac\x00') 10457db96d56Sopenharmony_ci 10467db96d56Sopenharmony_ci def test_misc_get(self): 10477db96d56Sopenharmony_ci self.check_unpickling_error(pickle.UnpicklingError, b'g0\np0') 10487db96d56Sopenharmony_ci self.check_unpickling_error(pickle.UnpicklingError, b'jens:') 10497db96d56Sopenharmony_ci self.check_unpickling_error(pickle.UnpicklingError, b'hens:') 10507db96d56Sopenharmony_ci self.assert_is_copy([(100,), (100,)], 10517db96d56Sopenharmony_ci self.loads(b'((Kdtp0\nh\x00l.))')) 10527db96d56Sopenharmony_ci 10537db96d56Sopenharmony_ci def test_binbytes8(self): 10547db96d56Sopenharmony_ci dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.' 10557db96d56Sopenharmony_ci self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00') 10567db96d56Sopenharmony_ci 10577db96d56Sopenharmony_ci def test_binunicode8(self): 10587db96d56Sopenharmony_ci dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.' 10597db96d56Sopenharmony_ci self.assertEqual(self.loads(dumped), '\u20ac\x00') 10607db96d56Sopenharmony_ci 10617db96d56Sopenharmony_ci def test_bytearray8(self): 10627db96d56Sopenharmony_ci dumped = b'\x80\x05\x96\x03\x00\x00\x00\x00\x00\x00\x00xxx.' 10637db96d56Sopenharmony_ci self.assertEqual(self.loads(dumped), bytearray(b'xxx')) 10647db96d56Sopenharmony_ci 10657db96d56Sopenharmony_ci @requires_32b 10667db96d56Sopenharmony_ci def test_large_32b_binbytes8(self): 10677db96d56Sopenharmony_ci dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' 10687db96d56Sopenharmony_ci self.check_unpickling_error((pickle.UnpicklingError, OverflowError), 10697db96d56Sopenharmony_ci dumped) 10707db96d56Sopenharmony_ci 10717db96d56Sopenharmony_ci @requires_32b 10727db96d56Sopenharmony_ci def test_large_32b_bytearray8(self): 10737db96d56Sopenharmony_ci dumped = b'\x80\x05\x96\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' 10747db96d56Sopenharmony_ci self.check_unpickling_error((pickle.UnpicklingError, OverflowError), 10757db96d56Sopenharmony_ci dumped) 10767db96d56Sopenharmony_ci 10777db96d56Sopenharmony_ci @requires_32b 10787db96d56Sopenharmony_ci def test_large_32b_binunicode8(self): 10797db96d56Sopenharmony_ci dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.' 10807db96d56Sopenharmony_ci self.check_unpickling_error((pickle.UnpicklingError, OverflowError), 10817db96d56Sopenharmony_ci dumped) 10827db96d56Sopenharmony_ci 10837db96d56Sopenharmony_ci def test_get(self): 10847db96d56Sopenharmony_ci pickled = b'((lp100000\ng100000\nt.' 10857db96d56Sopenharmony_ci unpickled = self.loads(pickled) 10867db96d56Sopenharmony_ci self.assertEqual(unpickled, ([],)*2) 10877db96d56Sopenharmony_ci self.assertIs(unpickled[0], unpickled[1]) 10887db96d56Sopenharmony_ci 10897db96d56Sopenharmony_ci def test_binget(self): 10907db96d56Sopenharmony_ci pickled = b'(]q\xffh\xfft.' 10917db96d56Sopenharmony_ci unpickled = self.loads(pickled) 10927db96d56Sopenharmony_ci self.assertEqual(unpickled, ([],)*2) 10937db96d56Sopenharmony_ci self.assertIs(unpickled[0], unpickled[1]) 10947db96d56Sopenharmony_ci 10957db96d56Sopenharmony_ci def test_long_binget(self): 10967db96d56Sopenharmony_ci pickled = b'(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.' 10977db96d56Sopenharmony_ci unpickled = self.loads(pickled) 10987db96d56Sopenharmony_ci self.assertEqual(unpickled, ([],)*2) 10997db96d56Sopenharmony_ci self.assertIs(unpickled[0], unpickled[1]) 11007db96d56Sopenharmony_ci 11017db96d56Sopenharmony_ci def test_dup(self): 11027db96d56Sopenharmony_ci pickled = b'((l2t.' 11037db96d56Sopenharmony_ci unpickled = self.loads(pickled) 11047db96d56Sopenharmony_ci self.assertEqual(unpickled, ([],)*2) 11057db96d56Sopenharmony_ci self.assertIs(unpickled[0], unpickled[1]) 11067db96d56Sopenharmony_ci 11077db96d56Sopenharmony_ci def test_negative_put(self): 11087db96d56Sopenharmony_ci # Issue #12847 11097db96d56Sopenharmony_ci dumped = b'Va\np-1\n.' 11107db96d56Sopenharmony_ci self.check_unpickling_error(ValueError, dumped) 11117db96d56Sopenharmony_ci 11127db96d56Sopenharmony_ci @requires_32b 11137db96d56Sopenharmony_ci def test_negative_32b_binput(self): 11147db96d56Sopenharmony_ci # Issue #12847 11157db96d56Sopenharmony_ci dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.' 11167db96d56Sopenharmony_ci self.check_unpickling_error(ValueError, dumped) 11177db96d56Sopenharmony_ci 11187db96d56Sopenharmony_ci def test_badly_escaped_string(self): 11197db96d56Sopenharmony_ci self.check_unpickling_error(ValueError, b"S'\\'\n.") 11207db96d56Sopenharmony_ci 11217db96d56Sopenharmony_ci def test_badly_quoted_string(self): 11227db96d56Sopenharmony_ci # Issue #17710 11237db96d56Sopenharmony_ci badpickles = [b"S'\n.", 11247db96d56Sopenharmony_ci b'S"\n.', 11257db96d56Sopenharmony_ci b'S\' \n.', 11267db96d56Sopenharmony_ci b'S" \n.', 11277db96d56Sopenharmony_ci b'S\'"\n.', 11287db96d56Sopenharmony_ci b'S"\'\n.', 11297db96d56Sopenharmony_ci b"S' ' \n.", 11307db96d56Sopenharmony_ci b'S" " \n.', 11317db96d56Sopenharmony_ci b"S ''\n.", 11327db96d56Sopenharmony_ci b'S ""\n.', 11337db96d56Sopenharmony_ci b'S \n.', 11347db96d56Sopenharmony_ci b'S\n.', 11357db96d56Sopenharmony_ci b'S.'] 11367db96d56Sopenharmony_ci for p in badpickles: 11377db96d56Sopenharmony_ci self.check_unpickling_error(pickle.UnpicklingError, p) 11387db96d56Sopenharmony_ci 11397db96d56Sopenharmony_ci def test_correctly_quoted_string(self): 11407db96d56Sopenharmony_ci goodpickles = [(b"S''\n.", ''), 11417db96d56Sopenharmony_ci (b'S""\n.', ''), 11427db96d56Sopenharmony_ci (b'S"\\n"\n.', '\n'), 11437db96d56Sopenharmony_ci (b"S'\\n'\n.", '\n')] 11447db96d56Sopenharmony_ci for p, expected in goodpickles: 11457db96d56Sopenharmony_ci self.assertEqual(self.loads(p), expected) 11467db96d56Sopenharmony_ci 11477db96d56Sopenharmony_ci def test_frame_readline(self): 11487db96d56Sopenharmony_ci pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.' 11497db96d56Sopenharmony_ci # 0: \x80 PROTO 4 11507db96d56Sopenharmony_ci # 2: \x95 FRAME 5 11517db96d56Sopenharmony_ci # 11: I INT 42 11527db96d56Sopenharmony_ci # 15: . STOP 11537db96d56Sopenharmony_ci self.assertEqual(self.loads(pickled), 42) 11547db96d56Sopenharmony_ci 11557db96d56Sopenharmony_ci def test_compat_unpickle(self): 11567db96d56Sopenharmony_ci # xrange(1, 7) 11577db96d56Sopenharmony_ci pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.' 11587db96d56Sopenharmony_ci unpickled = self.loads(pickled) 11597db96d56Sopenharmony_ci self.assertIs(type(unpickled), range) 11607db96d56Sopenharmony_ci self.assertEqual(unpickled, range(1, 7)) 11617db96d56Sopenharmony_ci self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6]) 11627db96d56Sopenharmony_ci # reduce 11637db96d56Sopenharmony_ci pickled = b'\x80\x02c__builtin__\nreduce\n.' 11647db96d56Sopenharmony_ci self.assertIs(self.loads(pickled), functools.reduce) 11657db96d56Sopenharmony_ci # whichdb.whichdb 11667db96d56Sopenharmony_ci pickled = b'\x80\x02cwhichdb\nwhichdb\n.' 11677db96d56Sopenharmony_ci self.assertIs(self.loads(pickled), dbm.whichdb) 11687db96d56Sopenharmony_ci # Exception(), StandardError() 11697db96d56Sopenharmony_ci for name in (b'Exception', b'StandardError'): 11707db96d56Sopenharmony_ci pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.') 11717db96d56Sopenharmony_ci unpickled = self.loads(pickled) 11727db96d56Sopenharmony_ci self.assertIs(type(unpickled), Exception) 11737db96d56Sopenharmony_ci self.assertEqual(str(unpickled), 'ugh') 11747db96d56Sopenharmony_ci # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2}) 11757db96d56Sopenharmony_ci for name in (b'UserDict', b'IterableUserDict'): 11767db96d56Sopenharmony_ci pickled = (b'\x80\x02(cUserDict\n' + name + 11777db96d56Sopenharmony_ci b'\no}U\x04data}K\x01K\x02ssb.') 11787db96d56Sopenharmony_ci unpickled = self.loads(pickled) 11797db96d56Sopenharmony_ci self.assertIs(type(unpickled), collections.UserDict) 11807db96d56Sopenharmony_ci self.assertEqual(unpickled, collections.UserDict({1: 2})) 11817db96d56Sopenharmony_ci 11827db96d56Sopenharmony_ci def test_bad_reduce(self): 11837db96d56Sopenharmony_ci self.assertEqual(self.loads(b'cbuiltins\nint\n)R.'), 0) 11847db96d56Sopenharmony_ci self.check_unpickling_error(TypeError, b'N)R.') 11857db96d56Sopenharmony_ci self.check_unpickling_error(TypeError, b'cbuiltins\nint\nNR.') 11867db96d56Sopenharmony_ci 11877db96d56Sopenharmony_ci def test_bad_newobj(self): 11887db96d56Sopenharmony_ci error = (pickle.UnpicklingError, TypeError) 11897db96d56Sopenharmony_ci self.assertEqual(self.loads(b'cbuiltins\nint\n)\x81.'), 0) 11907db96d56Sopenharmony_ci self.check_unpickling_error(error, b'cbuiltins\nlen\n)\x81.') 11917db96d56Sopenharmony_ci self.check_unpickling_error(error, b'cbuiltins\nint\nN\x81.') 11927db96d56Sopenharmony_ci 11937db96d56Sopenharmony_ci def test_bad_newobj_ex(self): 11947db96d56Sopenharmony_ci error = (pickle.UnpicklingError, TypeError) 11957db96d56Sopenharmony_ci self.assertEqual(self.loads(b'cbuiltins\nint\n)}\x92.'), 0) 11967db96d56Sopenharmony_ci self.check_unpickling_error(error, b'cbuiltins\nlen\n)}\x92.') 11977db96d56Sopenharmony_ci self.check_unpickling_error(error, b'cbuiltins\nint\nN}\x92.') 11987db96d56Sopenharmony_ci self.check_unpickling_error(error, b'cbuiltins\nint\n)N\x92.') 11997db96d56Sopenharmony_ci 12007db96d56Sopenharmony_ci def test_bad_stack(self): 12017db96d56Sopenharmony_ci badpickles = [ 12027db96d56Sopenharmony_ci b'.', # STOP 12037db96d56Sopenharmony_ci b'0', # POP 12047db96d56Sopenharmony_ci b'1', # POP_MARK 12057db96d56Sopenharmony_ci b'2', # DUP 12067db96d56Sopenharmony_ci b'(2', 12077db96d56Sopenharmony_ci b'R', # REDUCE 12087db96d56Sopenharmony_ci b')R', 12097db96d56Sopenharmony_ci b'a', # APPEND 12107db96d56Sopenharmony_ci b'Na', 12117db96d56Sopenharmony_ci b'b', # BUILD 12127db96d56Sopenharmony_ci b'Nb', 12137db96d56Sopenharmony_ci b'd', # DICT 12147db96d56Sopenharmony_ci b'e', # APPENDS 12157db96d56Sopenharmony_ci b'(e', 12167db96d56Sopenharmony_ci b'ibuiltins\nlist\n', # INST 12177db96d56Sopenharmony_ci b'l', # LIST 12187db96d56Sopenharmony_ci b'o', # OBJ 12197db96d56Sopenharmony_ci b'(o', 12207db96d56Sopenharmony_ci b'p1\n', # PUT 12217db96d56Sopenharmony_ci b'q\x00', # BINPUT 12227db96d56Sopenharmony_ci b'r\x00\x00\x00\x00', # LONG_BINPUT 12237db96d56Sopenharmony_ci b's', # SETITEM 12247db96d56Sopenharmony_ci b'Ns', 12257db96d56Sopenharmony_ci b'NNs', 12267db96d56Sopenharmony_ci b't', # TUPLE 12277db96d56Sopenharmony_ci b'u', # SETITEMS 12287db96d56Sopenharmony_ci b'(u', 12297db96d56Sopenharmony_ci b'}(Nu', 12307db96d56Sopenharmony_ci b'\x81', # NEWOBJ 12317db96d56Sopenharmony_ci b')\x81', 12327db96d56Sopenharmony_ci b'\x85', # TUPLE1 12337db96d56Sopenharmony_ci b'\x86', # TUPLE2 12347db96d56Sopenharmony_ci b'N\x86', 12357db96d56Sopenharmony_ci b'\x87', # TUPLE3 12367db96d56Sopenharmony_ci b'N\x87', 12377db96d56Sopenharmony_ci b'NN\x87', 12387db96d56Sopenharmony_ci b'\x90', # ADDITEMS 12397db96d56Sopenharmony_ci b'(\x90', 12407db96d56Sopenharmony_ci b'\x91', # FROZENSET 12417db96d56Sopenharmony_ci b'\x92', # NEWOBJ_EX 12427db96d56Sopenharmony_ci b')}\x92', 12437db96d56Sopenharmony_ci b'\x93', # STACK_GLOBAL 12447db96d56Sopenharmony_ci b'Vlist\n\x93', 12457db96d56Sopenharmony_ci b'\x94', # MEMOIZE 12467db96d56Sopenharmony_ci ] 12477db96d56Sopenharmony_ci for p in badpickles: 12487db96d56Sopenharmony_ci self.check_unpickling_error(self.bad_stack_errors, p) 12497db96d56Sopenharmony_ci 12507db96d56Sopenharmony_ci def test_bad_mark(self): 12517db96d56Sopenharmony_ci badpickles = [ 12527db96d56Sopenharmony_ci b'N(.', # STOP 12537db96d56Sopenharmony_ci b'N(2', # DUP 12547db96d56Sopenharmony_ci b'cbuiltins\nlist\n)(R', # REDUCE 12557db96d56Sopenharmony_ci b'cbuiltins\nlist\n()R', 12567db96d56Sopenharmony_ci b']N(a', # APPEND 12577db96d56Sopenharmony_ci # BUILD 12587db96d56Sopenharmony_ci b'cbuiltins\nValueError\n)R}(b', 12597db96d56Sopenharmony_ci b'cbuiltins\nValueError\n)R(}b', 12607db96d56Sopenharmony_ci b'(Nd', # DICT 12617db96d56Sopenharmony_ci b'N(p1\n', # PUT 12627db96d56Sopenharmony_ci b'N(q\x00', # BINPUT 12637db96d56Sopenharmony_ci b'N(r\x00\x00\x00\x00', # LONG_BINPUT 12647db96d56Sopenharmony_ci b'}NN(s', # SETITEM 12657db96d56Sopenharmony_ci b'}N(Ns', 12667db96d56Sopenharmony_ci b'}(NNs', 12677db96d56Sopenharmony_ci b'}((u', # SETITEMS 12687db96d56Sopenharmony_ci b'cbuiltins\nlist\n)(\x81', # NEWOBJ 12697db96d56Sopenharmony_ci b'cbuiltins\nlist\n()\x81', 12707db96d56Sopenharmony_ci b'N(\x85', # TUPLE1 12717db96d56Sopenharmony_ci b'NN(\x86', # TUPLE2 12727db96d56Sopenharmony_ci b'N(N\x86', 12737db96d56Sopenharmony_ci b'NNN(\x87', # TUPLE3 12747db96d56Sopenharmony_ci b'NN(N\x87', 12757db96d56Sopenharmony_ci b'N(NN\x87', 12767db96d56Sopenharmony_ci b']((\x90', # ADDITEMS 12777db96d56Sopenharmony_ci # NEWOBJ_EX 12787db96d56Sopenharmony_ci b'cbuiltins\nlist\n)}(\x92', 12797db96d56Sopenharmony_ci b'cbuiltins\nlist\n)(}\x92', 12807db96d56Sopenharmony_ci b'cbuiltins\nlist\n()}\x92', 12817db96d56Sopenharmony_ci # STACK_GLOBAL 12827db96d56Sopenharmony_ci b'Vbuiltins\n(Vlist\n\x93', 12837db96d56Sopenharmony_ci b'Vbuiltins\nVlist\n(\x93', 12847db96d56Sopenharmony_ci b'N(\x94', # MEMOIZE 12857db96d56Sopenharmony_ci ] 12867db96d56Sopenharmony_ci for p in badpickles: 12877db96d56Sopenharmony_ci self.check_unpickling_error(self.bad_stack_errors, p) 12887db96d56Sopenharmony_ci 12897db96d56Sopenharmony_ci def test_truncated_data(self): 12907db96d56Sopenharmony_ci self.check_unpickling_error(EOFError, b'') 12917db96d56Sopenharmony_ci self.check_unpickling_error(EOFError, b'N') 12927db96d56Sopenharmony_ci badpickles = [ 12937db96d56Sopenharmony_ci b'B', # BINBYTES 12947db96d56Sopenharmony_ci b'B\x03\x00\x00', 12957db96d56Sopenharmony_ci b'B\x03\x00\x00\x00', 12967db96d56Sopenharmony_ci b'B\x03\x00\x00\x00ab', 12977db96d56Sopenharmony_ci b'C', # SHORT_BINBYTES 12987db96d56Sopenharmony_ci b'C\x03', 12997db96d56Sopenharmony_ci b'C\x03ab', 13007db96d56Sopenharmony_ci b'F', # FLOAT 13017db96d56Sopenharmony_ci b'F0.0', 13027db96d56Sopenharmony_ci b'F0.00', 13037db96d56Sopenharmony_ci b'G', # BINFLOAT 13047db96d56Sopenharmony_ci b'G\x00\x00\x00\x00\x00\x00\x00', 13057db96d56Sopenharmony_ci b'I', # INT 13067db96d56Sopenharmony_ci b'I0', 13077db96d56Sopenharmony_ci b'J', # BININT 13087db96d56Sopenharmony_ci b'J\x00\x00\x00', 13097db96d56Sopenharmony_ci b'K', # BININT1 13107db96d56Sopenharmony_ci b'L', # LONG 13117db96d56Sopenharmony_ci b'L0', 13127db96d56Sopenharmony_ci b'L10', 13137db96d56Sopenharmony_ci b'L0L', 13147db96d56Sopenharmony_ci b'L10L', 13157db96d56Sopenharmony_ci b'M', # BININT2 13167db96d56Sopenharmony_ci b'M\x00', 13177db96d56Sopenharmony_ci # b'P', # PERSID 13187db96d56Sopenharmony_ci # b'Pabc', 13197db96d56Sopenharmony_ci b'S', # STRING 13207db96d56Sopenharmony_ci b"S'abc'", 13217db96d56Sopenharmony_ci b'T', # BINSTRING 13227db96d56Sopenharmony_ci b'T\x03\x00\x00', 13237db96d56Sopenharmony_ci b'T\x03\x00\x00\x00', 13247db96d56Sopenharmony_ci b'T\x03\x00\x00\x00ab', 13257db96d56Sopenharmony_ci b'U', # SHORT_BINSTRING 13267db96d56Sopenharmony_ci b'U\x03', 13277db96d56Sopenharmony_ci b'U\x03ab', 13287db96d56Sopenharmony_ci b'V', # UNICODE 13297db96d56Sopenharmony_ci b'Vabc', 13307db96d56Sopenharmony_ci b'X', # BINUNICODE 13317db96d56Sopenharmony_ci b'X\x03\x00\x00', 13327db96d56Sopenharmony_ci b'X\x03\x00\x00\x00', 13337db96d56Sopenharmony_ci b'X\x03\x00\x00\x00ab', 13347db96d56Sopenharmony_ci b'(c', # GLOBAL 13357db96d56Sopenharmony_ci b'(cbuiltins', 13367db96d56Sopenharmony_ci b'(cbuiltins\n', 13377db96d56Sopenharmony_ci b'(cbuiltins\nlist', 13387db96d56Sopenharmony_ci b'Ng', # GET 13397db96d56Sopenharmony_ci b'Ng0', 13407db96d56Sopenharmony_ci b'(i', # INST 13417db96d56Sopenharmony_ci b'(ibuiltins', 13427db96d56Sopenharmony_ci b'(ibuiltins\n', 13437db96d56Sopenharmony_ci b'(ibuiltins\nlist', 13447db96d56Sopenharmony_ci b'Nh', # BINGET 13457db96d56Sopenharmony_ci b'Nj', # LONG_BINGET 13467db96d56Sopenharmony_ci b'Nj\x00\x00\x00', 13477db96d56Sopenharmony_ci b'Np', # PUT 13487db96d56Sopenharmony_ci b'Np0', 13497db96d56Sopenharmony_ci b'Nq', # BINPUT 13507db96d56Sopenharmony_ci b'Nr', # LONG_BINPUT 13517db96d56Sopenharmony_ci b'Nr\x00\x00\x00', 13527db96d56Sopenharmony_ci b'\x80', # PROTO 13537db96d56Sopenharmony_ci b'\x82', # EXT1 13547db96d56Sopenharmony_ci b'\x83', # EXT2 13557db96d56Sopenharmony_ci b'\x84\x01', 13567db96d56Sopenharmony_ci b'\x84', # EXT4 13577db96d56Sopenharmony_ci b'\x84\x01\x00\x00', 13587db96d56Sopenharmony_ci b'\x8a', # LONG1 13597db96d56Sopenharmony_ci b'\x8b', # LONG4 13607db96d56Sopenharmony_ci b'\x8b\x00\x00\x00', 13617db96d56Sopenharmony_ci b'\x8c', # SHORT_BINUNICODE 13627db96d56Sopenharmony_ci b'\x8c\x03', 13637db96d56Sopenharmony_ci b'\x8c\x03ab', 13647db96d56Sopenharmony_ci b'\x8d', # BINUNICODE8 13657db96d56Sopenharmony_ci b'\x8d\x03\x00\x00\x00\x00\x00\x00', 13667db96d56Sopenharmony_ci b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00', 13677db96d56Sopenharmony_ci b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab', 13687db96d56Sopenharmony_ci b'\x8e', # BINBYTES8 13697db96d56Sopenharmony_ci b'\x8e\x03\x00\x00\x00\x00\x00\x00', 13707db96d56Sopenharmony_ci b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00', 13717db96d56Sopenharmony_ci b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab', 13727db96d56Sopenharmony_ci b'\x96', # BYTEARRAY8 13737db96d56Sopenharmony_ci b'\x96\x03\x00\x00\x00\x00\x00\x00', 13747db96d56Sopenharmony_ci b'\x96\x03\x00\x00\x00\x00\x00\x00\x00', 13757db96d56Sopenharmony_ci b'\x96\x03\x00\x00\x00\x00\x00\x00\x00ab', 13767db96d56Sopenharmony_ci b'\x95', # FRAME 13777db96d56Sopenharmony_ci b'\x95\x02\x00\x00\x00\x00\x00\x00', 13787db96d56Sopenharmony_ci b'\x95\x02\x00\x00\x00\x00\x00\x00\x00', 13797db96d56Sopenharmony_ci b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N', 13807db96d56Sopenharmony_ci ] 13817db96d56Sopenharmony_ci for p in badpickles: 13827db96d56Sopenharmony_ci self.check_unpickling_error(self.truncated_errors, p) 13837db96d56Sopenharmony_ci 13847db96d56Sopenharmony_ci @threading_helper.reap_threads 13857db96d56Sopenharmony_ci @threading_helper.requires_working_threading() 13867db96d56Sopenharmony_ci def test_unpickle_module_race(self): 13877db96d56Sopenharmony_ci # https://bugs.python.org/issue34572 13887db96d56Sopenharmony_ci locker_module = dedent(""" 13897db96d56Sopenharmony_ci import threading 13907db96d56Sopenharmony_ci barrier = threading.Barrier(2) 13917db96d56Sopenharmony_ci """) 13927db96d56Sopenharmony_ci locking_import_module = dedent(""" 13937db96d56Sopenharmony_ci import locker 13947db96d56Sopenharmony_ci locker.barrier.wait() 13957db96d56Sopenharmony_ci class ToBeUnpickled(object): 13967db96d56Sopenharmony_ci pass 13977db96d56Sopenharmony_ci """) 13987db96d56Sopenharmony_ci 13997db96d56Sopenharmony_ci os.mkdir(TESTFN) 14007db96d56Sopenharmony_ci self.addCleanup(shutil.rmtree, TESTFN) 14017db96d56Sopenharmony_ci sys.path.insert(0, TESTFN) 14027db96d56Sopenharmony_ci self.addCleanup(sys.path.remove, TESTFN) 14037db96d56Sopenharmony_ci with open(os.path.join(TESTFN, "locker.py"), "wb") as f: 14047db96d56Sopenharmony_ci f.write(locker_module.encode('utf-8')) 14057db96d56Sopenharmony_ci with open(os.path.join(TESTFN, "locking_import.py"), "wb") as f: 14067db96d56Sopenharmony_ci f.write(locking_import_module.encode('utf-8')) 14077db96d56Sopenharmony_ci self.addCleanup(forget, "locker") 14087db96d56Sopenharmony_ci self.addCleanup(forget, "locking_import") 14097db96d56Sopenharmony_ci 14107db96d56Sopenharmony_ci import locker 14117db96d56Sopenharmony_ci 14127db96d56Sopenharmony_ci pickle_bytes = ( 14137db96d56Sopenharmony_ci b'\x80\x03clocking_import\nToBeUnpickled\nq\x00)\x81q\x01.') 14147db96d56Sopenharmony_ci 14157db96d56Sopenharmony_ci # Then try to unpickle two of these simultaneously 14167db96d56Sopenharmony_ci # One of them will cause the module import, and we want it to block 14177db96d56Sopenharmony_ci # until the other one either: 14187db96d56Sopenharmony_ci # - fails (before the patch for this issue) 14197db96d56Sopenharmony_ci # - blocks on the import lock for the module, as it should 14207db96d56Sopenharmony_ci results = [] 14217db96d56Sopenharmony_ci barrier = threading.Barrier(3) 14227db96d56Sopenharmony_ci def t(): 14237db96d56Sopenharmony_ci # This ensures the threads have all started 14247db96d56Sopenharmony_ci # presumably barrier release is faster than thread startup 14257db96d56Sopenharmony_ci barrier.wait() 14267db96d56Sopenharmony_ci results.append(pickle.loads(pickle_bytes)) 14277db96d56Sopenharmony_ci 14287db96d56Sopenharmony_ci t1 = threading.Thread(target=t) 14297db96d56Sopenharmony_ci t2 = threading.Thread(target=t) 14307db96d56Sopenharmony_ci t1.start() 14317db96d56Sopenharmony_ci t2.start() 14327db96d56Sopenharmony_ci 14337db96d56Sopenharmony_ci barrier.wait() 14347db96d56Sopenharmony_ci # could have delay here 14357db96d56Sopenharmony_ci locker.barrier.wait() 14367db96d56Sopenharmony_ci 14377db96d56Sopenharmony_ci t1.join() 14387db96d56Sopenharmony_ci t2.join() 14397db96d56Sopenharmony_ci 14407db96d56Sopenharmony_ci from locking_import import ToBeUnpickled 14417db96d56Sopenharmony_ci self.assertEqual( 14427db96d56Sopenharmony_ci [type(x) for x in results], 14437db96d56Sopenharmony_ci [ToBeUnpickled] * 2) 14447db96d56Sopenharmony_ci 14457db96d56Sopenharmony_ci 14467db96d56Sopenharmony_ci 14477db96d56Sopenharmony_ciclass AbstractPickleTests: 14487db96d56Sopenharmony_ci # Subclass must define self.dumps, self.loads. 14497db96d56Sopenharmony_ci 14507db96d56Sopenharmony_ci optimized = False 14517db96d56Sopenharmony_ci 14527db96d56Sopenharmony_ci _testdata = AbstractUnpickleTests._testdata 14537db96d56Sopenharmony_ci 14547db96d56Sopenharmony_ci def setUp(self): 14557db96d56Sopenharmony_ci pass 14567db96d56Sopenharmony_ci 14577db96d56Sopenharmony_ci assert_is_copy = AbstractUnpickleTests.assert_is_copy 14587db96d56Sopenharmony_ci 14597db96d56Sopenharmony_ci def test_misc(self): 14607db96d56Sopenharmony_ci # test various datatypes not tested by testdata 14617db96d56Sopenharmony_ci for proto in protocols: 14627db96d56Sopenharmony_ci x = myint(4) 14637db96d56Sopenharmony_ci s = self.dumps(x, proto) 14647db96d56Sopenharmony_ci y = self.loads(s) 14657db96d56Sopenharmony_ci self.assert_is_copy(x, y) 14667db96d56Sopenharmony_ci 14677db96d56Sopenharmony_ci x = (1, ()) 14687db96d56Sopenharmony_ci s = self.dumps(x, proto) 14697db96d56Sopenharmony_ci y = self.loads(s) 14707db96d56Sopenharmony_ci self.assert_is_copy(x, y) 14717db96d56Sopenharmony_ci 14727db96d56Sopenharmony_ci x = initarg(1, x) 14737db96d56Sopenharmony_ci s = self.dumps(x, proto) 14747db96d56Sopenharmony_ci y = self.loads(s) 14757db96d56Sopenharmony_ci self.assert_is_copy(x, y) 14767db96d56Sopenharmony_ci 14777db96d56Sopenharmony_ci # XXX test __reduce__ protocol? 14787db96d56Sopenharmony_ci 14797db96d56Sopenharmony_ci def test_roundtrip_equality(self): 14807db96d56Sopenharmony_ci expected = self._testdata 14817db96d56Sopenharmony_ci for proto in protocols: 14827db96d56Sopenharmony_ci s = self.dumps(expected, proto) 14837db96d56Sopenharmony_ci got = self.loads(s) 14847db96d56Sopenharmony_ci self.assert_is_copy(expected, got) 14857db96d56Sopenharmony_ci 14867db96d56Sopenharmony_ci # There are gratuitous differences between pickles produced by 14877db96d56Sopenharmony_ci # pickle and cPickle, largely because cPickle starts PUT indices at 14887db96d56Sopenharmony_ci # 1 and pickle starts them at 0. See XXX comment in cPickle's put2() -- 14897db96d56Sopenharmony_ci # there's a comment with an exclamation point there whose meaning 14907db96d56Sopenharmony_ci # is a mystery. cPickle also suppresses PUT for objects with a refcount 14917db96d56Sopenharmony_ci # of 1. 14927db96d56Sopenharmony_ci def dont_test_disassembly(self): 14937db96d56Sopenharmony_ci from io import StringIO 14947db96d56Sopenharmony_ci from pickletools import dis 14957db96d56Sopenharmony_ci 14967db96d56Sopenharmony_ci for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS): 14977db96d56Sopenharmony_ci s = self.dumps(self._testdata, proto) 14987db96d56Sopenharmony_ci filelike = StringIO() 14997db96d56Sopenharmony_ci dis(s, out=filelike) 15007db96d56Sopenharmony_ci got = filelike.getvalue() 15017db96d56Sopenharmony_ci self.assertEqual(expected, got) 15027db96d56Sopenharmony_ci 15037db96d56Sopenharmony_ci def _test_recursive_list(self, cls, aslist=identity, minprotocol=0): 15047db96d56Sopenharmony_ci # List containing itself. 15057db96d56Sopenharmony_ci l = cls() 15067db96d56Sopenharmony_ci l.append(l) 15077db96d56Sopenharmony_ci for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1): 15087db96d56Sopenharmony_ci s = self.dumps(l, proto) 15097db96d56Sopenharmony_ci x = self.loads(s) 15107db96d56Sopenharmony_ci self.assertIsInstance(x, cls) 15117db96d56Sopenharmony_ci y = aslist(x) 15127db96d56Sopenharmony_ci self.assertEqual(len(y), 1) 15137db96d56Sopenharmony_ci self.assertIs(y[0], x) 15147db96d56Sopenharmony_ci 15157db96d56Sopenharmony_ci def test_recursive_list(self): 15167db96d56Sopenharmony_ci self._test_recursive_list(list) 15177db96d56Sopenharmony_ci 15187db96d56Sopenharmony_ci def test_recursive_list_subclass(self): 15197db96d56Sopenharmony_ci self._test_recursive_list(MyList, minprotocol=2) 15207db96d56Sopenharmony_ci 15217db96d56Sopenharmony_ci def test_recursive_list_like(self): 15227db96d56Sopenharmony_ci self._test_recursive_list(REX_six, aslist=lambda x: x.items) 15237db96d56Sopenharmony_ci 15247db96d56Sopenharmony_ci def _test_recursive_tuple_and_list(self, cls, aslist=identity, minprotocol=0): 15257db96d56Sopenharmony_ci # Tuple containing a list containing the original tuple. 15267db96d56Sopenharmony_ci t = (cls(),) 15277db96d56Sopenharmony_ci t[0].append(t) 15287db96d56Sopenharmony_ci for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1): 15297db96d56Sopenharmony_ci s = self.dumps(t, proto) 15307db96d56Sopenharmony_ci x = self.loads(s) 15317db96d56Sopenharmony_ci self.assertIsInstance(x, tuple) 15327db96d56Sopenharmony_ci self.assertEqual(len(x), 1) 15337db96d56Sopenharmony_ci self.assertIsInstance(x[0], cls) 15347db96d56Sopenharmony_ci y = aslist(x[0]) 15357db96d56Sopenharmony_ci self.assertEqual(len(y), 1) 15367db96d56Sopenharmony_ci self.assertIs(y[0], x) 15377db96d56Sopenharmony_ci 15387db96d56Sopenharmony_ci # List containing a tuple containing the original list. 15397db96d56Sopenharmony_ci t, = t 15407db96d56Sopenharmony_ci for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1): 15417db96d56Sopenharmony_ci s = self.dumps(t, proto) 15427db96d56Sopenharmony_ci x = self.loads(s) 15437db96d56Sopenharmony_ci self.assertIsInstance(x, cls) 15447db96d56Sopenharmony_ci y = aslist(x) 15457db96d56Sopenharmony_ci self.assertEqual(len(y), 1) 15467db96d56Sopenharmony_ci self.assertIsInstance(y[0], tuple) 15477db96d56Sopenharmony_ci self.assertEqual(len(y[0]), 1) 15487db96d56Sopenharmony_ci self.assertIs(y[0][0], x) 15497db96d56Sopenharmony_ci 15507db96d56Sopenharmony_ci def test_recursive_tuple_and_list(self): 15517db96d56Sopenharmony_ci self._test_recursive_tuple_and_list(list) 15527db96d56Sopenharmony_ci 15537db96d56Sopenharmony_ci def test_recursive_tuple_and_list_subclass(self): 15547db96d56Sopenharmony_ci self._test_recursive_tuple_and_list(MyList, minprotocol=2) 15557db96d56Sopenharmony_ci 15567db96d56Sopenharmony_ci def test_recursive_tuple_and_list_like(self): 15577db96d56Sopenharmony_ci self._test_recursive_tuple_and_list(REX_six, aslist=lambda x: x.items) 15587db96d56Sopenharmony_ci 15597db96d56Sopenharmony_ci def _test_recursive_dict(self, cls, asdict=identity, minprotocol=0): 15607db96d56Sopenharmony_ci # Dict containing itself. 15617db96d56Sopenharmony_ci d = cls() 15627db96d56Sopenharmony_ci d[1] = d 15637db96d56Sopenharmony_ci for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1): 15647db96d56Sopenharmony_ci s = self.dumps(d, proto) 15657db96d56Sopenharmony_ci x = self.loads(s) 15667db96d56Sopenharmony_ci self.assertIsInstance(x, cls) 15677db96d56Sopenharmony_ci y = asdict(x) 15687db96d56Sopenharmony_ci self.assertEqual(list(y.keys()), [1]) 15697db96d56Sopenharmony_ci self.assertIs(y[1], x) 15707db96d56Sopenharmony_ci 15717db96d56Sopenharmony_ci def test_recursive_dict(self): 15727db96d56Sopenharmony_ci self._test_recursive_dict(dict) 15737db96d56Sopenharmony_ci 15747db96d56Sopenharmony_ci def test_recursive_dict_subclass(self): 15757db96d56Sopenharmony_ci self._test_recursive_dict(MyDict, minprotocol=2) 15767db96d56Sopenharmony_ci 15777db96d56Sopenharmony_ci def test_recursive_dict_like(self): 15787db96d56Sopenharmony_ci self._test_recursive_dict(REX_seven, asdict=lambda x: x.table) 15797db96d56Sopenharmony_ci 15807db96d56Sopenharmony_ci def _test_recursive_tuple_and_dict(self, cls, asdict=identity, minprotocol=0): 15817db96d56Sopenharmony_ci # Tuple containing a dict containing the original tuple. 15827db96d56Sopenharmony_ci t = (cls(),) 15837db96d56Sopenharmony_ci t[0][1] = t 15847db96d56Sopenharmony_ci for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1): 15857db96d56Sopenharmony_ci s = self.dumps(t, proto) 15867db96d56Sopenharmony_ci x = self.loads(s) 15877db96d56Sopenharmony_ci self.assertIsInstance(x, tuple) 15887db96d56Sopenharmony_ci self.assertEqual(len(x), 1) 15897db96d56Sopenharmony_ci self.assertIsInstance(x[0], cls) 15907db96d56Sopenharmony_ci y = asdict(x[0]) 15917db96d56Sopenharmony_ci self.assertEqual(list(y), [1]) 15927db96d56Sopenharmony_ci self.assertIs(y[1], x) 15937db96d56Sopenharmony_ci 15947db96d56Sopenharmony_ci # Dict containing a tuple containing the original dict. 15957db96d56Sopenharmony_ci t, = t 15967db96d56Sopenharmony_ci for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1): 15977db96d56Sopenharmony_ci s = self.dumps(t, proto) 15987db96d56Sopenharmony_ci x = self.loads(s) 15997db96d56Sopenharmony_ci self.assertIsInstance(x, cls) 16007db96d56Sopenharmony_ci y = asdict(x) 16017db96d56Sopenharmony_ci self.assertEqual(list(y), [1]) 16027db96d56Sopenharmony_ci self.assertIsInstance(y[1], tuple) 16037db96d56Sopenharmony_ci self.assertEqual(len(y[1]), 1) 16047db96d56Sopenharmony_ci self.assertIs(y[1][0], x) 16057db96d56Sopenharmony_ci 16067db96d56Sopenharmony_ci def test_recursive_tuple_and_dict(self): 16077db96d56Sopenharmony_ci self._test_recursive_tuple_and_dict(dict) 16087db96d56Sopenharmony_ci 16097db96d56Sopenharmony_ci def test_recursive_tuple_and_dict_subclass(self): 16107db96d56Sopenharmony_ci self._test_recursive_tuple_and_dict(MyDict, minprotocol=2) 16117db96d56Sopenharmony_ci 16127db96d56Sopenharmony_ci def test_recursive_tuple_and_dict_like(self): 16137db96d56Sopenharmony_ci self._test_recursive_tuple_and_dict(REX_seven, asdict=lambda x: x.table) 16147db96d56Sopenharmony_ci 16157db96d56Sopenharmony_ci def _test_recursive_dict_key(self, cls, asdict=identity, minprotocol=0): 16167db96d56Sopenharmony_ci # Dict containing an immutable object (as key) containing the original 16177db96d56Sopenharmony_ci # dict. 16187db96d56Sopenharmony_ci d = cls() 16197db96d56Sopenharmony_ci d[K(d)] = 1 16207db96d56Sopenharmony_ci for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1): 16217db96d56Sopenharmony_ci s = self.dumps(d, proto) 16227db96d56Sopenharmony_ci x = self.loads(s) 16237db96d56Sopenharmony_ci self.assertIsInstance(x, cls) 16247db96d56Sopenharmony_ci y = asdict(x) 16257db96d56Sopenharmony_ci self.assertEqual(len(y.keys()), 1) 16267db96d56Sopenharmony_ci self.assertIsInstance(list(y.keys())[0], K) 16277db96d56Sopenharmony_ci self.assertIs(list(y.keys())[0].value, x) 16287db96d56Sopenharmony_ci 16297db96d56Sopenharmony_ci def test_recursive_dict_key(self): 16307db96d56Sopenharmony_ci self._test_recursive_dict_key(dict) 16317db96d56Sopenharmony_ci 16327db96d56Sopenharmony_ci def test_recursive_dict_subclass_key(self): 16337db96d56Sopenharmony_ci self._test_recursive_dict_key(MyDict, minprotocol=2) 16347db96d56Sopenharmony_ci 16357db96d56Sopenharmony_ci def test_recursive_dict_like_key(self): 16367db96d56Sopenharmony_ci self._test_recursive_dict_key(REX_seven, asdict=lambda x: x.table) 16377db96d56Sopenharmony_ci 16387db96d56Sopenharmony_ci def _test_recursive_tuple_and_dict_key(self, cls, asdict=identity, minprotocol=0): 16397db96d56Sopenharmony_ci # Tuple containing a dict containing an immutable object (as key) 16407db96d56Sopenharmony_ci # containing the original tuple. 16417db96d56Sopenharmony_ci t = (cls(),) 16427db96d56Sopenharmony_ci t[0][K(t)] = 1 16437db96d56Sopenharmony_ci for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1): 16447db96d56Sopenharmony_ci s = self.dumps(t, proto) 16457db96d56Sopenharmony_ci x = self.loads(s) 16467db96d56Sopenharmony_ci self.assertIsInstance(x, tuple) 16477db96d56Sopenharmony_ci self.assertEqual(len(x), 1) 16487db96d56Sopenharmony_ci self.assertIsInstance(x[0], cls) 16497db96d56Sopenharmony_ci y = asdict(x[0]) 16507db96d56Sopenharmony_ci self.assertEqual(len(y), 1) 16517db96d56Sopenharmony_ci self.assertIsInstance(list(y.keys())[0], K) 16527db96d56Sopenharmony_ci self.assertIs(list(y.keys())[0].value, x) 16537db96d56Sopenharmony_ci 16547db96d56Sopenharmony_ci # Dict containing an immutable object (as key) containing a tuple 16557db96d56Sopenharmony_ci # containing the original dict. 16567db96d56Sopenharmony_ci t, = t 16577db96d56Sopenharmony_ci for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1): 16587db96d56Sopenharmony_ci s = self.dumps(t, proto) 16597db96d56Sopenharmony_ci x = self.loads(s) 16607db96d56Sopenharmony_ci self.assertIsInstance(x, cls) 16617db96d56Sopenharmony_ci y = asdict(x) 16627db96d56Sopenharmony_ci self.assertEqual(len(y), 1) 16637db96d56Sopenharmony_ci self.assertIsInstance(list(y.keys())[0], K) 16647db96d56Sopenharmony_ci self.assertIs(list(y.keys())[0].value[0], x) 16657db96d56Sopenharmony_ci 16667db96d56Sopenharmony_ci def test_recursive_tuple_and_dict_key(self): 16677db96d56Sopenharmony_ci self._test_recursive_tuple_and_dict_key(dict) 16687db96d56Sopenharmony_ci 16697db96d56Sopenharmony_ci def test_recursive_tuple_and_dict_subclass_key(self): 16707db96d56Sopenharmony_ci self._test_recursive_tuple_and_dict_key(MyDict, minprotocol=2) 16717db96d56Sopenharmony_ci 16727db96d56Sopenharmony_ci def test_recursive_tuple_and_dict_like_key(self): 16737db96d56Sopenharmony_ci self._test_recursive_tuple_and_dict_key(REX_seven, asdict=lambda x: x.table) 16747db96d56Sopenharmony_ci 16757db96d56Sopenharmony_ci def test_recursive_set(self): 16767db96d56Sopenharmony_ci # Set containing an immutable object containing the original set. 16777db96d56Sopenharmony_ci y = set() 16787db96d56Sopenharmony_ci y.add(K(y)) 16797db96d56Sopenharmony_ci for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): 16807db96d56Sopenharmony_ci s = self.dumps(y, proto) 16817db96d56Sopenharmony_ci x = self.loads(s) 16827db96d56Sopenharmony_ci self.assertIsInstance(x, set) 16837db96d56Sopenharmony_ci self.assertEqual(len(x), 1) 16847db96d56Sopenharmony_ci self.assertIsInstance(list(x)[0], K) 16857db96d56Sopenharmony_ci self.assertIs(list(x)[0].value, x) 16867db96d56Sopenharmony_ci 16877db96d56Sopenharmony_ci # Immutable object containing a set containing the original object. 16887db96d56Sopenharmony_ci y, = y 16897db96d56Sopenharmony_ci for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): 16907db96d56Sopenharmony_ci s = self.dumps(y, proto) 16917db96d56Sopenharmony_ci x = self.loads(s) 16927db96d56Sopenharmony_ci self.assertIsInstance(x, K) 16937db96d56Sopenharmony_ci self.assertIsInstance(x.value, set) 16947db96d56Sopenharmony_ci self.assertEqual(len(x.value), 1) 16957db96d56Sopenharmony_ci self.assertIs(list(x.value)[0], x) 16967db96d56Sopenharmony_ci 16977db96d56Sopenharmony_ci def test_recursive_inst(self): 16987db96d56Sopenharmony_ci # Mutable object containing itself. 16997db96d56Sopenharmony_ci i = Object() 17007db96d56Sopenharmony_ci i.attr = i 17017db96d56Sopenharmony_ci for proto in protocols: 17027db96d56Sopenharmony_ci s = self.dumps(i, proto) 17037db96d56Sopenharmony_ci x = self.loads(s) 17047db96d56Sopenharmony_ci self.assertIsInstance(x, Object) 17057db96d56Sopenharmony_ci self.assertEqual(dir(x), dir(i)) 17067db96d56Sopenharmony_ci self.assertIs(x.attr, x) 17077db96d56Sopenharmony_ci 17087db96d56Sopenharmony_ci def test_recursive_multi(self): 17097db96d56Sopenharmony_ci l = [] 17107db96d56Sopenharmony_ci d = {1:l} 17117db96d56Sopenharmony_ci i = Object() 17127db96d56Sopenharmony_ci i.attr = d 17137db96d56Sopenharmony_ci l.append(i) 17147db96d56Sopenharmony_ci for proto in protocols: 17157db96d56Sopenharmony_ci s = self.dumps(l, proto) 17167db96d56Sopenharmony_ci x = self.loads(s) 17177db96d56Sopenharmony_ci self.assertIsInstance(x, list) 17187db96d56Sopenharmony_ci self.assertEqual(len(x), 1) 17197db96d56Sopenharmony_ci self.assertEqual(dir(x[0]), dir(i)) 17207db96d56Sopenharmony_ci self.assertEqual(list(x[0].attr.keys()), [1]) 17217db96d56Sopenharmony_ci self.assertIs(x[0].attr[1], x) 17227db96d56Sopenharmony_ci 17237db96d56Sopenharmony_ci def _test_recursive_collection_and_inst(self, factory): 17247db96d56Sopenharmony_ci # Mutable object containing a collection containing the original 17257db96d56Sopenharmony_ci # object. 17267db96d56Sopenharmony_ci o = Object() 17277db96d56Sopenharmony_ci o.attr = factory([o]) 17287db96d56Sopenharmony_ci t = type(o.attr) 17297db96d56Sopenharmony_ci for proto in protocols: 17307db96d56Sopenharmony_ci s = self.dumps(o, proto) 17317db96d56Sopenharmony_ci x = self.loads(s) 17327db96d56Sopenharmony_ci self.assertIsInstance(x.attr, t) 17337db96d56Sopenharmony_ci self.assertEqual(len(x.attr), 1) 17347db96d56Sopenharmony_ci self.assertIsInstance(list(x.attr)[0], Object) 17357db96d56Sopenharmony_ci self.assertIs(list(x.attr)[0], x) 17367db96d56Sopenharmony_ci 17377db96d56Sopenharmony_ci # Collection containing a mutable object containing the original 17387db96d56Sopenharmony_ci # collection. 17397db96d56Sopenharmony_ci o = o.attr 17407db96d56Sopenharmony_ci for proto in protocols: 17417db96d56Sopenharmony_ci s = self.dumps(o, proto) 17427db96d56Sopenharmony_ci x = self.loads(s) 17437db96d56Sopenharmony_ci self.assertIsInstance(x, t) 17447db96d56Sopenharmony_ci self.assertEqual(len(x), 1) 17457db96d56Sopenharmony_ci self.assertIsInstance(list(x)[0], Object) 17467db96d56Sopenharmony_ci self.assertIs(list(x)[0].attr, x) 17477db96d56Sopenharmony_ci 17487db96d56Sopenharmony_ci def test_recursive_list_and_inst(self): 17497db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(list) 17507db96d56Sopenharmony_ci 17517db96d56Sopenharmony_ci def test_recursive_tuple_and_inst(self): 17527db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(tuple) 17537db96d56Sopenharmony_ci 17547db96d56Sopenharmony_ci def test_recursive_dict_and_inst(self): 17557db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(dict.fromkeys) 17567db96d56Sopenharmony_ci 17577db96d56Sopenharmony_ci def test_recursive_set_and_inst(self): 17587db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(set) 17597db96d56Sopenharmony_ci 17607db96d56Sopenharmony_ci def test_recursive_frozenset_and_inst(self): 17617db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(frozenset) 17627db96d56Sopenharmony_ci 17637db96d56Sopenharmony_ci def test_recursive_list_subclass_and_inst(self): 17647db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(MyList) 17657db96d56Sopenharmony_ci 17667db96d56Sopenharmony_ci def test_recursive_tuple_subclass_and_inst(self): 17677db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(MyTuple) 17687db96d56Sopenharmony_ci 17697db96d56Sopenharmony_ci def test_recursive_dict_subclass_and_inst(self): 17707db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(MyDict.fromkeys) 17717db96d56Sopenharmony_ci 17727db96d56Sopenharmony_ci def test_recursive_set_subclass_and_inst(self): 17737db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(MySet) 17747db96d56Sopenharmony_ci 17757db96d56Sopenharmony_ci def test_recursive_frozenset_subclass_and_inst(self): 17767db96d56Sopenharmony_ci self._test_recursive_collection_and_inst(MyFrozenSet) 17777db96d56Sopenharmony_ci 17787db96d56Sopenharmony_ci def test_recursive_inst_state(self): 17797db96d56Sopenharmony_ci # Mutable object containing itself. 17807db96d56Sopenharmony_ci y = REX_state() 17817db96d56Sopenharmony_ci y.state = y 17827db96d56Sopenharmony_ci for proto in protocols: 17837db96d56Sopenharmony_ci s = self.dumps(y, proto) 17847db96d56Sopenharmony_ci x = self.loads(s) 17857db96d56Sopenharmony_ci self.assertIsInstance(x, REX_state) 17867db96d56Sopenharmony_ci self.assertIs(x.state, x) 17877db96d56Sopenharmony_ci 17887db96d56Sopenharmony_ci def test_recursive_tuple_and_inst_state(self): 17897db96d56Sopenharmony_ci # Tuple containing a mutable object containing the original tuple. 17907db96d56Sopenharmony_ci t = (REX_state(),) 17917db96d56Sopenharmony_ci t[0].state = t 17927db96d56Sopenharmony_ci for proto in protocols: 17937db96d56Sopenharmony_ci s = self.dumps(t, proto) 17947db96d56Sopenharmony_ci x = self.loads(s) 17957db96d56Sopenharmony_ci self.assertIsInstance(x, tuple) 17967db96d56Sopenharmony_ci self.assertEqual(len(x), 1) 17977db96d56Sopenharmony_ci self.assertIsInstance(x[0], REX_state) 17987db96d56Sopenharmony_ci self.assertIs(x[0].state, x) 17997db96d56Sopenharmony_ci 18007db96d56Sopenharmony_ci # Mutable object containing a tuple containing the object. 18017db96d56Sopenharmony_ci t, = t 18027db96d56Sopenharmony_ci for proto in protocols: 18037db96d56Sopenharmony_ci s = self.dumps(t, proto) 18047db96d56Sopenharmony_ci x = self.loads(s) 18057db96d56Sopenharmony_ci self.assertIsInstance(x, REX_state) 18067db96d56Sopenharmony_ci self.assertIsInstance(x.state, tuple) 18077db96d56Sopenharmony_ci self.assertEqual(len(x.state), 1) 18087db96d56Sopenharmony_ci self.assertIs(x.state[0], x) 18097db96d56Sopenharmony_ci 18107db96d56Sopenharmony_ci def test_unicode(self): 18117db96d56Sopenharmony_ci endcases = ['', '<\\u>', '<\\\u1234>', '<\n>', 18127db96d56Sopenharmony_ci '<\\>', '<\\\U00012345>', 18137db96d56Sopenharmony_ci # surrogates 18147db96d56Sopenharmony_ci '<\udc80>'] 18157db96d56Sopenharmony_ci for proto in protocols: 18167db96d56Sopenharmony_ci for u in endcases: 18177db96d56Sopenharmony_ci p = self.dumps(u, proto) 18187db96d56Sopenharmony_ci u2 = self.loads(p) 18197db96d56Sopenharmony_ci self.assert_is_copy(u, u2) 18207db96d56Sopenharmony_ci 18217db96d56Sopenharmony_ci def test_unicode_high_plane(self): 18227db96d56Sopenharmony_ci t = '\U00012345' 18237db96d56Sopenharmony_ci for proto in protocols: 18247db96d56Sopenharmony_ci p = self.dumps(t, proto) 18257db96d56Sopenharmony_ci t2 = self.loads(p) 18267db96d56Sopenharmony_ci self.assert_is_copy(t, t2) 18277db96d56Sopenharmony_ci 18287db96d56Sopenharmony_ci def test_bytes(self): 18297db96d56Sopenharmony_ci for proto in protocols: 18307db96d56Sopenharmony_ci for s in b'', b'xyz', b'xyz'*100: 18317db96d56Sopenharmony_ci p = self.dumps(s, proto) 18327db96d56Sopenharmony_ci self.assert_is_copy(s, self.loads(p)) 18337db96d56Sopenharmony_ci for s in [bytes([i]) for i in range(256)]: 18347db96d56Sopenharmony_ci p = self.dumps(s, proto) 18357db96d56Sopenharmony_ci self.assert_is_copy(s, self.loads(p)) 18367db96d56Sopenharmony_ci for s in [bytes([i, i]) for i in range(256)]: 18377db96d56Sopenharmony_ci p = self.dumps(s, proto) 18387db96d56Sopenharmony_ci self.assert_is_copy(s, self.loads(p)) 18397db96d56Sopenharmony_ci 18407db96d56Sopenharmony_ci def test_bytearray(self): 18417db96d56Sopenharmony_ci for proto in protocols: 18427db96d56Sopenharmony_ci for s in b'', b'xyz', b'xyz'*100: 18437db96d56Sopenharmony_ci b = bytearray(s) 18447db96d56Sopenharmony_ci p = self.dumps(b, proto) 18457db96d56Sopenharmony_ci bb = self.loads(p) 18467db96d56Sopenharmony_ci self.assertIsNot(bb, b) 18477db96d56Sopenharmony_ci self.assert_is_copy(b, bb) 18487db96d56Sopenharmony_ci if proto <= 3: 18497db96d56Sopenharmony_ci # bytearray is serialized using a global reference 18507db96d56Sopenharmony_ci self.assertIn(b'bytearray', p) 18517db96d56Sopenharmony_ci self.assertTrue(opcode_in_pickle(pickle.GLOBAL, p)) 18527db96d56Sopenharmony_ci elif proto == 4: 18537db96d56Sopenharmony_ci self.assertIn(b'bytearray', p) 18547db96d56Sopenharmony_ci self.assertTrue(opcode_in_pickle(pickle.STACK_GLOBAL, p)) 18557db96d56Sopenharmony_ci elif proto == 5: 18567db96d56Sopenharmony_ci self.assertNotIn(b'bytearray', p) 18577db96d56Sopenharmony_ci self.assertTrue(opcode_in_pickle(pickle.BYTEARRAY8, p)) 18587db96d56Sopenharmony_ci 18597db96d56Sopenharmony_ci def test_bytearray_memoization_bug(self): 18607db96d56Sopenharmony_ci for proto in protocols: 18617db96d56Sopenharmony_ci for s in b'', b'xyz', b'xyz'*100: 18627db96d56Sopenharmony_ci b = bytearray(s) 18637db96d56Sopenharmony_ci p = self.dumps((b, b), proto) 18647db96d56Sopenharmony_ci b1, b2 = self.loads(p) 18657db96d56Sopenharmony_ci self.assertIs(b1, b2) 18667db96d56Sopenharmony_ci 18677db96d56Sopenharmony_ci def test_ints(self): 18687db96d56Sopenharmony_ci for proto in protocols: 18697db96d56Sopenharmony_ci n = sys.maxsize 18707db96d56Sopenharmony_ci while n: 18717db96d56Sopenharmony_ci for expected in (-n, n): 18727db96d56Sopenharmony_ci s = self.dumps(expected, proto) 18737db96d56Sopenharmony_ci n2 = self.loads(s) 18747db96d56Sopenharmony_ci self.assert_is_copy(expected, n2) 18757db96d56Sopenharmony_ci n = n >> 1 18767db96d56Sopenharmony_ci 18777db96d56Sopenharmony_ci def test_long(self): 18787db96d56Sopenharmony_ci for proto in protocols: 18797db96d56Sopenharmony_ci # 256 bytes is where LONG4 begins. 18807db96d56Sopenharmony_ci for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257: 18817db96d56Sopenharmony_ci nbase = 1 << nbits 18827db96d56Sopenharmony_ci for npos in nbase-1, nbase, nbase+1: 18837db96d56Sopenharmony_ci for n in npos, -npos: 18847db96d56Sopenharmony_ci pickle = self.dumps(n, proto) 18857db96d56Sopenharmony_ci got = self.loads(pickle) 18867db96d56Sopenharmony_ci self.assert_is_copy(n, got) 18877db96d56Sopenharmony_ci # Try a monster. This is quadratic-time in protos 0 & 1, so don't 18887db96d56Sopenharmony_ci # bother with those. 18897db96d56Sopenharmony_ci nbase = int("deadbeeffeedface", 16) 18907db96d56Sopenharmony_ci nbase += nbase << 1000000 18917db96d56Sopenharmony_ci for n in nbase, -nbase: 18927db96d56Sopenharmony_ci p = self.dumps(n, 2) 18937db96d56Sopenharmony_ci got = self.loads(p) 18947db96d56Sopenharmony_ci # assert_is_copy is very expensive here as it precomputes 18957db96d56Sopenharmony_ci # a failure message by computing the repr() of n and got, 18967db96d56Sopenharmony_ci # we just do the check ourselves. 18977db96d56Sopenharmony_ci self.assertIs(type(got), int) 18987db96d56Sopenharmony_ci self.assertEqual(n, got) 18997db96d56Sopenharmony_ci 19007db96d56Sopenharmony_ci def test_float(self): 19017db96d56Sopenharmony_ci test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5, 19027db96d56Sopenharmony_ci 3.14, 263.44582062374053, 6.022e23, 1e30] 19037db96d56Sopenharmony_ci test_values = test_values + [-x for x in test_values] 19047db96d56Sopenharmony_ci for proto in protocols: 19057db96d56Sopenharmony_ci for value in test_values: 19067db96d56Sopenharmony_ci pickle = self.dumps(value, proto) 19077db96d56Sopenharmony_ci got = self.loads(pickle) 19087db96d56Sopenharmony_ci self.assert_is_copy(value, got) 19097db96d56Sopenharmony_ci 19107db96d56Sopenharmony_ci @run_with_locale('LC_ALL', 'de_DE', 'fr_FR') 19117db96d56Sopenharmony_ci def test_float_format(self): 19127db96d56Sopenharmony_ci # make sure that floats are formatted locale independent with proto 0 19137db96d56Sopenharmony_ci self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.') 19147db96d56Sopenharmony_ci 19157db96d56Sopenharmony_ci def test_reduce(self): 19167db96d56Sopenharmony_ci for proto in protocols: 19177db96d56Sopenharmony_ci inst = AAA() 19187db96d56Sopenharmony_ci dumped = self.dumps(inst, proto) 19197db96d56Sopenharmony_ci loaded = self.loads(dumped) 19207db96d56Sopenharmony_ci self.assertEqual(loaded, REDUCE_A) 19217db96d56Sopenharmony_ci 19227db96d56Sopenharmony_ci def test_getinitargs(self): 19237db96d56Sopenharmony_ci for proto in protocols: 19247db96d56Sopenharmony_ci inst = initarg(1, 2) 19257db96d56Sopenharmony_ci dumped = self.dumps(inst, proto) 19267db96d56Sopenharmony_ci loaded = self.loads(dumped) 19277db96d56Sopenharmony_ci self.assert_is_copy(inst, loaded) 19287db96d56Sopenharmony_ci 19297db96d56Sopenharmony_ci def test_metaclass(self): 19307db96d56Sopenharmony_ci a = use_metaclass() 19317db96d56Sopenharmony_ci for proto in protocols: 19327db96d56Sopenharmony_ci s = self.dumps(a, proto) 19337db96d56Sopenharmony_ci b = self.loads(s) 19347db96d56Sopenharmony_ci self.assertEqual(a.__class__, b.__class__) 19357db96d56Sopenharmony_ci 19367db96d56Sopenharmony_ci def test_dynamic_class(self): 19377db96d56Sopenharmony_ci a = create_dynamic_class("my_dynamic_class", (object,)) 19387db96d56Sopenharmony_ci copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__) 19397db96d56Sopenharmony_ci for proto in protocols: 19407db96d56Sopenharmony_ci s = self.dumps(a, proto) 19417db96d56Sopenharmony_ci b = self.loads(s) 19427db96d56Sopenharmony_ci self.assertEqual(a, b) 19437db96d56Sopenharmony_ci self.assertIs(type(a), type(b)) 19447db96d56Sopenharmony_ci 19457db96d56Sopenharmony_ci def test_structseq(self): 19467db96d56Sopenharmony_ci import time 19477db96d56Sopenharmony_ci import os 19487db96d56Sopenharmony_ci 19497db96d56Sopenharmony_ci t = time.localtime() 19507db96d56Sopenharmony_ci for proto in protocols: 19517db96d56Sopenharmony_ci s = self.dumps(t, proto) 19527db96d56Sopenharmony_ci u = self.loads(s) 19537db96d56Sopenharmony_ci self.assert_is_copy(t, u) 19547db96d56Sopenharmony_ci t = os.stat(os.curdir) 19557db96d56Sopenharmony_ci s = self.dumps(t, proto) 19567db96d56Sopenharmony_ci u = self.loads(s) 19577db96d56Sopenharmony_ci self.assert_is_copy(t, u) 19587db96d56Sopenharmony_ci if hasattr(os, "statvfs"): 19597db96d56Sopenharmony_ci t = os.statvfs(os.curdir) 19607db96d56Sopenharmony_ci s = self.dumps(t, proto) 19617db96d56Sopenharmony_ci u = self.loads(s) 19627db96d56Sopenharmony_ci self.assert_is_copy(t, u) 19637db96d56Sopenharmony_ci 19647db96d56Sopenharmony_ci def test_ellipsis(self): 19657db96d56Sopenharmony_ci for proto in protocols: 19667db96d56Sopenharmony_ci s = self.dumps(..., proto) 19677db96d56Sopenharmony_ci u = self.loads(s) 19687db96d56Sopenharmony_ci self.assertIs(..., u) 19697db96d56Sopenharmony_ci 19707db96d56Sopenharmony_ci def test_notimplemented(self): 19717db96d56Sopenharmony_ci for proto in protocols: 19727db96d56Sopenharmony_ci s = self.dumps(NotImplemented, proto) 19737db96d56Sopenharmony_ci u = self.loads(s) 19747db96d56Sopenharmony_ci self.assertIs(NotImplemented, u) 19757db96d56Sopenharmony_ci 19767db96d56Sopenharmony_ci def test_singleton_types(self): 19777db96d56Sopenharmony_ci # Issue #6477: Test that types of built-in singletons can be pickled. 19787db96d56Sopenharmony_ci singletons = [None, ..., NotImplemented] 19797db96d56Sopenharmony_ci for singleton in singletons: 19807db96d56Sopenharmony_ci for proto in protocols: 19817db96d56Sopenharmony_ci s = self.dumps(type(singleton), proto) 19827db96d56Sopenharmony_ci u = self.loads(s) 19837db96d56Sopenharmony_ci self.assertIs(type(singleton), u) 19847db96d56Sopenharmony_ci 19857db96d56Sopenharmony_ci def test_builtin_types(self): 19867db96d56Sopenharmony_ci for t in builtins.__dict__.values(): 19877db96d56Sopenharmony_ci if isinstance(t, type) and not issubclass(t, BaseException): 19887db96d56Sopenharmony_ci for proto in protocols: 19897db96d56Sopenharmony_ci s = self.dumps(t, proto) 19907db96d56Sopenharmony_ci self.assertIs(self.loads(s), t) 19917db96d56Sopenharmony_ci 19927db96d56Sopenharmony_ci def test_builtin_exceptions(self): 19937db96d56Sopenharmony_ci for t in builtins.__dict__.values(): 19947db96d56Sopenharmony_ci if isinstance(t, type) and issubclass(t, BaseException): 19957db96d56Sopenharmony_ci for proto in protocols: 19967db96d56Sopenharmony_ci s = self.dumps(t, proto) 19977db96d56Sopenharmony_ci u = self.loads(s) 19987db96d56Sopenharmony_ci if proto <= 2 and issubclass(t, OSError) and t is not BlockingIOError: 19997db96d56Sopenharmony_ci self.assertIs(u, OSError) 20007db96d56Sopenharmony_ci elif proto <= 2 and issubclass(t, ImportError): 20017db96d56Sopenharmony_ci self.assertIs(u, ImportError) 20027db96d56Sopenharmony_ci else: 20037db96d56Sopenharmony_ci self.assertIs(u, t) 20047db96d56Sopenharmony_ci 20057db96d56Sopenharmony_ci def test_builtin_functions(self): 20067db96d56Sopenharmony_ci for t in builtins.__dict__.values(): 20077db96d56Sopenharmony_ci if isinstance(t, types.BuiltinFunctionType): 20087db96d56Sopenharmony_ci for proto in protocols: 20097db96d56Sopenharmony_ci s = self.dumps(t, proto) 20107db96d56Sopenharmony_ci self.assertIs(self.loads(s), t) 20117db96d56Sopenharmony_ci 20127db96d56Sopenharmony_ci # Tests for protocol 2 20137db96d56Sopenharmony_ci 20147db96d56Sopenharmony_ci def test_proto(self): 20157db96d56Sopenharmony_ci for proto in protocols: 20167db96d56Sopenharmony_ci pickled = self.dumps(None, proto) 20177db96d56Sopenharmony_ci if proto >= 2: 20187db96d56Sopenharmony_ci proto_header = pickle.PROTO + bytes([proto]) 20197db96d56Sopenharmony_ci self.assertTrue(pickled.startswith(proto_header)) 20207db96d56Sopenharmony_ci else: 20217db96d56Sopenharmony_ci self.assertEqual(count_opcode(pickle.PROTO, pickled), 0) 20227db96d56Sopenharmony_ci 20237db96d56Sopenharmony_ci oob = protocols[-1] + 1 # a future protocol 20247db96d56Sopenharmony_ci build_none = pickle.NONE + pickle.STOP 20257db96d56Sopenharmony_ci badpickle = pickle.PROTO + bytes([oob]) + build_none 20267db96d56Sopenharmony_ci try: 20277db96d56Sopenharmony_ci self.loads(badpickle) 20287db96d56Sopenharmony_ci except ValueError as err: 20297db96d56Sopenharmony_ci self.assertIn("unsupported pickle protocol", str(err)) 20307db96d56Sopenharmony_ci else: 20317db96d56Sopenharmony_ci self.fail("expected bad protocol number to raise ValueError") 20327db96d56Sopenharmony_ci 20337db96d56Sopenharmony_ci def test_long1(self): 20347db96d56Sopenharmony_ci x = 12345678910111213141516178920 20357db96d56Sopenharmony_ci for proto in protocols: 20367db96d56Sopenharmony_ci s = self.dumps(x, proto) 20377db96d56Sopenharmony_ci y = self.loads(s) 20387db96d56Sopenharmony_ci self.assert_is_copy(x, y) 20397db96d56Sopenharmony_ci self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2) 20407db96d56Sopenharmony_ci 20417db96d56Sopenharmony_ci def test_long4(self): 20427db96d56Sopenharmony_ci x = 12345678910111213141516178920 << (256*8) 20437db96d56Sopenharmony_ci for proto in protocols: 20447db96d56Sopenharmony_ci s = self.dumps(x, proto) 20457db96d56Sopenharmony_ci y = self.loads(s) 20467db96d56Sopenharmony_ci self.assert_is_copy(x, y) 20477db96d56Sopenharmony_ci self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2) 20487db96d56Sopenharmony_ci 20497db96d56Sopenharmony_ci def test_short_tuples(self): 20507db96d56Sopenharmony_ci # Map (proto, len(tuple)) to expected opcode. 20517db96d56Sopenharmony_ci expected_opcode = {(0, 0): pickle.TUPLE, 20527db96d56Sopenharmony_ci (0, 1): pickle.TUPLE, 20537db96d56Sopenharmony_ci (0, 2): pickle.TUPLE, 20547db96d56Sopenharmony_ci (0, 3): pickle.TUPLE, 20557db96d56Sopenharmony_ci (0, 4): pickle.TUPLE, 20567db96d56Sopenharmony_ci 20577db96d56Sopenharmony_ci (1, 0): pickle.EMPTY_TUPLE, 20587db96d56Sopenharmony_ci (1, 1): pickle.TUPLE, 20597db96d56Sopenharmony_ci (1, 2): pickle.TUPLE, 20607db96d56Sopenharmony_ci (1, 3): pickle.TUPLE, 20617db96d56Sopenharmony_ci (1, 4): pickle.TUPLE, 20627db96d56Sopenharmony_ci 20637db96d56Sopenharmony_ci (2, 0): pickle.EMPTY_TUPLE, 20647db96d56Sopenharmony_ci (2, 1): pickle.TUPLE1, 20657db96d56Sopenharmony_ci (2, 2): pickle.TUPLE2, 20667db96d56Sopenharmony_ci (2, 3): pickle.TUPLE3, 20677db96d56Sopenharmony_ci (2, 4): pickle.TUPLE, 20687db96d56Sopenharmony_ci 20697db96d56Sopenharmony_ci (3, 0): pickle.EMPTY_TUPLE, 20707db96d56Sopenharmony_ci (3, 1): pickle.TUPLE1, 20717db96d56Sopenharmony_ci (3, 2): pickle.TUPLE2, 20727db96d56Sopenharmony_ci (3, 3): pickle.TUPLE3, 20737db96d56Sopenharmony_ci (3, 4): pickle.TUPLE, 20747db96d56Sopenharmony_ci } 20757db96d56Sopenharmony_ci a = () 20767db96d56Sopenharmony_ci b = (1,) 20777db96d56Sopenharmony_ci c = (1, 2) 20787db96d56Sopenharmony_ci d = (1, 2, 3) 20797db96d56Sopenharmony_ci e = (1, 2, 3, 4) 20807db96d56Sopenharmony_ci for proto in protocols: 20817db96d56Sopenharmony_ci for x in a, b, c, d, e: 20827db96d56Sopenharmony_ci s = self.dumps(x, proto) 20837db96d56Sopenharmony_ci y = self.loads(s) 20847db96d56Sopenharmony_ci self.assert_is_copy(x, y) 20857db96d56Sopenharmony_ci expected = expected_opcode[min(proto, 3), len(x)] 20867db96d56Sopenharmony_ci self.assertTrue(opcode_in_pickle(expected, s)) 20877db96d56Sopenharmony_ci 20887db96d56Sopenharmony_ci def test_singletons(self): 20897db96d56Sopenharmony_ci # Map (proto, singleton) to expected opcode. 20907db96d56Sopenharmony_ci expected_opcode = {(0, None): pickle.NONE, 20917db96d56Sopenharmony_ci (1, None): pickle.NONE, 20927db96d56Sopenharmony_ci (2, None): pickle.NONE, 20937db96d56Sopenharmony_ci (3, None): pickle.NONE, 20947db96d56Sopenharmony_ci 20957db96d56Sopenharmony_ci (0, True): pickle.INT, 20967db96d56Sopenharmony_ci (1, True): pickle.INT, 20977db96d56Sopenharmony_ci (2, True): pickle.NEWTRUE, 20987db96d56Sopenharmony_ci (3, True): pickle.NEWTRUE, 20997db96d56Sopenharmony_ci 21007db96d56Sopenharmony_ci (0, False): pickle.INT, 21017db96d56Sopenharmony_ci (1, False): pickle.INT, 21027db96d56Sopenharmony_ci (2, False): pickle.NEWFALSE, 21037db96d56Sopenharmony_ci (3, False): pickle.NEWFALSE, 21047db96d56Sopenharmony_ci } 21057db96d56Sopenharmony_ci for proto in protocols: 21067db96d56Sopenharmony_ci for x in None, False, True: 21077db96d56Sopenharmony_ci s = self.dumps(x, proto) 21087db96d56Sopenharmony_ci y = self.loads(s) 21097db96d56Sopenharmony_ci self.assertTrue(x is y, (proto, x, s, y)) 21107db96d56Sopenharmony_ci expected = expected_opcode[min(proto, 3), x] 21117db96d56Sopenharmony_ci self.assertTrue(opcode_in_pickle(expected, s)) 21127db96d56Sopenharmony_ci 21137db96d56Sopenharmony_ci def test_newobj_tuple(self): 21147db96d56Sopenharmony_ci x = MyTuple([1, 2, 3]) 21157db96d56Sopenharmony_ci x.foo = 42 21167db96d56Sopenharmony_ci x.bar = "hello" 21177db96d56Sopenharmony_ci for proto in protocols: 21187db96d56Sopenharmony_ci s = self.dumps(x, proto) 21197db96d56Sopenharmony_ci y = self.loads(s) 21207db96d56Sopenharmony_ci self.assert_is_copy(x, y) 21217db96d56Sopenharmony_ci 21227db96d56Sopenharmony_ci def test_newobj_list(self): 21237db96d56Sopenharmony_ci x = MyList([1, 2, 3]) 21247db96d56Sopenharmony_ci x.foo = 42 21257db96d56Sopenharmony_ci x.bar = "hello" 21267db96d56Sopenharmony_ci for proto in protocols: 21277db96d56Sopenharmony_ci s = self.dumps(x, proto) 21287db96d56Sopenharmony_ci y = self.loads(s) 21297db96d56Sopenharmony_ci self.assert_is_copy(x, y) 21307db96d56Sopenharmony_ci 21317db96d56Sopenharmony_ci def test_newobj_generic(self): 21327db96d56Sopenharmony_ci for proto in protocols: 21337db96d56Sopenharmony_ci for C in myclasses: 21347db96d56Sopenharmony_ci B = C.__base__ 21357db96d56Sopenharmony_ci x = C(C.sample) 21367db96d56Sopenharmony_ci x.foo = 42 21377db96d56Sopenharmony_ci s = self.dumps(x, proto) 21387db96d56Sopenharmony_ci y = self.loads(s) 21397db96d56Sopenharmony_ci detail = (proto, C, B, x, y, type(y)) 21407db96d56Sopenharmony_ci self.assert_is_copy(x, y) # XXX revisit 21417db96d56Sopenharmony_ci self.assertEqual(B(x), B(y), detail) 21427db96d56Sopenharmony_ci self.assertEqual(x.__dict__, y.__dict__, detail) 21437db96d56Sopenharmony_ci 21447db96d56Sopenharmony_ci def test_newobj_proxies(self): 21457db96d56Sopenharmony_ci # NEWOBJ should use the __class__ rather than the raw type 21467db96d56Sopenharmony_ci classes = myclasses[:] 21477db96d56Sopenharmony_ci # Cannot create weakproxies to these classes 21487db96d56Sopenharmony_ci for c in (MyInt, MyTuple): 21497db96d56Sopenharmony_ci classes.remove(c) 21507db96d56Sopenharmony_ci for proto in protocols: 21517db96d56Sopenharmony_ci for C in classes: 21527db96d56Sopenharmony_ci B = C.__base__ 21537db96d56Sopenharmony_ci x = C(C.sample) 21547db96d56Sopenharmony_ci x.foo = 42 21557db96d56Sopenharmony_ci p = weakref.proxy(x) 21567db96d56Sopenharmony_ci s = self.dumps(p, proto) 21577db96d56Sopenharmony_ci y = self.loads(s) 21587db96d56Sopenharmony_ci self.assertEqual(type(y), type(x)) # rather than type(p) 21597db96d56Sopenharmony_ci detail = (proto, C, B, x, y, type(y)) 21607db96d56Sopenharmony_ci self.assertEqual(B(x), B(y), detail) 21617db96d56Sopenharmony_ci self.assertEqual(x.__dict__, y.__dict__, detail) 21627db96d56Sopenharmony_ci 21637db96d56Sopenharmony_ci def test_newobj_overridden_new(self): 21647db96d56Sopenharmony_ci # Test that Python class with C implemented __new__ is pickleable 21657db96d56Sopenharmony_ci for proto in protocols: 21667db96d56Sopenharmony_ci x = MyIntWithNew2(1) 21677db96d56Sopenharmony_ci x.foo = 42 21687db96d56Sopenharmony_ci s = self.dumps(x, proto) 21697db96d56Sopenharmony_ci y = self.loads(s) 21707db96d56Sopenharmony_ci self.assertIs(type(y), MyIntWithNew2) 21717db96d56Sopenharmony_ci self.assertEqual(int(y), 1) 21727db96d56Sopenharmony_ci self.assertEqual(y.foo, 42) 21737db96d56Sopenharmony_ci 21747db96d56Sopenharmony_ci def test_newobj_not_class(self): 21757db96d56Sopenharmony_ci # Issue 24552 21767db96d56Sopenharmony_ci global SimpleNewObj 21777db96d56Sopenharmony_ci save = SimpleNewObj 21787db96d56Sopenharmony_ci o = SimpleNewObj.__new__(SimpleNewObj) 21797db96d56Sopenharmony_ci b = self.dumps(o, 4) 21807db96d56Sopenharmony_ci try: 21817db96d56Sopenharmony_ci SimpleNewObj = 42 21827db96d56Sopenharmony_ci self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b) 21837db96d56Sopenharmony_ci finally: 21847db96d56Sopenharmony_ci SimpleNewObj = save 21857db96d56Sopenharmony_ci 21867db96d56Sopenharmony_ci # Register a type with copyreg, with extension code extcode. Pickle 21877db96d56Sopenharmony_ci # an object of that type. Check that the resulting pickle uses opcode 21887db96d56Sopenharmony_ci # (EXT[124]) under proto 2, and not in proto 1. 21897db96d56Sopenharmony_ci 21907db96d56Sopenharmony_ci def produce_global_ext(self, extcode, opcode): 21917db96d56Sopenharmony_ci e = ExtensionSaver(extcode) 21927db96d56Sopenharmony_ci try: 21937db96d56Sopenharmony_ci copyreg.add_extension(__name__, "MyList", extcode) 21947db96d56Sopenharmony_ci x = MyList([1, 2, 3]) 21957db96d56Sopenharmony_ci x.foo = 42 21967db96d56Sopenharmony_ci x.bar = "hello" 21977db96d56Sopenharmony_ci 21987db96d56Sopenharmony_ci # Dump using protocol 1 for comparison. 21997db96d56Sopenharmony_ci s1 = self.dumps(x, 1) 22007db96d56Sopenharmony_ci self.assertIn(__name__.encode("utf-8"), s1) 22017db96d56Sopenharmony_ci self.assertIn(b"MyList", s1) 22027db96d56Sopenharmony_ci self.assertFalse(opcode_in_pickle(opcode, s1)) 22037db96d56Sopenharmony_ci 22047db96d56Sopenharmony_ci y = self.loads(s1) 22057db96d56Sopenharmony_ci self.assert_is_copy(x, y) 22067db96d56Sopenharmony_ci 22077db96d56Sopenharmony_ci # Dump using protocol 2 for test. 22087db96d56Sopenharmony_ci s2 = self.dumps(x, 2) 22097db96d56Sopenharmony_ci self.assertNotIn(__name__.encode("utf-8"), s2) 22107db96d56Sopenharmony_ci self.assertNotIn(b"MyList", s2) 22117db96d56Sopenharmony_ci self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2)) 22127db96d56Sopenharmony_ci 22137db96d56Sopenharmony_ci y = self.loads(s2) 22147db96d56Sopenharmony_ci self.assert_is_copy(x, y) 22157db96d56Sopenharmony_ci finally: 22167db96d56Sopenharmony_ci e.restore() 22177db96d56Sopenharmony_ci 22187db96d56Sopenharmony_ci def test_global_ext1(self): 22197db96d56Sopenharmony_ci self.produce_global_ext(0x00000001, pickle.EXT1) # smallest EXT1 code 22207db96d56Sopenharmony_ci self.produce_global_ext(0x000000ff, pickle.EXT1) # largest EXT1 code 22217db96d56Sopenharmony_ci 22227db96d56Sopenharmony_ci def test_global_ext2(self): 22237db96d56Sopenharmony_ci self.produce_global_ext(0x00000100, pickle.EXT2) # smallest EXT2 code 22247db96d56Sopenharmony_ci self.produce_global_ext(0x0000ffff, pickle.EXT2) # largest EXT2 code 22257db96d56Sopenharmony_ci self.produce_global_ext(0x0000abcd, pickle.EXT2) # check endianness 22267db96d56Sopenharmony_ci 22277db96d56Sopenharmony_ci def test_global_ext4(self): 22287db96d56Sopenharmony_ci self.produce_global_ext(0x00010000, pickle.EXT4) # smallest EXT4 code 22297db96d56Sopenharmony_ci self.produce_global_ext(0x7fffffff, pickle.EXT4) # largest EXT4 code 22307db96d56Sopenharmony_ci self.produce_global_ext(0x12abcdef, pickle.EXT4) # check endianness 22317db96d56Sopenharmony_ci 22327db96d56Sopenharmony_ci def test_list_chunking(self): 22337db96d56Sopenharmony_ci n = 10 # too small to chunk 22347db96d56Sopenharmony_ci x = list(range(n)) 22357db96d56Sopenharmony_ci for proto in protocols: 22367db96d56Sopenharmony_ci s = self.dumps(x, proto) 22377db96d56Sopenharmony_ci y = self.loads(s) 22387db96d56Sopenharmony_ci self.assert_is_copy(x, y) 22397db96d56Sopenharmony_ci num_appends = count_opcode(pickle.APPENDS, s) 22407db96d56Sopenharmony_ci self.assertEqual(num_appends, proto > 0) 22417db96d56Sopenharmony_ci 22427db96d56Sopenharmony_ci n = 2500 # expect at least two chunks when proto > 0 22437db96d56Sopenharmony_ci x = list(range(n)) 22447db96d56Sopenharmony_ci for proto in protocols: 22457db96d56Sopenharmony_ci s = self.dumps(x, proto) 22467db96d56Sopenharmony_ci y = self.loads(s) 22477db96d56Sopenharmony_ci self.assert_is_copy(x, y) 22487db96d56Sopenharmony_ci num_appends = count_opcode(pickle.APPENDS, s) 22497db96d56Sopenharmony_ci if proto == 0: 22507db96d56Sopenharmony_ci self.assertEqual(num_appends, 0) 22517db96d56Sopenharmony_ci else: 22527db96d56Sopenharmony_ci self.assertTrue(num_appends >= 2) 22537db96d56Sopenharmony_ci 22547db96d56Sopenharmony_ci def test_dict_chunking(self): 22557db96d56Sopenharmony_ci n = 10 # too small to chunk 22567db96d56Sopenharmony_ci x = dict.fromkeys(range(n)) 22577db96d56Sopenharmony_ci for proto in protocols: 22587db96d56Sopenharmony_ci s = self.dumps(x, proto) 22597db96d56Sopenharmony_ci self.assertIsInstance(s, bytes_types) 22607db96d56Sopenharmony_ci y = self.loads(s) 22617db96d56Sopenharmony_ci self.assert_is_copy(x, y) 22627db96d56Sopenharmony_ci num_setitems = count_opcode(pickle.SETITEMS, s) 22637db96d56Sopenharmony_ci self.assertEqual(num_setitems, proto > 0) 22647db96d56Sopenharmony_ci 22657db96d56Sopenharmony_ci n = 2500 # expect at least two chunks when proto > 0 22667db96d56Sopenharmony_ci x = dict.fromkeys(range(n)) 22677db96d56Sopenharmony_ci for proto in protocols: 22687db96d56Sopenharmony_ci s = self.dumps(x, proto) 22697db96d56Sopenharmony_ci y = self.loads(s) 22707db96d56Sopenharmony_ci self.assert_is_copy(x, y) 22717db96d56Sopenharmony_ci num_setitems = count_opcode(pickle.SETITEMS, s) 22727db96d56Sopenharmony_ci if proto == 0: 22737db96d56Sopenharmony_ci self.assertEqual(num_setitems, 0) 22747db96d56Sopenharmony_ci else: 22757db96d56Sopenharmony_ci self.assertTrue(num_setitems >= 2) 22767db96d56Sopenharmony_ci 22777db96d56Sopenharmony_ci def test_set_chunking(self): 22787db96d56Sopenharmony_ci n = 10 # too small to chunk 22797db96d56Sopenharmony_ci x = set(range(n)) 22807db96d56Sopenharmony_ci for proto in protocols: 22817db96d56Sopenharmony_ci s = self.dumps(x, proto) 22827db96d56Sopenharmony_ci y = self.loads(s) 22837db96d56Sopenharmony_ci self.assert_is_copy(x, y) 22847db96d56Sopenharmony_ci num_additems = count_opcode(pickle.ADDITEMS, s) 22857db96d56Sopenharmony_ci if proto < 4: 22867db96d56Sopenharmony_ci self.assertEqual(num_additems, 0) 22877db96d56Sopenharmony_ci else: 22887db96d56Sopenharmony_ci self.assertEqual(num_additems, 1) 22897db96d56Sopenharmony_ci 22907db96d56Sopenharmony_ci n = 2500 # expect at least two chunks when proto >= 4 22917db96d56Sopenharmony_ci x = set(range(n)) 22927db96d56Sopenharmony_ci for proto in protocols: 22937db96d56Sopenharmony_ci s = self.dumps(x, proto) 22947db96d56Sopenharmony_ci y = self.loads(s) 22957db96d56Sopenharmony_ci self.assert_is_copy(x, y) 22967db96d56Sopenharmony_ci num_additems = count_opcode(pickle.ADDITEMS, s) 22977db96d56Sopenharmony_ci if proto < 4: 22987db96d56Sopenharmony_ci self.assertEqual(num_additems, 0) 22997db96d56Sopenharmony_ci else: 23007db96d56Sopenharmony_ci self.assertGreaterEqual(num_additems, 2) 23017db96d56Sopenharmony_ci 23027db96d56Sopenharmony_ci def test_simple_newobj(self): 23037db96d56Sopenharmony_ci x = SimpleNewObj.__new__(SimpleNewObj, 0xface) # avoid __init__ 23047db96d56Sopenharmony_ci x.abc = 666 23057db96d56Sopenharmony_ci for proto in protocols: 23067db96d56Sopenharmony_ci with self.subTest(proto=proto): 23077db96d56Sopenharmony_ci s = self.dumps(x, proto) 23087db96d56Sopenharmony_ci if proto < 1: 23097db96d56Sopenharmony_ci self.assertIn(b'\nI64206', s) # INT 23107db96d56Sopenharmony_ci else: 23117db96d56Sopenharmony_ci self.assertIn(b'M\xce\xfa', s) # BININT2 23127db96d56Sopenharmony_ci self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), 23137db96d56Sopenharmony_ci 2 <= proto) 23147db96d56Sopenharmony_ci self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s)) 23157db96d56Sopenharmony_ci y = self.loads(s) # will raise TypeError if __init__ called 23167db96d56Sopenharmony_ci self.assert_is_copy(x, y) 23177db96d56Sopenharmony_ci 23187db96d56Sopenharmony_ci def test_complex_newobj(self): 23197db96d56Sopenharmony_ci x = ComplexNewObj.__new__(ComplexNewObj, 0xface) # avoid __init__ 23207db96d56Sopenharmony_ci x.abc = 666 23217db96d56Sopenharmony_ci for proto in protocols: 23227db96d56Sopenharmony_ci with self.subTest(proto=proto): 23237db96d56Sopenharmony_ci s = self.dumps(x, proto) 23247db96d56Sopenharmony_ci if proto < 1: 23257db96d56Sopenharmony_ci self.assertIn(b'\nI64206', s) # INT 23267db96d56Sopenharmony_ci elif proto < 2: 23277db96d56Sopenharmony_ci self.assertIn(b'M\xce\xfa', s) # BININT2 23287db96d56Sopenharmony_ci elif proto < 4: 23297db96d56Sopenharmony_ci self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE 23307db96d56Sopenharmony_ci else: 23317db96d56Sopenharmony_ci self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE 23327db96d56Sopenharmony_ci self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s), 23337db96d56Sopenharmony_ci 2 <= proto) 23347db96d56Sopenharmony_ci self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s)) 23357db96d56Sopenharmony_ci y = self.loads(s) # will raise TypeError if __init__ called 23367db96d56Sopenharmony_ci self.assert_is_copy(x, y) 23377db96d56Sopenharmony_ci 23387db96d56Sopenharmony_ci def test_complex_newobj_ex(self): 23397db96d56Sopenharmony_ci x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface) # avoid __init__ 23407db96d56Sopenharmony_ci x.abc = 666 23417db96d56Sopenharmony_ci for proto in protocols: 23427db96d56Sopenharmony_ci with self.subTest(proto=proto): 23437db96d56Sopenharmony_ci s = self.dumps(x, proto) 23447db96d56Sopenharmony_ci if proto < 1: 23457db96d56Sopenharmony_ci self.assertIn(b'\nI64206', s) # INT 23467db96d56Sopenharmony_ci elif proto < 2: 23477db96d56Sopenharmony_ci self.assertIn(b'M\xce\xfa', s) # BININT2 23487db96d56Sopenharmony_ci elif proto < 4: 23497db96d56Sopenharmony_ci self.assertIn(b'X\x04\x00\x00\x00FACE', s) # BINUNICODE 23507db96d56Sopenharmony_ci else: 23517db96d56Sopenharmony_ci self.assertIn(b'\x8c\x04FACE', s) # SHORT_BINUNICODE 23527db96d56Sopenharmony_ci self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s)) 23537db96d56Sopenharmony_ci self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s), 23547db96d56Sopenharmony_ci 4 <= proto) 23557db96d56Sopenharmony_ci y = self.loads(s) # will raise TypeError if __init__ called 23567db96d56Sopenharmony_ci self.assert_is_copy(x, y) 23577db96d56Sopenharmony_ci 23587db96d56Sopenharmony_ci def test_newobj_list_slots(self): 23597db96d56Sopenharmony_ci x = SlotList([1, 2, 3]) 23607db96d56Sopenharmony_ci x.foo = 42 23617db96d56Sopenharmony_ci x.bar = "hello" 23627db96d56Sopenharmony_ci s = self.dumps(x, 2) 23637db96d56Sopenharmony_ci y = self.loads(s) 23647db96d56Sopenharmony_ci self.assert_is_copy(x, y) 23657db96d56Sopenharmony_ci 23667db96d56Sopenharmony_ci def test_reduce_overrides_default_reduce_ex(self): 23677db96d56Sopenharmony_ci for proto in protocols: 23687db96d56Sopenharmony_ci x = REX_one() 23697db96d56Sopenharmony_ci self.assertEqual(x._reduce_called, 0) 23707db96d56Sopenharmony_ci s = self.dumps(x, proto) 23717db96d56Sopenharmony_ci self.assertEqual(x._reduce_called, 1) 23727db96d56Sopenharmony_ci y = self.loads(s) 23737db96d56Sopenharmony_ci self.assertEqual(y._reduce_called, 0) 23747db96d56Sopenharmony_ci 23757db96d56Sopenharmony_ci def test_reduce_ex_called(self): 23767db96d56Sopenharmony_ci for proto in protocols: 23777db96d56Sopenharmony_ci x = REX_two() 23787db96d56Sopenharmony_ci self.assertEqual(x._proto, None) 23797db96d56Sopenharmony_ci s = self.dumps(x, proto) 23807db96d56Sopenharmony_ci self.assertEqual(x._proto, proto) 23817db96d56Sopenharmony_ci y = self.loads(s) 23827db96d56Sopenharmony_ci self.assertEqual(y._proto, None) 23837db96d56Sopenharmony_ci 23847db96d56Sopenharmony_ci def test_reduce_ex_overrides_reduce(self): 23857db96d56Sopenharmony_ci for proto in protocols: 23867db96d56Sopenharmony_ci x = REX_three() 23877db96d56Sopenharmony_ci self.assertEqual(x._proto, None) 23887db96d56Sopenharmony_ci s = self.dumps(x, proto) 23897db96d56Sopenharmony_ci self.assertEqual(x._proto, proto) 23907db96d56Sopenharmony_ci y = self.loads(s) 23917db96d56Sopenharmony_ci self.assertEqual(y._proto, None) 23927db96d56Sopenharmony_ci 23937db96d56Sopenharmony_ci def test_reduce_ex_calls_base(self): 23947db96d56Sopenharmony_ci for proto in protocols: 23957db96d56Sopenharmony_ci x = REX_four() 23967db96d56Sopenharmony_ci self.assertEqual(x._proto, None) 23977db96d56Sopenharmony_ci s = self.dumps(x, proto) 23987db96d56Sopenharmony_ci self.assertEqual(x._proto, proto) 23997db96d56Sopenharmony_ci y = self.loads(s) 24007db96d56Sopenharmony_ci self.assertEqual(y._proto, proto) 24017db96d56Sopenharmony_ci 24027db96d56Sopenharmony_ci def test_reduce_calls_base(self): 24037db96d56Sopenharmony_ci for proto in protocols: 24047db96d56Sopenharmony_ci x = REX_five() 24057db96d56Sopenharmony_ci self.assertEqual(x._reduce_called, 0) 24067db96d56Sopenharmony_ci s = self.dumps(x, proto) 24077db96d56Sopenharmony_ci self.assertEqual(x._reduce_called, 1) 24087db96d56Sopenharmony_ci y = self.loads(s) 24097db96d56Sopenharmony_ci self.assertEqual(y._reduce_called, 1) 24107db96d56Sopenharmony_ci 24117db96d56Sopenharmony_ci @no_tracing 24127db96d56Sopenharmony_ci def test_bad_getattr(self): 24137db96d56Sopenharmony_ci # Issue #3514: crash when there is an infinite loop in __getattr__ 24147db96d56Sopenharmony_ci x = BadGetattr() 24157db96d56Sopenharmony_ci for proto in range(2): 24167db96d56Sopenharmony_ci with support.infinite_recursion(): 24177db96d56Sopenharmony_ci self.assertRaises(RuntimeError, self.dumps, x, proto) 24187db96d56Sopenharmony_ci for proto in range(2, pickle.HIGHEST_PROTOCOL + 1): 24197db96d56Sopenharmony_ci s = self.dumps(x, proto) 24207db96d56Sopenharmony_ci 24217db96d56Sopenharmony_ci def test_reduce_bad_iterator(self): 24227db96d56Sopenharmony_ci # Issue4176: crash when 4th and 5th items of __reduce__() 24237db96d56Sopenharmony_ci # are not iterators 24247db96d56Sopenharmony_ci class C(object): 24257db96d56Sopenharmony_ci def __reduce__(self): 24267db96d56Sopenharmony_ci # 4th item is not an iterator 24277db96d56Sopenharmony_ci return list, (), None, [], None 24287db96d56Sopenharmony_ci class D(object): 24297db96d56Sopenharmony_ci def __reduce__(self): 24307db96d56Sopenharmony_ci # 5th item is not an iterator 24317db96d56Sopenharmony_ci return dict, (), None, None, [] 24327db96d56Sopenharmony_ci 24337db96d56Sopenharmony_ci # Python implementation is less strict and also accepts iterables. 24347db96d56Sopenharmony_ci for proto in protocols: 24357db96d56Sopenharmony_ci try: 24367db96d56Sopenharmony_ci self.dumps(C(), proto) 24377db96d56Sopenharmony_ci except pickle.PicklingError: 24387db96d56Sopenharmony_ci pass 24397db96d56Sopenharmony_ci try: 24407db96d56Sopenharmony_ci self.dumps(D(), proto) 24417db96d56Sopenharmony_ci except pickle.PicklingError: 24427db96d56Sopenharmony_ci pass 24437db96d56Sopenharmony_ci 24447db96d56Sopenharmony_ci def test_many_puts_and_gets(self): 24457db96d56Sopenharmony_ci # Test that internal data structures correctly deal with lots of 24467db96d56Sopenharmony_ci # puts/gets. 24477db96d56Sopenharmony_ci keys = ("aaa" + str(i) for i in range(100)) 24487db96d56Sopenharmony_ci large_dict = dict((k, [4, 5, 6]) for k in keys) 24497db96d56Sopenharmony_ci obj = [dict(large_dict), dict(large_dict), dict(large_dict)] 24507db96d56Sopenharmony_ci 24517db96d56Sopenharmony_ci for proto in protocols: 24527db96d56Sopenharmony_ci with self.subTest(proto=proto): 24537db96d56Sopenharmony_ci dumped = self.dumps(obj, proto) 24547db96d56Sopenharmony_ci loaded = self.loads(dumped) 24557db96d56Sopenharmony_ci self.assert_is_copy(obj, loaded) 24567db96d56Sopenharmony_ci 24577db96d56Sopenharmony_ci def test_attribute_name_interning(self): 24587db96d56Sopenharmony_ci # Test that attribute names of pickled objects are interned when 24597db96d56Sopenharmony_ci # unpickling. 24607db96d56Sopenharmony_ci for proto in protocols: 24617db96d56Sopenharmony_ci x = C() 24627db96d56Sopenharmony_ci x.foo = 42 24637db96d56Sopenharmony_ci x.bar = "hello" 24647db96d56Sopenharmony_ci s = self.dumps(x, proto) 24657db96d56Sopenharmony_ci y = self.loads(s) 24667db96d56Sopenharmony_ci x_keys = sorted(x.__dict__) 24677db96d56Sopenharmony_ci y_keys = sorted(y.__dict__) 24687db96d56Sopenharmony_ci for x_key, y_key in zip(x_keys, y_keys): 24697db96d56Sopenharmony_ci self.assertIs(x_key, y_key) 24707db96d56Sopenharmony_ci 24717db96d56Sopenharmony_ci def test_pickle_to_2x(self): 24727db96d56Sopenharmony_ci # Pickle non-trivial data with protocol 2, expecting that it yields 24737db96d56Sopenharmony_ci # the same result as Python 2.x did. 24747db96d56Sopenharmony_ci # NOTE: this test is a bit too strong since we can produce different 24757db96d56Sopenharmony_ci # bytecode that 2.x will still understand. 24767db96d56Sopenharmony_ci dumped = self.dumps(range(5), 2) 24777db96d56Sopenharmony_ci self.assertEqual(dumped, DATA_XRANGE) 24787db96d56Sopenharmony_ci dumped = self.dumps(set([3]), 2) 24797db96d56Sopenharmony_ci self.assertEqual(dumped, DATA_SET2) 24807db96d56Sopenharmony_ci 24817db96d56Sopenharmony_ci def test_large_pickles(self): 24827db96d56Sopenharmony_ci # Test the correctness of internal buffering routines when handling 24837db96d56Sopenharmony_ci # large data. 24847db96d56Sopenharmony_ci for proto in protocols: 24857db96d56Sopenharmony_ci data = (1, min, b'xy' * (30 * 1024), len) 24867db96d56Sopenharmony_ci dumped = self.dumps(data, proto) 24877db96d56Sopenharmony_ci loaded = self.loads(dumped) 24887db96d56Sopenharmony_ci self.assertEqual(len(loaded), len(data)) 24897db96d56Sopenharmony_ci self.assertEqual(loaded, data) 24907db96d56Sopenharmony_ci 24917db96d56Sopenharmony_ci def test_int_pickling_efficiency(self): 24927db96d56Sopenharmony_ci # Test compacity of int representation (see issue #12744) 24937db96d56Sopenharmony_ci for proto in protocols: 24947db96d56Sopenharmony_ci with self.subTest(proto=proto): 24957db96d56Sopenharmony_ci pickles = [self.dumps(2**n, proto) for n in range(70)] 24967db96d56Sopenharmony_ci sizes = list(map(len, pickles)) 24977db96d56Sopenharmony_ci # the size function is monotonic 24987db96d56Sopenharmony_ci self.assertEqual(sorted(sizes), sizes) 24997db96d56Sopenharmony_ci if proto >= 2: 25007db96d56Sopenharmony_ci for p in pickles: 25017db96d56Sopenharmony_ci self.assertFalse(opcode_in_pickle(pickle.LONG, p)) 25027db96d56Sopenharmony_ci 25037db96d56Sopenharmony_ci def _check_pickling_with_opcode(self, obj, opcode, proto): 25047db96d56Sopenharmony_ci pickled = self.dumps(obj, proto) 25057db96d56Sopenharmony_ci self.assertTrue(opcode_in_pickle(opcode, pickled)) 25067db96d56Sopenharmony_ci unpickled = self.loads(pickled) 25077db96d56Sopenharmony_ci self.assertEqual(obj, unpickled) 25087db96d56Sopenharmony_ci 25097db96d56Sopenharmony_ci def test_appends_on_non_lists(self): 25107db96d56Sopenharmony_ci # Issue #17720 25117db96d56Sopenharmony_ci obj = REX_six([1, 2, 3]) 25127db96d56Sopenharmony_ci for proto in protocols: 25137db96d56Sopenharmony_ci if proto == 0: 25147db96d56Sopenharmony_ci self._check_pickling_with_opcode(obj, pickle.APPEND, proto) 25157db96d56Sopenharmony_ci else: 25167db96d56Sopenharmony_ci self._check_pickling_with_opcode(obj, pickle.APPENDS, proto) 25177db96d56Sopenharmony_ci 25187db96d56Sopenharmony_ci def test_setitems_on_non_dicts(self): 25197db96d56Sopenharmony_ci obj = REX_seven({1: -1, 2: -2, 3: -3}) 25207db96d56Sopenharmony_ci for proto in protocols: 25217db96d56Sopenharmony_ci if proto == 0: 25227db96d56Sopenharmony_ci self._check_pickling_with_opcode(obj, pickle.SETITEM, proto) 25237db96d56Sopenharmony_ci else: 25247db96d56Sopenharmony_ci self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto) 25257db96d56Sopenharmony_ci 25267db96d56Sopenharmony_ci # Exercise framing (proto >= 4) for significant workloads 25277db96d56Sopenharmony_ci 25287db96d56Sopenharmony_ci FRAME_SIZE_MIN = 4 25297db96d56Sopenharmony_ci FRAME_SIZE_TARGET = 64 * 1024 25307db96d56Sopenharmony_ci 25317db96d56Sopenharmony_ci def check_frame_opcodes(self, pickled): 25327db96d56Sopenharmony_ci """ 25337db96d56Sopenharmony_ci Check the arguments of FRAME opcodes in a protocol 4+ pickle. 25347db96d56Sopenharmony_ci 25357db96d56Sopenharmony_ci Note that binary objects that are larger than FRAME_SIZE_TARGET are not 25367db96d56Sopenharmony_ci framed by default and are therefore considered a frame by themselves in 25377db96d56Sopenharmony_ci the following consistency check. 25387db96d56Sopenharmony_ci """ 25397db96d56Sopenharmony_ci frame_end = frameless_start = None 25407db96d56Sopenharmony_ci frameless_opcodes = {'BINBYTES', 'BINUNICODE', 'BINBYTES8', 25417db96d56Sopenharmony_ci 'BINUNICODE8', 'BYTEARRAY8'} 25427db96d56Sopenharmony_ci for op, arg, pos in pickletools.genops(pickled): 25437db96d56Sopenharmony_ci if frame_end is not None: 25447db96d56Sopenharmony_ci self.assertLessEqual(pos, frame_end) 25457db96d56Sopenharmony_ci if pos == frame_end: 25467db96d56Sopenharmony_ci frame_end = None 25477db96d56Sopenharmony_ci 25487db96d56Sopenharmony_ci if frame_end is not None: # framed 25497db96d56Sopenharmony_ci self.assertNotEqual(op.name, 'FRAME') 25507db96d56Sopenharmony_ci if op.name in frameless_opcodes: 25517db96d56Sopenharmony_ci # Only short bytes and str objects should be written 25527db96d56Sopenharmony_ci # in a frame 25537db96d56Sopenharmony_ci self.assertLessEqual(len(arg), self.FRAME_SIZE_TARGET) 25547db96d56Sopenharmony_ci 25557db96d56Sopenharmony_ci else: # not framed 25567db96d56Sopenharmony_ci if (op.name == 'FRAME' or 25577db96d56Sopenharmony_ci (op.name in frameless_opcodes and 25587db96d56Sopenharmony_ci len(arg) > self.FRAME_SIZE_TARGET)): 25597db96d56Sopenharmony_ci # Frame or large bytes or str object 25607db96d56Sopenharmony_ci if frameless_start is not None: 25617db96d56Sopenharmony_ci # Only short data should be written outside of a frame 25627db96d56Sopenharmony_ci self.assertLess(pos - frameless_start, 25637db96d56Sopenharmony_ci self.FRAME_SIZE_MIN) 25647db96d56Sopenharmony_ci frameless_start = None 25657db96d56Sopenharmony_ci elif frameless_start is None and op.name != 'PROTO': 25667db96d56Sopenharmony_ci frameless_start = pos 25677db96d56Sopenharmony_ci 25687db96d56Sopenharmony_ci if op.name == 'FRAME': 25697db96d56Sopenharmony_ci self.assertGreaterEqual(arg, self.FRAME_SIZE_MIN) 25707db96d56Sopenharmony_ci frame_end = pos + 9 + arg 25717db96d56Sopenharmony_ci 25727db96d56Sopenharmony_ci pos = len(pickled) 25737db96d56Sopenharmony_ci if frame_end is not None: 25747db96d56Sopenharmony_ci self.assertEqual(frame_end, pos) 25757db96d56Sopenharmony_ci elif frameless_start is not None: 25767db96d56Sopenharmony_ci self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN) 25777db96d56Sopenharmony_ci 25787db96d56Sopenharmony_ci @support.skip_if_pgo_task 25797db96d56Sopenharmony_ci def test_framing_many_objects(self): 25807db96d56Sopenharmony_ci obj = list(range(10**5)) 25817db96d56Sopenharmony_ci for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): 25827db96d56Sopenharmony_ci with self.subTest(proto=proto): 25837db96d56Sopenharmony_ci pickled = self.dumps(obj, proto) 25847db96d56Sopenharmony_ci unpickled = self.loads(pickled) 25857db96d56Sopenharmony_ci self.assertEqual(obj, unpickled) 25867db96d56Sopenharmony_ci bytes_per_frame = (len(pickled) / 25877db96d56Sopenharmony_ci count_opcode(pickle.FRAME, pickled)) 25887db96d56Sopenharmony_ci self.assertGreater(bytes_per_frame, 25897db96d56Sopenharmony_ci self.FRAME_SIZE_TARGET / 2) 25907db96d56Sopenharmony_ci self.assertLessEqual(bytes_per_frame, 25917db96d56Sopenharmony_ci self.FRAME_SIZE_TARGET * 1) 25927db96d56Sopenharmony_ci self.check_frame_opcodes(pickled) 25937db96d56Sopenharmony_ci 25947db96d56Sopenharmony_ci def test_framing_large_objects(self): 25957db96d56Sopenharmony_ci N = 1024 * 1024 25967db96d56Sopenharmony_ci small_items = [[i] for i in range(10)] 25977db96d56Sopenharmony_ci obj = [b'x' * N, *small_items, b'y' * N, 'z' * N] 25987db96d56Sopenharmony_ci for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): 25997db96d56Sopenharmony_ci for fast in [False, True]: 26007db96d56Sopenharmony_ci with self.subTest(proto=proto, fast=fast): 26017db96d56Sopenharmony_ci if not fast: 26027db96d56Sopenharmony_ci # fast=False by default. 26037db96d56Sopenharmony_ci # This covers in-memory pickling with pickle.dumps(). 26047db96d56Sopenharmony_ci pickled = self.dumps(obj, proto) 26057db96d56Sopenharmony_ci else: 26067db96d56Sopenharmony_ci # Pickler is required when fast=True. 26077db96d56Sopenharmony_ci if not hasattr(self, 'pickler'): 26087db96d56Sopenharmony_ci continue 26097db96d56Sopenharmony_ci buf = io.BytesIO() 26107db96d56Sopenharmony_ci pickler = self.pickler(buf, protocol=proto) 26117db96d56Sopenharmony_ci pickler.fast = fast 26127db96d56Sopenharmony_ci pickler.dump(obj) 26137db96d56Sopenharmony_ci pickled = buf.getvalue() 26147db96d56Sopenharmony_ci unpickled = self.loads(pickled) 26157db96d56Sopenharmony_ci # More informative error message in case of failure. 26167db96d56Sopenharmony_ci self.assertEqual([len(x) for x in obj], 26177db96d56Sopenharmony_ci [len(x) for x in unpickled]) 26187db96d56Sopenharmony_ci # Perform full equality check if the lengths match. 26197db96d56Sopenharmony_ci self.assertEqual(obj, unpickled) 26207db96d56Sopenharmony_ci n_frames = count_opcode(pickle.FRAME, pickled) 26217db96d56Sopenharmony_ci # A single frame for small objects between 26227db96d56Sopenharmony_ci # first two large objects. 26237db96d56Sopenharmony_ci self.assertEqual(n_frames, 1) 26247db96d56Sopenharmony_ci self.check_frame_opcodes(pickled) 26257db96d56Sopenharmony_ci 26267db96d56Sopenharmony_ci def test_optional_frames(self): 26277db96d56Sopenharmony_ci if pickle.HIGHEST_PROTOCOL < 4: 26287db96d56Sopenharmony_ci return 26297db96d56Sopenharmony_ci 26307db96d56Sopenharmony_ci def remove_frames(pickled, keep_frame=None): 26317db96d56Sopenharmony_ci """Remove frame opcodes from the given pickle.""" 26327db96d56Sopenharmony_ci frame_starts = [] 26337db96d56Sopenharmony_ci # 1 byte for the opcode and 8 for the argument 26347db96d56Sopenharmony_ci frame_opcode_size = 9 26357db96d56Sopenharmony_ci for opcode, _, pos in pickletools.genops(pickled): 26367db96d56Sopenharmony_ci if opcode.name == 'FRAME': 26377db96d56Sopenharmony_ci frame_starts.append(pos) 26387db96d56Sopenharmony_ci 26397db96d56Sopenharmony_ci newpickle = bytearray() 26407db96d56Sopenharmony_ci last_frame_end = 0 26417db96d56Sopenharmony_ci for i, pos in enumerate(frame_starts): 26427db96d56Sopenharmony_ci if keep_frame and keep_frame(i): 26437db96d56Sopenharmony_ci continue 26447db96d56Sopenharmony_ci newpickle += pickled[last_frame_end:pos] 26457db96d56Sopenharmony_ci last_frame_end = pos + frame_opcode_size 26467db96d56Sopenharmony_ci newpickle += pickled[last_frame_end:] 26477db96d56Sopenharmony_ci return newpickle 26487db96d56Sopenharmony_ci 26497db96d56Sopenharmony_ci frame_size = self.FRAME_SIZE_TARGET 26507db96d56Sopenharmony_ci num_frames = 20 26517db96d56Sopenharmony_ci # Large byte objects (dict values) intermittent with small objects 26527db96d56Sopenharmony_ci # (dict keys) 26537db96d56Sopenharmony_ci for bytes_type in (bytes, bytearray): 26547db96d56Sopenharmony_ci obj = {i: bytes_type([i]) * frame_size for i in range(num_frames)} 26557db96d56Sopenharmony_ci 26567db96d56Sopenharmony_ci for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): 26577db96d56Sopenharmony_ci pickled = self.dumps(obj, proto) 26587db96d56Sopenharmony_ci 26597db96d56Sopenharmony_ci frameless_pickle = remove_frames(pickled) 26607db96d56Sopenharmony_ci self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0) 26617db96d56Sopenharmony_ci self.assertEqual(obj, self.loads(frameless_pickle)) 26627db96d56Sopenharmony_ci 26637db96d56Sopenharmony_ci some_frames_pickle = remove_frames(pickled, lambda i: i % 2) 26647db96d56Sopenharmony_ci self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle), 26657db96d56Sopenharmony_ci count_opcode(pickle.FRAME, pickled)) 26667db96d56Sopenharmony_ci self.assertEqual(obj, self.loads(some_frames_pickle)) 26677db96d56Sopenharmony_ci 26687db96d56Sopenharmony_ci @support.skip_if_pgo_task 26697db96d56Sopenharmony_ci def test_framed_write_sizes_with_delayed_writer(self): 26707db96d56Sopenharmony_ci class ChunkAccumulator: 26717db96d56Sopenharmony_ci """Accumulate pickler output in a list of raw chunks.""" 26727db96d56Sopenharmony_ci def __init__(self): 26737db96d56Sopenharmony_ci self.chunks = [] 26747db96d56Sopenharmony_ci def write(self, chunk): 26757db96d56Sopenharmony_ci self.chunks.append(chunk) 26767db96d56Sopenharmony_ci def concatenate_chunks(self): 26777db96d56Sopenharmony_ci return b"".join(self.chunks) 26787db96d56Sopenharmony_ci 26797db96d56Sopenharmony_ci for proto in range(4, pickle.HIGHEST_PROTOCOL + 1): 26807db96d56Sopenharmony_ci objects = [(str(i).encode('ascii'), i % 42, {'i': str(i)}) 26817db96d56Sopenharmony_ci for i in range(int(1e4))] 26827db96d56Sopenharmony_ci # Add a large unique ASCII string 26837db96d56Sopenharmony_ci objects.append('0123456789abcdef' * 26847db96d56Sopenharmony_ci (self.FRAME_SIZE_TARGET // 16 + 1)) 26857db96d56Sopenharmony_ci 26867db96d56Sopenharmony_ci # Protocol 4 packs groups of small objects into frames and issues 26877db96d56Sopenharmony_ci # calls to write only once or twice per frame: 26887db96d56Sopenharmony_ci # The C pickler issues one call to write per-frame (header and 26897db96d56Sopenharmony_ci # contents) while Python pickler issues two calls to write: one for 26907db96d56Sopenharmony_ci # the frame header and one for the frame binary contents. 26917db96d56Sopenharmony_ci writer = ChunkAccumulator() 26927db96d56Sopenharmony_ci self.pickler(writer, proto).dump(objects) 26937db96d56Sopenharmony_ci 26947db96d56Sopenharmony_ci # Actually read the binary content of the chunks after the end 26957db96d56Sopenharmony_ci # of the call to dump: any memoryview passed to write should not 26967db96d56Sopenharmony_ci # be released otherwise this delayed access would not be possible. 26977db96d56Sopenharmony_ci pickled = writer.concatenate_chunks() 26987db96d56Sopenharmony_ci reconstructed = self.loads(pickled) 26997db96d56Sopenharmony_ci self.assertEqual(reconstructed, objects) 27007db96d56Sopenharmony_ci self.assertGreater(len(writer.chunks), 1) 27017db96d56Sopenharmony_ci 27027db96d56Sopenharmony_ci # memoryviews should own the memory. 27037db96d56Sopenharmony_ci del objects 27047db96d56Sopenharmony_ci support.gc_collect() 27057db96d56Sopenharmony_ci self.assertEqual(writer.concatenate_chunks(), pickled) 27067db96d56Sopenharmony_ci 27077db96d56Sopenharmony_ci n_frames = (len(pickled) - 1) // self.FRAME_SIZE_TARGET + 1 27087db96d56Sopenharmony_ci # There should be at least one call to write per frame 27097db96d56Sopenharmony_ci self.assertGreaterEqual(len(writer.chunks), n_frames) 27107db96d56Sopenharmony_ci 27117db96d56Sopenharmony_ci # but not too many either: there can be one for the proto, 27127db96d56Sopenharmony_ci # one per-frame header, one per frame for the actual contents, 27137db96d56Sopenharmony_ci # and two for the header. 27147db96d56Sopenharmony_ci self.assertLessEqual(len(writer.chunks), 2 * n_frames + 3) 27157db96d56Sopenharmony_ci 27167db96d56Sopenharmony_ci chunk_sizes = [len(c) for c in writer.chunks] 27177db96d56Sopenharmony_ci large_sizes = [s for s in chunk_sizes 27187db96d56Sopenharmony_ci if s >= self.FRAME_SIZE_TARGET] 27197db96d56Sopenharmony_ci medium_sizes = [s for s in chunk_sizes 27207db96d56Sopenharmony_ci if 9 < s < self.FRAME_SIZE_TARGET] 27217db96d56Sopenharmony_ci small_sizes = [s for s in chunk_sizes if s <= 9] 27227db96d56Sopenharmony_ci 27237db96d56Sopenharmony_ci # Large chunks should not be too large: 27247db96d56Sopenharmony_ci for chunk_size in large_sizes: 27257db96d56Sopenharmony_ci self.assertLess(chunk_size, 2 * self.FRAME_SIZE_TARGET, 27267db96d56Sopenharmony_ci chunk_sizes) 27277db96d56Sopenharmony_ci # There shouldn't bee too many small chunks: the protocol header, 27287db96d56Sopenharmony_ci # the frame headers and the large string headers are written 27297db96d56Sopenharmony_ci # in small chunks. 27307db96d56Sopenharmony_ci self.assertLessEqual(len(small_sizes), 27317db96d56Sopenharmony_ci len(large_sizes) + len(medium_sizes) + 3, 27327db96d56Sopenharmony_ci chunk_sizes) 27337db96d56Sopenharmony_ci 27347db96d56Sopenharmony_ci def test_nested_names(self): 27357db96d56Sopenharmony_ci global Nested 27367db96d56Sopenharmony_ci class Nested: 27377db96d56Sopenharmony_ci class A: 27387db96d56Sopenharmony_ci class B: 27397db96d56Sopenharmony_ci class C: 27407db96d56Sopenharmony_ci pass 27417db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 27427db96d56Sopenharmony_ci for obj in [Nested.A, Nested.A.B, Nested.A.B.C]: 27437db96d56Sopenharmony_ci with self.subTest(proto=proto, obj=obj): 27447db96d56Sopenharmony_ci unpickled = self.loads(self.dumps(obj, proto)) 27457db96d56Sopenharmony_ci self.assertIs(obj, unpickled) 27467db96d56Sopenharmony_ci 27477db96d56Sopenharmony_ci def test_recursive_nested_names(self): 27487db96d56Sopenharmony_ci global Recursive 27497db96d56Sopenharmony_ci class Recursive: 27507db96d56Sopenharmony_ci pass 27517db96d56Sopenharmony_ci Recursive.mod = sys.modules[Recursive.__module__] 27527db96d56Sopenharmony_ci Recursive.__qualname__ = 'Recursive.mod.Recursive' 27537db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 27547db96d56Sopenharmony_ci with self.subTest(proto=proto): 27557db96d56Sopenharmony_ci unpickled = self.loads(self.dumps(Recursive, proto)) 27567db96d56Sopenharmony_ci self.assertIs(unpickled, Recursive) 27577db96d56Sopenharmony_ci del Recursive.mod # break reference loop 27587db96d56Sopenharmony_ci 27597db96d56Sopenharmony_ci def test_py_methods(self): 27607db96d56Sopenharmony_ci global PyMethodsTest 27617db96d56Sopenharmony_ci class PyMethodsTest: 27627db96d56Sopenharmony_ci @staticmethod 27637db96d56Sopenharmony_ci def cheese(): 27647db96d56Sopenharmony_ci return "cheese" 27657db96d56Sopenharmony_ci @classmethod 27667db96d56Sopenharmony_ci def wine(cls): 27677db96d56Sopenharmony_ci assert cls is PyMethodsTest 27687db96d56Sopenharmony_ci return "wine" 27697db96d56Sopenharmony_ci def biscuits(self): 27707db96d56Sopenharmony_ci assert isinstance(self, PyMethodsTest) 27717db96d56Sopenharmony_ci return "biscuits" 27727db96d56Sopenharmony_ci class Nested: 27737db96d56Sopenharmony_ci "Nested class" 27747db96d56Sopenharmony_ci @staticmethod 27757db96d56Sopenharmony_ci def ketchup(): 27767db96d56Sopenharmony_ci return "ketchup" 27777db96d56Sopenharmony_ci @classmethod 27787db96d56Sopenharmony_ci def maple(cls): 27797db96d56Sopenharmony_ci assert cls is PyMethodsTest.Nested 27807db96d56Sopenharmony_ci return "maple" 27817db96d56Sopenharmony_ci def pie(self): 27827db96d56Sopenharmony_ci assert isinstance(self, PyMethodsTest.Nested) 27837db96d56Sopenharmony_ci return "pie" 27847db96d56Sopenharmony_ci 27857db96d56Sopenharmony_ci py_methods = ( 27867db96d56Sopenharmony_ci PyMethodsTest.cheese, 27877db96d56Sopenharmony_ci PyMethodsTest.wine, 27887db96d56Sopenharmony_ci PyMethodsTest().biscuits, 27897db96d56Sopenharmony_ci PyMethodsTest.Nested.ketchup, 27907db96d56Sopenharmony_ci PyMethodsTest.Nested.maple, 27917db96d56Sopenharmony_ci PyMethodsTest.Nested().pie 27927db96d56Sopenharmony_ci ) 27937db96d56Sopenharmony_ci py_unbound_methods = ( 27947db96d56Sopenharmony_ci (PyMethodsTest.biscuits, PyMethodsTest), 27957db96d56Sopenharmony_ci (PyMethodsTest.Nested.pie, PyMethodsTest.Nested) 27967db96d56Sopenharmony_ci ) 27977db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 27987db96d56Sopenharmony_ci for method in py_methods: 27997db96d56Sopenharmony_ci with self.subTest(proto=proto, method=method): 28007db96d56Sopenharmony_ci unpickled = self.loads(self.dumps(method, proto)) 28017db96d56Sopenharmony_ci self.assertEqual(method(), unpickled()) 28027db96d56Sopenharmony_ci for method, cls in py_unbound_methods: 28037db96d56Sopenharmony_ci obj = cls() 28047db96d56Sopenharmony_ci with self.subTest(proto=proto, method=method): 28057db96d56Sopenharmony_ci unpickled = self.loads(self.dumps(method, proto)) 28067db96d56Sopenharmony_ci self.assertEqual(method(obj), unpickled(obj)) 28077db96d56Sopenharmony_ci 28087db96d56Sopenharmony_ci descriptors = ( 28097db96d56Sopenharmony_ci PyMethodsTest.__dict__['cheese'], # static method descriptor 28107db96d56Sopenharmony_ci PyMethodsTest.__dict__['wine'], # class method descriptor 28117db96d56Sopenharmony_ci ) 28127db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 28137db96d56Sopenharmony_ci for descr in descriptors: 28147db96d56Sopenharmony_ci with self.subTest(proto=proto, descr=descr): 28157db96d56Sopenharmony_ci self.assertRaises(TypeError, self.dumps, descr, proto) 28167db96d56Sopenharmony_ci 28177db96d56Sopenharmony_ci def test_c_methods(self): 28187db96d56Sopenharmony_ci global Subclass 28197db96d56Sopenharmony_ci class Subclass(tuple): 28207db96d56Sopenharmony_ci class Nested(str): 28217db96d56Sopenharmony_ci pass 28227db96d56Sopenharmony_ci 28237db96d56Sopenharmony_ci c_methods = ( 28247db96d56Sopenharmony_ci # bound built-in method 28257db96d56Sopenharmony_ci ("abcd".index, ("c",)), 28267db96d56Sopenharmony_ci # unbound built-in method 28277db96d56Sopenharmony_ci (str.index, ("abcd", "c")), 28287db96d56Sopenharmony_ci # bound "slot" method 28297db96d56Sopenharmony_ci ([1, 2, 3].__len__, ()), 28307db96d56Sopenharmony_ci # unbound "slot" method 28317db96d56Sopenharmony_ci (list.__len__, ([1, 2, 3],)), 28327db96d56Sopenharmony_ci # bound "coexist" method 28337db96d56Sopenharmony_ci ({1, 2}.__contains__, (2,)), 28347db96d56Sopenharmony_ci # unbound "coexist" method 28357db96d56Sopenharmony_ci (set.__contains__, ({1, 2}, 2)), 28367db96d56Sopenharmony_ci # built-in class method 28377db96d56Sopenharmony_ci (dict.fromkeys, (("a", 1), ("b", 2))), 28387db96d56Sopenharmony_ci # built-in static method 28397db96d56Sopenharmony_ci (bytearray.maketrans, (b"abc", b"xyz")), 28407db96d56Sopenharmony_ci # subclass methods 28417db96d56Sopenharmony_ci (Subclass([1,2,2]).count, (2,)), 28427db96d56Sopenharmony_ci (Subclass.count, (Subclass([1,2,2]), 2)), 28437db96d56Sopenharmony_ci (Subclass.Nested("sweet").count, ("e",)), 28447db96d56Sopenharmony_ci (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")), 28457db96d56Sopenharmony_ci ) 28467db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 28477db96d56Sopenharmony_ci for method, args in c_methods: 28487db96d56Sopenharmony_ci with self.subTest(proto=proto, method=method): 28497db96d56Sopenharmony_ci unpickled = self.loads(self.dumps(method, proto)) 28507db96d56Sopenharmony_ci self.assertEqual(method(*args), unpickled(*args)) 28517db96d56Sopenharmony_ci 28527db96d56Sopenharmony_ci descriptors = ( 28537db96d56Sopenharmony_ci bytearray.__dict__['maketrans'], # built-in static method descriptor 28547db96d56Sopenharmony_ci dict.__dict__['fromkeys'], # built-in class method descriptor 28557db96d56Sopenharmony_ci ) 28567db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 28577db96d56Sopenharmony_ci for descr in descriptors: 28587db96d56Sopenharmony_ci with self.subTest(proto=proto, descr=descr): 28597db96d56Sopenharmony_ci self.assertRaises(TypeError, self.dumps, descr, proto) 28607db96d56Sopenharmony_ci 28617db96d56Sopenharmony_ci def test_compat_pickle(self): 28627db96d56Sopenharmony_ci tests = [ 28637db96d56Sopenharmony_ci (range(1, 7), '__builtin__', 'xrange'), 28647db96d56Sopenharmony_ci (map(int, '123'), 'itertools', 'imap'), 28657db96d56Sopenharmony_ci (functools.reduce, '__builtin__', 'reduce'), 28667db96d56Sopenharmony_ci (dbm.whichdb, 'whichdb', 'whichdb'), 28677db96d56Sopenharmony_ci (Exception(), 'exceptions', 'Exception'), 28687db96d56Sopenharmony_ci (collections.UserDict(), 'UserDict', 'IterableUserDict'), 28697db96d56Sopenharmony_ci (collections.UserList(), 'UserList', 'UserList'), 28707db96d56Sopenharmony_ci (collections.defaultdict(), 'collections', 'defaultdict'), 28717db96d56Sopenharmony_ci ] 28727db96d56Sopenharmony_ci for val, mod, name in tests: 28737db96d56Sopenharmony_ci for proto in range(3): 28747db96d56Sopenharmony_ci with self.subTest(type=type(val), proto=proto): 28757db96d56Sopenharmony_ci pickled = self.dumps(val, proto) 28767db96d56Sopenharmony_ci self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled) 28777db96d56Sopenharmony_ci self.assertIs(type(self.loads(pickled)), type(val)) 28787db96d56Sopenharmony_ci 28797db96d56Sopenharmony_ci def test_local_lookup_error(self): 28807db96d56Sopenharmony_ci # Test that whichmodule() errors out cleanly when looking up 28817db96d56Sopenharmony_ci # an assumed globally-reachable object fails. 28827db96d56Sopenharmony_ci def f(): 28837db96d56Sopenharmony_ci pass 28847db96d56Sopenharmony_ci # Since the function is local, lookup will fail 28857db96d56Sopenharmony_ci for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): 28867db96d56Sopenharmony_ci with self.assertRaises((AttributeError, pickle.PicklingError)): 28877db96d56Sopenharmony_ci pickletools.dis(self.dumps(f, proto)) 28887db96d56Sopenharmony_ci # Same without a __module__ attribute (exercises a different path 28897db96d56Sopenharmony_ci # in _pickle.c). 28907db96d56Sopenharmony_ci del f.__module__ 28917db96d56Sopenharmony_ci for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): 28927db96d56Sopenharmony_ci with self.assertRaises((AttributeError, pickle.PicklingError)): 28937db96d56Sopenharmony_ci pickletools.dis(self.dumps(f, proto)) 28947db96d56Sopenharmony_ci # Yet a different path. 28957db96d56Sopenharmony_ci f.__name__ = f.__qualname__ 28967db96d56Sopenharmony_ci for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): 28977db96d56Sopenharmony_ci with self.assertRaises((AttributeError, pickle.PicklingError)): 28987db96d56Sopenharmony_ci pickletools.dis(self.dumps(f, proto)) 28997db96d56Sopenharmony_ci 29007db96d56Sopenharmony_ci # 29017db96d56Sopenharmony_ci # PEP 574 tests below 29027db96d56Sopenharmony_ci # 29037db96d56Sopenharmony_ci 29047db96d56Sopenharmony_ci def buffer_like_objects(self): 29057db96d56Sopenharmony_ci # Yield buffer-like objects with the bytestring "abcdef" in them 29067db96d56Sopenharmony_ci bytestring = b"abcdefgh" 29077db96d56Sopenharmony_ci yield ZeroCopyBytes(bytestring) 29087db96d56Sopenharmony_ci yield ZeroCopyBytearray(bytestring) 29097db96d56Sopenharmony_ci if _testbuffer is not None: 29107db96d56Sopenharmony_ci items = list(bytestring) 29117db96d56Sopenharmony_ci value = int.from_bytes(bytestring, byteorder='little') 29127db96d56Sopenharmony_ci for flags in (0, _testbuffer.ND_WRITABLE): 29137db96d56Sopenharmony_ci # 1-D, contiguous 29147db96d56Sopenharmony_ci yield PicklableNDArray(items, format='B', shape=(8,), 29157db96d56Sopenharmony_ci flags=flags) 29167db96d56Sopenharmony_ci # 2-D, C-contiguous 29177db96d56Sopenharmony_ci yield PicklableNDArray(items, format='B', shape=(4, 2), 29187db96d56Sopenharmony_ci strides=(2, 1), flags=flags) 29197db96d56Sopenharmony_ci # 2-D, Fortran-contiguous 29207db96d56Sopenharmony_ci yield PicklableNDArray(items, format='B', 29217db96d56Sopenharmony_ci shape=(4, 2), strides=(1, 4), 29227db96d56Sopenharmony_ci flags=flags) 29237db96d56Sopenharmony_ci 29247db96d56Sopenharmony_ci def test_in_band_buffers(self): 29257db96d56Sopenharmony_ci # Test in-band buffers (PEP 574) 29267db96d56Sopenharmony_ci for obj in self.buffer_like_objects(): 29277db96d56Sopenharmony_ci for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): 29287db96d56Sopenharmony_ci data = self.dumps(obj, proto) 29297db96d56Sopenharmony_ci if obj.c_contiguous and proto >= 5: 29307db96d56Sopenharmony_ci # The raw memory bytes are serialized in physical order 29317db96d56Sopenharmony_ci self.assertIn(b"abcdefgh", data) 29327db96d56Sopenharmony_ci self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 0) 29337db96d56Sopenharmony_ci if proto >= 5: 29347db96d56Sopenharmony_ci self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data), 29357db96d56Sopenharmony_ci 1 if obj.readonly else 0) 29367db96d56Sopenharmony_ci self.assertEqual(count_opcode(pickle.BYTEARRAY8, data), 29377db96d56Sopenharmony_ci 0 if obj.readonly else 1) 29387db96d56Sopenharmony_ci # Return a true value from buffer_callback should have 29397db96d56Sopenharmony_ci # the same effect 29407db96d56Sopenharmony_ci def buffer_callback(obj): 29417db96d56Sopenharmony_ci return True 29427db96d56Sopenharmony_ci data2 = self.dumps(obj, proto, 29437db96d56Sopenharmony_ci buffer_callback=buffer_callback) 29447db96d56Sopenharmony_ci self.assertEqual(data2, data) 29457db96d56Sopenharmony_ci 29467db96d56Sopenharmony_ci new = self.loads(data) 29477db96d56Sopenharmony_ci # It's a copy 29487db96d56Sopenharmony_ci self.assertIsNot(new, obj) 29497db96d56Sopenharmony_ci self.assertIs(type(new), type(obj)) 29507db96d56Sopenharmony_ci self.assertEqual(new, obj) 29517db96d56Sopenharmony_ci 29527db96d56Sopenharmony_ci # XXX Unfortunately cannot test non-contiguous array 29537db96d56Sopenharmony_ci # (see comment in PicklableNDArray.__reduce_ex__) 29547db96d56Sopenharmony_ci 29557db96d56Sopenharmony_ci def test_oob_buffers(self): 29567db96d56Sopenharmony_ci # Test out-of-band buffers (PEP 574) 29577db96d56Sopenharmony_ci for obj in self.buffer_like_objects(): 29587db96d56Sopenharmony_ci for proto in range(0, 5): 29597db96d56Sopenharmony_ci # Need protocol >= 5 for buffer_callback 29607db96d56Sopenharmony_ci with self.assertRaises(ValueError): 29617db96d56Sopenharmony_ci self.dumps(obj, proto, 29627db96d56Sopenharmony_ci buffer_callback=[].append) 29637db96d56Sopenharmony_ci for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): 29647db96d56Sopenharmony_ci buffers = [] 29657db96d56Sopenharmony_ci buffer_callback = lambda pb: buffers.append(pb.raw()) 29667db96d56Sopenharmony_ci data = self.dumps(obj, proto, 29677db96d56Sopenharmony_ci buffer_callback=buffer_callback) 29687db96d56Sopenharmony_ci self.assertNotIn(b"abcdefgh", data) 29697db96d56Sopenharmony_ci self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data), 0) 29707db96d56Sopenharmony_ci self.assertEqual(count_opcode(pickle.BYTEARRAY8, data), 0) 29717db96d56Sopenharmony_ci self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 1) 29727db96d56Sopenharmony_ci self.assertEqual(count_opcode(pickle.READONLY_BUFFER, data), 29737db96d56Sopenharmony_ci 1 if obj.readonly else 0) 29747db96d56Sopenharmony_ci 29757db96d56Sopenharmony_ci if obj.c_contiguous: 29767db96d56Sopenharmony_ci self.assertEqual(bytes(buffers[0]), b"abcdefgh") 29777db96d56Sopenharmony_ci # Need buffers argument to unpickle properly 29787db96d56Sopenharmony_ci with self.assertRaises(pickle.UnpicklingError): 29797db96d56Sopenharmony_ci self.loads(data) 29807db96d56Sopenharmony_ci 29817db96d56Sopenharmony_ci new = self.loads(data, buffers=buffers) 29827db96d56Sopenharmony_ci if obj.zero_copy_reconstruct: 29837db96d56Sopenharmony_ci # Zero-copy achieved 29847db96d56Sopenharmony_ci self.assertIs(new, obj) 29857db96d56Sopenharmony_ci else: 29867db96d56Sopenharmony_ci self.assertIs(type(new), type(obj)) 29877db96d56Sopenharmony_ci self.assertEqual(new, obj) 29887db96d56Sopenharmony_ci # Non-sequence buffers accepted too 29897db96d56Sopenharmony_ci new = self.loads(data, buffers=iter(buffers)) 29907db96d56Sopenharmony_ci if obj.zero_copy_reconstruct: 29917db96d56Sopenharmony_ci # Zero-copy achieved 29927db96d56Sopenharmony_ci self.assertIs(new, obj) 29937db96d56Sopenharmony_ci else: 29947db96d56Sopenharmony_ci self.assertIs(type(new), type(obj)) 29957db96d56Sopenharmony_ci self.assertEqual(new, obj) 29967db96d56Sopenharmony_ci 29977db96d56Sopenharmony_ci def test_oob_buffers_writable_to_readonly(self): 29987db96d56Sopenharmony_ci # Test reconstructing readonly object from writable buffer 29997db96d56Sopenharmony_ci obj = ZeroCopyBytes(b"foobar") 30007db96d56Sopenharmony_ci for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): 30017db96d56Sopenharmony_ci buffers = [] 30027db96d56Sopenharmony_ci buffer_callback = buffers.append 30037db96d56Sopenharmony_ci data = self.dumps(obj, proto, buffer_callback=buffer_callback) 30047db96d56Sopenharmony_ci 30057db96d56Sopenharmony_ci buffers = map(bytearray, buffers) 30067db96d56Sopenharmony_ci new = self.loads(data, buffers=buffers) 30077db96d56Sopenharmony_ci self.assertIs(type(new), type(obj)) 30087db96d56Sopenharmony_ci self.assertEqual(new, obj) 30097db96d56Sopenharmony_ci 30107db96d56Sopenharmony_ci def test_picklebuffer_error(self): 30117db96d56Sopenharmony_ci # PickleBuffer forbidden with protocol < 5 30127db96d56Sopenharmony_ci pb = pickle.PickleBuffer(b"foobar") 30137db96d56Sopenharmony_ci for proto in range(0, 5): 30147db96d56Sopenharmony_ci with self.assertRaises(pickle.PickleError): 30157db96d56Sopenharmony_ci self.dumps(pb, proto) 30167db96d56Sopenharmony_ci 30177db96d56Sopenharmony_ci def test_buffer_callback_error(self): 30187db96d56Sopenharmony_ci def buffer_callback(buffers): 30197db96d56Sopenharmony_ci 1/0 30207db96d56Sopenharmony_ci pb = pickle.PickleBuffer(b"foobar") 30217db96d56Sopenharmony_ci with self.assertRaises(ZeroDivisionError): 30227db96d56Sopenharmony_ci self.dumps(pb, 5, buffer_callback=buffer_callback) 30237db96d56Sopenharmony_ci 30247db96d56Sopenharmony_ci def test_buffers_error(self): 30257db96d56Sopenharmony_ci pb = pickle.PickleBuffer(b"foobar") 30267db96d56Sopenharmony_ci for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): 30277db96d56Sopenharmony_ci data = self.dumps(pb, proto, buffer_callback=[].append) 30287db96d56Sopenharmony_ci # Non iterable buffers 30297db96d56Sopenharmony_ci with self.assertRaises(TypeError): 30307db96d56Sopenharmony_ci self.loads(data, buffers=object()) 30317db96d56Sopenharmony_ci # Buffer iterable exhausts too early 30327db96d56Sopenharmony_ci with self.assertRaises(pickle.UnpicklingError): 30337db96d56Sopenharmony_ci self.loads(data, buffers=[]) 30347db96d56Sopenharmony_ci 30357db96d56Sopenharmony_ci def test_inband_accept_default_buffers_argument(self): 30367db96d56Sopenharmony_ci for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): 30377db96d56Sopenharmony_ci data_pickled = self.dumps(1, proto, buffer_callback=None) 30387db96d56Sopenharmony_ci data = self.loads(data_pickled, buffers=None) 30397db96d56Sopenharmony_ci 30407db96d56Sopenharmony_ci @unittest.skipIf(np is None, "Test needs Numpy") 30417db96d56Sopenharmony_ci def test_buffers_numpy(self): 30427db96d56Sopenharmony_ci def check_no_copy(x, y): 30437db96d56Sopenharmony_ci np.testing.assert_equal(x, y) 30447db96d56Sopenharmony_ci self.assertEqual(x.ctypes.data, y.ctypes.data) 30457db96d56Sopenharmony_ci 30467db96d56Sopenharmony_ci def check_copy(x, y): 30477db96d56Sopenharmony_ci np.testing.assert_equal(x, y) 30487db96d56Sopenharmony_ci self.assertNotEqual(x.ctypes.data, y.ctypes.data) 30497db96d56Sopenharmony_ci 30507db96d56Sopenharmony_ci def check_array(arr): 30517db96d56Sopenharmony_ci # In-band 30527db96d56Sopenharmony_ci for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): 30537db96d56Sopenharmony_ci data = self.dumps(arr, proto) 30547db96d56Sopenharmony_ci new = self.loads(data) 30557db96d56Sopenharmony_ci check_copy(arr, new) 30567db96d56Sopenharmony_ci for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): 30577db96d56Sopenharmony_ci buffer_callback = lambda _: True 30587db96d56Sopenharmony_ci data = self.dumps(arr, proto, buffer_callback=buffer_callback) 30597db96d56Sopenharmony_ci new = self.loads(data) 30607db96d56Sopenharmony_ci check_copy(arr, new) 30617db96d56Sopenharmony_ci # Out-of-band 30627db96d56Sopenharmony_ci for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): 30637db96d56Sopenharmony_ci buffers = [] 30647db96d56Sopenharmony_ci buffer_callback = buffers.append 30657db96d56Sopenharmony_ci data = self.dumps(arr, proto, buffer_callback=buffer_callback) 30667db96d56Sopenharmony_ci new = self.loads(data, buffers=buffers) 30677db96d56Sopenharmony_ci if arr.flags.c_contiguous or arr.flags.f_contiguous: 30687db96d56Sopenharmony_ci check_no_copy(arr, new) 30697db96d56Sopenharmony_ci else: 30707db96d56Sopenharmony_ci check_copy(arr, new) 30717db96d56Sopenharmony_ci 30727db96d56Sopenharmony_ci # 1-D 30737db96d56Sopenharmony_ci arr = np.arange(6) 30747db96d56Sopenharmony_ci check_array(arr) 30757db96d56Sopenharmony_ci # 1-D, non-contiguous 30767db96d56Sopenharmony_ci check_array(arr[::2]) 30777db96d56Sopenharmony_ci # 2-D, C-contiguous 30787db96d56Sopenharmony_ci arr = np.arange(12).reshape((3, 4)) 30797db96d56Sopenharmony_ci check_array(arr) 30807db96d56Sopenharmony_ci # 2-D, F-contiguous 30817db96d56Sopenharmony_ci check_array(arr.T) 30827db96d56Sopenharmony_ci # 2-D, non-contiguous 30837db96d56Sopenharmony_ci check_array(arr[::2]) 30847db96d56Sopenharmony_ci 30857db96d56Sopenharmony_ci def test_evil_class_mutating_dict(self): 30867db96d56Sopenharmony_ci # https://github.com/python/cpython/issues/92930 30877db96d56Sopenharmony_ci from random import getrandbits 30887db96d56Sopenharmony_ci 30897db96d56Sopenharmony_ci global Bad 30907db96d56Sopenharmony_ci class Bad: 30917db96d56Sopenharmony_ci def __eq__(self, other): 30927db96d56Sopenharmony_ci return ENABLED 30937db96d56Sopenharmony_ci def __hash__(self): 30947db96d56Sopenharmony_ci return 42 30957db96d56Sopenharmony_ci def __reduce__(self): 30967db96d56Sopenharmony_ci if getrandbits(6) == 0: 30977db96d56Sopenharmony_ci collection.clear() 30987db96d56Sopenharmony_ci return (Bad, ()) 30997db96d56Sopenharmony_ci 31007db96d56Sopenharmony_ci for proto in protocols: 31017db96d56Sopenharmony_ci for _ in range(20): 31027db96d56Sopenharmony_ci ENABLED = False 31037db96d56Sopenharmony_ci collection = {Bad(): Bad() for _ in range(20)} 31047db96d56Sopenharmony_ci for bad in collection: 31057db96d56Sopenharmony_ci bad.bad = bad 31067db96d56Sopenharmony_ci bad.collection = collection 31077db96d56Sopenharmony_ci ENABLED = True 31087db96d56Sopenharmony_ci try: 31097db96d56Sopenharmony_ci data = self.dumps(collection, proto) 31107db96d56Sopenharmony_ci self.loads(data) 31117db96d56Sopenharmony_ci except RuntimeError as e: 31127db96d56Sopenharmony_ci expected = "changed size during iteration" 31137db96d56Sopenharmony_ci self.assertIn(expected, str(e)) 31147db96d56Sopenharmony_ci 31157db96d56Sopenharmony_ci def test_evil_pickler_mutating_collection(self): 31167db96d56Sopenharmony_ci # https://github.com/python/cpython/issues/92930 31177db96d56Sopenharmony_ci if not hasattr(self, "pickler"): 31187db96d56Sopenharmony_ci raise self.skipTest(f"{type(self)} has no associated pickler type") 31197db96d56Sopenharmony_ci 31207db96d56Sopenharmony_ci global Clearer 31217db96d56Sopenharmony_ci class Clearer: 31227db96d56Sopenharmony_ci pass 31237db96d56Sopenharmony_ci 31247db96d56Sopenharmony_ci def check(collection): 31257db96d56Sopenharmony_ci class EvilPickler(self.pickler): 31267db96d56Sopenharmony_ci def persistent_id(self, obj): 31277db96d56Sopenharmony_ci if isinstance(obj, Clearer): 31287db96d56Sopenharmony_ci collection.clear() 31297db96d56Sopenharmony_ci return None 31307db96d56Sopenharmony_ci pickler = EvilPickler(io.BytesIO(), proto) 31317db96d56Sopenharmony_ci try: 31327db96d56Sopenharmony_ci pickler.dump(collection) 31337db96d56Sopenharmony_ci except RuntimeError as e: 31347db96d56Sopenharmony_ci expected = "changed size during iteration" 31357db96d56Sopenharmony_ci self.assertIn(expected, str(e)) 31367db96d56Sopenharmony_ci 31377db96d56Sopenharmony_ci for proto in protocols: 31387db96d56Sopenharmony_ci check([Clearer()]) 31397db96d56Sopenharmony_ci check([Clearer(), Clearer()]) 31407db96d56Sopenharmony_ci check({Clearer()}) 31417db96d56Sopenharmony_ci check({Clearer(), Clearer()}) 31427db96d56Sopenharmony_ci check({Clearer(): 1}) 31437db96d56Sopenharmony_ci check({Clearer(): 1, Clearer(): 2}) 31447db96d56Sopenharmony_ci check({1: Clearer(), 2: Clearer()}) 31457db96d56Sopenharmony_ci 31467db96d56Sopenharmony_ci 31477db96d56Sopenharmony_ciclass BigmemPickleTests: 31487db96d56Sopenharmony_ci 31497db96d56Sopenharmony_ci # Binary protocols can serialize longs of up to 2 GiB-1 31507db96d56Sopenharmony_ci 31517db96d56Sopenharmony_ci @bigmemtest(size=_2G, memuse=3.6, dry_run=False) 31527db96d56Sopenharmony_ci def test_huge_long_32b(self, size): 31537db96d56Sopenharmony_ci data = 1 << (8 * size) 31547db96d56Sopenharmony_ci try: 31557db96d56Sopenharmony_ci for proto in protocols: 31567db96d56Sopenharmony_ci if proto < 2: 31577db96d56Sopenharmony_ci continue 31587db96d56Sopenharmony_ci with self.subTest(proto=proto): 31597db96d56Sopenharmony_ci with self.assertRaises((ValueError, OverflowError)): 31607db96d56Sopenharmony_ci self.dumps(data, protocol=proto) 31617db96d56Sopenharmony_ci finally: 31627db96d56Sopenharmony_ci data = None 31637db96d56Sopenharmony_ci 31647db96d56Sopenharmony_ci # Protocol 3 can serialize up to 4 GiB-1 as a bytes object 31657db96d56Sopenharmony_ci # (older protocols don't have a dedicated opcode for bytes and are 31667db96d56Sopenharmony_ci # too inefficient) 31677db96d56Sopenharmony_ci 31687db96d56Sopenharmony_ci @bigmemtest(size=_2G, memuse=2.5, dry_run=False) 31697db96d56Sopenharmony_ci def test_huge_bytes_32b(self, size): 31707db96d56Sopenharmony_ci data = b"abcd" * (size // 4) 31717db96d56Sopenharmony_ci try: 31727db96d56Sopenharmony_ci for proto in protocols: 31737db96d56Sopenharmony_ci if proto < 3: 31747db96d56Sopenharmony_ci continue 31757db96d56Sopenharmony_ci with self.subTest(proto=proto): 31767db96d56Sopenharmony_ci try: 31777db96d56Sopenharmony_ci pickled = self.dumps(data, protocol=proto) 31787db96d56Sopenharmony_ci header = (pickle.BINBYTES + 31797db96d56Sopenharmony_ci struct.pack("<I", len(data))) 31807db96d56Sopenharmony_ci data_start = pickled.index(data) 31817db96d56Sopenharmony_ci self.assertEqual( 31827db96d56Sopenharmony_ci header, 31837db96d56Sopenharmony_ci pickled[data_start-len(header):data_start]) 31847db96d56Sopenharmony_ci finally: 31857db96d56Sopenharmony_ci pickled = None 31867db96d56Sopenharmony_ci finally: 31877db96d56Sopenharmony_ci data = None 31887db96d56Sopenharmony_ci 31897db96d56Sopenharmony_ci @bigmemtest(size=_4G, memuse=2.5, dry_run=False) 31907db96d56Sopenharmony_ci def test_huge_bytes_64b(self, size): 31917db96d56Sopenharmony_ci data = b"acbd" * (size // 4) 31927db96d56Sopenharmony_ci try: 31937db96d56Sopenharmony_ci for proto in protocols: 31947db96d56Sopenharmony_ci if proto < 3: 31957db96d56Sopenharmony_ci continue 31967db96d56Sopenharmony_ci with self.subTest(proto=proto): 31977db96d56Sopenharmony_ci if proto == 3: 31987db96d56Sopenharmony_ci # Protocol 3 does not support large bytes objects. 31997db96d56Sopenharmony_ci # Verify that we do not crash when processing one. 32007db96d56Sopenharmony_ci with self.assertRaises((ValueError, OverflowError)): 32017db96d56Sopenharmony_ci self.dumps(data, protocol=proto) 32027db96d56Sopenharmony_ci continue 32037db96d56Sopenharmony_ci try: 32047db96d56Sopenharmony_ci pickled = self.dumps(data, protocol=proto) 32057db96d56Sopenharmony_ci header = (pickle.BINBYTES8 + 32067db96d56Sopenharmony_ci struct.pack("<Q", len(data))) 32077db96d56Sopenharmony_ci data_start = pickled.index(data) 32087db96d56Sopenharmony_ci self.assertEqual( 32097db96d56Sopenharmony_ci header, 32107db96d56Sopenharmony_ci pickled[data_start-len(header):data_start]) 32117db96d56Sopenharmony_ci finally: 32127db96d56Sopenharmony_ci pickled = None 32137db96d56Sopenharmony_ci finally: 32147db96d56Sopenharmony_ci data = None 32157db96d56Sopenharmony_ci 32167db96d56Sopenharmony_ci # All protocols use 1-byte per printable ASCII character; we add another 32177db96d56Sopenharmony_ci # byte because the encoded form has to be copied into the internal buffer. 32187db96d56Sopenharmony_ci 32197db96d56Sopenharmony_ci @bigmemtest(size=_2G, memuse=8, dry_run=False) 32207db96d56Sopenharmony_ci def test_huge_str_32b(self, size): 32217db96d56Sopenharmony_ci data = "abcd" * (size // 4) 32227db96d56Sopenharmony_ci try: 32237db96d56Sopenharmony_ci for proto in protocols: 32247db96d56Sopenharmony_ci if proto == 0: 32257db96d56Sopenharmony_ci continue 32267db96d56Sopenharmony_ci with self.subTest(proto=proto): 32277db96d56Sopenharmony_ci try: 32287db96d56Sopenharmony_ci pickled = self.dumps(data, protocol=proto) 32297db96d56Sopenharmony_ci header = (pickle.BINUNICODE + 32307db96d56Sopenharmony_ci struct.pack("<I", len(data))) 32317db96d56Sopenharmony_ci data_start = pickled.index(b'abcd') 32327db96d56Sopenharmony_ci self.assertEqual( 32337db96d56Sopenharmony_ci header, 32347db96d56Sopenharmony_ci pickled[data_start-len(header):data_start]) 32357db96d56Sopenharmony_ci self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") - 32367db96d56Sopenharmony_ci pickled.index(b"abcd")), len(data)) 32377db96d56Sopenharmony_ci finally: 32387db96d56Sopenharmony_ci pickled = None 32397db96d56Sopenharmony_ci finally: 32407db96d56Sopenharmony_ci data = None 32417db96d56Sopenharmony_ci 32427db96d56Sopenharmony_ci # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes 32437db96d56Sopenharmony_ci # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge 32447db96d56Sopenharmony_ci # unicode strings however. 32457db96d56Sopenharmony_ci 32467db96d56Sopenharmony_ci @bigmemtest(size=_4G, memuse=8, dry_run=False) 32477db96d56Sopenharmony_ci def test_huge_str_64b(self, size): 32487db96d56Sopenharmony_ci data = "abcd" * (size // 4) 32497db96d56Sopenharmony_ci try: 32507db96d56Sopenharmony_ci for proto in protocols: 32517db96d56Sopenharmony_ci if proto == 0: 32527db96d56Sopenharmony_ci continue 32537db96d56Sopenharmony_ci with self.subTest(proto=proto): 32547db96d56Sopenharmony_ci if proto < 4: 32557db96d56Sopenharmony_ci with self.assertRaises((ValueError, OverflowError)): 32567db96d56Sopenharmony_ci self.dumps(data, protocol=proto) 32577db96d56Sopenharmony_ci continue 32587db96d56Sopenharmony_ci try: 32597db96d56Sopenharmony_ci pickled = self.dumps(data, protocol=proto) 32607db96d56Sopenharmony_ci header = (pickle.BINUNICODE8 + 32617db96d56Sopenharmony_ci struct.pack("<Q", len(data))) 32627db96d56Sopenharmony_ci data_start = pickled.index(b'abcd') 32637db96d56Sopenharmony_ci self.assertEqual( 32647db96d56Sopenharmony_ci header, 32657db96d56Sopenharmony_ci pickled[data_start-len(header):data_start]) 32667db96d56Sopenharmony_ci self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") - 32677db96d56Sopenharmony_ci pickled.index(b"abcd")), len(data)) 32687db96d56Sopenharmony_ci finally: 32697db96d56Sopenharmony_ci pickled = None 32707db96d56Sopenharmony_ci finally: 32717db96d56Sopenharmony_ci data = None 32727db96d56Sopenharmony_ci 32737db96d56Sopenharmony_ci 32747db96d56Sopenharmony_ci# Test classes for reduce_ex 32757db96d56Sopenharmony_ci 32767db96d56Sopenharmony_ciclass REX_one(object): 32777db96d56Sopenharmony_ci """No __reduce_ex__ here, but inheriting it from object""" 32787db96d56Sopenharmony_ci _reduce_called = 0 32797db96d56Sopenharmony_ci def __reduce__(self): 32807db96d56Sopenharmony_ci self._reduce_called = 1 32817db96d56Sopenharmony_ci return REX_one, () 32827db96d56Sopenharmony_ci 32837db96d56Sopenharmony_ciclass REX_two(object): 32847db96d56Sopenharmony_ci """No __reduce__ here, but inheriting it from object""" 32857db96d56Sopenharmony_ci _proto = None 32867db96d56Sopenharmony_ci def __reduce_ex__(self, proto): 32877db96d56Sopenharmony_ci self._proto = proto 32887db96d56Sopenharmony_ci return REX_two, () 32897db96d56Sopenharmony_ci 32907db96d56Sopenharmony_ciclass REX_three(object): 32917db96d56Sopenharmony_ci _proto = None 32927db96d56Sopenharmony_ci def __reduce_ex__(self, proto): 32937db96d56Sopenharmony_ci self._proto = proto 32947db96d56Sopenharmony_ci return REX_two, () 32957db96d56Sopenharmony_ci def __reduce__(self): 32967db96d56Sopenharmony_ci raise TestFailed("This __reduce__ shouldn't be called") 32977db96d56Sopenharmony_ci 32987db96d56Sopenharmony_ciclass REX_four(object): 32997db96d56Sopenharmony_ci """Calling base class method should succeed""" 33007db96d56Sopenharmony_ci _proto = None 33017db96d56Sopenharmony_ci def __reduce_ex__(self, proto): 33027db96d56Sopenharmony_ci self._proto = proto 33037db96d56Sopenharmony_ci return object.__reduce_ex__(self, proto) 33047db96d56Sopenharmony_ci 33057db96d56Sopenharmony_ciclass REX_five(object): 33067db96d56Sopenharmony_ci """This one used to fail with infinite recursion""" 33077db96d56Sopenharmony_ci _reduce_called = 0 33087db96d56Sopenharmony_ci def __reduce__(self): 33097db96d56Sopenharmony_ci self._reduce_called = 1 33107db96d56Sopenharmony_ci return object.__reduce__(self) 33117db96d56Sopenharmony_ci 33127db96d56Sopenharmony_ciclass REX_six(object): 33137db96d56Sopenharmony_ci """This class is used to check the 4th argument (list iterator) of 33147db96d56Sopenharmony_ci the reduce protocol. 33157db96d56Sopenharmony_ci """ 33167db96d56Sopenharmony_ci def __init__(self, items=None): 33177db96d56Sopenharmony_ci self.items = items if items is not None else [] 33187db96d56Sopenharmony_ci def __eq__(self, other): 33197db96d56Sopenharmony_ci return type(self) is type(other) and self.items == other.items 33207db96d56Sopenharmony_ci def append(self, item): 33217db96d56Sopenharmony_ci self.items.append(item) 33227db96d56Sopenharmony_ci def __reduce__(self): 33237db96d56Sopenharmony_ci return type(self), (), None, iter(self.items), None 33247db96d56Sopenharmony_ci 33257db96d56Sopenharmony_ciclass REX_seven(object): 33267db96d56Sopenharmony_ci """This class is used to check the 5th argument (dict iterator) of 33277db96d56Sopenharmony_ci the reduce protocol. 33287db96d56Sopenharmony_ci """ 33297db96d56Sopenharmony_ci def __init__(self, table=None): 33307db96d56Sopenharmony_ci self.table = table if table is not None else {} 33317db96d56Sopenharmony_ci def __eq__(self, other): 33327db96d56Sopenharmony_ci return type(self) is type(other) and self.table == other.table 33337db96d56Sopenharmony_ci def __setitem__(self, key, value): 33347db96d56Sopenharmony_ci self.table[key] = value 33357db96d56Sopenharmony_ci def __reduce__(self): 33367db96d56Sopenharmony_ci return type(self), (), None, None, iter(self.table.items()) 33377db96d56Sopenharmony_ci 33387db96d56Sopenharmony_ciclass REX_state(object): 33397db96d56Sopenharmony_ci """This class is used to check the 3th argument (state) of 33407db96d56Sopenharmony_ci the reduce protocol. 33417db96d56Sopenharmony_ci """ 33427db96d56Sopenharmony_ci def __init__(self, state=None): 33437db96d56Sopenharmony_ci self.state = state 33447db96d56Sopenharmony_ci def __eq__(self, other): 33457db96d56Sopenharmony_ci return type(self) is type(other) and self.state == other.state 33467db96d56Sopenharmony_ci def __setstate__(self, state): 33477db96d56Sopenharmony_ci self.state = state 33487db96d56Sopenharmony_ci def __reduce__(self): 33497db96d56Sopenharmony_ci return type(self), (), self.state 33507db96d56Sopenharmony_ci 33517db96d56Sopenharmony_ci 33527db96d56Sopenharmony_ci# Test classes for newobj 33537db96d56Sopenharmony_ci 33547db96d56Sopenharmony_ciclass MyInt(int): 33557db96d56Sopenharmony_ci sample = 1 33567db96d56Sopenharmony_ci 33577db96d56Sopenharmony_ciclass MyFloat(float): 33587db96d56Sopenharmony_ci sample = 1.0 33597db96d56Sopenharmony_ci 33607db96d56Sopenharmony_ciclass MyComplex(complex): 33617db96d56Sopenharmony_ci sample = 1.0 + 0.0j 33627db96d56Sopenharmony_ci 33637db96d56Sopenharmony_ciclass MyStr(str): 33647db96d56Sopenharmony_ci sample = "hello" 33657db96d56Sopenharmony_ci 33667db96d56Sopenharmony_ciclass MyUnicode(str): 33677db96d56Sopenharmony_ci sample = "hello \u1234" 33687db96d56Sopenharmony_ci 33697db96d56Sopenharmony_ciclass MyTuple(tuple): 33707db96d56Sopenharmony_ci sample = (1, 2, 3) 33717db96d56Sopenharmony_ci 33727db96d56Sopenharmony_ciclass MyList(list): 33737db96d56Sopenharmony_ci sample = [1, 2, 3] 33747db96d56Sopenharmony_ci 33757db96d56Sopenharmony_ciclass MyDict(dict): 33767db96d56Sopenharmony_ci sample = {"a": 1, "b": 2} 33777db96d56Sopenharmony_ci 33787db96d56Sopenharmony_ciclass MySet(set): 33797db96d56Sopenharmony_ci sample = {"a", "b"} 33807db96d56Sopenharmony_ci 33817db96d56Sopenharmony_ciclass MyFrozenSet(frozenset): 33827db96d56Sopenharmony_ci sample = frozenset({"a", "b"}) 33837db96d56Sopenharmony_ci 33847db96d56Sopenharmony_cimyclasses = [MyInt, MyFloat, 33857db96d56Sopenharmony_ci MyComplex, 33867db96d56Sopenharmony_ci MyStr, MyUnicode, 33877db96d56Sopenharmony_ci MyTuple, MyList, MyDict, MySet, MyFrozenSet] 33887db96d56Sopenharmony_ci 33897db96d56Sopenharmony_ciclass MyIntWithNew(int): 33907db96d56Sopenharmony_ci def __new__(cls, value): 33917db96d56Sopenharmony_ci raise AssertionError 33927db96d56Sopenharmony_ci 33937db96d56Sopenharmony_ciclass MyIntWithNew2(MyIntWithNew): 33947db96d56Sopenharmony_ci __new__ = int.__new__ 33957db96d56Sopenharmony_ci 33967db96d56Sopenharmony_ci 33977db96d56Sopenharmony_ciclass SlotList(MyList): 33987db96d56Sopenharmony_ci __slots__ = ["foo"] 33997db96d56Sopenharmony_ci 34007db96d56Sopenharmony_ciclass SimpleNewObj(int): 34017db96d56Sopenharmony_ci def __init__(self, *args, **kwargs): 34027db96d56Sopenharmony_ci # raise an error, to make sure this isn't called 34037db96d56Sopenharmony_ci raise TypeError("SimpleNewObj.__init__() didn't expect to get called") 34047db96d56Sopenharmony_ci def __eq__(self, other): 34057db96d56Sopenharmony_ci return int(self) == int(other) and self.__dict__ == other.__dict__ 34067db96d56Sopenharmony_ci 34077db96d56Sopenharmony_ciclass ComplexNewObj(SimpleNewObj): 34087db96d56Sopenharmony_ci def __getnewargs__(self): 34097db96d56Sopenharmony_ci return ('%X' % self, 16) 34107db96d56Sopenharmony_ci 34117db96d56Sopenharmony_ciclass ComplexNewObjEx(SimpleNewObj): 34127db96d56Sopenharmony_ci def __getnewargs_ex__(self): 34137db96d56Sopenharmony_ci return ('%X' % self,), {'base': 16} 34147db96d56Sopenharmony_ci 34157db96d56Sopenharmony_ciclass BadGetattr: 34167db96d56Sopenharmony_ci def __getattr__(self, key): 34177db96d56Sopenharmony_ci self.foo 34187db96d56Sopenharmony_ci 34197db96d56Sopenharmony_ci 34207db96d56Sopenharmony_ciclass AbstractPickleModuleTests: 34217db96d56Sopenharmony_ci 34227db96d56Sopenharmony_ci def test_dump_closed_file(self): 34237db96d56Sopenharmony_ci f = open(TESTFN, "wb") 34247db96d56Sopenharmony_ci try: 34257db96d56Sopenharmony_ci f.close() 34267db96d56Sopenharmony_ci self.assertRaises(ValueError, self.dump, 123, f) 34277db96d56Sopenharmony_ci finally: 34287db96d56Sopenharmony_ci os_helper.unlink(TESTFN) 34297db96d56Sopenharmony_ci 34307db96d56Sopenharmony_ci def test_load_closed_file(self): 34317db96d56Sopenharmony_ci f = open(TESTFN, "wb") 34327db96d56Sopenharmony_ci try: 34337db96d56Sopenharmony_ci f.close() 34347db96d56Sopenharmony_ci self.assertRaises(ValueError, self.dump, 123, f) 34357db96d56Sopenharmony_ci finally: 34367db96d56Sopenharmony_ci os_helper.unlink(TESTFN) 34377db96d56Sopenharmony_ci 34387db96d56Sopenharmony_ci def test_load_from_and_dump_to_file(self): 34397db96d56Sopenharmony_ci stream = io.BytesIO() 34407db96d56Sopenharmony_ci data = [123, {}, 124] 34417db96d56Sopenharmony_ci self.dump(data, stream) 34427db96d56Sopenharmony_ci stream.seek(0) 34437db96d56Sopenharmony_ci unpickled = self.load(stream) 34447db96d56Sopenharmony_ci self.assertEqual(unpickled, data) 34457db96d56Sopenharmony_ci 34467db96d56Sopenharmony_ci def test_highest_protocol(self): 34477db96d56Sopenharmony_ci # Of course this needs to be changed when HIGHEST_PROTOCOL changes. 34487db96d56Sopenharmony_ci self.assertEqual(pickle.HIGHEST_PROTOCOL, 5) 34497db96d56Sopenharmony_ci 34507db96d56Sopenharmony_ci def test_callapi(self): 34517db96d56Sopenharmony_ci f = io.BytesIO() 34527db96d56Sopenharmony_ci # With and without keyword arguments 34537db96d56Sopenharmony_ci self.dump(123, f, -1) 34547db96d56Sopenharmony_ci self.dump(123, file=f, protocol=-1) 34557db96d56Sopenharmony_ci self.dumps(123, -1) 34567db96d56Sopenharmony_ci self.dumps(123, protocol=-1) 34577db96d56Sopenharmony_ci self.Pickler(f, -1) 34587db96d56Sopenharmony_ci self.Pickler(f, protocol=-1) 34597db96d56Sopenharmony_ci 34607db96d56Sopenharmony_ci def test_dump_text_file(self): 34617db96d56Sopenharmony_ci f = open(TESTFN, "w") 34627db96d56Sopenharmony_ci try: 34637db96d56Sopenharmony_ci for proto in protocols: 34647db96d56Sopenharmony_ci self.assertRaises(TypeError, self.dump, 123, f, proto) 34657db96d56Sopenharmony_ci finally: 34667db96d56Sopenharmony_ci f.close() 34677db96d56Sopenharmony_ci os_helper.unlink(TESTFN) 34687db96d56Sopenharmony_ci 34697db96d56Sopenharmony_ci def test_incomplete_input(self): 34707db96d56Sopenharmony_ci s = io.BytesIO(b"X''.") 34717db96d56Sopenharmony_ci self.assertRaises((EOFError, struct.error, pickle.UnpicklingError), self.load, s) 34727db96d56Sopenharmony_ci 34737db96d56Sopenharmony_ci def test_bad_init(self): 34747db96d56Sopenharmony_ci # Test issue3664 (pickle can segfault from a badly initialized Pickler). 34757db96d56Sopenharmony_ci # Override initialization without calling __init__() of the superclass. 34767db96d56Sopenharmony_ci class BadPickler(self.Pickler): 34777db96d56Sopenharmony_ci def __init__(self): pass 34787db96d56Sopenharmony_ci 34797db96d56Sopenharmony_ci class BadUnpickler(self.Unpickler): 34807db96d56Sopenharmony_ci def __init__(self): pass 34817db96d56Sopenharmony_ci 34827db96d56Sopenharmony_ci self.assertRaises(pickle.PicklingError, BadPickler().dump, 0) 34837db96d56Sopenharmony_ci self.assertRaises(pickle.UnpicklingError, BadUnpickler().load) 34847db96d56Sopenharmony_ci 34857db96d56Sopenharmony_ci def check_dumps_loads_oob_buffers(self, dumps, loads): 34867db96d56Sopenharmony_ci # No need to do the full gamut of tests here, just enough to 34877db96d56Sopenharmony_ci # check that dumps() and loads() redirect their arguments 34887db96d56Sopenharmony_ci # to the underlying Pickler and Unpickler, respectively. 34897db96d56Sopenharmony_ci obj = ZeroCopyBytes(b"foo") 34907db96d56Sopenharmony_ci 34917db96d56Sopenharmony_ci for proto in range(0, 5): 34927db96d56Sopenharmony_ci # Need protocol >= 5 for buffer_callback 34937db96d56Sopenharmony_ci with self.assertRaises(ValueError): 34947db96d56Sopenharmony_ci dumps(obj, protocol=proto, 34957db96d56Sopenharmony_ci buffer_callback=[].append) 34967db96d56Sopenharmony_ci for proto in range(5, pickle.HIGHEST_PROTOCOL + 1): 34977db96d56Sopenharmony_ci buffers = [] 34987db96d56Sopenharmony_ci buffer_callback = buffers.append 34997db96d56Sopenharmony_ci data = dumps(obj, protocol=proto, 35007db96d56Sopenharmony_ci buffer_callback=buffer_callback) 35017db96d56Sopenharmony_ci self.assertNotIn(b"foo", data) 35027db96d56Sopenharmony_ci self.assertEqual(bytes(buffers[0]), b"foo") 35037db96d56Sopenharmony_ci # Need buffers argument to unpickle properly 35047db96d56Sopenharmony_ci with self.assertRaises(pickle.UnpicklingError): 35057db96d56Sopenharmony_ci loads(data) 35067db96d56Sopenharmony_ci new = loads(data, buffers=buffers) 35077db96d56Sopenharmony_ci self.assertIs(new, obj) 35087db96d56Sopenharmony_ci 35097db96d56Sopenharmony_ci def test_dumps_loads_oob_buffers(self): 35107db96d56Sopenharmony_ci # Test out-of-band buffers (PEP 574) with top-level dumps() and loads() 35117db96d56Sopenharmony_ci self.check_dumps_loads_oob_buffers(self.dumps, self.loads) 35127db96d56Sopenharmony_ci 35137db96d56Sopenharmony_ci def test_dump_load_oob_buffers(self): 35147db96d56Sopenharmony_ci # Test out-of-band buffers (PEP 574) with top-level dump() and load() 35157db96d56Sopenharmony_ci def dumps(obj, **kwargs): 35167db96d56Sopenharmony_ci f = io.BytesIO() 35177db96d56Sopenharmony_ci self.dump(obj, f, **kwargs) 35187db96d56Sopenharmony_ci return f.getvalue() 35197db96d56Sopenharmony_ci 35207db96d56Sopenharmony_ci def loads(data, **kwargs): 35217db96d56Sopenharmony_ci f = io.BytesIO(data) 35227db96d56Sopenharmony_ci return self.load(f, **kwargs) 35237db96d56Sopenharmony_ci 35247db96d56Sopenharmony_ci self.check_dumps_loads_oob_buffers(dumps, loads) 35257db96d56Sopenharmony_ci 35267db96d56Sopenharmony_ci 35277db96d56Sopenharmony_ciclass AbstractPersistentPicklerTests: 35287db96d56Sopenharmony_ci 35297db96d56Sopenharmony_ci # This class defines persistent_id() and persistent_load() 35307db96d56Sopenharmony_ci # functions that should be used by the pickler. All even integers 35317db96d56Sopenharmony_ci # are pickled using persistent ids. 35327db96d56Sopenharmony_ci 35337db96d56Sopenharmony_ci def persistent_id(self, object): 35347db96d56Sopenharmony_ci if isinstance(object, int) and object % 2 == 0: 35357db96d56Sopenharmony_ci self.id_count += 1 35367db96d56Sopenharmony_ci return str(object) 35377db96d56Sopenharmony_ci elif object == "test_false_value": 35387db96d56Sopenharmony_ci self.false_count += 1 35397db96d56Sopenharmony_ci return "" 35407db96d56Sopenharmony_ci else: 35417db96d56Sopenharmony_ci return None 35427db96d56Sopenharmony_ci 35437db96d56Sopenharmony_ci def persistent_load(self, oid): 35447db96d56Sopenharmony_ci if not oid: 35457db96d56Sopenharmony_ci self.load_false_count += 1 35467db96d56Sopenharmony_ci return "test_false_value" 35477db96d56Sopenharmony_ci else: 35487db96d56Sopenharmony_ci self.load_count += 1 35497db96d56Sopenharmony_ci object = int(oid) 35507db96d56Sopenharmony_ci assert object % 2 == 0 35517db96d56Sopenharmony_ci return object 35527db96d56Sopenharmony_ci 35537db96d56Sopenharmony_ci def test_persistence(self): 35547db96d56Sopenharmony_ci L = list(range(10)) + ["test_false_value"] 35557db96d56Sopenharmony_ci for proto in protocols: 35567db96d56Sopenharmony_ci self.id_count = 0 35577db96d56Sopenharmony_ci self.false_count = 0 35587db96d56Sopenharmony_ci self.load_false_count = 0 35597db96d56Sopenharmony_ci self.load_count = 0 35607db96d56Sopenharmony_ci self.assertEqual(self.loads(self.dumps(L, proto)), L) 35617db96d56Sopenharmony_ci self.assertEqual(self.id_count, 5) 35627db96d56Sopenharmony_ci self.assertEqual(self.false_count, 1) 35637db96d56Sopenharmony_ci self.assertEqual(self.load_count, 5) 35647db96d56Sopenharmony_ci self.assertEqual(self.load_false_count, 1) 35657db96d56Sopenharmony_ci 35667db96d56Sopenharmony_ci 35677db96d56Sopenharmony_ciclass AbstractIdentityPersistentPicklerTests: 35687db96d56Sopenharmony_ci 35697db96d56Sopenharmony_ci def persistent_id(self, obj): 35707db96d56Sopenharmony_ci return obj 35717db96d56Sopenharmony_ci 35727db96d56Sopenharmony_ci def persistent_load(self, pid): 35737db96d56Sopenharmony_ci return pid 35747db96d56Sopenharmony_ci 35757db96d56Sopenharmony_ci def _check_return_correct_type(self, obj, proto): 35767db96d56Sopenharmony_ci unpickled = self.loads(self.dumps(obj, proto)) 35777db96d56Sopenharmony_ci self.assertIsInstance(unpickled, type(obj)) 35787db96d56Sopenharmony_ci self.assertEqual(unpickled, obj) 35797db96d56Sopenharmony_ci 35807db96d56Sopenharmony_ci def test_return_correct_type(self): 35817db96d56Sopenharmony_ci for proto in protocols: 35827db96d56Sopenharmony_ci # Protocol 0 supports only ASCII strings. 35837db96d56Sopenharmony_ci if proto == 0: 35847db96d56Sopenharmony_ci self._check_return_correct_type("abc", 0) 35857db96d56Sopenharmony_ci else: 35867db96d56Sopenharmony_ci for obj in [b"abc\n", "abc\n", -1, -1.1 * 0.1, str]: 35877db96d56Sopenharmony_ci self._check_return_correct_type(obj, proto) 35887db96d56Sopenharmony_ci 35897db96d56Sopenharmony_ci def test_protocol0_is_ascii_only(self): 35907db96d56Sopenharmony_ci non_ascii_str = "\N{EMPTY SET}" 35917db96d56Sopenharmony_ci self.assertRaises(pickle.PicklingError, self.dumps, non_ascii_str, 0) 35927db96d56Sopenharmony_ci pickled = pickle.PERSID + non_ascii_str.encode('utf-8') + b'\n.' 35937db96d56Sopenharmony_ci self.assertRaises(pickle.UnpicklingError, self.loads, pickled) 35947db96d56Sopenharmony_ci 35957db96d56Sopenharmony_ci 35967db96d56Sopenharmony_ciclass AbstractPicklerUnpicklerObjectTests: 35977db96d56Sopenharmony_ci 35987db96d56Sopenharmony_ci pickler_class = None 35997db96d56Sopenharmony_ci unpickler_class = None 36007db96d56Sopenharmony_ci 36017db96d56Sopenharmony_ci def setUp(self): 36027db96d56Sopenharmony_ci assert self.pickler_class 36037db96d56Sopenharmony_ci assert self.unpickler_class 36047db96d56Sopenharmony_ci 36057db96d56Sopenharmony_ci def test_clear_pickler_memo(self): 36067db96d56Sopenharmony_ci # To test whether clear_memo() has any effect, we pickle an object, 36077db96d56Sopenharmony_ci # then pickle it again without clearing the memo; the two serialized 36087db96d56Sopenharmony_ci # forms should be different. If we clear_memo() and then pickle the 36097db96d56Sopenharmony_ci # object again, the third serialized form should be identical to the 36107db96d56Sopenharmony_ci # first one we obtained. 36117db96d56Sopenharmony_ci data = ["abcdefg", "abcdefg", 44] 36127db96d56Sopenharmony_ci for proto in protocols: 36137db96d56Sopenharmony_ci f = io.BytesIO() 36147db96d56Sopenharmony_ci pickler = self.pickler_class(f, proto) 36157db96d56Sopenharmony_ci 36167db96d56Sopenharmony_ci pickler.dump(data) 36177db96d56Sopenharmony_ci first_pickled = f.getvalue() 36187db96d56Sopenharmony_ci 36197db96d56Sopenharmony_ci # Reset BytesIO object. 36207db96d56Sopenharmony_ci f.seek(0) 36217db96d56Sopenharmony_ci f.truncate() 36227db96d56Sopenharmony_ci 36237db96d56Sopenharmony_ci pickler.dump(data) 36247db96d56Sopenharmony_ci second_pickled = f.getvalue() 36257db96d56Sopenharmony_ci 36267db96d56Sopenharmony_ci # Reset the Pickler and BytesIO objects. 36277db96d56Sopenharmony_ci pickler.clear_memo() 36287db96d56Sopenharmony_ci f.seek(0) 36297db96d56Sopenharmony_ci f.truncate() 36307db96d56Sopenharmony_ci 36317db96d56Sopenharmony_ci pickler.dump(data) 36327db96d56Sopenharmony_ci third_pickled = f.getvalue() 36337db96d56Sopenharmony_ci 36347db96d56Sopenharmony_ci self.assertNotEqual(first_pickled, second_pickled) 36357db96d56Sopenharmony_ci self.assertEqual(first_pickled, third_pickled) 36367db96d56Sopenharmony_ci 36377db96d56Sopenharmony_ci def test_priming_pickler_memo(self): 36387db96d56Sopenharmony_ci # Verify that we can set the Pickler's memo attribute. 36397db96d56Sopenharmony_ci data = ["abcdefg", "abcdefg", 44] 36407db96d56Sopenharmony_ci f = io.BytesIO() 36417db96d56Sopenharmony_ci pickler = self.pickler_class(f) 36427db96d56Sopenharmony_ci 36437db96d56Sopenharmony_ci pickler.dump(data) 36447db96d56Sopenharmony_ci first_pickled = f.getvalue() 36457db96d56Sopenharmony_ci 36467db96d56Sopenharmony_ci f = io.BytesIO() 36477db96d56Sopenharmony_ci primed = self.pickler_class(f) 36487db96d56Sopenharmony_ci primed.memo = pickler.memo 36497db96d56Sopenharmony_ci 36507db96d56Sopenharmony_ci primed.dump(data) 36517db96d56Sopenharmony_ci primed_pickled = f.getvalue() 36527db96d56Sopenharmony_ci 36537db96d56Sopenharmony_ci self.assertNotEqual(first_pickled, primed_pickled) 36547db96d56Sopenharmony_ci 36557db96d56Sopenharmony_ci def test_priming_unpickler_memo(self): 36567db96d56Sopenharmony_ci # Verify that we can set the Unpickler's memo attribute. 36577db96d56Sopenharmony_ci data = ["abcdefg", "abcdefg", 44] 36587db96d56Sopenharmony_ci f = io.BytesIO() 36597db96d56Sopenharmony_ci pickler = self.pickler_class(f) 36607db96d56Sopenharmony_ci 36617db96d56Sopenharmony_ci pickler.dump(data) 36627db96d56Sopenharmony_ci first_pickled = f.getvalue() 36637db96d56Sopenharmony_ci 36647db96d56Sopenharmony_ci f = io.BytesIO() 36657db96d56Sopenharmony_ci primed = self.pickler_class(f) 36667db96d56Sopenharmony_ci primed.memo = pickler.memo 36677db96d56Sopenharmony_ci 36687db96d56Sopenharmony_ci primed.dump(data) 36697db96d56Sopenharmony_ci primed_pickled = f.getvalue() 36707db96d56Sopenharmony_ci 36717db96d56Sopenharmony_ci unpickler = self.unpickler_class(io.BytesIO(first_pickled)) 36727db96d56Sopenharmony_ci unpickled_data1 = unpickler.load() 36737db96d56Sopenharmony_ci 36747db96d56Sopenharmony_ci self.assertEqual(unpickled_data1, data) 36757db96d56Sopenharmony_ci 36767db96d56Sopenharmony_ci primed = self.unpickler_class(io.BytesIO(primed_pickled)) 36777db96d56Sopenharmony_ci primed.memo = unpickler.memo 36787db96d56Sopenharmony_ci unpickled_data2 = primed.load() 36797db96d56Sopenharmony_ci 36807db96d56Sopenharmony_ci primed.memo.clear() 36817db96d56Sopenharmony_ci 36827db96d56Sopenharmony_ci self.assertEqual(unpickled_data2, data) 36837db96d56Sopenharmony_ci self.assertTrue(unpickled_data2 is unpickled_data1) 36847db96d56Sopenharmony_ci 36857db96d56Sopenharmony_ci def test_reusing_unpickler_objects(self): 36867db96d56Sopenharmony_ci data1 = ["abcdefg", "abcdefg", 44] 36877db96d56Sopenharmony_ci f = io.BytesIO() 36887db96d56Sopenharmony_ci pickler = self.pickler_class(f) 36897db96d56Sopenharmony_ci pickler.dump(data1) 36907db96d56Sopenharmony_ci pickled1 = f.getvalue() 36917db96d56Sopenharmony_ci 36927db96d56Sopenharmony_ci data2 = ["abcdefg", 44, 44] 36937db96d56Sopenharmony_ci f = io.BytesIO() 36947db96d56Sopenharmony_ci pickler = self.pickler_class(f) 36957db96d56Sopenharmony_ci pickler.dump(data2) 36967db96d56Sopenharmony_ci pickled2 = f.getvalue() 36977db96d56Sopenharmony_ci 36987db96d56Sopenharmony_ci f = io.BytesIO() 36997db96d56Sopenharmony_ci f.write(pickled1) 37007db96d56Sopenharmony_ci f.seek(0) 37017db96d56Sopenharmony_ci unpickler = self.unpickler_class(f) 37027db96d56Sopenharmony_ci self.assertEqual(unpickler.load(), data1) 37037db96d56Sopenharmony_ci 37047db96d56Sopenharmony_ci f.seek(0) 37057db96d56Sopenharmony_ci f.truncate() 37067db96d56Sopenharmony_ci f.write(pickled2) 37077db96d56Sopenharmony_ci f.seek(0) 37087db96d56Sopenharmony_ci self.assertEqual(unpickler.load(), data2) 37097db96d56Sopenharmony_ci 37107db96d56Sopenharmony_ci def _check_multiple_unpicklings(self, ioclass, *, seekable=True): 37117db96d56Sopenharmony_ci for proto in protocols: 37127db96d56Sopenharmony_ci with self.subTest(proto=proto): 37137db96d56Sopenharmony_ci data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len] 37147db96d56Sopenharmony_ci f = ioclass() 37157db96d56Sopenharmony_ci pickler = self.pickler_class(f, protocol=proto) 37167db96d56Sopenharmony_ci pickler.dump(data1) 37177db96d56Sopenharmony_ci pickled = f.getvalue() 37187db96d56Sopenharmony_ci 37197db96d56Sopenharmony_ci N = 5 37207db96d56Sopenharmony_ci f = ioclass(pickled * N) 37217db96d56Sopenharmony_ci unpickler = self.unpickler_class(f) 37227db96d56Sopenharmony_ci for i in range(N): 37237db96d56Sopenharmony_ci if seekable: 37247db96d56Sopenharmony_ci pos = f.tell() 37257db96d56Sopenharmony_ci self.assertEqual(unpickler.load(), data1) 37267db96d56Sopenharmony_ci if seekable: 37277db96d56Sopenharmony_ci self.assertEqual(f.tell(), pos + len(pickled)) 37287db96d56Sopenharmony_ci self.assertRaises(EOFError, unpickler.load) 37297db96d56Sopenharmony_ci 37307db96d56Sopenharmony_ci def test_multiple_unpicklings_seekable(self): 37317db96d56Sopenharmony_ci self._check_multiple_unpicklings(io.BytesIO) 37327db96d56Sopenharmony_ci 37337db96d56Sopenharmony_ci def test_multiple_unpicklings_unseekable(self): 37347db96d56Sopenharmony_ci self._check_multiple_unpicklings(UnseekableIO, seekable=False) 37357db96d56Sopenharmony_ci 37367db96d56Sopenharmony_ci def test_multiple_unpicklings_minimal(self): 37377db96d56Sopenharmony_ci # File-like object that doesn't support peek() and readinto() 37387db96d56Sopenharmony_ci # (bpo-39681) 37397db96d56Sopenharmony_ci self._check_multiple_unpicklings(MinimalIO, seekable=False) 37407db96d56Sopenharmony_ci 37417db96d56Sopenharmony_ci def test_unpickling_buffering_readline(self): 37427db96d56Sopenharmony_ci # Issue #12687: the unpickler's buffering logic could fail with 37437db96d56Sopenharmony_ci # text mode opcodes. 37447db96d56Sopenharmony_ci data = list(range(10)) 37457db96d56Sopenharmony_ci for proto in protocols: 37467db96d56Sopenharmony_ci for buf_size in range(1, 11): 37477db96d56Sopenharmony_ci f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size) 37487db96d56Sopenharmony_ci pickler = self.pickler_class(f, protocol=proto) 37497db96d56Sopenharmony_ci pickler.dump(data) 37507db96d56Sopenharmony_ci f.seek(0) 37517db96d56Sopenharmony_ci unpickler = self.unpickler_class(f) 37527db96d56Sopenharmony_ci self.assertEqual(unpickler.load(), data) 37537db96d56Sopenharmony_ci 37547db96d56Sopenharmony_ci 37557db96d56Sopenharmony_ci# Tests for dispatch_table attribute 37567db96d56Sopenharmony_ci 37577db96d56Sopenharmony_ciREDUCE_A = 'reduce_A' 37587db96d56Sopenharmony_ci 37597db96d56Sopenharmony_ciclass AAA(object): 37607db96d56Sopenharmony_ci def __reduce__(self): 37617db96d56Sopenharmony_ci return str, (REDUCE_A,) 37627db96d56Sopenharmony_ci 37637db96d56Sopenharmony_ciclass BBB(object): 37647db96d56Sopenharmony_ci def __init__(self): 37657db96d56Sopenharmony_ci # Add an instance attribute to enable state-saving routines at pickling 37667db96d56Sopenharmony_ci # time. 37677db96d56Sopenharmony_ci self.a = "some attribute" 37687db96d56Sopenharmony_ci 37697db96d56Sopenharmony_ci def __setstate__(self, state): 37707db96d56Sopenharmony_ci self.a = "BBB.__setstate__" 37717db96d56Sopenharmony_ci 37727db96d56Sopenharmony_ci 37737db96d56Sopenharmony_cidef setstate_bbb(obj, state): 37747db96d56Sopenharmony_ci """Custom state setter for BBB objects 37757db96d56Sopenharmony_ci 37767db96d56Sopenharmony_ci Such callable may be created by other persons than the ones who created the 37777db96d56Sopenharmony_ci BBB class. If passed as the state_setter item of a custom reducer, this 37787db96d56Sopenharmony_ci allows for custom state setting behavior of BBB objects. One can think of 37797db96d56Sopenharmony_ci it as the analogous of list_setitems or dict_setitems but for foreign 37807db96d56Sopenharmony_ci classes/functions. 37817db96d56Sopenharmony_ci """ 37827db96d56Sopenharmony_ci obj.a = "custom state_setter" 37837db96d56Sopenharmony_ci 37847db96d56Sopenharmony_ci 37857db96d56Sopenharmony_ci 37867db96d56Sopenharmony_ciclass AbstractCustomPicklerClass: 37877db96d56Sopenharmony_ci """Pickler implementing a reducing hook using reducer_override.""" 37887db96d56Sopenharmony_ci def reducer_override(self, obj): 37897db96d56Sopenharmony_ci obj_name = getattr(obj, "__name__", None) 37907db96d56Sopenharmony_ci 37917db96d56Sopenharmony_ci if obj_name == 'f': 37927db96d56Sopenharmony_ci # asking the pickler to save f as 5 37937db96d56Sopenharmony_ci return int, (5, ) 37947db96d56Sopenharmony_ci 37957db96d56Sopenharmony_ci if obj_name == 'MyClass': 37967db96d56Sopenharmony_ci return str, ('some str',) 37977db96d56Sopenharmony_ci 37987db96d56Sopenharmony_ci elif obj_name == 'g': 37997db96d56Sopenharmony_ci # in this case, the callback returns an invalid result (not a 2-5 38007db96d56Sopenharmony_ci # tuple or a string), the pickler should raise a proper error. 38017db96d56Sopenharmony_ci return False 38027db96d56Sopenharmony_ci 38037db96d56Sopenharmony_ci elif obj_name == 'h': 38047db96d56Sopenharmony_ci # Simulate a case when the reducer fails. The error should 38057db96d56Sopenharmony_ci # be propagated to the original ``dump`` call. 38067db96d56Sopenharmony_ci raise ValueError('The reducer just failed') 38077db96d56Sopenharmony_ci 38087db96d56Sopenharmony_ci return NotImplemented 38097db96d56Sopenharmony_ci 38107db96d56Sopenharmony_ciclass AbstractHookTests: 38117db96d56Sopenharmony_ci def test_pickler_hook(self): 38127db96d56Sopenharmony_ci # test the ability of a custom, user-defined CPickler subclass to 38137db96d56Sopenharmony_ci # override the default reducing routines of any type using the method 38147db96d56Sopenharmony_ci # reducer_override 38157db96d56Sopenharmony_ci 38167db96d56Sopenharmony_ci def f(): 38177db96d56Sopenharmony_ci pass 38187db96d56Sopenharmony_ci 38197db96d56Sopenharmony_ci def g(): 38207db96d56Sopenharmony_ci pass 38217db96d56Sopenharmony_ci 38227db96d56Sopenharmony_ci def h(): 38237db96d56Sopenharmony_ci pass 38247db96d56Sopenharmony_ci 38257db96d56Sopenharmony_ci class MyClass: 38267db96d56Sopenharmony_ci pass 38277db96d56Sopenharmony_ci 38287db96d56Sopenharmony_ci for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): 38297db96d56Sopenharmony_ci with self.subTest(proto=proto): 38307db96d56Sopenharmony_ci bio = io.BytesIO() 38317db96d56Sopenharmony_ci p = self.pickler_class(bio, proto) 38327db96d56Sopenharmony_ci 38337db96d56Sopenharmony_ci p.dump([f, MyClass, math.log]) 38347db96d56Sopenharmony_ci new_f, some_str, math_log = pickle.loads(bio.getvalue()) 38357db96d56Sopenharmony_ci 38367db96d56Sopenharmony_ci self.assertEqual(new_f, 5) 38377db96d56Sopenharmony_ci self.assertEqual(some_str, 'some str') 38387db96d56Sopenharmony_ci # math.log does not have its usual reducer overridden, so the 38397db96d56Sopenharmony_ci # custom reduction callback should silently direct the pickler 38407db96d56Sopenharmony_ci # to the default pickling by attribute, by returning 38417db96d56Sopenharmony_ci # NotImplemented 38427db96d56Sopenharmony_ci self.assertIs(math_log, math.log) 38437db96d56Sopenharmony_ci 38447db96d56Sopenharmony_ci with self.assertRaises(pickle.PicklingError): 38457db96d56Sopenharmony_ci p.dump(g) 38467db96d56Sopenharmony_ci 38477db96d56Sopenharmony_ci with self.assertRaisesRegex( 38487db96d56Sopenharmony_ci ValueError, 'The reducer just failed'): 38497db96d56Sopenharmony_ci p.dump(h) 38507db96d56Sopenharmony_ci 38517db96d56Sopenharmony_ci @support.cpython_only 38527db96d56Sopenharmony_ci def test_reducer_override_no_reference_cycle(self): 38537db96d56Sopenharmony_ci # bpo-39492: reducer_override used to induce a spurious reference cycle 38547db96d56Sopenharmony_ci # inside the Pickler object, that could prevent all serialized objects 38557db96d56Sopenharmony_ci # from being garbage-collected without explicitly invoking gc.collect. 38567db96d56Sopenharmony_ci 38577db96d56Sopenharmony_ci for proto in range(0, pickle.HIGHEST_PROTOCOL + 1): 38587db96d56Sopenharmony_ci with self.subTest(proto=proto): 38597db96d56Sopenharmony_ci def f(): 38607db96d56Sopenharmony_ci pass 38617db96d56Sopenharmony_ci 38627db96d56Sopenharmony_ci wr = weakref.ref(f) 38637db96d56Sopenharmony_ci 38647db96d56Sopenharmony_ci bio = io.BytesIO() 38657db96d56Sopenharmony_ci p = self.pickler_class(bio, proto) 38667db96d56Sopenharmony_ci p.dump(f) 38677db96d56Sopenharmony_ci new_f = pickle.loads(bio.getvalue()) 38687db96d56Sopenharmony_ci assert new_f == 5 38697db96d56Sopenharmony_ci 38707db96d56Sopenharmony_ci del p 38717db96d56Sopenharmony_ci del f 38727db96d56Sopenharmony_ci 38737db96d56Sopenharmony_ci self.assertIsNone(wr()) 38747db96d56Sopenharmony_ci 38757db96d56Sopenharmony_ci 38767db96d56Sopenharmony_ciclass AbstractDispatchTableTests: 38777db96d56Sopenharmony_ci 38787db96d56Sopenharmony_ci def test_default_dispatch_table(self): 38797db96d56Sopenharmony_ci # No dispatch_table attribute by default 38807db96d56Sopenharmony_ci f = io.BytesIO() 38817db96d56Sopenharmony_ci p = self.pickler_class(f, 0) 38827db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 38837db96d56Sopenharmony_ci p.dispatch_table 38847db96d56Sopenharmony_ci self.assertFalse(hasattr(p, 'dispatch_table')) 38857db96d56Sopenharmony_ci 38867db96d56Sopenharmony_ci def test_class_dispatch_table(self): 38877db96d56Sopenharmony_ci # A dispatch_table attribute can be specified class-wide 38887db96d56Sopenharmony_ci dt = self.get_dispatch_table() 38897db96d56Sopenharmony_ci 38907db96d56Sopenharmony_ci class MyPickler(self.pickler_class): 38917db96d56Sopenharmony_ci dispatch_table = dt 38927db96d56Sopenharmony_ci 38937db96d56Sopenharmony_ci def dumps(obj, protocol=None): 38947db96d56Sopenharmony_ci f = io.BytesIO() 38957db96d56Sopenharmony_ci p = MyPickler(f, protocol) 38967db96d56Sopenharmony_ci self.assertEqual(p.dispatch_table, dt) 38977db96d56Sopenharmony_ci p.dump(obj) 38987db96d56Sopenharmony_ci return f.getvalue() 38997db96d56Sopenharmony_ci 39007db96d56Sopenharmony_ci self._test_dispatch_table(dumps, dt) 39017db96d56Sopenharmony_ci 39027db96d56Sopenharmony_ci def test_instance_dispatch_table(self): 39037db96d56Sopenharmony_ci # A dispatch_table attribute can also be specified instance-wide 39047db96d56Sopenharmony_ci dt = self.get_dispatch_table() 39057db96d56Sopenharmony_ci 39067db96d56Sopenharmony_ci def dumps(obj, protocol=None): 39077db96d56Sopenharmony_ci f = io.BytesIO() 39087db96d56Sopenharmony_ci p = self.pickler_class(f, protocol) 39097db96d56Sopenharmony_ci p.dispatch_table = dt 39107db96d56Sopenharmony_ci self.assertEqual(p.dispatch_table, dt) 39117db96d56Sopenharmony_ci p.dump(obj) 39127db96d56Sopenharmony_ci return f.getvalue() 39137db96d56Sopenharmony_ci 39147db96d56Sopenharmony_ci self._test_dispatch_table(dumps, dt) 39157db96d56Sopenharmony_ci 39167db96d56Sopenharmony_ci def _test_dispatch_table(self, dumps, dispatch_table): 39177db96d56Sopenharmony_ci def custom_load_dump(obj): 39187db96d56Sopenharmony_ci return pickle.loads(dumps(obj, 0)) 39197db96d56Sopenharmony_ci 39207db96d56Sopenharmony_ci def default_load_dump(obj): 39217db96d56Sopenharmony_ci return pickle.loads(pickle.dumps(obj, 0)) 39227db96d56Sopenharmony_ci 39237db96d56Sopenharmony_ci # pickling complex numbers using protocol 0 relies on copyreg 39247db96d56Sopenharmony_ci # so check pickling a complex number still works 39257db96d56Sopenharmony_ci z = 1 + 2j 39267db96d56Sopenharmony_ci self.assertEqual(custom_load_dump(z), z) 39277db96d56Sopenharmony_ci self.assertEqual(default_load_dump(z), z) 39287db96d56Sopenharmony_ci 39297db96d56Sopenharmony_ci # modify pickling of complex 39307db96d56Sopenharmony_ci REDUCE_1 = 'reduce_1' 39317db96d56Sopenharmony_ci def reduce_1(obj): 39327db96d56Sopenharmony_ci return str, (REDUCE_1,) 39337db96d56Sopenharmony_ci dispatch_table[complex] = reduce_1 39347db96d56Sopenharmony_ci self.assertEqual(custom_load_dump(z), REDUCE_1) 39357db96d56Sopenharmony_ci self.assertEqual(default_load_dump(z), z) 39367db96d56Sopenharmony_ci 39377db96d56Sopenharmony_ci # check picklability of AAA and BBB 39387db96d56Sopenharmony_ci a = AAA() 39397db96d56Sopenharmony_ci b = BBB() 39407db96d56Sopenharmony_ci self.assertEqual(custom_load_dump(a), REDUCE_A) 39417db96d56Sopenharmony_ci self.assertIsInstance(custom_load_dump(b), BBB) 39427db96d56Sopenharmony_ci self.assertEqual(default_load_dump(a), REDUCE_A) 39437db96d56Sopenharmony_ci self.assertIsInstance(default_load_dump(b), BBB) 39447db96d56Sopenharmony_ci 39457db96d56Sopenharmony_ci # modify pickling of BBB 39467db96d56Sopenharmony_ci dispatch_table[BBB] = reduce_1 39477db96d56Sopenharmony_ci self.assertEqual(custom_load_dump(a), REDUCE_A) 39487db96d56Sopenharmony_ci self.assertEqual(custom_load_dump(b), REDUCE_1) 39497db96d56Sopenharmony_ci self.assertEqual(default_load_dump(a), REDUCE_A) 39507db96d56Sopenharmony_ci self.assertIsInstance(default_load_dump(b), BBB) 39517db96d56Sopenharmony_ci 39527db96d56Sopenharmony_ci # revert pickling of BBB and modify pickling of AAA 39537db96d56Sopenharmony_ci REDUCE_2 = 'reduce_2' 39547db96d56Sopenharmony_ci def reduce_2(obj): 39557db96d56Sopenharmony_ci return str, (REDUCE_2,) 39567db96d56Sopenharmony_ci dispatch_table[AAA] = reduce_2 39577db96d56Sopenharmony_ci del dispatch_table[BBB] 39587db96d56Sopenharmony_ci self.assertEqual(custom_load_dump(a), REDUCE_2) 39597db96d56Sopenharmony_ci self.assertIsInstance(custom_load_dump(b), BBB) 39607db96d56Sopenharmony_ci self.assertEqual(default_load_dump(a), REDUCE_A) 39617db96d56Sopenharmony_ci self.assertIsInstance(default_load_dump(b), BBB) 39627db96d56Sopenharmony_ci 39637db96d56Sopenharmony_ci # End-to-end testing of save_reduce with the state_setter keyword 39647db96d56Sopenharmony_ci # argument. This is a dispatch_table test as the primary goal of 39657db96d56Sopenharmony_ci # state_setter is to tweak objects reduction behavior. 39667db96d56Sopenharmony_ci # In particular, state_setter is useful when the default __setstate__ 39677db96d56Sopenharmony_ci # behavior is not flexible enough. 39687db96d56Sopenharmony_ci 39697db96d56Sopenharmony_ci # No custom reducer for b has been registered for now, so 39707db96d56Sopenharmony_ci # BBB.__setstate__ should be used at unpickling time 39717db96d56Sopenharmony_ci self.assertEqual(default_load_dump(b).a, "BBB.__setstate__") 39727db96d56Sopenharmony_ci 39737db96d56Sopenharmony_ci def reduce_bbb(obj): 39747db96d56Sopenharmony_ci return BBB, (), obj.__dict__, None, None, setstate_bbb 39757db96d56Sopenharmony_ci 39767db96d56Sopenharmony_ci dispatch_table[BBB] = reduce_bbb 39777db96d56Sopenharmony_ci 39787db96d56Sopenharmony_ci # The custom reducer reduce_bbb includes a state setter, that should 39797db96d56Sopenharmony_ci # have priority over BBB.__setstate__ 39807db96d56Sopenharmony_ci self.assertEqual(custom_load_dump(b).a, "custom state_setter") 39817db96d56Sopenharmony_ci 39827db96d56Sopenharmony_ci 39837db96d56Sopenharmony_ciif __name__ == "__main__": 39847db96d56Sopenharmony_ci # Print some stuff that can be used to rewrite DATA{0,1,2} 39857db96d56Sopenharmony_ci from pickletools import dis 39867db96d56Sopenharmony_ci x = create_data() 39877db96d56Sopenharmony_ci for i in range(pickle.HIGHEST_PROTOCOL+1): 39887db96d56Sopenharmony_ci p = pickle.dumps(x, i) 39897db96d56Sopenharmony_ci print("DATA{0} = (".format(i)) 39907db96d56Sopenharmony_ci for j in range(0, len(p), 20): 39917db96d56Sopenharmony_ci b = bytes(p[j:j+20]) 39927db96d56Sopenharmony_ci print(" {0!r}".format(b)) 39937db96d56Sopenharmony_ci print(")") 39947db96d56Sopenharmony_ci print() 39957db96d56Sopenharmony_ci print("# Disassembly of DATA{0}".format(i)) 39967db96d56Sopenharmony_ci print("DATA{0}_DIS = \"\"\"\\".format(i)) 39977db96d56Sopenharmony_ci dis(p) 39987db96d56Sopenharmony_ci print("\"\"\"") 39997db96d56Sopenharmony_ci print() 4000