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

Disallow no-args generic aliases when using PEP 613 explicit aliases #18173

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion mypy/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3593,7 +3593,7 @@ def f(x: B[T]) -> T: ... # without T, Any would be used here
type will be initially an instance type with wrong number of type arguments.
Such instances are all fixed either during or after main semantic analysis passes.
We therefore store the difference between `List` and `List[Any]` rvalues (targets)
using the `no_args` flag. See also TypeAliasExpr.no_args.
using the `no_args` flag.

Meaning of other fields:

Expand Down
13 changes: 7 additions & 6 deletions mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -2765,15 +2765,15 @@ def get_declared_metaclass(
return None, True, False # defer later in the caller

# Support type aliases, like `_Meta: TypeAlias = type`
metaclass_info: Node | None = sym.node
if (
isinstance(sym.node, TypeAlias)
and sym.node.no_args
and isinstance(sym.node.target, ProperType)
and isinstance(sym.node.target, Instance)
and not sym.node.python_3_12_type_alias
and not sym.node.alias_tvars
):
metaclass_info: Node | None = sym.node.target.type
else:
metaclass_info = sym.node
target = get_proper_type(sym.node.target)
if isinstance(target, Instance):
metaclass_info = target.type

if not isinstance(metaclass_info, TypeInfo) or metaclass_info.tuple_type is not None:
self.fail(f'Invalid metaclass "{metaclass_name}"', metaclass_expr)
Expand Down Expand Up @@ -4040,6 +4040,7 @@ def check_and_set_up_type_alias(self, s: AssignmentStmt) -> bool:
and not res.args
and not empty_tuple_index
and not pep_695
and not pep_613
)
if isinstance(res, ProperType) and isinstance(res, Instance):
if not validate_instance(res, self.fail, empty_tuple_index):
Expand Down
53 changes: 53 additions & 0 deletions test-data/unit/check-type-aliases.test
Original file line number Diff line number Diff line change
Expand Up @@ -1238,3 +1238,56 @@ from typing import List, Union
A = Union[int, List[A]]
def func(x: A) -> int: ...
[builtins fixtures/tuple.pyi]

[case testAliasExplicitNoArgsBasic]
from typing import Any, List, assert_type
from typing_extensions import TypeAlias

Implicit = List
Explicit: TypeAlias = List
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also test with non-alias generic class (e.g. <alias> = list)? You could also test with tuple, since it's a bit special.


x1: Implicit[str]
x2: Explicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
assert_type(x1, List[str])
assert_type(x2, List[Any])
[builtins fixtures/tuple.pyi]

[case testAliasExplicitNoArgsGenericClass]
# flags: --python-version 3.9
from typing import Any, assert_type
from typing_extensions import TypeAlias

Implicit = list
Explicit: TypeAlias = list

x1: Implicit[str]
x2: Explicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
assert_type(x1, list[str])
assert_type(x2, list[Any])
[builtins fixtures/tuple.pyi]

[case testAliasExplicitNoArgsTuple]
from typing import Any, Tuple, assert_type
from typing_extensions import TypeAlias

Implicit = Tuple
Explicit: TypeAlias = Tuple

x1: Implicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
x2: Explicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
assert_type(x1, Tuple[Any, ...])
assert_type(x2, Tuple[Any, ...])
[builtins fixtures/tuple.pyi]

[case testAliasExplicitNoArgsCallable]
from typing import Any, Callable, assert_type
from typing_extensions import TypeAlias

Implicit = Callable
Explicit: TypeAlias = Callable

x1: Implicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
x2: Explicit[str] # E: Bad number of arguments for type alias, expected 0, given 1
assert_type(x1, Callable[..., Any])
assert_type(x2, Callable[..., Any])
[builtins fixtures/tuple.pyi]
1 change: 0 additions & 1 deletion test-data/unit/diff.test
Original file line number Diff line number Diff line change
Expand Up @@ -1563,7 +1563,6 @@ type H[T] = int
__main__.A
__main__.C
__main__.D
__main__.E
__main__.G
__main__.H

Expand Down
Loading