diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a716531b2..6e575f5a9 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,6 +4,11 @@ Changelog (unreleased) ************ +Bug fixes: + +- Typing: Fix type annotations for `class Meta ` options (:issue:`2804`). + Thanks :user:`lawrence-law` for reporting. + Other changes: - Remove default value for the ``data`` param of `Nested._deserialize ` (:issue:`2802`). diff --git a/src/marshmallow/schema.py b/src/marshmallow/schema.py index 828bb1f01..50fb5c492 100644 --- a/src/marshmallow/schema.py +++ b/src/marshmallow/schema.py @@ -384,9 +384,9 @@ class Meta(Schema.Opts): .. versionchanged:: 3.26.0 Deprecate `ordered`. Field order is preserved by default. """ - fields: typing.ClassVar[tuple[Field] | list[Field]] + fields: typing.ClassVar[tuple[str, ...] | list[str]] """Fields to include in the (de)serialized result""" - additional: typing.ClassVar[tuple[Field] | list[Field]] + additional: typing.ClassVar[tuple[str, ...] | list[str]] """Fields to include in addition to the explicitly declared fields. `additional ` and `fields ` are mutually-exclusive options. @@ -396,7 +396,7 @@ class Meta(Schema.Opts): usually better to define fields as class variables, but you may need to use this option, e.g., if your fields are Python keywords. """ - exclude: typing.ClassVar[tuple[Field] | list[Field]] + exclude: typing.ClassVar[tuple[str, ...] | list[str]] """Fields to exclude in the serialized result. Nested fields can be represented with dot delimiters. """ @@ -408,7 +408,10 @@ class Meta(Schema.Opts): """Default format for `DateTime ` fields.""" timeformat: typing.ClassVar[str] """Default format for `Time ` fields.""" - render_module: typing.ClassVar[types.RenderModule] + + # FIXME: Use a more constrained type here. + # ClassVar[RenderModule] doesn't work. + render_module: typing.Any """ Module to use for `loads ` and `dumps `. Defaults to `json` from the standard library. """ @@ -416,9 +419,9 @@ class Meta(Schema.Opts): """If `True`, `Schema.dump ` is a `collections.OrderedDict`.""" index_errors: typing.ClassVar[bool] """If `True`, errors dictionaries will include the index of invalid items in a collection.""" - load_only: typing.ClassVar[tuple[Field] | list[Field]] + load_only: typing.ClassVar[tuple[str, ...] | list[str]] """Fields to exclude from serialized results""" - dump_only: typing.ClassVar[tuple[Field] | list[Field]] + dump_only: typing.ClassVar[tuple[str, ...] | list[str]] """Fields to exclude from serialized results""" unknown: typing.ClassVar[str] """Whether to exclude, include, or raise an error for unknown fields in the data. diff --git a/tests/mypy_test_cases/test_schema.py b/tests/mypy_test_cases/test_schema.py new file mode 100644 index 000000000..e13637862 --- /dev/null +++ b/tests/mypy_test_cases/test_schema.py @@ -0,0 +1,29 @@ +import json + +from marshmallow import EXCLUDE, Schema +from marshmallow.fields import Integer, String + + +# Test that valid `Meta` class attributes pass type checking +class MySchema(Schema): + foo = String() + bar = Integer() + + class Meta(Schema.Meta): + fields = ("foo", "bar") + additional = ("baz", "qux") + include = { + "foo2": String(), + } + exclude = ("bar", "baz") + many = True + dateformat = "%Y-%m-%d" + datetimeformat = "%Y-%m-%dT%H:%M:%S" + timeformat = "%H:%M:%S" + render_module = json + ordered = False + index_errors = True + load_only = ("foo", "bar") + dump_only = ("baz", "qux") + unknown = EXCLUDE + register = False