summaryrefslogtreecommitdiff
path: root/Lib/unittest/mock.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/unittest/mock.py')
-rw-r--r--Lib/unittest/mock.py68
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'