Serhiy Storchaka <storchaka+cpyt...@gmail.com> added the comment:

Interesting, when lookup any attribute you will get a RecursionError, but this 
is one of only two places where the recursion check is disabled (the other one 
is in interning strings).

You get a crash also when call isinstance(1, instance) or issubclass(int, 
instance). This is the same bug.

The implementation of issubclass() calls PyObject_IsSubclass() which calls 
object_issubclass() which calls recursive_issubclass() which calls 
check_class() which calls abstract_get_bases() which looks up attribute 
"__bases__" which leads to infinite recursion in __getattr__().

#125278 0x000055555576116d in abstract_get_bases (cls=cls@entry=0x7fffeabcee10) 
at Objects/abstract.c:2340
#125279 0x00005555557611f1 in check_class (cls=cls@entry=0x7fffeabcee10, 
error=error@entry=0x55555585c828 "issubclass() arg 1 must be a class") at 
Objects/abstract.c:2396
#125280 0x00005555557619bf in recursive_issubclass 
(derived=derived@entry=0x7fffeabcee10, cls=cls@entry=0x555555946220 
<PyLong_Type>) at Objects/abstract.c:2524
#125281 0x0000555555761daf in object_issubclass (tstate=<optimized out>, 
derived=0x7fffeabcee10, cls=0x555555946220 <PyLong_Type>) at 
Objects/abstract.c:2550
#125282 0x0000555555765ea1 in PyObject_IsSubclass (derived=<optimized out>, 
cls=<optimized out>) at Objects/abstract.c:2600
#125283 0x00005555557b78f3 in builtin_issubclass_impl 
(module=module@entry=0x7fffeae21d70, cls=<optimized out>, 
class_or_tuple=<optimized out>) at Python/bltinmodule.c:2511
#125284 0x00005555557b794d in builtin_issubclass (module=0x7fffeae21d70, 
args=0x7fffead0e388, nargs=<optimized out>) at Python/clinic/bltinmodule.c.h:828

The problem is that in abstract_get_bases() the recursion check is disabled by 
using macros Py_ALLOW_RECURSION/Py_END_ALLOW_RECURSION (added in 
5b222135f8d2492713994f2cb003980e87ce6a72). I do not know why it was necessary. 
Currently tests are passed if enable recursion check, and this fixes this issue.

It is worth to mention that attribute __bases__ is looked up to support 
non-types in issubclass() and isinstance(). Originally it was added in 
issue464992 to support Zope extension ExtensionClass. I tested that the current 
code of ExtensionClass does not need it. So we could simplify the code and 
avoid recursion by just using tp_bases. But this needs wider discussion.

----------
nosy: +gvanrossum, loewis, nascheme, serhiy.storchaka
versions: +Python 3.10, Python 3.8, Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41909>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to