Instagram / MonkeyType

A Python library that generates static type annotations by collecting runtime types
Other
4.74k stars 170 forks source link

RemoveEmptyContainers rewriter can crash with "Cannot take a Union of no types" #53

Closed carljm closed 6 years ago

carljm commented 6 years ago

The end of the traceback looks like:

  File "/.../lib/python3.6/site-packages/monkeytype/typing.py", line 180, in rewrite_Union 
    return Union[elems] 
  File "/.../lib/python3.6/typing.py", line 682, in inner 
    return func(*args, **kwds) 
  File "/.../lib/python3.6/typing.py", line 793, in __getitem__ 
    raise TypeError("Cannot take a Union of no types.") 
TypeError: Cannot take a Union of no types. 

Haven't worked on a repro, but from looking at the code I think it ought to be pretty easy to repro with e.g. a List parameter that is only ever called with an empty list. In this case we should just leave the annotation as List[Any], there's nothing else we can do.

carljm commented 6 years ago

Repro is slightly more complex than I'd thought; Union[List[Any]] simplifies to just List[Any] and never hits this rewriter. So in order to repro you need traces that result in a type like Union[List[Any], Set[Any]]; i.e. a function where some arg is given two different empty container types in different calls. This repros:

mymod.py:

def myfunc(things):
    pass

and myscript.py:

from mymod import myfunc
myfunc([])
myfunc(set())
monkeytype run myscript.py
monkeytype stub mymod