升级marshmallow后如何批量修改Field()元数据参数消除RemovedInMarshmallow4Warning
marshmallow 3.14+ 版本字段元参数警告批量整改方案
问题背景
升级 marshmallow 后,title、description 这类非保留参数需要通过 metadata 参数传入,否则会触发 RemovedInMarshmallow4Warning 警告。如果项目中存在大量 Field() 调用语句,可通过以下方案快速批量修改消除警告。
示例复现场景
原问题代码(schemas.py)
# schemas.py from marshmallow import Schema from marshmallow import fields class FooSchema(Schema): name = fields.String( required=True, title='foo', description='foo name') relationship = fields.String( title='bar', description='foobar')
测试用例代码
from schemas import FooSchema def test_warn(): INPUT = { 'name': 'something', 'relationship': 'others' } schema = FooSchema() data = schema.load(INPUT) assert data == INPUT
文件结构
$ tree . . ├── requirements.txt # marshmallow==3.3.0 ├── schemas.py └── test_warning.py
警告复现步骤
升级 marshmallow 到高版本后运行测试即可触发警告:
$ pip install -U marshmallow ... Successfully installed marshmallow-3.14.1 $ pytest test_warning.py ================== test session starts ================================ platform darwin -- Python 3.8.3, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 rootdir: /private/tmp/_ collected 1 item test_warning.py . [100%] ================== warnings summary ================================= .venv/lib/python3.8/site-packages/marshmallow/fields.py:218 /private/tmp/_/.venv/lib/python3.8/site-packages/marshmallow/fields.py:218: RemovedInMarshmallow4Warning: Passing field metadata as keyword arguments is deprecated. Use the explicit `metadata=...` argument instead. Additional metadata: {'title': 'foo', 'description': 'foo name'} warnings.warn( .venv/lib/python3.8/site-packages/marshmallow/fields.py:218 /private/tmp/_/.venv/lib/python3.8/site-packages/marshmallow/fields.py:218: RemovedInMarshmallow4Warning: Passing field metadata as keyword arguments is deprecated. Use the explicit `metadata=...` argument instead. Additional metadata: {'title': 'bar', 'description': 'foobar'} warnings.warn( ================== 1 passed, 2 warnings in 0.03s ===================
整改后预期代码
... class FooSchema(Schema): name = fields.String( required=True, metadata={'title': 'foo', 'description': 'foo name'}) relationship = fields.String( metadata={'title': 'bar', 'description': 'foobar'})
批量整改方案
优先用官方维护的代码重构脚本实现无错批量修改,操作步骤如下:
- 第一步:安装重构工具依赖
pip install bowler marshmallow-codemods
- 第二步:执行批量修改
在项目根目录执行以下命令,工具会自动扫描所有Python文件,把字段的非保留参数自动迁移到metadata字典内:
# 直接写入修改 marshmallow-codemods use-metadata-kwargs . # 仅预览修改不写入,可先执行确认修改范围 marshmallow-codemods use-metadata-kwargs . --dry-run
- 第三步:验证修改结果
运行测试确认警告已经消除:
pytest test_warning.py
如果项目文件量很少,也可以手动修改或者用编辑器正则替换,但要注意正则替换对跨行、多参数场景容易出现匹配错误,优先使用codemod工具更稳妥。
内容的提问来源于stack exchange,提问作者ryesurfing
相关产品推荐
相关产品推荐

