Skip to content

Commit

Permalink
Merge pull request #583 from marshmallow-code/drop_ma2
Browse files Browse the repository at this point in the history
Drop marshmallow 2
  • Loading branch information
lafrech committed Aug 31, 2020
2 parents d60ac66 + 6e0817e commit 938f6ca
Show file tree
Hide file tree
Showing 10 changed files with 16 additions and 106 deletions.
4 changes: 2 additions & 2 deletions README.rst
Expand Up @@ -14,9 +14,9 @@ apispec
:target: https://apispec.readthedocs.io/
:alt: Documentation

.. image:: https://badgen.net/badge/marshmallow/2,3?list=1
.. image:: https://badgen.net/badge/marshmallow/3?list=1
:target: https://marshmallow.readthedocs.io/en/latest/upgrading.html
:alt: marshmallow 2/3 compatible
:alt: marshmallow 3 only

.. image:: https://badgen.net/badge/OAS/2,3?list=1&color=cyan
:target: https://github.com/OAI/OpenAPI-Specification
Expand Down
5 changes: 0 additions & 5 deletions azure-pipelines.yml
Expand Up @@ -27,14 +27,9 @@ jobs:
toxenvs:
- lint

- py35-marshmallow2
- py35-marshmallow3

- py36-marshmallow3

- py37-marshmallow3

- py38-marshmallow2
- py38-marshmallow3

- py38-marshmallowdev
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Expand Up @@ -6,7 +6,7 @@
"validation": ["prance[osv]>=0.11"],
"lint": ["flake8==3.8.3", "flake8-bugbear==20.1.4", "pre-commit~=2.4"],
"docs": [
"marshmallow>=2.19.2",
"marshmallow>=3.0.0",
"pyyaml==5.3.1",
"sphinx==3.2.1",
"sphinx-issues==1.2.0",
Expand All @@ -16,7 +16,7 @@
EXTRAS_REQUIRE["tests"] = (
EXTRAS_REQUIRE["yaml"]
+ EXTRAS_REQUIRE["validation"]
+ ["marshmallow>=2.19.2", "pytest", "mock"]
+ ["marshmallow>=3.0.0", "pytest", "mock"]
)
EXTRAS_REQUIRE["dev"] = EXTRAS_REQUIRE["tests"] + EXTRAS_REQUIRE["lint"] + ["tox"]

Expand Down
20 changes: 5 additions & 15 deletions src/apispec/ext/marshmallow/field_converter.py
Expand Up @@ -17,11 +17,6 @@

RegexType = type(re.compile(""))

MARSHMALLOW_VERSION_INFO = tuple(
[int(part) for part in marshmallow.__version__.split(".") if part.isdigit()]
)


# marshmallow field => (JSON Schema type, format)
DEFAULT_FIELD_MAPPING = {
marshmallow.fields.Integer: ("integer", "int32"),
Expand Down Expand Up @@ -212,8 +207,7 @@ def field2default(self, field, **kwargs):
else:
default = field.missing
if default is not marshmallow.missing and not callable(default):
if MARSHMALLOW_VERSION_INFO[0] >= 3:
default = field._serialize(default, None, None)
default = field._serialize(default, None, None)
ret["default"] = default
return ret

Expand Down Expand Up @@ -437,10 +431,7 @@ def list2properties(self, field, **kwargs):
"""
ret = {}
if isinstance(field, marshmallow.fields.List):
inner_field = (
field.inner if MARSHMALLOW_VERSION_INFO[0] >= 3 else field.container
)
ret["items"] = self.field2property(inner_field)
ret["items"] = self.field2property(field.inner)
return ret

def dict2properties(self, field, **kwargs):
Expand All @@ -454,8 +445,7 @@ def dict2properties(self, field, **kwargs):
"""
ret = {}
if isinstance(field, marshmallow.fields.Dict):
if MARSHMALLOW_VERSION_INFO[0] >= 3:
value_field = field.value_field
if value_field:
ret["additionalProperties"] = self.field2property(value_field)
value_field = field.value_field
if value_field:
ret["additionalProperties"] = self.field2property(value_field)
return ret
26 changes: 2 additions & 24 deletions src/apispec/ext/marshmallow/openapi.py
Expand Up @@ -22,11 +22,6 @@
)


MARSHMALLOW_VERSION_INFO = tuple(
[int(part) for part in marshmallow.__version__.split(".") if part.isdigit()]
)


__location_map__ = {
"match_info": "path",
"query": "query",
Expand Down Expand Up @@ -60,21 +55,6 @@ def __init__(self, openapi_version, schema_name_resolver, spec):
# Schema references
self.refs = {}

@staticmethod
def _observed_name(field, name):
"""Adjust field name to reflect `dump_to` and `load_from` attributes.
:param Field field: A marshmallow field.
:param str name: Field name
:rtype: str
"""
if MARSHMALLOW_VERSION_INFO[0] < 3:
# use getattr in case we're running against older versions of marshmallow.
dump_to = getattr(field, "dump_to", None)
load_from = getattr(field, "load_from", None)
return dump_to or load_from or name
return field.data_key or name

def resolve_nested_schema(self, schema):
"""Return the OpenAPI representation of a marshmallow Schema.
Expand Down Expand Up @@ -143,9 +123,7 @@ def schema2parameters(

return [
self._field2parameter(
field_obj,
name=self._observed_name(field_obj, field_name),
location=location,
field_obj, name=field_obj.data_key or field_name, location=location,
)
for field_name, field_obj in fields.items()
]
Expand Down Expand Up @@ -212,7 +190,7 @@ def fields2jsonschema(self, fields, *, ordered=False, partial=None):
jsonschema = {"type": "object", "properties": OrderedDict() if ordered else {}}

for field_name, field_obj in fields.items():
observed_field_name = self._observed_name(field_obj, field_name)
observed_field_name = field_obj.data_key or field_name
property = self.field2property(field_obj)
jsonschema["properties"][observed_field_name] = property

Expand Down
10 changes: 2 additions & 8 deletions tests/schemas.py
@@ -1,7 +1,5 @@
from marshmallow import Schema, fields

from apispec.ext.marshmallow.openapi import MARSHMALLOW_VERSION_INFO


class PetSchema(Schema):
description = dict(id="Pet id", name="Pet name", password="Password")
Expand Down Expand Up @@ -40,12 +38,8 @@ class PatternedObjectSchema(Schema):

class SelfReferencingSchema(Schema):
id = fields.Int()
if MARSHMALLOW_VERSION_INFO[0] < 3:
single = fields.Nested("self")
many = fields.Nested("self", many=True)
else:
single = fields.Nested(lambda: SelfReferencingSchema())
many = fields.Nested(lambda: SelfReferencingSchema(many=True))
single = fields.Nested(lambda: SelfReferencingSchema())
many = fields.Nested(lambda: SelfReferencingSchema(many=True))


class OrderedSchema(Schema):
Expand Down
4 changes: 0 additions & 4 deletions tests/test_ext_marshmallow.py
Expand Up @@ -7,7 +7,6 @@

from apispec import APISpec
from apispec.ext.marshmallow import MarshmallowPlugin
from apispec.ext.marshmallow.openapi import MARSHMALLOW_VERSION_INFO
from apispec.ext.marshmallow import common
from apispec.exceptions import APISpecError
from .schemas import (
Expand Down Expand Up @@ -883,9 +882,6 @@ def test_schema_with_default_values(self, spec):
assert "default" not in props["numbers"]


@pytest.mark.skipif(
MARSHMALLOW_VERSION_INFO[0] < 3, reason="Values ignored in marshmallow 2"
)
class TestDictValues:
def test_dict_values_resolve_to_additional_properties(self, spec):
class SchemaWithDict(Schema):
Expand Down
7 changes: 1 addition & 6 deletions tests/test_ext_marshmallow_field.py
Expand Up @@ -4,8 +4,6 @@
import pytest
from marshmallow import fields, validate

from apispec.ext.marshmallow.openapi import MARSHMALLOW_VERSION_INFO

from .schemas import CategorySchema, CustomList, CustomStringField, CustomIntegerField
from .utils import build_ref

Expand Down Expand Up @@ -95,10 +93,7 @@ def test_boolean_field_with_false_missing(spec_fixture):


def test_datetime_field_with_missing(spec_fixture):
if MARSHMALLOW_VERSION_INFO[0] < 3:
field = fields.Date(missing=dt.date(2014, 7, 18).isoformat())
else:
field = fields.Date(missing=dt.date(2014, 7, 18))
field = fields.Date(missing=dt.date(2014, 7, 18))
res = spec_fixture.openapi.field2property(field)
assert res["default"] == dt.date(2014, 7, 18).isoformat()

Expand Down
40 changes: 2 additions & 38 deletions tests/test_ext_marshmallow_openapi.py
Expand Up @@ -3,7 +3,6 @@
from marshmallow import fields, Schema, validate

from apispec.ext.marshmallow import MarshmallowPlugin
from apispec.ext.marshmallow.openapi import MARSHMALLOW_VERSION_INFO
from apispec import exceptions, utils, APISpec

from .schemas import CustomList, CustomStringField
Expand Down Expand Up @@ -71,36 +70,7 @@ class Meta:
assert props["email"]["format"] == "email"
assert props["email"]["description"] == "email address of the user"

@pytest.mark.skipif(
MARSHMALLOW_VERSION_INFO[0] >= 3, reason="Behaviour changed in marshmallow 3"
)
def test_schema2jsonschema_override_name_ma2(self, openapi):
class ExampleSchema(Schema):
_id = fields.Int(load_from="id", dump_to="id")
_dt = fields.Int(load_from="lf_no_match", dump_to="dt")
_lf = fields.Int(load_from="lf")
_global = fields.Int(load_from="global", dump_to="global")

class Meta:
exclude = ("_global",)

res = openapi.schema2jsonschema(ExampleSchema)
assert res["type"] == "object"
props = res["properties"]
# `_id` renamed to `id`
assert "_id" not in props and props["id"]["type"] == "integer"
# `load_from` and `dump_to` do not match, `dump_to` is used
assert "lf_no_match" not in props
assert props["dt"]["type"] == "integer"
# `load_from` and no `dump_to`, `load_from` is used
assert props["lf"]["type"] == "integer"
# `_global` excluded correctly
assert "_global" not in props and "global" not in props

@pytest.mark.skipif(
MARSHMALLOW_VERSION_INFO[0] < 3, reason="Behaviour changed in marshmallow 3"
)
def test_schema2jsonschema_override_name_ma3(self, openapi):
def test_schema2jsonschema_override_name(self, openapi):
class ExampleSchema(Schema):
_id = fields.Int(data_key="id")
_global = fields.Int(data_key="global")
Expand Down Expand Up @@ -184,13 +154,7 @@ class Meta:
assert "email" not in props

def test_observed_field_name_for_required_field(self, openapi):
if MARSHMALLOW_VERSION_INFO[0] < 3:
fields_dict = {
"user_id": fields.Int(load_from="id", dump_to="id", required=True)
}
else:
fields_dict = {"user_id": fields.Int(data_key="id", required=True)}

fields_dict = {"user_id": fields.Int(data_key="id", required=True)}
res = openapi.fields2jsonschema(fields_dict)
assert res["required"] == ["id"]

Expand Down
2 changes: 0 additions & 2 deletions tox.ini
@@ -1,15 +1,13 @@
[tox]
envlist=
lint
py{35,36,37,38}-marshmallow2
py{35,36,37,38}-marshmallow3
py38-marshmallowdev
docs

[testenv]
extras = tests
deps =
marshmallow2: marshmallow>=2.0.0,<3.0.0
marshmallow3: marshmallow>=3.0.0,<4.0.0
marshmallowdev: https://github.com/marshmallow-code/marshmallow/archive/dev.tar.gz
commands = pytest {posargs}
Expand Down

0 comments on commit 938f6ca

Please sign in to comment.