Skip to content

Commit 4f9a396

Browse files
authored
Merge pull request #44 from michaels-lyft/master
BUG: Fix superclass checking for subclass methods
2 parents 7de8eeb + 0c991ce commit 4f9a396

File tree

5 files changed

+25
-8
lines changed

5 files changed

+25
-8
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ develop-eggs
3939
.installed.cfg
4040
coverage.xml
4141
nosetests.xml
42+
venv/
43+
.idea/
4244

4345
# C Extensions
4446
*.o

interface/functional.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def merge(dicts):
5353
if len(dicts) == 0:
5454
return {}
5555
elif len(dicts) == 1:
56-
return dicts[0]
56+
return dicts[0].copy()
5757
else:
5858
out = dicts[0].copy()
5959
for other in dicts[1:]:

interface/tests/test_interface.py

+16-5
Original file line numberDiff line numberDiff line change
@@ -901,8 +901,8 @@ class AandB(A): # pragma: nocover
901901
def method_b(self):
902902
pass
903903

904+
# expected to fail since it's missing method_b
904905
with pytest.raises(InvalidImplementation) as exc:
905-
906906
class JustA(implements(AandB)): # pragma: nocover
907907
def method_a(self):
908908
pass
@@ -917,8 +917,8 @@ class JustA failed to implement interface AandB:
917917
)
918918
assert actual_message == expected_message
919919

920+
# expected to fail since it's missing method_a
920921
with pytest.raises(InvalidImplementation) as exc:
921-
922922
class JustB(implements(AandB)): # pragma: nocover
923923
def method_b(self):
924924
pass
@@ -933,6 +933,12 @@ class JustB failed to implement interface AandB:
933933
)
934934
assert actual_message == expected_message
935935

936+
# expected to pass since interface A only requires method_a
937+
class JustA2(implements(A)): # pragma: nocover
938+
def method_a(self):
939+
pass
940+
941+
# expected to pass since it implements both methods
936942
class Both(implements(AandB)): # pragma: nocover
937943
def method_a(self):
938944
pass
@@ -950,8 +956,8 @@ class B(A): # pragma: nocover
950956
def method_b(self):
951957
pass
952958

959+
# expected to fail since method_a has different signature in interface A
953960
with pytest.raises(TypeError) as exc:
954-
955961
class C1(A): # pragma: nocover
956962
def method_a(self, x):
957963
pass
@@ -964,9 +970,9 @@ def method_a(self, x):
964970
)
965971
assert actual_message == expected_message
966972

973+
# expected to fail since method_b has different signature in interface B
967974
with pytest.raises(TypeError) as exc:
968-
969-
class C2(A): # pragma: nocover
975+
class C2(B): # pragma: nocover
970976
def method_b(self, y, z=None):
971977
pass
972978

@@ -978,6 +984,11 @@ def method_b(self, y, z=None):
978984
)
979985
assert actual_message == expected_message
980986

987+
# expected to pass since method_b does not exist in interface A
988+
class C3(A): # pragma: nocover
989+
def method_b(self, y, z=None):
990+
pass
991+
981992

982993
def test_subclass_allow_compatible_extension():
983994
class A(Interface): # pragma: nocover

interface/tests/test_utils.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ def g(*args): # pragma: nocover
2525

2626
def test_merge():
2727
assert merge([]) == {}
28-
assert merge([{"a": 1, "b": 2}]) == {"a": 1, "b": 2}
28+
29+
input = {"a": 1, "b": 2}
30+
output = merge([input])
31+
assert output is not input
32+
assert output == input
2933

3034
result = merge([{"a": 1}, {"b": 2}, {"a": 3, "c": 4}])
3135
assert result == {"a": 3, "b": 2, "c": 4}

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def install_requires():
2828

2929
setup(
3030
name="python-interface",
31-
version="1.6.0",
31+
version="1.6.1",
3232
description="Pythonic Interface definitions",
3333
author="Scott Sanderson",
3434
author_email="[email protected]",

0 commit comments

Comments
 (0)