diff --git a/.gitignore b/.gitignore index c56a460..03d67f3 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,8 @@ develop-eggs .installed.cfg coverage.xml nosetests.xml +venv/ +.idea/ # C Extensions *.o diff --git a/interface/functional.py b/interface/functional.py index ec23d8b..147b4bc 100644 --- a/interface/functional.py +++ b/interface/functional.py @@ -53,7 +53,7 @@ def merge(dicts): if len(dicts) == 0: return {} elif len(dicts) == 1: - return dicts[0] + return dicts[0].copy() else: out = dicts[0].copy() for other in dicts[1:]: diff --git a/interface/tests/test_interface.py b/interface/tests/test_interface.py index 7f86875..bb4bac2 100644 --- a/interface/tests/test_interface.py +++ b/interface/tests/test_interface.py @@ -901,8 +901,8 @@ class AandB(A): # pragma: nocover def method_b(self): pass + # expected to fail since it's missing method_b with pytest.raises(InvalidImplementation) as exc: - class JustA(implements(AandB)): # pragma: nocover def method_a(self): pass @@ -917,8 +917,8 @@ class JustA failed to implement interface AandB: ) assert actual_message == expected_message + # expected to fail since it's missing method_a with pytest.raises(InvalidImplementation) as exc: - class JustB(implements(AandB)): # pragma: nocover def method_b(self): pass @@ -933,6 +933,12 @@ class JustB failed to implement interface AandB: ) assert actual_message == expected_message + # expected to pass since interface A only requires method_a + class JustA2(implements(A)): # pragma: nocover + def method_a(self): + pass + + # expected to pass since it implements both methods class Both(implements(AandB)): # pragma: nocover def method_a(self): pass @@ -950,8 +956,8 @@ class B(A): # pragma: nocover def method_b(self): pass + # expected to fail since method_a has different signature in interface A with pytest.raises(TypeError) as exc: - class C1(A): # pragma: nocover def method_a(self, x): pass @@ -964,9 +970,9 @@ def method_a(self, x): ) assert actual_message == expected_message + # expected to fail since method_b has different signature in interface B with pytest.raises(TypeError) as exc: - - class C2(A): # pragma: nocover + class C2(B): # pragma: nocover def method_b(self, y, z=None): pass @@ -978,6 +984,11 @@ def method_b(self, y, z=None): ) assert actual_message == expected_message + # expected to pass since method_b does not exist in interface A + class C3(A): # pragma: nocover + def method_b(self, y, z=None): + pass + def test_subclass_allow_compatible_extension(): class A(Interface): # pragma: nocover diff --git a/interface/tests/test_utils.py b/interface/tests/test_utils.py index 1a146a3..6053e02 100644 --- a/interface/tests/test_utils.py +++ b/interface/tests/test_utils.py @@ -25,7 +25,11 @@ def g(*args): # pragma: nocover def test_merge(): assert merge([]) == {} - assert merge([{"a": 1, "b": 2}]) == {"a": 1, "b": 2} + + input = {"a": 1, "b": 2} + output = merge([input]) + assert output is not input + assert output == input result = merge([{"a": 1}, {"b": 2}, {"a": 3, "c": 4}]) assert result == {"a": 3, "b": 2, "c": 4} diff --git a/setup.py b/setup.py index aa7373a..b4557f7 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ def install_requires(): setup( name="python-interface", - version="1.6.0", + version="1.6.1", description="Pythonic Interface definitions", author="Scott Sanderson", author_email="scott.b.sanderson90@gmail.com",