def test_invalid_arg_for_override_to_add_method(): def dummy_validator(): pass mm = MultiMethod(lambda *a: a) # See #1991 with pytest.raises(ValueError): mm.add(dummy_validator, tuple(), override=sys.maxsize)
class AttrWalker(object): def __init__(self): self.applymm = MultiMethod(lambda *a, **kw: (a[1], )) self.createmm = MultiMethod(lambda *a, **kw: (a[1], )) def add_creator(self, *types): def _dec(fun): for type_ in types: self.createmm.add(fun, (type_, )) return fun return _dec def add_applier(self, *types): def _dec(fun): for type_ in types: self.applymm.add(fun, (type_, )) return fun return _dec def add_converter(self, *types): def _dec(fun): for type_ in types: self.applymm.add(self.cv_apply(fun), (type_, )) self.createmm.add(self.cv_create(fun), (type_, )) return fun return _dec def cv_apply(self, fun): def _fun(*args, **kwargs): args = list(args) args[1] = fun(args[1]) return self.applymm(*args, **kwargs) return _fun def cv_create(self, fun): def _fun(*args, **kwargs): args = list(args) args[1] = fun(args[1]) return self.createmm(*args, **kwargs) return _fun def create(self, *args, **kwargs): return self.createmm(self, *args, **kwargs) def apply(self, *args, **kwargs): return self.applymm(self, *args, **kwargs) def super_create(self, *args, **kwargs): return self.createmm.super(self, *args, **kwargs) def super_apply(self, *args, **kwargs): return self.applymm.super(self, *args, **kwargs)
class AttrWalker(object): def __init__(self): self.applymm = MultiMethod(lambda *a, **kw: (a[1],)) self.createmm = MultiMethod(lambda *a, **kw: (a[1],)) def add_creator(self, *types): def _dec(fun): for type_ in types: self.createmm.add(fun, (type_,)) return fun return _dec def add_applier(self, *types): def _dec(fun): for type_ in types: self.applymm.add(fun, (type_,)) return fun return _dec def add_converter(self, *types): def _dec(fun): for type_ in types: self.applymm.add(self.cv_apply(fun), (type_,)) self.createmm.add(self.cv_create(fun), (type_,)) return fun return _dec def cv_apply(self, fun): def _fun(*args, **kwargs): args = list(args) args[1] = fun(args[1]) return self.applymm(*args, **kwargs) return _fun def cv_create(self, fun): def _fun(*args, **kwargs): args = list(args) args[1] = fun(args[1]) return self.createmm(*args, **kwargs) return _fun def create(self, *args, **kwargs): return self.createmm(self, *args, **kwargs) def apply(self, *args, **kwargs): return self.applymm(self, *args, **kwargs) def super_create(self, *args, **kwargs): return self.createmm.super(self, *args, **kwargs) def super_apply(self, *args, **kwargs): return self.applymm.super(self, *args, **kwargs)
def test_call_cached(): def sum_together(first, second): return first + second # Setup mm = MultiMethod(lambda *a: a) mm.add(sum_together, (int, int, )) assert mm(3, 4) == 7 # The following call 'should' use the previously cached call # You'll only see the result of this in the code coverage test though assert mm(1, 2) == 3
def test_override(recwarn): class String(str): pass mm = MultiMethod(lambda *a: a) @mm.add_dec(str, str) def foo(foo, bar): return 'String' pytest.raises( TypeError, mm.add_dec(String, str, override=FAIL), lambda x, y: None ) mm.add_dec(String, str, override=WARN)(lambda x, y: None) w = recwarn.pop(TypeWarning) assert 'Definition (String, str) overrides prior definition (str, str).' in str(w.message)
def test_override(recwarn): class String(str): pass mm = MultiMethod(lambda *a: a) @mm.add_dec(str, str) def foo(foo, bar): return 'String' pytest.raises(TypeError, mm.add_dec(String, str, override=FAIL), lambda x, y: None) mm.add_dec(String, str, override=WARN)(lambda x, y: None) w = recwarn.pop(TypeWarning) assert 'Definition (String, str) overrides prior definition (str, str).' in str( w.message)
def test_super(): class String(str): pass mm = MultiMethod(lambda *a: a) with pytest.raises(TypeError): mm.super() @mm.add_dec(str, str) def foo(foo, bar): return 'String' # Suppress pep8 warning "F811 redefinition of unused 'foo' ..." @mm.add_dec(String, str) def foo(foo, bar): return 'Fancy', mm.super(super(String, foo), bar) assert mm('foo', 'bar') == 'String' assert mm(String('foo'), 'bar') == ('Fancy', 'String')
def test_super(): class String(str): pass mm = MultiMethod(lambda *a: a) with pytest.raises(TypeError): mm.super() @mm.add_dec(str, str) def foo(foo, bar): return 'String' # Suppress pep8 warning "F811 redefinition of unused 'foo' ..." @mm.add_dec(String, str) # noqa def foo(foo, bar): return 'Fancy', mm.super(super(String, foo), bar) assert mm('foo', 'bar') == 'String' assert mm(String('foo'), 'bar') == ('Fancy', 'String')
def test_super(): class String(str): pass mm = MultiMethod(lambda *a: a) @mm.add_dec(str, str) def foo(foo, bar): return 'String' @mm.add_dec(String, str) def foo(foo, bar): return 'Fancy', mm.super(super(String, foo), bar) assert mm('foo', 'bar') == 'String' assert mm(String('foo'), 'bar') == ('Fancy', 'String')
def __init__(self): self.applymm = MultiMethod(lambda *a, **kw: (a[1], )) self.createmm = MultiMethod(lambda *a, **kw: (a[1], ))
lambda x: ValueAttr({(x.__class__.__name__.lower(), ): x.value})) walker.add_converter(Wavelength)( lambda x: ValueAttr({ ('wave', 'wavemin'): x.min.value, ('wave', 'wavemax'): x.max.value, ('wave', 'waveunit'): x.unit, })) # The idea of using a multi-method here - that means a method which dispatches # by type but is not attached to said class - is that the attribute classes are # designed to be used not only in the context of VSO but also elsewhere (which # AttrAnd and AttrOr obviously are - in the HEK module). If we defined the # filter method as a member of the attribute classes, we could only filter # one type of data (that is, VSO data). filter_results = MultiMethod(lambda *a, **kw: (a[0], )) # If we filter with ANDed together attributes, the only items are the ones # that match all of them - this is implementing by ANDing the pool of items # with the matched items - only the ones that match everything are there # after this. @filter_results.add_dec(AttrAnd) def _(attr, results): res = set(results) for elem in attr.attrs: res &= filter_results(elem, res) return res # If we filter with ORed attributes, the only attributes that should be
def mm(): with pytest.warns(SunpyDeprecationWarning): return MultiMethod(lambda *a: a)
def test_no_registered_methods(): mm = MultiMethod(lambda *a: a) with pytest.raises(TypeError): mm(2)