Repository navigation
segfault on recursive type #6730
Copy link
Copy link
Closed
Description
I'm running mypy 0.701 on Python 3.7.2 on Linux, with the following input:
from typing import Any, Generic, Iterable, TypeVar, Union
ValueT = TypeVar('ValueT')
class Recursive(Iterable[Union[ValueT, 'Recursive[ValueT]']]):
pass
class Base(Generic[ValueT]):
def __init__(self, element: ValueT):
pass
class Sub(Base[Union[ValueT, Recursive[ValueT]]]):
pass
x: Iterable[str]
print(Sub(x))I ran mypy under gdb to get a stack trace, but the stack trace is over 70,000 frames long (the point at which I aborted its listing), so I don't think including the full thing would be feasible or useful.
It looks like the following pattern is repeated over and over:
#70084 0x00007ffff5f0d32f in CPyDef_types_accept_Instance (cpy_r_self=0x0, cpy_r_visitor=<optimized out>) at build/__native.c:1601677
#70085 0x00007ffff5db4b84 in CPyDef_subtypes_is_proper_subtype (cpy_r_left=0x7fffe766a6d8, cpy_r_right=<optimized out>, cpy_r_ignore_promotions=<optimized out>) at build/__native.c:1474319
#70086 0x00007ffff5d79820 in CPyDef_types_make_simplified_union_UnionType (cpy_r_items=<optimized out>, cpy_r_line=<optimized out>, cpy_r_column=<optimized out>) at build/__native.c:1626562
#70087 0x00007ffff5f26ccd in CPyDef_expandtype_visit_union_type_ExpandTypeVisitor (cpy_r_self=<optimized out>, cpy_r_t=0x7fffe8294f48) at build/__native.c:388697
#70088 0x00007ffff5f26e06 in CPyDef_expandtype_visit_union_type__TypeVisitor_glue_ExpandTypeVisitor (cpy_r_self=0x8af200 <PyDict_Type>, cpy_r_t=0x7ffff6ccec00) at build/__native.c:388750
#70089 0x00007ffff65bac5f in CPyDef_types_accept_UnionType (cpy_r_self=0x0, cpy_r_visitor=<optimized out>) at build/__native.c:1626978
#70090 0x00007ffff5f24be7 in CPyDef_expandtype_expand_types_ExpandTypeVisitor (cpy_r_self=0x7fffe76e5870, cpy_r_types=<optimized out>) at build/__native.c:389037
#70091 0x00007ffff5f2481f in CPyDef_expandtype_visit_instance_ExpandTypeVisitor (cpy_r_self=0x7fffe76e5870, cpy_r_t=0x7fffe7d5cf28) at build/__native.c:387615
#70092 0x00007ffff5f24e36 in CPyDef_expandtype_visit_instance__TypeVisitor_glue_ExpandTypeVisitor (cpy_r_self=0x8af200 <PyDict_Type>, cpy_r_t=0x7ffff6ccec00) at build/__native.c:387706
#70093 0x00007ffff5f0d32f in CPyDef_types_accept_Instance (cpy_r_self=0x0, cpy_r_visitor=<optimized out>) at build/__native.c:1601677
#70094 0x00007ffff5c4ef15 in CPyDef_expandtype_expand_type (cpy_r_typ=0x7fffe7d5cf28, cpy_r_env=0x7fffe76e5828) at build/__native.c:386276
#70095 0x00007ffff5ff068b in CPyDef_maptype_map_instance_to_direct_supertypes (cpy_r_instance=0x7fffe766a588, cpy_r_supertype=0x7fffe858b258) at build/__native.c:519519
#70096 0x00007ffff5fef535 in CPyDef_maptype_map_instance_to_supertypes (cpy_r_instance=<optimized out>, cpy_r_supertype=<optimized out>) at build/__native.c:518873
#70097 0x00007ffff5d9d105 in CPyDef_maptype_map_instance_to_supertype (cpy_r_instance=0x7fffe766a588, cpy_r_superclass=0x7fffe858b258) at build/__native.c:518619
#70098 0x00007ffff6509a9c in CPyDef_subtypes_visit_instance_ProperSubtypeVisitor (cpy_r_self=<optimized out>, cpy_r_left=<optimized out>) at build/__native.c:1475884
#70099 0x00007ffff650aff6 in CPyDef_subtypes_visit_instance__TypeVisitor_glue_ProperSubtypeVisitor (cpy_r_self=0x8af200 <PyDict_Type>, cpy_r_t=0x7ffff6ccec00) at build/__native.c:1476491
I guess the compiled part of mypy got into an infinite recursion trying to figure out the recursive type definition and eventually hit a system limit on the native stack size.
Reactions are currently unavailable
Activity
ilevkivskyi commentedon Apr 27, 2019
I confirm this on master. Here is a traceback from the interpreted version, that shows where the problem starts:
There is a loop in the logic:
expand_type -> make_simplified_union -> is_proper_subtype -> map_instance_to_supertype -> expand_type. I am not sure what is the best place to break it, but replacingmake_simplified_unionwithmake_unioncan be a decent quick-fix.JukkaL commentedon Feb 14, 2020
This is still crashing on master.
TH3CHARLie commentedon Feb 14, 2020
I remember I once tried to fix this but replacing
make_simpified_unionwithUnionType.make_unionbreaks several places in mypy's own code, let alone tests.bluetech commentedon Mar 29, 2020
This also crashes with a stack overflow segmentation fault:
A5rocks commentedon Aug 16, 2020
I don't have anything to add, but I ran into this for:
(which I simplified from the actual case I ran into this)
My intuition (without knowing any internals whatsoever) tells me that
mypyis trying to figure out what theTis, as replacingInList[T]withInList[int]prevents a segfault (while also erroring asArgument 1 to "list_thing" has incompatible type "List[int]"; expected "Union[int, InListRecurse[int]]"which means I've typed something wrong but oh well...)Proposal: don't simplify unions in expand_type() (#14178)