Skip to content

Commit

Permalink
adds dataclass argument type test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
tgallant committed Aug 7, 2021
1 parent 09f03eb commit 21fa8be
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 2 deletions.
11 changes: 9 additions & 2 deletions mypy/plugins/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing_extensions import Final

from mypy.nodes import (
ARG_OPT, ARG_POS, MDEF, Argument, AssignmentStmt, CallExpr,
ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_POS, MDEF, Argument, AssignmentStmt, CallExpr,
Context, Expression, JsonDict, NameExpr, RefExpr,
SymbolTableNode, TempNode, TypeInfo, Var, TypeVarExpr, PlaceholderNode
)
Expand Down Expand Up @@ -49,11 +49,18 @@ def __init__(
self.kw_only = kw_only

def to_argument(self) -> Argument:
arg_kind = ARG_POS
if self.kw_only and self.has_default:
arg_kind = ARG_NAMED_OPT
elif self.kw_only and not self.has_default:
arg_kind = ARG_NAMED
elif not self.kw_only and self.has_default:
arg_kind = ARG_OPT
return Argument(
variable=self.to_var(),
type_annotation=self.type,
initializer=None,
kind=ARG_OPT if self.has_default else ARG_POS,
kind=arg_kind,
)

def to_var(self) -> Var:
Expand Down
34 changes: 34 additions & 0 deletions test-data/unit/check-dataclasses.test
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,13 @@ class Application:
rating: int

Application(rating=5)
Application(name='name', rating=5)
Application() # E: Missing named argument "rating" for "Application"
Application('name') # E: Too many positional arguments for "Application" # E: Missing named argument "rating" for "Application"
Application('name', 123) # E: Too many positional arguments for "Application"
Application('name', rating=123) # E: Too many positional arguments for "Application"
Application(name=123, rating='name') # E: Argument "name" to "Application" has incompatible type "int"; expected "str" # E: Argument "rating" to "Application" has incompatible type "str"; expected "int"
Application(rating='name', name=123) # E: Argument "rating" to "Application" has incompatible type "str"; expected "int" # E: Argument "name" to "Application" has incompatible type "int"; expected "str"

[builtins fixtures/list.pyi]

Expand All @@ -334,6 +341,12 @@ class Application:
rating: int = field(kw_only=True)

Application(rating=5)
Application('name', rating=123)
Application(name='name', rating=5)
Application() # E: Missing named argument "rating" for "Application"
Application('name') # E: Missing named argument "rating" for "Application"
Application('name', 123) # E: Too many positional arguments for "Application"
Application(123, rating='name') # E: Argument 1 to "Application" has incompatible type "int"; expected "str" # E: Argument "rating" to "Application" has incompatible type "str"; expected "int"

[builtins fixtures/list.pyi]

Expand All @@ -346,6 +359,12 @@ class Application:
name: str = 'Unnamed'
rating: int = field(kw_only=False) # E: Attributes without a default cannot follow attributes with one

Application(name='name', rating=5)
Application('name', 123)
Application('name', rating=123)
Application() # E: Missing positional argument "name" in call to "Application"
Application('name') # E: Too few arguments for "Application"

[builtins fixtures/list.pyi]

[case testDataclassesOrderingKwOnlyWithSentinel]
Expand All @@ -359,6 +378,11 @@ class Application:
rating: int

Application(rating=5)
Application(name='name', rating=5)
Application() # E: Missing named argument "rating" for "Application"
Application('name') # E: Too many positional arguments for "Application" # E: Missing named argument "rating" for "Application"
Application('name', 123) # E: Too many positional arguments for "Application"
Application('name', rating=123) # E: Too many positional arguments for "Application"

[builtins fixtures/list.pyi]

Expand All @@ -372,6 +396,12 @@ class Application:
name: str = 'Unnamed'
rating: int = field(kw_only=False) # E: Attributes without a default cannot follow attributes with one

Application(name='name', rating=5)
Application() # E: Missing positional argument "name" in call to "Application"
Application('name') # E: Too many positional arguments for "Application" # E: Too few arguments for "Application"
Application('name', 123) # E: Too many positional arguments for "Application"
Application('name', rating=123) # E: Too many positional arguments for "Application"

[builtins fixtures/list.pyi]

[case testDataclassesOrderingKwOnlyWithSentinelAndSubclass]
Expand All @@ -391,6 +421,10 @@ class D(Base):
a: str = "a"

D("Hello", "World")
D(x="Hello", z="World")
D("Hello", "World", y=1, w=2, a="b")
D("Hello") # E: Missing positional argument "z" in call to "D"
D() # E: Missing positional arguments "x", "z" in call to "D"

[case testDataclassesOrderingKwOnlyWithMultipleSentinel]
# flags: --python-version 3.10
Expand Down

0 comments on commit 21fa8be

Please sign in to comment.