Skip to content
This repository was archived by the owner on Jun 6, 2024. It is now read-only.

Commit 7ae6124

Browse files
authored
Test against Python 3.8 and 3.9; drop marshmallow 2 support (#332)
* Test against Python 3.9; don't test ma 2 * Remove ma 2 compatibility code * Update changelog * pre-commit autoupdate
1 parent 18279dc commit 7ae6124

15 files changed

+153
-317
lines changed

.pre-commit-config.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/asottile/pyupgrade
3-
rev: v2.7.2
3+
rev: v2.7.3
44
hooks:
55
- id: pyupgrade
66
args: ["--py36-plus"]
@@ -10,7 +10,7 @@ repos:
1010
- id: black
1111
language_version: python3
1212
- repo: https://gitlab.com/pycqa/flake8
13-
rev: 3.8.3
13+
rev: 3.8.4
1414
hooks:
1515
- id: flake8
1616
additional_dependencies: ['flake8-bugbear==20.1.4']

CHANGELOG.rst

+11
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
Changelog
33
*********
44

5+
0.24.0 (unreleased)
6+
===================
7+
8+
Deprecations/Removals:
9+
10+
* Drop support for marshmallow 2, which is now EOL (:pr:`332`).
11+
12+
Other changes:
13+
14+
* Test against Python 3.8 and 3.9 (:pr:`332`).
15+
516
0.23.2 (2020-07-20)
617
===================
718

README.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ marshmallow-jsonapi
1414
:target: https://marshmallow-jsonapi.readthedocs.io/
1515
:alt: Documentation
1616

17-
.. image:: https://badgen.net/badge/marshmallow/2,3?list=1
17+
.. image:: https://badgen.net/badge/marshmallow/3
1818
:target: https://marshmallow.readthedocs.io/en/latest/upgrading.html
19-
:alt: marshmallow 2/3 compatible
19+
:alt: marshmallow 3 compatible
2020

2121
.. image:: https://badgen.net/badge/code%20style/black/000
2222
:target: https://github.com/ambv/black

azure-pipelines.yml

+25-27
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ trigger:
22
branches:
33
include: [dev, test-me-*]
44
tags:
5-
include: ['*']
5+
include: ["*"]
66

77
# Run builds nightly to catch incompatibilities with new marshmallow releases
88
schedules:
9-
- cron: "0 0 * * *"
10-
displayName: Daily midnight build
11-
branches:
12-
include:
13-
- dev
14-
always: "true"
9+
- cron: "0 0 * * *"
10+
displayName: Daily midnight build
11+
branches:
12+
include:
13+
- dev
14+
always: "true"
1515

1616
resources:
1717
repositories:
@@ -22,23 +22,21 @@ resources:
2222
ref: refs/heads/sloria
2323

2424
jobs:
25-
- template: job--python-tox.yml@sloria
26-
parameters:
27-
toxenvs:
28-
- lint
29-
30-
- py36-marshmallow2
31-
- py36-marshmallow3
32-
33-
- py37-marshmallow2
34-
- py37-marshmallow3
35-
36-
- py37-marshmallowdev
37-
38-
- docs
39-
40-
os: linux
41-
- template: job--pypi-release.yml@sloria
42-
parameters:
43-
dependsOn:
44-
- tox_linux
25+
- template: job--python-tox.yml@sloria
26+
parameters:
27+
toxenvs:
28+
- lint
29+
30+
- py36-marshmallow3
31+
- py37-marshmallow3
32+
- py38-marshmallow3
33+
- py39-marshmallow3
34+
- py39-marshmallowdev
35+
36+
- docs
37+
38+
os: linux
39+
- template: job--pypi-release.yml@sloria
40+
parameters:
41+
dependsOn:
42+
- tox_linux

marshmallow_jsonapi/fields.py

+13-43
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
# Make core fields importable from marshmallow_jsonapi
1010
from marshmallow.fields import * # noqa
1111
from marshmallow.base import SchemaABC
12-
from marshmallow.utils import is_collection, missing as missing_
12+
from marshmallow.utils import is_collection, missing as missing_, get_value
1313

14-
from .utils import get_value, resolve_params, _MARSHMALLOW_VERSION_INFO
14+
from .utils import resolve_params
1515

1616

1717
_RECURSIVE_NESTED = "self"
@@ -203,7 +203,7 @@ def extract_value(self, data):
203203
result = self.schema.load(
204204
{"data": data, "included": self.root.included_data}
205205
)
206-
return result.data if _MARSHMALLOW_VERSION_INFO[0] < 3 else result
206+
return result
207207

208208
id_value = data.get("id")
209209

@@ -278,28 +278,16 @@ def _serialize(self, value, attr, obj):
278278

279279
def _serialize_included(self, value):
280280
result = self.schema.dump(value)
281-
282-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
283-
data = result.data
284-
else:
285-
data = result
286-
287-
item = data["data"]
281+
item = result["data"]
288282
self.root.included_data[(item["type"], item["id"])] = item
289283
for key, value in self.schema.included_data.items():
290284
self.root.included_data[key] = value
291285

292286
def _get_id(self, value):
293-
if _MARSHMALLOW_VERSION_INFO[0] >= 3:
294-
if self.__schema:
295-
return self.schema.get_attribute(value, self.id_field, value)
296-
else:
297-
return get_value(value, self.id_field, value)
287+
if self.__schema:
288+
return self.schema.get_attribute(value, self.id_field, value)
298289
else:
299-
if self.__schema:
300-
return self.schema.get_attribute(self.id_field, value, value)
301-
else:
302-
return get_value(value, self.id_field, value)
290+
return get_value(value, self.id_field, value)
303291

304292

305293
class DocumentMeta(Field):
@@ -323,28 +311,19 @@ class Meta:
323311

324312
def __init__(self, **kwargs):
325313
super().__init__(**kwargs)
326-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
327-
self.load_from = _DOCUMENT_META_LOAD_FROM
328-
else:
329-
self.data_key = _DOCUMENT_META_LOAD_FROM
314+
self.data_key = _DOCUMENT_META_LOAD_FROM
330315

331316
def _deserialize(self, value, attr, data, **kwargs):
332317
if isinstance(value, collections.abc.Mapping):
333318
return value
334319
else:
335-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
336-
self.fail("invalid")
337-
else:
338-
raise self.make_error("invalid")
320+
raise self.make_error("invalid")
339321

340322
def _serialize(self, value, *args, **kwargs):
341323
if isinstance(value, collections.abc.Mapping):
342324
return super()._serialize(value, *args, **kwargs)
343325
else:
344-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
345-
self.fail("invalid")
346-
else:
347-
raise self.make_error("invalid")
326+
raise self.make_error("invalid")
348327

349328

350329
class ResourceMeta(Field):
@@ -368,25 +347,16 @@ class Meta:
368347

369348
def __init__(self, **kwargs):
370349
super().__init__(**kwargs)
371-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
372-
self.load_from = _RESOURCE_META_LOAD_FROM
373-
else:
374-
self.data_key = _RESOURCE_META_LOAD_FROM
350+
self.data_key = _RESOURCE_META_LOAD_FROM
375351

376352
def _deserialize(self, value, attr, data, **kwargs):
377353
if isinstance(value, collections.abc.Mapping):
378354
return value
379355
else:
380-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
381-
self.fail("invalid")
382-
else:
383-
raise self.make_error("invalid")
356+
raise self.make_error("invalid")
384357

385358
def _serialize(self, value, *args, **kwargs):
386359
if isinstance(value, collections.abc.Mapping):
387360
return super()._serialize(value, *args, **kwargs)
388361
else:
389-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
390-
self.fail("invalid")
391-
else:
392-
raise self.make_error("invalid")
362+
raise self.make_error("invalid")

marshmallow_jsonapi/schema.py

+5-19
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from .fields import BaseRelationship, DocumentMeta, ResourceMeta
88
from .fields import _RESOURCE_META_LOAD_FROM, _DOCUMENT_META_LOAD_FROM
99
from .exceptions import IncorrectTypeError
10-
from .utils import resolve_params, _MARSHMALLOW_VERSION_INFO, get_dump_key
10+
from .utils import resolve_params
1111

1212
TYPE = "type"
1313
ID = "id"
@@ -215,15 +215,9 @@ def unwrap_request(self, data, many, **kwargs):
215215
return self.unwrap_item(data)
216216

217217
def on_bind_field(self, field_name, field_obj):
218-
"""Schema hook override. When binding fields, set ``data_key`` (on marshmallow 3) or
219-
load_from (on marshmallow 2) to the inflected form of field_name.
220-
"""
221-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
222-
if not field_obj.load_from:
223-
field_obj.load_from = self.inflect(field_name)
224-
else:
225-
if not field_obj.data_key:
226-
field_obj.data_key = self.inflect(field_name)
218+
"""Schema hook override. When binding fields, set ``data_key`` to the inflected form of field_name."""
219+
if not field_obj.data_key:
220+
field_obj.data_key = self.inflect(field_name)
227221
return None
228222

229223
def _do_load(self, data, many=None, **kwargs):
@@ -249,14 +243,6 @@ def _do_load(self, data, many=None, **kwargs):
249243
formatted_messages = self.format_errors(error_messages, many=many)
250244
err.messages = formatted_messages
251245
raise err
252-
else:
253-
# On marshmallow 2, _do_load returns a tuple (load_data, errors)
254-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
255-
data, error_messages = result
256-
if "_schema" in error_messages:
257-
error_messages = error_messages["_schema"]
258-
formatted_messages = self.format_errors(error_messages, many=many)
259-
return data, formatted_messages
260246
return result
261247

262248
def _extract_from_included(self, data):
@@ -358,7 +344,7 @@ def format_item(self, item):
358344

359345
# Get the schema attributes so we can confirm `dump-to` values exist
360346
attributes = {
361-
(get_dump_key(self.fields[field]) or field): field for field in self.fields
347+
(self.fields[field].data_key or field): field for field in self.fields
362348
}
363349

364350
for field_name, value in item.items():

marshmallow_jsonapi/utils.py

+1-21
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,7 @@
44
"""
55
import re
66

7-
import marshmallow
8-
from marshmallow.utils import get_value as _get_value, missing
9-
10-
_MARSHMALLOW_VERSION_INFO = tuple(
11-
[int(part) for part in marshmallow.__version__.split(".") if part.isdigit()]
12-
)
13-
14-
15-
def get_dump_key(field):
16-
if _MARSHMALLOW_VERSION_INFO[0] < 3:
17-
return field.dump_to
18-
else:
19-
return field.data_key
20-
21-
22-
if _MARSHMALLOW_VERSION_INFO[0] >= 3:
23-
get_value = _get_value
24-
else:
25-
26-
def get_value(obj, attr, *args, **kwargs):
27-
return _get_value(attr, obj, *args, **kwargs)
7+
from marshmallow.utils import get_value, missing
288

299

3010
_tpl_pattern = re.compile(r"\s*<\s*(\S*)\s*>\s*")

setup.py

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ def read(fname):
5959
"Programming Language :: Python :: 3",
6060
"Programming Language :: Python :: 3.6",
6161
"Programming Language :: Python :: 3.7",
62+
"Programming Language :: Python :: 3.8",
63+
"Programming Language :: Python :: 3.9",
6264
],
6365
test_suite="tests",
6466
project_urls={

tests/base.py

+7-23
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,10 @@
44
from marshmallow import validate
55

66
from marshmallow_jsonapi import Schema, fields
7-
from marshmallow_jsonapi.utils import _MARSHMALLOW_VERSION_INFO
87

98
fake = Factory.create()
109

1110

12-
def unpack(return_value):
13-
return return_value.data if _MARSHMALLOW_VERSION_INFO[0] < 3 else return_value
14-
15-
1611
class Bunch:
1712
def __init__(self, **kwargs):
1813
for key, val in kwargs.items():
@@ -51,32 +46,21 @@ def get_top_level_links(self, data, many):
5146

5247
class Meta:
5348
type_ = "people"
54-
strict = True # for marshmallow 2
5549

5650

5751
class KeywordSchema(Schema):
5852
id = fields.Str()
5953
keyword = fields.Str(required=True)
6054

6155
def get_attribute(self, attr, obj, default):
62-
if _MARSHMALLOW_VERSION_INFO[0] >= 3:
63-
if obj == "id":
64-
return md5(
65-
super(Schema, self)
66-
.get_attribute(attr, "keyword", default)
67-
.encode("utf-8")
68-
).hexdigest()
69-
else:
70-
return super(Schema, self).get_attribute(attr, obj, default)
56+
if obj == "id":
57+
return md5(
58+
super(Schema, self)
59+
.get_attribute(attr, "keyword", default)
60+
.encode("utf-8")
61+
).hexdigest()
7162
else:
72-
if attr == "id":
73-
return md5(
74-
super(Schema, self)
75-
.get_attribute("keyword", obj, default)
76-
.encode("utf-8")
77-
).hexdigest()
78-
else:
79-
return super(Schema, self).get_attribute(attr, obj, default)
63+
return super(Schema, self).get_attribute(attr, obj, default)
8064

8165
class Meta:
8266
type_ = "keywords"

0 commit comments

Comments
 (0)