1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
import pytest
from generic.multimethod import has_multimethods, multimethod
def test_multimethod():
@has_multimethods
class Dummy:
@multimethod(int)
def foo(self, x):
return x + 1
@foo.register(str) # type: ignore[no-redef]
def foo(self, x):
return f"{x}1"
assert Dummy().foo(1) == 2
assert Dummy().foo("1") == "11"
with pytest.raises(TypeError):
Dummy().foo([])
def test_multimethod_with_two_arguments():
@has_multimethods
class Dummy:
@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:
@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:
@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:
@multimethod(int)
def foo(self, x):
return x + 1
@foo.register(float) # type: ignore[no-redef]
def foo(self, x):
return x + 1.5
@has_multimethods
class DummySub(Dummy):
@Dummy.foo.register(str)
def foo(self, x):
return f"{x}1"
@foo.register(tuple) # type: ignore[no-redef]
def foo(self, x):
return x + (1,)
@Dummy.foo.register(bool) # type: ignore[no-redef]
def foo(self, x):
return not x
assert Dummy().foo(1) == 2
assert Dummy().foo(1.5) == 3.0
with pytest.raises(TypeError):
Dummy().foo("1")
assert DummySub().foo(1) == 2
assert DummySub().foo(1.5) == 3.0
assert DummySub().foo("1") == "11"
assert DummySub().foo((1, 2)) == (1, 2, 1)
assert DummySub().foo(True) is False
with pytest.raises(TypeError):
DummySub().foo([])
def test_override_in_same_class_not_allowed():
with pytest.raises(ValueError):
@has_multimethods
class Dummy:
@multimethod(str, str)
def foo(self, x, y):
return x + y
@foo.register(str, str) # type: ignore[no-redef]
def foo(self, x, y):
return y + x
def test_inheritance_override():
@has_multimethods
class Dummy:
@multimethod(int)
def foo(self, x):
return x + 1
@has_multimethods
class DummySub(Dummy):
@Dummy.foo.register(int)
def foo(self, x):
return x + 3
assert Dummy().foo(1) == 2
assert DummySub().foo(1) == 4
|