import contextlib
import itertools
import sys
import types
import unittest
import warnings

from test.support import import_helper

_testinternalcapi = import_helper.import_module('_testinternalcapi')
_interpreters = import_helper.import_module('_interpreters')
from _interpreters import NotShareableError

from test import _code_definitions as code_defs
from test import _crossinterp_definitions as defs


@contextlib.contextmanager
def ignore_byteswarning():
    with warnings.catch_warnings():
        warnings.filterwarnings('ignore', category=BytesWarning)
        yield


# builtin types

BUILTINS_TYPES = [o for _, o in __builtins__.items() if isinstance(o, type)]
EXCEPTION_TYPES = [cls for cls in BUILTINS_TYPES
                   if issubclass(cls, BaseException)]
OTHER_TYPES = [o for n, o in vars(types).items()
               if (isinstance(o, type) and
                   n not in ('DynamicClassAttribute', '_GeneratorWrapper'))]
BUILTIN_TYPES = [
    *BUILTINS_TYPES,
    *OTHER_TYPES,
]

# builtin exceptions

try:
    raise Exception
except Exception as exc:
    CAUGHT = exc
EXCEPTIONS_WITH_SPECIAL_SIG = {
    BaseExceptionGroup: (lambda msg: (msg, [CAUGHT])),
    ExceptionGroup: (lambda msg: (msg, [CAUGHT])),
    UnicodeError: (lambda msg: (None, msg, None, None, None)),
    UnicodeEncodeError: (lambda msg: ('utf-8', '', 1, 3, msg)),
    UnicodeDecodeError: (lambda msg: ('utf-8', b'', 1, 3, msg)),
    UnicodeTranslateError: (lambda msg: ('', 1, 3, msg)),
}
BUILTIN_EXCEPTIONS = [
    *(cls(*sig('error!')) for cls, sig in EXCEPTIONS_WITH_SPECIAL_SIG.items()),
    *(cls('error!') for cls in EXCEPTION_TYPES
      if cls not in EXCEPTIONS_WITH_SPECIAL_SIG),
]

# other builtin objects

METHOD = defs.SpamOkay().okay
BUILTIN_METHOD = [].append
METHOD_DESCRIPTOR_WRAPPER = str.join
METHOD_WRAPPER = object().__str__
WRAPPER_DESCRIPTOR = object.__init__
BUILTIN_WRAPPERS = {
    METHOD: types.MethodType,
    BUILTIN_METHOD: types.BuiltinMethodType,
    dict.__dict__['fromkeys']: types.ClassMethodDescriptorType,
    types.FunctionType.__code__: types.GetSetDescriptorType,
    types.FunctionType.__globals__: types.MemberDescriptorType,
    METHOD_DESCRIPTOR_WRAPPER: types.MethodDescriptorType,
    METHOD_WRAPPER: types.MethodWrapperType,
    WRAPPER_DESCRIPTOR: types.WrapperDescriptorType,
    staticmethod(defs.SpamOkay.okay): None,
    classmethod(defs.SpamOkay.okay): None,
    property(defs.SpamOkay.okay): None,
}
BUILTIN_FUNCTIONS = [
    # types.BuiltinFunctionType
    len,
    sys.is_finalizing,
    sys.exit,
    _testinternalcapi.get_crossinterp_data,
]
assert 'emptymod' not in sys.modules
with import_helper.ready_to_import('emptymod', ''):
    import emptymod as EMPTYMOD
MODULES = [
    sys,
    defs,
    unittest,
    EMPTYMOD,
]
OBJECT = object()
EXCEPTION = Exception()
LAMBDA = (lambda: None)
BUILTIN_SIMPLE = [
    OBJECT,
    # singletons
    None,
    True,
    False,
    Ellipsis,
    NotImplemented,
    # bytes
    *(i.to_bytes(2, 'little', signed=True)
      for i in range(-1, 258)),
    # str
    'hello world',
    '你好世界',
    '',
    # int
    sys.maxsize + 1,
    sys.maxsize,
    -sys.maxsize - 1,
    -sys.maxsize - 2,
    *range(-1, 258),
    2**1000,
    # float
    0.0,
    1.1,
    -1.0,
    0.12345678,
    -0.12345678,
]
TUPLE_EXCEPTION = (0, 1.0, EXCEPTION)
TUPLE_OBJECT = (0, 1.0, OBJECT)
TUPLE_NESTED_EXCEPTION = (0, 1.0, (EXCEPTION,))
TUPLE_NESTED_OBJECT = (0, 1.0, (OBJECT,))
MEMORYVIEW_EMPTY = memoryview(b'')
MEMORYVIEW_NOT_EMPTY = memoryview(b'spam'*42)
MAPPING_PROXY_EMPTY = types.MappingProxyType({})
BUILTIN_CONTAINERS = [
    # tuple (flat)
    (),
    (1,),
    ("hello", "world", ),
    (1, True, "hello"),
    TUPLE_EXCEPTION,
    TUPLE_OBJECT,
    # tuple (nested)
    ((1,),),
    ((1, 2), (3, 4)),
    ((1, 2), (3, 4), (5, 6)),
    TUPLE_NESTED_EXCEPTION,
    TUPLE_NESTED_OBJECT,
    # buffer
    MEMORYVIEW_EMPTY,
    MEMORYVIEW_NOT_EMPTY,
    # list
    [],
    [1, 2, 3],
    [[1], (2,), {3: 4}],
    # dict
    {},
    {1: 7, 2: 8, 3: 9},
    {1: [1], 2: (2,), 3: {3: 4}},
    # set
    set(),
    {1, 2, 3},
    {frozenset({1}), (2,)},
    # frozenset
    frozenset([]),
    frozenset({frozenset({1}), (2,)}),
    # bytearray
    bytearray(b''),
    # other
    MAPPING_PROXY_EMPTY,
    types.SimpleNamespace(),
]
ns = {}
exec("""
try:
    raise Exception
except Exception as exc:
    TRACEBACK = exc.__traceback__
    FRAME = TRACEBACK.tb_frame
""", ns, ns)
BUILTIN_OTHER = [
    # types.CellType
    types.CellType(),
    # types.FrameType
    ns['FRAME'],
    # types.TracebackType
    ns['TRACEBACK'],
]
del ns

# user-defined objects

USER_TOP_INSTANCES = [c(*a) for c, a in defs.TOP_CLASSES.items()]
USER_NESTED_INSTANCES = [c(*a) for c, a in defs.NESTED_CLASSES.items()]
USER_INSTANCES = [
    *USER_TOP_INSTANCES,
    *USER_NESTED_INSTANCES,
]
USER_EXCEPTIONS = [
    defs.MimimalError('error!'),
]

# shareable objects

TUPLES_WITHOUT_EQUALITY = [
    TUPLE_EXCEPTION,
    TUPLE_OBJECT,
    TUPLE_NESTED_EXCEPTION,
    TUPLE_NESTED_OBJECT,
]
_UNSHAREABLE_SIMPLE = [
    Ellipsis,
    NotImplemented,
    OBJECT,
    sys.maxsize + 1,
    -sys.maxsize - 2,
    2**1000,
]
with ignore_byteswarning():
    _SHAREABLE_SIMPLE = [o for o in BUILTIN_SIMPLE
                         if o not in _UNSHAREABLE_SIMPLE]
    _SHAREABLE_CONTAINERS = [
        *(o for o in BUILTIN_CONTAINERS if type(o) is memoryview),
        *(o for o in BUILTIN_CONTAINERS
          if type(o) is tuple and o not in TUPLES_WITHOUT_EQUALITY),
    ]
    _UNSHAREABLE_CONTAINERS = [o for o in BUILTIN_CONTAINERS
                               if o not in _SHAREABLE_CONTAINERS]
SHAREABLE = [
    *_SHAREABLE_SIMPLE,
    *_SHAREABLE_CONTAINERS,
]
NOT_SHAREABLE = [
    *_UNSHAREABLE_SIMPLE,
    *_UNSHAREABLE_CONTAINERS,
    *BUILTIN_TYPES,
    *BUILTIN_WRAPPERS,
    *BUILTIN_EXCEPTIONS,
    *BUILTIN_FUNCTIONS,
    *MODULES,
    *BUILTIN_OTHER,
    # types.CodeType
    *(f.__code__ for f in defs.FUNCTIONS),
    *(f.__code__ for f in defs.FUNCTION_LIKE),
    # types.FunctionType
    *defs.FUNCTIONS,
    defs.SpamOkay.okay,
    LAMBDA,
    *defs.FUNCTION_LIKE,
    # coroutines and generators
    *defs.FUNCTION_LIKE_APPLIED,
    # user classes
    *defs.CLASSES,
    *USER_INSTANCES,
    # user exceptions
    *USER_EXCEPTIONS,
]

# pickleable objects

PICKLEABLE = [
    *BUILTIN_SIMPLE,
    *(o for o in BUILTIN_CONTAINERS if o not in [
        MEMORYVIEW_EMPTY,
        MEMORYVIEW_NOT_EMPTY,
        MAPPING_PROXY_EMPTY,
    ] or type(o) is dict),
    *BUILTINS_TYPES,
    *BUILTIN_EXCEPTIONS,
    *BUILTIN_FUNCTIONS,
    *defs.TOP_FUNCTIONS,
    defs.SpamOkay.okay,
    *defs.FUNCTION_LIKE,
    *defs.TOP_CLASSES,
    *USER_TOP_INSTANCES,
    *USER_EXCEPTIONS,
    # from OTHER_TYPES
    types.NoneType,
    types.EllipsisType,
    types.NotImplementedType,
    types.GenericAlias,
    types.UnionType,
    types.SimpleNamespace,
    # from BUILTIN_WRAPPERS
    METHOD,
    BUILTIN_METHOD,
    METHOD_DESCRIPTOR_WRAPPER,
    METHOD_WRAPPER,
    WRAPPER_DESCRIPTOR,
]
assert not any(isinstance(o, types.MappingProxyType) for o in PICKLEABLE)


# helpers

DEFS = defs
with open(code_defs.__file__) as infile:
    _code_defs_text = infile.read()
with open(DEFS.__file__) as infile:
    _defs_text = infile.read()
    _defs_text = _defs_text.replace('from ', '# from ')
DEFS_TEXT = f"""
#######################################
# from {code_defs.__file__}

{_code_defs_text}

#######################################
# from {defs.__file__}

{_defs_text}
"""
del infile, _code_defs_text, _defs_text


def load_defs(module=None):
    """Return a new copy of the test._crossinterp_definitions module.

    The module's __name__ matches the "module" arg, which is either
    a str or a module.

    If the "module" arg is a module then the just-loaded defs are also
    copied into that module.

    Note that the new module is not added to sys.modules.
    """
    if module is None:
        modname = DEFS.__name__
    elif isinstance(module, str):
        modname = module
        module = None
    else:
        modname = module.__name__
    # Create the new module and populate it.
    defs = import_helper.create_module(modname)
    defs.__file__ = DEFS.__file__
    exec(DEFS_TEXT, defs.__dict__)
    # Copy the defs into the module arg, if any.
    if module is not None:
        for name, value in defs.__dict__.items():
            if name.startswith('_'):
                continue
            assert not hasattr(module, name), (name, getattr(module, name))
            setattr(module, name, value)
    return defs


@contextlib.contextmanager
def using___main__():
    """Make sure __main__ module exists (and clean up after)."""
    modname = '__main__'
    if modname not in sys.modules:
        with import_helper.isolated_modules():
            yield import_helper.add_module(modname)
    else:
        with import_helper.module_restored(modname) as mod:
            yield mod


@contextlib.contextmanager
def temp_module(modname):
    """Create the module and add to sys.modules, then remove it after."""
    assert modname not in sys.modules, (modname,)
    with import_helper.isolated_modules():
        yield import_helper.add_module(modname)


@contextlib.contextmanager
def missing_defs_module(modname, *, prep=False):
    assert modname not in sys.modules, (modname,)
    if prep:
        with import_helper.ready_to_import(modname, DEFS_TEXT):
            yield modname
    else:
        with import_helper.isolated_modules():
            yield modname


class _GetXIDataTests(unittest.TestCase):

    MODE = None

    def assert_functions_equal(self, func1, func2):
        assert type(func1) is types.FunctionType, repr(func1)
        assert type(func2) is types.FunctionType, repr(func2)
        self.assertEqual(func1.__name__, func2.__name__)
        self.assertEqual(func1.__code__, func2.__code__)
        self.assertEqual(func1.__defaults__, func2.__defaults__)
        self.assertEqual(func1.__kwdefaults__, func2.__kwdefaults__)
        # We don't worry about __globals__ for now.

    def assert_exc_args_equal(self, exc1, exc2):
        args1 = exc1.args
        args2 = exc2.args
        if isinstance(exc1, ExceptionGroup):
            self.assertIs(type(args1), type(args2))
            self.assertEqual(len(args1), 2)
            self.assertEqual(len(args1), len(args2))
            self.assertEqual(args1[0], args2[0])
            group1 = args1[1]
            group2 = args2[1]
            self.assertEqual(len(group1), len(group2))
            for grouped1, grouped2 in zip(group1, group2):
                # Currently the "extra" attrs are not preserved
                # (via __reduce__).
                self.assertIs(type(exc1), type(exc2))
                self.assert_exc_equal(grouped1, grouped2)
        else:
            self.assertEqual(args1, args2)

    def assert_exc_equal(self, exc1, exc2):
        self.assertIs(type(exc1), type(exc2))

        if type(exc1).__eq__ is not object.__eq__:
            self.assertEqual(exc1, exc2)

        self.assert_exc_args_equal(exc1, exc2)
        # XXX For now we do not preserve tracebacks.
        if exc1.__traceback__ is not None:
            self.assertEqual(exc1.__traceback__, exc2.__traceback__)
        self.assertEqual(
            getattr(exc1, '__notes__', None),
            getattr(exc2, '__notes__', None),
        )
        # We assume there are no cycles.
        if exc1.__cause__ is None:
            self.assertIs(exc1.__cause__, exc2.__cause__)
        else:
            self.assert_exc_equal(exc1.__cause__, exc2.__cause__)
        if exc1.__context__ is None:
            self.assertIs(exc1.__context__, exc2.__context__)
        else:
            self.assert_exc_equal(exc1.__context__, exc2.__context__)

    def assert_equal_or_equalish(self, obj, expected):
        cls = type(expected)
        if cls.__eq__ is not object.__eq__:
            self.assertEqual(obj, expected)
        elif cls is types.FunctionType:
            self.assert_functions_equal(obj, expected)
        elif isinstance(expected, BaseException):
            self.assert_exc_equal(obj, expected)
        elif cls is types.MethodType:
            raise NotImplementedError(cls)
        elif cls is types.BuiltinMethodType:
            raise NotImplementedError(cls)
        elif cls is types.MethodWrapperType:
            raise NotImplementedError(cls)
        elif cls.__bases__ == (object,):
            self.assertEqual(obj.__dict__, expected.__dict__)
        else:
            raise NotImplementedError(cls)

    def get_xidata(self, obj, *, mode=None):
        mode = self._resolve_mode(mode)
        return _testinternalcapi.get_crossinterp_data(obj, mode)

    def get_roundtrip(self, obj, *, mode=None):
        mode = self._resolve_mode(mode)
        return self._get_roundtrip(obj, mode)

    def _get_roundtrip(self, obj, mode):
        xid = _testinternalcapi.get_crossinterp_data(obj, mode)
        return _testinternalcapi.restore_crossinterp_data(xid)

    def assert_roundtrip_identical(self, values, *, mode=None):
        mode = self._resolve_mode(mode)
        for obj in values:
            with self.subTest(repr(obj)):
                got = self._get_roundtrip(obj, mode)
                self.assertIs(got, obj)

    def assert_roundtrip_equal(self, values, *, mode=None, expecttype=None):
        mode = self._resolve_mode(mode)
        for obj in values:
            with self.subTest(repr(obj)):
                got = self._get_roundtrip(obj, mode)
                if got is obj:
                    continue
                self.assertIs(type(got),
                              type(obj) if expecttype is None else expecttype)
                self.assert_equal_or_equalish(got, obj)

    def assert_roundtrip_equal_not_identical(self, values, *,
                                             mode=None, expecttype=None):
        mode = self._resolve_mode(mode)
        for obj in values:
            with self.subTest(repr(obj)):
                got = self._get_roundtrip(obj, mode)
                self.assertIsNot(got, obj)
                self.assertIs(type(got),
                              type(obj) if expecttype is None else expecttype)
                self.assert_equal_or_equalish(got, obj)

    def assert_roundtrip_not_equal(self, values, *,
                                   mode=None, expecttype=None):
        mode = self._resolve_mode(mode)
        for obj in values:
            with self.subTest(repr(obj)):
                got = self._get_roundtrip(obj, mode)
                self.assertIsNot(got, obj)
                self.assertIs(type(got),
                              type(obj) if expecttype is None else expecttype)
                self.assertNotEqual(got, obj)

    def assert_not_shareable(self, values, exctype=None, *, mode=None):
        mode = self._resolve_mode(mode)
        for obj in values:
            with self.subTest(repr(obj)):
                with self.assertRaises(NotShareableError) as cm:
                    _testinternalcapi.get_crossinterp_data(obj, mode)
                if exctype is not None:
                    self.assertIsInstance(cm.exception.__cause__, exctype)

    def _resolve_mode(self, mode):
        if mode is None:
            mode = self.MODE
        assert mode
        return mode


class PickleTests(_GetXIDataTests):

    MODE = 'pickle'

    def test_shareable(self):
        with ignore_byteswarning():
            for obj in SHAREABLE:
                if obj in PICKLEABLE:
                    self.assert_roundtrip_equal([obj])
                else:
                    self.assert_not_shareable([obj])

    def test_not_shareable(self):
        with ignore_byteswarning():
            for obj in NOT_SHAREABLE:
                if type(obj) is types.MappingProxyType:
                    self.assert_not_shareable([obj])
                elif obj in PICKLEABLE:
                    with self.subTest(repr(obj)):
                        # We don't worry about checking the actual value.
                        # The other tests should cover that well enough.
                        got = self.get_roundtrip(obj)
                        self.assertIs(type(got), type(obj))
                else:
                    self.assert_not_shareable([obj])

    def test_list(self):
        self.assert_roundtrip_equal_not_identical([
            [],
            [1, 2, 3],
            [[1], (2,), {3: 4}],
        ])

    def test_dict(self):
        self.assert_roundtrip_equal_not_identical([
            {},
            {1: 7, 2: 8, 3: 9},
            {1: [1], 2: (2,), 3: {3: 4}},
        ])

    def test_set(self):
        self.assert_roundtrip_equal_not_identical([
            set(),
            {1, 2, 3},
            {frozenset({1}), (2,)},
        ])

    # classes

    def assert_class_defs_same(self, defs):
        # Unpickle relative to the unchanged original module.
        self.assert_roundtrip_identical(defs.TOP_CLASSES)

        instances = []
        for cls, args in defs.TOP_CLASSES.items():
            if cls in defs.CLASSES_WITHOUT_EQUALITY:
                continue
            instances.append(cls(*args))
        self.assert_roundtrip_equal_not_identical(instances)

        # these don't compare equal
        instances = []
        for cls, args in defs.TOP_CLASSES.items():
            if cls not in defs.CLASSES_WITHOUT_EQUALITY:
                continue
            instances.append(cls(*args))
        self.assert_roundtrip_equal(instances)

    def assert_class_defs_other_pickle(self, defs, mod):
        # Pickle relative to a different module than the original.
        for cls in defs.TOP_CLASSES:
            assert not hasattr(mod, cls.__name__), (cls, getattr(mod, cls.__name__))
        self.assert_not_shareable(defs.TOP_CLASSES)

        instances = []
        for cls, args in defs.TOP_CLASSES.items():
            instances.append(cls(*args))
        self.assert_not_shareable(instances)

    def assert_class_defs_other_unpickle(self, defs, mod, *, fail=False):
        # Unpickle relative to a different module than the original.
        for cls in defs.TOP_CLASSES:
            assert not hasattr(mod, cls.__name__), (cls, getattr(mod, cls.__name__))

        instances = []
        for cls, args in defs.TOP_CLASSES.items():
            with self.subTest(repr(cls)):
                setattr(mod, cls.__name__, cls)
                xid = self.get_xidata(cls)
                inst = cls(*args)
                instxid = self.get_xidata(inst)
                instances.append(
                        (cls, xid, inst, instxid))

        for cls, xid, inst, instxid in instances:
            with self.subTest(repr(cls)):
                delattr(mod, cls.__name__)
                if fail:
                    with self.assertRaises(NotShareableError):
                        _testinternalcapi.restore_crossinterp_data(xid)
                    continue
                got = _testinternalcapi.restore_crossinterp_data(xid)
                self.assertIsNot(got, cls)
                self.assertNotEqual(got, cls)

                gotcls = got
                got = _testinternalcapi.restore_crossinterp_data(instxid)
                self.assertIsNot(got, inst)
                self.assertIs(type(got), gotcls)
                if cls in defs.CLASSES_WITHOUT_EQUALITY:
                    self.assertNotEqual(got, inst)
                elif cls in defs.BUILTIN_SUBCLASSES:
                    self.assertEqual(got, inst)
                else:
                    self.assertNotEqual(got, inst)

    def assert_class_defs_not_shareable(self, defs):
        self.assert_not_shareable(defs.TOP_CLASSES)

        instances = []
        for cls, args in defs.TOP_CLASSES.items():
            instances.append(cls(*args))
        self.assert_not_shareable(instances)

    def test_user_class_normal(self):
        self.assert_class_defs_same(defs)

    def test_user_class_in___main__(self):
        with using___main__() as mod:
            defs = load_defs(mod)
            self.assert_class_defs_same(defs)

    def test_user_class_not_in___main___with_filename(self):
        with using___main__() as mod:
            defs = load_defs('__main__')
            assert defs.__file__
            mod.__file__ = defs.__file__
            self.assert_class_defs_not_shareable(defs)

    def test_user_class_not_in___main___without_filename(self):
        with using___main__() as mod:
            defs = load_defs('__main__')
            defs.__file__ = None
            mod.__file__ = None
            self.assert_class_defs_not_shareable(defs)

    def test_user_class_not_in___main___unpickle_with_filename(self):
        with using___main__() as mod:
            defs = load_defs('__main__')
            assert defs.__file__
            mod.__file__ = defs.__file__
            self.assert_class_defs_other_unpickle(defs, mod)

    def test_user_class_not_in___main___unpickle_without_filename(self):
        with using___main__() as mod:
            defs = load_defs('__main__')
            defs.__file__ = None
            mod.__file__ = None
            self.assert_class_defs_other_unpickle(defs, mod, fail=True)

    def test_user_class_in_module(self):
        with temp_module('__spam__') as mod:
            defs = load_defs(mod)
            self.assert_class_defs_same(defs)

    def test_user_class_not_in_module_with_filename(self):
        with temp_module('__spam__') as mod:
            defs = load_defs(mod.__name__)
            assert defs.__file__
            # For now, we only address this case for __main__.
            self.assert_class_defs_not_shareable(defs)

    def test_user_class_not_in_module_without_filename(self):
        with temp_module('__spam__') as mod:
            defs = load_defs(mod.__name__)
            defs.__file__ = None
            self.assert_class_defs_not_shareable(defs)

    def test_user_class_module_missing_then_imported(self):
        with missing_defs_module('__spam__', prep=True) as modname:
            defs = load_defs(modname)
            # For now, we only address this case for __main__.
            self.assert_class_defs_not_shareable(defs)

    def test_user_class_module_missing_not_available(self):
        with missing_defs_module('__spam__') as modname:
            defs = load_defs(modname)
            self.assert_class_defs_not_shareable(defs)

    def test_nested_class(self):
        eggs = defs.EggsNested()
        with self.assertRaises(NotShareableError):
            self.get_roundtrip(eggs)

    # functions

    def assert_func_defs_same(self, defs):
        # Unpickle relative to the unchanged original module.
        self.assert_roundtrip_identical(defs.TOP_FUNCTIONS)

    def assert_func_defs_other_pickle(self, defs, mod):
        # Pickle relative to a different module than the original.
        for func in defs.TOP_FUNCTIONS:
            assert not hasattr(mod, func.__name__), (getattr(mod, func.__name__),)
        self.assert_not_shareable(defs.TOP_FUNCTIONS)

    def assert_func_defs_other_unpickle(self, defs, mod, *, fail=False):
        # Unpickle relative to a different module than the original.
        for func in defs.TOP_FUNCTIONS:
            assert not hasattr(mod, func.__name__), (getattr(mod, func.__name__),)

        captured = []
        for func in defs.TOP_FUNCTIONS:
            with self.subTest(func):
                setattr(mod, func.__name__, func)
                xid = self.get_xidata(func)
                captured.append(
                        (func, xid))

        for func, xid in captured:
            with self.subTest(func):
                delattr(mod, func.__name__)
                if fail:
                    with self.assertRaises(NotShareableError):
                        _testinternalcapi.restore_crossinterp_data(xid)
                    continue
                got = _testinternalcapi.restore_crossinterp_data(xid)
                self.assertIsNot(got, func)
                self.assertNotEqual(got, func)

    def assert_func_defs_not_shareable(self, defs):
        self.assert_not_shareable(defs.TOP_FUNCTIONS)

    def test_user_function_normal(self):
        self.assert_roundtrip_equal(defs.TOP_FUNCTIONS)
        self.assert_func_defs_same(defs)

    def test_user_func_in___main__(self):
        with using___main__() as mod:
            defs = load_defs(mod)
            self.assert_func_defs_same(defs)

    def test_user_func_not_in___main___with_filename(self):
        with using___main__() as mod:
            defs = load_defs('__main__')
            assert defs.__file__
            mod.__file__ = defs.__file__
            self.assert_func_defs_not_shareable(defs)

    def test_user_func_not_in___main___without_filename(self):
        with using___main__() as mod:
            defs = load_defs('__main__')
            defs.__file__ = None
            mod.__file__ = None
            self.assert_func_defs_not_shareable(defs)

    def test_user_func_not_in___main___unpickle_with_filename(self):
        with using___main__() as mod:
            defs = load_defs('__main__')
            assert defs.__file__
            mod.__file__ = defs.__file__
            self.assert_func_defs_other_unpickle(defs, mod)

    def test_user_func_not_in___main___unpickle_without_filename(self):
        with using___main__() as mod:
            defs = load_defs('__main__')
            defs.__file__ = None
            mod.__file__ = None
            self.assert_func_defs_other_unpickle(defs, mod, fail=True)

    def test_user_func_in_module(self):
        with temp_module('__spam__') as mod:
            defs = load_defs(mod)
            self.assert_func_defs_same(defs)

    def test_user_func_not_in_module_with_filename(self):
        with temp_module('__spam__') as mod:
            defs = load_defs(mod.__name__)
            assert defs.__file__
            # For now, we only address this case for __main__.
            self.assert_func_defs_not_shareable(defs)

    def test_user_func_not_in_module_without_filename(self):
        with temp_module('__spam__') as mod:
            defs = load_defs(mod.__name__)
            defs.__file__ = None
            self.assert_func_defs_not_shareable(defs)

    def test_user_func_module_missing_then_imported(self):
        with missing_defs_module('__spam__', prep=True) as modname:
            defs = load_defs(modname)
            # For now, we only address this case for __main__.
            self.assert_func_defs_not_shareable(defs)

    def test_user_func_module_missing_not_available(self):
        with missing_defs_module('__spam__') as modname:
            defs = load_defs(modname)
            self.assert_func_defs_not_shareable(defs)

    def test_nested_function(self):
        self.assert_not_shareable(defs.NESTED_FUNCTIONS)

    # exceptions

    def test_user_exception_normal(self):
        self.assert_roundtrip_equal([
            defs.MimimalError('error!'),
        ])
        self.assert_roundtrip_equal_not_identical([
            defs.RichError('error!', 42),
        ])

    def test_builtin_exception(self):
        msg = 'error!'
        try:
            raise Exception
        except Exception as exc:
            caught = exc
        special = {
            BaseExceptionGroup: (msg, [caught]),
            ExceptionGroup: (msg, [caught]),
            UnicodeError: (None, msg, None, None, None),
            UnicodeEncodeError: ('utf-8', '', 1, 3, msg),
            UnicodeDecodeError: ('utf-8', b'', 1, 3, msg),
            UnicodeTranslateError: ('', 1, 3, msg),
        }
        exceptions = []
        for cls in EXCEPTION_TYPES:
            args = special.get(cls) or (msg,)
            exceptions.append(cls(*args))

        self.assert_roundtrip_equal(exceptions)


class MarshalTests(_GetXIDataTests):

    MODE = 'marshal'

    def test_simple_builtin_singletons(self):
        self.assert_roundtrip_identical([
            True,
            False,
            None,
            Ellipsis,
        ])
        self.assert_not_shareable([
            NotImplemented,
        ])

    def test_simple_builtin_objects(self):
        self.assert_roundtrip_equal([
            # int
            *range(-1, 258),
            sys.maxsize + 1,
            sys.maxsize,
            -sys.maxsize - 1,
            -sys.maxsize - 2,
            2**1000,
            # complex
            1+2j,
            # float
            0.0,
            1.1,
            -1.0,
            0.12345678,
            -0.12345678,
            # bytes
            *(i.to_bytes(2, 'little', signed=True)
              for i in range(-1, 258)),
            b'hello world',
            # str
            'hello world',
            '你好世界',
            '',
        ])
        self.assert_not_shareable([
            OBJECT,
            types.SimpleNamespace(),
        ])

    def test_bytearray(self):
        # bytearray is special because it unmarshals to bytes, not bytearray.
        self.assert_roundtrip_equal([
            bytearray(),
            bytearray(b'hello world'),
        ], expecttype=bytes)

    def test_compound_immutable_builtin_objects(self):
        self.assert_roundtrip_equal([
            # tuple
            (),
            (1,),
            ("hello", "world"),
            (1, True, "hello"),
            # frozenset
            frozenset([1, 2, 3]),
        ])
        # nested
        self.assert_roundtrip_equal([
            # tuple
            ((1,),),
            ((1, 2), (3, 4)),
            ((1, 2), (3, 4), (5, 6)),
            # frozenset
            frozenset([frozenset([1]), frozenset([2]), frozenset([3])]),
        ])

    def test_compound_mutable_builtin_objects(self):
        self.assert_roundtrip_equal([
            # list
            [],
            [1, 2, 3],
            # dict
            {},
            {1: 7, 2: 8, 3: 9},
            # set
            set(),
            {1, 2, 3},
        ])
        # nested
        self.assert_roundtrip_equal([
            [[1], [2], [3]],
            {1: {'a': True}, 2: {'b': False}},
            {(1, 2, 3,)},
        ])

    def test_compound_builtin_objects_with_bad_items(self):
        bogus = object()
        self.assert_not_shareable([
            (bogus,),
            frozenset([bogus]),
            [bogus],
            {bogus: True},
            {True: bogus},
            {bogus},
        ])

    def test_builtin_code(self):
        self.assert_roundtrip_equal([
            *(f.__code__ for f in defs.FUNCTIONS),
            *(f.__code__ for f in defs.FUNCTION_LIKE),
        ])

    def test_builtin_type(self):
        shareable = [
            StopIteration,
        ]
        types = BUILTIN_TYPES
        self.assert_not_shareable(cls for cls in types
                                  if cls not in shareable)
        self.assert_roundtrip_identical(cls for cls in types
                                        if cls in shareable)

    def test_builtin_function(self):
        functions = [
            len,
            sys.is_finalizing,
            sys.exit,
            _testinternalcapi.get_crossinterp_data,
        ]
        for func in functions:
            assert type(func) is types.BuiltinFunctionType, func

        self.assert_not_shareable(functions)

    def test_builtin_exception(self):
        msg = 'error!'
        try:
            raise Exception
        except Exception as exc:
            caught = exc
        special = {
            BaseExceptionGroup: (msg, [caught]),
            ExceptionGroup: (msg, [caught]),
#            UnicodeError: (None, msg, None, None, None),
            UnicodeEncodeError: ('utf-8', '', 1, 3, msg),
            UnicodeDecodeError: ('utf-8', b'', 1, 3, msg),
            UnicodeTranslateError: ('', 1, 3, msg),
        }
        exceptions = []
        for cls in EXCEPTION_TYPES:
            args = special.get(cls) or (msg,)
            exceptions.append(cls(*args))

        self.assert_not_shareable(exceptions)
        # Note that StopIteration (the type) can be marshalled,
        # but its instances cannot.

    def test_module(self):
        assert type(sys) is types.ModuleType, type(sys)
        assert type(defs) is types.ModuleType, type(defs)
        assert type(unittest) is types.ModuleType, type(defs)

        assert 'emptymod' not in sys.modules
        with import_helper.ready_to_import('emptymod', ''):
            import emptymod

        self.assert_not_shareable([
            sys,
            defs,
            unittest,
            emptymod,
        ])

    def test_user_class(self):
        self.assert_not_shareable(defs.TOP_CLASSES)

        instances = []
        for cls, args in defs.TOP_CLASSES.items():
            instances.append(cls(*args))
        self.assert_not_shareable(instances)

    def test_user_function(self):
        self.assert_not_shareable(defs.TOP_FUNCTIONS)

    def test_user_exception(self):
        self.assert_not_shareable([
            defs.MimimalError('error!'),
            defs.RichError('error!', 42),
        ])


class CodeTests(_GetXIDataTests):

    MODE = 'code'

    def test_function_code(self):
        self.assert_roundtrip_equal_not_identical([
            *(f.__code__ for f in defs.FUNCTIONS),
            *(f.__code__ for f in defs.FUNCTION_LIKE),
        ])

    def test_functions(self):
        self.assert_not_shareable([
            *defs.FUNCTIONS,
            *defs.FUNCTION_LIKE,
        ])

    def test_other_objects(self):
        self.assert_not_shareable([
            None,
            True,
            False,
            Ellipsis,
            NotImplemented,
            9999,
            'spam',
            b'spam',
            (),
            [],
            {},
            object(),
        ])


class ShareableFuncTests(_GetXIDataTests):

    MODE = 'func'

    def test_stateless(self):
        self.assert_roundtrip_equal([
            *defs.STATELESS_FUNCTIONS,
            # Generators can be stateless too.
            *defs.FUNCTION_LIKE,
        ])

    def test_not_stateless(self):
        self.assert_not_shareable([
            *(f for f in defs.FUNCTIONS
              if f not in defs.STATELESS_FUNCTIONS),
        ])

    def test_other_objects(self):
        self.assert_not_shareable([
            None,
            True,
            False,
            Ellipsis,
            NotImplemented,
            9999,
            'spam',
            b'spam',
            (),
            [],
            {},
            object(),
        ])


class PureShareableScriptTests(_GetXIDataTests):

    MODE = 'script-pure'

    VALID_SCRIPTS = [
        '',
        'spam',
        '# a comment',
        'print("spam")',
        'raise Exception("spam")',
        """if True:
            do_something()
            """,
        """if True:
            def spam(x):
                return x
            class Spam:
                def eggs(self):
                    return 42
            x = Spam().eggs()
            raise ValueError(spam(x))
            """,
    ]
    INVALID_SCRIPTS = [
        '    pass',  # IndentationError
        '----',  # SyntaxError
        """if True:
            def spam():
                # no body
            spam()
            """,  # IndentationError
    ]

    def test_valid_str(self):
        self.assert_roundtrip_not_equal([
            *self.VALID_SCRIPTS,
        ], expecttype=types.CodeType)

    def test_invalid_str(self):
        self.assert_not_shareable([
            *self.INVALID_SCRIPTS,
        ])

    def test_valid_bytes(self):
        self.assert_roundtrip_not_equal([
            *(s.encode('utf8') for s in self.VALID_SCRIPTS),
        ], expecttype=types.CodeType)

    def test_invalid_bytes(self):
        self.assert_not_shareable([
            *(s.encode('utf8') for s in self.INVALID_SCRIPTS),
        ])

    def test_pure_script_code(self):
        self.assert_roundtrip_equal_not_identical([
            *(f.__code__ for f in defs.PURE_SCRIPT_FUNCTIONS),
        ])

    def test_impure_script_code(self):
        self.assert_not_shareable([
            *(f.__code__ for f in defs.SCRIPT_FUNCTIONS
              if f not in defs.PURE_SCRIPT_FUNCTIONS),
        ])

    def test_other_code(self):
        self.assert_not_shareable([
            *(f.__code__ for f in defs.FUNCTIONS
              if f not in defs.SCRIPT_FUNCTIONS),
            *(f.__code__ for f in defs.FUNCTION_LIKE),
        ])

    def test_pure_script_function(self):
        self.assert_roundtrip_not_equal([
            *defs.PURE_SCRIPT_FUNCTIONS,
        ], expecttype=types.CodeType)

    def test_impure_script_function(self):
        self.assert_not_shareable([
            *(f for f in defs.SCRIPT_FUNCTIONS
              if f not in defs.PURE_SCRIPT_FUNCTIONS),
        ])

    def test_other_function(self):
        self.assert_not_shareable([
            *(f for f in defs.FUNCTIONS
              if f not in defs.SCRIPT_FUNCTIONS),
            *defs.FUNCTION_LIKE,
        ])

    def test_other_objects(self):
        self.assert_not_shareable([
            None,
            True,
            False,
            Ellipsis,
            NotImplemented,
            (),
            [],
            {},
            object(),
        ])


class ShareableScriptTests(PureShareableScriptTests):

    MODE = 'script'

    def test_impure_script_code(self):
        self.assert_roundtrip_equal_not_identical([
            *(f.__code__ for f in defs.SCRIPT_FUNCTIONS
              if f not in defs.PURE_SCRIPT_FUNCTIONS),
        ])

    def test_impure_script_function(self):
        self.assert_roundtrip_not_equal([
            *(f for f in defs.SCRIPT_FUNCTIONS
              if f not in defs.PURE_SCRIPT_FUNCTIONS),
        ], expecttype=types.CodeType)


class ShareableFallbackTests(_GetXIDataTests):

    MODE = 'fallback'

    def test_shareable(self):
        self.assert_roundtrip_equal(SHAREABLE)

    def test_not_shareable(self):
        okay = [
            *PICKLEABLE,
            *defs.STATELESS_FUNCTIONS,
            LAMBDA,
        ]
        ignored = [
            *TUPLES_WITHOUT_EQUALITY,
            OBJECT,
            METHOD,
            BUILTIN_METHOD,
            METHOD_WRAPPER,
        ]
        with ignore_byteswarning():
            self.assert_roundtrip_equal([
                *(o for o in NOT_SHAREABLE
                  if o in okay and o not in ignored
                  and o is not MAPPING_PROXY_EMPTY),
            ])
            self.assert_roundtrip_not_equal([
                *(o for o in NOT_SHAREABLE
                  if o in ignored and o is not MAPPING_PROXY_EMPTY),
            ])
            self.assert_not_shareable([
                *(o for o in NOT_SHAREABLE if o not in okay),
                MAPPING_PROXY_EMPTY,
            ])


class ShareableTypeTests(_GetXIDataTests):

    MODE = 'xidata'

    def test_shareable(self):
        self.assert_roundtrip_equal(SHAREABLE)

    def test_singletons(self):
        self.assert_roundtrip_identical([
            None,
            True,
            False,
        ])
        self.assert_not_shareable([
            Ellipsis,
            NotImplemented,
        ])

    def test_types(self):
        self.assert_roundtrip_equal([
            b'spam',
            9999,
        ])

    def test_bytes(self):
        values = (i.to_bytes(2, 'little', signed=True)
                  for i in range(-1, 258))
        self.assert_roundtrip_equal(values)

    def test_strs(self):
        self.assert_roundtrip_equal([
            'hello world',
            '你好世界',
            '',
        ])

    def test_int(self):
        bounds = [sys.maxsize, -sys.maxsize - 1]
        values = itertools.chain(range(-1, 258), bounds)
        self.assert_roundtrip_equal(values)

    def test_non_shareable_int(self):
        ints = [
            sys.maxsize + 1,
            -sys.maxsize - 2,
            2**1000,
        ]
        self.assert_not_shareable(ints, OverflowError)

    def test_float(self):
        self.assert_roundtrip_equal([
            0.0,
            1.1,
            -1.0,
            0.12345678,
            -0.12345678,
        ])

    def test_tuple(self):
        self.assert_roundtrip_equal([
            (),
            (1,),
            ("hello", "world", ),
            (1, True, "hello"),
        ])
        # Test nesting
        self.assert_roundtrip_equal([
            ((1,),),
            ((1, 2), (3, 4)),
            ((1, 2), (3, 4), (5, 6)),
        ])

    def test_tuples_containing_non_shareable_types(self):
        non_shareables = [
            EXCEPTION,
            OBJECT,
        ]
        for s in non_shareables:
            value = tuple([0, 1.0, s])
            with self.subTest(repr(value)):
                with self.assertRaises(NotShareableError):
                    self.get_xidata(value)
            # Check nested as well
            value = tuple([0, 1., (s,)])
            with self.subTest("nested " + repr(value)):
                with self.assertRaises(NotShareableError):
                    self.get_xidata(value)

    # The rest are not shareable.

    def test_not_shareable(self):
        self.assert_not_shareable(NOT_SHAREABLE)

    def test_object(self):
        self.assert_not_shareable([
            object(),
        ])

    def test_code(self):
        # types.CodeType
        self.assert_not_shareable([
            *(f.__code__ for f in defs.FUNCTIONS),
            *(f.__code__ for f in defs.FUNCTION_LIKE),
        ])

    def test_function_object(self):
        for func in defs.FUNCTIONS:
            assert type(func) is types.FunctionType, func
        assert type(defs.SpamOkay.okay) is types.FunctionType, func
        assert type(LAMBDA) is types.LambdaType

        self.assert_not_shareable([
            *defs.FUNCTIONS,
            defs.SpamOkay.okay,
            LAMBDA,
        ])

    def test_builtin_function(self):
        functions = [
            len,
            sys.is_finalizing,
            sys.exit,
            _testinternalcapi.get_crossinterp_data,
        ]
        for func in functions:
            assert type(func) is types.BuiltinFunctionType, func

        self.assert_not_shareable(functions)

    def test_function_like(self):
        self.assert_not_shareable(defs.FUNCTION_LIKE)
        self.assert_not_shareable(defs.FUNCTION_LIKE_APPLIED)

    def test_builtin_wrapper(self):
        _wrappers = {
            defs.SpamOkay().okay: types.MethodType,
            [].append: types.BuiltinMethodType,
            dict.__dict__['fromkeys']: types.ClassMethodDescriptorType,
            types.FunctionType.__code__: types.GetSetDescriptorType,
            types.FunctionType.__globals__: types.MemberDescriptorType,
            str.join: types.MethodDescriptorType,
            object().__str__: types.MethodWrapperType,
            object.__init__: types.WrapperDescriptorType,
        }
        for obj, expected in _wrappers.items():
            assert type(obj) is expected, (obj, expected)

        self.assert_not_shareable([
            *_wrappers,
            staticmethod(defs.SpamOkay.okay),
            classmethod(defs.SpamOkay.okay),
            property(defs.SpamOkay.okay),
        ])

    def test_module(self):
        assert type(sys) is types.ModuleType, type(sys)
        assert type(defs) is types.ModuleType, type(defs)
        assert type(unittest) is types.ModuleType, type(defs)

        assert 'emptymod' not in sys.modules
        with import_helper.ready_to_import('emptymod', ''):
            import emptymod

        self.assert_not_shareable([
            sys,
            defs,
            unittest,
            emptymod,
        ])

    def test_class(self):
        self.assert_not_shareable(defs.CLASSES)

        instances = []
        for cls, args in defs.CLASSES.items():
            instances.append(cls(*args))
        self.assert_not_shareable(instances)

    def test_builtin_type(self):
        self.assert_not_shareable(BUILTIN_TYPES)

    def test_exception(self):
        self.assert_not_shareable([
            defs.MimimalError('error!'),
        ])

    def test_builtin_exception(self):
        msg = 'error!'
        try:
            raise Exception
        except Exception as exc:
            caught = exc
        special = {
            BaseExceptionGroup: (msg, [caught]),
            ExceptionGroup: (msg, [caught]),
#            UnicodeError: (None, msg, None, None, None),
            UnicodeEncodeError: ('utf-8', '', 1, 3, msg),
            UnicodeDecodeError: ('utf-8', b'', 1, 3, msg),
            UnicodeTranslateError: ('', 1, 3, msg),
        }
        exceptions = []
        for cls in EXCEPTION_TYPES:
            args = special.get(cls) or (msg,)
            exceptions.append(cls(*args))

        self.assert_not_shareable(exceptions)

    def test_builtin_objects(self):
        ns = {}
        exec("""if True:
            try:
                raise Exception
            except Exception as exc:
                TRACEBACK = exc.__traceback__
                FRAME = TRACEBACK.tb_frame
            """, ns, ns)

        self.assert_not_shareable([
            MAPPING_PROXY_EMPTY,
            types.SimpleNamespace(),
            # types.CellType
            types.CellType(),
            # types.FrameType
            ns['FRAME'],
            # types.TracebackType
            ns['TRACEBACK'],
        ])


if __name__ == '__main__':
    unittest.main()
