Files
RustPython/extra_tests/snippets/recursion.py
T
Jeong, YunWon e053f7d5b6 vm: drop trailing space from RecursionError text (#8992)
* vm: drop trailing space from RecursionError text

Format Python-limit and native-stack RecursionError messages
through one helper so empty context is not a trailing space
or an empty string.

Assisted-by: Grok 4.6

* test: deepen nested hash snippets for release stack frames

The cold RecursionError helper thins with_recursion's hot frame,
so 100_000 nested hashes no longer trip the native stack guard
in release.

Assisted-by: Grok 4.6

* vm: let RecursionError callers own the where-clause space

The helper concatenates an empty suffix or one that already
starts with a space. Call sites supply that space.

Assisted-by: Grok 4.6
2026-10-08 00:58:39 +09:00

76 lines
1.5 KiB
Python

from testutils import assert_raises
class Foo(object):
pass
Foo.__repr__ = Foo.__str__
foo = Foo()
# Since the default __str__ implementation calls __repr__ and __repr__ is
# actually __str__, str(foo) should raise a RecursionError.
assert_raises(RecursionError, str, foo)
# A __call__ that is the object being called dispatches through the call slot
# again, and none of that pushes a Python frame.
class Caller:
pass
caller = Caller()
Caller.__call__ = caller
assert_raises(RecursionError, caller)
# The same shape through the descriptor protocol: resolving the attribute
# fetches __get__, which is the descriptor itself.
class Descr:
pass
descr = Descr()
Descr.__get__ = descr
Descr.x = descr
try:
descr.x
except (RecursionError, TypeError):
# RecursionError here, TypeError from the call of a non-callable elsewhere
pass
else:
raise AssertionError("descr.x should not resolve")
def recurse():
recurse()
try:
recurse()
except RecursionError as e:
msg = str(e)
assert msg, f"empty RecursionError message: {e!r}"
assert not msg.endswith(" "), f"trailing space in RecursionError: {e!r}"
import sys
prev_limit = sys.getrecursionlimit()
try:
sys.setrecursionlimit(50)
try:
recurse()
except RecursionError as e:
assert str(e) == "maximum recursion depth exceeded", (
f"unexpected message: {e!r}"
)
assert e.args == ("maximum recursion depth exceeded",), (
f"unexpected args: {e.args!r}"
)
finally:
sys.setrecursionlimit(prev_limit)