marshmallow icon indicating copy to clipboard operation
marshmallow copied to clipboard

Static typing of Field subclass kwargs

Open navignaw opened this issue 1 year ago • 0 comments

Today, the subclasses of Field have their constructor kwargs untyped, which means that static typecheckers like mypy/pyright treat them as Unknown. This can lead to bugs or typos like passing fields.Integer(validates=...) instead of fields.Integer(validate=...). In addition, editors like VSCode or neovim can't autocomplete or show you the types of these kwargs: Screenshot 2024-07-12 at 4 06 00 PM

In https://github.com/microsoft/pyright/issues/6344#issuecomment-2226519311, it was recommended to use the TypedDict and Unpack features to statically type kwargs. For example:

class BaseFieldKwargs(TypedDict, total=False):
    load_default: typing.Any
    missing: typing.Any
    dump_default: typing.Any
    default: typing.Any
    data_key: str | None
    attribute: str | None
    validate: (
        None
        | typing.Callable[[typing.Any], typing.Any]
        | typing.Iterable[typing.Callable[[typing.Any], typing.Any]]
    )
    ...

class Integer(Number):
    ...
    def __init__(self, *, strict: bool = False, **kwargs: Unpack[BaseFieldKwargs]):
        ...

(The presence of a catch-all additional_metadata makes it a little tricky. We might need to union it with a generic Dict[str, typing.Any] until that parameter is deprecated.)

Thoughts on adding this to improve static typechecking?

navignaw avatar Jul 12 '24 23:07 navignaw