diff options
Diffstat (limited to 'Lib/unittest/mock.py')
-rw-r--r-- | Lib/unittest/mock.py | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 5555774467d..6b261d616d3 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) @@ -1660,11 +1677,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): @@ -1675,19 +1693,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), @@ -1875,7 +1893,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 @@ -2016,6 +2034,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' |