diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py index ad7accf2099f43..005374f429399f 100644 --- a/Lib/test/test_list.py +++ b/Lib/test/test_list.py @@ -1,6 +1,8 @@ import sys +import textwrap from test import list_tests from test.support import cpython_only +from test.support.script_helper import assert_python_ok import pickle import unittest @@ -309,5 +311,25 @@ def test_tier2_invalidates_iterator(self): a.append(4) self.assertEqual(list(it), []) + def test_deopt_from_append_list(self): + # gh-132011: it used to crash, because + # of `CALL_LIST_APPEND` specialization failure. + code = textwrap.dedent(""" + l = [] + def lappend(l, x, y): + l.append((x, y)) + for x in range(3): + lappend(l, None, None) + try: + lappend(list, None, None) + except TypeError: + pass + else: + raise AssertionError + """) + + rc, _, _ = assert_python_ok("-c", code) + self.assertEqual(rc, 0) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-04-02-17-47-14.gh-issue-132011.dNh64H.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-02-17-47-14.gh-issue-132011.dNh64H.rst new file mode 100644 index 00000000000000..b2484bf7c01a72 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-04-02-17-47-14.gh-issue-132011.dNh64H.rst @@ -0,0 +1 @@ +Fix crash when calling :meth:`!list.append` as an unbound method. diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 1e6185d3c9e489..ba8ecc7faf2dbc 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -3631,7 +3631,7 @@ dummy_func( assert(oparg == 1); PyInterpreterState *interp = tstate->interp; DEOPT_IF(callable != interp->callable_cache.list_append); - assert(self != NULL); + DEOPT_IF(self == NULL); DEOPT_IF(!PyList_Check(self)); STAT_INC(CALL, hit); if (_PyList_AppendTakeRef((PyListObject *)self, arg) < 0) { diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 1488e4215cf579..93d5a782b469d4 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1590,7 +1590,7 @@ assert(oparg == 1); PyInterpreterState *interp = tstate->interp; DEOPT_IF(callable != interp->callable_cache.list_append, CALL); - assert(self != NULL); + DEOPT_IF(self == NULL, CALL); DEOPT_IF(!PyList_Check(self), CALL); STAT_INC(CALL, hit); if (_PyList_AppendTakeRef((PyListObject *)self, arg) < 0) {
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: