Skip to content
This repository was archived by the owner on Jan 28, 2022. It is now read-only.

Commit 1b55373

Browse files
committed
Fix: drop support for marshmallow 2
1 parent bdc5589 commit 1b55373

File tree

5 files changed

+31
-52
lines changed

5 files changed

+31
-52
lines changed

.travis.yml

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,10 @@ branches:
77

88
python:
99
- "3.6"
10-
- "2.7"
11-
12-
env:
13-
- MARSHMALLOW_VERSION=2.19.2
14-
- MARSHMALLOW_VERSION=3.0.0
15-
16-
matrix:
17-
exclude:
18-
- python: "2.7"
19-
env: MARSHMALLOW_VERSION=3.0.0
2010

2111
install:
22-
- pip install marshmallow==$MARSHMALLOW_VERSION
2312
- pip install -r requirements.txt -r test-requirements.txt
2413

25-
script: coverage run --source=marshmallow_objects setup.py test
26-
after_success: codecov
27-
2814
stages:
2915
- pep8
3016
- test
@@ -36,6 +22,9 @@ jobs:
3622
script: flake8 --show-source
3723
install: pip install flake8
3824
after_success: skip
25+
- stage: test
26+
script: coverage run --source=marshmallow_objects setup.py test
27+
after_success: codecov
3928
- stage: deploy
4029
script: skip
4130
install: skip

ChangeLog

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
CHANGES
22
=======
33

4+
* Drop support for marshmallow 2
5+
46
1.0.23
57
------
68

marshmallow_objects/models.py

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,9 @@
22
import contextlib
33
import json
44
import pprint
5-
import sys
65
import threading
7-
try:
8-
import configparser
9-
import io
10-
except ImportError:
11-
import ConfigParser as configparser
12-
import StringIO as io
6+
import configparser
7+
import io
138

149
import marshmallow
1510
from marshmallow import fields
@@ -18,10 +13,6 @@
1813
except ImportError:
1914
pass
2015

21-
# Checking Marshmallow version
22-
MM2 = marshmallow.__version__.startswith('2')
23-
PY2 = int(sys.version_info[0]) == 2
24-
2516

2617
@marshmallow.post_load
2718
def __make_object__(self, data, **kwargs):
@@ -51,7 +42,7 @@ def __new__(mcs, name, parents, dct):
5142
schema_fields[method_name] = dct[method_name]
5243

5344
elif hasattr(
54-
value, '__marshmallow_tags__' if MM2 else
45+
value,
5546
'__marshmallow_hook__') or key in ('Meta', 'on_bind_field',
5647
'handle_error'):
5748
schema_fields[key] = value
@@ -72,6 +63,7 @@ def __new__(mcs, name, parents, dct):
7263
def __call__(cls, *args, **kwargs):
7364
if kwargs.pop('__post_load__', False):
7465
kwargs.pop("many", None)
66+
kwargs.pop("unknown", None)
7567
schema = kwargs.pop('__schema__')
7668
obj = cls.__new__(cls, *args, **kwargs)
7769
obj.__dump_lock__ = threading.RLock()
@@ -87,7 +79,8 @@ def __call__(cls, *args, **kwargs):
8779
context = kwargs.pop('context', None)
8880
partial = kwargs.pop('partial', None)
8981
many = kwargs.pop("many", None)
90-
obj = cls.load(kwargs, many=many, context=context, partial=partial)
82+
unknown = kwargs.pop('unknown', None)
83+
obj = cls.load(kwargs, many=many, context=context, partial=partial, unknown=unknown)
9184
return obj
9285

9386

@@ -126,8 +119,6 @@ class Model(with_metaclass(ModelMeta)):
126119

127120
@classmethod
128121
def __get_schema_class__(cls, **kwargs):
129-
if MM2:
130-
kwargs.setdefault('strict', True)
131122
return cls.__schema_class__(**kwargs)
132123

133124
def __setattr_default__(self, key, value):
@@ -179,18 +170,14 @@ def context(self, value):
179170
self.__schema__.context = value
180171

181172
@classmethod
182-
def load(cls, data, context=None, many=None, partial=None):
173+
def load(cls, data, context=None, many=None, partial=None, unknown=None):
183174
schema = cls.__get_schema_class__(context=context, partial=partial)
184-
loaded = schema.load(data, many=many)
185-
if MM2:
186-
return loaded[0]
175+
loaded = schema.load(data, many=many, unknown=unknown)
187176
return loaded
188177

189178
def dump(self):
190179
with self.__dump_mode_on__():
191180
dump = self.__schema__.dump(self)
192-
if MM2:
193-
return dump.data
194181
return dump
195182

196183
@classmethod
@@ -199,16 +186,16 @@ def load_json(cls,
199186
context=None,
200187
many=None,
201188
partial=None,
189+
unknown=None,
202190
*args,
203191
**kwargs):
204192
schema = cls.__get_schema_class__(context=context)
205193
loaded = schema.loads(data,
206194
many=many,
207195
partial=partial,
196+
unknown=unknown,
208197
*args,
209198
**kwargs)
210-
if MM2:
211-
return loaded[0]
212199
return loaded
213200

214201
def dump_json(self):
@@ -220,22 +207,19 @@ def load_yaml(cls,
220207
context=None,
221208
many=None,
222209
partial=None,
210+
unknown=None,
223211
*args,
224212
**kwargs):
225-
loaded = yaml.load(data, *args, **kwargs)
226-
return cls.load(loaded, context=context, many=many, partial=partial)
213+
loaded = yaml.load(data, Loader=yaml.FullLoader)
214+
return cls.load(loaded, context=context, many=many, partial=partial, unknown=unknown)
227215

228216
def dump_yaml(self, default_flow_style=False):
229217
return yaml.dump(self.dump(), default_flow_style=default_flow_style)
230218

231219
@classmethod
232220
def load_ini(cls, data, context=None, partial=None, **kwargs):
233221
parser = configparser.ConfigParser(**kwargs)
234-
if PY2:
235-
fp = io.StringIO(data)
236-
parser.readfp(fp)
237-
else:
238-
parser.read_string(data)
222+
parser.read_string(data)
239223
ddata = {s: dict(parser.items(s)) for s in parser.sections()}
240224
ddata.update(parser.defaults())
241225
return cls.load(ddata, context=context, partial=partial)
@@ -258,8 +242,6 @@ def dump_ini(self, **kwargs):
258242
@classmethod
259243
def validate(cls, data, context=None, many=None, partial=None):
260244
kwargs = {'context': context}
261-
if MM2:
262-
kwargs['strict'] = False
263245
schema = cls.__get_schema_class__(**kwargs)
264246
return schema.validate(data, many=many, partial=partial)
265247

@@ -297,8 +279,6 @@ def dump_many(data, context=None):
297279
else:
298280
schema = obj.__get_schema_class__(context=context)
299281
obj_data = schema.dump(obj)
300-
if MM2:
301-
obj_data = obj_data[0]
302282
ret.append(obj_data)
303283
elif (isinstance(obj, collections.Sequence)
304284
and not isinstance(obj, str)):

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
marshmallow
1+
marshmallow>=3.0.0

tests/test_models.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Meta:
2828
def on_bind_field(self, field_name, field_obj):
2929
pass
3030

31-
def handle_error(self, error, data):
31+
def handle_error(self, error, data, many, partial):
3232
pass
3333

3434

@@ -289,7 +289,7 @@ def test_load_yaml_partial(self):
289289
@unittest.skipIf(skip_yaml, 'PyYaml is not installed')
290290
def test_dump_yaml(self):
291291
a = A(test_field='foo')
292-
ydata = yaml.load(a.dump_yaml())
292+
ydata = yaml.load(a.dump_yaml(), Loader=yaml.FullLoader)
293293
self.assertEqual(self.data, ydata)
294294

295295
def test_dump_ordered(self):
@@ -298,6 +298,14 @@ def test_dump_ordered(self):
298298
self.assertIsInstance(a, collections.OrderedDict)
299299
self.assertIsInstance(b, dict)
300300

301+
def test_load_unknwon(self):
302+
data = dict(test_field='foo', unknown_b="B", a=dict(test_field='bar', unknown_b="B"))
303+
with self.assertRaises(marshmallow.ValidationError):
304+
B.load(data)
305+
b = B.load(data, unknown=marshmallow.EXCLUDE)
306+
self.assertEqual(b.test_field, 'foo')
307+
self.assertEqual(b.a.test_field, 'bar')
308+
301309

302310
class TestContext(unittest.TestCase):
303311
def setUp(self):
@@ -439,7 +447,7 @@ def test_dump_json(self):
439447
def test_dump_yaml(self):
440448
bb = B.load(self.data, many=True)
441449
ydata = marshmallow.dump_many_yaml(bb)
442-
ddata = yaml.load(ydata)
450+
ddata = yaml.load(ydata, Loader=yaml.FullLoader)
443451
self.assertEqual(self.data, ddata)
444452

445453

0 commit comments

Comments
 (0)