Skip to content

TypeGuard should not appear here #10647

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

Closed
dfroger opened this issue Jun 15, 2021 · 1 comment · Fixed by #11061
Closed

TypeGuard should not appear here #10647

dfroger opened this issue Jun 15, 2021 · 1 comment · Fixed by #11061
Labels

Comments

@dfroger
Copy link
Contributor

dfroger commented Jun 15, 2021

Crash Report

Get a crash with RuntimeError: TypeGuard should not appear here. A source code to reproduce it is included bellow.

Traceback

$ mypy --show-traceback foo.py 
foo.py:26: 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.9d92fbaab4d1c18991d71517a9981900ae60db25
Traceback (most recent call last):
  File "/home/david/mypy-master/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/__main__.py", line 11, in console_entry
    main(None, sys.stdout, sys.stderr)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/main.py", line 103, in main
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/build.py", line 180, in build
    sources, options, alt_lib_path, flush_errors, fscache, stdout, stderr, extra_plugins
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/build.py", line 254, in _build
    graph = dispatch(sources, manager, stdout)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/build.py", line 2696, in dispatch
    process_graph(graph, manager)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/build.py", line 3020, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/build.py", line 3118, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/build.py", line 2165, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 294, in check_first_pass
    self.accept(d)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 401, in accept
    stmt.accept(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/nodes.py", line 689, in accept
    return visitor.visit_func_def(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 726, in visit_func_def
    self._visit_func_def(defn)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 730, in _visit_func_def
    self.check_func_item(defn, name=defn.name)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 792, in check_func_item
    self.check_func_def(defn, typ, name)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 975, in check_func_def
    self.accept(item.body)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 401, in accept
    stmt.accept(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/nodes.py", line 1017, in accept
    return visitor.visit_block(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 1984, in visit_block
    self.accept(s)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 401, in accept
    stmt.accept(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/nodes.py", line 1153, in accept
    return visitor.visit_return_stmt(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 3169, in visit_return_stmt
    self.check_return_stmt(s)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checker.py", line 3202, in check_return_stmt
    s.expr, return_type, allow_none_return=allow_none_func_call))
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checkexpr.py", line 3903, in accept
    typ = node.accept(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/nodes.py", line 1961, in accept
    return visitor.visit_list_comprehension(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checkexpr.py", line 3719, in visit_list_comprehension
    e.generator, 'builtins.list', '<list-comprehension>')
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checkexpr.py", line 3761, in check_generator_or_comprehension
    [gen.left_expr], [nodes.ARG_POS], gen)[0]
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checkexpr.py", line 920, in check_call
    object_type)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checkexpr.py", line 1016, in check_callable_call
    messages=arg_messages, object_type=object_type)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checkexpr.py", line 1485, in check_argument_types
    actual + 1, i + 1, callee, object_type, args[actual], context, messages)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/checkexpr.py", line 1513, in check_arg
    elif not is_subtype(caller_type, callee_type):
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/subtypes.py", line 97, in is_subtype
    ignore_promotions=ignore_promotions)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/subtypes.py", line 151, in _is_subtype
    ignore_promotions=ignore_promotions))
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/types.py", line 1790, in accept
    return visitor.visit_union_type(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/subtypes.py", line 476, in visit_union_type
    return all(self._is_subtype(item, self.orig_right) for item in left.items)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/subtypes.py", line 476, in <genexpr>
    return all(self._is_subtype(item, self.orig_right) for item in left.items)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/subtypes.py", line 209, in _is_subtype
    ignore_promotions=self.ignore_promotions)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/subtypes.py", line 97, in is_subtype
    ignore_promotions=ignore_promotions)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/subtypes.py", line 151, in _is_subtype
    ignore_promotions=ignore_promotions))
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/types.py", line 290, in accept
    return visitor.visit_type_guard_type(self)
  File "/home/david/mypy-master/lib/python3.7/site-packages/mypy/subtypes.py", line 479, in visit_type_guard_type
    raise RuntimeError("TypeGuard should not appear here")
RuntimeError: TypeGuard should not appear here
foo.py:26: : note: use --pdb to drop into pdb

To Reproduce

from typing import Any, List
from typing_extensions import TypeGuard


class Base:
    ...


class Foo(Base):
    ...


class Bar(Base):
    ...


def is_foo(item: Any) -> TypeGuard[Foo]:
    return isinstance(item, Foo)


def is_bar(item: Any) -> TypeGuard[Bar]:
    return isinstance(item, Bar)


def foobar(items: List[Any]) -> List[Base]:
    return [x for x in items if is_foo(x) or is_bar(x)]

Your Environment

  • Mypy version used: 0.910+dev.9d92fbaab4d1c18991d71517a9981900ae60db25
  • Mypy command-line flags: mypy --show-traceback foo.py
  • Mypy configuration options from mypy.ini (and other config files): no config file
  • Python version used: 3.7.10
  • Operating system and version: Linux Mint 20.1 Ulyssa
@dfroger dfroger added the crash label Jun 15, 2021
@hauntsaninja
Copy link
Collaborator

cc @JelleZijlstra

hauntsaninja added a commit that referenced this issue Sep 14, 2021
Fixes #11007, fixes #10899, fixes #10647

Since the initial implementation of TypeGuard, there have been several fixes quickly applied to make mypy not crash on various TypeGuard things. This includes #10496, #10683 and #11015. We'll discuss how this PR relates to each of these three changes.

In particular, #10496 seems incorrect. As A5rocks discusses in #10899 , it introduces confusion between a type guarded variable and a TypeGuard[T]. This PR basically walks back that change entirely and renames TypeGuardType to TypeGuardedType to reduce that possible confusion.

Now, we still have the issue that TypeGuardedTypes are getting everywhere and causing unhappiness. I see two high level solutions to this:
a) Make TypeGuardedType a proper type, then delegate to the wrapped type in a bunch of type visitors and arbitrary amounts of other places where multiple types interact, and hope that we got all of them,
b) Make TypeGuardedType as an improper type (as it was in the original implementation)! Similar to TypeAliasType, it's just a wrapper for another type, so we unwrap it in get_proper_type. This is the approach this PR takes. This might feel controversial, but I think it could be the better option. It also means that if we type check we won't get type guard crashes.

#10683 is basically "remove call that leads to crash from the stacktrace". I think the join here (that ends up being with the wrapped type of the TypeGuardedType) is actually fine: if it's different, it tells us that the type changed, which is what we want to know. So seems fine to remove the special casing.

Finally, #11015. This is the other contentious part of this PR. I liked the idea of moving the core "type guard overrides narrowing" idea into meet.py, so I kept that. But my changes ended up regressing a reveal_type testTypeGuardNestedRestrictionAny test that was added. But it's not really clear to me how that worked or really, what it tested. I tried writing a simpler version of what I thought the test was meant to test (this is testTypeGuardMultipleCondition added in this PR), but that fails on master.

Anyway, this should at least fix the type guard crashes that have been coming up.
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.

2 participants