Skip to content

Commit

Permalink
Support marshmallow 3.24.0 and 4.0 (#987)
Browse files Browse the repository at this point in the history
* Use fields.Raw instead of fields.Field

* Address all Marshmallow4Warnings

* Update changelog and badge

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
sloria and pre-commit-ci[bot] authored Jan 7, 2025
1 parent fa9cd7b commit dbde72f
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 116 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Other changes:

* Test against Python 3.13 (:pr:`982`).
* Drop support for Python 3.8, which is EOL (:pr:`981`).
* Support marshmallow 4.

8.6.0 (2024-09-11)
******************
Expand Down
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
webargs
*******

|pypi| |build-status| |docs| |marshmallow3|
|pypi| |build-status| |docs| |marshmallow-support|

.. |pypi| image:: https://badgen.net/pypi/v/webargs
:target: https://pypi.org/project/webargs/
Expand All @@ -16,9 +16,9 @@ webargs
:target: https://webargs.readthedocs.io/
:alt: Documentation

.. |marshmallow3| image:: https://badgen.net/badge/marshmallow/3
.. |marshmallow-support| image:: https://badgen.net/badge/marshmallow/3,4?list=1
:target: https://marshmallow.readthedocs.io/en/latest/upgrading.html
:alt: marshmallow 3 compatible
:alt: marshmallow 3|4 compatible

Homepage: https://webargs.readthedocs.io/

Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ tests = [
"webtest==3.0.2",
"webtest-aiohttp==2.0.0",
"pytest-aiohttp>=0.3.0",
"packaging>=17.0",
]
docs = [
"webargs[frameworks]",
Expand Down Expand Up @@ -141,4 +142,5 @@ module = [
"webargs.bottleparser",
"webargs.djangoparser",
"webargs.falconparser",
"tests.*",
]
6 changes: 3 additions & 3 deletions tests/apps/aiohttp_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
import marshmallow as ma
from aiohttp.web import json_response

from webargs import fields
from webargs import fields, validate
from webargs.aiohttpparser import parser, use_args, use_kwargs
from webargs.core import json

hello_args = {"name": fields.Str(load_default="World", validate=lambda n: len(n) >= 3)}
hello_args = {"name": fields.Str(load_default="World", validate=validate.Length(min=3))}
hello_multiple = {"name": fields.List(fields.Str())}


class HelloSchema(ma.Schema):
name = fields.Str(load_default="World", validate=lambda n: len(n) >= 3)
name = fields.Str(load_default="World", validate=validate.Length(min=3))


hello_many_schema = HelloSchema(many=True)
Expand Down
8 changes: 4 additions & 4 deletions tests/apps/bottle_app.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import marshmallow as ma
from bottle import Bottle, HTTPResponse, debug, request, response

from webargs import fields
from webargs import fields, validate
from webargs.bottleparser import parser, use_args, use_kwargs
from webargs.core import json

hello_args = {"name": fields.Str(load_default="World", validate=lambda n: len(n) >= 3)}
hello_args = {"name": fields.Str(load_default="World", validate=validate.Length(min=3))}
hello_multiple = {"name": fields.List(fields.Str())}


class HelloSchema(ma.Schema):
name = fields.Str(load_default="World", validate=lambda n: len(n) >= 3)
name = fields.Str(load_default="World", validate=validate.Length(min=3))


hello_many_schema = HelloSchema(many=True)
Expand Down Expand Up @@ -132,7 +132,7 @@ def echo_cookie():

@app.route("/echo_file", method=["POST"])
def echo_file():
args = {"myfile": fields.Field()}
args = {"myfile": fields.Raw()}
result = parser.parse(args, location="files")
myfile = result["myfile"]
content = myfile.file.read().decode("utf8")
Expand Down
8 changes: 4 additions & 4 deletions tests/apps/django_app/echo/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@
from django.http import HttpResponse
from django.views.generic import View

from webargs import fields
from webargs import fields, validate
from webargs.core import json
from webargs.djangoparser import parser, use_args, use_kwargs

hello_args = {"name": fields.Str(load_default="World", validate=lambda n: len(n) >= 3)}
hello_args = {"name": fields.Str(load_default="World", validate=validate.Length(min=3))}
hello_multiple = {"name": fields.List(fields.Str())}


class HelloSchema(ma.Schema):
name = fields.Str(load_default="World", validate=lambda n: len(n) >= 3)
name = fields.Str(load_default="World", validate=validate.Length(min=3))


hello_many_schema = HelloSchema(many=True)
Expand Down Expand Up @@ -161,7 +161,7 @@ def echo_cookie(request):

@handle_view_errors
def echo_file(request):
args = {"myfile": fields.Field()}
args = {"myfile": fields.Raw()}
result = parser.parse(args, request, location="files")
myfile = result["myfile"]
content = myfile.read().decode("utf8")
Expand Down
6 changes: 3 additions & 3 deletions tests/apps/falcon_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
import falcon
import marshmallow as ma

from webargs import fields
from webargs import fields, validate
from webargs.core import json
from webargs.falconparser import parser, use_args, use_kwargs

hello_args = {"name": fields.Str(load_default="World", validate=lambda n: len(n) >= 3)}
hello_args = {"name": fields.Str(load_default="World", validate=validate.Length(min=3))}
hello_multiple = {"name": fields.List(fields.Str())}

FALCON_MAJOR_VERSION = int(importlib.metadata.version("falcon").split(".")[0])
FALCON_SUPPORTS_ASYNC = FALCON_MAJOR_VERSION >= 3


class HelloSchema(ma.Schema):
name = fields.Str(load_default="World", validate=lambda n: len(n) >= 3)
name = fields.Str(load_default="World", validate=validate.Length(min=3))


hello_many_schema = HelloSchema(many=True)
Expand Down
17 changes: 10 additions & 7 deletions tests/apps/flask_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from flask import jsonify as J
from flask.views import MethodView

from webargs import fields
from webargs import fields, validate
from webargs.core import json
from webargs.flaskparser import (
parser,
Expand All @@ -21,12 +21,12 @@ class TestAppConfig:
TESTING = True


hello_args = {"name": fields.Str(load_default="World", validate=lambda n: len(n) >= 3)}
hello_args = {"name": fields.Str(load_default="World", validate=validate.Length(min=3))}
hello_multiple = {"name": fields.List(fields.Str())}


class HelloSchema(ma.Schema):
name = fields.Str(load_default="World", validate=lambda n: len(n) >= 3)
name = fields.Str(load_default="World", validate=validate.Length(min=3))


hello_many_schema = HelloSchema(many=True)
Expand Down Expand Up @@ -61,10 +61,13 @@ def echo_use_args(args):
return J(args)


def validator(args):
if args["value"] <= 42:
raise ma.ValidationError("invalid")


@app.route("/echo_use_args_validated", methods=["POST"])
@use_args(
{"value": fields.Int()}, validate=lambda args: args["value"] > 42, location="form"
)
@use_args({"value": fields.Int()}, validate=validator, location="form")
def echo_use_args_validated(args):
return J(args)

Expand Down Expand Up @@ -150,7 +153,7 @@ def echo_cookie():

@app.route("/echo_file", methods=["POST"])
def echo_file():
args = {"myfile": fields.Field()}
args = {"myfile": fields.Raw()}
result = parser.parse(args, location="files")
fp = result["myfile"]
content = fp.read().decode("utf8")
Expand Down
8 changes: 4 additions & 4 deletions tests/apps/pyramid_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
from pyramid.config import Configurator
from pyramid.httpexceptions import HTTPBadRequest

from webargs import fields
from webargs import fields, validate
from webargs.core import json
from webargs.pyramidparser import parser, use_args, use_kwargs

hello_args = {"name": fields.Str(load_default="World", validate=lambda n: len(n) >= 3)}
hello_args = {"name": fields.Str(load_default="World", validate=validate.Length(min=3))}
hello_multiple = {"name": fields.List(fields.Str())}


class HelloSchema(ma.Schema):
name = fields.Str(load_default="World", validate=lambda n: len(n) >= 3)
name = fields.Str(load_default="World", validate=validate.Length(min=3))


hello_many_schema = HelloSchema(many=True)
Expand Down Expand Up @@ -122,7 +122,7 @@ def echo_cookie(request):


def echo_file(request):
args = {"myfile": fields.Field()}
args = {"myfile": fields.Raw()}
result = parser.parse(args, request, location="files")
myfile = result["myfile"]
content = myfile.file.read().decode("utf8")
Expand Down
2 changes: 1 addition & 1 deletion tests/test_aiohttpparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def test_use_args_multiple(self, testapp):
def test_validation_error_returns_422_response(self, testapp):
res = testapp.post_json("/echo_json", {"name": "b"}, expect_errors=True)
assert res.status_code == 422
assert res.json == {"json": {"name": ["Invalid value."]}}
assert res.json == {"json": {"name": ["Shorter than minimum length 3."]}}


@pytest.mark.asyncio
Expand Down
Loading

0 comments on commit dbde72f

Please sign in to comment.