diff --git a/marshmallow_dataclass/__init__.py b/marshmallow_dataclass/__init__.py index b28cfc5..aa47ab0 100644 --- a/marshmallow_dataclass/__init__.py +++ b/marshmallow_dataclass/__init__.py @@ -71,8 +71,12 @@ class User: if sys.version_info >= (3, 11): from typing import dataclass_transform -else: +elif sys.version_info >= (3, 7): from typing_extensions import dataclass_transform +else: + # @dataclass_transform() only helps us with mypy>=1.1 which is only available for python>=3.7 + def dataclass_transform(**kwargs): + return lambda cls: cls __all__ = ["dataclass", "add_schema", "class_schema", "field_for_schema", "NewType"] @@ -122,7 +126,7 @@ def dataclass( # _cls should never be specified by keyword, so start it with an # underscore. The presence of _cls is used to detect if this # decorator is being called with parameters or not. -@dataclass_transform() +@dataclass_transform(field_specifiers=(dataclasses.Field, dataclasses.field)) def dataclass( _cls: Optional[Type[_U]] = None, *, diff --git a/tests/test_mypy.yml b/tests/test_mypy.yml index 55e5cb2..46819df 100644 --- a/tests/test_mypy.yml +++ b/tests/test_mypy.yml @@ -65,3 +65,18 @@ reveal_type(website.email) # N: Revealed type is "builtins.str" Website(url=42, email="user@email.com") # E: Argument "url" to "Website" has incompatible type "int"; expected "str" [arg-type] +- case: dataclasses_field_not_a_default + mypy_config: | + follow_imports = silent + plugins = marshmallow_dataclass.mypy + show_error_codes = true + env: + - PYTHONPATH=. + main: | + from dataclasses import field + from marshmallow_dataclass import dataclass + + @dataclass + class User: + id: int = field(metadata={"required": True}) + name: str