Skip to content

Commit 1c73d55

Browse files
Merge remote-tracking branch 'upstream/main' into pr/142769
2 parents 9622734 + bef63d2 commit 1c73d55

File tree

13 files changed

+105
-18
lines changed

13 files changed

+105
-18
lines changed

Include/internal/pycore_opcode_metadata.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_ids.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_uop_metadata.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_capi/test_opt.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2631,7 +2631,25 @@ def testfunc(n):
26312631
self.assertNotIn("_POP_TOP_INT", uops)
26322632
self.assertIn("_POP_TOP_NOP", uops)
26332633

2634-
def test_store_susbscr_dict(self):
2634+
def test_store_attr_slot(self):
2635+
class C:
2636+
__slots__ = ('x',)
2637+
2638+
def testfunc(n):
2639+
c = C()
2640+
for _ in range(n):
2641+
c.x = 42
2642+
y = c.x
2643+
return y
2644+
2645+
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
2646+
self.assertEqual(res, 42)
2647+
self.assertIsNotNone(ex)
2648+
uops = get_opnames(ex)
2649+
self.assertIn("_STORE_ATTR_SLOT", uops)
2650+
self.assertIn("_POP_TOP_NOP", uops)
2651+
2652+
def test_store_subscr_dict(self):
26352653
def testfunc(n):
26362654
d = {}
26372655
for _ in range(n):

Lib/test/test_traceback.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from test.support import (Error, captured_output, cpython_only, ALWAYS_EQ,
1919
requires_debug_ranges, has_no_debug_ranges,
2020
requires_subprocess)
21-
from test.support.os_helper import TESTFN, unlink
21+
from test.support.os_helper import TESTFN, temp_dir, unlink
2222
from test.support.script_helper import assert_python_ok, assert_python_failure, make_script
2323
from test.support.import_helper import forget
2424
from test.support import force_not_colorized, force_not_colorized_test_class
@@ -524,6 +524,33 @@ def __del__(self):
524524
b'ZeroDivisionError: division by zero']
525525
self.assertEqual(stderr.splitlines(), expected)
526526

527+
@cpython_only
528+
def test_lost_io_open(self):
529+
# GH-142737: Display the traceback even if io.open is lost
530+
crasher = textwrap.dedent("""\
531+
import io
532+
import traceback
533+
# Trigger fallback mode
534+
traceback._print_exception_bltin = None
535+
del io.open
536+
raise RuntimeError("should not crash")
537+
""")
538+
539+
# Create a temporary script to exercise _Py_FindSourceFile
540+
with temp_dir() as script_dir:
541+
script = make_script(
542+
script_dir=script_dir,
543+
script_basename='tb_test_no_io_open',
544+
source=crasher)
545+
rc, stdout, stderr = assert_python_failure(script)
546+
547+
self.assertEqual(rc, 1) # Make sure it's not a crash
548+
549+
expected = [b'Traceback (most recent call last):',
550+
f' File "{script}", line 6, in <module>'.encode(),
551+
b'RuntimeError: should not crash']
552+
self.assertEqual(stderr.splitlines(), expected)
553+
527554
def test_print_exception(self):
528555
output = StringIO()
529556
traceback.print_exception(
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Tracebacks will be displayed in fallback mode even if :func:`io.open` is lost.
2+
Previously, this would crash the interpreter.
3+
Patch by Bartosz Sławecki.

Objects/call.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,7 @@ _Py_COMP_DIAG_POP
729729
PyObject * _PyObject_CallMethodFormat(PyThreadState *tstate, PyObject *callable,
730730
const char *format, ...)
731731
{
732+
assert(callable != NULL);
732733
va_list va;
733734
va_start(va, format);
734735
PyObject *retval = callmethod(tstate, callable, format, va);

Python/bytecodes.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,7 +2642,7 @@ dummy_func(
26422642
_GUARD_TYPE_VERSION +
26432643
_STORE_ATTR_WITH_HINT;
26442644

2645-
op(_STORE_ATTR_SLOT, (index/1, value, owner --)) {
2645+
op(_STORE_ATTR_SLOT, (index/1, value, owner -- o)) {
26462646
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
26472647

26482648
DEOPT_IF(!LOCK_OBJECT(owner_o));
@@ -2651,14 +2651,16 @@ dummy_func(
26512651
PyObject *old_value = *(PyObject **)addr;
26522652
FT_ATOMIC_STORE_PTR_RELEASE(*(PyObject **)addr, PyStackRef_AsPyObjectSteal(value));
26532653
UNLOCK_OBJECT(owner_o);
2654-
PyStackRef_CLOSE(owner);
2654+
INPUTS_DEAD();
2655+
o = owner;
26552656
Py_XDECREF(old_value);
26562657
}
26572658

26582659
macro(STORE_ATTR_SLOT) =
26592660
unused/1 +
26602661
_GUARD_TYPE_VERSION +
2661-
_STORE_ATTR_SLOT;
2662+
_STORE_ATTR_SLOT +
2663+
POP_TOP;
26622664

26632665
family(COMPARE_OP, INLINE_CACHE_ENTRIES_COMPARE_OP) = {
26642666
COMPARE_OP_FLOAT,

Python/executor_cases.c.h

Lines changed: 10 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)