Skip to content

Commit

Permalink
Update for Flask 1.0+
Browse files Browse the repository at this point in the history
fixes #100 - flask 1.x compatibility
  • Loading branch information
rsyring committed Mar 25, 2019
1 parent 03b3920 commit 63e3667
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 44 deletions.
11 changes: 3 additions & 8 deletions keg/app.py
Expand Up @@ -50,9 +50,7 @@ class Keg(flask.Flask):

_init_ran = False

def __init__(self, import_name=None, static_path=None, static_url_path=None,
static_folder='static', template_folder='templates', instance_path=None,
instance_relative_config=False, config=None):
def __init__(self, import_name=None, *args, **kwargs):

# flask requires an import name, so we should too.
if import_name is None and self.import_name is None:
Expand All @@ -63,12 +61,9 @@ def __init__(self, import_name=None, static_path=None, static_url_path=None,
import_name = import_name or self.import_name

self.keyring_manager = None
self._init_config = config or {}
self._init_config = kwargs.pop('config', {})

flask.Flask.__init__(self, import_name, static_path=static_path,
static_url_path=static_url_path, static_folder=static_folder,
template_folder=template_folder, instance_path=instance_path,
instance_relative_config=instance_relative_config)
flask.Flask.__init__(self, import_name, *args, **kwargs)

def make_config(self, instance_relative=False):
"""
Expand Down
23 changes: 0 additions & 23 deletions keg/compat.py
Expand Up @@ -13,26 +13,3 @@ def object_from_source(fpath, objname):
if not hasattr(tmpmodule, objname):
return None
return getattr(tmpmodule, objname)


def with_metaclass(meta, *bases):
# This requires a bit of explanation: the basic idea is to make a
# dummy metaclass for one level of class instantiation that replaces
# itself with the actual metaclass. Because of internal type checks
# we also need to make sure that we downgrade the custom metaclass
# for one level to something closer to type (that's why __call__ and
# __init__ comes back from type etc.).
#
# This has the advantage over six.with_metaclass in that it does not
# introduce dummy classes into the final MRO.
#
# copied from Flask._compat
class _MetaClass(meta):
__call__ = type.__call__
__init__ = type.__init__

def __new__(cls, name, this_bases, d):
if this_bases is None:
return type.__new__(cls, name, (), d)
return meta(name, bases, d)
return _MetaClass(str('temporary_class'), None, {})
21 changes: 11 additions & 10 deletions keg/web.py
Expand Up @@ -6,12 +6,12 @@
from blazeutils.strings import case_cw2us, case_cw2dash
import flask
from flask import request
from flask._compat import with_metaclass
from flask.views import MethodView, MethodViewType, http_method_funcs
import six
from werkzeug.datastructures import MultiDict
from werkzeug.utils import validate_arguments, ArgumentValidationError

from keg.compat import with_metaclass
from keg.extensions import lazy_gettext as _


Expand Down Expand Up @@ -84,17 +84,18 @@ def _call_with_expected_args(view, calling_args, method, method_is_bound=True):


class _ViewMeta(MethodViewType):

def __new__(cls, clsname, bases, attr):
rules = attr.pop('_rules', [])
viewcls = super(_ViewMeta, cls).__new__(cls, clsname, bases, attr)
def __init__(cls, name, bases, d):
MethodViewType.__init__(cls, name, bases, d)
rules = []
if hasattr(cls, '_rules'):
rules = cls._rules
del cls._rules

# Assuming child views will always have a blueprint OR they are intended to be used like
# abstract classes and will never be routed to directly.
if viewcls.blueprint is not None:
viewcls.init_routes()
viewcls.init_blueprint(rules)
return viewcls
if cls.blueprint is not None:
cls.init_routes()
cls.init_blueprint(rules)


class BaseView(with_metaclass(_ViewMeta, MethodView)):
Expand Down Expand Up @@ -237,7 +238,7 @@ def method_with_rules(obj):
cls.view_funcs[method_route.endpoint] = view_func
mr_options['view_func'] = cls.view_funcs[method_route.endpoint]
cls.blueprint.add_url_rule(method_route.rule(), **mr_options)
if method_name in http_method_funcs:
if method_name in http_method_funcs and cls.methods:
# A @route() is being used on a method with the same name as an HTTP verb.
# Since this method is being explicitly routed, the automatic rule that would
# be created due to MethodView logic should not apply.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -40,7 +40,7 @@
'BlazeUtils',
'blinker',
'Click>=3.0',
'Flask<1.0.0',
'Flask',
'Flask-SQLAlchemy',
'pathlib',
'python-json-logger',
Expand Down
6 changes: 4 additions & 2 deletions tox.ini
@@ -1,11 +1,13 @@
[tox]
envlist = py{27,35,36,37}-{base,i18n},project
envlist = py{27,35,36,37}-{base,i18n},py27-lowest,py37-lowest,project


[testenv]
# Ignore all "not installed in testenv" warnings.
whitelist_externals = *
skip_install = true
commands =
lowest: pip install flask<1.0
pip install .[tests]
i18n: pip install .[i18n]
# Output installed versions to compare with previous test runs in case a dependency's change
Expand All @@ -25,7 +27,7 @@ commands =
keg {posargs}

[testenv:project]
basepython = python3.6
basepython = python3.7
skip_install = true
usedevelop = false
deps =
Expand Down

0 comments on commit 63e3667

Please sign in to comment.