Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on assigning to guarded variable in failed TypeGuard branch #10665

Closed
p7g opened this issue Jun 17, 2021 · 1 comment
Closed

Crash on assigning to guarded variable in failed TypeGuard branch #10665

p7g opened this issue Jun 17, 2021 · 1 comment
Labels

Comments

@p7g
Copy link

p7g commented Jun 17, 2021

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
@A5rocks
Copy link
Contributor

A5rocks commented Jun 22, 2021

This seems to have been fixed in mypy master branch (by #10683), though this might want to stay open as that solution is described as a "hacky" fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants