def test_introspect_curry_py3(): if not PY3: return f = toolz.curry(make_func('')) assert num_required_args(f) == 0 assert is_arity(0, f) assert has_varargs(f) is False assert has_keywords(f) is False f = toolz.curry(make_func('x')) assert num_required_args(f) == 0 assert is_arity(0, f) is False assert is_arity(1, f) is False assert has_varargs(f) is False assert has_keywords(f) # A side-effect of being curried f = toolz.curry(make_func('x, y, z=0')) assert num_required_args(f) == 0 assert is_arity(0, f) is False assert is_arity(1, f) is False assert is_arity(2, f) is False assert is_arity(3, f) is False assert has_varargs(f) is False assert has_keywords(f) f = toolz.curry(make_func('*args, **kwargs')) assert num_required_args(f) == 0 assert has_varargs(f) assert has_keywords(f)
def test_inspect_signature_property(): if not PY3: return # By adding AddX to our signature registry, we can inspect the class # itself and objects of the class. `inspect.signature` doesn't like # it when `obj.__signature__` is a property. class AddX(object): def __init__(self, func): self.func = func def __call__(self, addx, *args, **kwargs): return addx + self.func(*args, **kwargs) @property def __signature__(self): sig = inspect.signature(self.func) params = list(sig.parameters.values()) kind = inspect.Parameter.POSITIONAL_OR_KEYWORD newparam = inspect.Parameter('addx', kind) params = [newparam] + params return sig.replace(parameters=params) addx = AddX(lambda x: x) sig = inspect.signature(addx) assert sig == inspect.Signature(parameters=[ inspect.Parameter('addx', inspect.Parameter.POSITIONAL_OR_KEYWORD), inspect.Parameter('x', inspect.Parameter.POSITIONAL_OR_KEYWORD)]) assert num_required_args(AddX) is False _sigs.signatures[AddX] = (_sigs.expand_sig((0, lambda func: None)),) assert num_required_args(AddX) == 1 del _sigs.signatures[AddX]
def should_curry(func): if not callable(func) or isinstance(func, curry): return False nargs = num_required_args(func) if nargs is None or nargs > 1: return True else: return nargs == 1 and has_keywords(func)
def test_num_required_args(): assert num_required_args(lambda: None) == 0 assert num_required_args(lambda x: None) == 1 assert num_required_args(lambda x, *args: None) == 1 assert num_required_args(lambda x, **kwargs: None) == 1 assert num_required_args(lambda x, y, *args, **kwargs: None) == 2 assert num_required_args(map) == 2 assert num_required_args(dict) is None
def test_inspect_wrapped_property(): class Wrapped(object): def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): return self.func(*args, **kwargs) @property def __wrapped__(self): return self.func func = lambda x: x wrapped = Wrapped(func) assert inspect.signature(func) == inspect.signature(wrapped) assert num_required_args(Wrapped) is None _sigs.signatures[Wrapped] = (_sigs.expand_sig((0, lambda func: None)), ) assert num_required_args(Wrapped) == 1
def test_inspect_wrapped_property(): class Wrapped(object): def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): return self.func(*args, **kwargs) @property def __wrapped__(self): return self.func func = lambda x: x wrapped = Wrapped(func) if PY3: assert inspect.signature(func) == inspect.signature(wrapped) assert num_required_args(Wrapped) == (False if PY33 else None) _sigs.signatures[Wrapped] = (_sigs.expand_sig((0, lambda func: None)),) assert num_required_args(Wrapped) == 1
def should_curry(f): num = num_required_args(f) return num is None or num > 1 or num == 1 and has_keywords(f) is not False