# already an instance
return getattr(obj, '__call__', None) is not None
- klass = obj
- # uses __bases__ instead of __mro__ so that we work with old style classes
- if klass.__dict__.get('__call__') is not None:
- return True
-
- for base in klass.__bases__:
- if _instance_callable(base):
+ # *could* be broken by a class overriding __mro__ or __dict__ via
+ # a metaclass
+ for base in (obj,) + obj.__mro__:
+ if base.__dict__.get('__call__') is not None:
return True
return False
if entry in getattr(spec, '__dict__', {}):
# instance attribute - shouldn't skip
return False
- # can't use type because of old style classes
spec = spec.__class__
- if not hasattr(spec, '__mro__'):
- # old style class: can't have descriptors anyway
- return is_type
for klass in spec.__mro__:
result = klass.__dict__.get(entry, DEFAULT)
class Multi(SomeClass, Sub):
pass
- class OldStyle:
- def __call__(self):
- pass
-
- class OldStyleSub(OldStyle):
- pass
-
for arg in 'spec', 'spec_set':
- for Klass in CallableX, Sub, Multi, OldStyle, OldStyleSub:
- patcher = patch('%s.X' % __name__, **{arg: Klass})
- mock = patcher.start()
-
- try:
+ for Klass in CallableX, Sub, Multi:
+ with patch('%s.X' % __name__, **{arg: Klass}) as mock:
instance = mock()
mock.assert_called_once_with()
result.assert_called_once_with(3, 2, 1)
result.foo(3, 2, 1)
result.foo.assert_called_once_with(3, 2, 1)
- finally:
- patcher.stop()
def test_create_autopsec(self):