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 if a class is generic over a PEP-695 parameter that has the same name as an old-style TypeVar that is also in scope and the old-style TypeVar has a bound which uses an unquoted forward reference #18507

Open
AlexWaygood opened this issue Jan 22, 2025 · 1 comment
Labels
crash topic-pep-695 Issues related to PEP 695 syntax

Comments

@AlexWaygood
Copy link
Member

Crash Report

This feels quite specific, but I think it may come up a surprising amount as more and more people use codemods to try to auto-upgrade their code to use PEP 695 in the coming years! Mypy crashes on this snippet:

from typing import TypeVar

T = TypeVar("T", bound=Foo)

class Foo: ...
class Bar[T]: ...

The following things must all be true for the crash to occur:

  • The global-scope TypeVar must have the same name as the type parameter used for Bar
  • The global-scope TypeVar must have a bound= argument that uses a forward reference
  • The forward reference in the global-scope TypeVar's bound must be unquoted. (For .py files, you generally need to quote all forward references, but this is not true for stubs.)

Traceback

% mypy foo.py --python-version=3.12 --show-traceback
foo.py:6: 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.15.0+dev.58de753b6b76227ff726e9ce1888cfc24c7ba44b
Traceback (most recent call last):
  File "/Users/alexw/dev/typeshed/.venv/bin/mypy", line 8, in <module>
    sys.exit(console_entry())
  File "/Users/alexw/dev/mypy/mypy/__main__.py", line 15, in console_entry
    main()
  File "/Users/alexw/dev/mypy/mypy/main.py", line 119, in main
    res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
  File "/Users/alexw/dev/mypy/mypy/main.py", line 203, in run_build
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "/Users/alexw/dev/mypy/mypy/build.py", line 191, in build
    result = _build(
  File "/Users/alexw/dev/mypy/mypy/build.py", line 267, in _build
    graph = dispatch(sources, manager, stdout)
  File "/Users/alexw/dev/mypy/mypy/build.py", line 2937, in dispatch
    process_graph(graph, manager)
  File "/Users/alexw/dev/mypy/mypy/build.py", line 3335, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/Users/alexw/dev/mypy/mypy/build.py", line 3430, in process_stale_scc
    mypy.semanal_main.semantic_analysis_for_scc(graph, scc, manager.errors)
  File "/Users/alexw/dev/mypy/mypy/semanal_main.py", line 93, in semantic_analysis_for_scc
    process_top_levels(graph, scc, patches)
  File "/Users/alexw/dev/mypy/mypy/semanal_main.py", line 220, in process_top_levels
    deferred, incomplete, progress = semantic_analyze_target(
  File "/Users/alexw/dev/mypy/mypy/semanal_main.py", line 351, in semantic_analyze_target
    analyzer.refresh_partial(
  File "/Users/alexw/dev/mypy/mypy/semanal.py", line 646, in refresh_partial
    self.refresh_top_level(node)
  File "/Users/alexw/dev/mypy/mypy/semanal.py", line 657, in refresh_top_level
    self.accept(d)
  File "/Users/alexw/dev/mypy/mypy/semanal.py", line 7241, in accept
    node.accept(self)
    ~~~~~~~~~~~^^^^^^
  File "/Users/alexw/dev/mypy/mypy/nodes.py", line 1177, in accept
    return visitor.visit_class_def(self)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/Users/alexw/dev/mypy/mypy/semanal.py", line 1728, in visit_class_def
    self.analyze_class(defn)
    ~~~~~~~~~~~~~~~~~~^^^^^^
  File "/Users/alexw/dev/mypy/mypy/semanal.py", line 1869, in analyze_class
    bases, tvar_defs, is_protocol = self.clean_up_bases_and_infer_type_variables(
                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        defn, bases, context=defn
        ^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/Users/alexw/dev/mypy/mypy/semanal.py", line 2174, in clean_up_bases_and_infer_type_variables
    assert isinstance(node.node, TypeVarLikeExpr)
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError:

To Reproduce

Paste the above snippet into a foo.py file and run mypy --python-version=3.12 foo.py --show-traceback

Your Environment

  • Mypy version used: 1.15.0+dev.58de753b6b76227ff726e9ce1888cfc24c7ba44b
  • Mypy command-line flags: --python-version=3.12 --show-traceback
  • Python version used: 3.13.1
@AlexWaygood AlexWaygood added crash topic-pep-695 Issues related to PEP 695 syntax labels Jan 22, 2025
@AlexWaygood
Copy link
Member Author

(Feel free to retitle the issue if you can think of something snappier...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
crash topic-pep-695 Issues related to PEP 695 syntax
Projects
None yet
Development

No branches or pull requests

1 participant