Skip to content

Commit

Permalink
chg: update deprecated calls [ACSBP-4025] (#290)
Browse files Browse the repository at this point in the history
* fix: replace usages of the deprecated 'missing' field kwarg with 'load_default'

* test: replace usages for deprecated 'default' marshmallow field argument with 'dump_default'

* test: update deprecated use of kwargs for passing metadata to a marshmallow field

* test: wrap the tests intentionally testing the deprecated Nested field api with a deprecated context manager to capture the warnings

* test: clean up usage of deprecated 'authenticator' rebar arg

* build: configure warnings to block tests

* fix: linting

* maint: update pre-commit configuration and linting libraries
pre-commit no longer targets Python 3.7 only. This was especially silly as the CI is targeting Python 3.11 for linting.
updated flake8 and black to the latest versions.
  • Loading branch information
airstandley authored Jun 30, 2023
1 parent 37ce30a commit 2396996
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 65 deletions.
6 changes: 2 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ repos:
# NOTE: it is not recommended to use mutable revs e.g. "stable" - run pre-commit autoupdate instead
# ref: https://github.com/ambv/black/issues/420
- repo: https://github.com/ambv/black
rev: 22.3.0
rev: 23.3.0
hooks:
- id: black
language_version: python3.7
- repo: https://github.com/pycqa/flake8
rev: 4.0.1
rev: 6.0.0
hooks:
- id: flake8
language_version: python3.7
2 changes: 1 addition & 1 deletion docs/quickstart/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ Query String Validation
.. code-block:: python
class GetTodosSchema(RequestSchema):
exclude_completed = fields.String(missing=False)
exclude_completed = fields.String(load_default="")
@registry.handles(
Expand Down
6 changes: 3 additions & 3 deletions flask_rebar/swagger_generation/marshmallow_to_swagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,12 @@ def convert(self, obj, context):
@sets_swagger_attr(sw.default)
def get_default(self, obj, context):
if (
obj.missing is not m.missing
obj.load_default is not m.missing
# Marshmallow accepts a callable for the default. This is tricky
# to handle, so let's just ignore this for now.
and not callable(obj.missing)
and not callable(obj.load_default)
):
return obj.missing
return obj.load_default
else:
return UNSET

Expand Down
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ exclude = '''
)/
'''

[tool.pytest.ini_options]
filterwarnings = [
"error"
]

[build-system]
requires = [
"setuptools >= 35.0.2",
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

# packages required for local development and testing
development = [
"black==22.3.0",
"black==23.3.0",
"bumpversion==0.5.3",
"click>=8.1.3,<9.0.0",
"flake8==4.0.1",
"flake8==6.0.0",
"gitchangelog>=3.0.4,<4.0.0",
"jsonschema==3.0.2",
"marshmallow-objects~=2.3",
Expand Down
4 changes: 3 additions & 1 deletion tests/swagger_generation/registries/exploded_query_string.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

class ExplodedQueryStringSchema(RequestSchema):
foos = QueryParamList(
marshmallow.fields.String(), required=True, description="foo string"
marshmallow.fields.String(),
required=True,
metadata={"description": "foo string"},
)


Expand Down
6 changes: 3 additions & 3 deletions tests/swagger_generation/registries/hidden_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def get_foo(foo_uid):
method="PATCH",
response_body_schema={200: FooSchema()},
request_body_schema=FooUpdateSchema(),
authenticator=authenticator,
authenticators=[authenticator],
)
def update_foo(foo_uid):
pass
Expand All @@ -70,7 +70,7 @@ def update_foo(foo_uid):
rule="/foo_list",
method="GET",
response_body_schema={200: FooSchema(many=True)},
authenticator=None, # Override the default!
authenticators=None, # Override the default!
hidden=True,
)
def list_foos():
Expand All @@ -82,7 +82,7 @@ def list_foos():
method="GET",
response_body_schema={200: NestedFoosSchema()},
query_string_schema=NameAndOtherSchema(),
authenticator=None, # Override the default!
authenticators=None, # Override the default!
)
def nested_foos():
pass
Expand Down
65 changes: 33 additions & 32 deletions tests/swagger_generation/registries/legacy.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import marshmallow as m
import pytest

from flask_rebar import Rebar
from flask_rebar import HeaderApiKeyAuthenticator
Expand Down Expand Up @@ -52,38 +53,38 @@ def get_foo(foo_uid):
pass


@registry.handles(
rule="/foos/<foo_uid>",
method="PATCH",
response_body_schema={200: FooSchema()},
request_body_schema=FooUpdateSchema(),
authenticator=authenticator,
)
def update_foo(foo_uid):
pass


# Test using Schema(many=True) without using a nested Field.
# https://github.com/plangrid/flask-rebar/issues/41
@registry.handles(
rule="/foo_list",
method="GET",
response_body_schema={200: FooSchema(many=True)},
authenticator=None, # Override the default!
)
def list_foos():
pass


@registry.handles(
rule="/foos",
method="GET",
response_body_schema={200: NestedFoosSchema()},
query_string_schema=NameAndOtherSchema(),
authenticator=None, # Override the default!
)
def nested_foos():
pass
with pytest.warns(FutureWarning): # authenticator kwarg is deprecating

@registry.handles(
rule="/foos/<foo_uid>",
method="PATCH",
response_body_schema={200: FooSchema()},
request_body_schema=FooUpdateSchema(),
authenticator=authenticator,
)
def update_foo(foo_uid):
pass

# Test using Schema(many=True) without using a nested Field.
# https://github.com/plangrid/flask-rebar/issues/41
@registry.handles(
rule="/foo_list",
method="GET",
response_body_schema={200: FooSchema(many=True)},
authenticator=None, # Override the default!
)
def list_foos():
pass

@registry.handles(
rule="/foos",
method="GET",
response_body_schema={200: NestedFoosSchema()},
query_string_schema=NameAndOtherSchema(),
authenticator=None, # Override the default!
)
def nested_foos():
pass


@registry.handles(rule="/tagged_foos", tags=["bar", "baz"])
Expand Down
4 changes: 2 additions & 2 deletions tests/swagger_generation/registries/marshmallow_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def get_foo(foo_uid):
method="PATCH",
response_body_schema={200: FooModel},
request_body_schema=FooUpdateModel,
authenticator=authenticator,
authenticators=[authenticator],
)
def update_foo(foo_uid):
pass
Expand All @@ -70,7 +70,7 @@ def update_foo(foo_uid):
method="GET",
response_body_schema={200: NestedFoosModel},
query_string_schema=NameAndOtherModel,
authenticator=None, # Override the default!
authenticators=None, # Override the default!
)
def nested_foos():
pass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ def list_foos():
method="GET",
response_body_schema={200: NestedFoosSchema()},
query_string_schema=NameAndOtherSchema(),
authenticator=None, # Override the default!
authenticators=None, # Override the default!
)
def nested_foos():
pass
Expand Down
71 changes: 63 additions & 8 deletions tests/swagger_generation/test_marshmallow_to_swagger.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import enum
from unittest import TestCase
from parametrize import parametrize
import pytest


import marshmallow as m
Expand Down Expand Up @@ -49,9 +50,9 @@ def test_primitive_types(self):
(m.fields.URL(), {"type": "string"}),
(m.fields.Email(), {"type": "string"}),
(m.fields.Constant("foo"), {"enum": ["foo"], "default": "foo"}),
(m.fields.Integer(missing=5), {"type": "integer", "default": 5}),
(m.fields.Integer(load_default=5), {"type": "integer", "default": 5}),
(m.fields.Integer(dump_only=True), {"type": "integer", "readOnly": True}),
(m.fields.Integer(missing=lambda: 5), {"type": "integer"}),
(m.fields.Integer(load_default=lambda: 5), {"type": "integer"}),
(
EnumField(StopLight),
{"enum": ["green", "yellow", "red"], "type": "string"},
Expand All @@ -73,7 +74,7 @@ def test_primitive_types(self):
{"type": "array", "items": {"type": "integer"}},
),
(
m.fields.Integer(description="blam!"),
m.fields.Integer(metadata={"description": "blam!"}),
{"type": "integer", "description": "blam!"},
),
(
Expand Down Expand Up @@ -122,14 +123,16 @@ def test_primitive_types(self):
),
(m.fields.Dict(), {"type": "object"}),
(
m.fields.Method(serialize="x", deserialize="y", swagger_type="integer"),
m.fields.Method(
serialize="x", deserialize="y", metadata={"swagger_type": "integer"}
),
{"type": "integer"},
),
(
m.fields.Function(
serialize=lambda _: _,
deserialize=lambda _: _,
swagger_type="string",
metadata={"swagger_type": "string"},
),
{"type": "string"},
),
Expand Down Expand Up @@ -358,16 +361,68 @@ class Foo(m.Schema):
},
)

def test_self_referential_nested(self):
def test_self_referential_nested_pre_3_3(self):
# Issue 90
# note for Marshmallow >= 3.3, preferred format is e.g.,:
# m.fields.Nested(lambda: Foo(only=("d", "b")))
# and passing "self" as a string is deprecated
# but that doesn't work in < 3.3, so until 4.x we'll keep supporting/testing with "self"
with pytest.deprecated_call():

class Foo(m.Schema):
a = m.fields.Nested("self", exclude=("a",))
b = m.fields.Integer()
c = m.fields.Nested("self", only=("d", "b"))
d = m.fields.Email()

schema = Foo()
json_schema = self.registry.convert(schema)

self.assertEqual(
json_schema,
{
"properties": {
"a": {
"additionalProperties": False,
"properties": {
"b": {"type": "integer"},
"c": {
"additionalProperties": False,
"properties": {
"b": {"type": "integer"},
"d": {"type": "string"},
},
"title": "Foo",
"type": "object",
},
"d": {"type": "string"},
},
"title": "Foo",
"type": "object",
},
"b": {"type": "integer"},
"c": {
"additionalProperties": False,
"properties": {
"b": {"type": "integer"},
"d": {"type": "string"},
},
"title": "Foo",
"type": "object",
},
"d": {"type": "string"},
},
"title": "Foo",
"type": "object",
"additionalProperties": False,
},
)

def test_self_referential_nested(self):
class Foo(m.Schema):
a = m.fields.Nested("self", exclude=("a",))
a = m.fields.Nested(lambda: Foo(), exclude=("a",))
b = m.fields.Integer()
c = m.fields.Nested("self", only=("d", "b"))
c = m.fields.Nested(lambda: Foo(), only=("d", "b"))
d = m.fields.Email()

schema = Foo()
Expand Down
8 changes: 2 additions & 6 deletions tests/test_rebar.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,11 @@ class FooListModel(mo.Model):


class HeadersSchema(m.Schema):
name = set_data_key(
field=m.fields.String(load_from="x-name", required=True), key="x-name"
)
name = set_data_key(field=m.fields.String(required=True), key="x-name")


class HeadersModel(mo.Model):
name = set_data_key(
field=mo.fields.String(load_from="x-name", required=True), key="x-name"
)
name = set_data_key(field=mo.fields.String(required=True), key="x-name")


class MeSchema(m.Schema):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ class RequireOnDumpMixinSchema(NoRequireOnDumpMixinSchema, RequireOnDumpMixin):


class InnerNested(Schema, RequireOnDumpMixin):
inner_dump_only = fields.String(default="Inner dump-only", dump_only=True)
inner_dump_only = fields.String(dump_default="Inner dump-only", dump_only=True)
inner_nested = fields.Nested(RequireOnDumpMixinSchema)
inner_nested_dump_only = fields.Nested(RequireOnDumpMixinSchema, dump_only=True)
inner_nested_list = fields.List(fields.Nested(RequireOnDumpMixinSchema))
validated = fields.Integer(required=False, validate=Range(42, 99))


class OuterNested(Schema, RequireOnDumpMixin):
outer_dump_only = fields.String(default="Outer dump-only", dump_only=True)
outer_dump_only = fields.String(dump_default="Outer dump-only", dump_only=True)
nested = fields.Nested(InnerNested)
nested_list = fields.List(fields.Nested(InnerNested))

Expand Down

0 comments on commit 2396996

Please sign in to comment.