Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

functional style decorators proof of concept #39

Open
faassen opened this issue Sep 27, 2016 · 0 comments
Open

functional style decorators proof of concept #39

faassen opened this issue Sep 27, 2016 · 0 comments

Comments

@faassen
Copy link
Member

faassen commented Sep 27, 2016

Here is some proof of concept code I wrote that demonstrates how Dectate might work if we use a more functional way to define directives, instead of using the action subclasses we do now. The idea is to make the signature of the directive be the correct signature right away if we generated code or alternatively used a library like wrapt.

This does require us to give up on the current with statement as that allows you to define a subset of functions. This could be replaced by pointing people in the direction of functools.partial.

class App(object):
    registered = []

    @classmethod
    def commit(cls):
        for perform, config, obj in cls.registered:
            kw = {}
            for key, value in config.items():
                for name, factory in config.items():
                    c = getattr(cls, name, None)
                    if c is None:
                        c = factory()
                        setattr(cls, name, c)
                    kw[name] = c
            perform(obj, **kw)


def action(config):
    def get_directive(func):
        def wrapper(cls, *args, **kw):
            info = func(cls, *args, **kw)

            def register(obj):
                cls.registered.append(
                    (info.perform, get_directive.config, obj))
                return obj
            return register
        return classmethod(wrapper)
    get_directive.config = config
    return get_directive


class Info(object):
    def __init__(self, perform):
        self.perform = perform


class MyApp(App):
    @action(config={'r': dict})
    def mydecorator(cls, message):
        def perform(obj, r):
            r[message] = obj
        return Info(perform)


@MyApp.mydecorator('foo')
def myfunction():
    return "the function"


MyApp.commit()


assert MyApp.r == {'foo': myfunction}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant