Skip to content

AssertionError when using reveal_type on a class-bound ParamSpec. #19839

Description

@JBushagour

Crash Report

The following code triggers an AssertionError internally in mypy:

from collections.abc import Callable
from typing import reveal_type


class Sneaky[**P]:
    def __init__(self, fn: Callable[P, object], *args: P.args, **kwargs: P.kwargs) -> None:
        self.args = args
        self.kwargs = kwargs


def identity(x: int) -> int:
    return x

reveal_type(Sneaky(identity, 1).args)

Traceback

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/__main__.py", line 37, in <module>
    console_entry()
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/__main__.py", line 15, in console_entry
    main()
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/main.py", line 127, in main
    res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/main.py", line 211, in run_build
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 197, in build
    result = _build(
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 273, in _build
    graph = dispatch(sources, manager, stdout)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 2970, in dispatch
    process_graph(graph, manager)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 3403, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 3504, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 2344, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checker.py", line 524, in check_first_pass
    self.accept(d)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checker.py", line 635, in accept
    stmt.accept(self)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/nodes.py", line 1562, in accept
    return visitor.visit_expression_stmt(self)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checker.py", line 4842, in visit_expression_stmt
    expr_type = self.expr_checker.accept(s.expr, allow_none_return=True, always_allow_any=True)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkexpr.py", line 6020, in accept
    typ = self.visit_call_expr(node, allow_none_return=True)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkexpr.py", line 493, in visit_call_expr
    return self.accept(e.analyzed, self.type_context[-1])
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkexpr.py", line 6048, in accept
    typ = node.accept(self)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/nodes.py", line 2520, in accept
    return visitor.visit_reveal_expr(self)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkexpr.py", line 4723, in visit_reveal_expr
    revealed_type = self.accept(
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkexpr.py", line 6048, in accept
    typ = node.accept(self)
          ^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/nodes.py", line 2175, in accept
    return visitor.visit_member_expr(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkexpr.py", line 3315, in visit_member_expr
    result = self.analyze_ordinary_member_access(e, is_lvalue)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkexpr.py", line 3345, in analyze_ordinary_member_access
    member_type = analyze_member_access(
                  ^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkmember.py", line 227, in analyze_member_access
    result = _analyze_member_access(name, typ, mx, override_info)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkmember.py", line 244, in _analyze_member_access
    return analyze_instance_member_access(name, typ, mx, override_info)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkmember.py", line 386, in analyze_instance_member_access
    return analyze_member_var_access(name, typ, info, mx)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkmember.py", line 570, in analyze_member_var_access
    return analyze_var(name, v, itype, mx, implicit=implicit, is_trivial_self=is_trivial_self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkmember.py", line 888, in analyze_var
    result = expand_without_binding(typ, var, itype, original_itype, mx)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/checkmember.py", line 955, in expand_without_binding
    expanded = expand_type_by_instance(typ, itype)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/expandtype.py", line 115, in expand_type_by_instance
    return expand_type(typ, variables)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/expandtype.py", line 70, in expand_type
    return typ.accept(ExpandTypeVisitor(env))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/types.py", line 823, in accept
    return visitor.visit_param_spec(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/expandtype.py", line 273, in visit_param_spec
    assert t.flavor == ParamSpecFlavor.BARE
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 
main.py:14: 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.19.0+dev.9ae3e9aa160c11b99960f12eef111e4a3197b7d3
main.py:14: : note: use --pdb to drop into pdb

To Reproduce

The above code should be sufficient; here's a mypy-play link for convenience.

AFAICT it's reproducible across all versions of mypy that support PEP 695 generics, including versions that require --enable-incomplete-feature=NewGenericSyntax (1.11.0 and up). Something of note is that mypy doesn't trigger the assertion if we define the ParamSpec explicitly with P = ParamSpec("P") (mypy-play link).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions