marshmallow_dataclass
marshmallow_dataclass copied to clipboard
Marshmallow 3.10.0 warning on using explicit `metadata=...`
When using marshmallow version 3.10.0 this warning appears:
RemovedInMarshmallow4Warning: Passing field metadata as a keyword arg is deprecated.
Use the explicit `metadata=...` argument instead.
Here is the commit where they have changed the behavior. https://github.com/marshmallow-code/marshmallow/commit/013abfd669f64446cc7954d0320cf5f1d668bd49
I understand this is something that needs to be addressed on the marshmallow_dataclass side, right?
Can you give an example of code that triggers this?
Given this test_m.py file:
from dataclasses import dataclass, field
import marshmallow_dataclass
@dataclass
class Foo:
bar: float = field(
metadata={
"required": False,
"default": 0.0,
"description": "test",
}
)
def test_create_schema():
schema = marshmallow_dataclass.class_schema(Foo)()
Running pytest on that file shows this warning:
$ pytest test_m.py
=========================================== test session starts ===========================================
platform darwin -- Python 3.8.1, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
rootdir: current/path/test
collected 1 item
test_m.py . [100%]
============================================ warnings summary =============================================
test_m.py::test_create_schema
/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/marshmallow/fields.py:195:
RemovedInMarshmallow4Warning: Passing field metadata as a keyword arg is deprecated.
Use the explicit `metadata=...` argument instead.
warnings.warn(
-- Docs: https://docs.pytest.org/en/stable/warnings.html
====================================== 1 passed, 1 warning in 0.06s =======================================
If no metadata= is set under field() then the warning does not appear.
Using "metadata" as a key inside field(metadata={...}) seems to solve the issue...
No warnings when pytesting the following test_m.py file:
from dataclasses import dataclass, field
import marshmallow_dataclass
@dataclass
class Foo:
bar: float = field(
metadata={
"required": False,
"default": 0.0,
"metadata": {
"description": "test",
}
}
)
def test_create_schema():
schema = marshmallow_dataclass.class_schema(Foo)()
This would seem a cleaner code (without nested metadatas) using Field (or Float, Int, Str...) from marshmallow.fields instead of built-in field, but then required, default and other marshamallow properties stop working:
from dataclasses import dataclass
from marshmallow.fields import Field, Float
import marshmallow_dataclass
@dataclass
class Foo:
bar: float = Float(
required=False,
default=0.0,
metadata={
"description": "test",
}
)
def test_create_schema():
schema = marshmallow_dataclass.class_schema(Foo)()
Yes, I think the only thing we can do here is follow marshmallow and update our documentation to ask people to use an explicit metadata key. PR welcome for the docs and readme changes.
Just to mention that when using the keyword "strict" in metadata={}, like in the following test example, the warning also appears.
from dataclasses import dataclass, field
import marshmallow_dataclass
@dataclass
class Foo:
bar: float = field(
metadata={
"required": False,
"strict": True, # This causes the warning
"default": 0.0,
"metadata": {
"description": "test",
}
}
)
def test_create_schema():
schema = marshmallow_dataclass.class_schema(Foo)()
Note: warning also appears if field is str, bool or float, and it doesn't appear when using int
This makes me think where can I find the complete compatible keys that won't trigger the warning? Thanks!
Just using metadata in field is not enough, there's one occurence where marshmallow_dataclass doesn't forward the metadata using the metadata parameter.
Seems there's much more. In fact, every occurence of **metadata probably needs to be replaced by metadata=metadata, and there are quite a few.
Same for exclude field here