marshmallow_dataclass icon indicating copy to clipboard operation
marshmallow_dataclass copied to clipboard

Marshmallow 3.10.0 warning on using explicit `metadata=...`

Open bonastreyair opened this issue 4 years ago • 8 comments

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?

bonastreyair avatar Dec 23 '20 17:12 bonastreyair

Can you give an example of code that triggers this?

lovasoa avatar Dec 23 '20 19:12 lovasoa

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.

bonastreyair avatar Dec 23 '20 22:12 bonastreyair

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)()

bonastreyair avatar Jan 05 '21 12:01 bonastreyair

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.

lovasoa avatar Jan 10 '21 14:01 lovasoa

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!

bonastreyair avatar Feb 04 '21 18:02 bonastreyair

Just using metadata in field is not enough, there's one occurence where marshmallow_dataclass doesn't forward the metadata using the metadata parameter.

liberforce avatar Mar 15 '21 13:03 liberforce

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.

liberforce avatar Mar 15 '21 14:03 liberforce

Same for exclude field here

eugene-bright avatar Mar 02 '22 12:03 eugene-bright