diff options
Diffstat (limited to 'Lib/unittest/mock.py')
-rw-r--r-- | Lib/unittest/mock.py | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 1b1c9f4422..c3ab4e82e8 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -27,9 +27,13 @@ __version__ = '1.0' import inspect import pprint import sys +import builtins +from types import ModuleType from functools import wraps, partial +_builtins = {name for name in dir(builtins) if not name.startswith('_')} + BaseExceptions = (BaseException,) if 'java' in sys.platform: # jython @@ -271,13 +275,11 @@ def _copy(value): return value -_allowed_names = set( - [ - 'return_value', '_mock_return_value', 'side_effect', - '_mock_side_effect', '_mock_parent', '_mock_new_parent', - '_mock_name', '_mock_new_name' - ] -) +_allowed_names = { + 'return_value', '_mock_return_value', 'side_effect', + '_mock_side_effect', '_mock_parent', '_mock_new_parent', + '_mock_name', '_mock_new_name' +} def _delegating_property(name): @@ -375,7 +377,7 @@ class NonCallableMock(Base): def __init__( self, spec=None, wraps=None, name=None, spec_set=None, parent=None, _spec_state=None, _new_name='', _new_parent=None, - _spec_as_instance=False, _eat_self=None, **kwargs + _spec_as_instance=False, _eat_self=None, unsafe=False, **kwargs ): if _new_parent is None: _new_parent = parent @@ -405,6 +407,7 @@ class NonCallableMock(Base): __dict__['_mock_mock_calls'] = _CallList() __dict__['method_calls'] = _CallList() + __dict__['_mock_unsafe'] = unsafe if kwargs: self.configure_mock(**kwargs) @@ -561,13 +564,16 @@ class NonCallableMock(Base): def __getattr__(self, name): - if name == '_mock_methods': + if name in {'_mock_methods', '_mock_unsafe'}: raise AttributeError(name) elif self._mock_methods is not None: if name not in self._mock_methods or name in _all_magics: raise AttributeError("Mock object has no attribute %r" % name) elif _is_magic(name): raise AttributeError(name) + if not self._mock_unsafe: + if name.startswith(('assert', 'assret')): + raise AttributeError(name) result = self._mock_children.get(name) if result is _deleted: @@ -750,6 +756,14 @@ class NonCallableMock(Base): else: return _call + def assert_not_called(_mock_self): + """assert that the mock was never called. + """ + self = _mock_self + if self.call_count != 0: + msg = ("Expected '%s' to not have been called. Called %s times." % + (self._mock_name or 'mock', self.call_count)) + raise AssertionError(msg) def assert_called_with(_mock_self, *args, **kwargs): """assert that the mock was called with the specified arguments. @@ -1166,6 +1180,9 @@ class _patch(object): else: local = True + if name in _builtins and isinstance(target, ModuleType): + self.create = True + if not self.create and original is DEFAULT: raise AttributeError( "%s does not have the attribute %r" % (target, name) @@ -1653,7 +1670,7 @@ magic_methods = ( ) numerics = ( - "add sub mul div floordiv mod lshift rshift and xor or pow truediv" + "add sub mul matmul div floordiv mod lshift rshift and xor or pow truediv" ) inplace = ' '.join('i%s' % n for n in numerics.split()) right = ' '.join('r%s' % n for n in numerics.split()) @@ -1662,11 +1679,12 @@ right = ' '.join('r%s' % n for n in numerics.split()) # (as they are metaclass methods) # __del__ is not supported at all as it causes problems if it exists -_non_defaults = set('__%s__' % method for method in [ - 'get', 'set', 'delete', 'reversed', 'missing', 'reduce', 'reduce_ex', - 'getinitargs', 'getnewargs', 'getstate', 'setstate', 'getformat', - 'setformat', 'repr', 'dir', 'subclasses', 'format', -]) +_non_defaults = { + '__get__', '__set__', '__delete__', '__reversed__', '__missing__', + '__reduce__', '__reduce_ex__', '__getinitargs__', '__getnewargs__', + '__getstate__', '__setstate__', '__getformat__', '__setformat__', + '__repr__', '__dir__', '__subclasses__', '__format__', +} def _get_method(name, func): @@ -1677,19 +1695,19 @@ def _get_method(name, func): return method -_magics = set( +_magics = { '__%s__' % method for method in ' '.join([magic_methods, numerics, inplace, right]).split() -) +} _all_magics = _magics | _non_defaults -_unsupported_magics = set([ +_unsupported_magics = { '__getattr__', '__setattr__', '__init__', '__new__', '__prepare__' '__instancecheck__', '__subclasscheck__', '__del__' -]) +} _calculate_return_value = { '__hash__': lambda self: object.__hash__(self), @@ -1878,7 +1896,7 @@ def _format_call_signature(name, args, kwargs): formatted_args = '' args_string = ', '.join([repr(arg) for arg in args]) kwargs_string = ', '.join([ - '%s=%r' % (key, value) for key, value in kwargs.items() + '%s=%r' % (key, value) for key, value in sorted(kwargs.items()) ]) if args_string: formatted_args = args_string @@ -2000,10 +2018,6 @@ class _Call(tuple): return (other_args, other_kwargs) == (self_args, self_kwargs) - def __ne__(self, other): - return not self.__eq__(other) - - def __call__(self, *args, **kwargs): if self.name is None: return _Call(('', args, kwargs), name='()') @@ -2019,6 +2033,12 @@ class _Call(tuple): return _Call(name=name, parent=self, from_kall=False) + def count(self, *args, **kwargs): + return self.__getattr__('count')(*args, **kwargs) + + def index(self, *args, **kwargs): + return self.__getattr__('index')(*args, **kwargs) + def __repr__(self): if not self.from_kall: name = self.name or 'call' |