From 899f2f01d999f90e3effd6d2d4062076bfd416b1 Mon Sep 17 00:00:00 2001 From: Sebastien Pierre Date: Mon, 13 Feb 2012 15:26:45 -0500 Subject: [PATCH] Added @dispatch(prefix) --- src/cuisine.py | 72 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/src/cuisine.py b/src/cuisine.py index b40004a..d3f7237 100644 --- a/src/cuisine.py +++ b/src/cuisine.py @@ -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() 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() 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__ + wrapper.__doc__ = function.__doc__ + return wrapper + if type(prefix) == types.FunctionType: + return dispatch_wrapper(prefix, None) + else: + return dispatch_wrapper + # ============================================================================= #