Issue5508
Created on 2009-03-18 15:25 by gangesmaster, last changed 2009-04-05 14:38 by georg.brandl.
| Messages (3) | |||
|---|---|---|---|
| msg83752 - (view) | Author: ganges master (gangesmaster) | Date: 2009-03-18 15:25 | |
this is similar to bug #5370, but this for is a different reason. also, i have seen several sites on google that mention it, so it has happened to quite a few people. the bug is that when calling dir() on a object, it looks for __members__ and __methods__, which might not exist, thus invoking __getattr__ (if it exists). if __getattr__ fails, say, due to a never ending recusion, the exception is silently swallowed. this was the behavior in py2.5. since 2.6, it emits a warning (that looks like PyErr_WriteUnraisable) with the strangest message: Exception RuntimeError: 'maximum recursion depth exceeded in __subclasscheck__' in <type 'exceptions.AttributeError'> ignored this is very confusing. either dir() raises this exception, or silently ignore it, but displaying this message is only confusing. i haven't been able to detect why this happens: * the source of this exception, merge_list_attr, calls PyErr_Clear * nobody seems to call PyErr_WriteUnraisable here's a snippet: class Foo(object): def __getattr__(self, name): return self.x # which will recursively call __getattr__ >>> f = Foo() >>> print dir(f) Exception RuntimeError: 'maximum recursion depth exceeded in __subclasscheck__' in <type 'exceptions.AttributeError'> ignored Exception RuntimeError: 'maximum recursion depth exceeded in __subclasscheck__' in <type 'exceptions.AttributeError'> ignored ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] |
|||
| msg83764 - (view) | Author: Antoine Pitrou (pitrou) | Date: 2009-03-18 17:27 | |
Here is the reason. Starting from Python 2.6, classes can redefine subclass checking using a special method named __subclasscheck__. Since this method can contain arbitrary code, we have to guard against recursion when calling it. Therefore, the recursion count is incremented before doing a subclass checking. Now the problem is that when checking for an exception, we do exactly that: check whether the raised exception is a subclass of a given type. If the raised exception occurred just after a recursion overflow, it can happen that subclass checking overflows the recursion count again. However, since we don't want the newly raised exception (during exception subclass checking) to overwrite the original one, so we just write out it (using PyErr_WriteUnraisable, precisely) and then discard it. That's where these strange messages come from. (note: py3k has a slightly different recursion checking mechanism and doesn't print such messages) |
|||
| msg85502 - (view) | Author: Georg Brandl (georg.brandl) | Date: 2009-04-05 14:38 | |
The messages are now suppressed by the temporary bump of the recursion limit in PyErr_GivenExceptionMatches. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2009-04-05 14:38:22 | georg.brandl | set | status: open -> closed resolution: out of date messages: + msg85502 |
| 2009-03-18 17:27:52 | pitrou | set | nosy:
+ amaury.forgeotdarc, loewis, pitrou messages: + msg83764 |
| 2009-03-18 15:25:48 | gangesmaster | create | |