import builtins
import collections
import copyreg
import dbm
import io
import functools
import os
import math
import pickle
import pickletools
import shutil
import struct
import sys
import threading
import types
import unittest
import weakref
import __main__
from textwrap import dedent
from http.cookies import SimpleCookie

try:
    import _testbuffer
except ImportError:
    _testbuffer = None

from test import support
from test.support import os_helper
from test.support import (
    run_with_locales, no_tracing,
    _2G, _4G, bigmemtest
    )
from test.support.import_helper import forget
from test.support.os_helper import TESTFN
from test.support import threading_helper
from test.support.warnings_helper import save_restore_warnings_filters
from test import picklecommon
from test.picklecommon import *

from pickle import bytes_types


# bpo-41003: Save/restore warnings filters to leave them unchanged.
# Ignore filters installed by numpy.
try:
    with save_restore_warnings_filters():
        import numpy as np
except ImportError:
    np = None


requires_32b = unittest.skipUnless(sys.maxsize < 2**32,
                                   "test is only meaningful on 32-bit builds")

# Tests that try a number of pickle protocols should have a
#     for proto in protocols:
# kind of outer loop.
protocols = range(pickle.HIGHEST_PROTOCOL + 1)


# Return True if opcode code appears in the pickle, else False.
def opcode_in_pickle(code, pickle):
    for op, dummy, dummy in pickletools.genops(pickle):
        if op.code == code.decode("latin-1"):
            return True
    return False

# Return the number of times opcode code appears in pickle.
def count_opcode(code, pickle):
    n = 0
    for op, dummy, dummy in pickletools.genops(pickle):
        if op.code == code.decode("latin-1"):
            n += 1
    return n


def identity(x):
    return x

def itersize(start, stop):
    # Produce geometrical increasing sequence from start to stop
    # (inclusively) for tests.
    size = start
    while size < stop:
        yield size
        size <<= 1
    yield stop


class UnseekableIO(io.BytesIO):
    def peek(self, *args):
        raise NotImplementedError

    def seekable(self):
        return False

    def seek(self, *args):
        raise io.UnsupportedOperation

    def tell(self):
        raise io.UnsupportedOperation


class MinimalIO(object):
    """
    A file-like object that doesn't support readinto().
    """
    def __init__(self, *args):
        self._bio = io.BytesIO(*args)
        self.getvalue = self._bio.getvalue
        self.read = self._bio.read
        self.readline = self._bio.readline
        self.write = self._bio.write


# We can't very well test the extension registry without putting known stuff
# in it, but we have to be careful to restore its original state.  Code
# should do this:
#
#     e = ExtensionSaver(extension_code)
#     try:
#         fiddle w/ the extension registry's stuff for extension_code
#     finally:
#         e.restore()

class ExtensionSaver:
    # Remember current registration for code (if any), and remove it (if
    # there is one).
    def __init__(self, code):
        self.code = code
        if code in copyreg._inverted_registry:
            self.pair = copyreg._inverted_registry[code]
            copyreg.remove_extension(self.pair[0], self.pair[1], code)
        else:
            self.pair = None

    # Restore previous registration for code.
    def restore(self):
        code = self.code
        curpair = copyreg._inverted_registry.get(code)
        if curpair is not None:
            copyreg.remove_extension(curpair[0], curpair[1], code)
        pair = self.pair
        if pair is not None:
            copyreg.add_extension(pair[0], pair[1], code)

class pickling_metaclass(type):
    def __eq__(self, other):
        return (type(self) == type(other) and
                self.reduce_args == other.reduce_args)

    def __reduce__(self):
        return (create_dynamic_class, self.reduce_args)

def create_dynamic_class(name, bases):
    result = pickling_metaclass(name, bases, dict())
    result.reduce_args = (name, bases)
    return result


if _testbuffer is not None:

    class PicklableNDArray:
        # A not-really-zero-copy picklable ndarray, as the ndarray()
        # constructor doesn't allow for it

        zero_copy_reconstruct = False

        def __init__(self, *args, **kwargs):
            self.array = _testbuffer.ndarray(*args, **kwargs)

        def __getitem__(self, idx):
            cls = type(self)
            new = cls.__new__(cls)
            new.array = self.array[idx]
            return new

        @property
        def readonly(self):
            return self.array.readonly

        @property
        def c_contiguous(self):
            return self.array.c_contiguous

        @property
        def f_contiguous(self):
            return self.array.f_contiguous

        def __eq__(self, other):
            if not isinstance(other, PicklableNDArray):
                return NotImplemented
            return (other.array.format == self.array.format and
                    other.array.shape == self.array.shape and
                    other.array.strides == self.array.strides and
                    other.array.readonly == self.array.readonly and
                    other.array.tobytes() == self.array.tobytes())

        def __ne__(self, other):
            if not isinstance(other, PicklableNDArray):
                return NotImplemented
            return not (self == other)

        def __repr__(self):
            return ("{name}(shape={array.shape},"
                    "strides={array.strides}, "
                    "bytes={array.tobytes()})").format(
                    name=type(self).__name__, array=self.array.shape)

        def __reduce_ex__(self, protocol):
            if not self.array.contiguous:
                raise NotImplementedError("Reconstructing a non-contiguous "
                                          "ndarray does not seem possible")
            ndarray_kwargs = {"shape": self.array.shape,
                              "strides": self.array.strides,
                              "format": self.array.format,
                              "flags": (0 if self.readonly
                                        else _testbuffer.ND_WRITABLE)}
            pb = pickle.PickleBuffer(self.array)
            if protocol >= 5:
                return (type(self)._reconstruct,
                        (pb, ndarray_kwargs))
            else:
                # Need to serialize the bytes in physical order
                with pb.raw() as m:
                    return (type(self)._reconstruct,
                            (m.tobytes(), ndarray_kwargs))

        @classmethod
        def _reconstruct(cls, obj, kwargs):
            with memoryview(obj) as m:
                # For some reason, ndarray() wants a list of integers...
                # XXX This only works if format == 'B'
                items = list(m.tobytes())
            return cls(items, **kwargs)


# DATA0 .. DATA4 are the pickles we expect under the various protocols, for
# the object returned by create_data().

DATA0 = (
    b'(lp0\nL0L\naL1L\naF2.0\n'
    b'ac__builtin__\ncomple'
    b'x\np1\n(F3.0\nF0.0\ntp2\n'
    b'Rp3\naL1L\naL-1L\naL255'
    b'L\naL-255L\naL-256L\naL'
    b'65535L\naL-65535L\naL-'
    b'65536L\naL2147483647L'
    b'\naL-2147483647L\naL-2'
    b'147483648L\na(Vabc\np4'
    b'\ng4\nccopy_reg\n_recon'
    b'structor\np5\n(c__main'
    b'__\nC\np6\nc__builtin__'
    b'\nobject\np7\nNtp8\nRp9\n'
    b'(dp10\nVfoo\np11\nL1L\ns'
    b'Vbar\np12\nL2L\nsbg9\ntp'
    b'13\nag13\naL5L\na.'
)

# Disassembly of DATA0
DATA0_DIS = """\
    0: (    MARK
    1: l        LIST       (MARK at 0)
    2: p    PUT        0
    5: L    LONG       0
    9: a    APPEND
   10: L    LONG       1
   14: a    APPEND
   15: F    FLOAT      2.0
   20: a    APPEND
   21: c    GLOBAL     '__builtin__ complex'
   42: p    PUT        1
   45: (    MARK
   46: F        FLOAT      3.0
   51: F        FLOAT      0.0
   56: t        TUPLE      (MARK at 45)
   57: p    PUT        2
   60: R    REDUCE
   61: p    PUT        3
   64: a    APPEND
   65: L    LONG       1
   69: a    APPEND
   70: L    LONG       -1
   75: a    APPEND
   76: L    LONG       255
   82: a    APPEND
   83: L    LONG       -255
   90: a    APPEND
   91: L    LONG       -256
   98: a    APPEND
   99: L    LONG       65535
  107: a    APPEND
  108: L    LONG       -65535
  117: a    APPEND
  118: L    LONG       -65536
  127: a    APPEND
  128: L    LONG       2147483647
  141: a    APPEND
  142: L    LONG       -2147483647
  156: a    APPEND
  157: L    LONG       -2147483648
  171: a    APPEND
  172: (    MARK
  173: V        UNICODE    'abc'
  178: p        PUT        4
  181: g        GET        4
  184: c        GLOBAL     'copy_reg _reconstructor'
  209: p        PUT        5
  212: (        MARK
  213: c            GLOBAL     '__main__ C'
  225: p            PUT        6
  228: c            GLOBAL     '__builtin__ object'
  248: p            PUT        7
  251: N            NONE
  252: t            TUPLE      (MARK at 212)
  253: p        PUT        8
  256: R        REDUCE
  257: p        PUT        9
  260: (        MARK
  261: d            DICT       (MARK at 260)
  262: p        PUT        10
  266: V        UNICODE    'foo'
  271: p        PUT        11
  275: L        LONG       1
  279: s        SETITEM
  280: V        UNICODE    'bar'
  285: p        PUT        12
  289: L        LONG       2
  293: s        SETITEM
  294: b        BUILD
  295: g        GET        9
  298: t        TUPLE      (MARK at 172)
  299: p    PUT        13
  303: a    APPEND
  304: g    GET        13
  308: a    APPEND
  309: L    LONG       5
  313: a    APPEND
  314: .    STOP
highest protocol among opcodes = 0
"""

DATA1 = (
    b']q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c__'
    b'builtin__\ncomplex\nq\x01'
    b'(G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00t'
    b'q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ'
    b'\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff'
    b'\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00ab'
    b'cq\x04h\x04ccopy_reg\n_reco'
    b'nstructor\nq\x05(c__main'
    b'__\nC\nq\x06c__builtin__\n'
    b'object\nq\x07Ntq\x08Rq\t}q\n('
    b'X\x03\x00\x00\x00fooq\x0bK\x01X\x03\x00\x00\x00bar'
    b'q\x0cK\x02ubh\ttq\rh\rK\x05e.'
)

# Disassembly of DATA1
DATA1_DIS = """\
    0: ]    EMPTY_LIST
    1: q    BINPUT     0
    3: (    MARK
    4: K        BININT1    0
    6: K        BININT1    1
    8: G        BINFLOAT   2.0
   17: c        GLOBAL     '__builtin__ complex'
   38: q        BINPUT     1
   40: (        MARK
   41: G            BINFLOAT   3.0
   50: G            BINFLOAT   0.0
   59: t            TUPLE      (MARK at 40)
   60: q        BINPUT     2
   62: R        REDUCE
   63: q        BINPUT     3
   65: K        BININT1    1
   67: J        BININT     -1
   72: K        BININT1    255
   74: J        BININT     -255
   79: J        BININT     -256
   84: M        BININT2    65535
   87: J        BININT     -65535
   92: J        BININT     -65536
   97: J        BININT     2147483647
  102: J        BININT     -2147483647
  107: J        BININT     -2147483648
  112: (        MARK
  113: X            BINUNICODE 'abc'
  121: q            BINPUT     4
  123: h            BINGET     4
  125: c            GLOBAL     'copy_reg _reconstructor'
  150: q            BINPUT     5
  152: (            MARK
  153: c                GLOBAL     '__main__ C'
  165: q                BINPUT     6
  167: c                GLOBAL     '__builtin__ object'
  187: q                BINPUT     7
  189: N                NONE
  190: t                TUPLE      (MARK at 152)
  191: q            BINPUT     8
  193: R            REDUCE
  194: q            BINPUT     9
  196: }            EMPTY_DICT
  197: q            BINPUT     10
  199: (            MARK
  200: X                BINUNICODE 'foo'
  208: q                BINPUT     11
  210: K                BININT1    1
  212: X                BINUNICODE 'bar'
  220: q                BINPUT     12
  222: K                BININT1    2
  224: u                SETITEMS   (MARK at 199)
  225: b            BUILD
  226: h            BINGET     9
  228: t            TUPLE      (MARK at 112)
  229: q        BINPUT     13
  231: h        BINGET     13
  233: K        BININT1    5
  235: e        APPENDS    (MARK at 3)
  236: .    STOP
highest protocol among opcodes = 1
"""

DATA2 = (
    b'\x80\x02]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
    b'__builtin__\ncomplex\n'
    b'q\x01G@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00'
    b'\x86q\x02Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xff'
    b'J\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff'
    b'\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00a'
    b'bcq\x04h\x04c__main__\nC\nq\x05'
    b')\x81q\x06}q\x07(X\x03\x00\x00\x00fooq\x08K\x01'
    b'X\x03\x00\x00\x00barq\tK\x02ubh\x06tq\nh'
    b'\nK\x05e.'
)

# Disassembly of DATA2
DATA2_DIS = """\
    0: \x80 PROTO      2
    2: ]    EMPTY_LIST
    3: q    BINPUT     0
    5: (    MARK
    6: K        BININT1    0
    8: K        BININT1    1
   10: G        BINFLOAT   2.0
   19: c        GLOBAL     '__builtin__ complex'
   40: q        BINPUT     1
   42: G        BINFLOAT   3.0
   51: G        BINFLOAT   0.0
   60: \x86     TUPLE2
   61: q        BINPUT     2
   63: R        REDUCE
   64: q        BINPUT     3
   66: K        BININT1    1
   68: J        BININT     -1
   73: K        BININT1    255
   75: J        BININT     -255
   80: J        BININT     -256
   85: M        BININT2    65535
   88: J        BININT     -65535
   93: J        BININT     -65536
   98: J        BININT     2147483647
  103: J        BININT     -2147483647
  108: J        BININT     -2147483648
  113: (        MARK
  114: X            BINUNICODE 'abc'
  122: q            BINPUT     4
  124: h            BINGET     4
  126: c            GLOBAL     '__main__ C'
  138: q            BINPUT     5
  140: )            EMPTY_TUPLE
  141: \x81         NEWOBJ
  142: q            BINPUT     6
  144: }            EMPTY_DICT
  145: q            BINPUT     7
  147: (            MARK
  148: X                BINUNICODE 'foo'
  156: q                BINPUT     8
  158: K                BININT1    1
  160: X                BINUNICODE 'bar'
  168: q                BINPUT     9
  170: K                BININT1    2
  172: u                SETITEMS   (MARK at 147)
  173: b            BUILD
  174: h            BINGET     6
  176: t            TUPLE      (MARK at 113)
  177: q        BINPUT     10
  179: h        BINGET     10
  181: K        BININT1    5
  183: e        APPENDS    (MARK at 5)
  184: .    STOP
highest protocol among opcodes = 2
"""

DATA3 = (
    b'\x80\x03]q\x00(K\x00K\x01G@\x00\x00\x00\x00\x00\x00\x00c'
    b'builtins\ncomplex\nq\x01G'
    b'@\x08\x00\x00\x00\x00\x00\x00G\x00\x00\x00\x00\x00\x00\x00\x00\x86q\x02'
    b'Rq\x03K\x01J\xff\xff\xff\xffK\xffJ\x01\xff\xff\xffJ\x00\xff'
    b'\xff\xffM\xff\xffJ\x01\x00\xff\xffJ\x00\x00\xff\xffJ\xff\xff\xff\x7f'
    b'J\x01\x00\x00\x80J\x00\x00\x00\x80(X\x03\x00\x00\x00abcq'
    b'\x04h\x04c__main__\nC\nq\x05)\x81q'
    b'\x06}q\x07(X\x03\x00\x00\x00barq\x08K\x02X\x03\x00'
    b'\x00\x00fooq\tK\x01ubh\x06tq\nh\nK\x05'
    b'e.'
)

# Disassembly of DATA3
DATA3_DIS = """\
    0: \x80 PROTO      3
    2: ]    EMPTY_LIST
    3: q    BINPUT     0
    5: (    MARK
    6: K        BININT1    0
    8: K        BININT1    1
   10: G        BINFLOAT   2.0
   19: c        GLOBAL     'builtins complex'
   37: q        BINPUT     1
   39: G        BINFLOAT   3.0
   48: G        BINFLOAT   0.0
   57: \x86     TUPLE2
   58: q        BINPUT     2
   60: R        REDUCE
   61: q        BINPUT     3
   63: K        BININT1    1
   65: J        BININT     -1
   70: K        BININT1    255
   72: J        BININT     -255
   77: J        BININT     -256
   82: M        BININT2    65535
   85: J        BININT     -65535
   90: J        BININT     -65536
   95: J        BININT     2147483647
  100: J        BININT     -2147483647
  105: J        BININT     -2147483648
  110: (        MARK
  111: X            BINUNICODE 'abc'
  119: q            BINPUT     4
  121: h            BINGET     4
  123: c            GLOBAL     '__main__ C'
  135: q            BINPUT     5
  137: )            EMPTY_TUPLE
  138: \x81         NEWOBJ
  139: q            BINPUT     6
  141: }            EMPTY_DICT
  142: q            BINPUT     7
  144: (            MARK
  145: X                BINUNICODE 'bar'
  153: q                BINPUT     8
  155: K                BININT1    2
  157: X                BINUNICODE 'foo'
  165: q                BINPUT     9
  167: K                BININT1    1
  169: u                SETITEMS   (MARK at 144)
  170: b            BUILD
  171: h            BINGET     6
  173: t            TUPLE      (MARK at 110)
  174: q        BINPUT     10
  176: h        BINGET     10
  178: K        BININT1    5
  180: e        APPENDS    (MARK at 5)
  181: .    STOP
highest protocol among opcodes = 2
"""

DATA4 = (
    b'\x80\x04\x95\xa8\x00\x00\x00\x00\x00\x00\x00]\x94(K\x00K\x01G@'
    b'\x00\x00\x00\x00\x00\x00\x00\x8c\x08builtins\x94\x8c\x07'
    b'complex\x94\x93\x94G@\x08\x00\x00\x00\x00\x00\x00G'
    b'\x00\x00\x00\x00\x00\x00\x00\x00\x86\x94R\x94K\x01J\xff\xff\xff\xffK'
    b'\xffJ\x01\xff\xff\xffJ\x00\xff\xff\xffM\xff\xffJ\x01\x00\xff\xffJ'
    b'\x00\x00\xff\xffJ\xff\xff\xff\x7fJ\x01\x00\x00\x80J\x00\x00\x00\x80('
    b'\x8c\x03abc\x94h\x06\x8c\x08__main__\x94\x8c'
    b'\x01C\x94\x93\x94)\x81\x94}\x94(\x8c\x03bar\x94K\x02\x8c'
    b'\x03foo\x94K\x01ubh\nt\x94h\x0eK\x05e.'
)

# Disassembly of DATA4
DATA4_DIS = """\
    0: \x80 PROTO      4
    2: \x95 FRAME      168
   11: ]    EMPTY_LIST
   12: \x94 MEMOIZE
   13: (    MARK
   14: K        BININT1    0
   16: K        BININT1    1
   18: G        BINFLOAT   2.0
   27: \x8c     SHORT_BINUNICODE 'builtins'
   37: \x94     MEMOIZE
   38: \x8c     SHORT_BINUNICODE 'complex'
   47: \x94     MEMOIZE
   48: \x93     STACK_GLOBAL
   49: \x94     MEMOIZE
   50: G        BINFLOAT   3.0
   59: G        BINFLOAT   0.0
   68: \x86     TUPLE2
   69: \x94     MEMOIZE
   70: R        REDUCE
   71: \x94     MEMOIZE
   72: K        BININT1    1
   74: J        BININT     -1
   79: K        BININT1    255
   81: J        BININT     -255
   86: J        BININT     -256
   91: M        BININT2    65535
   94: J        BININT     -65535
   99: J        BININT     -65536
  104: J        BININT     2147483647
  109: J        BININT     -2147483647
  114: J        BININT     -2147483648
  119: (        MARK
  120: \x8c         SHORT_BINUNICODE 'abc'
  125: \x94         MEMOIZE
  126: h            BINGET     6
  128: \x8c         SHORT_BINUNICODE '__main__'
  138: \x94         MEMOIZE
  139: \x8c         SHORT_BINUNICODE 'C'
  142: \x94         MEMOIZE
  143: \x93         STACK_GLOBAL
  144: \x94         MEMOIZE
  145: )            EMPTY_TUPLE
  146: \x81         NEWOBJ
  147: \x94         MEMOIZE
  148: }            EMPTY_DICT
  149: \x94         MEMOIZE
  150: (            MARK
  151: \x8c             SHORT_BINUNICODE 'bar'
  156: \x94             MEMOIZE
  157: K                BININT1    2
  159: \x8c             SHORT_BINUNICODE 'foo'
  164: \x94             MEMOIZE
  165: K                BININT1    1
  167: u                SETITEMS   (MARK at 150)
  168: b            BUILD
  169: h            BINGET     10
  171: t            TUPLE      (MARK at 119)
  172: \x94     MEMOIZE
  173: h        BINGET     14
  175: K        BININT1    5
  177: e        APPENDS    (MARK at 13)
  178: .    STOP
highest protocol among opcodes = 4
"""

# set([1,2]) pickled from 2.x with protocol 2
DATA_SET = b'\x80\x02c__builtin__\nset\nq\x00]q\x01(K\x01K\x02e\x85q\x02Rq\x03.'

# xrange(5) pickled from 2.x with protocol 2
DATA_XRANGE = b'\x80\x02c__builtin__\nxrange\nq\x00K\x00K\x05K\x01\x87q\x01Rq\x02.'

# a SimpleCookie() object pickled from 2.x with protocol 2
DATA_COOKIE = (b'\x80\x02cCookie\nSimpleCookie\nq\x00)\x81q\x01U\x03key'
               b'q\x02cCookie\nMorsel\nq\x03)\x81q\x04(U\x07commentq\x05U'
               b'\x00q\x06U\x06domainq\x07h\x06U\x06secureq\x08h\x06U\x07'
               b'expiresq\th\x06U\x07max-ageq\nh\x06U\x07versionq\x0bh\x06U'
               b'\x04pathq\x0ch\x06U\x08httponlyq\rh\x06u}q\x0e(U\x0b'
               b'coded_valueq\x0fU\x05valueq\x10h\x10h\x10h\x02h\x02ubs}q\x11b.')

# set([3]) pickled from 2.x with protocol 2
DATA_SET2 = b'\x80\x02c__builtin__\nset\nq\x00]q\x01K\x03a\x85q\x02Rq\x03.'

python2_exceptions_without_args = (
    ArithmeticError,
    AssertionError,
    AttributeError,
    BaseException,
    BufferError,
    BytesWarning,
    DeprecationWarning,
    EOFError,
    EnvironmentError,
    Exception,
    FloatingPointError,
    FutureWarning,
    GeneratorExit,
    IOError,
    ImportError,
    ImportWarning,
    IndentationError,
    IndexError,
    KeyError,
    KeyboardInterrupt,
    LookupError,
    MemoryError,
    NameError,
    NotImplementedError,
    OSError,
    OverflowError,
    PendingDeprecationWarning,
    ReferenceError,
    RuntimeError,
    RuntimeWarning,
    # StandardError is gone in Python 3, we map it to Exception
    StopIteration,
    SyntaxError,
    SyntaxWarning,
    SystemError,
    SystemExit,
    TabError,
    TypeError,
    UnboundLocalError,
    UnicodeError,
    UnicodeWarning,
    UserWarning,
    ValueError,
    Warning,
    ZeroDivisionError,
)

exception_pickle = b'\x80\x02cexceptions\n?\nq\x00)Rq\x01.'

# UnicodeEncodeError object pickled from 2.x with protocol 2
DATA_UEERR = (b'\x80\x02cexceptions\nUnicodeEncodeError\n'
              b'q\x00(U\x05asciiq\x01X\x03\x00\x00\x00fooq\x02K\x00K\x01'
              b'U\x03badq\x03tq\x04Rq\x05.')


def create_data():
    c = C()
    c.foo = 1
    c.bar = 2
    x = [0, 1, 2.0, 3.0+0j]
    # Append some integer test cases at cPickle.c's internal size
    # cutoffs.
    uint1max = 0xff
    uint2max = 0xffff
    int4max = 0x7fffffff
    x.extend([1, -1,
              uint1max, -uint1max, -uint1max-1,
              uint2max, -uint2max, -uint2max-1,
               int4max,  -int4max,  -int4max-1])
    y = ('abc', 'abc', c, c)
    x.append(y)
    x.append(y)
    x.append(5)
    return x


class AbstractUnpickleTests:
    # Subclass must define self.loads.

    _testdata = create_data()

    def assert_is_copy(self, obj, objcopy, msg=None):
        """Utility method to verify if two objects are copies of each others.
        """
        if msg is None:
            msg = "{!r} is not a copy of {!r}".format(obj, objcopy)
        self.assertEqual(obj, objcopy, msg=msg)
        self.assertIs(type(obj), type(objcopy), msg=msg)
        if hasattr(obj, '__dict__'):
            self.assertDictEqual(obj.__dict__, objcopy.__dict__, msg=msg)
            self.assertIsNot(obj.__dict__, objcopy.__dict__, msg=msg)
        if hasattr(obj, '__slots__'):
            self.assertListEqual(obj.__slots__, objcopy.__slots__, msg=msg)
            for slot in obj.__slots__:
                self.assertEqual(
                    hasattr(obj, slot), hasattr(objcopy, slot), msg=msg)
                self.assertEqual(getattr(obj, slot, None),
                                 getattr(objcopy, slot, None), msg=msg)

    def check_unpickling_error_strict(self, errors, data):
        with self.assertRaises(errors):
            try:
                self.loads(data)
            except BaseException as exc:
                if support.verbose > 1:
                    print('%-32r - %s: %s' %
                          (data, exc.__class__.__name__, exc))
                raise

    def check_unpickling_error(self, errors, data):
        with self.subTest(data=data):
            self.check_unpickling_error_strict(errors, data)

    def test_load_from_data0(self):
        self.assert_is_copy(self._testdata, self.loads(DATA0))

    def test_load_from_data1(self):
        self.assert_is_copy(self._testdata, self.loads(DATA1))

    def test_load_from_data2(self):
        self.assert_is_copy(self._testdata, self.loads(DATA2))

    def test_load_from_data3(self):
        self.assert_is_copy(self._testdata, self.loads(DATA3))

    def test_load_from_data4(self):
        self.assert_is_copy(self._testdata, self.loads(DATA4))

    def test_load_classic_instance(self):
        # See issue5180.  Test loading 2.x pickles that
        # contain an instance of old style class.
        for X, args in [(C, ()), (D, ('x',)), (E, ())]:
            xname = X.__name__.encode('ascii')
            # Protocol 0 (text mode pickle):
            """
             0: (    MARK
             1: i        INST       '__main__ X' (MARK at 0)
            13: p    PUT        0
            16: (    MARK
            17: d        DICT       (MARK at 16)
            18: p    PUT        1
            21: b    BUILD
            22: .    STOP
            """
            pickle0 = (b"(i__main__\n"
                       b"X\n"
                       b"p0\n"
                       b"(dp1\nb.").replace(b'X', xname)
            self.assert_is_copy(X(*args), self.loads(pickle0))

            # Protocol 1 (binary mode pickle)
            """
             0: (    MARK
             1: c        GLOBAL     '__main__ X'
            13: q        BINPUT     0
            15: o        OBJ        (MARK at 0)
            16: q    BINPUT     1
            18: }    EMPTY_DICT
            19: q    BINPUT     2
            21: b    BUILD
            22: .    STOP
            """
            pickle1 = (b'(c__main__\n'
                       b'X\n'
                       b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
            self.assert_is_copy(X(*args), self.loads(pickle1))

            # Protocol 2 (pickle2 = b'\x80\x02' + pickle1)
            """
             0: \x80 PROTO      2
             2: (    MARK
             3: c        GLOBAL     '__main__ X'
            15: q        BINPUT     0
            17: o        OBJ        (MARK at 2)
            18: q    BINPUT     1
            20: }    EMPTY_DICT
            21: q    BINPUT     2
            23: b    BUILD
            24: .    STOP
            """
            pickle2 = (b'\x80\x02(c__main__\n'
                       b'X\n'
                       b'q\x00oq\x01}q\x02b.').replace(b'X', xname)
            self.assert_is_copy(X(*args), self.loads(pickle2))

    def test_maxint64(self):
        maxint64 = (1 << 63) - 1
        data = b'I' + str(maxint64).encode("ascii") + b'\n.'
        got = self.loads(data)
        self.assert_is_copy(maxint64, got)

        # Try too with a bogus literal.
        data = b'I' + str(maxint64).encode("ascii") + b'JUNK\n.'
        self.check_unpickling_error(ValueError, data)

    def test_unpickle_from_2x(self):
        # Unpickle non-trivial data from Python 2.x.
        loaded = self.loads(DATA_SET)
        self.assertEqual(loaded, set([1, 2]))
        loaded = self.loads(DATA_XRANGE)
        self.assertEqual(type(loaded), type(range(0)))
        self.assertEqual(list(loaded), list(range(5)))
        loaded = self.loads(DATA_COOKIE)
        self.assertEqual(type(loaded), SimpleCookie)
        self.assertEqual(list(loaded.keys()), ["key"])
        self.assertEqual(loaded["key"].value, "value")

        # Exception objects without arguments pickled from 2.x with protocol 2
        for exc in python2_exceptions_without_args:
            data = exception_pickle.replace(b'?', exc.__name__.encode("ascii"))
            loaded = self.loads(data)
            self.assertIs(type(loaded), exc)

        # StandardError is mapped to Exception, test that separately
        loaded = self.loads(exception_pickle.replace(b'?', b'StandardError'))
        self.assertIs(type(loaded), Exception)

        loaded = self.loads(DATA_UEERR)
        self.assertIs(type(loaded), UnicodeEncodeError)
        self.assertEqual(loaded.object, "foo")
        self.assertEqual(loaded.encoding, "ascii")
        self.assertEqual(loaded.start, 0)
        self.assertEqual(loaded.end, 1)
        self.assertEqual(loaded.reason, "bad")

    def test_load_python2_str_as_bytes(self):
        # From Python 2: pickle.dumps('a\x00\xa0', protocol=0)
        self.assertEqual(self.loads(b"S'a\\x00\\xa0'\n.",
                                    encoding="bytes"), b'a\x00\xa0')
        # From Python 2: pickle.dumps('a\x00\xa0', protocol=1)
        self.assertEqual(self.loads(b'U\x03a\x00\xa0.',
                                    encoding="bytes"), b'a\x00\xa0')
        # From Python 2: pickle.dumps('a\x00\xa0', protocol=2)
        self.assertEqual(self.loads(b'\x80\x02U\x03a\x00\xa0.',
                                    encoding="bytes"), b'a\x00\xa0')

    def test_load_python2_unicode_as_str(self):
        # From Python 2: pickle.dumps(u'π', protocol=0)
        self.assertEqual(self.loads(b'V\\u03c0\n.',
                                    encoding='bytes'), 'π')
        # From Python 2: pickle.dumps(u'π', protocol=1)
        self.assertEqual(self.loads(b'X\x02\x00\x00\x00\xcf\x80.',
                                    encoding="bytes"), 'π')
        # From Python 2: pickle.dumps(u'π', protocol=2)
        self.assertEqual(self.loads(b'\x80\x02X\x02\x00\x00\x00\xcf\x80.',
                                    encoding="bytes"), 'π')

    def test_load_long_python2_str_as_bytes(self):
        # From Python 2: pickle.dumps('x' * 300, protocol=1)
        self.assertEqual(self.loads(pickle.BINSTRING +
                                    struct.pack("<I", 300) +
                                    b'x' * 300 + pickle.STOP,
                                    encoding='bytes'), b'x' * 300)

    def test_constants(self):
        self.assertIsNone(self.loads(b'N.'))
        self.assertIs(self.loads(b'\x88.'), True)
        self.assertIs(self.loads(b'\x89.'), False)
        self.assertIs(self.loads(b'I01\n.'), True)
        self.assertIs(self.loads(b'I00\n.'), False)

    def test_issue135241(self):
        # C implementation should check for hardcoded values 00 and 01
        # when getting booleans from the INT opcode. Doing a str comparison
        # to bypass truthy/falsy comparisons. These payloads should return
        # 0, not False.
        out1 = self.loads(b'I+0\n.')
        self.assertEqual(str(out1), '0')
        out2 = self.loads(b'I 0\n.')
        self.assertEqual(str(out2), '0')

    def test_zero_padded_integers(self):
        self.assertEqual(self.loads(b'I010\n.'), 10)
        self.assertEqual(self.loads(b'I-010\n.'), -10)
        self.assertEqual(self.loads(b'I0010\n.'), 10)
        self.assertEqual(self.loads(b'I-0010\n.'), -10)
        self.assertEqual(self.loads(b'L010\n.'), 10)
        self.assertEqual(self.loads(b'L-010\n.'), -10)
        self.assertEqual(self.loads(b'L0010\n.'), 10)
        self.assertEqual(self.loads(b'L-0010\n.'), -10)
        self.assertEqual(self.loads(b'L010L\n.'), 10)
        self.assertEqual(self.loads(b'L-010L\n.'), -10)

    def test_nondecimal_integers(self):
        self.assertRaises(ValueError, self.loads, b'I0b10\n.')
        self.assertRaises(ValueError, self.loads, b'I0o10\n.')
        self.assertRaises(ValueError, self.loads, b'I0x10\n.')
        self.assertRaises(ValueError, self.loads, b'L0b10L\n.')
        self.assertRaises(ValueError, self.loads, b'L0o10L\n.')
        self.assertRaises(ValueError, self.loads, b'L0x10L\n.')

    def test_empty_bytestring(self):
        # issue 11286
        empty = self.loads(b'\x80\x03U\x00q\x00.', encoding='koi8-r')
        self.assertEqual(empty, '')

    def test_short_binbytes(self):
        dumped = b'\x80\x03C\x04\xe2\x82\xac\x00.'
        self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')

    def test_binbytes(self):
        dumped = b'\x80\x03B\x04\x00\x00\x00\xe2\x82\xac\x00.'
        self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')

    @requires_32b
    def test_negative_32b_binbytes(self):
        # On 32-bit builds, a BINBYTES of 2**31 or more is refused
        dumped = b'\x80\x03B\xff\xff\xff\xffxyzq\x00.'
        self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
                                    dumped)

    @requires_32b
    def test_negative_32b_binunicode(self):
        # On 32-bit builds, a BINUNICODE of 2**31 or more is refused
        dumped = b'\x80\x03X\xff\xff\xff\xffxyzq\x00.'
        self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
                                    dumped)

    def test_short_binunicode(self):
        dumped = b'\x80\x04\x8c\x04\xe2\x82\xac\x00.'
        self.assertEqual(self.loads(dumped), '\u20ac\x00')

    def test_misc_get(self):
        self.check_unpickling_error(pickle.UnpicklingError, b'g0\np0')
        self.check_unpickling_error(pickle.UnpicklingError, b'jens:')
        self.check_unpickling_error(pickle.UnpicklingError, b'hens:')
        self.assert_is_copy([(100,), (100,)],
                            self.loads(b'((Kdtp0\nh\x00l.))'))

    def test_binbytes8(self):
        dumped = b'\x80\x04\x8e\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
        self.assertEqual(self.loads(dumped), b'\xe2\x82\xac\x00')

    def test_binunicode8(self):
        dumped = b'\x80\x04\x8d\4\0\0\0\0\0\0\0\xe2\x82\xac\x00.'
        self.assertEqual(self.loads(dumped), '\u20ac\x00')

    def test_bytearray8(self):
        dumped = b'\x80\x05\x96\x03\x00\x00\x00\x00\x00\x00\x00xxx.'
        self.assertEqual(self.loads(dumped), bytearray(b'xxx'))

    @requires_32b
    def test_large_32b_binbytes8(self):
        dumped = b'\x80\x04\x8e\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
        self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
                                    dumped)

    @requires_32b
    def test_large_32b_bytearray8(self):
        dumped = b'\x80\x05\x96\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
        self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
                                    dumped)

    @requires_32b
    def test_large_32b_binunicode8(self):
        dumped = b'\x80\x04\x8d\4\0\0\0\1\0\0\0\xe2\x82\xac\x00.'
        self.check_unpickling_error((pickle.UnpicklingError, OverflowError),
                                    dumped)

    def test_large_binstring(self):
        errmsg = 'BINSTRING pickle has negative byte count'
        with self.assertRaisesRegex(pickle.UnpicklingError, errmsg):
            self.loads(b'T\0\0\0\x80')

    def test_get(self):
        pickled = b'((lp100000\ng100000\nt.'
        unpickled = self.loads(pickled)
        self.assertEqual(unpickled, ([],)*2)
        self.assertIs(unpickled[0], unpickled[1])

    def test_binget(self):
        pickled = b'(]q\xffh\xfft.'
        unpickled = self.loads(pickled)
        self.assertEqual(unpickled, ([],)*2)
        self.assertIs(unpickled[0], unpickled[1])

    def test_long_binget(self):
        pickled = b'(]r\x00\x00\x01\x00j\x00\x00\x01\x00t.'
        unpickled = self.loads(pickled)
        self.assertEqual(unpickled, ([],)*2)
        self.assertIs(unpickled[0], unpickled[1])

    def test_dup(self):
        pickled = b'((l2t.'
        unpickled = self.loads(pickled)
        self.assertEqual(unpickled, ([],)*2)
        self.assertIs(unpickled[0], unpickled[1])

    def test_negative_put(self):
        # Issue #12847
        dumped = b'Va\np-1\n.'
        self.check_unpickling_error(ValueError, dumped)

    @requires_32b
    def test_negative_32b_binput(self):
        # Issue #12847
        dumped = b'\x80\x03X\x01\x00\x00\x00ar\xff\xff\xff\xff.'
        self.check_unpickling_error(ValueError, dumped)

    def test_too_large_put(self):
        # Test that PUT with large id does not cause allocation of
        # too large memo table. The C implementation uses a dict-based memo
        # for sparse indices (when idx > memo_len * 2) instead of allocating
        # a massive array. This test verifies large sparse indices work without
        # causing memory exhaustion.
        #
        # The following simple pickle creates an empty list, memoizes it
        # using a large index, then loads it back on the stack, builds
        # a tuple containing 2 identical empty lists and returns it.
        data = lambda n: (b'((lp' + str(n).encode() + b'\n' +
                          b'g' + str(n).encode() + b'\nt.')
        #    0: (    MARK
        #    1: (        MARK
        #    2: l            LIST       (MARK at 1)
        #    3: p        PUT        1000000000000
        #   18: g        GET        1000000000000
        #   33: t        TUPLE      (MARK at 0)
        #   34: .    STOP
        for idx in [10**6, 10**9, 10**12]:
            if idx > sys.maxsize:
                continue
            self.assertEqual(self.loads(data(idx)), ([],)*2)

    def test_too_large_long_binput(self):
        # Test that LONG_BINPUT with large id does not cause allocation of
        # too large memo table. The C implementation uses a dict-based memo
        # for sparse indices (when idx > memo_len * 2) instead of allocating
        # a massive array. This test verifies large sparse indices work without
        # causing memory exhaustion.
        #
        # The following simple pickle creates an empty list, memoizes it
        # using a large index, then loads it back on the stack, builds
        # a tuple containing 2 identical empty lists and returns it.
        data = lambda n: (b'(]r' + struct.pack('<I', n) +
                          b'j' + struct.pack('<I', n) + b't.')
        #    0: (    MARK
        #    1: ]        EMPTY_LIST
        #    2: r        LONG_BINPUT 4294967295
        #    7: j        LONG_BINGET 4294967295
        #   12: t        TUPLE      (MARK at 0)
        #   13: .    STOP
        for idx in itersize(1 << 20, min(sys.maxsize, (1 << 32) - 1)):
            self.assertEqual(self.loads(data(idx)), ([],)*2)

    def _test_truncated_data(self, dumped, expected_error=None):
        # Test that instructions to read large data without providing
        # such amount of data do not cause large memory usage.
        if expected_error is None:
            expected_error = self.truncated_data_error
        # BytesIO
        with self.assertRaisesRegex(*expected_error):
            self.loads(dumped)
        if hasattr(self, 'unpickler'):
            try:
                with open(TESTFN, 'wb') as f:
                    f.write(dumped)
                # buffered file
                with open(TESTFN, 'rb') as f:
                    u = self.unpickler(f)
                    with self.assertRaisesRegex(*expected_error):
                        u.load()
                # unbuffered file
                with open(TESTFN, 'rb', buffering=0) as f:
                    u = self.unpickler(f)
                    with self.assertRaisesRegex(*expected_error):
                        u.load()
            finally:
                os_helper.unlink(TESTFN)

    def test_truncated_large_binstring(self):
        data = lambda size: b'T' + struct.pack('<I', size) + b'.' * 5
        #    0: T    BINSTRING  '....'
        #    9: .    STOP
        self.assertEqual(self.loads(data(4)), '....') # self-testing
        for size in itersize(1 << 10, min(sys.maxsize - 5, (1 << 31) - 1)):
            self._test_truncated_data(data(size))
        self._test_truncated_data(data(1 << 31),
            (pickle.UnpicklingError, 'truncated|exceeds|negative byte count'))

    def test_truncated_large_binunicode(self):
        data = lambda size: b'X' + struct.pack('<I', size) + b'.' * 5
        #    0: X    BINUNICODE '....'
        #    9: .    STOP
        self.assertEqual(self.loads(data(4)), '....') # self-testing
        for size in itersize(1 << 10, min(sys.maxsize - 5, (1 << 32) - 1)):
            self._test_truncated_data(data(size))

    def test_truncated_large_binbytes(self):
        data = lambda size: b'B' + struct.pack('<I', size) + b'.' * 5
        #    0: B    BINBYTES   b'....'
        #    9: .    STOP
        self.assertEqual(self.loads(data(4)), b'....') # self-testing
        for size in itersize(1 << 10, min(sys.maxsize, 1 << 31)):
            self._test_truncated_data(data(size))

    def test_truncated_large_long4(self):
        data = lambda size: b'\x8b' + struct.pack('<I', size) + b'.' * 5
        #    0: \x8b LONG4      0x2e2e2e2e
        #    9: .    STOP
        self.assertEqual(self.loads(data(4)), 0x2e2e2e2e) # self-testing
        for size in itersize(1 << 10, min(sys.maxsize - 5, (1 << 31) - 1)):
            self._test_truncated_data(data(size))
        self._test_truncated_data(data(1 << 31),
            (pickle.UnpicklingError, 'LONG pickle has negative byte count'))

    def test_truncated_large_frame(self):
        data = lambda size: b'\x95' + struct.pack('<Q', size) + b'N.'
        #    0: \x95 FRAME      2
        #    9: N    NONE
        #   10: .    STOP
        self.assertIsNone(self.loads(data(2))) # self-testing
        for size in itersize(1 << 10, sys.maxsize - 9):
            self._test_truncated_data(data(size))
        if sys.maxsize + 1 < 1 << 64:
            self._test_truncated_data(data(sys.maxsize + 1),
                ((OverflowError, ValueError),
                 'FRAME length exceeds|frame size > sys.maxsize'))

    def test_truncated_large_binunicode8(self):
        data = lambda size: b'\x8d' + struct.pack('<Q', size) + b'.' * 5
        #    0: \x8d BINUNICODE8 '....'
        #   13: .    STOP
        self.assertEqual(self.loads(data(4)), '....') # self-testing
        for size in itersize(1 << 10, sys.maxsize - 9):
            self._test_truncated_data(data(size))
        if sys.maxsize + 1 < 1 << 64:
            self._test_truncated_data(data(sys.maxsize + 1), self.size_overflow_error)

    def test_truncated_large_binbytes8(self):
        data = lambda size: b'\x8e' + struct.pack('<Q', size) + b'.' * 5
        #    0: \x8e BINBYTES8  b'....'
        #   13: .    STOP
        self.assertEqual(self.loads(data(4)), b'....') # self-testing
        for size in itersize(1 << 10, sys.maxsize):
            self._test_truncated_data(data(size))
        if sys.maxsize + 1 < 1 << 64:
            self._test_truncated_data(data(sys.maxsize + 1), self.size_overflow_error)

    def test_truncated_large_bytearray8(self):
        data = lambda size: b'\x96' + struct.pack('<Q', size) + b'.' * 5
        #    0: \x96 BYTEARRAY8 bytearray(b'....')
        #   13: .    STOP
        self.assertEqual(self.loads(data(4)), bytearray(b'....')) # self-testing
        for size in itersize(1 << 10, sys.maxsize):
            self._test_truncated_data(data(size))
        if sys.maxsize + 1 < 1 << 64:
            self._test_truncated_data(data(sys.maxsize + 1), self.size_overflow_error)

    def test_badly_escaped_string(self):
        self.check_unpickling_error(ValueError, b"S'\\'\n.")

    def test_badly_quoted_string(self):
        # Issue #17710
        badpickles = [b"S'\n.",
                      b'S"\n.',
                      b'S\' \n.',
                      b'S" \n.',
                      b'S\'"\n.',
                      b'S"\'\n.',
                      b"S' ' \n.",
                      b'S" " \n.',
                      b"S ''\n.",
                      b'S ""\n.',
                      b'S \n.',
                      b'S\n.',
                      b'S.']
        for p in badpickles:
            self.check_unpickling_error(pickle.UnpicklingError, p)

    def test_correctly_quoted_string(self):
        goodpickles = [(b"S''\n.", ''),
                       (b'S""\n.', ''),
                       (b'S"\\n"\n.', '\n'),
                       (b"S'\\n'\n.", '\n')]
        for p, expected in goodpickles:
            self.assertEqual(self.loads(p), expected)

    def test_frame_readline(self):
        pickled = b'\x80\x04\x95\x05\x00\x00\x00\x00\x00\x00\x00I42\n.'
        #    0: \x80 PROTO      4
        #    2: \x95 FRAME      5
        #   11: I    INT        42
        #   15: .    STOP
        self.assertEqual(self.loads(pickled), 42)

    def test_compat_unpickle(self):
        # xrange(1, 7)
        pickled = b'\x80\x02c__builtin__\nxrange\nK\x01K\x07K\x01\x87R.'
        unpickled = self.loads(pickled)
        self.assertIs(type(unpickled), range)
        self.assertEqual(unpickled, range(1, 7))
        self.assertEqual(list(unpickled), [1, 2, 3, 4, 5, 6])
        # reduce
        pickled = b'\x80\x02c__builtin__\nreduce\n.'
        self.assertIs(self.loads(pickled), functools.reduce)
        # whichdb.whichdb
        pickled = b'\x80\x02cwhichdb\nwhichdb\n.'
        self.assertIs(self.loads(pickled), dbm.whichdb)
        # Exception(), StandardError()
        for name in (b'Exception', b'StandardError'):
            pickled = (b'\x80\x02cexceptions\n' + name + b'\nU\x03ugh\x85R.')
            unpickled = self.loads(pickled)
            self.assertIs(type(unpickled), Exception)
            self.assertEqual(str(unpickled), 'ugh')
        # UserDict.UserDict({1: 2}), UserDict.IterableUserDict({1: 2})
        for name in (b'UserDict', b'IterableUserDict'):
            pickled = (b'\x80\x02(cUserDict\n' + name +
                       b'\no}U\x04data}K\x01K\x02ssb.')
            unpickled = self.loads(pickled)
            self.assertIs(type(unpickled), collections.UserDict)
            self.assertEqual(unpickled, collections.UserDict({1: 2}))

    def test_load_global(self):
        self.assertIs(self.loads(b'cbuiltins\nstr\n.'), str)
        self.assertIs(self.loads(b'cmath\nlog\n.'), math.log)
        self.assertIs(self.loads(b'cos.path\njoin\n.'), os.path.join)
        self.assertIs(self.loads(b'\x80\x04cbuiltins\nstr.upper\n.'), str.upper)
        with support.swap_item(sys.modules, 'mödule', types.SimpleNamespace(glöbal=42)):
            self.assertEqual(self.loads(b'\x80\x04cm\xc3\xb6dule\ngl\xc3\xb6bal\n.'), 42)

        self.assertRaises(UnicodeDecodeError, self.loads, b'c\xff\nlog\n.')
        self.assertRaises(UnicodeDecodeError, self.loads, b'cmath\n\xff\n.')
        self.assertRaises(self.truncated_errors, self.loads, b'c\nlog\n.')
        self.assertRaises(self.truncated_errors, self.loads, b'cmath\n\n.')
        self.assertRaises(self.truncated_errors, self.loads, b'\x80\x04cmath\n\n.')

    def test_load_stack_global(self):
        self.assertIs(self.loads(b'\x8c\x08builtins\x8c\x03str\x93.'), str)
        self.assertIs(self.loads(b'\x8c\x04math\x8c\x03log\x93.'), math.log)
        self.assertIs(self.loads(b'\x8c\x07os.path\x8c\x04join\x93.'),
                      os.path.join)
        self.assertIs(self.loads(b'\x80\x04\x8c\x08builtins\x8c\x09str.upper\x93.'),
                      str.upper)
        with support.swap_item(sys.modules, 'mödule', types.SimpleNamespace(glöbal=42)):
            self.assertEqual(self.loads(b'\x80\x04\x8c\x07m\xc3\xb6dule\x8c\x07gl\xc3\xb6bal\x93.'), 42)

        self.assertRaises(UnicodeDecodeError, self.loads, b'\x8c\x01\xff\x8c\x03log\x93.')
        self.assertRaises(UnicodeDecodeError, self.loads, b'\x8c\x04math\x8c\x01\xff\x93.')
        self.assertRaises(ValueError, self.loads, b'\x8c\x00\x8c\x03log\x93.')
        self.assertRaises(AttributeError, self.loads, b'\x8c\x04math\x8c\x00\x93.')
        self.assertRaises(AttributeError, self.loads, b'\x80\x04\x8c\x04math\x8c\x00\x93.')

        self.assertRaises(pickle.UnpicklingError, self.loads, b'N\x8c\x03log\x93.')
        self.assertRaises(pickle.UnpicklingError, self.loads, b'\x8c\x04mathN\x93.')
        self.assertRaises(pickle.UnpicklingError, self.loads, b'\x80\x04\x8c\x04mathN\x93.')

    def test_find_class(self):
        unpickler = self.unpickler(io.BytesIO())
        unpickler_nofix = self.unpickler(io.BytesIO(), fix_imports=False)
        unpickler4 = self.unpickler(io.BytesIO(b'\x80\x04N.'))
        unpickler4.load()

        self.assertIs(unpickler.find_class('__builtin__', 'str'), str)
        self.assertRaises(ModuleNotFoundError,
                          unpickler_nofix.find_class, '__builtin__', 'str')
        self.assertIs(unpickler.find_class('builtins', 'str'), str)
        self.assertIs(unpickler_nofix.find_class('builtins', 'str'), str)
        self.assertIs(unpickler.find_class('math', 'log'), math.log)
        self.assertIs(unpickler.find_class('os.path', 'join'), os.path.join)
        self.assertIs(unpickler.find_class('os.path', 'join'), os.path.join)

        self.assertIs(unpickler4.find_class('builtins', 'str.upper'), str.upper)
        with self.assertRaisesRegex(AttributeError,
                r"module 'builtins' has no attribute 'str\.upper'"):
            unpickler.find_class('builtins', 'str.upper')

        with self.assertRaisesRegex(AttributeError,
                "module 'math' has no attribute 'spam'"):
            unpickler.find_class('math', 'spam')
        with self.assertRaisesRegex(AttributeError,
                "module 'math' has no attribute 'spam'"):
            unpickler4.find_class('math', 'spam')
        with self.assertRaisesRegex(AttributeError,
                r"module 'math' has no attribute 'log\.spam'"):
            unpickler.find_class('math', 'log.spam')
        with self.assertRaisesRegex(AttributeError,
                r"Can't resolve path 'log\.spam' on module 'math'") as cm:
            unpickler4.find_class('math', 'log.spam')
        self.assertEqual(str(cm.exception.__context__),
            "'builtin_function_or_method' object has no attribute 'spam'")
        with self.assertRaisesRegex(AttributeError,
                r"module 'math' has no attribute 'log\.<locals>\.spam'"):
            unpickler.find_class('math', 'log.<locals>.spam')
        with self.assertRaisesRegex(AttributeError,
                r"Can't resolve path 'log\.<locals>\.spam' on module 'math'") as cm:
            unpickler4.find_class('math', 'log.<locals>.spam')
        self.assertEqual(str(cm.exception.__context__),
            "'builtin_function_or_method' object has no attribute '<locals>'")
        with self.assertRaisesRegex(AttributeError,
                "module 'math' has no attribute ''"):
            unpickler.find_class('math', '')
        with self.assertRaisesRegex(AttributeError,
                "module 'math' has no attribute ''"):
            unpickler4.find_class('math', '')
        self.assertRaises(ModuleNotFoundError, unpickler.find_class, 'spam', 'log')
        self.assertRaises(ValueError, unpickler.find_class, '', 'log')

        self.assertRaises(TypeError, unpickler.find_class, None, 'log')
        self.assertRaises(TypeError, unpickler.find_class, 'math', None)
        self.assertRaises((TypeError, AttributeError), unpickler4.find_class, 'math', None)

    def test_custom_find_class(self):
        def loads(data):
            class Unpickler(self.unpickler):
                def find_class(self, module_name, global_name):
                    return (module_name, global_name)
            return Unpickler(io.BytesIO(data)).load()

        self.assertEqual(loads(b'cmath\nlog\n.'), ('math', 'log'))
        self.assertEqual(loads(b'\x8c\x04math\x8c\x03log\x93.'), ('math', 'log'))

        def loads(data):
            class Unpickler(self.unpickler):
                @staticmethod
                def find_class(module_name, global_name):
                    return (module_name, global_name)
            return Unpickler(io.BytesIO(data)).load()

        self.assertEqual(loads(b'cmath\nlog\n.'), ('math', 'log'))
        self.assertEqual(loads(b'\x8c\x04math\x8c\x03log\x93.'), ('math', 'log'))

        def loads(data):
            class Unpickler(self.unpickler):
                @classmethod
                def find_class(cls, module_name, global_name):
                    return (module_name, global_name)
            return Unpickler(io.BytesIO(data)).load()

        self.assertEqual(loads(b'cmath\nlog\n.'), ('math', 'log'))
        self.assertEqual(loads(b'\x8c\x04math\x8c\x03log\x93.'), ('math', 'log'))

        def loads(data):
            class Unpickler(self.unpickler):
                pass
            def find_class(module_name, global_name):
                return (module_name, global_name)
            unpickler = Unpickler(io.BytesIO(data))
            unpickler.find_class = find_class
            return unpickler.load()

        self.assertEqual(loads(b'cmath\nlog\n.'), ('math', 'log'))
        self.assertEqual(loads(b'\x8c\x04math\x8c\x03log\x93.'), ('math', 'log'))

    def test_bad_ext_code(self):
        # unregistered extension code
        self.check_unpickling_error(ValueError, b'\x82\x01.')
        self.check_unpickling_error(ValueError, b'\x82\xff.')
        self.check_unpickling_error(ValueError, b'\x83\x01\x00.')
        self.check_unpickling_error(ValueError, b'\x83\xff\xff.')
        self.check_unpickling_error(ValueError, b'\x84\x01\x00\x00\x00.')
        self.check_unpickling_error(ValueError, b'\x84\xff\xff\xff\x7f.')
        # EXT specifies code <= 0
        self.check_unpickling_error(pickle.UnpicklingError, b'\x82\x00.')
        self.check_unpickling_error(pickle.UnpicklingError, b'\x83\x00\x00.')
        self.check_unpickling_error(pickle.UnpicklingError, b'\x84\x00\x00\x00\x00.')
        self.check_unpickling_error(pickle.UnpicklingError, b'\x84\x00\x00\x00\x80.')
        self.check_unpickling_error(pickle.UnpicklingError, b'\x84\xff\xff\xff\xff.')

    @support.cpython_only
    def test_bad_ext_inverted_registry(self):
        code = 1
        def check(key, exc):
            with support.swap_item(copyreg._inverted_registry, code, key):
                with self.assertRaises(exc):
                    self.loads(b'\x82\x01.')
        check(None, ValueError)
        check((), ValueError)
        check((MyList.__module__,), (TypeError, ValueError))
        check((MyList.__module__, "MyList", "x"), (TypeError, ValueError))
        check((MyList.__module__, None), (TypeError, ValueError))
        check((None, "MyList"), (TypeError, ValueError))

    def test_bad_reduce(self):
        self.assertEqual(self.loads(b'cbuiltins\nint\n)R.'), 0)
        self.check_unpickling_error(TypeError, b'N)R.')
        self.check_unpickling_error(TypeError, b'cbuiltins\nint\nNR.')

    def test_bad_newobj(self):
        error = (pickle.UnpicklingError, TypeError)
        self.assertEqual(self.loads(b'cbuiltins\nint\n)\x81.'), 0)
        self.check_unpickling_error(error, b'cbuiltins\nlen\n)\x81.')
        self.check_unpickling_error(error, b'cbuiltins\nint\nN\x81.')

    def test_bad_newobj_ex(self):
        error = (pickle.UnpicklingError, TypeError)
        self.assertEqual(self.loads(b'cbuiltins\nint\n)}\x92.'), 0)
        self.check_unpickling_error(error, b'cbuiltins\nlen\n)}\x92.')
        self.check_unpickling_error(error, b'cbuiltins\nint\nN}\x92.')
        self.check_unpickling_error(error, b'cbuiltins\nint\n)N\x92.')

    def test_bad_state(self):
        c = C()
        c.x = None
        base = b'c__main__\nC\n)\x81'
        self.assertEqual(self.loads(base + b'}X\x01\x00\x00\x00xNsb.'), c)
        self.assertEqual(self.loads(base + b'N}X\x01\x00\x00\x00xNs\x86b.'), c)
        # non-hashable dict key
        self.check_unpickling_error(TypeError, base + b'}]Nsb.')
        # state = list
        error = (pickle.UnpicklingError, AttributeError)
        self.check_unpickling_error(error, base + b'](}}eb.')
        # state = 1-tuple
        self.check_unpickling_error(error, base + b'}\x85b.')
        # state = 3-tuple
        self.check_unpickling_error(error, base + b'}}}\x87b.')
        # non-hashable slot name
        self.check_unpickling_error(TypeError, base + b'}}]Ns\x86b.')
        # non-string slot name
        self.check_unpickling_error(TypeError, base + b'}}NNs\x86b.')
        # dict = True
        self.check_unpickling_error(error, base + b'\x88}\x86b.')
        # slots dict = True
        self.check_unpickling_error(error, base + b'}\x88\x86b.')

        class BadKey1:
            count = 1
            def __hash__(self):
                if not self.count:
                    raise CustomError
                self.count -= 1
                return 42
        __main__.BadKey1 = BadKey1
        # bad hashable dict key
        self.check_unpickling_error(CustomError, base + b'}c__main__\nBadKey1\n)\x81Nsb.')

    def test_bad_types(self):
        # APPEND
        self.assertEqual(self.loads(b']Na.'), [None])
        self.check_unpickling_error(AttributeError, b'NNa.')  # non-list
        # APPENDS
        self.assertEqual(self.loads(b'](Ne.'), [None])
        self.check_unpickling_error(AttributeError, b'N(Ne.')  # non-list
        self.check_unpickling_error(AttributeError, b'N(e.')
        # SETITEM
        self.assertEqual(self.loads(b'}NNs.'), {None: None})
        self.check_unpickling_error(TypeError, b'NNNs.')  # non-dict
        self.check_unpickling_error(TypeError, b'}]Ns.')  # non-hashable key
        # SETITEMS
        self.assertEqual(self.loads(b'}(NNu.'), {None: None})
        self.check_unpickling_error(TypeError, b'N(NNu.')  # non-dict
        self.assertEqual(self.loads(b'N(u.'), None)  # no validation for empty items
        self.check_unpickling_error(TypeError, b'}(]Nu.')  # non-hashable key
        # ADDITEMS
        self.assertEqual(self.loads(b'\x8f(N\x90.'), {None})
        self.check_unpickling_error(AttributeError, b'N(N\x90.')  # non-set
        self.check_unpickling_error(AttributeError, b'N(\x90.')
        self.check_unpickling_error(TypeError, b'\x8f(]\x90.')  # non-hashable element

    def test_bad_stack(self):
        badpickles = [
            b'.',                       # STOP
            b'0',                       # POP
            b'1',                       # POP_MARK
            b'2',                       # DUP
            b'(2',
            b'R',                       # REDUCE
            b')R',
            b'a',                       # APPEND
            b'Na',
            b'b',                       # BUILD
            b'Nb',
            b'd',                       # DICT
            b'e',                       # APPENDS
            b'(e',
            b'ibuiltins\nlist\n',       # INST
            b'l',                       # LIST
            b'o',                       # OBJ
            b'(o',
            b'p1\n',                    # PUT
            b'q\x00',                   # BINPUT
            b'r\x00\x00\x00\x00',       # LONG_BINPUT
            b's',                       # SETITEM
            b'Ns',
            b'NNs',
            b't',                       # TUPLE
            b'u',                       # SETITEMS
            b'(u',
            b'}(Nu',
            b'\x81',                    # NEWOBJ
            b')\x81',
            b'\x85',                    # TUPLE1
            b'\x86',                    # TUPLE2
            b'N\x86',
            b'\x87',                    # TUPLE3
            b'N\x87',
            b'NN\x87',
            b'\x90',                    # ADDITEMS
            b'(\x90',
            b'\x91',                    # FROZENSET
            b'\x92',                    # NEWOBJ_EX
            b')}\x92',
            b'\x93',                    # STACK_GLOBAL
            b'Vlist\n\x93',
            b'\x94',                    # MEMOIZE
        ]
        for p in badpickles:
            self.check_unpickling_error(self.bad_stack_errors, p)

    def test_bad_mark(self):
        badpickles = [
            b'N(.',                     # STOP
            b'N(2',                     # DUP
            b'cbuiltins\nlist\n)(R',    # REDUCE
            b'cbuiltins\nlist\n()R',
            b']N(a',                    # APPEND
                                        # BUILD
            b'cbuiltins\nValueError\n)R}(b',
            b'cbuiltins\nValueError\n)R(}b',
            b'(Nd',                     # DICT
            b'N(p1\n',                  # PUT
            b'N(q\x00',                 # BINPUT
            b'N(r\x00\x00\x00\x00',     # LONG_BINPUT
            b'}NN(s',                   # SETITEM
            b'}N(Ns',
            b'}(NNs',
            b'}((u',                    # SETITEMS
            b'cbuiltins\nlist\n)(\x81', # NEWOBJ
            b'cbuiltins\nlist\n()\x81',
            b'N(\x85',                  # TUPLE1
            b'NN(\x86',                 # TUPLE2
            b'N(N\x86',
            b'NNN(\x87',                # TUPLE3
            b'NN(N\x87',
            b'N(NN\x87',
            b']((\x90',                 # ADDITEMS
                                        # NEWOBJ_EX
            b'cbuiltins\nlist\n)}(\x92',
            b'cbuiltins\nlist\n)(}\x92',
            b'cbuiltins\nlist\n()}\x92',
                                        # STACK_GLOBAL
            b'Vbuiltins\n(Vlist\n\x93',
            b'Vbuiltins\nVlist\n(\x93',
            b'N(\x94',                  # MEMOIZE
        ]
        for p in badpickles:
            self.check_unpickling_error(self.bad_stack_errors, p)

    def test_truncated_data(self):
        self.check_unpickling_error(EOFError, b'')
        self.check_unpickling_error(EOFError, b'N')
        badpickles = [
            b'B',                       # BINBYTES
            b'B\x03\x00\x00',
            b'B\x03\x00\x00\x00',
            b'B\x03\x00\x00\x00ab',
            b'C',                       # SHORT_BINBYTES
            b'C\x03',
            b'C\x03ab',
            b'F',                       # FLOAT
            b'F0.0',
            b'F0.00',
            b'G',                       # BINFLOAT
            b'G\x00\x00\x00\x00\x00\x00\x00',
            b'I',                       # INT
            b'I0',
            b'J',                       # BININT
            b'J\x00\x00\x00',
            b'K',                       # BININT1
            b'L',                       # LONG
            b'L0',
            b'L10',
            b'L0L',
            b'L10L',
            b'M',                       # BININT2
            b'M\x00',
            # b'P',                       # PERSID
            # b'Pabc',
            b'S',                       # STRING
            b"S'abc'",
            b'T',                       # BINSTRING
            b'T\x03\x00\x00',
            b'T\x03\x00\x00\x00',
            b'T\x03\x00\x00\x00ab',
            b'U',                       # SHORT_BINSTRING
            b'U\x03',
            b'U\x03ab',
            b'V',                       # UNICODE
            b'Vabc',
            b'X',                       # BINUNICODE
            b'X\x03\x00\x00',
            b'X\x03\x00\x00\x00',
            b'X\x03\x00\x00\x00ab',
            b'(c',                      # GLOBAL
            b'(cbuiltins',
            b'(cbuiltins\n',
            b'(cbuiltins\nlist',
            b'Ng',                      # GET
            b'Ng0',
            b'(i',                      # INST
            b'(ibuiltins',
            b'(ibuiltins\n',
            b'(ibuiltins\nlist',
            b'Nh',                      # BINGET
            b'Nj',                      # LONG_BINGET
            b'Nj\x00\x00\x00',
            b'Np',                      # PUT
            b'Np0',
            b'Nq',                      # BINPUT
            b'Nr',                      # LONG_BINPUT
            b'Nr\x00\x00\x00',
            b'\x80',                    # PROTO
            b'\x82',                    # EXT1
            b'\x83',                    # EXT2
            b'\x84\x01',
            b'\x84',                    # EXT4
            b'\x84\x01\x00\x00',
            b'\x8a',                    # LONG1
            b'\x8b',                    # LONG4
            b'\x8b\x00\x00\x00',
            b'\x8c',                    # SHORT_BINUNICODE
            b'\x8c\x03',
            b'\x8c\x03ab',
            b'\x8d',                    # BINUNICODE8
            b'\x8d\x03\x00\x00\x00\x00\x00\x00',
            b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00',
            b'\x8d\x03\x00\x00\x00\x00\x00\x00\x00ab',
            b'\x8e',                    # BINBYTES8
            b'\x8e\x03\x00\x00\x00\x00\x00\x00',
            b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00',
            b'\x8e\x03\x00\x00\x00\x00\x00\x00\x00ab',
            b'\x96',                    # BYTEARRAY8
            b'\x96\x03\x00\x00\x00\x00\x00\x00',
            b'\x96\x03\x00\x00\x00\x00\x00\x00\x00',
            b'\x96\x03\x00\x00\x00\x00\x00\x00\x00ab',
            b'\x95',                    # FRAME
            b'\x95\x02\x00\x00\x00\x00\x00\x00',
            b'\x95\x02\x00\x00\x00\x00\x00\x00\x00',
            b'\x95\x02\x00\x00\x00\x00\x00\x00\x00N',
        ]
        for p in badpickles:
            self.check_unpickling_error(self.truncated_errors, p)

    @threading_helper.reap_threads
    @threading_helper.requires_working_threading()
    def test_unpickle_module_race(self):
        # https://bugs.python.org/issue34572
        locker_module = dedent("""
        import threading
        barrier = threading.Barrier(2)
        """)
        locking_import_module = dedent("""
        import locker
        locker.barrier.wait()
        class ToBeUnpickled(object):
            pass
        """)

        os.mkdir(TESTFN)
        self.addCleanup(shutil.rmtree, TESTFN)
        sys.path.insert(0, TESTFN)
        self.addCleanup(sys.path.remove, TESTFN)
        with open(os.path.join(TESTFN, "locker.py"), "wb") as f:
            f.write(locker_module.encode('utf-8'))
        with open(os.path.join(TESTFN, "locking_import.py"), "wb") as f:
            f.write(locking_import_module.encode('utf-8'))
        self.addCleanup(forget, "locker")
        self.addCleanup(forget, "locking_import")

        import locker

        pickle_bytes = (
            b'\x80\x03clocking_import\nToBeUnpickled\nq\x00)\x81q\x01.')

        # Then try to unpickle two of these simultaneously
        # One of them will cause the module import, and we want it to block
        # until the other one either:
        #   - fails (before the patch for this issue)
        #   - blocks on the import lock for the module, as it should
        results = []
        barrier = threading.Barrier(3)
        def t():
            # This ensures the threads have all started
            # presumably barrier release is faster than thread startup
            barrier.wait()
            results.append(pickle.loads(pickle_bytes))

        t1 = threading.Thread(target=t)
        t2 = threading.Thread(target=t)
        t1.start()
        t2.start()

        barrier.wait()
        # could have delay here
        locker.barrier.wait()

        t1.join()
        t2.join()

        from locking_import import ToBeUnpickled
        self.assertEqual(
            [type(x) for x in results],
            [ToBeUnpickled] * 2)


class AbstractPicklingErrorTests:
    # Subclass must define self.dumps, self.pickler.

    def test_bad_reduce_result(self):
        obj = REX([print, ()])
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    '__reduce__ must return a string or tuple, not list')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

        obj = REX((print,))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    'tuple returned by __reduce__ must contain 2 through 6 elements')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

        obj = REX((print, (), None, None, None, None, None))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    'tuple returned by __reduce__ must contain 2 through 6 elements')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

    def test_bad_reconstructor(self):
        obj = REX((42, ()))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    'first item of the tuple returned by __reduce__ '
                    'must be callable, not int')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_reconstructor(self):
        obj = REX((UnpickleableCallable(), ()))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX reconstructor',
                    f'when serializing {REX.__module__}.REX object'])

    def test_bad_reconstructor_args(self):
        obj = REX((print, []))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    'second item of the tuple returned by __reduce__ '
                    'must be a tuple, not list')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_reconstructor_args(self):
        obj = REX((print, (1, 2, UNPICKLEABLE)))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    'when serializing tuple item 2',
                    f'when serializing {REX.__module__}.REX reconstructor arguments',
                    f'when serializing {REX.__module__}.REX object'])

    def test_bad_newobj_args(self):
        obj = REX((copyreg.__newobj__, ()))
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                with self.assertRaises((IndexError, pickle.PicklingError)) as cm:
                    self.dumps(obj, proto)
                self.assertIn(str(cm.exception), {
                    'tuple index out of range',
                    '__newobj__ expected at least 1 argument, got 0'})
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

        obj = REX((copyreg.__newobj__, [REX]))
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    'second item of the tuple returned by __reduce__ '
                    'must be a tuple, not list')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

    def test_bad_newobj_class(self):
        obj = REX((copyreg.__newobj__, (NoNew(),)))
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertIn(str(cm.exception), {
                    'first argument to __newobj__() has no __new__',
                    f'first argument to __newobj__() must be a class, not {NoNew.__module__}.NoNew'})
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

    def test_wrong_newobj_class(self):
        obj = REX((copyreg.__newobj__, (str,)))
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f'first argument to __newobj__() must be {REX!r}, not {str!r}')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_newobj_class(self):
        class LocalREX(REX): pass
        obj = LocalREX((copyreg.__newobj__, (LocalREX,)))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
            if proto >= 2:
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} class',
                    f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} object'])
            else:
                self.assertEqual(cm.exception.__notes__, [
                    'when serializing tuple item 0',
                    f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} reconstructor arguments',
                    f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} object'])

    def test_unpickleable_newobj_args(self):
        obj = REX((copyreg.__newobj__, (REX, 1, 2, UNPICKLEABLE)))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                if proto >= 2:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing tuple item 2',
                        f'when serializing {REX.__module__}.REX __new__ arguments',
                        f'when serializing {REX.__module__}.REX object'])
                else:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing tuple item 3',
                        f'when serializing {REX.__module__}.REX reconstructor arguments',
                        f'when serializing {REX.__module__}.REX object'])

    def test_bad_newobj_ex_args(self):
        obj = REX((copyreg.__newobj_ex__, ()))
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                with self.assertRaises((ValueError, pickle.PicklingError)) as cm:
                    self.dumps(obj, proto)
                self.assertIn(str(cm.exception), {
                    'not enough values to unpack (expected 3, got 0)',
                    '__newobj_ex__ expected 3 arguments, got 0'})
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

        obj = REX((copyreg.__newobj_ex__, 42))
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    'second item of the tuple returned by __reduce__ '
                    'must be a tuple, not int')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

        obj = REX((copyreg.__newobj_ex__, (REX, 42, {})))
        if self.pickler is pickle._Pickler:
            for proto in protocols[2:4]:
                with self.subTest(proto=proto):
                    with self.assertRaises(TypeError) as cm:
                        self.dumps(obj, proto)
                    self.assertEqual(str(cm.exception),
                        'Value after * must be an iterable, not int')
                    self.assertEqual(cm.exception.__notes__, [
                        f'when serializing {REX.__module__}.REX object'])
        else:
            for proto in protocols[2:]:
                with self.subTest(proto=proto):
                    with self.assertRaises(pickle.PicklingError) as cm:
                        self.dumps(obj, proto)
                    self.assertEqual(str(cm.exception),
                        'second argument to __newobj_ex__() must be a tuple, not int')
                    self.assertEqual(cm.exception.__notes__, [
                        f'when serializing {REX.__module__}.REX object'])

        obj = REX((copyreg.__newobj_ex__, (REX, (), [])))
        if self.pickler is pickle._Pickler:
            for proto in protocols[2:4]:
                with self.subTest(proto=proto):
                    with self.assertRaises(TypeError) as cm:
                        self.dumps(obj, proto)
                    self.assertEqual(str(cm.exception),
                        'Value after ** must be a mapping, not list')
                    self.assertEqual(cm.exception.__notes__, [
                        f'when serializing {REX.__module__}.REX object'])
        else:
            for proto in protocols[2:]:
                with self.subTest(proto=proto):
                    with self.assertRaises(pickle.PicklingError) as cm:
                        self.dumps(obj, proto)
                    self.assertEqual(str(cm.exception),
                        'third argument to __newobj_ex__() must be a dict, not list')
                    self.assertEqual(cm.exception.__notes__, [
                        f'when serializing {REX.__module__}.REX object'])

    def test_bad_newobj_ex__class(self):
        obj = REX((copyreg.__newobj_ex__, (NoNew(), (), {})))
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertIn(str(cm.exception), {
                    'first argument to __newobj_ex__() has no __new__',
                    f'first argument to __newobj_ex__() must be a class, not {NoNew.__module__}.NoNew'})
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

    def test_wrong_newobj_ex_class(self):
        if self.pickler is not pickle._Pickler:
            self.skipTest('only verified in the Python implementation')
        obj = REX((copyreg.__newobj_ex__, (str, (), {})))
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f'first argument to __newobj_ex__() must be {REX}, not {str}')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_newobj_ex_class(self):
        class LocalREX(REX): pass
        obj = LocalREX((copyreg.__newobj_ex__, (LocalREX, (), {})))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                if proto >= 4:
                    self.assertEqual(cm.exception.__notes__, [
                        f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} class',
                        f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} object'])
                elif proto >= 2:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing tuple item 0',
                        'when serializing tuple item 1',
                        'when serializing functools.partial state',
                        'when serializing functools.partial object',
                        f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} reconstructor',
                        f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} object'])
                else:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing tuple item 0',
                        f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} reconstructor arguments',
                        f'when serializing {LocalREX.__module__}.{LocalREX.__qualname__} object'])

    def test_unpickleable_newobj_ex_args(self):
        obj = REX((copyreg.__newobj_ex__, (REX, (1, 2, UNPICKLEABLE), {})))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                if proto >= 4:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing tuple item 2',
                        f'when serializing {REX.__module__}.REX __new__ arguments',
                        f'when serializing {REX.__module__}.REX object'])
                elif proto >= 2:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing tuple item 3',
                        'when serializing tuple item 1',
                        'when serializing functools.partial state',
                        'when serializing functools.partial object',
                        f'when serializing {REX.__module__}.REX reconstructor',
                        f'when serializing {REX.__module__}.REX object'])
                else:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing tuple item 2',
                        'when serializing tuple item 1',
                        f'when serializing {REX.__module__}.REX reconstructor arguments',
                        f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_newobj_ex_kwargs(self):
        obj = REX((copyreg.__newobj_ex__, (REX, (), {'a': UNPICKLEABLE})))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                if proto >= 4:
                    self.assertEqual(cm.exception.__notes__, [
                        "when serializing dict item 'a'",
                        f'when serializing {REX.__module__}.REX __new__ arguments',
                        f'when serializing {REX.__module__}.REX object'])
                elif proto >= 2:
                    self.assertEqual(cm.exception.__notes__, [
                        "when serializing dict item 'a'",
                        'when serializing tuple item 2',
                        'when serializing functools.partial state',
                        'when serializing functools.partial object',
                        f'when serializing {REX.__module__}.REX reconstructor',
                        f'when serializing {REX.__module__}.REX object'])
                else:
                    self.assertEqual(cm.exception.__notes__, [
                        "when serializing dict item 'a'",
                        'when serializing tuple item 2',
                        f'when serializing {REX.__module__}.REX reconstructor arguments',
                        f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_state(self):
        obj = REX_state(UNPICKLEABLE)
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX_state.__module__}.REX_state state',
                    f'when serializing {REX_state.__module__}.REX_state object'])

    def test_bad_state_setter(self):
        if self.pickler is pickle._Pickler:
            self.skipTest('only verified in the C implementation')
        obj = REX((print, (), 'state', None, None, 42))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    'sixth item of the tuple returned by __reduce__ '
                    'must be callable, not int')
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_state_setter(self):
        obj = REX((print, (), 'state', None, None, UnpickleableCallable()))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX state setter',
                    f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_state_with_state_setter(self):
        obj = REX((print, (), UNPICKLEABLE, None, None, print))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX state',
                    f'when serializing {REX.__module__}.REX object'])

    def test_bad_object_list_items(self):
        # Issue4176: crash when 4th and 5th items of __reduce__()
        # are not iterators
        obj = REX((list, (), None, 42))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises((TypeError, pickle.PicklingError)) as cm:
                    self.dumps(obj, proto)
                self.assertIn(str(cm.exception), {
                    "'int' object is not iterable",
                    'fourth item of the tuple returned by __reduce__ '
                    'must be an iterator, not int'})
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

        if self.pickler is not pickle._Pickler:
            # Python implementation is less strict and also accepts iterables.
            obj = REX((list, (), None, []))
            for proto in protocols:
                with self.subTest(proto=proto):
                    with self.assertRaises(pickle.PicklingError):
                        self.dumps(obj, proto)
                    self.assertEqual(str(cm.exception),
                        'fourth item of the tuple returned by __reduce__ '
                        'must be an iterator, not int')
                    self.assertEqual(cm.exception.__notes__, [
                        f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_object_list_items(self):
        obj = REX_six([1, 2, UNPICKLEABLE])
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX_six.__module__}.REX_six item 2',
                    f'when serializing {REX_six.__module__}.REX_six object'])

    def test_bad_object_dict_items(self):
        # Issue4176: crash when 4th and 5th items of __reduce__()
        # are not iterators
        obj = REX((dict, (), None, None, 42))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises((TypeError, pickle.PicklingError)) as cm:
                    self.dumps(obj, proto)
                self.assertIn(str(cm.exception), {
                    "'int' object is not iterable",
                    'fifth item of the tuple returned by __reduce__ '
                    'must be an iterator, not int'})
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

        for proto in protocols:
            obj = REX((dict, (), None, None, iter([('a',)])))
            with self.subTest(proto=proto):
                with self.assertRaises((ValueError, TypeError)) as cm:
                    self.dumps(obj, proto)
                self.assertIn(str(cm.exception), {
                    'not enough values to unpack (expected 2, got 1)',
                    'dict items iterator must return 2-tuples'})
                self.assertEqual(cm.exception.__notes__, [
                    f'when serializing {REX.__module__}.REX object'])

        if self.pickler is not pickle._Pickler:
            # Python implementation is less strict and also accepts iterables.
            obj = REX((dict, (), None, None, []))
            for proto in protocols:
                with self.subTest(proto=proto):
                    with self.assertRaises(pickle.PicklingError):
                        self.dumps(obj, proto)
                    self.assertEqual(str(cm.exception),
                        'dict items iterator must return 2-tuples')
                    self.assertEqual(cm.exception.__notes__, [
                        f'when serializing {REX.__module__}.REX object'])

    def test_unpickleable_object_dict_items(self):
        obj = REX_seven({'a': UNPICKLEABLE})
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    f"when serializing {REX_seven.__module__}.REX_seven item 'a'",
                    f'when serializing {REX_seven.__module__}.REX_seven object'])

    def test_unpickleable_list_items(self):
        obj = [1, [2, 3, UNPICKLEABLE]]
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    'when serializing list item 2',
                    'when serializing list item 1'])
        for n in [0, 1, 1000, 1005]:
            obj = [*range(n), UNPICKLEABLE]
            for proto in protocols:
                with self.subTest(proto=proto):
                    with self.assertRaises(CustomError) as cm:
                        self.dumps(obj, proto)
                    self.assertEqual(cm.exception.__notes__, [
                        f'when serializing list item {n}'])

    def test_unpickleable_tuple_items(self):
        obj = (1, (2, 3, UNPICKLEABLE))
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    'when serializing tuple item 2',
                    'when serializing tuple item 1'])
        obj = (*range(10), UNPICKLEABLE)
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    'when serializing tuple item 10'])

    def test_unpickleable_dict_items(self):
        obj = {'a': {'b': UNPICKLEABLE}}
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(cm.exception.__notes__, [
                    "when serializing dict item 'b'",
                    "when serializing dict item 'a'"])
        for n in [0, 1, 1000, 1005]:
            obj = dict.fromkeys(range(n))
            obj['a'] = UNPICKLEABLE
            for proto in protocols:
                with self.subTest(proto=proto, n=n):
                    with self.assertRaises(CustomError) as cm:
                        self.dumps(obj, proto)
                    self.assertEqual(cm.exception.__notes__, [
                        "when serializing dict item 'a'"])

    def test_unpickleable_set_items(self):
        obj = {UNPICKLEABLE}
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                if proto >= 4:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing set element'])
                else:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing list item 0',
                        'when serializing tuple item 0',
                        'when serializing set reconstructor arguments'])

    def test_unpickleable_frozenset_items(self):
        obj = frozenset({frozenset({UNPICKLEABLE})})
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(CustomError) as cm:
                    self.dumps(obj, proto)
                if proto >= 4:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing frozenset element',
                        'when serializing frozenset element'])
                else:
                    self.assertEqual(cm.exception.__notes__, [
                        'when serializing list item 0',
                        'when serializing tuple item 0',
                        'when serializing frozenset reconstructor arguments',
                        'when serializing list item 0',
                        'when serializing tuple item 0',
                        'when serializing frozenset reconstructor arguments'])

    def test_global_lookup_error(self):
        # Global name does not exist
        obj = REX('spam')
        obj.__module__ = 'test.picklecommon'
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle {obj!r}: it's not found as test.picklecommon.spam")
                self.assertEqual(str(cm.exception.__context__),
                    "module 'test.picklecommon' has no attribute 'spam'")

        obj.__module__ = 'nonexisting'
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle {obj!r}: No module named 'nonexisting'")
                self.assertEqual(str(cm.exception.__context__),
                    "No module named 'nonexisting'")

        obj.__module__ = ''
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle {obj!r}: Empty module name")
                self.assertEqual(str(cm.exception.__context__),
                    "Empty module name")

        obj.__module__ = None
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle {obj!r}: it's not found as __main__.spam")
                self.assertEqual(str(cm.exception.__context__),
                    "module '__main__' has no attribute 'spam'")

    def test_nonencodable_global_name_error(self):
        for proto in protocols[:4]:
            with self.subTest(proto=proto):
                name = 'nonascii\xff' if proto < 3 else 'nonencodable\udbff'
                obj = REX(name)
                obj.__module__ = __name__
                with support.swap_item(globals(), name, obj):
                    with self.assertRaises(pickle.PicklingError) as cm:
                        self.dumps(obj, proto)
                    self.assertEqual(str(cm.exception),
                        f"can't pickle global identifier {name!r} using pickle protocol {proto}")
                    self.assertIsInstance(cm.exception.__context__, UnicodeEncodeError)

    def test_nonencodable_module_name_error(self):
        for proto in protocols[:4]:
            with self.subTest(proto=proto):
                name = 'nonascii\xff' if proto < 3 else 'nonencodable\udbff'
                obj = REX('test')
                obj.__module__ = name
                mod = types.SimpleNamespace(test=obj)
                with support.swap_item(sys.modules, name, mod):
                    with self.assertRaises(pickle.PicklingError) as cm:
                        self.dumps(obj, proto)
                    self.assertEqual(str(cm.exception),
                        f"can't pickle module identifier {name!r} using pickle protocol {proto}")
                    self.assertIsInstance(cm.exception.__context__, UnicodeEncodeError)

    def test_nested_lookup_error(self):
        # Nested name does not exist
        global TestGlobal
        class TestGlobal:
            class A:
                pass
        obj = REX('TestGlobal.A.B.C')
        obj.__module__ = __name__
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle {obj!r}: "
                    f"it's not found as {__name__}.TestGlobal.A.B.C")
                self.assertEqual(str(cm.exception.__context__),
                    "type object 'A' has no attribute 'B'")

        obj.__module__ = None
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle {obj!r}: "
                    f"it's not found as __main__.TestGlobal.A.B.C")
                self.assertEqual(str(cm.exception.__context__),
                    "module '__main__' has no attribute 'TestGlobal'")

    def test_wrong_object_lookup_error(self):
        # Name is bound to different object
        global TestGlobal
        class TestGlobal:
            pass
        obj = REX('TestGlobal')
        obj.__module__ = __name__
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle {obj!r}: "
                    f"it's not the same object as {__name__}.TestGlobal")
                self.assertIsNone(cm.exception.__context__)

        obj.__module__ = None
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(obj, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle {obj!r}: "
                    f"it's not found as __main__.TestGlobal")
                self.assertEqual(str(cm.exception.__context__),
                    "module '__main__' has no attribute 'TestGlobal'")

    def test_local_lookup_error(self):
        # Test that whichmodule() errors out cleanly when looking up
        # an assumed globally-reachable object fails.
        def f():
            pass
        # Since the function is local, lookup will fail
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(f, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle local object {f!r}")
        # Same without a __module__ attribute (exercises a different path
        # in _pickle.c).
        del f.__module__
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(f, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle local object {f!r}")
        # Yet a different path.
        f.__name__ = f.__qualname__
        for proto in protocols:
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PicklingError) as cm:
                    self.dumps(f, proto)
                self.assertEqual(str(cm.exception),
                    f"Can't pickle local object {f!r}")

    def test_reduce_ex_None(self):
        c = REX_None()
        with self.assertRaises(TypeError):
            self.dumps(c)

    def test_reduce_None(self):
        c = R_None()
        with self.assertRaises(TypeError):
            self.dumps(c)

    @support.skip_if_unlimited_stack_size
    @no_tracing
    def test_bad_getattr(self):
        # Issue #3514: crash when there is an infinite loop in __getattr__
        x = BadGetattr()
        for proto in range(2):
            with support.infinite_recursion(25):
                self.assertRaises(RuntimeError, self.dumps, x, proto)
        for proto in range(2, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(x, proto)

    def test_picklebuffer_error(self):
        # PickleBuffer forbidden with protocol < 5
        pb = pickle.PickleBuffer(b"foobar")
        for proto in range(0, 5):
            with self.subTest(proto=proto):
                with self.assertRaises(pickle.PickleError) as cm:
                    self.dumps(pb, proto)
                self.assertEqual(str(cm.exception),
                    'PickleBuffer can only be pickled with protocol >= 5')

    def test_non_continuous_buffer(self):
        for proto in protocols[5:]:
            with self.subTest(proto=proto):
                pb = pickle.PickleBuffer(memoryview(b"foobar")[::2])
                with self.assertRaises((pickle.PicklingError, BufferError)):
                    self.dumps(pb, proto)

    def test_buffer_callback_error(self):
        def buffer_callback(buffers):
            raise CustomError
        pb = pickle.PickleBuffer(b"foobar")
        with self.assertRaises(CustomError):
            self.dumps(pb, 5, buffer_callback=buffer_callback)

    def test_evil_pickler_mutating_collection(self):
        # https://github.com/python/cpython/issues/92930
        global Clearer
        class Clearer:
            pass

        def check(collection):
            class EvilPickler(self.pickler):
                def persistent_id(self, obj):
                    if isinstance(obj, Clearer):
                        collection.clear()
                    return None
            pickler = EvilPickler(io.BytesIO(), proto)
            try:
                pickler.dump(collection)
            except RuntimeError as e:
                expected = "changed size during iteration"
                self.assertIn(expected, str(e))

        for proto in protocols:
            check([Clearer()])
            check([Clearer(), Clearer()])
            check({Clearer()})
            check({Clearer(), Clearer()})
            check({Clearer(): 1})
            check({Clearer(): 1, Clearer(): 2})
            check({1: Clearer(), 2: Clearer()})

    @support.cpython_only
    def test_bad_ext_code(self):
        # This should never happen in normal circumstances, because the type
        # and the value of the extension code is checked in copyreg.add_extension().
        key = (MyList.__module__, 'MyList')
        def check(code, exc):
            assert key not in copyreg._extension_registry
            assert code not in copyreg._inverted_registry
            with (support.swap_item(copyreg._extension_registry, key, code),
                  support.swap_item(copyreg._inverted_registry, code, key)):
                for proto in protocols[2:]:
                    with self.assertRaises(exc):
                        self.dumps(MyList, proto)

        check(object(), TypeError)
        check(None, TypeError)
        check(-1, (RuntimeError, struct.error))
        check(0, RuntimeError)
        check(2**31, (RuntimeError, OverflowError, struct.error))
        check(2**1000, (OverflowError, struct.error))
        check(-2**1000, (OverflowError, struct.error))


class AbstractPickleTests:
    # Subclass must define self.dumps, self.loads.

    py_version = sys.version_info  # for test_xpickle
    optimized = False

    _testdata = AbstractUnpickleTests._testdata

    def setUp(self):
        pass

    assert_is_copy = AbstractUnpickleTests.assert_is_copy

    def test_misc(self):
        # test various datatypes not tested by testdata
        for proto in protocols:
            with self.subTest('myint', proto=proto):
                if self.py_version < (3, 0) and proto < 2:
                    self.skipTest('int subclasses are not interoperable with Python 2')
                x = myint(4)
                s = self.dumps(x, proto)
                y = self.loads(s)
                self.assert_is_copy(x, y)

            with self.subTest('tuple', proto=proto):
                x = (1, ())
                s = self.dumps(x, proto)
                y = self.loads(s)
                self.assert_is_copy(x, y)

            with self.subTest('initarg', proto=proto):
                if self.py_version < (3, 0):
                    self.skipTest('"classic" classes are not interoperable with Python 2')
                x = initarg(1, x)
                s = self.dumps(x, proto)
                y = self.loads(s)
                self.assert_is_copy(x, y)

        # XXX test __reduce__ protocol?

    def test_roundtrip_equality(self):
        if self.py_version < (3, 0):
            self.skipTest('"classic" classes are not interoperable with Python 2')
        expected = self._testdata
        for proto in protocols:
            s = self.dumps(expected, proto)
            got = self.loads(s)
            self.assert_is_copy(expected, got)

    # There are gratuitous differences between pickles produced by
    # pickle and cPickle, largely because cPickle starts PUT indices at
    # 1 and pickle starts them at 0.  See XXX comment in cPickle's put2() --
    # there's a comment with an exclamation point there whose meaning
    # is a mystery.  cPickle also suppresses PUT for objects with a refcount
    # of 1.
    def dont_test_disassembly(self):
        from io import StringIO
        from pickletools import dis

        for proto, expected in (0, DATA0_DIS), (1, DATA1_DIS):
            s = self.dumps(self._testdata, proto)
            filelike = StringIO()
            dis(s, out=filelike)
            got = filelike.getvalue()
            self.assertEqual(expected, got)

    def _test_recursive_list(self, cls, aslist=identity, minprotocol=0):
        # List containing itself.
        l = cls()
        l.append(l)
        for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(l, proto)
            x = self.loads(s)
            self.assertIsInstance(x, cls)
            y = aslist(x)
            self.assertEqual(len(y), 1)
            self.assertIs(y[0], x)

    def test_recursive_list(self):
        self._test_recursive_list(list)

    def test_recursive_list_subclass(self):
        self._test_recursive_list(MyList, minprotocol=2)

    def test_recursive_list_like(self):
        self._test_recursive_list(REX_six, aslist=lambda x: x.items)

    def _test_recursive_tuple_and_list(self, cls, aslist=identity, minprotocol=0):
        # Tuple containing a list containing the original tuple.
        t = (cls(),)
        t[0].append(t)
        for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(t, proto)
            x = self.loads(s)
            self.assertIsInstance(x, tuple)
            self.assertEqual(len(x), 1)
            self.assertIsInstance(x[0], cls)
            y = aslist(x[0])
            self.assertEqual(len(y), 1)
            self.assertIs(y[0], x)

        # List containing a tuple containing the original list.
        t, = t
        for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(t, proto)
            x = self.loads(s)
            self.assertIsInstance(x, cls)
            y = aslist(x)
            self.assertEqual(len(y), 1)
            self.assertIsInstance(y[0], tuple)
            self.assertEqual(len(y[0]), 1)
            self.assertIs(y[0][0], x)

    def test_recursive_tuple_and_list(self):
        self._test_recursive_tuple_and_list(list)

    def test_recursive_tuple_and_list_subclass(self):
        self._test_recursive_tuple_and_list(MyList, minprotocol=2)

    def test_recursive_tuple_and_list_like(self):
        self._test_recursive_tuple_and_list(REX_six, aslist=lambda x: x.items)

    def _test_recursive_dict(self, cls, asdict=identity, minprotocol=0):
        # Dict containing itself.
        d = cls()
        d[1] = d
        for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(d, proto)
            x = self.loads(s)
            self.assertIsInstance(x, cls)
            y = asdict(x)
            self.assertEqual(list(y.keys()), [1])
            self.assertIs(y[1], x)

    def test_recursive_dict(self):
        self._test_recursive_dict(dict)

    def test_recursive_dict_subclass(self):
        self._test_recursive_dict(MyDict, minprotocol=2)

    def test_recursive_dict_like(self):
        self._test_recursive_dict(REX_seven, asdict=lambda x: x.table)

    def _test_recursive_tuple_and_dict(self, cls, asdict=identity, minprotocol=0):
        # Tuple containing a dict containing the original tuple.
        t = (cls(),)
        t[0][1] = t
        for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(t, proto)
            x = self.loads(s)
            self.assertIsInstance(x, tuple)
            self.assertEqual(len(x), 1)
            self.assertIsInstance(x[0], cls)
            y = asdict(x[0])
            self.assertEqual(list(y), [1])
            self.assertIs(y[1], x)

        # Dict containing a tuple containing the original dict.
        t, = t
        for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(t, proto)
            x = self.loads(s)
            self.assertIsInstance(x, cls)
            y = asdict(x)
            self.assertEqual(list(y), [1])
            self.assertIsInstance(y[1], tuple)
            self.assertEqual(len(y[1]), 1)
            self.assertIs(y[1][0], x)

    def test_recursive_tuple_and_dict(self):
        self._test_recursive_tuple_and_dict(dict)

    def test_recursive_tuple_and_dict_subclass(self):
        self._test_recursive_tuple_and_dict(MyDict, minprotocol=2)

    def test_recursive_tuple_and_dict_like(self):
        self._test_recursive_tuple_and_dict(REX_seven, asdict=lambda x: x.table)

    def _test_recursive_dict_key(self, cls, asdict=identity, minprotocol=0):
        # Dict containing an immutable object (as key) containing the original
        # dict.
        d = cls()
        d[K(d)] = 1
        for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(d, proto)
            x = self.loads(s)
            self.assertIsInstance(x, cls)
            y = asdict(x)
            self.assertEqual(len(y.keys()), 1)
            self.assertIsInstance(list(y.keys())[0], K)
            self.assertIs(list(y.keys())[0].value, x)

    def test_recursive_dict_key(self):
        self._test_recursive_dict_key(dict)

    def test_recursive_dict_subclass_key(self):
        self._test_recursive_dict_key(MyDict, minprotocol=2)

    def test_recursive_dict_like_key(self):
        self._test_recursive_dict_key(REX_seven, asdict=lambda x: x.table)

    def _test_recursive_tuple_and_dict_key(self, cls, asdict=identity, minprotocol=0):
        # Tuple containing a dict containing an immutable object (as key)
        # containing the original tuple.
        t = (cls(),)
        t[0][K(t)] = 1
        for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(t, proto)
            x = self.loads(s)
            self.assertIsInstance(x, tuple)
            self.assertEqual(len(x), 1)
            self.assertIsInstance(x[0], cls)
            y = asdict(x[0])
            self.assertEqual(len(y), 1)
            self.assertIsInstance(list(y.keys())[0], K)
            self.assertIs(list(y.keys())[0].value, x)

        # Dict containing an immutable object (as key) containing a tuple
        # containing the original dict.
        t, = t
        for proto in range(minprotocol, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(t, proto)
            x = self.loads(s)
            self.assertIsInstance(x, cls)
            y = asdict(x)
            self.assertEqual(len(y), 1)
            self.assertIsInstance(list(y.keys())[0], K)
            self.assertIs(list(y.keys())[0].value[0], x)

    def test_recursive_tuple_and_dict_key(self):
        self._test_recursive_tuple_and_dict_key(dict)

    def test_recursive_tuple_and_dict_subclass_key(self):
        self._test_recursive_tuple_and_dict_key(MyDict, minprotocol=2)

    def test_recursive_tuple_and_dict_like_key(self):
        self._test_recursive_tuple_and_dict_key(REX_seven, asdict=lambda x: x.table)

    def test_recursive_set(self):
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')
        # Set containing an immutable object containing the original set.
        y = set()
        y.add(K(y))
        for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(y, proto)
            x = self.loads(s)
            self.assertIsInstance(x, set)
            self.assertEqual(len(x), 1)
            self.assertIsInstance(list(x)[0], K)
            self.assertIs(list(x)[0].value, x)

        # Immutable object containing a set containing the original object.
        y, = y
        for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
            s = self.dumps(y, proto)
            x = self.loads(s)
            self.assertIsInstance(x, K)
            self.assertIsInstance(x.value, set)
            self.assertEqual(len(x.value), 1)
            self.assertIs(list(x.value)[0], x)

    def test_recursive_inst(self):
        # Mutable object containing itself.
        if self.py_version < (3, 0):
            self.skipTest('"classic" classes are not interoperable with Python 2')
        i = Object()
        i.attr = i
        for proto in protocols:
            s = self.dumps(i, proto)
            x = self.loads(s)
            self.assertIsInstance(x, Object)
            self.assertEqual(dir(x), dir(i))
            self.assertIs(x.attr, x)

    def test_recursive_multi(self):
        if self.py_version < (3, 0):
            self.skipTest('"classic" classes are not interoperable with Python 2')
        l = []
        d = {1:l}
        i = Object()
        i.attr = d
        l.append(i)
        for proto in protocols:
            s = self.dumps(l, proto)
            x = self.loads(s)
            self.assertIsInstance(x, list)
            self.assertEqual(len(x), 1)
            self.assertEqual(dir(x[0]), dir(i))
            self.assertEqual(list(x[0].attr.keys()), [1])
            self.assertIs(x[0].attr[1], x)

    def _test_recursive_collection_and_inst(self, factory, oldminproto=None,
                                            minprotocol=0):
        if self.py_version < (3, 0):
            self.skipTest('"classic" classes are not interoperable with Python 2')
        # Mutable object containing a collection containing the original
        # object.
        protocols = range(minprotocol, pickle.HIGHEST_PROTOCOL + 1)
        o = Object()
        o.attr = factory([o])
        t = type(o.attr)
        with self.subTest('obj -> {t.__name__} -> obj'):
            for proto in protocols:
                with self.subTest(proto=proto):
                    s = self.dumps(o, proto)
                    x = self.loads(s)
                    self.assertIsInstance(x.attr, t)
                    self.assertEqual(len(x.attr), 1)
                    self.assertIsInstance(list(x.attr)[0], Object)
                    self.assertIs(list(x.attr)[0], x)

        # Collection containing a mutable object containing the original
        # collection.
        o = o.attr
        with self.subTest(f'{t.__name__} -> obj -> {t.__name__}'):
            if self.py_version < (3, 4) and oldminproto is None:
                self.skipTest('not supported in Python < 3.4')
            for proto in protocols:
                with self.subTest(proto=proto):
                    if self.py_version < (3, 4) and proto < oldminproto:
                        self.skipTest(f'requires protocol {oldminproto} in Python < 3.4')
                    s = self.dumps(o, proto)
                    x = self.loads(s)
                    self.assertIsInstance(x, t)
                    self.assertEqual(len(x), 1)
                    self.assertIsInstance(list(x)[0], Object)
                    self.assertIs(list(x)[0].attr, x)

    def test_recursive_list_and_inst(self):
        self._test_recursive_collection_and_inst(list, oldminproto=0)

    def test_recursive_tuple_and_inst(self):
        self._test_recursive_collection_and_inst(tuple, oldminproto=0)

    def test_recursive_dict_and_inst(self):
        self._test_recursive_collection_and_inst(dict.fromkeys, oldminproto=0)

    def test_recursive_frozendict_and_inst(self):
        if self.py_version < (3, 15):
            self.skipTest('need frozendict')
        self._test_recursive_collection_and_inst(frozendict.fromkeys, minprotocol=2)

    def test_recursive_set_and_inst(self):
        self._test_recursive_collection_and_inst(set)

    def test_recursive_frozenset_and_inst(self):
        self._test_recursive_collection_and_inst(frozenset)

    def test_recursive_list_subclass_and_inst(self):
        self._test_recursive_collection_and_inst(MyList, oldminproto=2)

    def test_recursive_tuple_subclass_and_inst(self):
        self._test_recursive_collection_and_inst(MyTuple)

    def test_recursive_dict_subclass_and_inst(self):
        self._test_recursive_collection_and_inst(MyDict.fromkeys, oldminproto=2)

    def test_recursive_set_subclass_and_inst(self):
        self._test_recursive_collection_and_inst(MySet)

    def test_recursive_frozenset_subclass_and_inst(self):
        self._test_recursive_collection_and_inst(MyFrozenSet)

    def _test_recursive_collection_in_key(self, factory, minprotocol=0):
        protocols = range(minprotocol, pickle.HIGHEST_PROTOCOL + 1)
        key = Object()
        o = factory({key: 1})
        key.attr = o
        for proto in protocols:
            with self.subTest(proto=proto):
                s = self.dumps(o, proto)
                x = self.loads(s)
                keys = list(x.keys())
                self.assertEqual(len(keys), 1)
                self.assertIs(keys[0].attr, x)

    def test_recursive_frozendict_in_key(self):
        if self.py_version < (3, 15):
            self.skipTest('need frozendict')
        self._test_recursive_collection_in_key(frozendict, minprotocol=2)

    def test_recursive_frozendict_subclass_in_key(self):
        if self.py_version < (3, 15):
            self.skipTest('need frozendict')
        self._test_recursive_collection_in_key(MyFrozenDict)

    def _test_recursive_collection_in_value(self, factory, minprotocol=0):
        protocols = range(minprotocol, pickle.HIGHEST_PROTOCOL + 1)
        o = factory(key=[])
        o['key'].append(o)
        for proto in protocols:
            with self.subTest(proto=proto):
                s = self.dumps(o, proto)
                x = self.loads(s)
                self.assertEqual(len(x['key']), 1)
                self.assertIs(x['key'][0], x)

    def test_recursive_frozendict_in_value(self):
        if self.py_version < (3, 15):
            self.skipTest('need frozendict')
        self._test_recursive_collection_in_value(frozendict, minprotocol=2)

    def test_recursive_frozendict_subclass_in_value(self):
        if self.py_version < (3, 15):
            self.skipTest('need frozendict')
        self._test_recursive_collection_in_value(MyFrozenDict)

    def test_recursive_inst_state(self):
        # Mutable object containing itself.
        y = REX_state()
        y.state = y
        for proto in protocols:
            s = self.dumps(y, proto)
            x = self.loads(s)
            self.assertIsInstance(x, REX_state)
            self.assertIs(x.state, x)

    def test_recursive_tuple_and_inst_state(self):
        # Tuple containing a mutable object containing the original tuple.
        t = (REX_state(),)
        t[0].state = t
        for proto in protocols:
            s = self.dumps(t, proto)
            x = self.loads(s)
            self.assertIsInstance(x, tuple)
            self.assertEqual(len(x), 1)
            self.assertIsInstance(x[0], REX_state)
            self.assertIs(x[0].state, x)

        # Mutable object containing a tuple containing the object.
        t, = t
        for proto in protocols:
            s = self.dumps(t, proto)
            x = self.loads(s)
            self.assertIsInstance(x, REX_state)
            self.assertIsInstance(x.state, tuple)
            self.assertEqual(len(x.state), 1)
            self.assertIs(x.state[0], x)

    def test_unicode(self):
        endcases = ['', '<\\u>', '<\\\u1234>', '<\n>',
                    '<\\>', '<\\\U00012345>',
                    # surrogates
                    '<\udc80>']
        for proto in protocols:
            for u in endcases:
                p = self.dumps(u, proto)
                u2 = self.loads(p)
                self.assert_is_copy(u, u2)

    def test_unicode_high_plane(self):
        t = '\U00012345'
        for proto in protocols:
            p = self.dumps(t, proto)
            t2 = self.loads(p)
            self.assert_is_copy(t, t2)

    def test_unicode_memoization(self):
        # Repeated str is re-used (even when escapes added).
        if self.py_version < (3, 0):
            self.skipTest('not supported in Python < 3.0')
        for proto in protocols:
            for s in '', 'xyz', 'xyz\n', 'x\\yz', 'x\xa1yz\r':
                p = self.dumps((s, s), proto)
                s1, s2 = self.loads(p)
                self.assertIs(s1, s2)

    def test_bytes(self):
        for proto in protocols:
            for s in b'', b'xyz', b'xyz'*100:
                p = self.dumps(s, proto)
                self.assert_is_copy(s, self.loads(p))
            for s in [bytes([i]) for i in range(256)]:
                p = self.dumps(s, proto)
                self.assert_is_copy(s, self.loads(p))
            for s in [bytes([i, i]) for i in range(256)]:
                p = self.dumps(s, proto)
                self.assert_is_copy(s, self.loads(p))

    def test_bytes_memoization(self):
        array_types = [bytes]
        if self.py_version >= (3, 4):
            array_types += [ZeroCopyBytes]
        for proto in protocols:
            for array_type in array_types:
                for s in b'', b'xyz', b'xyz'*100:
                    b = array_type(s)
                    expected = (b, b) if self.py_version >= (3, 0) else (b.decode(),)*2
                    with self.subTest(proto=proto, array_type=array_type, s=s, independent=False):
                        p = self.dumps((b, b), proto)
                        x, y = self.loads(p)
                        self.assertIs(x, y)
                        self.assert_is_copy(expected, (x, y))

                    b2 = array_type(s)
                    with self.subTest(proto=proto, array_type=array_type, s=s, independent=True):
                        p = self.dumps((b, b2), proto)
                        # Note that (b, b2) = self.loads(p) might have identical
                        # components, i.e., b is b2, but this is not always the
                        # case if the content is large (equality still holds).
                        self.assert_is_copy(expected, self.loads(p))

    def test_bytearray(self):
        for proto in protocols:
            for s in b'', b'xyz', b'xyz'*100:
                b = bytearray(s)
                p = self.dumps(b, proto)
                bb = self.loads(p)
                self.assertIsNot(bb, b)
                self.assert_is_copy(b, bb)
                if proto <= 3:
                    # bytearray is serialized using a global reference
                    self.assertIn(b'bytearray', p)
                    self.assertTrue(opcode_in_pickle(pickle.GLOBAL, p))
                elif proto == 4:
                    self.assertIn(b'bytearray', p)
                    self.assertTrue(opcode_in_pickle(pickle.STACK_GLOBAL, p))
                elif proto == 5:
                    self.assertNotIn(b'bytearray', p)
                    self.assertTrue(opcode_in_pickle(pickle.BYTEARRAY8, p))

    def test_bytearray_memoization(self):
        array_types = [bytearray]
        if self.py_version >= (3, 4):
            array_types += [ZeroCopyBytearray]
        for proto in protocols:
            for array_type in array_types:
                for s in b'', b'xyz', b'xyz'*100:
                    with self.subTest(proto=proto, array_type=array_type, s=s, independent=False):
                        b = array_type(s)
                        p = self.dumps((b, b), proto)
                        b1, b2 = self.loads(p)
                        self.assertIs(b1, b2)

                    with self.subTest(proto=proto, array_type=array_type, s=s, independent=True):
                        b1a, b2a = array_type(s), array_type(s)
                        # Unlike bytes, equal but independent bytearray objects are
                        # never identical.
                        self.assertIsNot(b1a, b2a)

                        p = self.dumps((b1a, b2a), proto)
                        b1b, b2b = self.loads(p)
                        self.assertIsNot(b1b, b2b)

                        self.assertIsNot(b1a, b1b)
                        self.assert_is_copy(b1a, b1b)

                        self.assertIsNot(b2a, b2b)
                        self.assert_is_copy(b2a, b2b)

    def test_ints(self):
        for proto in protocols:
            n = sys.maxsize
            while n:
                for expected in (-n, n):
                    s = self.dumps(expected, proto)
                    n2 = self.loads(s)
                    self.assert_is_copy(expected, n2)
                n = n >> 1

    def test_long(self):
        for proto in protocols:
            # 256 bytes is where LONG4 begins.
            for nbits in 1, 8, 8*254, 8*255, 8*256, 8*257:
                nbase = 1 << nbits
                for npos in nbase-1, nbase, nbase+1:
                    for n in npos, -npos:
                        pickle = self.dumps(n, proto)
                        got = self.loads(pickle)
                        self.assert_is_copy(n, got)
        # Try a monster.  This is quadratic-time in protos 0 & 1, so don't
        # bother with those.
        nbase = int("deadbeeffeedface", 16)
        nbase += nbase << 1000000
        for n in nbase, -nbase:
            p = self.dumps(n, 2)
            got = self.loads(p)
            # assert_is_copy is very expensive here as it precomputes
            # a failure message by computing the repr() of n and got,
            # we just do the check ourselves.
            self.assertIs(type(got), int)
            self.assertEqual(n, got)

    def test_float(self):
        test_values = [0.0, 4.94e-324, 1e-310, 7e-308, 6.626e-34, 0.1, 0.5,
                       3.14, 263.44582062374053, 6.022e23, 1e30]
        test_values = test_values + [-x for x in test_values]
        for proto in protocols:
            for value in test_values:
                pickle = self.dumps(value, proto)
                got = self.loads(pickle)
                self.assert_is_copy(value, got)

    @run_with_locales('LC_ALL', 'de_DE', 'fr_FR', '')
    def test_float_format(self):
        # make sure that floats are formatted locale independent with proto 0
        self.assertEqual(self.dumps(1.2, 0)[0:3], b'F1.')

    def test_reduce(self):
        for proto in protocols:
            with self.subTest(proto=proto):
                if self.py_version < (3, 4) and proto < 3:
                    self.skipTest('str is not interoperable with Python < 3.4')
                inst = AAA()
                dumped = self.dumps(inst, proto)
                loaded = self.loads(dumped)
                self.assertEqual(loaded, REDUCE_A)

    def test_getinitargs(self):
        if self.py_version < (3, 0):
            self.skipTest('"classic" classes are not interoperable with Python 2')
        for proto in protocols:
            inst = initarg(1, 2)
            dumped = self.dumps(inst, proto)
            loaded = self.loads(dumped)
            self.assert_is_copy(inst, loaded)

    def test_metaclass(self):
        self.assertEqual(type(use_metaclass), metaclass)
        a = use_metaclass()
        for proto in protocols:
            s = self.dumps(a, proto)
            b = self.loads(s)
            self.assertEqual(a.__class__, b.__class__)

    def test_dynamic_class(self):
        a = create_dynamic_class("my_dynamic_class", (object,))
        copyreg.pickle(pickling_metaclass, pickling_metaclass.__reduce__)
        for proto in protocols:
            s = self.dumps(a, proto)
            b = self.loads(s)
            self.assertEqual(a, b)
            self.assertIs(type(a), type(b))

    def test_structseq(self):
        import time
        import os

        t = time.localtime()
        for proto in protocols:
            s = self.dumps(t, proto)
            u = self.loads(s)
            self.assert_is_copy(t, u)
            if self.py_version < (3, 4):
                # module 'os' has no attributes '_make_stat_result' and
                # '_make_statvfs_result'
                continue
            t = os.stat(os.curdir)
            s = self.dumps(t, proto)
            u = self.loads(s)
            self.assert_is_copy(t, u)
            if hasattr(os, "statvfs"):
                t = os.statvfs(os.curdir)
                s = self.dumps(t, proto)
                u = self.loads(s)
                self.assert_is_copy(t, u)

    def test_ellipsis(self):
        if self.py_version < (3, 3):
            self.skipTest('not supported in Python < 3.3')
        for proto in protocols:
            with self.subTest(proto=proto):
                s = self.dumps(..., proto)
                u = self.loads(s)
                self.assertIs(..., u)

    def test_notimplemented(self):
        if self.py_version < (3, 3):
            self.skipTest('not supported in Python < 3.3')
        for proto in protocols:
            with self.subTest(proto=proto):
                s = self.dumps(NotImplemented, proto)
                u = self.loads(s)
                self.assertIs(NotImplemented, u)

    def test_singleton_types(self):
        # Issue #6477: Test that types of built-in singletons can be pickled.
        if self.py_version < (3, 3):
            self.skipTest('not supported in Python < 3.3')
        singletons = [None, ..., NotImplemented]
        for singleton in singletons:
            t = type(singleton)
            for proto in protocols:
                with self.subTest(name=t.__name__, proto=proto):
                    s = self.dumps(t, proto)
                    u = self.loads(s)
                    self.assertIs(t, u)

    def test_builtin_types(self):
        new_names = {
            'bytes': (3, 0),
            'BuiltinImporter': (3, 3),
            'str': (3, 4),  # not interoperable with Python < 3.4
            'frozendict': (3, 15),
        }
        for t in builtins.__dict__.values():
            if isinstance(t, type) and not issubclass(t, BaseException):
                if t.__name__ in new_names and self.py_version < new_names[t.__name__]:
                    continue
                for proto in protocols:
                    with self.subTest(name=t.__name__, proto=proto):
                        s = self.dumps(t, proto)
                        self.assertIs(self.loads(s), t)

    def test_builtin_exceptions(self):
        new_names = {
            'BlockingIOError': (3, 3),
            'BrokenPipeError': (3, 3),
            'ChildProcessError': (3, 3),
            'ConnectionError': (3, 3),
            'ConnectionAbortedError': (3, 3),
            'ConnectionRefusedError': (3, 3),
            'ConnectionResetError': (3, 3),
            'FileExistsError': (3, 3),
            'FileNotFoundError': (3, 3),
            'InterruptedError': (3, 3),
            'IsADirectoryError': (3, 3),
            'NotADirectoryError': (3, 3),
            'PermissionError': (3, 3),
            'ProcessLookupError': (3, 3),
            'TimeoutError': (3, 3),
            'RecursionError': (3, 5),
            'StopAsyncIteration': (3, 5),
            'ModuleNotFoundError': (3, 6),
            'EncodingWarning': (3, 10),
            'BaseExceptionGroup': (3, 11),
            'ExceptionGroup': (3, 11),
            '_IncompleteInputError': (3, 13),
            'PythonFinalizationError': (3, 13),
            'ImportCycleError': (3, 15),
        }
        for t in builtins.__dict__.values():
            if isinstance(t, type) and issubclass(t, BaseException):
                if t.__name__ in new_names and self.py_version < new_names[t.__name__]:
                    continue
                for proto in protocols:
                    with self.subTest(name=t.__name__, proto=proto):
                        if self.py_version < (3, 3) and proto < 3:
                            self.skipTest('exception classes are not interoperable with Python < 3.3')
                        s = self.dumps(t, proto)
                        u = self.loads(s)
                        if proto <= 2 and issubclass(t, OSError) and t is not BlockingIOError:
                            self.assertIs(u, OSError)
                        elif proto <= 2 and issubclass(t, ImportError):
                            self.assertIs(u, ImportError)
                        else:
                            self.assertIs(u, t)

    def test_builtin_functions(self):
        new_names = {
            '__build_class__': (3, 0),
            'ascii': (3, 0),
            'exec': (3, 0),
            'breakpoint': (3, 7),
            'aiter': (3, 10),
            'anext': (3, 10),
            '__lazy_import__': (3, 15),
        }
        for t in builtins.__dict__.values():
            if isinstance(t, types.BuiltinFunctionType):
                if t.__name__ in new_names and self.py_version < new_names[t.__name__]:
                    continue
                for proto in protocols:
                    with self.subTest(name=t.__name__, proto=proto):
                        s = self.dumps(t, proto)
                        self.assertIs(self.loads(s), t)

    # Tests for protocol 2

    def test_proto(self):
        for proto in protocols:
            pickled = self.dumps(None, proto)
            if proto >= 2:
                proto_header = pickle.PROTO + bytes([proto])
                self.assertStartsWith(pickled, proto_header)
            else:
                self.assertEqual(count_opcode(pickle.PROTO, pickled), 0)

    def test_bad_proto(self):
        if self.py_version < (3, 8):
            self.skipTest('no protocol validation in Python < 3.8')
        oob = protocols[-1] + 1     # a future protocol
        build_none = pickle.NONE + pickle.STOP
        badpickle = pickle.PROTO + bytes([oob]) + build_none
        try:
            self.loads(badpickle)
        except ValueError as err:
            self.assertIn("unsupported pickle protocol", str(err))
        else:
            self.fail("expected bad protocol number to raise ValueError")

    def test_long1(self):
        x = 12345678910111213141516178920
        for proto in protocols:
            s = self.dumps(x, proto)
            y = self.loads(s)
            self.assert_is_copy(x, y)
            self.assertEqual(opcode_in_pickle(pickle.LONG1, s), proto >= 2)

    def test_long4(self):
        x = 12345678910111213141516178920 << (256*8)
        for proto in protocols:
            s = self.dumps(x, proto)
            y = self.loads(s)
            self.assert_is_copy(x, y)
            self.assertEqual(opcode_in_pickle(pickle.LONG4, s), proto >= 2)

    def test_short_tuples(self):
        # Map (proto, len(tuple)) to expected opcode.
        expected_opcode = {(0, 0): pickle.TUPLE,
                           (0, 1): pickle.TUPLE,
                           (0, 2): pickle.TUPLE,
                           (0, 3): pickle.TUPLE,
                           (0, 4): pickle.TUPLE,

                           (1, 0): pickle.EMPTY_TUPLE,
                           (1, 1): pickle.TUPLE,
                           (1, 2): pickle.TUPLE,
                           (1, 3): pickle.TUPLE,
                           (1, 4): pickle.TUPLE,

                           (2, 0): pickle.EMPTY_TUPLE,
                           (2, 1): pickle.TUPLE1,
                           (2, 2): pickle.TUPLE2,
                           (2, 3): pickle.TUPLE3,
                           (2, 4): pickle.TUPLE,

                           (3, 0): pickle.EMPTY_TUPLE,
                           (3, 1): pickle.TUPLE1,
                           (3, 2): pickle.TUPLE2,
                           (3, 3): pickle.TUPLE3,
                           (3, 4): pickle.TUPLE,
                          }
        a = ()
        b = (1,)
        c = (1, 2)
        d = (1, 2, 3)
        e = (1, 2, 3, 4)
        for proto in protocols:
            for x in a, b, c, d, e:
                s = self.dumps(x, proto)
                y = self.loads(s)
                self.assert_is_copy(x, y)
                expected = expected_opcode[min(proto, 3), len(x)]
                self.assertTrue(opcode_in_pickle(expected, s))

    def test_singletons(self):
        # Map (proto, singleton) to expected opcode.
        expected_opcode = {(0, None): pickle.NONE,
                           (1, None): pickle.NONE,
                           (2, None): pickle.NONE,
                           (3, None): pickle.NONE,

                           (0, True): pickle.INT,
                           (1, True): pickle.INT,
                           (2, True): pickle.NEWTRUE,
                           (3, True): pickle.NEWTRUE,

                           (0, False): pickle.INT,
                           (1, False): pickle.INT,
                           (2, False): pickle.NEWFALSE,
                           (3, False): pickle.NEWFALSE,
                          }
        for proto in protocols:
            for x in None, False, True:
                s = self.dumps(x, proto)
                y = self.loads(s)
                self.assertTrue(x is y, (proto, x, s, y))
                expected = expected_opcode[min(proto, 3), x]
                self.assertTrue(opcode_in_pickle(expected, s))

    def test_newobj_tuple(self):
        x = MyTuple([1, 2, 3])
        x.foo = 42
        x.bar = "hello"
        for proto in protocols:
            s = self.dumps(x, proto)
            y = self.loads(s)
            self.assert_is_copy(x, y)

    def test_newobj_list(self):
        x = MyList([1, 2, 3])
        x.foo = 42
        x.bar = "hello"
        for proto in protocols:
            s = self.dumps(x, proto)
            y = self.loads(s)
            self.assert_is_copy(x, y)

    def test_newobj_generic(self):
        for proto in protocols:
            for C in myclasses:
                with self.subTest(proto=proto, C=C):
                    if self.py_version < (3, 0) and proto < 2 and C in (MyInt, MyStr):
                        self.skipTest('int and str subclasses are not interoperable with Python 2')
                    if (3, 0) <= self.py_version < (3, 4) and proto < 2 and C in (MyStr, MyUnicode):
                        self.skipTest('str subclasses are not interoperable with Python < 3.4')
                    if self.py_version < (3, 15) and C == MyFrozenDict:
                        self.skipTest('frozendict is not available on Python < 3.15')
                    B = C.__base__
                    x = C(C.sample)
                    x.foo = 42
                    s = self.dumps(x, proto)
                    y = self.loads(s)
                    detail = (proto, C, B, x, y, type(y))
                    self.assert_is_copy(x, y) # XXX revisit
                    self.assertEqual(B(x), B(y), detail)
                    self.assertEqual(x.__dict__, y.__dict__, detail)

    def test_newobj_proxies(self):
        # NEWOBJ should use the __class__ rather than the raw type
        classes = myclasses[:]
        # Cannot create weakproxies to these classes
        for c in (MyInt, MyLong, MyTuple):
            classes.remove(c)
        for proto in protocols:
            for C in classes:
                with self.subTest(proto=proto, C=C):
                    if self.py_version < (3, 4) and proto < 3 and C in (MyStr, MyUnicode):
                        self.skipTest('str subclasses are not interoperable with Python < 3.4')
                    if self.py_version < (3, 15) and C == MyFrozenDict:
                        self.skipTest('frozendict is not available on Python < 3.15')
                    B = C.__base__
                    x = C(C.sample)
                    x.foo = 42
                    p = weakref.proxy(x)
                    s = self.dumps(p, proto)
                    y = self.loads(s)
                    self.assertEqual(type(y), type(x))  # rather than type(p)
                    detail = (proto, C, B, x, y, type(y))
                    self.assertEqual(B(x), B(y), detail)
                    self.assertEqual(x.__dict__, y.__dict__, detail)

    def test_newobj_overridden_new(self):
        # Test that Python class with C implemented __new__ is pickleable
        for proto in protocols:
            with self.subTest(proto=proto):
                if self.py_version < (3, 0) and proto < 2:
                    self.skipTest('int subclasses are not interoperable with Python 2')
                x = MyIntWithNew2(1)
                x.foo = 42
                s = self.dumps(x, proto)
                y = self.loads(s)
                self.assertIs(type(y), MyIntWithNew2)
                self.assertEqual(int(y), 1)
                self.assertEqual(y.foo, 42)

    def test_newobj_not_class(self):
        # Issue 24552
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')
        o = SimpleNewObj.__new__(SimpleNewObj)
        b = self.dumps(o, 4)
        with support.swap_attr(picklecommon, 'SimpleNewObj', 42):
            self.assertRaises((TypeError, pickle.UnpicklingError), self.loads, b)

    # Register a type with copyreg, with extension code extcode.  Pickle
    # an object of that type.  Check that the resulting pickle uses opcode
    # (EXT[124]) under proto 2, and not in proto 1.

    def produce_global_ext(self, extcode, opcode):
        e = ExtensionSaver(extcode)
        try:
            copyreg.add_extension(MyList.__module__, "MyList", extcode)
            x = MyList([1, 2, 3])
            x.foo = 42
            x.bar = "hello"

            # Dump using protocol 1 for comparison.
            s1 = self.dumps(x, 1)
            self.assertIn(MyList.__module__.encode(), s1)
            self.assertIn(b"MyList", s1)
            self.assertFalse(opcode_in_pickle(opcode, s1))

            y = self.loads(s1)
            self.assert_is_copy(x, y)

            # Dump using protocol 2 for test.
            s2 = self.dumps(x, 2)
            self.assertNotIn(MyList.__module__.encode(), s2)
            self.assertNotIn(b"MyList", s2)
            self.assertEqual(opcode_in_pickle(opcode, s2), True, repr(s2))

            y = self.loads(s2)
            self.assert_is_copy(x, y)
        finally:
            e.restore()

    def test_global_ext1(self):
        self.produce_global_ext(0x00000001, pickle.EXT1)  # smallest EXT1 code
        self.produce_global_ext(0x000000ff, pickle.EXT1)  # largest EXT1 code

    def test_global_ext2(self):
        self.produce_global_ext(0x00000100, pickle.EXT2)  # smallest EXT2 code
        self.produce_global_ext(0x0000ffff, pickle.EXT2)  # largest EXT2 code
        self.produce_global_ext(0x0000abcd, pickle.EXT2)  # check endianness

    def test_global_ext4(self):
        self.produce_global_ext(0x00010000, pickle.EXT4)  # smallest EXT4 code
        self.produce_global_ext(0x7fffffff, pickle.EXT4)  # largest EXT4 code
        self.produce_global_ext(0x12abcdef, pickle.EXT4)  # check endianness

    def test_list_chunking(self):
        n = 10  # too small to chunk
        x = list(range(n))
        for proto in protocols:
            s = self.dumps(x, proto)
            y = self.loads(s)
            self.assert_is_copy(x, y)
            num_appends = count_opcode(pickle.APPENDS, s)
            self.assertEqual(num_appends, proto > 0)

        n = 2500  # expect at least two chunks when proto > 0
        x = list(range(n))
        for proto in protocols:
            s = self.dumps(x, proto)
            y = self.loads(s)
            self.assert_is_copy(x, y)
            num_appends = count_opcode(pickle.APPENDS, s)
            if proto == 0:
                self.assertEqual(num_appends, 0)
            else:
                self.assertTrue(num_appends >= 2)

    def test_dict_chunking(self):
        n = 10  # too small to chunk
        x = dict.fromkeys(range(n))
        for proto in protocols:
            s = self.dumps(x, proto)
            self.assertIsInstance(s, bytes_types)
            y = self.loads(s)
            self.assert_is_copy(x, y)
            num_setitems = count_opcode(pickle.SETITEMS, s)
            self.assertEqual(num_setitems, proto > 0)

        n = 2500  # expect at least two chunks when proto > 0
        x = dict.fromkeys(range(n))
        for proto in protocols:
            s = self.dumps(x, proto)
            y = self.loads(s)
            self.assert_is_copy(x, y)
            num_setitems = count_opcode(pickle.SETITEMS, s)
            if proto == 0:
                self.assertEqual(num_setitems, 0)
            else:
                self.assertTrue(num_setitems >= 2)

    def test_set_chunking(self):
        n = 10  # too small to chunk
        x = set(range(n))
        for proto in protocols:
            s = self.dumps(x, proto)
            y = self.loads(s)
            self.assert_is_copy(x, y)
            num_additems = count_opcode(pickle.ADDITEMS, s)
            if proto < 4:
                self.assertEqual(num_additems, 0)
            else:
                self.assertEqual(num_additems, 1)

        n = 2500  # expect at least two chunks when proto >= 4
        x = set(range(n))
        for proto in protocols:
            s = self.dumps(x, proto)
            y = self.loads(s)
            self.assert_is_copy(x, y)
            num_additems = count_opcode(pickle.ADDITEMS, s)
            if proto < 4:
                self.assertEqual(num_additems, 0)
            else:
                self.assertGreaterEqual(num_additems, 2)

    def test_simple_newobj(self):
        x = SimpleNewObj.__new__(SimpleNewObj, 0xface)  # avoid __init__
        x.abc = 666
        for proto in protocols:
            with self.subTest(proto=proto):
                if self.py_version < (3, 0) and proto < 2:
                    self.skipTest('int subclasses are not interoperable with Python 2')
                s = self.dumps(x, proto)
                if proto < 1:
                    if self.py_version >= (3, 7):
                        self.assertIn(b'\nI64206', s)  # INT
                    else:  # for test_xpickle
                        self.assertIn(b'64206', s)  # INT or LONG
                else:
                    self.assertIn(b'M\xce\xfa', s)  # BININT2
                if not (self.py_version < (3, 5) and proto == 4):
                    self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
                                     2 <= proto)
                    self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
                y = self.loads(s)   # will raise TypeError if __init__ called
                self.assert_is_copy(x, y)

    def test_complex_newobj(self):
        x = ComplexNewObj.__new__(ComplexNewObj, 0xface)  # avoid __init__
        x.abc = 666
        for proto in protocols:
            with self.subTest(proto=proto):
                if self.py_version < (3, 0) and proto < 2:
                    self.skipTest('int subclasses are not interoperable with Python 2')
                s = self.dumps(x, proto)
                if proto < 1:
                    if self.py_version >= (3, 7):
                        self.assertIn(b'\nI64206', s)  # INT
                    else:  # for test_xpickle
                        self.assertIn(b'64206', s)  # INT or LONG
                elif proto < 2:
                    self.assertIn(b'M\xce\xfa', s)  # BININT2
                elif proto < 4:
                    if self.py_version >= (3, 0):
                        self.assertIn(b'X\x04\x00\x00\x00FACE', s)  # BINUNICODE
                    else:  # for test_xpickle
                        self.assertIn(b'U\x04FACE', s)  # SHORT_BINSTRING
                else:
                    self.assertIn(b'\x8c\x04FACE', s)  # SHORT_BINUNICODE
                if not (self.py_version < (3, 5) and proto == 4):
                    self.assertEqual(opcode_in_pickle(pickle.NEWOBJ, s),
                                     2 <= proto)
                    self.assertFalse(opcode_in_pickle(pickle.NEWOBJ_EX, s))
                y = self.loads(s)   # will raise TypeError if __init__ called
                self.assert_is_copy(x, y)

    def test_complex_newobj_ex(self):
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')
        x = ComplexNewObjEx.__new__(ComplexNewObjEx, 0xface)  # avoid __init__
        x.abc = 666
        for proto in protocols:
            with self.subTest(proto=proto):
                if self.py_version < (3, 6) and proto < 4:
                    self.skipTest('requires protocol 4 in Python < 3.6')
                s = self.dumps(x, proto)
                if proto < 1:
                    if self.py_version >= (3, 7):
                        self.assertIn(b'\nI64206', s)  # INT
                    else:  # for test_xpickle
                        self.assertIn(b'64206', s)  # INT or LONG
                elif proto < 2:
                    self.assertIn(b'M\xce\xfa', s)  # BININT2
                elif proto < 4:
                    self.assertIn(b'X\x04\x00\x00\x00FACE', s)  # BINUNICODE
                else:
                    self.assertIn(b'\x8c\x04FACE', s)  # SHORT_BINUNICODE
                self.assertFalse(opcode_in_pickle(pickle.NEWOBJ, s))
                self.assertEqual(opcode_in_pickle(pickle.NEWOBJ_EX, s),
                                 4 <= proto)
                y = self.loads(s)   # will raise TypeError if __init__ called
                self.assert_is_copy(x, y)

    def test_newobj_list_slots(self):
        x = SlotList([1, 2, 3])
        x.foo = 42
        x.bar = "hello"
        s = self.dumps(x, 2)
        y = self.loads(s)
        self.assert_is_copy(x, y)

    def test_reduce_overrides_default_reduce_ex(self):
        for proto in protocols:
            x = REX_one()
            self.assertEqual(x._reduce_called, 0)
            s = self.dumps(x, proto)
            self.assertEqual(x._reduce_called, 1)
            y = self.loads(s)
            self.assertEqual(y._reduce_called, 0)

    def test_reduce_ex_called(self):
        for proto in protocols:
            x = REX_two()
            self.assertEqual(x._proto, None)
            s = self.dumps(x, proto)
            self.assertEqual(x._proto, proto)
            y = self.loads(s)
            self.assertEqual(y._proto, None)

    def test_reduce_ex_overrides_reduce(self):
        for proto in protocols:
            x = REX_three()
            self.assertEqual(x._proto, None)
            s = self.dumps(x, proto)
            self.assertEqual(x._proto, proto)
            y = self.loads(s)
            self.assertEqual(y._proto, None)

    def test_reduce_ex_calls_base(self):
        for proto in protocols:
            x = REX_four()
            self.assertEqual(x._proto, None)
            s = self.dumps(x, proto)
            self.assertEqual(x._proto, proto)
            y = self.loads(s)
            self.assertEqual(y._proto, proto)

    def test_reduce_calls_base(self):
        for proto in protocols:
            x = REX_five()
            self.assertEqual(x._reduce_called, 0)
            s = self.dumps(x, proto)
            self.assertEqual(x._reduce_called, 1)
            y = self.loads(s)
            self.assertEqual(y._reduce_called, 1)

    def test_pickle_setstate_None(self):
        c = C_None_setstate()
        p = self.dumps(c)
        with self.assertRaises(TypeError):
            self.loads(p)

    def test_many_puts_and_gets(self):
        # Test that internal data structures correctly deal with lots of
        # puts/gets.
        keys = ("aaa" + str(i) for i in range(100))
        large_dict = dict((k, [4, 5, 6]) for k in keys)
        obj = [dict(large_dict), dict(large_dict), dict(large_dict)]

        for proto in protocols:
            with self.subTest(proto=proto):
                dumped = self.dumps(obj, proto)
                loaded = self.loads(dumped)
                self.assert_is_copy(obj, loaded)

    def test_attribute_name_interning(self):
        # Test that attribute names of pickled objects are interned when
        # unpickling.
        if self.py_version < (3, 0):
            self.skipTest('"classic" classes are not interoperable with Python 2')
        for proto in protocols:
            x = C()
            x.foo = 42
            x.bar = "hello"
            s = self.dumps(x, proto)
            y = self.loads(s)
            x_keys = sorted(x.__dict__)
            y_keys = sorted(y.__dict__)
            for x_key, y_key in zip(x_keys, y_keys):
                self.assertIs(x_key, y_key)

    def test_pickle_to_2x(self):
        # Pickle non-trivial data with protocol 2, expecting that it yields
        # the same result as Python 2.x did.
        # NOTE: this test is a bit too strong since we can produce different
        # bytecode that 2.x will still understand.
        dumped = self.dumps(range(5), 2)
        self.assertEqual(dumped, DATA_XRANGE)
        dumped = self.dumps(set([3]), 2)
        self.assertEqual(dumped, DATA_SET2)

    def test_large_pickles(self):
        # Test the correctness of internal buffering routines when handling
        # large data.
        for proto in protocols:
            data = (1, min, b'xy' * (30 * 1024), len)
            dumped = self.dumps(data, proto)
            loaded = self.loads(dumped)
            self.assertEqual(len(loaded), len(data))
            if self.py_version < (3, 0):
                data = (1, min, 'xy' * (30 * 1024), len)
            self.assertEqual(loaded, data)

    def test_int_pickling_efficiency(self):
        # Test compacity of int representation (see issue #12744)
        if self.py_version < (3, 3):
            self.skipTest('not supported in Python < 3.3')
        for proto in protocols:
            with self.subTest(proto=proto):
                pickles = [self.dumps(2**n, proto) for n in range(70)]
                sizes = list(map(len, pickles))
                # the size function is monotonic
                self.assertEqual(sorted(sizes), sizes)
                if proto >= 2:
                    for p in pickles:
                        self.assertFalse(opcode_in_pickle(pickle.LONG, p))

    def _check_pickling_with_opcode(self, obj, opcode, proto):
        pickled = self.dumps(obj, proto)
        self.assertTrue(opcode_in_pickle(opcode, pickled))
        unpickled = self.loads(pickled)
        self.assertEqual(obj, unpickled)

    def test_appends_on_non_lists(self):
        # Issue #17720
        obj = REX_six([1, 2, 3])
        for proto in protocols:
            with self.subTest(proto=proto):
                if proto == 0:
                    self._check_pickling_with_opcode(obj, pickle.APPEND, proto)
                else:
                    if self.py_version < (3, 0):
                        self.skipTest('not supported in Python 2')
                    self._check_pickling_with_opcode(obj, pickle.APPENDS, proto)

    def test_setitems_on_non_dicts(self):
        obj = REX_seven({1: -1, 2: -2, 3: -3})
        for proto in protocols:
            if proto == 0:
                self._check_pickling_with_opcode(obj, pickle.SETITEM, proto)
            else:
                self._check_pickling_with_opcode(obj, pickle.SETITEMS, proto)

    # Exercise framing (proto >= 4) for significant workloads

    FRAME_SIZE_MIN = 4
    FRAME_SIZE_TARGET = 64 * 1024

    def check_frame_opcodes(self, pickled):
        """
        Check the arguments of FRAME opcodes in a protocol 4+ pickle.

        Note that binary objects that are larger than FRAME_SIZE_TARGET are not
        framed by default and are therefore considered a frame by themselves in
        the following consistency check.
        """
        frame_end = frameless_start = None
        frameless_opcodes = {'BINBYTES', 'BINUNICODE', 'BINBYTES8',
                             'BINUNICODE8', 'BYTEARRAY8'}
        for op, arg, pos in pickletools.genops(pickled):
            if frame_end is not None:
                self.assertLessEqual(pos, frame_end)
                if pos == frame_end:
                    frame_end = None

            if frame_end is not None:  # framed
                self.assertNotEqual(op.name, 'FRAME')
                if op.name in frameless_opcodes:
                    # Only short bytes and str objects should be written
                    # in a frame
                    self.assertLessEqual(len(arg), self.FRAME_SIZE_TARGET)

            else:  # not framed
                if (op.name == 'FRAME' or
                    (op.name in frameless_opcodes and
                     len(arg) > self.FRAME_SIZE_TARGET)):
                    # Frame or large bytes or str object
                    if frameless_start is not None:
                        # Only short data should be written outside of a frame
                        self.assertLess(pos - frameless_start,
                                        self.FRAME_SIZE_MIN)
                        frameless_start = None
                elif frameless_start is None and op.name != 'PROTO':
                    frameless_start = pos

            if op.name == 'FRAME':
                self.assertGreaterEqual(arg, self.FRAME_SIZE_MIN)
                frame_end = pos + 9 + arg

        pos = len(pickled)
        if frame_end is not None:
            self.assertEqual(frame_end, pos)
        elif frameless_start is not None:
            self.assertLess(pos - frameless_start, self.FRAME_SIZE_MIN)

    @support.skip_if_pgo_task
    @support.requires_resource('cpu')
    def test_framing_many_objects(self):
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')
        obj = list(range(10**5))
        for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
            with self.subTest(proto=proto):
                pickled = self.dumps(obj, proto)
                unpickled = self.loads(pickled)
                self.assertEqual(obj, unpickled)
                bytes_per_frame = (len(pickled) /
                                   count_opcode(pickle.FRAME, pickled))
                self.assertGreater(bytes_per_frame,
                                   self.FRAME_SIZE_TARGET / 2)
                self.assertLessEqual(bytes_per_frame,
                                     self.FRAME_SIZE_TARGET * 1)
                self.check_frame_opcodes(pickled)

    def test_framing_large_objects(self):
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')
        N = 1024 * 1024
        small_items = [[i] for i in range(10)]
        obj = [b'x' * N, *small_items, b'y' * N, 'z' * N]
        for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
            for fast in [False, True]:
                with self.subTest(proto=proto, fast=fast):
                    if not fast:
                        # fast=False by default.
                        # This covers in-memory pickling with pickle.dumps().
                        pickled = self.dumps(obj, proto)
                    else:
                        # Pickler is required when fast=True.
                        if not hasattr(self, 'pickler'):
                            continue
                        buf = io.BytesIO()
                        pickler = self.pickler(buf, protocol=proto)
                        pickler.fast = fast
                        pickler.dump(obj)
                        pickled = buf.getvalue()
                    unpickled = self.loads(pickled)
                    # More informative error message in case of failure.
                    self.assertEqual([len(x) for x in obj],
                                     [len(x) for x in unpickled])
                    # Perform full equality check if the lengths match.
                    self.assertEqual(obj, unpickled)
                    if self.py_version >= (3, 7):
                        n_frames = count_opcode(pickle.FRAME, pickled)
                        # A single frame for small objects between
                        # first two large objects.
                        self.assertEqual(n_frames, 1)
                        self.check_frame_opcodes(pickled)

    def test_optional_frames(self):
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')

        def remove_frames(pickled, keep_frame=None):
            """Remove frame opcodes from the given pickle."""
            frame_starts = []
            # 1 byte for the opcode and 8 for the argument
            frame_opcode_size = 9
            for opcode, _, pos in pickletools.genops(pickled):
                if opcode.name == 'FRAME':
                    frame_starts.append(pos)

            newpickle = bytearray()
            last_frame_end = 0
            for i, pos in enumerate(frame_starts):
                if keep_frame and keep_frame(i):
                    continue
                newpickle += pickled[last_frame_end:pos]
                last_frame_end = pos + frame_opcode_size
            newpickle += pickled[last_frame_end:]
            return newpickle

        frame_size = self.FRAME_SIZE_TARGET
        num_frames = 20
        # Large byte objects (dict values) intermittent with small objects
        # (dict keys)
        for bytes_type in (bytes, bytearray):
            obj = {i: bytes_type([i]) * frame_size for i in range(num_frames)}

            for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
                pickled = self.dumps(obj, proto)

                frameless_pickle = remove_frames(pickled)
                self.assertEqual(count_opcode(pickle.FRAME, frameless_pickle), 0)
                self.assertEqual(obj, self.loads(frameless_pickle))

                some_frames_pickle = remove_frames(pickled, lambda i: i % 2)
                self.assertLess(count_opcode(pickle.FRAME, some_frames_pickle),
                                count_opcode(pickle.FRAME, pickled))
                self.assertEqual(obj, self.loads(some_frames_pickle))

    @support.skip_if_pgo_task
    def test_framed_write_sizes_with_delayed_writer(self):
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')

        class ChunkAccumulator:
            """Accumulate pickler output in a list of raw chunks."""
            def __init__(self):
                self.chunks = []
            def write(self, chunk):
                self.chunks.append(chunk)
            def concatenate_chunks(self):
                return b"".join(self.chunks)

        for proto in range(4, pickle.HIGHEST_PROTOCOL + 1):
            objects = [(str(i).encode('ascii'), i % 42, {'i': str(i)})
                       for i in range(int(1e4))]
            # Add a large unique ASCII string
            objects.append('0123456789abcdef' *
                           (self.FRAME_SIZE_TARGET // 16 + 1))

            # Protocol 4 packs groups of small objects into frames and issues
            # calls to write only once or twice per frame:
            # The C pickler issues one call to write per-frame (header and
            # contents) while Python pickler issues two calls to write: one for
            # the frame header and one for the frame binary contents.
            writer = ChunkAccumulator()
            self.pickler(writer, proto).dump(objects)

            # Actually read the binary content of the chunks after the end
            # of the call to dump: any memoryview passed to write should not
            # be released otherwise this delayed access would not be possible.
            pickled = writer.concatenate_chunks()
            reconstructed = self.loads(pickled)
            self.assertEqual(reconstructed, objects)
            self.assertGreater(len(writer.chunks), 1)

            # memoryviews should own the memory.
            del objects
            support.gc_collect()
            self.assertEqual(writer.concatenate_chunks(), pickled)

            n_frames = (len(pickled) - 1) // self.FRAME_SIZE_TARGET + 1
            # There should be at least one call to write per frame
            self.assertGreaterEqual(len(writer.chunks), n_frames)

            # but not too many either: there can be one for the proto,
            # one per-frame header, one per frame for the actual contents,
            # and two for the header.
            self.assertLessEqual(len(writer.chunks), 2 * n_frames + 3)

            chunk_sizes = [len(c) for c in writer.chunks]
            large_sizes = [s for s in chunk_sizes
                           if s >= self.FRAME_SIZE_TARGET]
            medium_sizes = [s for s in chunk_sizes
                           if 9 < s < self.FRAME_SIZE_TARGET]
            small_sizes = [s for s in chunk_sizes if s <= 9]

            # Large chunks should not be too large:
            for chunk_size in large_sizes:
                self.assertLess(chunk_size, 2 * self.FRAME_SIZE_TARGET,
                                chunk_sizes)
            # There shouldn't bee too many small chunks: the protocol header,
            # the frame headers and the large string headers are written
            # in small chunks.
            self.assertLessEqual(len(small_sizes),
                                 len(large_sizes) + len(medium_sizes) + 3,
                                 chunk_sizes)

    def test_nested_names(self):
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')
        # required protocol 4 in Python 3.4
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            if self.py_version < (3, 5) and proto < 4:
                continue
            for obj in [Nested.A, Nested.A.B, Nested.A.B.C]:
                with self.subTest(proto=proto, obj=obj):
                    unpickled = self.loads(self.dumps(obj, proto))
                    self.assertIs(obj, unpickled)

    def test_recursive_nested_names(self):
        global Recursive
        class Recursive:
            pass
        Recursive.mod = sys.modules[Recursive.__module__]
        Recursive.__qualname__ = 'Recursive.mod.Recursive'
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(Recursive, proto))
                self.assertIs(unpickled, Recursive)
        del Recursive.mod # break reference loop

    def test_recursive_nested_names2(self):
        global Recursive
        class Recursive:
            pass
        Recursive.ref = Recursive
        Recursive.__qualname__ = 'Recursive.ref'
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(Recursive, proto))
                self.assertIs(unpickled, Recursive)
        del Recursive.ref # break reference loop

    def test_py_methods(self):
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')
        py_methods = (
            PyMethodsTest.wine,
            PyMethodsTest().biscuits,
        )
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            for method in py_methods:
                with self.subTest(proto=proto, method=method):
                    unpickled = self.loads(self.dumps(method, proto))
                    self.assertEqual(method(), unpickled())

        # required protocol 4 in Python 3.4
        py_methods = (
            PyMethodsTest.cheese,
            PyMethodsTest.Nested.ketchup,
            PyMethodsTest.Nested.maple,
            PyMethodsTest.Nested().pie
        )
        py_unbound_methods = (
            (PyMethodsTest.biscuits, PyMethodsTest),
            (PyMethodsTest.Nested.pie, PyMethodsTest.Nested)
        )
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            if self.py_version < (3, 5) and proto < 4:
                continue
            for method in py_methods:
                with self.subTest(proto=proto, method=method):
                    unpickled = self.loads(self.dumps(method, proto))
                    self.assertEqual(method(), unpickled())
            for method, cls in py_unbound_methods:
                obj = cls()
                with self.subTest(proto=proto, method=method):
                    unpickled = self.loads(self.dumps(method, proto))
                    self.assertEqual(method(obj), unpickled(obj))

        descriptors = (
            PyMethodsTest.__dict__['cheese'],  # static method descriptor
            PyMethodsTest.__dict__['wine'],  # class method descriptor
        )
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            for descr in descriptors:
                with self.subTest(proto=proto, descr=descr):
                    self.assertRaises(TypeError, self.dumps, descr, proto)

    def test_c_methods(self):
        if self.py_version < (3, 4):
            self.skipTest('not supported in Python < 3.4')
        c_methods = (
            # bound built-in method
            ("abcd".index, ("c",)),
            # unbound built-in method
            (str.index, ("abcd", "c")),
            # bound "slot" method
            ([1, 2, 3].__len__, ()),
            # unbound "slot" method
            (list.__len__, ([1, 2, 3],)),
            # bound "coexist" method
            ({1, 2}.__contains__, (2,)),
            # unbound "coexist" method
            (set.__contains__, ({1, 2}, 2)),
            # built-in class method
            (dict.fromkeys, (("a", 1), ("b", 2))),
            # built-in static method
            (bytearray.maketrans, (b"abc", b"xyz")),
            # subclass methods
            (Subclass([1,2,2]).count, (2,)),
            (Subclass.count, (Subclass([1,2,2]), 2)),
            (Subclass.Nested.count, (Subclass.Nested("sweet"), "e")),
        )
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            for method, args in c_methods:
                with self.subTest(proto=proto, method=method):
                    unpickled = self.loads(self.dumps(method, proto))
                    self.assertEqual(method(*args), unpickled(*args))

        # required protocol 4 in Python 3.4
        c_methods = (
            (Subclass.Nested("sweet").count, ("e",)),
        )
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            if self.py_version < (3, 5) and proto < 4:
                continue
            for method, args in c_methods:
                with self.subTest(proto=proto, method=method):
                    unpickled = self.loads(self.dumps(method, proto))
                    self.assertEqual(method(*args), unpickled(*args))

        descriptors = (
            bytearray.__dict__['maketrans'],  # built-in static method descriptor
            dict.__dict__['fromkeys'],  # built-in class method descriptor
        )
        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
            for descr in descriptors:
                with self.subTest(proto=proto, descr=descr):
                    self.assertRaises(TypeError, self.dumps, descr, proto)

    def test_private_methods(self):
        if self.py_version < (3, 15):
            self.skipTest('not supported in Python < 3.15')
        obj = PrivateMethods(42)
        for proto in protocols:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(obj.get_method(), proto))
                self.assertEqual(unpickled(), 42)
                unpickled = self.loads(self.dumps(obj.get_unbound_method(), proto))
                self.assertEqual(unpickled(obj), 42)
                unpickled = self.loads(self.dumps(obj.get_classmethod(), proto))
                self.assertEqual(unpickled(), 43)
                unpickled = self.loads(self.dumps(obj.get_staticmethod(), proto))
                self.assertEqual(unpickled(), 44)

    def test_private_nested_classes(self):
        if self.py_version < (3, 15):
            self.skipTest('not supported in Python < 3.15')
        cls1 = PrivateNestedClasses.get_nested()
        cls2 = cls1.get_nested2()
        for proto in protocols:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(cls1, proto))
                self.assertIs(unpickled, cls1)
                unpickled = self.loads(self.dumps(cls2, proto))
                self.assertIs(unpickled, cls2)

    def test_object_with_attrs(self):
        obj = Object()
        obj.a = 1
        for proto in protocols:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(obj, proto))
                self.assertEqual(unpickled.a, obj.a)

    def test_object_with_slots(self):
        obj = WithSlots()
        obj.a = 1
        self.assertRaises(TypeError, self.dumps, obj, 0)
        self.assertRaises(TypeError, self.dumps, obj, 1)
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(obj, proto))
                self.assertEqual(unpickled.a, obj.a)
                self.assertNotHasAttr(unpickled, 'b')

        obj = WithSlotsSubclass()
        obj.a = 1
        obj.c = 2
        self.assertRaises(TypeError, self.dumps, obj, 0)
        self.assertRaises(TypeError, self.dumps, obj, 1)
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(obj, proto))
                self.assertEqual(unpickled.a, obj.a)
                self.assertEqual(unpickled.c, obj.c)
                self.assertNotHasAttr(unpickled, 'b')

        obj = WithSlotsAndDict()
        obj.a = 1
        obj.c = 2
        self.assertRaises(TypeError, self.dumps, obj, 0)
        self.assertRaises(TypeError, self.dumps, obj, 1)
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(obj, proto))
                self.assertEqual(unpickled.a, obj.a)
                self.assertEqual(unpickled.c, obj.c)
                self.assertEqual(unpickled.__dict__, obj.__dict__)
                self.assertNotHasAttr(unpickled, 'b')

    def test_object_with_private_attrs(self):
        obj = WithPrivateAttrs(1)
        for proto in protocols:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(obj, proto))
                self.assertEqual(unpickled.get(), obj.get())

        obj = WithPrivateAttrsSubclass(1, 2)
        for proto in protocols:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(obj, proto))
                self.assertEqual(unpickled.get(), obj.get())
                self.assertEqual(unpickled.get2(), obj.get2())

    def test_object_with_private_slots(self):
        obj = WithPrivateSlots(1)
        self.assertRaises(TypeError, self.dumps, obj, 0)
        self.assertRaises(TypeError, self.dumps, obj, 1)
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(obj, proto))
                self.assertEqual(unpickled.get(), obj.get())

        obj = WithPrivateSlotsSubclass(1, 2)
        self.assertRaises(TypeError, self.dumps, obj, 0)
        self.assertRaises(TypeError, self.dumps, obj, 1)
        for proto in protocols[2:]:
            with self.subTest(proto=proto):
                unpickled = self.loads(self.dumps(obj, proto))
                self.assertEqual(unpickled.get(), obj.get())
                self.assertEqual(unpickled.get2(), obj.get2())

    def test_compat_pickle(self):
        if self.py_version < (3, 4):
            self.skipTest("doesn't work in Python < 3.4'")
        tests = [
            (range(1, 7), '__builtin__', 'xrange'),
            (map(int, '123'), 'itertools', 'imap'),
            (functools.reduce, '__builtin__', 'reduce'),
            (dbm.whichdb, 'whichdb', 'whichdb'),
            (Exception(), 'exceptions', 'Exception'),
            (collections.UserDict(), 'UserDict', 'IterableUserDict'),
            (collections.UserList(), 'UserList', 'UserList'),
            (collections.defaultdict(), 'collections', 'defaultdict'),
        ]
        for val, mod, name in tests:
            for proto in range(3):
                with self.subTest(type=type(val), proto=proto):
                    pickled = self.dumps(val, proto)
                    self.assertIn(('c%s\n%s' % (mod, name)).encode(), pickled)
                    self.assertIs(type(self.loads(pickled)), type(val))

    #
    # PEP 574 tests below
    #

    def buffer_like_objects(self):
        # Yield buffer-like objects with the bytestring "abcdef" in them
        bytestring = b"abcdefgh"
        yield ZeroCopyBytes(bytestring)
        yield ZeroCopyBytearray(bytestring)
        if _testbuffer is not None:
            items = list(bytestring)
            value = int.from_bytes(bytestring, byteorder='little')
            for flags in (0, _testbuffer.ND_WRITABLE):
                # 1-D, contiguous
                yield PicklableNDArray(items, format='B', shape=(8,),
                                       flags=flags)
                # 2-D, C-contiguous
                yield PicklableNDArray(items, format='B', shape=(4, 2),
                                       strides=(2, 1), flags=flags)
                # 2-D, Fortran-contiguous
                yield PicklableNDArray(items, format='B',
                                       shape=(4, 2), strides=(1, 4),
                                       flags=flags)

    def test_in_band_buffers(self):
        # Test in-band buffers (PEP 574)
        for obj in self.buffer_like_objects():
            for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
                data = self.dumps(obj, proto)
                if obj.c_contiguous and proto >= 5:
                    # The raw memory bytes are serialized in physical order
                    self.assertIn(b"abcdefgh", data)
                self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 0)
                if proto >= 5:
                    self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data),
                                     1 if obj.readonly else 0)
                    self.assertEqual(count_opcode(pickle.BYTEARRAY8, data),
                                     0 if obj.readonly else 1)
                    # Return a true value from buffer_callback should have
                    # the same effect
                    def buffer_callback(obj):
                        return True
                    data2 = self.dumps(obj, proto,
                                       buffer_callback=buffer_callback)
                    self.assertEqual(data2, data)

                new = self.loads(data)
                # It's a copy
                self.assertIsNot(new, obj)
                self.assertIs(type(new), type(obj))
                self.assertEqual(new, obj)

    # XXX Unfortunately cannot test non-contiguous array
    # (see comment in PicklableNDArray.__reduce_ex__)

    def test_oob_buffers(self):
        # Test out-of-band buffers (PEP 574)
        for obj in self.buffer_like_objects():
            for proto in range(0, 5):
                # Need protocol >= 5 for buffer_callback
                with self.assertRaises(ValueError):
                    self.dumps(obj, proto,
                               buffer_callback=[].append)
            for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
                buffers = []
                buffer_callback = lambda pb: buffers.append(pb.raw())
                data = self.dumps(obj, proto,
                                  buffer_callback=buffer_callback)
                self.assertNotIn(b"abcdefgh", data)
                self.assertEqual(count_opcode(pickle.SHORT_BINBYTES, data), 0)
                self.assertEqual(count_opcode(pickle.BYTEARRAY8, data), 0)
                self.assertEqual(count_opcode(pickle.NEXT_BUFFER, data), 1)
                self.assertEqual(count_opcode(pickle.READONLY_BUFFER, data),
                                 1 if obj.readonly else 0)

                if obj.c_contiguous:
                    self.assertEqual(bytes(buffers[0]), b"abcdefgh")
                # Need buffers argument to unpickle properly
                with self.assertRaises(pickle.UnpicklingError):
                    self.loads(data)

                new = self.loads(data, buffers=buffers)
                if obj.zero_copy_reconstruct:
                    # Zero-copy achieved
                    self.assertIs(new, obj)
                else:
                    self.assertIs(type(new), type(obj))
                    self.assertEqual(new, obj)
                # Non-sequence buffers accepted too
                new = self.loads(data, buffers=iter(buffers))
                if obj.zero_copy_reconstruct:
                    # Zero-copy achieved
                    self.assertIs(new, obj)
                else:
                    self.assertIs(type(new), type(obj))
                    self.assertEqual(new, obj)

    def test_oob_buffers_writable_to_readonly(self):
        # Test reconstructing readonly object from writable buffer
        obj = ZeroCopyBytes(b"foobar")
        for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
            buffers = []
            buffer_callback = buffers.append
            data = self.dumps(obj, proto, buffer_callback=buffer_callback)

            buffers = map(bytearray, buffers)
            new = self.loads(data, buffers=buffers)
            self.assertIs(type(new), type(obj))
            self.assertEqual(new, obj)

    def test_buffers_error(self):
        pb = pickle.PickleBuffer(b"foobar")
        for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
            data = self.dumps(pb, proto, buffer_callback=[].append)
            # Non iterable buffers
            with self.assertRaises(TypeError):
                self.loads(data, buffers=object())
            # Buffer iterable exhausts too early
            with self.assertRaises(pickle.UnpicklingError):
                self.loads(data, buffers=[])

    def test_inband_accept_default_buffers_argument(self):
        for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
            data_pickled = self.dumps(1, proto, buffer_callback=None)
            data = self.loads(data_pickled, buffers=None)

    @unittest.skipIf(np is None, "Test needs Numpy")
    def test_buffers_numpy(self):
        def check_no_copy(x, y):
            np.testing.assert_equal(x, y)
            self.assertEqual(x.ctypes.data, y.ctypes.data)

        def check_copy(x, y):
            np.testing.assert_equal(x, y)
            self.assertNotEqual(x.ctypes.data, y.ctypes.data)

        def check_array(arr):
            # In-band
            for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
                data = self.dumps(arr, proto)
                new = self.loads(data)
                check_copy(arr, new)
            for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
                buffer_callback = lambda _: True
                data = self.dumps(arr, proto, buffer_callback=buffer_callback)
                new = self.loads(data)
                check_copy(arr, new)
            # Out-of-band
            for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
                buffers = []
                buffer_callback = buffers.append
                data = self.dumps(arr, proto, buffer_callback=buffer_callback)
                new = self.loads(data, buffers=buffers)
                if arr.flags.c_contiguous or arr.flags.f_contiguous:
                    check_no_copy(arr, new)
                else:
                    check_copy(arr, new)

        # 1-D
        arr = np.arange(6)
        check_array(arr)
        # 1-D, non-contiguous
        check_array(arr[::2])
        # 2-D, C-contiguous
        arr = np.arange(12).reshape((3, 4))
        check_array(arr)
        # 2-D, F-contiguous
        check_array(arr.T)
        # 2-D, non-contiguous
        check_array(arr[::2])

    def test_concurrent_mutation_in_buffer_with_bytearray(self):
        def factory():
            s = b"a" * 16
            return bytearray(s), s
        self.do_test_concurrent_mutation_in_buffer_callback(factory)

    def test_concurrent_mutation_in_buffer_with_memoryview(self):
        def factory():
            obj = memoryview(b"a" * 32)[10:26]
            sub = b"a" * len(obj)
            return obj, sub
        self.do_test_concurrent_mutation_in_buffer_callback(factory)

    def do_test_concurrent_mutation_in_buffer_callback(self, factory):
        # See: https://github.com/python/cpython/issues/143308.
        class R:
            def __bool__(self):
                buf.release()
                return True

        for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
            obj, sub = factory()
            buf = pickle.PickleBuffer(obj)
            buffer_callback = lambda _: R()

            with self.subTest(proto=proto, obj=obj, sub=sub):
                res = self.dumps(buf, proto, buffer_callback=buffer_callback)
                self.assertIn(sub, res)

    def test_evil_class_mutating_dict(self):
        # https://github.com/python/cpython/issues/92930
        from random import getrandbits

        global Bad
        class Bad:
            def __eq__(self, other):
                return ENABLED
            def __hash__(self):
                return 42
            def __reduce__(self):
                if getrandbits(6) == 0:
                    collection.clear()
                return (Bad, ())

        for proto in protocols:
            for _ in range(20):
                ENABLED = False
                collection = {Bad(): Bad() for _ in range(20)}
                for bad in collection:
                    bad.bad = bad
                    bad.collection = collection
                ENABLED = True
                try:
                    data = self.dumps(collection, proto)
                    self.loads(data)
                except RuntimeError as e:
                    expected = "changed size during iteration"
                    self.assertIn(expected, str(e))


class BigmemPickleTests:

    # Binary protocols can serialize longs of up to 2 GiB-1

    @bigmemtest(size=_2G, memuse=3.6, dry_run=False)
    def test_huge_long_32b(self, size):
        data = 1 << (8 * size)
        try:
            for proto in protocols:
                if proto < 2:
                    continue
                with self.subTest(proto=proto):
                    with self.assertRaises((ValueError, OverflowError)):
                        self.dumps(data, protocol=proto)
        finally:
            data = None

    # Protocol 3 can serialize up to 4 GiB-1 as a bytes object
    # (older protocols don't have a dedicated opcode for bytes and are
    # too inefficient)

    @bigmemtest(size=_2G, memuse=2.5, dry_run=False)
    def test_huge_bytes_32b(self, size):
        data = b"abcd" * (size // 4)
        try:
            for proto in protocols:
                if proto < 3:
                    continue
                with self.subTest(proto=proto):
                    try:
                        pickled = self.dumps(data, protocol=proto)
                        header = (pickle.BINBYTES +
                                  struct.pack("<I", len(data)))
                        data_start = pickled.index(data)
                        self.assertEqual(
                            header,
                            pickled[data_start-len(header):data_start])
                    finally:
                        pickled = None
        finally:
            data = None

    @bigmemtest(size=_4G, memuse=2.5, dry_run=False)
    def test_huge_bytes_64b(self, size):
        data = b"acbd" * (size // 4)
        try:
            for proto in protocols:
                if proto < 3:
                    continue
                with self.subTest(proto=proto):
                    if proto == 3:
                        # Protocol 3 does not support large bytes objects.
                        # Verify that we do not crash when processing one.
                        with self.assertRaises((ValueError, OverflowError)):
                            self.dumps(data, protocol=proto)
                        continue
                    try:
                        pickled = self.dumps(data, protocol=proto)
                        header = (pickle.BINBYTES8 +
                                  struct.pack("<Q", len(data)))
                        data_start = pickled.index(data)
                        self.assertEqual(
                            header,
                            pickled[data_start-len(header):data_start])
                    finally:
                        pickled = None
        finally:
            data = None

    # All protocols use 1-byte per printable ASCII character; we add another
    # byte because the encoded form has to be copied into the internal buffer.

    @bigmemtest(size=_2G, memuse=8, dry_run=False)
    def test_huge_str_32b(self, size):
        data = "abcd" * (size // 4)
        try:
            for proto in protocols:
                if proto == 0:
                    continue
                with self.subTest(proto=proto):
                    try:
                        pickled = self.dumps(data, protocol=proto)
                        header = (pickle.BINUNICODE +
                                  struct.pack("<I", len(data)))
                        data_start = pickled.index(b'abcd')
                        self.assertEqual(
                            header,
                            pickled[data_start-len(header):data_start])
                        self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
                                          pickled.index(b"abcd")), len(data))
                    finally:
                        pickled = None
        finally:
            data = None

    # BINUNICODE (protocols 1, 2 and 3) cannot carry more than 2**32 - 1 bytes
    # of utf-8 encoded unicode. BINUNICODE8 (protocol 4) supports these huge
    # unicode strings however.

    @bigmemtest(size=_4G, memuse=8, dry_run=False)
    def test_huge_str_64b(self, size):
        data = "abcd" * (size // 4)
        try:
            for proto in protocols:
                if proto == 0:
                    continue
                with self.subTest(proto=proto):
                    if proto < 4:
                        with self.assertRaises((ValueError, OverflowError)):
                            self.dumps(data, protocol=proto)
                        continue
                    try:
                        pickled = self.dumps(data, protocol=proto)
                        header = (pickle.BINUNICODE8 +
                                  struct.pack("<Q", len(data)))
                        data_start = pickled.index(b'abcd')
                        self.assertEqual(
                            header,
                            pickled[data_start-len(header):data_start])
                        self.assertEqual((pickled.rindex(b"abcd") + len(b"abcd") -
                                          pickled.index(b"abcd")), len(data))
                    finally:
                        pickled = None
        finally:
            data = None


class CustomError(Exception):
    pass

class Unpickleable:
    def __reduce__(self):
        raise CustomError

UNPICKLEABLE = Unpickleable()

# For test_unpickleable_reconstructor and test_unpickleable_state_setter
class UnpickleableCallable(Unpickleable):
    def __call__(self, *args, **kwargs):
        pass

# For test_bad_getattr
class BadGetattr:
    def __getattr__(self, key):
        self.foo

# For test_bad_newobj_class and test_bad_newobj_ex__class
class NoNew:
    def __getattribute__(self, name):
        if name == '__new__':
            raise AttributeError
        return super().__getattribute__(name)


class AbstractPickleModuleTests:

    def test_dump_closed_file(self):
        f = open(TESTFN, "wb")
        try:
            f.close()
            self.assertRaises(ValueError, self.dump, 123, f)
        finally:
            os_helper.unlink(TESTFN)

    def test_load_closed_file(self):
        f = open(TESTFN, "wb")
        try:
            f.close()
            self.assertRaises(ValueError, self.dump, 123, f)
        finally:
            os_helper.unlink(TESTFN)

    def test_load_from_and_dump_to_file(self):
        stream = io.BytesIO()
        data = [123, {}, 124]
        self.dump(data, stream)
        stream.seek(0)
        unpickled = self.load(stream)
        self.assertEqual(unpickled, data)

    def test_highest_protocol(self):
        # Of course this needs to be changed when HIGHEST_PROTOCOL changes.
        self.assertEqual(pickle.HIGHEST_PROTOCOL, 5)

    def test_callapi(self):
        f = io.BytesIO()
        # With and without keyword arguments
        self.dump(123, f, -1)
        self.dump(123, file=f, protocol=-1)
        self.dumps(123, -1)
        self.dumps(123, protocol=-1)
        self.Pickler(f, -1)
        self.Pickler(f, protocol=-1)

    def test_dump_text_file(self):
        f = open(TESTFN, "w")
        try:
            for proto in protocols:
                self.assertRaises(TypeError, self.dump, 123, f, proto)
        finally:
            f.close()
            os_helper.unlink(TESTFN)

    def test_incomplete_input(self):
        s = io.BytesIO(b"X''.")
        self.assertRaises((EOFError, struct.error, pickle.UnpicklingError), self.load, s)

    def test_bad_init(self):
        # Test issue3664 (pickle can segfault from a badly initialized Pickler).
        # Override initialization without calling __init__() of the superclass.
        class BadPickler(self.Pickler):
            def __init__(self): pass

        class BadUnpickler(self.Unpickler):
            def __init__(self): pass

        self.assertRaises(pickle.PicklingError, BadPickler().dump, 0)
        self.assertRaises(pickle.UnpicklingError, BadUnpickler().load)

    def test_unpickler_bad_file(self):
        # bpo-38384: Crash in _pickle if the read attribute raises an error.
        def raises_oserror(self, *args, **kwargs):
            raise OSError
        @property
        def bad_property(self):
            raise CustomError

        # File without read and readline
        class F:
            pass
        self.assertRaises((AttributeError, TypeError), self.Unpickler, F())

        # File without read
        class F:
            readline = raises_oserror
        self.assertRaises((AttributeError, TypeError), self.Unpickler, F())

        # File without readline
        class F:
            read = raises_oserror
        self.assertRaises((AttributeError, TypeError), self.Unpickler, F())

        # File with bad read
        class F:
            read = bad_property
            readline = raises_oserror
        self.assertRaises(CustomError, self.Unpickler, F())

        # File with bad readline
        class F:
            readline = bad_property
            read = raises_oserror
        self.assertRaises(CustomError, self.Unpickler, F())

        # File with bad readline, no read
        class F:
            readline = bad_property
        self.assertRaises(CustomError, self.Unpickler, F())

        # File with bad read, no readline
        class F:
            read = bad_property
        self.assertRaises((AttributeError, CustomError), self.Unpickler, F())

        # File with bad peek
        class F:
            peek = bad_property
            read = raises_oserror
            readline = raises_oserror
        try:
            self.Unpickler(F())
        except CustomError:
            pass

        # File with bad readinto
        class F:
            readinto = bad_property
            read = raises_oserror
            readline = raises_oserror
        try:
            self.Unpickler(F())
        except CustomError:
            pass

    def test_pickler_bad_file(self):
        # File without write
        class F:
            pass
        self.assertRaises(TypeError, self.Pickler, F())

        # File with bad write
        class F:
            @property
            def write(self):
                raise CustomError
        self.assertRaises(CustomError, self.Pickler, F())

    def check_dumps_loads_oob_buffers(self, dumps, loads):
        # No need to do the full gamut of tests here, just enough to
        # check that dumps() and loads() redirect their arguments
        # to the underlying Pickler and Unpickler, respectively.
        obj = ZeroCopyBytes(b"foo")

        for proto in range(0, 5):
            # Need protocol >= 5 for buffer_callback
            with self.assertRaises(ValueError):
                dumps(obj, protocol=proto,
                      buffer_callback=[].append)
        for proto in range(5, pickle.HIGHEST_PROTOCOL + 1):
            buffers = []
            buffer_callback = buffers.append
            data = dumps(obj, protocol=proto,
                         buffer_callback=buffer_callback)
            self.assertNotIn(b"foo", data)
            self.assertEqual(bytes(buffers[0]), b"foo")
            # Need buffers argument to unpickle properly
            with self.assertRaises(pickle.UnpicklingError):
                loads(data)
            new = loads(data, buffers=buffers)
            self.assertIs(new, obj)

    def test_dumps_loads_oob_buffers(self):
        # Test out-of-band buffers (PEP 574) with top-level dumps() and loads()
        self.check_dumps_loads_oob_buffers(self.dumps, self.loads)

    def test_dump_load_oob_buffers(self):
        # Test out-of-band buffers (PEP 574) with top-level dump() and load()
        def dumps(obj, **kwargs):
            f = io.BytesIO()
            self.dump(obj, f, **kwargs)
            return f.getvalue()

        def loads(data, **kwargs):
            f = io.BytesIO(data)
            return self.load(f, **kwargs)

        self.check_dumps_loads_oob_buffers(dumps, loads)


class AbstractPersistentPicklerTests:

    # This class defines persistent_id() and persistent_load()
    # functions that should be used by the pickler.  All even integers
    # are pickled using persistent ids.

    def persistent_id(self, object):
        if isinstance(object, int) and object % 2 == 0:
            self.id_count += 1
            return str(object)
        elif object == "test_false_value":
            self.false_count += 1
            return ""
        else:
            return None

    def persistent_load(self, oid):
        if not oid:
            self.load_false_count += 1
            return "test_false_value"
        else:
            self.load_count += 1
            object = int(oid)
            assert object % 2 == 0
            return object

    def test_persistence(self):
        L = list(range(10)) + ["test_false_value"]
        for proto in protocols:
            self.id_count = 0
            self.false_count = 0
            self.load_false_count = 0
            self.load_count = 0
            self.assertEqual(self.loads(self.dumps(L, proto)), L)
            self.assertEqual(self.id_count, 5)
            self.assertEqual(self.false_count, 1)
            self.assertEqual(self.load_count, 5)
            self.assertEqual(self.load_false_count, 1)


class AbstractIdentityPersistentPicklerTests:

    def persistent_id(self, obj):
        return obj

    def persistent_load(self, pid):
        return pid

    def _check_return_correct_type(self, obj, proto):
        unpickled = self.loads(self.dumps(obj, proto))
        self.assertIsInstance(unpickled, type(obj))
        self.assertEqual(unpickled, obj)

    def test_return_correct_type(self):
        for proto in protocols:
            # Protocol 0 supports only ASCII strings.
            if proto == 0:
                self._check_return_correct_type("abc", 0)
            else:
                for obj in [b"abc\n", "abc\n", -1, -1.1 * 0.1, str]:
                    self._check_return_correct_type(obj, proto)

    def test_protocol0_is_ascii_only(self):
        non_ascii_str = "\N{EMPTY SET}"
        with self.assertRaises(pickle.PicklingError) as cm:
            self.dumps(non_ascii_str, 0)
        self.assertEqual(str(cm.exception),
                         'persistent IDs in protocol 0 must be ASCII strings')
        pickled = pickle.PERSID + non_ascii_str.encode('utf-8') + b'\n.'
        with self.assertRaises(pickle.UnpicklingError) as cm:
            self.loads(pickled)
        self.assertEqual(str(cm.exception),
                         'persistent IDs in protocol 0 must be ASCII strings')


class AbstractPicklerUnpicklerObjectTests:

    pickler_class = None
    unpickler_class = None

    def setUp(self):
        assert self.pickler_class
        assert self.unpickler_class

    def test_clear_pickler_memo(self):
        # To test whether clear_memo() has any effect, we pickle an object,
        # then pickle it again without clearing the memo; the two serialized
        # forms should be different. If we clear_memo() and then pickle the
        # object again, the third serialized form should be identical to the
        # first one we obtained.
        data = ["abcdefg", "abcdefg", 44]
        for proto in protocols:
            f = io.BytesIO()
            pickler = self.pickler_class(f, proto)

            pickler.dump(data)
            first_pickled = f.getvalue()

            # Reset BytesIO object.
            f.seek(0)
            f.truncate()

            pickler.dump(data)
            second_pickled = f.getvalue()

            # Reset the Pickler and BytesIO objects.
            pickler.clear_memo()
            f.seek(0)
            f.truncate()

            pickler.dump(data)
            third_pickled = f.getvalue()

            self.assertNotEqual(first_pickled, second_pickled)
            self.assertEqual(first_pickled, third_pickled)

    def test_priming_pickler_memo(self):
        # Verify that we can set the Pickler's memo attribute.
        data = ["abcdefg", "abcdefg", 44]
        f = io.BytesIO()
        pickler = self.pickler_class(f)

        pickler.dump(data)
        first_pickled = f.getvalue()

        f = io.BytesIO()
        primed = self.pickler_class(f)
        primed.memo = pickler.memo

        primed.dump(data)
        primed_pickled = f.getvalue()

        self.assertNotEqual(first_pickled, primed_pickled)

    def test_priming_unpickler_memo(self):
        # Verify that we can set the Unpickler's memo attribute.
        data = ["abcdefg", "abcdefg", 44]
        f = io.BytesIO()
        pickler = self.pickler_class(f)

        pickler.dump(data)
        first_pickled = f.getvalue()

        f = io.BytesIO()
        primed = self.pickler_class(f)
        primed.memo = pickler.memo

        primed.dump(data)
        primed_pickled = f.getvalue()

        unpickler = self.unpickler_class(io.BytesIO(first_pickled))
        unpickled_data1 = unpickler.load()

        self.assertEqual(unpickled_data1, data)

        primed = self.unpickler_class(io.BytesIO(primed_pickled))
        primed.memo = unpickler.memo
        unpickled_data2 = primed.load()

        primed.memo.clear()

        self.assertEqual(unpickled_data2, data)
        self.assertTrue(unpickled_data2 is unpickled_data1)

    def test_reusing_unpickler_objects(self):
        data1 = ["abcdefg", "abcdefg", 44]
        f = io.BytesIO()
        pickler = self.pickler_class(f)
        pickler.dump(data1)
        pickled1 = f.getvalue()

        data2 = ["abcdefg", 44, 44]
        f = io.BytesIO()
        pickler = self.pickler_class(f)
        pickler.dump(data2)
        pickled2 = f.getvalue()

        f = io.BytesIO()
        f.write(pickled1)
        f.seek(0)
        unpickler = self.unpickler_class(f)
        self.assertEqual(unpickler.load(), data1)

        f.seek(0)
        f.truncate()
        f.write(pickled2)
        f.seek(0)
        self.assertEqual(unpickler.load(), data2)

    def _check_multiple_unpicklings(self, ioclass, *, seekable=True):
        for proto in protocols:
            with self.subTest(proto=proto):
                data1 = [(x, str(x)) for x in range(2000)] + [b"abcde", len]
                f = ioclass()
                pickler = self.pickler_class(f, protocol=proto)
                pickler.dump(data1)
                pickled = f.getvalue()

                N = 5
                f = ioclass(pickled * N)
                unpickler = self.unpickler_class(f)
                for i in range(N):
                    if seekable:
                        pos = f.tell()
                    self.assertEqual(unpickler.load(), data1)
                    if seekable:
                        self.assertEqual(f.tell(), pos + len(pickled))
                self.assertRaises(EOFError, unpickler.load)

    def test_multiple_unpicklings_seekable(self):
        self._check_multiple_unpicklings(io.BytesIO)

    def test_multiple_unpicklings_unseekable(self):
        self._check_multiple_unpicklings(UnseekableIO, seekable=False)

    def test_multiple_unpicklings_minimal(self):
        # File-like object that doesn't support peek() and readinto()
        # (bpo-39681)
        self._check_multiple_unpicklings(MinimalIO, seekable=False)

    def test_unpickling_buffering_readline(self):
        # Issue #12687: the unpickler's buffering logic could fail with
        # text mode opcodes.
        data = list(range(10))
        for proto in protocols:
            for buf_size in range(1, 11):
                f = io.BufferedRandom(io.BytesIO(), buffer_size=buf_size)
                pickler = self.pickler_class(f, protocol=proto)
                pickler.dump(data)
                f.seek(0)
                unpickler = self.unpickler_class(f)
                self.assertEqual(unpickler.load(), data)

    def test_pickle_invalid_reducer_override(self):
        # gh-103035
        obj = object()

        f = io.BytesIO()
        class MyPickler(self.pickler_class):
            pass
        pickler = MyPickler(f)
        pickler.dump(obj)

        pickler.clear_memo()
        pickler.reducer_override = None
        with self.assertRaises(TypeError):
            pickler.dump(obj)

        pickler.clear_memo()
        pickler.reducer_override = 10
        with self.assertRaises(TypeError):
            pickler.dump(obj)

# Tests for dispatch_table attribute

REDUCE_A = 'reduce_A'

class AAA(object):
    def __reduce__(self):
        return str, (REDUCE_A,)

class BBB(object):
    def __init__(self):
        # Add an instance attribute to enable state-saving routines at pickling
        # time.
        self.a = "some attribute"

    def __setstate__(self, state):
        self.a = "BBB.__setstate__"


def setstate_bbb(obj, state):
    """Custom state setter for BBB objects

    Such callable may be created by other persons than the ones who created the
    BBB class. If passed as the state_setter item of a custom reducer, this
    allows for custom state setting behavior of BBB objects. One can think of
    it as the analogous of list_setitems or dict_setitems but for foreign
    classes/functions.
    """
    obj.a = "custom state_setter"



class AbstractCustomPicklerClass:
    """Pickler implementing a reducing hook using reducer_override."""
    def reducer_override(self, obj):
        obj_name = getattr(obj, "__name__", None)

        if obj_name == 'f':
            # asking the pickler to save f as 5
            return int, (5, )

        if obj_name == 'MyClass':
            return str, ('some str',)

        elif obj_name == 'g':
            # in this case, the callback returns an invalid result (not a 2-5
            # tuple or a string), the pickler should raise a proper error.
            return False

        elif obj_name == 'h':
            # Simulate a case when the reducer fails. The error should
            # be propagated to the original ``dump`` call.
            raise ValueError('The reducer just failed')

        return NotImplemented

class AbstractHookTests:
    def test_pickler_hook(self):
        # test the ability of a custom, user-defined CPickler subclass to
        # override the default reducing routines of any type using the method
        # reducer_override

        def f():
            pass

        def g():
            pass

        def h():
            pass

        class MyClass:
            pass

        for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
            with self.subTest(proto=proto):
                bio = io.BytesIO()
                p = self.pickler_class(bio, proto)

                p.dump([f, MyClass, math.log])
                new_f, some_str, math_log = pickle.loads(bio.getvalue())

                self.assertEqual(new_f, 5)
                self.assertEqual(some_str, 'some str')
                # math.log does not have its usual reducer overridden, so the
                # custom reduction callback should silently direct the pickler
                # to the default pickling by attribute, by returning
                # NotImplemented
                self.assertIs(math_log, math.log)

                with self.assertRaises(pickle.PicklingError) as cm:
                    p.dump(g)
                self.assertRegex(str(cm.exception),
                    r'(__reduce__|<bound method .*reducer_override.*>)'
                    r' must return (a )?string or tuple')

                with self.assertRaisesRegex(
                        ValueError, 'The reducer just failed'):
                    p.dump(h)

    @support.cpython_only
    def test_reducer_override_no_reference_cycle(self):
        # bpo-39492: reducer_override used to induce a spurious reference cycle
        # inside the Pickler object, that could prevent all serialized objects
        # from being garbage-collected without explicitly invoking gc.collect.

        for proto in range(0, pickle.HIGHEST_PROTOCOL + 1):
            with self.subTest(proto=proto):
                def f():
                    pass

                wr = weakref.ref(f)

                bio = io.BytesIO()
                p = self.pickler_class(bio, proto)
                p.dump(f)
                new_f = pickle.loads(bio.getvalue())
                assert new_f == 5

                del p
                del f

                self.assertIsNone(wr())


class AbstractDispatchTableTests:

    def test_default_dispatch_table(self):
        # No dispatch_table attribute by default
        f = io.BytesIO()
        p = self.pickler_class(f, 0)
        with self.assertRaises(AttributeError):
            p.dispatch_table
        self.assertNotHasAttr(p, 'dispatch_table')

    def test_class_dispatch_table(self):
        # A dispatch_table attribute can be specified class-wide
        dt = self.get_dispatch_table()

        class MyPickler(self.pickler_class):
            dispatch_table = dt

        def dumps(obj, protocol=None):
            f = io.BytesIO()
            p = MyPickler(f, protocol)
            self.assertEqual(p.dispatch_table, dt)
            p.dump(obj)
            return f.getvalue()

        self._test_dispatch_table(dumps, dt)

    def test_instance_dispatch_table(self):
        # A dispatch_table attribute can also be specified instance-wide
        dt = self.get_dispatch_table()

        def dumps(obj, protocol=None):
            f = io.BytesIO()
            p = self.pickler_class(f, protocol)
            p.dispatch_table = dt
            self.assertEqual(p.dispatch_table, dt)
            p.dump(obj)
            return f.getvalue()

        self._test_dispatch_table(dumps, dt)

    def test_dispatch_table_None_item(self):
        # gh-93627
        obj = object()
        f = io.BytesIO()
        pickler = self.pickler_class(f)
        pickler.dispatch_table = {type(obj): None}
        with self.assertRaises(TypeError):
            pickler.dump(obj)

    def _test_dispatch_table(self, dumps, dispatch_table):
        def custom_load_dump(obj):
            return pickle.loads(dumps(obj, 0))

        def default_load_dump(obj):
            return pickle.loads(pickle.dumps(obj, 0))

        # pickling complex numbers using protocol 0 relies on copyreg
        # so check pickling a complex number still works
        z = 1 + 2j
        self.assertEqual(custom_load_dump(z), z)
        self.assertEqual(default_load_dump(z), z)

        # modify pickling of complex
        REDUCE_1 = 'reduce_1'
        def reduce_1(obj):
            return str, (REDUCE_1,)
        dispatch_table[complex] = reduce_1
        self.assertEqual(custom_load_dump(z), REDUCE_1)
        self.assertEqual(default_load_dump(z), z)

        # check picklability of AAA and BBB
        a = AAA()
        b = BBB()
        self.assertEqual(custom_load_dump(a), REDUCE_A)
        self.assertIsInstance(custom_load_dump(b), BBB)
        self.assertEqual(default_load_dump(a), REDUCE_A)
        self.assertIsInstance(default_load_dump(b), BBB)

        # modify pickling of BBB
        dispatch_table[BBB] = reduce_1
        self.assertEqual(custom_load_dump(a), REDUCE_A)
        self.assertEqual(custom_load_dump(b), REDUCE_1)
        self.assertEqual(default_load_dump(a), REDUCE_A)
        self.assertIsInstance(default_load_dump(b), BBB)

        # revert pickling of BBB and modify pickling of AAA
        REDUCE_2 = 'reduce_2'
        def reduce_2(obj):
            return str, (REDUCE_2,)
        dispatch_table[AAA] = reduce_2
        del dispatch_table[BBB]
        self.assertEqual(custom_load_dump(a), REDUCE_2)
        self.assertIsInstance(custom_load_dump(b), BBB)
        self.assertEqual(default_load_dump(a), REDUCE_A)
        self.assertIsInstance(default_load_dump(b), BBB)

        # End-to-end testing of save_reduce with the state_setter keyword
        # argument. This is a dispatch_table test as the primary goal of
        # state_setter is to tweak objects reduction behavior.
        # In particular, state_setter is useful when the default __setstate__
        # behavior is not flexible enough.

        # No custom reducer for b has been registered for now, so
        # BBB.__setstate__ should be used at unpickling time
        self.assertEqual(default_load_dump(b).a, "BBB.__setstate__")

        def reduce_bbb(obj):
            return BBB, (), obj.__dict__, None, None, setstate_bbb

        dispatch_table[BBB] = reduce_bbb

        # The custom reducer reduce_bbb includes a state setter, that should
        # have priority over BBB.__setstate__
        self.assertEqual(custom_load_dump(b).a, "custom state_setter")


if __name__ == "__main__":
    # Print some stuff that can be used to rewrite DATA{0,1,2}
    from pickletools import dis
    x = create_data()
    for i in range(pickle.HIGHEST_PROTOCOL+1):
        p = pickle.dumps(x, i)
        print("DATA{0} = (".format(i))
        for j in range(0, len(p), 20):
            b = bytes(p[j:j+20])
            print("    {0!r}".format(b))
        print(")")
        print()
        print("# Disassembly of DATA{0}".format(i))
        print("DATA{0}_DIS = \"\"\"\\".format(i))
        dis(p)
        print("\"\"\"")
        print()
