Skip to content

Unify a codepath in typevarlike semanal #12480

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

Merged
merged 1 commit into from
Mar 28, 2022
Merged
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
34 changes: 18 additions & 16 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
@@ -3093,14 +3093,8 @@ def process_typevar_declaration(self, s: AssignmentStmt) -> bool:
if not call:
return False

lvalue = s.lvalues[0]
assert isinstance(lvalue, NameExpr)
if s.type:
self.fail("Cannot declare the type of a type variable", s)
return False

name = lvalue.name
if not self.check_typevarlike_name(call, name, s):
name = self.extract_typevarlike_name(s, call)
if name is None:
return False

# Constraining types
@@ -3279,6 +3273,20 @@ def process_typevar_parameters(self, args: List[Expression],
variance = INVARIANT
return variance, upper_bound

def extract_typevarlike_name(self, s: AssignmentStmt, call: CallExpr) -> Optional[str]:
if not call:
return None

lvalue = s.lvalues[0]
assert isinstance(lvalue, NameExpr)
if s.type:
self.fail("Cannot declare the type of a TypeVar or similar construct", s)
return None

if not self.check_typevarlike_name(call, lvalue.name, s):
return None
return lvalue.name

def process_paramspec_declaration(self, s: AssignmentStmt) -> bool:
"""Checks if s declares a ParamSpec; if yes, store it in symbol table.

@@ -3293,14 +3301,8 @@ def process_paramspec_declaration(self, s: AssignmentStmt) -> bool:
if not call:
return False

lvalue = s.lvalues[0]
assert isinstance(lvalue, NameExpr)
if s.type:
self.fail("Cannot declare the type of a parameter specification", s)
return False

name = lvalue.name
if not self.check_typevarlike_name(call, name, s):
name = self.extract_typevarlike_name(s, call)
if name is None:
return False

# ParamSpec is different from a regular TypeVar:
4 changes: 2 additions & 2 deletions test-data/unit/semanal-errors.test
Original file line number Diff line number Diff line change
@@ -1081,7 +1081,7 @@ x = TypeVar('x') # E: Cannot redefine "x" as a type variable

[case testTypevarWithType]
from typing import TypeVar
x = TypeVar('x') # type: int # E: Cannot declare the type of a type variable
x = TypeVar('x') # type: int # E: Cannot declare the type of a TypeVar or similar construct
[out]

[case testRedefineTypevar]
@@ -1432,7 +1432,7 @@ from typing_extensions import ParamSpec

TParams = ParamSpec('TParams')
TP = ParamSpec('?') # E: String argument 1 "?" to ParamSpec(...) does not match variable name "TP"
TP2: int = ParamSpec('TP2') # E: Cannot declare the type of a parameter specification
TP2: int = ParamSpec('TP2') # E: Cannot declare the type of a TypeVar or similar construct

[out]