Closed
Description
The title is probably not fully accurate, but I'm unable to fully intuit what's going on.
Crash Report
I'm using a TypeGuard to narrow the type of a variable from a more general one (not Any). If I add a branch like if not guard(var): var = ...
there's an AssertionError.
I suspect something weird happens to the type of the variable after the failed type guard.
Traceback
test4.py:10: error: INTERNAL ERROR -- Please try using mypy master on Github:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 0.910+dev.7f54bd064399ee4e38586c311a2796ff3f255276
Traceback (most recent call last):
File "/Users/patrick/.local/venvs/fellow/bin/mypy", line 8, in <module>
sys.exit(console_entry())
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/__main__.py", line 11, in console_entry
main(None, sys.stdout, sys.stderr)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/main.py", line 103, in main
res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/build.py", line 179, in build
result = _build(
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/build.py", line 254, in _build
graph = dispatch(sources, manager, stdout)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/build.py", line 2696, in dispatch
process_graph(graph, manager)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/build.py", line 3020, in process_graph
process_stale_scc(graph, scc, manager)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/build.py", line 3118, in process_stale_scc
graph[id].type_check_first_pass()
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/build.py", line 2165, in type_check_first_pass
self.type_checker().check_first_pass()
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/checker.py", line 294, in check_first_pass
self.accept(d)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/checker.py", line 401, in accept
stmt.accept(self)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/nodes.py", line 1208, in accept
return visitor.visit_if_stmt(self)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/checker.py", line 3276, in visit_if_stmt
self.accept(s.else_body)
File "/Users/patrick/.asdf/installs/python/3.8.8/lib/python3.8/contextlib.py", line 120, in __exit__
next(self.gen)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/binder.py", line 407, in frame_context
self.pop_frame(can_skip, fall_through)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/binder.py", line 229, in pop_frame
self.last_pop_changed = self.update_from_options(options)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/binder.py", line 205, in update_from_options
type = join_simple(self.declarations[key], type, other)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/join.py", line 142, in join_simple
value = t.accept(TypeJoinVisitor(s))
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/types.py", line 290, in accept
return visitor.visit_type_guard_type(self)
File "/Users/patrick/.local/venvs/fellow/lib/python3.8/site-packages/mypy/join.py", line 436, in visit_type_guard_type
assert False, "This should be never called, got {}".format(t)
AssertionError: This should be never called, got TypeGuard(test4.B)
test4.py:10: : note: use --pdb to drop into pdb
To Reproduce
Here's a repro:
from typing_extensions import TypeGuard
class A: pass
class B(A): pass
def guard(a: A) -> TypeGuard[B]:
pass
a = A()
if not guard(a):
a = A()
Note that the same error occurs if B
is not a subclass of A
, but then the code doesn't really make any sense.
Your Environment
- Mypy version used: 0.902 and latest master
- Mypy command-line flags:
--show-traceback --config-file=empty.ini
- Mypy configuration options from
mypy.ini
(and other config files): none (just the[mypy]
header) - Python version used: 3.8.8
- Operating system and version: macOS 11.2.3 (20D91)
For what it's worth, the actual code where I encountered the issue looks more like this:
class PayloadA(TypedDict):
type: Literal["A"]
class PayloadB(TypedDict):
type: Literal["B"]
...
Payload = Union[PayloadA, PayloadB]
def is_payload(raw_msg: Mapping[str, Any]) -> TypeGuard[Payload]:
...
class Client:
...
def next_payload(self) -> Payload:
msg = json.loads(self._next_payload())
while not is_payload(msg):
msg = json.loads(self._next_payload())
return msg