fab-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Fab-user] Possible issue stacking decorators


From: Erich Heine
Subject: Re: [Fab-user] Possible issue stacking decorators
Date: Fri, 15 Jul 2011 10:47:30 -0500

I would propose a "task protocol" like so:

1. @task wraps a function in a task object (if it is not already such an object)
2. Any decorator that assumes a task wraps the function in a task object, if it is not already such an object.
3. Any decorator that doesn't assume a task (but is officially part of fabric) must have semantics that can work with a task object or explicitly fails because it doesn't handle task objects.

To get there, some changes need to be made, but surprisingly few as adding attributes to a function or adding attributes to an object are the same basic thing.

This would result in:
1. No ordering requirements
2. fewer confusions over stacking issues.
3. a @task decorator that occasionally does nothing (but not worries, it still helps the readability of the code)

example code:

class Task(object):
    def __init__(self, f):
        self.f = f
    def __call__(self, *args, **kw):
        return self.f(*args, **kw)

def task(f):
    print "in task deco",
    if not isinstance(f, Task):
        print "making task"
        return Task(f)
    else:
        print "task already made"
        return f

def hostdeco(hostname):
    def actualdeco(f):
        f = task(f)
        print "in hostdeco setting hostname"
        f.hostname = hostname
        return f
    return actualdeco

print "setting up tasks"
print "@hostdeco then @task:"

@hostdeco("foo")
@task
def mytask():
    print "mytask"

print '------------------------------'
print "@task then @hostdeco"
# equivalent
@task
@hostdeco("foo")
def mytask2():
    print "mytask2"

print '------------------------------'
print "running tasks"
mytask()
mytask2()

outputs:

setting up tasks
@hostdeco then @task:
in task deco making task
in task deco task already made
in hostdeco setting hostname
------------------------------
@task then @hostdeco
in task deco making task
in hostdeco setting hostname
in task deco task already made
------------------------------
running tasks
mytask
mytask2

Regards,
Erich

On Thu, Jul 14, 2011 at 7:33 PM, Jeff Forcier <address@hidden> wrote:
Hi Corry,

On Thu, Jul 14, 2011 at 3:50 PM, Corry Haines <address@hidden> wrote:
> I have some fab files that stack decorators, and while trying the name
> spacing feature, I seem to have hit an odd issue.
> Below are some example files, but the basic issue is that some decorators do
> not seem to stack (and order matters).

Well, decorators in general always have an "order matters" behavior,
unfortunately -- since they are not guaranteed to always return the
function they were given.

This is the case with @task -- it wraps the function in a richer task class.

So, it does need to come first/at the top of the list of decorators.
We should probably add this to the docs so it's explicitly obvious.

Please let us know if that doesn't answer the question -- since *most*
of the other decorators don't care about the ordering (other Fab
decorators simply tack attributes onto the functions and return them)
it shouldn't be a problem, per se, to always stick @task at the top.

Best,
Jeff

--
Jeff Forcier
Unix sysadmin; Python/Ruby engineer
http://bitprophet.org

_______________________________________________
Fab-user mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/fab-user


reply via email to

[Prev in Thread] Current Thread [Next in Thread]