Skip to content

Commit c859cb1

Browse files
Disallow no-args generic aliases when using PEP 613 explicit aliases (#18173)
Per the type system conformance tests, [this is ok](https://github.com/python/typing/blob/46b05a4c10ed3841c9bc5126ba9f31dd8ae061e7/conformance/tests/aliases_implicit.py#L130): ```python ListAlias = list x = ListAlias[int]() # OK ``` While [this is not](https://github.com/python/typing/blob/46b05a4c10ed3841c9bc5126ba9f31dd8ae061e7/conformance/tests/aliases_explicit.py#L100): ```python ListAlias: TypeAlias = list x: ListAlias[int] # E: already specialized ``` Mypy currently permits both. This PR makes mypy reject the latter case, improving conformance. As part of this, no-args PEP 613 explicit aliases are no longer eagerly expanded. (Also removed a stale comment referencing `TypeAliasExpr.no_args`, which was removed in #15924)
1 parent 7959a20 commit c859cb1

File tree

4 files changed

+61
-8
lines changed

4 files changed

+61
-8
lines changed

mypy/nodes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3593,7 +3593,7 @@ def f(x: B[T]) -> T: ... # without T, Any would be used here
35933593
type will be initially an instance type with wrong number of type arguments.
35943594
Such instances are all fixed either during or after main semantic analysis passes.
35953595
We therefore store the difference between `List` and `List[Any]` rvalues (targets)
3596-
using the `no_args` flag. See also TypeAliasExpr.no_args.
3596+
using the `no_args` flag.
35973597
35983598
Meaning of other fields:
35993599

mypy/semanal.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -2797,15 +2797,15 @@ def get_declared_metaclass(
27972797
return None, True, False # defer later in the caller
27982798

27992799
# Support type aliases, like `_Meta: TypeAlias = type`
2800+
metaclass_info: Node | None = sym.node
28002801
if (
28012802
isinstance(sym.node, TypeAlias)
2802-
and sym.node.no_args
2803-
and isinstance(sym.node.target, ProperType)
2804-
and isinstance(sym.node.target, Instance)
2803+
and not sym.node.python_3_12_type_alias
2804+
and not sym.node.alias_tvars
28052805
):
2806-
metaclass_info: Node | None = sym.node.target.type
2807-
else:
2808-
metaclass_info = sym.node
2806+
target = get_proper_type(sym.node.target)
2807+
if isinstance(target, Instance):
2808+
metaclass_info = target.type
28092809

28102810
if not isinstance(metaclass_info, TypeInfo) or metaclass_info.tuple_type is not None:
28112811
self.fail(f'Invalid metaclass "{metaclass_name}"', metaclass_expr)
@@ -4077,6 +4077,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool:
40774077
and not res.args
40784078
and not empty_tuple_index
40794079
and not pep_695
4080+
and not pep_613
40804081
)
40814082
if isinstance(res, ProperType) and isinstance(res, Instance):
40824083
if not validate_instance(res, self.fail, empty_tuple_index):

test-data/unit/check-type-aliases.test

+53
Original file line numberDiff line numberDiff line change
@@ -1242,3 +1242,56 @@ from typing import List, Union
12421242
A = Union[int, List[A]]
12431243
def func(x: A) -> int: ...
12441244
[builtins fixtures/tuple.pyi]
1245+
1246+
[case testAliasExplicitNoArgsBasic]
1247+
from typing import Any, List, assert_type
1248+
from typing_extensions import TypeAlias
1249+
1250+
Implicit = List
1251+
Explicit: TypeAlias = List
1252+
1253+
x1: Implicit[str]
1254+
x2: Explicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
1255+
assert_type(x1, List[str])
1256+
assert_type(x2, List[Any])
1257+
[builtins fixtures/tuple.pyi]
1258+
1259+
[case testAliasExplicitNoArgsGenericClass]
1260+
# flags: --python-version 3.9
1261+
from typing import Any, assert_type
1262+
from typing_extensions import TypeAlias
1263+
1264+
Implicit = list
1265+
Explicit: TypeAlias = list
1266+
1267+
x1: Implicit[str]
1268+
x2: Explicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
1269+
assert_type(x1, list[str])
1270+
assert_type(x2, list[Any])
1271+
[builtins fixtures/tuple.pyi]
1272+
1273+
[case testAliasExplicitNoArgsTuple]
1274+
from typing import Any, Tuple, assert_type
1275+
from typing_extensions import TypeAlias
1276+
1277+
Implicit = Tuple
1278+
Explicit: TypeAlias = Tuple
1279+
1280+
x1: Implicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
1281+
x2: Explicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
1282+
assert_type(x1, Tuple[Any, ...])
1283+
assert_type(x2, Tuple[Any, ...])
1284+
[builtins fixtures/tuple.pyi]
1285+
1286+
[case testAliasExplicitNoArgsCallable]
1287+
from typing import Any, Callable, assert_type
1288+
from typing_extensions import TypeAlias
1289+
1290+
Implicit = Callable
1291+
Explicit: TypeAlias = Callable
1292+
1293+
x1: Implicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
1294+
x2: Explicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
1295+
assert_type(x1, Callable[..., Any])
1296+
assert_type(x2, Callable[..., Any])
1297+
[builtins fixtures/tuple.pyi]

test-data/unit/diff.test

-1
Original file line numberDiff line numberDiff line change
@@ -1563,7 +1563,6 @@ type H[T] = int
15631563
__main__.A
15641564
__main__.C
15651565
__main__.D
1566-
__main__.E
15671566
__main__.G
15681567
__main__.H
15691568

0 commit comments

Comments
 (0)