Skip to content

Commit

Permalink
#83: Add special handling for __call__ to interface_only().
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-mitchell committed Sep 22, 2021
1 parent c3aba97 commit 6511ba6
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
2 changes: 2 additions & 0 deletions pure_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,8 @@ def interface_only(cls, implementation):
if cls._pi.impl_wrapper_type is None:
type_name = '_{}Only'.format(cls.__name__)
attributes = {'__module__': cls.__module__}
if '__call__' in cls._pi.interface_names:
attributes['__call__'] = getattr(implementation, '__call__')
cls._pi.impl_wrapper_type = type(type_name, (_ImplementationWrapper,), attributes)
abc.ABCMeta.register(cls, cls._pi.impl_wrapper_type)
return cls._pi.impl_wrapper_type(implementation, cls)
Expand Down
30 changes: 30 additions & 0 deletions tests/test_adaption.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,23 @@ def speak(self, volume):
super(SleepTalker, self).speak(volume)


class DunderInterface(pure_interface.Interface):
def __call__(self, a):
pass

def __len__(self):
pass


class DunderClass(DunderInterface, object):

def __call__(self, a):
super().__call__(a)

def __len__(self):
return 5


class TestAdaption(unittest.TestCase):
@classmethod
def setUpClass(cls):
Expand Down Expand Up @@ -350,3 +367,16 @@ def test_adapt_interface_only(self):
ISpeaker.adapt(talker_only)
except:
self.fail('adaption of interface only failed.')

def test_adapt_callable_is_callable(self):
dunder = DunderClass()
dunder_only = DunderInterface.adapt(dunder)
try:
dunder_only(1)
except TypeError:
self.fail('calling interface only failed')

try:
len(dunder)
except:
self.fail('len() interface only failed')

0 comments on commit 6511ba6

Please sign in to comment.