xref: /third_party/python/Lib/test/pickletester.py (revision 7db96d56)
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