Skip to content

Commit

Permalink
Added @dispatch(prefix)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastien committed Feb 13, 2012
1 parent c26c147 commit 899f2f0
Showing 1 changed file with 52 additions and 20 deletions.
72 changes: 52 additions & 20 deletions src/cuisine.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,28 +178,60 @@ def sudo(*args, **kwargs):
#
# =============================================================================

def dispatch(function):
"""Dispatches the current function to specific implementation. For instance
@dispatch("package_ensure", select="package_system").
def dispatch(prefix=None):
"""Dispatches the current function to specific implementation. The `prefix`
parameter indicates the common option prefix, and the `option_select()`
function will determine the function suffix.
For instance the package functions are defined like that:
{{{
@dispatch("package")
def package_ensure(...):
...
def package_ensure_apt(...):
...
def package_ensure_yum(...):
...
}}}
and then when a user does
{{{
cuisine.option_select("package", "yum")
cuisine.package_ensure(...)
}}}
then the `dispatch` function will dispatch `package_ensure` to
`package_ensure_yum`.
If your prefix is the first word of the function name before the
first `_` then you can simply use `@dispatch` without parameters.
"""
def wrapper(*args, **kwargs):
function_name = function.__name__
prefix = function_name.split("_")[0]
select = fabric.api.env.get("option_" + prefix)
assert select, "No option defined for: %s, call select_%s(<YOUR OPTION>) to set it" % (prefix, prefix)
function_name = function.__name__ + "_" + select
specific = eval(function_name)
if specific:
if type(specific) == types.FunctionType:
return specific(*args, **kwargs)
def dispatch_wrapper(function, prefix=prefix):
def wrapper(*args, **kwargs):
function_name = function.__name__
_prefix = prefix or function_name.split("_")[0]
select = fabric.api.env.get("option_" + _prefix)
assert select, "No option defined for: %s, call select_%s(<YOUR OPTION>) to set it" % (_prefix, prefix)
function_name = function.__name__ + "_" + select
specific = eval(function_name)
if specific:
if type(specific) == types.FunctionType:
return specific(*args, **kwargs)
else:
raise Exception("Function expected for: " + function_name)
else:
raise Exception("Function expected for: " + function_name)
else:
raise Exception("Function variant not defined: " + function_name)
# We copy name and docstring
wrapper.__name__ = function.__name__
wrapper.__doc__ = function.__doc__
return wrapper
raise Exception("Function variant not defined: " + function_name)
# We copy name and docstring
wrapper.__name__ = function.__name__

This comment has been minimized.

Copy link
@swaroopch

swaroopch Feb 13, 2012

Contributor

A python idiom query - can the built-in functools.update_wrapper help with this?

This comment has been minimized.

Copy link
@ghoseb

ghoseb Feb 14, 2012

What about the functools.wraps decorator?

This comment has been minimized.

Copy link
@sebastien

sebastien Feb 14, 2012

Author Owner

It would make the code a little bit too cryptic in this case, I think. upate_wrapper is good enough.

wrapper.__doc__ = function.__doc__
return wrapper
if type(prefix) == types.FunctionType:
return dispatch_wrapper(prefix, None)
else:
return dispatch_wrapper


# =============================================================================
#
Expand Down

1 comment on commit 899f2f0

@sebastien
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good point! Will do it.

Please sign in to comment.