flask-classy icon indicating copy to clipboard operation
flask-classy copied to clipboard

Fix issue #22 (rule lookup does not count inheritance)

Open ivan-kleshnin opened this issue 11 years ago • 3 comments

Fix issue https://github.com/apiguy/flask-classy/issues/22

The issue is with cache strictly bound to the class object. Rule lookup doesn't count inheritance correctly.

Then, if you have

class BaseView(FlaskView):
    @route('/delete/<id>')
    def delete(self, id=None):
        pass

class PostsView(BaseView):
    @route('test')  # any route to provide new cache obj instance
    def test(self): # and break behavior
        pass

It generates

Map(...
    <Rule '/posts/<id>' (OPTIONS, DELETE) ...>,
)

While it should generate

Map(...
 <Rule '/delete/<id>' (HEAD, OPTIONS, GET) ...>
)

Diff looks a bit scary but basically i added just 3 lines to deal with inheritance. This fix passes all tests.

I fixed this fragment

if hasattr(cls, "_rule_cache") and name in cls._rule_cache:
    for idx, cached_rule in enumerate(cls._rule_cache[name]):
        ...
elif name in special_methods:
    ...

by wrapping in .mro() lookup loop:

for _cls in cls.mro()[:-1]: # -1 to skip `object` lookup
    if hasattr(_cls, "_rule_cache") and name in _cls._rule_cache:
        for idx, cached_rule in enumerate(_cls._rule_cache[name]):
            ...
        break
else: # no break
    if name in special_methods: # elif -> if
        ... 

I'm not 100% sure about solution. Flask-Classy is kinda tricky ;) I'm sure even less about git though...

ivan-kleshnin avatar Jun 11 '13 16:06 ivan-kleshnin

This is great. Let me play with it just a bit and add some tests specifically for it.

apiguy avatar Jun 12 '13 10:06 apiguy

After the Python 3 changes (pretty substantial changes were needed) this will need to be modified. I think the general idea is still the right way to do it though. I'll spend some more time on this tomorrow and hopefully get it out.

apiguy avatar Jun 14 '13 03:06 apiguy

Yep, thank you.

ivan-kleshnin avatar Jun 14 '13 08:06 ivan-kleshnin