Skip to content

Commit

Permalink
Fix support for marshmallow>=3.x; drop marshmallow<=2.0.0
Browse files Browse the repository at this point in the history
Also:

- Fix #62
- Test against py36
  • Loading branch information
sloria committed May 28, 2017
1 parent 8aecc43 commit 22c65b4
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 34 deletions.
5 changes: 2 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
language: python
sudo: false
python:
- "3.6"
- "3.5"
- "3.4"
- "3.3"
Expand All @@ -9,16 +10,14 @@ python:

env:
# Lowest supported version
- MARSHMALLOW_VERSION="==1.2.0"
- MARSHMALLOW_VERSION="==2.0.0"
# Latest release
- MARSHMALLOW_VERSION=""

install:
- travis_retry pip install -U -r dev-requirements.txt
- travis_retry pip install -U .
- travis_retry pip install -U marshmallow"$MARSHMALLOW_VERSION" --pre
- travis_retry pip install -U git+https://github.com/marshmallow-code/marshmallow@dev
- travis_retry pip install -U git+https://github.com/marshmallow-code/marshmallow-sqlalchemy@dev
before_script:
- flake8 .
script: py.test
10 changes: 10 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
Changelog
=========

0.8.0 (unreleased)
******************

* Fix compatibility with marshmallow>=3.0.

Support:

* *Backwards-incompatible*: Drop support for marshmallow<=2.0.0.
* Test against Python 3.6.

0.7.0 (2016-06-28)
******************

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2014-2016 Steven Loria and contributors
Copyright 2014-2017 Steven Loria and contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ flake8==2.4.1

# Soft requirements
flask-sqlalchemy
marshmallow-sqlalchemy>=0.6.0
marshmallow-sqlalchemy>=0.13.0
17 changes: 17 additions & 0 deletions flask_marshmallow/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"""Compatibility module.
This module should be considered private API.
"""
import marshmallow
from marshmallow.utils import get_value as _get_value

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

# marshmallow>=3.0 switches the order of the obj and attr arguments from previous versions
if _MARSHMALLOW_VERSION_INFO[0] >= 3:
get_value = _get_value
else:
def get_value(obj, attr, *args, **kwargs):
return _get_value(attr, obj, *args, **kwargs)
32 changes: 6 additions & 26 deletions flask_marshmallow/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,11 @@
import re

from flask import url_for
from werkzeug.routing import BuildError
from marshmallow import fields, utils
from marshmallow import fields
from marshmallow.compat import iteritems
try:
from marshmallow import missing
except ImportError: # marshmallow 1.2 support
from marshmallow.fields import missing
from marshmallow import missing

try:
# marshmallow 1.2
from marshmallow.exceptions import ForcedError
except ImportError:
has_forced_error = False
else: # marshmallow 2.0
has_forced_error = True
from .compat import get_value


_tpl_pattern = re.compile(r'\s*<\s*(\S*)\s*>\s*')
Expand Down Expand Up @@ -79,27 +69,17 @@ def _serialize(self, value, key, obj):
for name, attr_tpl in iteritems(self.params):
attr_name = _tpl(str(attr_tpl))
if attr_name:
attribute_value = utils.get_value(attr_name, obj, default=missing)
attribute_value = get_value(obj, attr_name, default=missing)
if attribute_value is not missing:
param_values[name] = attribute_value
else:
err = AttributeError(
raise AttributeError(
'{attr_name!r} is not a valid '
'attribute of {obj!r}'.format(attr_name=attr_name, obj=obj)
)
if has_forced_error:
raise ForcedError(err)
else:
raise err
else:
param_values[name] = attr_tpl
try:
return url_for(self.endpoint, **param_values)
except BuildError as err: # Make sure BuildErrors are raised
if has_forced_error:
raise ForcedError(err)
else:
raise err
return url_for(self.endpoint, **param_values)

UrlFor = URLFor

Expand Down
4 changes: 2 additions & 2 deletions flask_marshmallow/sqla.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ class Meta. The actual session from `flask_sqlalchemy` gets bound
"""
session = DummySession()

def __init__(self, meta):
def __init__(self, meta, **kwargs):
if not hasattr(meta, 'sqla_session'):
meta.sqla_session = self.session
super(SchemaOpts, self).__init__(meta)
super(SchemaOpts, self).__init__(meta, **kwargs)

class ModelSchema(msqla.ModelSchema, Schema):
"""ModelSchema that generates fields based on the
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

REQUIRES = [
'Flask',
'marshmallow>=1.2.0',
'marshmallow>=2.0.0',
'six>=1.9.0',
]

Expand Down Expand Up @@ -60,6 +60,7 @@ def read(fname):
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
],
test_suite='tests',
Expand Down

0 comments on commit 22c65b4

Please sign in to comment.