[Top][All Lists]
[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