Permalink
Browse files

Fixed to handle order of views in controller

Before this change, the definition order of views had been lost.
and the order of dispatching was random.
  • Loading branch information...
hirokiky committed Nov 3, 2013
1 parent 2c4ed7a commit d7a840c09ce30af10dc81fd86fbbf21772910833
Showing with 28 additions and 8 deletions.
  1. +10 −2 tests/test_controller.py
  2. +13 −6 uiro/controller.py
  3. +5 −0 uiro/view.py
View
@@ -9,8 +9,13 @@ def target_class():
def test_init(target_class):
class Controller(target_class):
def yui_view(self):
return 'yui'
yui_view._order = 1
def ritsu_view(self):
return 'ritsu'
ritsu_view._order = 0
def get_mio(self):
return 'mio'
@@ -20,15 +25,17 @@ def _mugi_view(self):
actual = Controller()
assert len(actual.views) == 1
assert actual.views[0]() == 'ritsu'
assert len(actual.views) == 2
assert actual.views[0].__name__ == 'ritsu_view'
assert actual.views[1].__name__ == 'yui_view'
def test_call(target_class):
def mio_decorator(func):
def wraped(*args, **kwargs):
return func(*args, **kwargs) + ' x mio'
func._wrapped = wraped
func._order = 0
return func
class Controller(target_class):
@@ -52,6 +59,7 @@ def view_callable(request):
target = target_class()
view_callable._wrapped = not_matched_wrapped
view_callable._order = 0
target.views = [view_callable]
actual = target('request')
View
@@ -5,7 +5,18 @@
from uiro.view import ViewNotMatched
class BaseController(object):
class ControllerMetaClass(type):
def __new__(cls, name, bases, attrs):
super_new = super(ControllerMetaClass, cls).__new__
new_class = super_new(cls, name, bases, attrs)
new_class.views = [value for name, value in attrs.items()
if not name.startswith('_') and name.endswith('_view')]
new_class.views.sort(key=lambda x: x._order)
return new_class
class BaseController(metaclass=ControllerMetaClass):
""" Base WSGI application class to handle Views.
Controllers try to call methods containing '_view' suffix on it's name.
@@ -33,11 +44,7 @@ def post_view(self, request):
Check the behavior of view_config for more detail.
"""
def __init__(self):
self.views = []
for attr_names in dir(self):
if not attr_names.startswith('_') and attr_names.endswith('_view'):
self.views.append(getattr(self, attr_names))
views = []
@wsgify(RequestClass=Request)
def __call__(self, request):
View
@@ -1,3 +1,4 @@
import itertools
from functools import reduce
from uiro.template import get_app_template
@@ -21,6 +22,9 @@ def get_base_wrappers(method='get', template_name=''):
return wrappers
_counter = itertools.count()
def view_config(
method='get',
template_name='',
@@ -42,6 +46,7 @@ def _wrapped(*args, **kwargs):
reversed(wrappers + [view_callable])
)(*args, **kwargs)
view_callable._wrapped = _wrapped
view_callable._order = next(_counter)
return view_callable
return wrapper

0 comments on commit d7a840c

Please sign in to comment.