You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I encountered one condition where calling get_type_hints causes infinite recursion when dealing with forward declaration and cyclic types.
Here's an example:
from typing import Union, List, get_type_hints
ValueList = List['Value']
Value = Union[str, ValueList]
class A:
a: List[Value]
get_type_hints(A, globals(), locals())
This reaches the recursion limit as of 3.8.0b2.
It seems that the combining _GenericAlias with ForwardRef is what triggers this condition:
ForwardRef._evaluate sets __forward_value__ on its first call on a given instance
_GenericAlias tries to compare its args post evaluation
If one of the arguments is a previously evaluated forward reference containing a cycle, then it will infinitely recurse in the hash function when building a frozen set for the comparison.
The above is, of course, a very artificial example, but I can imagine this happening a lot in code with trees or similar structures.
My initial reproduction case was using _eval_type to resolve forward references returned by get_args (side note: it would be nice to have a public function to do that).
Thanks for reporting! This looks like something worth fixing soon. Also this tracker is now used for the backport module on PyPI, could you please open an issue on the main https://bugs.python.org tracker?
Will the patch from python/cpython#15400 be applied here as suggested by @ilevkivskyi? The fix was merged 2019-09-13 however this issue still plagues get_type_hints in python 3.6 and 3.7. It also may not be possible without backporting the fix to cpython 3.6 and 3.7.
@gvanrossum Thanks for the quick reply. The patch requires modifying __eq__ and __hash__ in ForwardRef. I now realize, as I'm using python 3.7, a patch to _ForwardRef in src/typing.py here won't help me. I'll have to make a backport PR to python/cpython.
Since I resurrected this thread anyway, I'll go ahead and make a PR here with the patch anyway.
Backporting this here will not really help with 3.7, as stdlib module takes preference over installed one. Essentially this repo is now mostly about Python 2.
Yeah that's the conclusion I came to. I figured since I brought it up I may as well help people with python <3.5 who may run into this, so I'll make a PR here as well. I went ahead and made python/cpython#18751 to address my issue.
Activity
ilevkivskyi commentedon Aug 9, 2019
Thanks for reporting! This looks like something worth fixing soon. Also this tracker is now used for the backport module on PyPI, could you please open an issue on the main https://bugs.python.org tracker?
ilevkivskyi commentedon Aug 9, 2019
(when opening the issue please don't forget to mention it here)
vg0377467 commentedon Aug 10, 2019
I opened an issue on the main tracker:
https://bugs.python.org/issue37806
rfrowe commentedon Mar 2, 2020
Will the patch from python/cpython#15400 be applied here as suggested by @ilevkivskyi? The fix was merged 2019-09-13 however this issue still plagues
get_type_hintsin python 3.6 and 3.7. It also may not be possible without backporting the fix to cpython 3.6 and 3.7.gvanrossum commentedon Mar 2, 2020
Perhaps you can speed it along by opening a PR against this repo containing the patch you link to?
rfrowe commentedon Mar 2, 2020
@gvanrossum Thanks for the quick reply. The patch requires modifying
__eq__and__hash__inForwardRef. I now realize, as I'm using python 3.7, a patch to_ForwardRefinsrc/typing.pyhere won't help me. I'll have to make a backport PR topython/cpython.Since I resurrected this thread anyway, I'll go ahead and make a PR here with the patch anyway.
ilevkivskyi commentedon Mar 2, 2020
Backporting this here will not really help with 3.7, as stdlib module takes preference over installed one. Essentially this repo is now mostly about Python 2.
rfrowe commentedon Mar 2, 2020
Yeah that's the conclusion I came to. I figured since I brought it up I may as well help people with python <3.5 who may run into this, so I'll make a PR here as well. I went ahead and made python/cpython#18751 to address my issue.