Skip to content

Commit 8978cd3

Browse files
mdantoniosloria
authored andcommitted
Bump to webargs 6.0+; drop python 2 and marshmallow 2 compatibility (jmcarp#195)
* Compatibility fix to bump webargs requirement to 6.0+ Breaking change: in use_kwargs replaced locations:tuple with location:str * Dropped compatibility with python 2 * Bug fix * Restored tests on multiple schemas Inputs converted from dict to schemas with Meta.unknown=EXCLUDE * Bump marshmallow minimum version from 2.0.0 to 3.0.0 * Added a comment to explain the introduction of schemas in unknown = EXCLUDE used during tests * Run pyupgrade Co-authored-by: Steven Loria <[email protected]>
1 parent 34735d5 commit 8978cd3

20 files changed

+124
-112
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ language: python
22
cache: pip
33
sudo: false
44
env:
5-
- MARSHMALLOW_VERSION="==2.13.0"
5+
- MARSHMALLOW_VERSION="==3.0.0"
66
- MARSHMALLOW_VERSION=""
77
python:
8-
- '2.7'
98
- '3.5'
109
- '3.6'
1110
before_install:

docs/conf.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
from __future__ import unicode_literals
3-
41
import datetime as dt
52
import os
63
import sys
@@ -29,7 +26,7 @@
2926
source_suffix = '.rst'
3027
master_doc = 'index'
3128
project = 'flask-apispec'
32-
copyright = 'Joshua Carp and contributors {0:%Y}'.format(dt.datetime.utcnow())
29+
copyright = 'Joshua Carp and contributors {:%Y}'.format(dt.datetime.utcnow())
3330

3431
version = release = flask_apispec.__version__
3532

docs/requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ sphinx
22
sphinx-issues
33
sphinx-rtd-theme
44

5-
six
65
flask
76
apispec
87
webargs

examples/petstore.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
# -*- coding: utf-8 -*-
2-
3-
import six
41
import marshmallow as ma
52

63
from flask_apispec import ResourceMeta, Ref, doc, marshal_with, use_kwargs
74

5+
86
class Pet:
97
def __init__(self, name, type):
108
self.name = name
119
self.type = type
1210

11+
1312
class PetSchema(ma.Schema):
1413
name = ma.fields.Str()
1514
type = ma.fields.Str()
1615

17-
class PetResource(six.with_metaclass(ResourceMeta)):
16+
17+
class PetResource(metaclass=ResourceMeta):
1818
@use_kwargs({
1919
'category': ma.fields.Str(),
2020
'name': ma.fields.Str(),
@@ -23,6 +23,7 @@ class PetResource(six.with_metaclass(ResourceMeta)):
2323
def get(self):
2424
return Pet('calici', 'cat')
2525

26+
2627
class CatResource(PetResource):
2728
@use_kwargs({'category': ma.fields.Int()})
2829
@marshal_with(PetSchema(), code=201)
@@ -31,7 +32,7 @@ def get(self):
3132

3233
###
3334

34-
class CrudResource(six.with_metaclass(ResourceMeta)):
35+
class CrudResource(metaclass=ResourceMeta):
3536

3637
schema = None
3738

@@ -52,6 +53,7 @@ def put(self, id):
5253
def delete(self, id):
5354
pass
5455

56+
5557
class PetResource(CrudResource):
5658
schema = PetSchema
5759

@@ -77,7 +79,7 @@ def get_pet(pet_id):
7779
class MethodResourceMeta(ResourceMeta, flask.views.MethodViewType):
7880
pass
7981

80-
class MethodResource(six.with_metaclass(MethodResourceMeta, flask.views.MethodView)):
82+
class MethodResource(flask.views.MethodView, metaclass=MethodResourceMeta):
8183
methods = None
8284

8385
@doc(

flask_apispec/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# -*- coding: utf-8 -*-
21
from flask_apispec.views import ResourceMeta, MethodResource
32
from flask_apispec.annotations import doc, wrap_with, use_kwargs, marshal_with
43
from flask_apispec.extension import FlaskApiSpec

flask_apispec/annotations.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
# -*- coding: utf-8 -*-
2-
31
import functools
42

53
from flask_apispec import utils
64
from flask_apispec.wrapper import Wrapper
75

8-
def use_kwargs(args, locations=None, inherit=None, apply=None, **kwargs):
6+
7+
def use_kwargs(args, location=None, inherit=None, apply=None, **kwargs):
98
"""Inject keyword arguments from the specified webargs arguments into the
109
decorated view function.
1110
@@ -22,11 +21,12 @@ def get_pets(**kwargs):
2221
:param args: Mapping of argument names to :class:`Field <marshmallow.fields.Field>`
2322
objects, :class:`Schema <marshmallow.Schema>`, or a callable which accepts a
2423
request and returns a :class:`Schema <marshmallow.Schema>`
25-
:param locations: Default request locations to parse
24+
:param location: Default request location to parse
2625
:param inherit: Inherit args from parent classes
2726
:param apply: Parse request with specified args
2827
"""
29-
kwargs.update({'locations': locations})
28+
29+
kwargs.update({'location': location})
3030

3131
def wrapper(func):
3232
options = {
@@ -73,6 +73,7 @@ def wrapper(func):
7373
return activate(func)
7474
return wrapper
7575

76+
7677
def doc(inherit=None, **kwargs):
7778
"""Annotate the decorated view function or class with the specified Swagger
7879
attributes.
@@ -92,6 +93,7 @@ def wrapper(func):
9293
return activate(func)
9394
return wrapper
9495

96+
9597
def wrap_with(wrapper_cls):
9698
"""Use a custom `Wrapper` to apply annotations to the decorated function.
9799
@@ -102,11 +104,13 @@ def wrapper(func):
102104
return activate(func)
103105
return wrapper
104106

107+
105108
def annotate(func, key, options, **kwargs):
106109
annotation = utils.Annotation(options, **kwargs)
107110
func.__apispec__ = func.__dict__.get('__apispec__', {})
108111
func.__apispec__.setdefault(key, []).insert(0, annotation)
109112

113+
110114
def activate(func):
111115
if isinstance(func, type) or getattr(func, '__apispec__', {}).get('wrapped'):
112116
return func

flask_apispec/apidoc.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
1-
# -*- coding: utf-8 -*-
2-
31
import copy
42

5-
import six
6-
73
import apispec
84
from apispec.core import VALID_METHODS
95
from apispec.ext.marshmallow import MarshmallowPlugin
@@ -18,7 +14,7 @@
1814
[int(part) for part in apispec.__version__.split('.') if part.isdigit()]
1915
)
2016

21-
class Converter(object):
17+
class Converter:
2218

2319
def __init__(self, app, spec, document_options=True):
2420
self.app = app
@@ -54,7 +50,7 @@ def get_path(self, rule, target, **kwargs):
5450
'path': rule_to_path(rule),
5551
'operations': {
5652
method.lower(): self.get_operation(rule, view, parent=parent)
57-
for method, view in six.iteritems(operations)
53+
for method, view in operations.items()
5854
if method.lower() in (set(valid_methods) - excluded_methods)
5955
},
6056
}
@@ -95,9 +91,9 @@ def get_parameters(self, rule, view, docs, parent=None):
9591
else:
9692
converter = openapi.fields2parameters
9793
options = copy.copy(args.get('kwargs', {}))
98-
locations = options.pop('locations', None)
99-
if locations:
100-
options['default_in'] = locations[0]
94+
location = options.pop('location', None)
95+
if location:
96+
options['default_in'] = location
10197
elif 'default_in' not in options:
10298
options['default_in'] = 'body'
10399
extra_params += converter(schema, **options) if args else []

flask_apispec/extension.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# -*- coding: utf-8 -*-
21
import flask
32
import functools
43
import types
@@ -9,7 +8,7 @@
98
from flask_apispec.apidoc import ViewConverter, ResourceConverter
109

1110

12-
class FlaskApiSpec(object):
11+
class FlaskApiSpec:
1312
"""Flask-apispec extension.
1413
1514
Usage:

flask_apispec/paths.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
# -*- coding: utf-8 -*-
2-
31
import re
42

53
import werkzeug.routing
64

75
PATH_RE = re.compile(r'<(?:[^:<>]+:)?([^<>]+)>')
86

7+
98
def rule_to_path(rule):
109
return PATH_RE.sub(r'{\1}', rule.rule)
1110

@@ -18,6 +17,7 @@ def rule_to_path(rule):
1817

1918
DEFAULT_TYPE = ('string', None)
2019

20+
2121
def rule_to_params(rule, overrides=None):
2222
overrides = (overrides or {})
2323
result = [

flask_apispec/utils.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
1-
# -*- coding: utf-8 -*-
2-
31
import functools
42

5-
import six
63
import marshmallow as ma
74

5+
86
def resolve_resource(resource, **kwargs):
97
resource_class_args = kwargs.get('resource_class_args') or ()
108
resource_class_kwargs = kwargs.get('resource_class_kwargs') or {}
119
if isinstance(resource, type):
1210
return resource(*resource_class_args, **resource_class_kwargs)
1311
return resource
1412

13+
1514
def resolve_schema(schema, request=None):
1615
if isinstance(schema, type) and issubclass(schema, ma.Schema):
1716
schema = schema()
1817
elif callable(schema):
1918
schema = schema(request)
2019
return schema
2120

22-
class Ref(object):
21+
class Ref:
2322

2423
def __init__(self, key):
2524
self.key = key
2625

2726
def resolve(self, obj):
2827
return getattr(obj, self.key, None)
2928

29+
3030
def resolve_refs(obj, attr):
3131
if isinstance(attr, dict):
3232
return {
3333
key: resolve_refs(obj, value)
34-
for key, value in six.iteritems(attr)
34+
for key, value in attr.items()
3535
}
3636
if isinstance(attr, list):
3737
return [resolve_refs(obj, value) for value in attr]
3838
if isinstance(attr, Ref):
3939
return attr.resolve(obj)
4040
return attr
4141

42-
class Annotation(object):
42+
class Annotation:
4343

4444
def __init__(self, options=None, inherit=None, apply=None):
4545
self.options = options or []

0 commit comments

Comments
 (0)