-
-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
Maximum recursion depth exceeded in __getattr__(). #103272
Comments
Cc. @wangxiang-hz and @Fidget-Spinner |
Thanks for finding this. I'll try to debug once there's a minimal reproducer. Sorry I'm a little swamped for the next 2 weeks. |
NB: when running this test with debug build, it crashes.
|
I got a minimal repo! class A:
def __init__(self) -> None:
self.bar = 0
def __getattribute__(self, name):
return super().__getattribute__(name)
def __getattr__(self, name):
if self.bar == 0:
raise ValueError
@property
def foo(self):
return self.__getattr__("foo")
A().foo Running in older Python version, we got Traceback (most recent call last):
File "/home/ubuntu/django-main/tests/../a.py", line 17, in <module>
A().foo
File "/home/ubuntu/django-main/tests/../a.py", line 6, in __getattribute__
return super().__getattribute__(name)
File "/home/ubuntu/django-main/tests/../a.py", line 14, in foo
return self.__getattr__("foo")
File "/home/ubuntu/django-main/tests/../a.py", line 10, in __getattr__
raise ValueError
ValueError Call flow:
But with the new python in main branch, (with out pydebug) Exception ignored in tp_clear of: <class 'type'>
Traceback (most recent call last):
File "/home/ubuntu/django-main/tests/../a.py", line 6, in __getattribute__
return super().__getattribute__(name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
SystemError: <method-wrapper '__getattribute__' of A object at 0x7fc8af29e090> returned a result with an exception set
Traceback (most recent call last):
File "/home/ubuntu/django-main/tests/../a.py", line 17, in <module>
A().foo
File "/home/ubuntu/django-main/tests/../a.py", line 9, in __getattr__
if self.bar == 0:
^^^^^^^^
File "/home/ubuntu/django-main/tests/../a.py", line 9, in __getattr__
if self.bar == 0:
^^^^^^^^
File "/home/ubuntu/django-main/tests/../a.py", line 9, in __getattr__
if self.bar == 0:
^^^^^^^^
[Previous line repeated 71 more times]
File "/home/ubuntu/django-main/tests/../a.py", line 10, in __getattr__
raise ValueError
ValueError More precuriously, when I try to add some debug lines like this: class A:
def __init__(self) -> None:
self.bar = 0
def __getattribute__(self, name):
return super().__getattribute__(name)
def __getattr__(self, name):
print(name) ######### <----------- Here
if self.bar == 0:
raise ValueError
@property
def foo(self):
return self.__getattr__("foo")
A().foo The new python outputs, foo
Traceback (most recent call last):
File "/home/ubuntu/django-main/tests/../a.py", line 18, in <module>
A().foo
File "/home/ubuntu/django-main/tests/../a.py", line 9, in __getattr__
print(name)
File "/home/ubuntu/django-main/tests/../a.py", line 6, in __getattribute__
return super().__getattribute__(name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/django-main/tests/../a.py", line 15, in foo
return self.__getattr__("foo")
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/django-main/tests/../a.py", line 11, in __getattr__
raise ValueError
ValueError Everything just works fine? Looks like something in C is corrupting ❓ ❓ ❓ |
Now with foo
python: Python/ceval.c:821: _PyEval_EvalFrameDefault: Assertion `!_PyErr_Occurred(tstate)' failed.
Aborted (core dumped) I can confirm, for this minimum repo, crash starts at aa0a73d |
…ythonGH-103336) (cherry picked from commit 5d7d86f) Co-authored-by: sunmy2019 <[email protected]>
(cherry picked from commit 5d7d86f) Co-authored-by: sunmy2019 <[email protected]>
Thanks for the report and for narrowing this down! The change that regressed this has been reverted and we've added a regression test, so I think this can be closed |
WHEW, hi all, been bisecting all day (including getting better at bisecting large C code bases) to get here. SQLAlchemy has been having failures on this in 3.12.0a7 and seem to be good in 3.12.0b1, just wanted to make sure this was logged. FTR, here's our test case: import sys
class Thing:
@property
def comparator(self):
raise TypeError("a type error")
def __getattr__(self, name):
return getattr(self.comparator, name)
t1 = Thing()
try:
t1.comparator
except TypeError:
print("got typeerror as expected") with the bug it throws a RecursionError |
I have confirmed that version 3.12.0a7 was released on April 4th and the bug does exist in this version. However, the bug has been fixed in version 3.12.0b1. Therefore, it is highly likely that your error is related to this issue. |
It is. Test coverage is added in #103272 |
Bug report
We're hitting
RecursionError: maximum recursion depth exceeded
in Django test suite with Python 3.12.0a7 when accessing an attribute with a custom__getattr__()
method:See affected test and
LazySettings.__getattr__()
.Bisected to the aa0a73d.
I'd try to prepare a small regression test.
Your environment
Linked PRs
The text was updated successfully, but these errors were encountered: