Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -1794,7 +1794,9 @@ def push_type_args(
if self.is_defined_type_param(p.name):
self.fail(f'"{p.name}" already defined as a type parameter', context)
else:
self.add_symbol(p.name, tv, context, no_progress=True, type_param=True)
assert self.add_symbol(
p.name, tv, context, no_progress=True, type_param=True
), "Type parameter should not be discarded"

return tvs

Expand Down Expand Up @@ -6830,6 +6832,7 @@ def add_symbol_table_node(
else:
# see note in docstring describing None contexts
self.defer()

if (
existing is not None
and context is not None
Expand All @@ -6849,7 +6852,9 @@ def add_symbol_table_node(
self.add_redefinition(names, name, symbol)
if not (isinstance(new, (FuncDef, Decorator)) and self.set_original_def(old, new)):
self.name_already_defined(name, context, existing)
elif name not in self.missing_names[-1] and "*" not in self.missing_names[-1]:
elif type_param or (
name not in self.missing_names[-1] and "*" not in self.missing_names[-1]
):
names[name] = symbol
if not no_progress:
self.progress = True
Expand Down
37 changes: 37 additions & 0 deletions test-data/unit/check-python312.test
Original file line number Diff line number Diff line change
Expand Up @@ -1228,6 +1228,43 @@ class C[T]:
def f[S, S](x: S) -> S: # E: "S" already defined as a type parameter
return x

[case testPEP695TypeVarNameClashNoCrashForwardReference]
# https://github.com/python/mypy/issues/18507
from typing import TypeVar
T = TypeVar("T", bound=Foo) # E: Name "Foo" is used before definition

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

[case testPEP695TypeVarNameClashNoCrashDeferredSymbol]
# https://github.com/python/mypy/issues/19526
T = Unknown # E: Name "Unknown" is not defined

class Foo[T]: ...
class Bar[*T]: ...
class Baz[**T]: ...
[builtins fixtures/tuple.pyi]

[case testPEP695TypeVarNameClashTypeAlias]
type Tb = object
type Ta[Tb] = 'B[Tb]'
class A[Ta]: ...
class B[Tb](A[Ta]): ...

[case testPEP695TypeVarNameClashStarImport]
# Similar to
# https://github.com/python/mypy/issues/19946
import a

[file a.py]
from b import *
class Foo[T]: ...

[file b.py]
from a import *
class Bar[T]: ...
[builtins fixtures/tuple.pyi]

[case testPEP695ClassDecorator]
from typing import Any

Expand Down