from boltons.funcutils import (copy_function, total_ordering, format_invocation, InstancePartial, CachedInstancePartial, noop) class Greeter: def __init__(self, greeting): self.greeting = greeting def greet(self, excitement='.'): return self.greeting.capitalize() + excitement partial_greet = InstancePartial(greet, excitement='!') cached_partial_greet = CachedInstancePartial(greet, excitement='...') def native_greet(self): return self.greet(';') class SubGreeter(Greeter): pass def test_partials(): g = SubGreeter('hello') assert g.greet() == 'Hello.' assert g.native_greet() == 'Hello;' assert g.partial_greet() == 'Hello!' assert g.cached_partial_greet() == 'Hello...' assert CachedInstancePartial(g.greet, excitement='s')() == 'Hellos' g.native_greet = 'native reassigned' assert g.native_greet == 'native reassigned' g.partial_greet = 'partial reassigned' assert g.partial_greet == 'partial reassigned' g.cached_partial_greet = 'cached_partial reassigned' assert g.cached_partial_greet == 'cached_partial reassigned' def test_copy_function(): def callee(): return 1 callee_copy = copy_function(callee) assert callee is not callee_copy assert callee() == callee_copy() def test_total_ordering(): @total_ordering class Number: def __init__(self, val): self.val = int(val) def __gt__(self, other): return self.val > other def __eq__(self, other): return self.val == other num = Number(3) assert num > 0 assert num == 3 assert num < 5 assert num >= 2 assert num != 1 def test_format_invocation(): assert format_invocation('d') == "d()" assert format_invocation('f', ('a', 'b')) == "f('a', 'b')" assert format_invocation('g', (), {'x': 'y'}) == "g(x='y')" assert format_invocation('h', ('a', 'b'), {'x': 'y', 'z': 'zz'}) == "h('a', 'b', x='y', z='zz')" def test_noop(): assert noop() is None assert noop(1, 2) is None assert noop(a=1, b=2) is None