Skip to content

Crash when passing too many type arguments to generic base class accepting single ParamSpec #17765

Closed
@brianschubert

Description

@brianschubert

Crash Report

A crash occurs when inheriting from a generic type that expects a single ParamSpec if too many type arguments are passed. The crash appears to only occur in an inheritance context (passing too many arguments in other contexts does not produce a crash) and when the parent type expects only a single ParamSpec (using additional type variables do not produce a crash).

Traceback

v1.11.2 Traceback
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.11.2
Traceback (most recent call last):
  File "mypy/semanal.py", line 7087, in accept
  File "mypy/nodes.py", line 1183, in accept
  File "mypy/semanal.py", line 1700, in visit_class_def
  File "mypy/semanal.py", line 1818, in analyze_class
  File "mypy/semanal.py", line 2112, in clean_up_bases_and_infer_type_variables
  File "mypy/semanal.py", line 7141, in analyze_type_expr
  File "mypy/nodes.py", line 2028, in accept
  File "mypy/semanal.py", line 5802, in visit_index_expr
  File "mypy/semanal.py", line 5808, in analyze_type_application
  File "mypy/semanal.py", line 5910, in analyze_type_application_args
  File "mypy/types.py", line 1634, in __init__
AssertionError: 
master (1.12.0+dev.0c10367) 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 102, 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 186, 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 193, in build
    result = _build(
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 268, in _build
    graph = dispatch(sources, manager, stdout)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 2950, in dispatch
    process_graph(graph, manager)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 3348, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/build.py", line 3443, in process_stale_scc
    mypy.semanal_main.semantic_analysis_for_scc(graph, scc, manager.errors)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal_main.py", line 93, in semantic_analysis_for_scc
    process_top_levels(graph, scc, patches)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal_main.py", line 220, in process_top_levels
    deferred, incomplete, progress = semantic_analyze_target(
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal_main.py", line 351, in semantic_analyze_target
    analyzer.refresh_partial(
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 619, in refresh_partial
    self.refresh_top_level(node)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 630, in refresh_top_level
    self.accept(d)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 7087, in accept
    node.accept(self)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/nodes.py", line 1183, in accept
    return visitor.visit_class_def(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 1700, in visit_class_def
    self.analyze_class(defn)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 1818, in analyze_class
    bases, tvar_defs, is_protocol = self.clean_up_bases_and_infer_type_variables(
                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 2112, in clean_up_bases_and_infer_type_variables
    self.analyze_type_expr(base_expr)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 7141, in analyze_type_expr
    expr.accept(self)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/nodes.py", line 2028, in accept
    return visitor.visit_index_expr(self)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 5802, in visit_index_expr
    self.analyze_type_application(expr)
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 5808, in analyze_type_application
    types = self.analyze_type_application_args(expr)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/semanal.py", line 5910, in analyze_type_application_args
    types = [Parameters(types, [ARG_POS] * len(types), [None] * len(types))]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/layers/google.python.pip/pip/lib/python3.12/site-packages/mypy/types.py", line 1634, in __init__
    assert not any(isinstance(t, Parameters) for t in arg_types)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 

main.py:13: 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.12.0+dev.0c1036717578b00e35625cc353a538e4eb63bc37
main.py:13: : note: use --pdb to drop into pdb

To Reproduce

Reproducers in mypy playground: v1.11.2, master

from typing import ParamSpec, Generic

P = ParamSpec("P")


class FooP(Generic[P]):
    pass


# CRASH - extraneous type parameter
class Bar1(FooP[[int, int], str]):
    pass


# CRASH - extraneous parameter spec
class Bar2(FooP[[int, int], [int, int]]):
    pass

Additionally, the following similar setups fail to reproduce the crash:

Non-reproducers
from typing import TypeVar, ParamSpec, Generic

T = TypeVar("T")
P = ParamSpec("P")
Q = ParamSpec("Q")


class FooP(Generic[P]):
    pass


class FooTP(Generic[T, P]):
    pass


class FooPQ(Generic[P, Q]):
    pass


x1: FooP[int, int]  # ok
x2: FooP[[int, int]]  # ok

# Crash when inheriting, but valid type error here.
# error: Nested parameter specifications are not allowed
x3: FooP[[int, int], str]


# ok
class BarP1(FooP[int, int]):
    pass


# ok
class BarP2(FooP[[int, int]]):
    pass


# CRASH case from reproducer above
# class BarP3(FooP[[int, int], str]):
#     pass


# ok
class BarTP1(FooTP[int, [int, int]]):
    pass


# "FooTP" expects 2 type arguments, but 3 given
class BarTP2(FooTP[int, [int, int], str]):
    pass


# ok
class BarPQ1(FooPQ[[int, int], [int, int]]):
    pass


# "FooPQ" expects 2 type arguments, but 3 given
class BarPQ2(FooPQ[[int, int], [int, int], str]):
    pass

Your Environment

  • Mypy version used: 1.11.2, 1.12.0+dev.0c10367
  • Mypy command-line flags: --show-traceback
  • Mypy configuration options from mypy.ini (and other config files): Defaults (confirmed by mypy --verbose)
  • Python version used: 3.10.12
  • Operating system and version: Mint 21.3

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions