Skip to content

Instantly share code, notes, and snippets.

Created September 13, 2014 10:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/04b1ef14c466ba4544df to your computer and use it in GitHub Desktop.
Save anonymous/04b1ef14c466ba4544df to your computer and use it in GitHub Desktop.
import inspect
class n_partialable(object):
@staticmethod
def arity_evaluation_checker(function):
is_class = inspect.isclass(function)
if is_class:
function = function.__init__
function_info = inspect.getargspec(function)
function_args = function_info.args
if is_class:
# This is to handle the fact that self will get passed in automatically.
function_args = function_args[1:]
def evaluation_checker(*args, **kwargs):
acceptable_kwargs = function_args[len(args):]
kwarg_keys = set(kwargs.keys())
# Make sure that we didn't get an argument we can't handle.
assert kwarg_keys.issubset(acceptable_kwargs)
needed_args = function_args[len(args):]
if function_info.defaults:
needed_args = needed_args[:-len(function_info.defaults)]
return not needed_args or kwarg_keys.issuperset(needed_args)
return evaluation_checker
def __init__(self, function, evaluation_checker=None, args=None, kwargs=None):
self.function = function
self.evaluation_checker = (evaluation_checker or
self.arity_evaluation_checker(function))
self.args = args or ()
self.kwargs = kwargs or {}
def __call__(self, *args, **kwargs):
new_args = self.args + args
new_kwargs = self.kwargs.copy()
new_kwargs.update(kwargs)
if self.evaluation_checker(*new_args, **new_kwargs):
return self.function(*new_args, **new_kwargs)
else:
return type(self)(self.function, self.evaluation_checker,
new_args, new_kwargs)
def __get__(self, obj, obj_type):
bound = type(self)(self.function, self.evaluation_checker,
args=self.args + (obj,), kwargs=self.kwargs)
setattr(obj, self.function.__name__, bound)
return bound
n_partialable = n_partialable(n_partialable)
@justanr
Copy link

justanr commented Nov 7, 2014

Why type(self) instead of self.__class__? Also, I'd recommend applying functools.update_wrapper in __init__. But this looks really interesting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment