diff --git a/marshmallow_dataclass/__init__.py b/marshmallow_dataclass/__init__.py index 7312374..29a0e0a 100644 --- a/marshmallow_dataclass/__init__.py +++ b/marshmallow_dataclass/__init__.py @@ -103,6 +103,9 @@ def dataclass( order: bool = False, unsafe_hash: bool = False, frozen: bool = False, + match_args: bool = True, + kw_only: bool = False, + slots: bool = False, base_schema: Optional[Type[marshmallow.Schema]] = None, cls_frame: Optional[types.FrameType] = None, ) -> Type[_U]: @@ -117,6 +120,9 @@ def dataclass( order: bool = False, unsafe_hash: bool = False, frozen: bool = False, + match_args: bool = True, + kw_only: bool = False, + slots: bool = False, base_schema: Optional[Type[marshmallow.Schema]] = None, cls_frame: Optional[types.FrameType] = None, ) -> Callable[[Type[_U]], Type[_U]]: @@ -135,6 +141,9 @@ def dataclass( order: bool = False, unsafe_hash: bool = False, frozen: bool = False, + match_args: bool = True, + kw_only: bool = False, + slots: bool = False, base_schema: Optional[Type[marshmallow.Schema]] = None, cls_frame: Optional[types.FrameType] = None, ) -> Union[Type[_U], Callable[[Type[_U]], Type[_U]]]: @@ -163,10 +172,46 @@ def dataclass( >>> Point.Schema().load({'x':0, 'y':0}) # This line can be statically type checked Point(x=0.0, y=0.0) """ - # dataclass's typing doesn't expect it to be called as a function, so ignore type check - dc = dataclasses.dataclass( # type: ignore - _cls, repr=repr, eq=eq, order=order, unsafe_hash=unsafe_hash, frozen=frozen - ) + # Check python version for dataclass params only available for python >= 3.10. + # If python version is below 3.10 and any of these params are set to anything + # other than their default, raise ValueError + if sys.version_info >= (3, 10): + # dataclass's typing doesn't expect it to be called as a function, so ignore type check + dc = dataclasses.dataclass( # type: ignore + _cls, + repr=repr, + eq=eq, + order=order, + unsafe_hash=unsafe_hash, + frozen=frozen, + match_args=match_args, + kw_only=kw_only, + slots=slots, + ) + else: + args = { + "match_args": { + "error_message": "'match_args' argument is only available for python >= 3.10", + "default_value": True, + }, + "kw_only": { + "error_message": "'kw_only' argument is only available for python >= 3.10", + "default_value": False, + }, + "slots": { + "error_message": "'slots' argument is only available for python >= 3.10", + "default_value": False, + }, + } + + for arg, arg_info in args.items(): + if locals()[arg] is not arg_info["default_value"]: + raise ValueError(arg_info["error_message"]) + + # dataclass's typing doesn't expect it to be called as a function, so ignore type check + dc = dataclasses.dataclass( # type: ignore + _cls, repr=repr, eq=eq, order=order, unsafe_hash=unsafe_hash, frozen=frozen + ) if not cls_frame: current_frame = inspect.currentframe() if current_frame: