-
-
Notifications
You must be signed in to change notification settings - Fork 33.1k
[3.13] gh-134163: fix: exec('_testcapi.set_nomemory(0)') hang in new repl 3.13 #138491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
1202ec6
4cd38e8
e557017
53f713c
9cc89f1
a9b6f96
66ec42e
a9e6b64
791ca86
4827680
8ec5769
edcfff7
81c6244
847bd7b
ff3c7f4
175a13e
d952d53
5fa3a1b
d3274fb
c89c5b5
63a6b7d
977703f
095f865
932c15e
52310f0
bb790af
06b779a
30cd34d
26ce31b
5ab08c7
789040c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -98,6 +98,71 @@ def test_no_memory(self): | |
# Exit code 120: Py_FinalizeEx() failed to flush stdout and stderr. | ||
self.assertIn(p.returncode, (1, 120)) | ||
|
||
@cpython_only | ||
def test_issue134163_exec_hang(self): | ||
# Complete reproduction code that simulates REPL exec() behavior | ||
# note these prints are used can not drop | ||
user_input = dedent(""" | ||
exec(''' | ||
def test_repl_hanging(): | ||
print("=" * 60) | ||
print("Reproducing gh-134163 outside REPL") | ||
print("Simulating interactive interpreter exec() behavior") | ||
print("=" * 60) | ||
print() | ||
|
||
# First, import and set up the memory failure condition | ||
print("Step 1: Setting up memory allocation failure...") | ||
print("Step 2: Preparing code that will trigger exception handling...") | ||
# Create a code object that will cause exception handling | ||
# This simulates what happens when REPL executes user input | ||
test_code = \"\"\" | ||
# This code will trigger the problematic code path | ||
# by causing an exception during execution when memory is constrained | ||
import _testcapi | ||
_testcapi.set_nomemory(0) # This line triggers the hang condition | ||
\"\"\" | ||
print("Step 3: Compiling test code...") | ||
try: | ||
compiled_code = compile(test_code, "<reproduce_script>", "exec") | ||
except Exception as e: | ||
print(f"Compilation failed: {e}") | ||
exit(1) | ||
print("Step 4: Executing code that triggers the hang condition...") | ||
print("BEFORE FIX: This would hang indefinitely") | ||
print("AFTER FIX: This should exit gracefully") | ||
print() | ||
try: | ||
exec(compiled_code, {"__name__": "__console__"}) | ||
print("Code executed successfully (unexpected)") | ||
except SystemExit: | ||
print("SystemExit caught - re-raising") | ||
raise | ||
except Exception as e: | ||
print(f"Exception caught during exec(): {type(e).__name__}: {e}") | ||
print("This is the expected path - exception handling should work normally") | ||
# The showtraceback() equivalent would be called here in real REPL | ||
import traceback | ||
traceback.print_exc() | ||
|
||
test_repl_hanging() | ||
''') | ||
""") | ||
p = spawn_repl() | ||
with SuppressCrashReport(): | ||
p.stdin.write(user_input) | ||
|
||
output = kill_python(p) | ||
yihong0618 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
# The test should complete without hanging and show expected output | ||
# We expect either successful completion or controlled failure | ||
self.assertIn(p.returncode, (0, 1, 120)) | ||
yihong0618 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
# Verify that the simulation steps were executed or that we got the expected memory error output | ||
# The key test is that it doesn't hang - if we get output, the test passed | ||
# Look for either the expected reproduction output or memory error indicators | ||
has_reproduction_output = "Reproducing gh-134163 outside REPL" in output | ||
has_memory_error_output = "object type name: MemoryError" in output | ||
self.assertTrue(has_reproduction_output or has_memory_error_output, | ||
f"Expected either reproduction output or memory error output, got: {output[:500]}...") | ||
|
||
@cpython_only | ||
def test_multiline_string_parsing(self): | ||
# bpo-39209: Multiline string tokens need to be handled in the tokenizer | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
fix in default repl exec('_testcapi.set_nomemory(0)') hang forever. | ||
yihong0618 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.