https://github.com/python/cpython/commit/c0661df42ad20e488dbfa3e0fec22462833fc3d6
commit: c0661df42ad20e488dbfa3e0fec22462833fc3d6
branch: main
author: sobolevn <m...@sobolevn.me>
committer: sobolevn <m...@sobolevn.me>
date: 2025-04-06T19:10:39+03:00
summary:

gh-132011: Fix crash on invalid `CALL_LIST_APPEND` deoptimization (#132018)

Co-authored-by: Victor Stinner <vstin...@python.org>
Co-authored-by: Peter Bierma <zintensity...@gmail.com>

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2025-04-02-17-47-14.gh-issue-132011.dNh64H.rst
M Lib/test/test_list.py
M Python/bytecodes.c
M Python/executor_cases.c.h
M Python/generated_cases.c.h

diff --git a/Lib/test/test_list.py b/Lib/test/test_list.py
index 725e07f3ad023f..ec65ed49281527 100644
--- a/Lib/test/test_list.py
+++ b/Lib/test/test_list.py
@@ -4,7 +4,7 @@
 from test import list_tests, support
 from test.support import cpython_only
 from test.support.import_helper import import_module
-from test.support.script_helper import assert_python_failure
+from test.support.script_helper import assert_python_failure, assert_python_ok
 import pickle
 import unittest
 
@@ -332,5 +332,25 @@ def test_no_memory(self):
         else:
             self.assertNotEqual(rc, -int(signal.SIGSEGV))
 
+    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 a6cdc089d7a851..d17cac2473b101 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -4235,7 +4235,7 @@ dummy_func(
 
             PyInterpreterState *interp = tstate->interp;
             DEOPT_IF(callable_o != interp->callable_cache.list_append);
-            assert(self_o != NULL);
+            DEOPT_IF(self_o == NULL);
             DEOPT_IF(!PyList_Check(self_o));
             DEOPT_IF(!LOCK_OBJECT(self_o));
             STAT_INC(CALL, hit);
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index c0422d87bfd78b..497aa909b329c1 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -5710,7 +5710,10 @@
                 UOP_STAT_INC(uopcode, miss);
                 JUMP_TO_JUMP_TARGET();
             }
-            assert(self_o != NULL);
+            if (self_o == NULL) {
+                UOP_STAT_INC(uopcode, miss);
+                JUMP_TO_JUMP_TARGET();
+            }
             if (!PyList_Check(self_o)) {
                 UOP_STAT_INC(uopcode, miss);
                 JUMP_TO_JUMP_TARGET();
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 4a3884b9568b98..fa3de197f4bcab 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -3265,7 +3265,11 @@
                 assert(_PyOpcode_Deopt[opcode] == (CALL));
                 JUMP_TO_PREDICTED(CALL);
             }
-            assert(self_o != NULL);
+            if (self_o == NULL) {
+                UPDATE_MISS_STATS(CALL);
+                assert(_PyOpcode_Deopt[opcode] == (CALL));
+                JUMP_TO_PREDICTED(CALL);
+            }
             if (!PyList_Check(self_o)) {
                 UPDATE_MISS_STATS(CALL);
                 assert(_PyOpcode_Deopt[opcode] == (CALL));

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to