Fix error in multimethod's otherwise clause
This commit is contained in:
parent
6eef860ff4
commit
afb1a7996f
@ -121,6 +121,7 @@ class FunctionDispatcher(Generic[T]):
|
||||
trimmed_args = args[: self.params_arity]
|
||||
rule = self.registry.lookup(*trimmed_args)
|
||||
if not rule:
|
||||
print(self.registry._tree)
|
||||
raise TypeError(f"No available rule found for {trimmed_args!r}")
|
||||
return rule(*args, **kwargs)
|
||||
|
||||
|
@ -85,6 +85,7 @@ class MethodDispatcher(FunctionDispatcher[T]):
|
||||
""" Process all unbound rule by binding them to ``cls`` type."""
|
||||
for argtypes, func in self.local.unbound_rules:
|
||||
argtypes = (cls,) + argtypes
|
||||
print("register rule", argtypes)
|
||||
self.register_rule(func, *argtypes)
|
||||
self.local.unbound_rules = []
|
||||
|
||||
@ -106,8 +107,8 @@ class MethodDispatcher(FunctionDispatcher[T]):
|
||||
def otherwise(self) -> Callable[[T], T]:
|
||||
""" Decorator which registeres "catch-all" case for multimethod"""
|
||||
|
||||
def make_declaration(func):
|
||||
self.register_unbound_rule(func, [object] * self.params_arity)
|
||||
def make_declaration(meth):
|
||||
self.register_unbound_rule(meth, *([object] * (self.params_arity - 1)))
|
||||
return self
|
||||
|
||||
return make_declaration
|
||||
|
@ -20,6 +20,54 @@ def test_multimethod():
|
||||
Dummy().foo([])
|
||||
|
||||
|
||||
def test_multimethod_with_two_arguments():
|
||||
@has_multimethods
|
||||
class Dummy(object):
|
||||
@multimethod(int, int)
|
||||
def foo(self, x, y):
|
||||
return x * y
|
||||
|
||||
@foo.register(str, int) # type: ignore[no-redef]
|
||||
def foo(self, s, x):
|
||||
return s * x
|
||||
|
||||
assert Dummy().foo(1, 1) == 1
|
||||
assert Dummy().foo("1", 2) == "11"
|
||||
with pytest.raises(TypeError):
|
||||
Dummy().foo([])
|
||||
|
||||
|
||||
def test_multimethod_otherwise_clause():
|
||||
@has_multimethods
|
||||
class Dummy(object):
|
||||
@multimethod(int)
|
||||
def foo(self, x):
|
||||
return x + 1
|
||||
|
||||
@foo.otherwise # type: ignore[no-redef]
|
||||
def foo(self, x):
|
||||
return type(x)
|
||||
|
||||
assert Dummy().foo(1) == 2
|
||||
assert Dummy().foo("") is str
|
||||
assert Dummy().foo([]) is list
|
||||
|
||||
|
||||
def test_multimethod_otherwise_clausewith_two_arguments():
|
||||
@has_multimethods
|
||||
class Dummy(object):
|
||||
@multimethod(int, int)
|
||||
def foo(self, x, y):
|
||||
return x * y
|
||||
|
||||
@foo.otherwise # type: ignore[no-redef]
|
||||
def foo(self, s, x):
|
||||
return f"{s} {x}"
|
||||
|
||||
assert Dummy().foo(1, 2) == 2
|
||||
assert Dummy().foo("a", []) == "a []"
|
||||
|
||||
|
||||
def test_inheritance():
|
||||
@has_multimethods
|
||||
class Dummy(object):
|
||||
|
Loading…
Reference in New Issue
Block a user