-
Notifications
You must be signed in to change notification settings - Fork 237
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
Infinite recursion in isinstance check #582
Comments
Potentially related to #562, though doesn't look to necessarily be happening in the same part of the code, so not sure |
Thanks for reporting! This looks like a bizarre bug (also you have made a great analysis). Have you tried replacing the |
The problem persists with Wondering if there is some form of monkeypatching going on, but have as yet been unable to pin down where that would be happening. |
Another idea is just to add a debugging print to see what is |
I'll get back to actively debugging when I get the chance. I was able to (crudely) fix the problem by doing string comparison on |
We have similar issue in our project (running Python 2.7.15) when there is more than 1 instance of This allows me to find a very simple way to reproduce a bug. You just need to import a library twice, and two versions will fight against each other: $ cp python2/typing.py python2/typing2.py
$ cat reproduce.py
import typing
import typing2
from collections import Mapping
assert isinstance(1, Mapping) is False
$ PYTHONPATH=python2 reproduce.py
Traceback (most recent call last):
File "reproduce.py", line 4, in <module>
assert isinstance(1, Mapping) is False
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 144, in __instancecheck__
return cls.__subclasscheck__(subtype)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 180, in __subclasscheck__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 180, in __subclasscheck__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/python2/typing.py", line 982, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing2.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/python2/typing2.py", line 982, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/python2/typing.py", line 982, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing2.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/python2/typing2.py", line 982, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
...
File "/home/ahitrin/src/typing/python2/typing2.py", line 982, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/python2/typing.py", line 982, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing2.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/python2/typing2.py", line 982, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/python2/typing.py", line 982, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing2.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 161, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/python2/typing2.py", line 982, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/python2/typing.py", line 1250, in __subclasscheck__
return super(GenericMeta, self).__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.env/lib/python2.7/abc.py", line 151, in __subclasscheck__
if subclass in cls._abc_cache:
RuntimeError: maximum recursion depth exceeded while calling a Python object This script works both for py2 and py3 versions (at least on 3.6). The similar stack trace for Py3: $ PYTHONPATH=src .3env/bin/python reproduce.py
Traceback (most recent call last):
File "reproduce.py", line 4, in <module>
assert isinstance(1, Mapping) is False
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 193, in __instancecheck__
return cls.__subclasscheck__(subclass)
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 228, in __subclasscheck__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 228, in __subclasscheck__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 228, in __subclasscheck__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/src/typing.py", line 1155, in __subclasscheck__
return super().__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 209, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/src/typing.py", line 885, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/src/typing2.py", line 1155, in __subclasscheck__
return super().__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 209, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/src/typing2.py", line 885, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/src/typing.py", line 1155, in __subclasscheck__
return super().__subclasscheck__(cls)
...
File "/home/ahitrin/src/typing/src/typing2.py", line 885, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/src/typing.py", line 1155, in __subclasscheck__
return super().__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 209, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/src/typing.py", line 885, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/src/typing2.py", line 1155, in __subclasscheck__
return super().__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 209, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/src/typing2.py", line 885, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/src/typing.py", line 1155, in __subclasscheck__
return super().__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 209, in __subclasscheck__
ok = cls.__subclasshook__(subclass)
File "/home/ahitrin/src/typing/src/typing.py", line 885, in __extrahook__
if issubclass(subclass, scls):
File "/home/ahitrin/src/typing/src/typing2.py", line 1155, in __subclasscheck__
return super().__subclasscheck__(cls)
File "/home/ahitrin/src/typing/.3env/lib/python3.6/abc.py", line 199, in __subclasscheck__
if subclass in cls._abc_cache:
File "/home/ahitrin/src/typing/.3env/lib/python3.6/_weakrefset.py", line 72, in __contains__
wr = ref(item)
RecursionError: maximum recursion depth exceeded while calling a Python object |
Great, thanks! I just tried and this is fixed in Python 3.7. I think I understand the cause of the crash, the problem is that there are two instances of |
As the |
Is there anything one could do to prevent this situation from happening? |
A repo that reproduces this issue (with CI checks running) can be found at ksunden/typing_recursion
This appears to be a resurgence of #503 / #501, but in a very particular set of circumstances:
weakref.finalize
calltyping
is importedpytest
viasetup.py test
The crux of the issue seems to boil down two seemingly identical entries in
cls.__extra__.subclasses__()
(I've seen it as eithertyping.Generator
ortyping.ContextManager
, depending on whatisinstance
check causes it.)However, one of the two entries fails the check
isinstance(scls, GenericMeta)
, despite the fact that it's parent class is, in facttyping.GenericMeta
by any other method of inspection.I'm not actually convinced this is the fault of
typing.py
, could be either setuptools or pytest or even weakref, but the issue has been seen in this repo before, so starting here.Note that the issue presents after CI checks pass, so particularly hard to test for properly.
Particularly relevant lines of code:
https://github.com/python/typing/blob/master/src/typing.py#L882-L885
The text was updated successfully, but these errors were encountered: