Skip to content

Commit

Permalink
Fix crash on type alias definition inside dataclass declaration (#12792)
Browse files Browse the repository at this point in the history
Skip processing a type alias node and generate an error.

Fixes #12544.
  • Loading branch information
AlexWaygood authored May 20, 2022
1 parent 6c2690e commit e612e44
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
16 changes: 15 additions & 1 deletion mypy/plugins/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from mypy.nodes import (
ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_POS, ARG_STAR, ARG_STAR2, MDEF,
Argument, AssignmentStmt, CallExpr, Context, Expression, JsonDict,
Argument, AssignmentStmt, CallExpr, TypeAlias, Context, Expression, JsonDict,
NameExpr, RefExpr, SymbolTableNode, TempNode, TypeInfo, Var, TypeVarExpr,
PlaceholderNode
)
Expand Down Expand Up @@ -333,6 +333,20 @@ def collect_attributes(self) -> Optional[List[DataclassAttribute]]:

node = sym.node
assert not isinstance(node, PlaceholderNode)

if isinstance(node, TypeAlias):
ctx.api.fail(
(
'Type aliases inside dataclass definitions '
'are not supported at runtime'
),
node
)
# Skip processing this node. This doesn't match the runtime behaviour,
# but the only alternative would be to modify the SymbolTable,
# and it's a little hairy to do that in a plugin.
continue

assert isinstance(node, Var)

# x: ClassVar[int] is ignored by dataclasses.
Expand Down
28 changes: 28 additions & 0 deletions test-data/unit/check-dataclasses.test
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,34 @@ Application.COUNTER = 1

[builtins fixtures/dataclasses.pyi]

[case testTypeAliasInDataclassDoesNotCrash]
# flags: --python-version 3.7
from dataclasses import dataclass
from typing import Callable
from typing_extensions import TypeAlias

@dataclass
class Foo:
x: int

@dataclass
class One:
S: TypeAlias = Foo # E: Type aliases inside dataclass definitions are not supported at runtime

a = One()
reveal_type(a.S) # N: Revealed type is "def (x: builtins.int) -> __main__.Foo"
a.S() # E: Missing positional argument "x" in call to "Foo"
reveal_type(a.S(5)) # N: Revealed type is "__main__.Foo"

@dataclass
class Two:
S: TypeAlias = Callable[[int], str] # E: Type aliases inside dataclass definitions are not supported at runtime

c = Two()
x = c.S # E: Member "S" is not assignable
reveal_type(x) # N: Revealed type is "Any"
[builtins fixtures/dataclasses.pyi]

[case testDataclassOrdering]
# flags: --python-version 3.7
from dataclasses import dataclass
Expand Down

0 comments on commit e612e44

Please sign in to comment.