Created
September 13, 2014 10:22
-
-
Save anonymous/04b1ef14c466ba4544df to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
Regarding type vs class see
http://stackoverflow.com/questions/9610993/python-type-or-class-or-is
functools.update_wrapper is a good idea
I'm maintaining this at https://github.com/IvanMalison/okcupyd/blob/master/okcupyd/util/currying.py
and the docs are here: http://okcupyd.readthedocs.org/en/latest/okcupyd.util.html?highlight=curry#okcupyd.util.currying.curry
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Why
type(self)
instead ofself.__class__
? Also, I'd recommend applyingfunctools.update_wrapper
in__init__
. But this looks really interesting.