Skip to content

Commit 2a2cd69

Browse files
committed
adds dataclass argument type test cases
1 parent 32384e1 commit 2a2cd69

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

mypy/plugins/dataclasses.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing_extensions import Final
55

66
from mypy.nodes import (
7-
ARG_OPT, ARG_POS, MDEF, Argument, AssignmentStmt, CallExpr,
7+
ARG_OPT, ARG_NAMED, ARG_NAMED_OPT, ARG_POS, MDEF, Argument, AssignmentStmt, CallExpr,
88
Context, Expression, JsonDict, NameExpr, RefExpr,
99
SymbolTableNode, TempNode, TypeInfo, Var, TypeVarExpr, PlaceholderNode
1010
)
@@ -49,11 +49,18 @@ def __init__(
4949
self.kw_only = kw_only
5050

5151
def to_argument(self) -> Argument:
52+
arg_kind = ARG_POS
53+
if self.kw_only and self.has_default:
54+
arg_kind = ARG_NAMED_OPT
55+
elif self.kw_only and not self.has_default:
56+
arg_kind = ARG_NAMED
57+
elif not self.kw_only and self.has_default:
58+
arg_kind = ARG_OPT
5259
return Argument(
5360
variable=self.to_var(),
5461
type_annotation=self.type,
5562
initializer=None,
56-
kind=ARG_OPT if self.has_default else ARG_POS,
63+
kind=arg_kind,
5764
)
5865

5966
def to_var(self) -> Var:

test-data/unit/check-dataclasses.test

+37
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,13 @@ class Application:
321321
rating: int
322322

323323
Application(rating=5)
324+
Application(name='name', rating=5)
325+
Application() # E: Missing named argument "rating" for "Application"
326+
Application('name') # E: Too many positional arguments for "Application" # E: Missing named argument "rating" for "Application"
327+
Application('name', 123) # E: Too many positional arguments for "Application"
328+
Application('name', rating=123) # E: Too many positional arguments for "Application"
329+
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"
330+
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"
324331

325332
[builtins fixtures/list.pyi]
326333

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

336343
Application(rating=5)
344+
Application('name', rating=123)
345+
Application(name='name', rating=5)
346+
Application() # E: Missing named argument "rating" for "Application"
347+
Application('name') # E: Missing named argument "rating" for "Application"
348+
Application('name', 123) # E: Too many positional arguments for "Application"
349+
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"
337350

338351
[builtins fixtures/list.pyi]
339352

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

362+
Application(name='name', rating=5)
363+
Application('name', 123)
364+
Application('name', rating=123)
365+
Application() # E: Missing positional argument "name" in call to "Application"
366+
Application('name') # E: Too few arguments for "Application"
367+
349368
[builtins fixtures/list.pyi]
350369

351370
[case testDataclassesOrderingKwOnlyWithSentinel]
@@ -359,6 +378,11 @@ class Application:
359378
rating: int
360379

361380
Application(rating=5)
381+
Application(name='name', rating=5)
382+
Application() # E: Missing named argument "rating" for "Application"
383+
Application('name') # E: Too many positional arguments for "Application" # E: Missing named argument "rating" for "Application"
384+
Application('name', 123) # E: Too many positional arguments for "Application"
385+
Application('name', rating=123) # E: Too many positional arguments for "Application"
362386

363387
[builtins fixtures/list.pyi]
364388

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

399+
Application(name='name', rating=5)
400+
Application() # E: Missing positional argument "name" in call to "Application"
401+
Application('name') # E: Too many positional arguments for "Application" # E: Too few arguments for "Application"
402+
Application('name', 123) # E: Too many positional arguments for "Application"
403+
Application('name', rating=123) # E: Too many positional arguments for "Application"
404+
375405
[builtins fixtures/list.pyi]
376406

377407
[case testDataclassesOrderingKwOnlyWithSentinelAndSubclass]
@@ -391,6 +421,13 @@ class D(Base):
391421
a: str = "a"
392422

393423
D("Hello", "World")
424+
D(x="Hello", z="World")
425+
D("Hello", "World", y=1, w=2, a="b")
426+
D("Hello") # E: Missing positional argument "z" in call to "D"
427+
D() # E: Missing positional arguments "x", "z" in call to "D"
428+
D(123, "World") # E: Argument 1 to "D" has incompatible type "int"; expected "str"
429+
D("Hello", False) # E: Argument 2 to "D" has incompatible type "bool"; expected "str"
430+
D(123, False) # E: Argument 1 to "D" has incompatible type "int"; expected "str" # E: Argument 2 to "D" has incompatible type "bool"; expected "str"
394431

395432
[case testDataclassesOrderingKwOnlyWithMultipleSentinel]
396433
# flags: --python-version 3.10

0 commit comments

Comments
 (0)