Skip to content

Commit

Permalink
Fix error message for dataclasses.field with positional argument (#11180
Browse files Browse the repository at this point in the history
)

Fixes #10248

The crash due to dataclasses.field was fixed in the recent PR #11137, but the error 
message was wrong when positional arguments are used.

I update the error message based on 
#10248 (comment)
(Thanks @JelleZijlstra!)
  • Loading branch information
hi-ogawa authored Sep 24, 2021
1 parent 8b47a03 commit 3ec0284
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
20 changes: 11 additions & 9 deletions mypy/plugins/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,16 +460,18 @@ def _collect_field_args(expr: Expression,
):
# field() only takes keyword arguments.
args = {}
for name, arg in zip(expr.arg_names, expr.args):
if name is None:
# This means that `field` is used with `**` unpacking,
# the best we can do for now is not to fail.
# TODO: we can infer what's inside `**` and try to collect it.
ctx.api.fail(
'Unpacking **kwargs in "field()" is not supported',
expr,
)
for name, arg, kind in zip(expr.arg_names, expr.args, expr.arg_kinds):
if not kind.is_named():
if kind.is_named(star=True):
# This means that `field` is used with `**` unpacking,
# the best we can do for now is not to fail.
# TODO: we can infer what's inside `**` and try to collect it.
message = 'Unpacking **kwargs in "field()" is not supported'
else:
message = '"field()" does not accept positional arguments'
ctx.api.fail(message, expr)
return True, {}
assert name is not None
args[name] = arg
return True, args
return False, {}
13 changes: 13 additions & 0 deletions test-data/unit/check-dataclasses.test
Original file line number Diff line number Diff line change
Expand Up @@ -1320,6 +1320,19 @@ main:7: note: def [_T] field(*, default_factory: Callable[[], _T], init: boo
main:7: note: def field(*, init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> Any
[builtins fixtures/dataclasses.pyi]

[case testDataclassFieldWithPositionalArguments]
# flags: --python-version 3.7
from dataclasses import dataclass, field

@dataclass
class C:
x: int = field(0) # E: "field()" does not accept positional arguments \
# E: No overload variant of "field" matches argument type "int" \
# N: Possible overload variants: \
# N: def [_T] field(*, default: _T, init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> _T \
# N: def [_T] field(*, default_factory: Callable[[], _T], init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> _T \
# N: def field(*, init: bool = ..., repr: bool = ..., hash: Optional[bool] = ..., compare: bool = ..., metadata: Optional[Mapping[str, Any]] = ..., kw_only: bool = ...) -> Any
[builtins fixtures/dataclasses.pyi]

[case testDataclassFieldWithTypedDictUnpacking]
# flags: --python-version 3.7
Expand Down

0 comments on commit 3ec0284

Please sign in to comment.