def test_curry_comparable(): def foo(a, b, c=1): return a + b + c f1 = curry(foo, 1, c=2) f2 = curry(foo, 1, c=2) g1 = curry(foo, 1, c=3) h1 = curry(foo, c=2) h2 = h1(c=2) h3 = h1() assert f1 == f2 assert not (f1 != f2) assert f1 != g1 assert not (f1 == g1) assert f1 != h1 assert h1 == h2 assert h1 == h3 # test function comparison works def bar(a, b, c=1): return a + b + c b1 = curry(bar, 1, c=2) assert b1 != f1 assert {f1, f2, g1, h1, h2, h3, b1, b1()} == {f1, g1, h1, b1} # test unhashable input unhash1 = curry(foo, []) assert raises(TypeError, lambda: hash(unhash1)) unhash2 = curry(foo, c=[]) assert raises(TypeError, lambda: hash(unhash2))
def test_nth(): assert nth(2, 'ABCDE') == 'C' assert nth(2, iter('ABCDE')) == 'C' assert nth(1, (3, 2, 1)) == 2 assert nth(0, {'foo': 'bar'}) == 'foo' assert raises(StopIteration, lambda: nth(10, {10: 'foo'})) assert nth(-2, 'ABCDE') == 'D' assert raises(ValueError, lambda: nth(-2, iter('ABCDE')))
def test_excepts(): # These are descriptors, make sure this works correctly. assert excepts.__name__ == 'excepts' assert ('A wrapper around a function to catch exceptions and\n' ' dispatch to a handler.\n') in excepts.__doc__ def idx(a): """idx docstring """ return [1, 2].index(a) def handler(e): """handler docstring """ assert isinstance(e, ValueError) return -1 excepting = excepts(ValueError, idx, handler) assert excepting(1) == 0 assert excepting(2) == 1 assert excepting(3) == -1 assert excepting.__name__ == 'idx_excepting_ValueError' assert 'idx docstring' in excepting.__doc__ assert 'ValueError' in excepting.__doc__ assert 'handler docstring' in excepting.__doc__ def getzero(a): """getzero docstring """ return a[0] excepting = excepts((IndexError, KeyError), getzero) assert excepting([]) is None assert excepting([1]) == 1 assert excepting({}) is None assert excepting({0: 1}) == 1 assert excepting.__name__ == 'getzero_excepting_IndexError_or_KeyError' assert 'getzero docstring' in excepting.__doc__ assert 'return_none' in excepting.__doc__ assert 'Returns None' in excepting.__doc__ def raise_(a): """A function that raises an instance of the exception type given. """ raise a() excepting = excepts((ValueError, KeyError), raise_) assert excepting(ValueError) is None assert excepting(KeyError) is None assert raises(TypeError, lambda: excepting(TypeError)) assert raises(NotImplementedError, lambda: excepting(NotImplementedError)) excepting = excepts(object(), object(), object()) assert excepting.__name__ == 'excepting' assert excepting.__doc__ == excepts.__doc__
def test_curry_passes_errors(): @curry def f(a, b): if not isinstance(a, int): raise TypeError() return a + b assert f(1, 2) == 3 assert raises(TypeError, lambda: f('1', 2)) assert raises(TypeError, lambda: f('1')(2)) assert raises(TypeError, lambda: f(1, 2, 3))
def test_curry_simple(): cmul = curry(mul) double = cmul(2) assert callable(double) assert double(10) == 20 assert repr(cmul) == repr(mul) cmap = curry(map) assert list(cmap(inc)([1, 2, 3])) == [2, 3, 4] assert raises(TypeError, lambda: curry()) assert raises(TypeError, lambda: curry({1: 2}))
def test_peek(): alist = ["Alice", "Bob", "Carol"] element, blist = peek(alist) element == alist[0] assert list(blist) == alist assert raises(StopIteration, lambda: peek([]))
def test_curry_kwargs(): def f(a, b, c=10): return (a + b) * c f = curry(f) assert f(1, 2, 3) == 9 assert f(1)(2, 3) == 9 assert f(1, 2) == 30 assert f(1, c=3)(2) == 9 assert f(c=3)(1, 2) == 9 def g(a=1, b=10, c=0): return a + b + c cg = curry(g, b=2) assert cg() == 3 assert cg(b=3) == 4 assert cg(a=0) == 2 assert cg(a=0, b=1) == 1 assert cg(0) == 2 # pass "a" as arg, not kwarg assert raises(TypeError, lambda: cg(1, 2)) # pass "b" as arg AND kwarg def h(x, func=int): return func(x) if platform.python_implementation() != 'PyPy'\ or platform.python_version_tuple()[0] != '3': # Bug on PyPy3<2.5 # __init__ must not pick func as positional arg assert curry(h)(0.0) == 0 assert curry(h)(func=str)(0.0) == '0.0' assert curry(h, func=str)(0.0) == '0.0'
def test_pluck(): assert list(pluck(0, [[0, 1], [2, 3], [4, 5]])) == [0, 2, 4] assert list(pluck([0, 1], [[0, 1, 2], [3, 4, 5]])) == [(0, 1), (3, 4)] assert list(pluck(1, [[0], [0, 1]], None)) == [None, 1] data = [{'id': 1, 'name': 'cheese'}, {'id': 2, 'name': 'pies', 'price': 1}] assert list(pluck('id', data)) == [1, 2] assert list(pluck('price', data, 0)) == [0, 1] assert list(pluck(['id', 'name'], data)) == [(1, 'cheese'), (2, 'pies')] assert list(pluck(['name'], data)) == [('cheese',), ('pies',)] assert list(pluck(['price', 'other'], data, 0)) == [(0, 0), (1, 0)] assert raises(IndexError, lambda: list(pluck(1, [[0]]))) assert raises(KeyError, lambda: list(pluck('name', [{'id': 1}]))) assert list(pluck(0, [[0, 1], [2, 3], [4, 5]], no_default2)) == [0, 2, 4] assert raises(IndexError, lambda: list(pluck(1, [[0]], no_default2)))
def test_curry_call(): @curry def add(x, y): return x + y assert raises(TypeError, lambda: add.call(1)) assert add(1)(2) == add.call(1, 2) assert add(1)(2) == add(1).call(2)
def test_diff(): assert raises(TypeError, lambda: list(diff())) assert raises(TypeError, lambda: list(diff([1, 2]))) assert raises(TypeError, lambda: list(diff([1, 2], 3))) assert list(diff([1, 2], (1, 2), iter([1, 2]))) == [] assert list(diff([1, 2, 3], (1, 10, 3), iter([1, 2, 10]))) == [ (2, 10, 2), (3, 3, 10)] assert list(diff([1, 2], [10])) == [(1, 10)] assert list(diff([1, 2], [10], default=None)) == [(1, 10), (2, None)] # non-variadic usage assert raises(TypeError, lambda: list(diff([]))) assert raises(TypeError, lambda: list(diff([[]]))) assert raises(TypeError, lambda: list(diff([[1, 2]]))) assert raises(TypeError, lambda: list(diff([[1, 2], 3]))) assert list(diff([(1, 2), (1, 3)])) == [(2, 3)] data1 = [{'cost': 1, 'currency': 'dollar'}, {'cost': 2, 'currency': 'dollar'}] data2 = [{'cost': 100, 'currency': 'yen'}, {'cost': 300, 'currency': 'yen'}] conversions = {'dollar': 1, 'yen': 0.01} def indollars(item): return conversions[item['currency']] * item['cost'] list(diff(data1, data2, key=indollars)) == [ ({'cost': 2, 'currency': 'dollar'}, {'cost': 300, 'currency': 'yen'})]
def test_get(): assert get(1, 'ABCDE') == 'B' assert list(get([1, 3], 'ABCDE')) == list('BD') assert get('a', {'a': 1, 'b': 2, 'c': 3}) == 1 assert get(['a', 'b'], {'a': 1, 'b': 2, 'c': 3}) == (1, 2) assert get('foo', {}, default='bar') == 'bar' assert get({}, [1, 2, 3], default='bar') == 'bar' assert get([0, 2], 'AB', 'C') == ('A', 'C') assert get([0], 'AB') == ('A',) assert get([], 'AB') == () assert raises(IndexError, lambda: get(10, 'ABC')) assert raises(KeyError, lambda: get(10, {'a': 1})) assert raises(TypeError, lambda: get({}, [1, 2, 3])) assert raises(TypeError, lambda: get([1, 2, 3], 1, None)) assert raises(KeyError, lambda: get('foo', {}, default=no_default2))
def test_make_func(): f = make_func('') assert raises(ValueError, lambda: f()) assert raises(TypeError, lambda: f(1)) f = make_func('', raise_if_called=False) assert f() assert raises(TypeError, lambda: f(1)) f = make_func('x, y=1', raise_if_called=False) assert f(1) assert f(x=1) assert f(1, 2) assert f(x=1, y=2) assert raises(TypeError, lambda: f(1, 2, 3)) f = make_func('(x, y=1)', raise_if_called=False) assert f(1) assert f(x=1) assert f(1, 2) assert f(x=1, y=2) assert raises(TypeError, lambda: f(1, 2, 3))
async def test_memoize(): fn_calls = [0] # Storage for side effects async def f(x, y): """ A docstring """ fn_calls[0] += 1 return x + y mf = memoize(f) assert await mf(2, 3) is await mf(2, 3) assert fn_calls == [1] # function was only called once assert mf.__doc__ == f.__doc__ assert raises(TypeError, lambda: await mf(1, {}))
def test_memoize_key_signature(): # Single argument should not be tupled as a key. No keywords. mf = memoize(lambda x: False, cache={1: True}) assert mf(1) is True assert mf(2) is False # Single argument must be tupled if signature has varargs. No keywords. mf = memoize(lambda x, *args: False, cache={(1, ): True, (1, 2): 2}) assert mf(1) is True assert mf(2) is False assert mf(1, 1) is False assert mf(1, 2) == 2 assert mf((1, 2)) is False # More than one argument is always tupled. No keywords. mf = memoize(lambda x, y: False, cache={(1, 2): True}) assert mf(1, 2) is True assert mf(1, 3) is False assert raises(TypeError, lambda: mf((1, 2))) # Nullary function (no inputs) uses empty tuple as the key mf = memoize(lambda: False, cache={(): True}) assert mf() is True # Single argument must be tupled if there are keyword arguments, because # keyword arguments may be passed as unnamed args. mf = memoize(lambda x, y=0: False, cache={ ((1, ), frozenset((('y', 2), ))): 2, ((1, 2), None): 3 }) assert mf(1, y=2) == 2 assert mf(1, 2) == 3 assert mf(2, y=2) is False assert mf(2, 2) is False assert mf(1) is False assert mf((1, 2)) is False # Keyword-only signatures must still have an "args" tuple. mf = memoize(lambda x=0: False, cache={ (None, frozenset((('x', 1), ))): 1, ((1, ), None): 2 }) assert mf() is False assert mf(x=1) == 1 assert mf(1) == 2
def test_curry_attributes_readonly(): def foo(a, b, c=1): return a + b + c f = curry(foo, 1, c=2) assert raises(AttributeError, lambda: setattr(f, 'args', (2, ))) assert raises(AttributeError, lambda: setattr(f, 'keywords', {'c': 3})) assert raises(AttributeError, lambda: setattr(f, 'func', f)) assert raises(AttributeError, lambda: delattr(f, 'args')) assert raises(AttributeError, lambda: delattr(f, 'keywords')) assert raises(AttributeError, lambda: delattr(f, 'func'))
def test_factory(self): D, kw = self.D, self.kw assert merge(defaultdict(int, D({1: 2})), D({2: 3})) == {1: 2, 2: 3} assert (merge(defaultdict(int, D({1: 2})), D({2: 3}), factory=lambda: defaultdict(int)) == defaultdict( int, D({ 1: 2, 2: 3 }))) assert not (merge(defaultdict(int, D({1: 2})), D({2: 3}), factory=lambda: defaultdict(int)) == { 1: 2, 2: 3 }) assert raises(TypeError, lambda: merge(D({1: 2}), D({2: 3}), factoryy=dict))
def test_random_sample(): alist = list(range(100)) assert list(random_sample(prob=1, seq=alist, random_state=2016)) == alist mk_rsample = lambda rs=1: list(random_sample(prob=0.1, seq=alist, random_state=rs)) rsample1 = mk_rsample() assert rsample1 == mk_rsample() rsample2 = mk_rsample(1984) randobj = Random(1984) assert rsample2 == mk_rsample(randobj) assert rsample1 != rsample2 assert mk_rsample(object) == mk_rsample(object) assert mk_rsample(object) != mk_rsample(object()) assert mk_rsample(b"a") == mk_rsample(u"a") assert raises(TypeError, lambda: mk_rsample([]))
def test_curried_bad_qualname(): @aiotoolz.curry class Bad(object): __qualname__ = 'aiotoolz.functoolz.not.a.valid.path' assert raises(pickle.PicklingError, lambda: pickle.dumps(Bad))
def test_curry_bad_types(): assert raises(TypeError, lambda: curry(1))