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

Binding a name that is used before but now out of scope in a pattern match breaks mypy #16793

Open
Luis-omega opened this issue Jan 18, 2024 · 0 comments
Labels
crash topic-match-statement Python 3.10's match statement

Comments

@Luis-omega
Copy link

If you already used a name like value to define something in a branch of a match, like a function def value()... and by some reason you use the same name as a binding in another branch of the match case Some(value), then I guess that value is lookup for it's previous value (a function) instead of making a new fresh variable for it, this broke an assertion.


some.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: 1.9.0+dev.75b68fa2c0d32bd08b98b00aece20c22d82b1b15
Traceback (most recent call last):
  File "projects/mal/impls/python.3/.env/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
  File "projects/mypy/mypy/__main__.py", line 15, in console_entry
    main()
  File "projects/mypy/mypy/main.py", line 100, in main
    res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
  File "projects/mypy/mypy/main.py", line 182, in run_build
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "projects/mypy/mypy/build.py", line 191, in build
    result = _build(
  File "projects/mypy/mypy/build.py", line 265, in _build
    graph = dispatch(sources, manager, stdout)
  File "projects/mypy/mypy/build.py", line 2941, in dispatch
    process_graph(graph, manager)
  File "projects/mypy/mypy/build.py", line 3339, in process_graph
    process_stale_scc(graph, scc, manager)
  File "projects/mypy/mypy/build.py", line 3440, in process_stale_scc
    graph[id].type_check_first_pass()
  File "projects/mypy/mypy/build.py", line 2309, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "projects/mypy/mypy/checker.py", line 481, in check_first_pass
    self.accept(d)
  File "projects/mypy/mypy/checker.py", line 591, in accept
    stmt.accept(self)
  File "projects/mypy/mypy/nodes.py", line 787, in accept
    return visitor.visit_func_def(self)
  File "projects/mypy/mypy/checker.py", line 1001, in visit_func_def
    self._visit_func_def(defn)
  File "projects/mypy/mypy/checker.py", line 1005, in _visit_func_def
    self.check_func_item(defn, name=defn.name)
  File "projects/mypy/mypy/checker.py", line 1078, in check_func_item
    self.check_func_def(defn, typ, name, allow_empty)
  File "projects/mypy/mypy/checker.py", line 1294, in check_func_def
    self.accept(item.body)
  File "projects/mypy/mypy/checker.py", line 591, in accept
    stmt.accept(self)
  File "projects/mypy/mypy/nodes.py", line 1223, in accept
    return visitor.visit_block(self)
  File "projects/mypy/mypy/checker.py", line 2771, in visit_block
    self.accept(s)
  File "projects/mypy/mypy/checker.py", line 591, in accept
    stmt.accept(self)
  File "projects/mypy/mypy/nodes.py", line 1607, in accept
    return visitor.visit_match_stmt(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "projects/mypy/mypy/checker.py", line 5063, in visit_match_stmt
    inferred_types = self.infer_variable_types_from_type_maps(type_maps)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "projects/mypy/mypy/checker.py", line 5127, in infer_variable_types_from_type_maps
    assert isinstance(node, Var)
AssertionError: 
some.py:10: : note: use --pdb to drop into pdb

I was able to reduce the crash to this file:

from dataclasses import dataclass

@dataclass
class Some:
    value: int | "Some"

def some(x: Some):
    match x:
        case int():

            def value():
                return 1

        case Some(value):
            pass

I put a print in the function handling the match and got:

  NameExpr(x [l])
  Pattern(
    ClassPattern:11(
      NameExpr(int [builtins.int])))
  Body(
    FuncDef:13(
      value
      Block:14(
        ReturnStmt:14(
          IntExpr(1)))))
  Pattern(
    ClassPattern:16(
      NameExpr(Some [some.Some])
      Positionals(
        AsPattern:16(
          NameExpr(value [l])))))
  Body(
    PassStmt:17()))

The particular source of the crash is the

AsPattern:16(
          NameExpr(value [l])))))

A print of the value that breaks the assert just before breaking:

FuncDef:13(
  value
  Block:14(
    ReturnStmt:14(
      IntExpr(1))))
FuncDef:13(
  value
  Block:14(
    ReturnStmt:14(
      IntExpr(1))))
  • Mypy version used: both 1.7.something and 1.9.0+dev.75b68fa2c0d32bd08b98b00aece20c22d82b1b15
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.11.6
  • Operating system and version: Archlinux
@JelleZijlstra JelleZijlstra added the topic-match-statement Python 3.10's match statement label Jan 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crash topic-match-statement Python 3.10's match statement
Projects
None yet
Development

No branches or pull requests

2 participants