def test_recursive_pickle(): with AllowPickle(): f = partial(capture) f.__setstate__((f, (), {}, {})) try: for proto in range(pickle.HIGHEST_PROTOCOL + 1): with pytest.raises(RecursionError): pickle.dumps(f, proto) finally: f.__setstate__((capture, (), {}, {})) f = partial(capture) f.__setstate__((capture, (f, ), {}, {})) try: for proto in range(pickle.HIGHEST_PROTOCOL + 1): f_copy = pickle.loads(pickle.dumps(f, proto)) try: assert f_copy.args[0] is f_copy finally: f_copy.__setstate__((capture, (), {}, {})) finally: f.__setstate__((capture, (), {}, {})) f = partial(capture) f.__setstate__((capture, (), {'a': f}, {})) try: for proto in range(pickle.HIGHEST_PROTOCOL + 1): f_copy = pickle.loads(pickle.dumps(f, proto)) try: assert f_copy.keywords['a'] is f_copy finally: f_copy.__setstate__((capture, (), {}, {})) finally: f.__setstate__((capture, (), {}, {}))
def test_basic_examples(): p = partial(capture, T(1), T(2), a=T(10), b=T(20)) assert callable(p) assert p(T(3), T(4), b=T(30), c=T(40)) == ((T(1), T(2), T(3), T(4)), dict(a=T(10), b=T(30), c=T(40))) p = partial(map, lambda x: x * T(10)) assert list(p([T(1), T(2), T(3), T(4)])) == toT([10, 20, 30, 40])
def test_argument_checking(): # at least one argument with pytest.raises(TypeError): partial() # must be callable with pytest.raises(TypeError): partial(T(2))
def test_arg_combinations(): # exercise special code paths for zero args in either partial # object or the caller p = partial(capture) assert p() == ((), {}) assert p(T(1), T(2)) == ((T(1), T(2)), {}) p = partial(capture, T(1), T(2)) assert p() == ((T(1), T(2)), {}) assert p(T(3), T(4)) == ((T(1), T(2), T(3), T(4)), {})
def test_partial_from_partial_basic2(): # Two placeholders, one argument given p1 = partial(capture, partial._, T(2), partial._) p2 = partial(p1, T(1)) assert p1.args == (partial._, T(2), partial._) assert p1(T(1), T(3)) == ((T(1), T(2), T(3)), {}) assert p1(T(1), T(3), T(4)) == ((T(1), T(2), T(3), T(4)), {}) assert p2.args == (T(1), T(2), partial._) assert p2(T(3)) == ((T(1), T(2), T(3)), {}) assert p2(T(3), T(4)) == ((T(1), T(2), T(3), T(4)), {})
def test_partial_from_partial_basic5(): # Two placeholderss, three arguments given p1 = partial(capture, partial._, partial._, T(3)) p2 = partial(p1, T(1), T(2), T(4)) assert p1.args == (partial._, partial._, T(3)) assert p1(T(1), T(2)) == ((T(1), T(2), T(3)), {}) assert p1(T(1), T(2), T(4)) == ((T(1), T(2), T(3), T(4)), {}) assert p2.args == (T(1), T(2), T(3), T(4)) assert p2() == ((T(1), T(2), T(3), T(4)), {}) assert p2(T(5)) == ((T(1), T(2), T(3), T(4), T(5)), {})
def test_nested_partial_with_attribute(): # see issue 25137 def foo(bar): return bar p = partial(foo, 'first') p2 = partial(p, 'second') p2.new_attr = 'spam' assert p2.new_attr == 'spam'
def test_partial_sizeof(): p1 = partial(isinstance, 10, int) p2 = partial(isinstance, partial._, int) p3 = partial(isinstance, partial._, partial._) # The sizes should be different because each placeholder leads to one more # element in the posph array. sizes = [sys.getsizeof(p) for p in (p1, p2, p3)] assert sizes[2] > sizes[1] assert sizes[1] > sizes[0] # Also make sure that the difference is the same between 3 vs. 2 and 2 vs. 1 assert sizes[2] - sizes[1] == sizes[1] - sizes[0]
def test_partial_from_partial_basic3(): # One placeholders, two arguments given p1 = partial(capture, partial._, T(2)) p2 = partial(p1, T(1), T(3)) assert p1.args == (partial._, T(2)) assert p1(T(1)) == ((T(1), T(2)), {}) assert p1(T(1), T(3)) == ((T(1), T(2), T(3)), {}) assert p1(T(1), T(3), T(4)) == ((T(1), T(2), T(3), T(4)), {}) assert p2.args == (T(1), T(2), T(3)) assert p2() == ((T(1), T(2), T(3)), {}) assert p2(T(4)) == ((T(1), T(2), T(3), T(4)), {})
def test_attributes_unwritable(): p = partial(capture, T(1), T(2), a=T(10), b=T(20)) with pytest.raises(AttributeError): p.func = map with pytest.raises(AttributeError): p.args = (T(1), T(2)) with pytest.raises(AttributeError): p.keywords = {'a': T(1), 'b': T(2)} p = partial(hex) with pytest.raises(TypeError): del p.__dict__
def test_kw_combinations(): # exercise special code paths for no keyword args in # either the partial object or the caller p = partial(capture) assert p.keywords == {} assert p() == ((), {}) assert p(a=T(1)) == ((), {'a': T(1)}) p = partial(capture, a=T(1)) assert p.keywords == {'a': T(1)} assert p() == ((), {'a': T(1)}) assert p(b=T(2)) == ((), {'a': T(1), 'b': T(2)}) # keyword args in the call override those in the partial object assert p(a=T(3), b=T(2)) == ((), {'a': T(3), 'b': T(2)})
def test_partial_dict_setter(): p = partial(capture, b=10) with pytest.raises(TypeError): p.__dict__ = 10 p = partial(capture, b=10) p.__dict__ = {} assert signature(p) == (capture, (), {'b': 10}, {}) p = partial(capture, b=10) p.__dict__ = collections.OrderedDict() assert signature(p) == (capture, (), {'b': 10}, collections.OrderedDict()) assert isinstance(p.__dict__, collections.OrderedDict)
def test_partial_placeholder_missing_args(): p = partial(isinstance, partial._, int) with pytest.raises(TypeError, match='not enough values'): p() # partial with multiple placeholders and too many or too few arguments p = partial(isinstance, partial._, partial._) assert p.num_placeholders == 2 with pytest.raises(TypeError, match='not enough values'): p() with pytest.raises(TypeError, match='not enough values'): p(T(1))
def test_traverse(): """To test the traverse implementation we call gc.collect() while instances of all the C objects are still valid.""" acc = iteration_utilities.accumulate([]) app = iteration_utilities.applyfunc(lambda x: x, 1) cha = iteration_utilities.chained(int, float) cla = iteration_utilities.clamp([], 0, 1) com = iteration_utilities.complement(int) con = iteration_utilities.constant(1) dee = iteration_utilities.deepflatten([]) dup = iteration_utilities.duplicates([]) fli = iteration_utilities.flip(int) gro = iteration_utilities.grouper([], 2) ine = iteration_utilities.intersperse([], 1) iik = iteration_utilities.ItemIdxKey(10, 2) ite = iteration_utilities.iter_except(int, TypeError) mer = iteration_utilities.merge([]) nth = iteration_utilities.nth(1) pac = iteration_utilities.packed(int) par = iteration_utilities.partial(int, 10) rep = iteration_utilities.replicate([], 3) rou = iteration_utilities.roundrobin([]) see = iteration_utilities.Seen() sid = iteration_utilities.sideeffects([], lambda x: x) spl = iteration_utilities.split([], lambda x: True) sta = iteration_utilities.starfilter(lambda x: True, []) suc = iteration_utilities.successive([]) tab = iteration_utilities.tabulate(int) une = iteration_utilities.unique_everseen([]) unj = iteration_utilities.unique_justseen([]) gc.collect()
def test_pickle(): with AllowPickle(): f = partial(signature, ['asdf'], bar=[True]) f.attr = [] for proto in range(pickle.HIGHEST_PROTOCOL + 1): f_copy = pickle.loads(pickle.dumps(f, proto)) assert signature(f_copy) == signature(f)
def test_partial_with_lots_of_kwargs_with_duplicate(): p = partial(capture, a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8, i=9, j=10, k=11) r = p(a=12, b=13, c=14, d=15, e=16, f=17, g=18, h=19, i=20, j=21, k=22, l=23) assert r == (tuple(), dict(zip('abcdefghijkl', range(12, 24))))
def test_keyword(): # make sure keyword arguments are captured correctly for a in [T('a'), T(0), T(None), T(3.5)]: p = partial(capture, a=T(a)) expected = {'a': T(a), 'x': T(None)} empty, got = p(x=T(None)) assert expected == got and empty == ()
def test_partial_with_lots_of_kwargs(): """The purpose of this test is to test the vectorcall implementation which converts the kwargs passed to the call to a set to speed-up the lookup behavior. """ p = partial(capture, a=1, b=2, c=3, d=4, e=5, f=6, g=7, h=8, i=9, j=10, k=11) r = p(l=12, m=13, n=14, o=15, p=16, q=17, r=18, s=19, t=20, u=21, v=22, w=23) assert r == (tuple(), dict(zip('abcdefghijklmnopqrstuvw', range(1, 24))))
def test_partial_placeholder_basic(): p = partial(isinstance, partial._, int) assert p.num_placeholders == 1 assert p.args == (partial._, int) assert p(20) assert not p(1.2) assert not p(T(1.2))
def test_no_side_effects(): # make sure there are no side effects that affect subsequent calls p = partial(capture, T(0), a=T(1)) args1, kw1 = p(T(1), b=T(2)) assert args1 == (T(0), T(1)) and kw1 == {'a': T(1), 'b': T(2)} args2, kw2 = p() assert args2 == (T(0), ) and kw2 == {'a': T(1)}
def test_partial_placeholder_deepcopy(): p = partial(isinstance, partial._, int) p2 = copy.deepcopy(p) assert p2.num_placeholders == 1 assert p2(20) assert not p2(1.2) assert not p2(T(1.2))
def test_weakref(): f = partial(int, base=16) p = weakref.proxy(f) assert f.func == p.func f = None with pytest.raises(ReferenceError): p.func
def test_kwargs_copy(): # Issue #29532: Altering a kwarg dictionary passed to a constructor # should not affect a partial object after creation d = {'a': T(3)} p = partial(capture, **d) assert p() == ((), {'a': T(3)}) d['a'] = T(5) assert p(), ((), {'a': T(3)})
def test_positional(): # make sure positional arguments are captured correctly for args in [(), (T(0), ), (T(0), T(1)), (T(0), T(1), T(2)), (T(0), T(1), T(2), T(3))]: p = partial(capture, *args) expected = args + (T('x'), ) got, empty = p(T('x')) assert expected == got and empty == {}
def test_copy(): f = partial(signature, ['asdf'], bar=[True]) f.attr = [] f_copy = copy.copy(f) assert signature(f_copy) == signature(f) assert f_copy.attr is f.attr assert f_copy.args is f.args assert f_copy.keywords is f.keywords
def test_partial_placeholder_copy(): p = partial(isinstance, partial._, int) # call a copy of a partial with placeholders p2 = copy.copy(p) assert p2.num_placeholders == 1 assert p2(20) assert not p2(1.2) assert not p2(T(1.2))
def test_partial_placeholder_someone_holds_ref(): p = partial(isinstance, partial._, int) # hold a reference to args while calling the function x = p.args assert p(20) assert not p(1.2) assert not p(T(1.2)) del x
def test_error_propagation(): def f(x, y): x / y with pytest.raises(ZeroDivisionError): partial(f, 1, 0)() with pytest.raises(ZeroDivisionError): partial(f, 1)(0) with pytest.raises(ZeroDivisionError): partial(f)(1, 0) with pytest.raises(ZeroDivisionError): partial(f, y=0)(1)
def test_deepcopy(): f = partial(signature, ['asdf'], bar=[True]) f.attr = [] f_copy = copy.deepcopy(f) assert signature(f_copy) == signature(f) assert f_copy.attr is not f.attr assert f_copy.args is not f.args assert f_copy.args[0] is not f.args[0] assert f_copy.keywords is not f.keywords assert f_copy.keywords['bar'] is not f.keywords['bar']
def test_protection_of_callers_dict_argument(): # a caller's dictionary should not be altered by partial def func(a=10, b=20): return a d = {'a': T(3)} p = partial(func, a=T(5)) assert p(**d) == T(3) assert d == {'a': T(3)} p(b=7) assert d == {'a': T(3)}