import copy
import gc
import operator
import re
import sys
import textwrap
import threading
import types
import unittest
import weakref
try:
    import _testcapi
except ImportError:
    _testcapi = None

from test import support
from test.support import import_helper, threading_helper, Py_GIL_DISABLED
from test.support.script_helper import assert_python_ok


class ClearTest(unittest.TestCase):
    """
    Tests for frame.clear().
    """

    def inner(self, x=5, **kwargs):
        1/0

    def outer(self, **kwargs):
        try:
            self.inner(**kwargs)
        except ZeroDivisionError as e:
            exc = e
        return exc

    def clear_traceback_frames(self, tb):
        """
        Clear all frames in a traceback.
        """
        while tb is not None:
            tb.tb_frame.clear()
            tb = tb.tb_next

    def test_clear_locals(self):
        class C:
            pass
        c = C()
        wr = weakref.ref(c)
        exc = self.outer(c=c)
        del c
        support.gc_collect()
        # A reference to c is held through the frames
        self.assertIsNot(None, wr())
        self.clear_traceback_frames(exc.__traceback__)
        support.gc_collect()
        # The reference was released by .clear()
        self.assertIs(None, wr())

    def test_clear_locals_after_f_locals_access(self):
        # see gh-113939
        class C:
            pass

        wr = None
        def inner():
            nonlocal wr
            c = C()
            wr = weakref.ref(c)
            1/0

        try:
            inner()
        except ZeroDivisionError as exc:
            support.gc_collect()
            self.assertIsNotNone(wr())
            exc.__traceback__.tb_next.tb_frame.clear()
            support.gc_collect()
            self.assertIsNone(wr())

    def test_clear_does_not_clear_specials(self):
        class C:
            pass
        c = C()
        exc = self.outer(c=c)
        del c
        f = exc.__traceback__.tb_frame
        f.clear()
        self.assertIsNot(f.f_code, None)
        self.assertIsNot(f.f_locals, None)
        self.assertIsNot(f.f_builtins, None)
        self.assertIsNot(f.f_globals, None)

    def test_clear_generator(self):
        endly = False
        def g():
            nonlocal endly
            try:
                yield
                self.inner()
            finally:
                endly = True
        gen = g()
        next(gen)
        self.assertFalse(endly)

        # Cannot clear a suspended frame
        with self.assertRaisesRegex(RuntimeError, r'suspended frame'):
            gen.gi_frame.clear()
        self.assertFalse(endly)

    def test_clear_executing(self):
        # Attempting to clear an executing frame is forbidden.
        try:
            1/0
        except ZeroDivisionError as e:
            f = e.__traceback__.tb_frame
        with self.assertRaises(RuntimeError):
            f.clear()
        with self.assertRaises(RuntimeError):
            f.f_back.clear()

    def test_clear_executing_generator(self):
        # Attempting to clear an executing generator frame is forbidden.
        endly = False
        def g():
            nonlocal endly
            try:
                1/0
            except ZeroDivisionError as e:
                f = e.__traceback__.tb_frame
                with self.assertRaises(RuntimeError):
                    f.clear()
                with self.assertRaises(RuntimeError):
                    f.f_back.clear()
                yield f
            finally:
                endly = True
        gen = g()
        f = next(gen)
        self.assertFalse(endly)
        # Cannot clear a suspended frame
        with self.assertRaisesRegex(RuntimeError, 'suspended frame'):
            f.clear()
        self.assertFalse(endly)

    def test_lineno_with_tracing(self):
        def record_line():
            f = sys._getframe(1)
            lines.append(f.f_lineno-f.f_code.co_firstlineno)

        def test(trace):
            record_line()
            if trace:
                sys._getframe(0).f_trace = True
            record_line()
            record_line()

        expected_lines = [1, 4, 5]
        lines = []
        test(False)
        self.assertEqual(lines, expected_lines)
        lines = []
        test(True)
        self.assertEqual(lines, expected_lines)

    @support.cpython_only
    def test_clear_refcycles(self):
        # .clear() doesn't leave any refcycle behind
        with support.disable_gc():
            class C:
                pass
            c = C()
            wr = weakref.ref(c)
            exc = self.outer(c=c)
            del c
            self.assertIsNot(None, wr())
            self.clear_traceback_frames(exc.__traceback__)
            self.assertIs(None, wr())


class FrameAttrsTest(unittest.TestCase):

    def make_frames(self):
        def outer():
            x = 5
            y = 6
            def inner():
                z = x + 2
                1/0
                t = 9
            return inner()
        try:
            outer()
        except ZeroDivisionError as e:
            tb = e.__traceback__
            frames = []
            while tb:
                frames.append(tb.tb_frame)
                tb = tb.tb_next
        return frames

    def test_clear_locals(self):
        # Test f_locals after clear() (issue #21897)
        f, outer, inner = self.make_frames()
        outer.clear()
        inner.clear()
        self.assertEqual(outer.f_locals, {})
        self.assertEqual(inner.f_locals, {})

    def test_locals_clear_locals(self):
        # Test f_locals before and after clear() (to exercise caching)
        f, outer, inner = self.make_frames()
        self.assertNotEqual(outer.f_locals, {})
        self.assertNotEqual(inner.f_locals, {})
        outer.clear()
        inner.clear()
        self.assertEqual(outer.f_locals, {})
        self.assertEqual(inner.f_locals, {})

    def test_f_lineno_del_segfault(self):
        f, _, _ = self.make_frames()
        with self.assertRaises(AttributeError):
            del f.f_lineno


class ReprTest(unittest.TestCase):
    """
    Tests for repr(frame).
    """

    def test_repr(self):
        def outer():
            x = 5
            y = 6
            def inner():
                z = x + 2
                1/0
                t = 9
            return inner()

        offset = outer.__code__.co_firstlineno
        try:
            outer()
        except ZeroDivisionError as e:
            tb = e.__traceback__
            frames = []
            while tb:
                frames.append(tb.tb_frame)
                tb = tb.tb_next
        else:
            self.fail("should have raised")

        f_this, f_outer, f_inner = frames
        file_repr = re.escape(repr(__file__))
        self.assertRegex(repr(f_this),
                         r"^<frame at 0x[0-9a-fA-F]+, file %s, line %d, code test_repr>$"
                         % (file_repr, offset + 23))
        self.assertRegex(repr(f_outer),
                         r"^<frame at 0x[0-9a-fA-F]+, file %s, line %d, code outer>$"
                         % (file_repr, offset + 7))
        self.assertRegex(repr(f_inner),
                         r"^<frame at 0x[0-9a-fA-F]+, file %s, line %d, code inner>$"
                         % (file_repr, offset + 5))

class TestFrameLocals(unittest.TestCase):
    def test_scope(self):
        class A:
            x = 1
            sys._getframe().f_locals['x'] = 2
            sys._getframe().f_locals['y'] = 2

        self.assertEqual(A.x, 2)
        self.assertEqual(A.y, 2)

        def f():
            x = 1
            sys._getframe().f_locals['x'] = 2
            sys._getframe().f_locals['y'] = 2
            self.assertEqual(x, 2)
            self.assertEqual(locals()['y'], 2)
        f()

    def test_closure(self):
        x = 1
        y = 2

        def f():
            z = x + y
            d = sys._getframe().f_locals
            self.assertEqual(d['x'], 1)
            self.assertEqual(d['y'], 2)
            d['x'] = 2
            d['y'] = 3

        f()
        self.assertEqual(x, 2)
        self.assertEqual(y, 3)

    def test_as_dict(self):
        x = 1
        y = 2
        d = sys._getframe().f_locals
        # self, x, y, d
        self.assertEqual(len(d), 4)
        self.assertIs(d['d'], d)
        self.assertEqual(set(d.keys()), set(['x', 'y', 'd', 'self']))
        self.assertEqual(len(d.values()), 4)
        self.assertIn(1, d.values())
        self.assertEqual(len(d.items()), 4)
        self.assertIn(('x', 1), d.items())
        self.assertEqual(d.__getitem__('x'), 1)
        d.__setitem__('x', 2)
        self.assertEqual(d['x'], 2)
        self.assertEqual(d.get('x'), 2)
        self.assertIs(d.get('non_exist', None), None)
        self.assertEqual(d.__len__(), 4)
        self.assertEqual(set([key for key in d]), set(['x', 'y', 'd', 'self']))
        self.assertIn('x', d)
        self.assertTrue(d.__contains__('x'))

        self.assertEqual(reversed(d), list(reversed(d.keys())))

        d.update({'x': 3, 'z': 4})
        self.assertEqual(d['x'], 3)
        self.assertEqual(d['z'], 4)

        with self.assertRaises(TypeError):
            d.update([1, 2])

        self.assertEqual(d.setdefault('x', 5), 3)
        self.assertEqual(d.setdefault('new', 5), 5)
        self.assertEqual(d['new'], 5)

        with self.assertRaises(KeyError):
            d['non_exist']

    def test_as_number(self):
        x = 1
        y = 2
        d = sys._getframe().f_locals
        self.assertIn('z', d | {'z': 3})
        d |= {'z': 3}
        self.assertEqual(d['z'], 3)
        d |= {'y': 3}
        self.assertEqual(d['y'], 3)
        with self.assertRaises(TypeError):
            d |= 3
        with self.assertRaises(TypeError):
            _ = d | [3]

    def test_non_string_key(self):
        d = sys._getframe().f_locals
        d[1] = 2
        self.assertEqual(d[1], 2)

    def test_write_with_hidden(self):
        def f():
            f_locals = [sys._getframe().f_locals for b in [0]][0]
            f_locals['b'] = 2
            f_locals['c'] = 3
            self.assertEqual(b, 2)
            self.assertEqual(c, 3)
            b = 0
            c = 0
        f()

    def test_local_objects(self):
        o = object()
        k = '.'.join(['a', 'b', 'c'])
        f_locals = sys._getframe().f_locals
        f_locals['o'] = f_locals['k']
        self.assertEqual(o, 'a.b.c')

    def test_copy(self):
        x = 0
        d = sys._getframe().f_locals
        d_copy = d.copy()
        self.assertIsInstance(d_copy, dict)
        self.assertEqual(d_copy['x'], 0)
        d_copy['x'] = 1
        self.assertEqual(x, 0)

    def test_update_with_self(self):
        def f():
            f_locals = sys._getframe().f_locals
            f_locals.update(f_locals)
            f_locals.update(f_locals)
            f_locals.update(f_locals)
        f()

    def test_repr(self):
        x = 1
        # Introduce a reference cycle
        frame = sys._getframe()
        self.assertEqual(repr(frame.f_locals), repr(dict(frame.f_locals)))

    def test_delete(self):
        x = 1
        d = sys._getframe().f_locals
        with self.assertRaises(TypeError):
            del d['x']

        with self.assertRaises(AttributeError):
            d.clear()

        with self.assertRaises(AttributeError):
            d.pop('x')

    @support.cpython_only
    def test_sizeof(self):
        proxy = sys._getframe().f_locals
        support.check_sizeof(self, proxy, support.calcobjsize("P"))

    def test_unsupport(self):
        x = 1
        d = sys._getframe().f_locals
        with self.assertRaises(TypeError):
            copy.copy(d)

        with self.assertRaises(TypeError):
            copy.deepcopy(d)


class TestFrameCApi(unittest.TestCase):
    def test_basic(self):
        x = 1
        ctypes = import_helper.import_module('ctypes')
        PyEval_GetFrameLocals = ctypes.pythonapi.PyEval_GetFrameLocals
        PyEval_GetFrameLocals.restype = ctypes.py_object
        frame_locals = PyEval_GetFrameLocals()
        self.assertTrue(type(frame_locals), dict)
        self.assertEqual(frame_locals['x'], 1)
        frame_locals['x'] = 2
        self.assertEqual(x, 1)

        PyEval_GetFrameGlobals = ctypes.pythonapi.PyEval_GetFrameGlobals
        PyEval_GetFrameGlobals.restype = ctypes.py_object
        frame_globals = PyEval_GetFrameGlobals()
        self.assertTrue(type(frame_globals), dict)
        self.assertIs(frame_globals, globals())

        PyEval_GetFrameBuiltins = ctypes.pythonapi.PyEval_GetFrameBuiltins
        PyEval_GetFrameBuiltins.restype = ctypes.py_object
        frame_builtins = PyEval_GetFrameBuiltins()
        self.assertEqual(frame_builtins, __builtins__)

        PyFrame_GetLocals = ctypes.pythonapi.PyFrame_GetLocals
        PyFrame_GetLocals.argtypes = [ctypes.py_object]
        PyFrame_GetLocals.restype = ctypes.py_object
        frame = sys._getframe()
        f_locals = PyFrame_GetLocals(frame)
        self.assertTrue(f_locals['x'], 1)
        f_locals['x'] = 2
        self.assertEqual(x, 2)


class TestIncompleteFrameAreInvisible(unittest.TestCase):

    def test_issue95818(self):
        # See GH-95818 for details
        code = textwrap.dedent(f"""
            import gc

            gc.set_threshold(1,1,1)
            class GCHello:
                def __del__(self):
                    print("Destroyed from gc")

            def gen():
                yield

            fd = open({__file__!r})
            l = [fd, GCHello()]
            l.append(l)
            del fd
            del l
            gen()
        """)
        assert_python_ok("-c", code)

    @support.cpython_only
    @threading_helper.requires_working_threading()
    def test_sneaky_frame_object_teardown(self):

        class SneakyDel:
            def __del__(self):
                """
                Stash a reference to the entire stack for walking later.

                It may look crazy, but you'd be surprised how common this is
                when using a test runner (like pytest). The typical recipe is:
                ResourceWarning + -Werror + a custom sys.unraisablehook.
                """
                nonlocal sneaky_frame_object
                sneaky_frame_object = sys._getframe()

        class SneakyThread(threading.Thread):
            """
            A separate thread isn't needed to make this code crash, but it does
            make crashes more consistent, since it means sneaky_frame_object is
            backed by freed memory after the thread completes!
            """

            def run(self):
                """Run SneakyDel.__del__ as this frame is popped."""
                ref = SneakyDel()

        sneaky_frame_object = None
        t = SneakyThread()
        t.start()
        t.join()
        # sneaky_frame_object can be anything, really, but it's crucial that
        # SneakyThread.run's frame isn't anywhere on the stack while it's being
        # torn down:
        self.assertIsNotNone(sneaky_frame_object)
        while sneaky_frame_object is not None:
            self.assertIsNot(
                sneaky_frame_object.f_code, SneakyThread.run.__code__
            )
            sneaky_frame_object = sneaky_frame_object.f_back

    def test_entry_frames_are_invisible_during_teardown(self):
        class C:
            """A weakref'able class."""

        def f():
            """Try to find globals and locals as this frame is being cleared."""
            ref = C()
            # Ignore the fact that exec(C()) is a nonsense callback. We're only
            # using exec here because it tries to access the current frame's
            # globals and locals. If it's trying to get those from a shim frame,
            # we'll crash before raising:
            return weakref.ref(ref, exec)

        with support.catch_unraisable_exception() as catcher:
            # Call from C, so there is a shim frame directly above f:
            weak = operator.call(f)  # BOOM!
            # Cool, we didn't crash. Check that the callback actually happened:
            self.assertIs(catcher.unraisable.exc_type, TypeError)
        self.assertIsNone(weak())

@unittest.skipIf(_testcapi is None, 'need _testcapi')
class TestCAPI(unittest.TestCase):
    def getframe(self):
        return sys._getframe()

    def test_frame_getters(self):
        frame = self.getframe()
        self.assertEqual(frame.f_locals, _testcapi.frame_getlocals(frame))
        self.assertIs(frame.f_globals, _testcapi.frame_getglobals(frame))
        self.assertIs(frame.f_builtins, _testcapi.frame_getbuiltins(frame))
        self.assertEqual(frame.f_lasti, _testcapi.frame_getlasti(frame))

    def test_getvar(self):
        current_frame = sys._getframe()
        x = 1
        self.assertEqual(_testcapi.frame_getvar(current_frame, "x"), 1)
        self.assertEqual(_testcapi.frame_getvarstring(current_frame, b"x"), 1)
        with self.assertRaises(NameError):
            _testcapi.frame_getvar(current_frame, "y")
        with self.assertRaises(NameError):
            _testcapi.frame_getvarstring(current_frame, b"y")

        # wrong name type
        with self.assertRaises(TypeError):
            _testcapi.frame_getvar(current_frame, b'x')
        with self.assertRaises(TypeError):
            _testcapi.frame_getvar(current_frame, 123)

    def getgenframe(self):
        yield sys._getframe()

    def test_frame_get_generator(self):
        gen = self.getgenframe()
        frame = next(gen)
        self.assertIs(gen, _testcapi.frame_getgenerator(frame))

    def test_frame_fback_api(self):
        """Test that accessing `f_back` does not cause a segmentation fault on
        a frame created with `PyFrame_New` (GH-99110)."""
        def dummy():
            pass

        frame = _testcapi.frame_new(dummy.__code__, globals(), locals())
        # The following line should not cause a segmentation fault.
        self.assertIsNone(frame.f_back)

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