Handling of (potentially mutating) method calls on NewType
`NewType` is great for making API code more type safe while not introducing runtime wrappers. Take for example ``` from typing import NewType, List NonEmptyList = NewType('NonEmptyList', List) def prove_list_is_not_empty(seq: List) -> NonEmptyList: if len(seq) > 0: return NonEmptyList(seq) else: raise ValueError('Sequence is empty') def foo(seq: NonEmptyList) -> NoReturn: pass # api function that will explode when passed an empty list ``` Test cases: ``` a = [1, 2, 3] b = prove_list_is_not_empty(a) c = b + a d = b d.pop() # when using pylint it complains that d has no member 'pop' ``` Results: ``` foo(b) # accepted foo(a) # rejected foo(c) # rejected foo(d) # accepted, though see what pylint does for the use-case above ``` In the results above `foo(c)` is rejected by mypy because `reveal_type(c)` is `List[Any]` which I think is good behavior, however `reveal_type(d)` is still `NonEmptyList`. Obviously mypy can't know that `d.pop` is dangerous here (and `d.append(1)` would be fine). Would it be possible (and desirable) for mypy to *downgrade* `d` back to `List[Any]` for all method calls?
participants (1)
-
sascha.schlemmer@me.com