diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2023-05-12 16:03:47 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-12 23:03:47 +0000 |
commit | fbb6def08a7ce7d21653e15ccbc4017b4eb2e795 (patch) | |
tree | 85c86ae7bbc4afc2e3675d71b025e3f4246f6c8f | |
parent | [3.11] Fix refleak in super_descr_get (GH-104440) (diff) | |
download | cpython-fbb6def08a7ce7d21653e15ccbc4017b4eb2e795.tar.gz cpython-fbb6def08a7ce7d21653e15ccbc4017b4eb2e795.tar.bz2 cpython-fbb6def08a7ce7d21653e15ccbc4017b4eb2e795.zip |
[3.11] GH-104405: Add missing PEP 523 checks (GH-104441)
-rw-r--r-- | Lib/test/test_capi/test_misc.py | 47 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2023-05-12-00-19-02.gh-issue-104405.tXV5fn.rst | 2 | ||||
-rw-r--r-- | Python/ceval.c | 1 | ||||
-rw-r--r-- | Python/specialize.c | 4 |
4 files changed, 36 insertions, 18 deletions
diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py index 67150a8d24c..3e36fbde8c6 100644 --- a/Lib/test/test_capi/test_misc.py +++ b/Lib/test/test_capi/test_misc.py @@ -1378,28 +1378,39 @@ SUFFICIENT_TO_DEOPT_AND_SPECIALIZE = 100 class Test_Pep523API(unittest.TestCase): - def do_test(self, func): - calls = [] + def do_test(self, func, names): + actual_calls = [] start = SUFFICIENT_TO_DEOPT_AND_SPECIALIZE count = start + SUFFICIENT_TO_DEOPT_AND_SPECIALIZE - for i in range(count): - if i == start: - _testinternalcapi.set_eval_frame_record(calls) - func() - _testinternalcapi.set_eval_frame_default() - self.assertEqual(len(calls), SUFFICIENT_TO_DEOPT_AND_SPECIALIZE) - for name in calls: - self.assertEqual(name, func.__name__) - - def test_pep523_with_specialization_simple(self): - def func1(): - pass - self.do_test(func1) + try: + for i in range(count): + if i == start: + _testinternalcapi.set_eval_frame_record(actual_calls) + func() + finally: + _testinternalcapi.set_eval_frame_default() + expected_calls = names * SUFFICIENT_TO_DEOPT_AND_SPECIALIZE + self.assertEqual(len(expected_calls), len(actual_calls)) + for expected, actual in zip(expected_calls, actual_calls, strict=True): + self.assertEqual(expected, actual) + + def test_inlined_binary_subscr(self): + class C: + def __getitem__(self, other): + return None + def func(): + C()[42] + names = ["func", "__getitem__"] + self.do_test(func, names) - def test_pep523_with_specialization_with_default(self): - def func2(x=None): + def test_inlined_call(self): + def inner(x=42): pass - self.do_test(func2) + def func(): + inner() + inner(42) + names = ["func", "inner", "inner"] + self.do_test(func, names) if __name__ == "__main__": diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-12-00-19-02.gh-issue-104405.tXV5fn.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-12-00-19-02.gh-issue-104405.tXV5fn.rst new file mode 100644 index 00000000000..06ec5d7b0f0 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-05-12-00-19-02.gh-issue-104405.tXV5fn.rst @@ -0,0 +1,2 @@ +Fix an issue where some :term:`bytecode` instructions could ignore +:pep:`523` when "inlining" calls. diff --git a/Python/ceval.c b/Python/ceval.c index 72f9c8375d0..47df3531970 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2233,6 +2233,7 @@ handle_eval_breaker: } TARGET(BINARY_SUBSCR_GETITEM) { + DEOPT_IF(tstate->interp->eval_frame, BINARY_SUBSCR); PyObject *sub = TOP(); PyObject *container = SECOND(); _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr; diff --git a/Python/specialize.c b/Python/specialize.c index 08ce2f5caa6..9d182fd31b0 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -1238,6 +1238,10 @@ _Py_Specialize_BinarySubscr( SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OUT_OF_VERSIONS); goto fail; } + if (_PyInterpreterState_GET()->eval_frame) { + SPECIALIZATION_FAIL(BINARY_SUBSCR, SPEC_FAIL_OTHER); + goto fail; + } cache->func_version = version; ((PyHeapTypeObject *)container_type)->_spec_cache.getitem = descriptor; _Py_SET_OPCODE(*instr, BINARY_SUBSCR_GETITEM); |