[Python-checkins] cpython: Closes Issue 21238: New keyword argument `unsafe` to Mock.
kushal.das
python-checkins at python.org
Wed Apr 16 20:06:59 CEST 2014
http://hg.python.org/cpython/rev/e4ee0b15cc4f
changeset: 90363:e4ee0b15cc4f
user: Kushal Das <kushaldas at gmail.com>
date: Wed Apr 16 23:32:21 2014 +0530
summary:
Closes Issue 21238: New keyword argument `unsafe` to Mock.
It raises `AttributeError` incase of an attribute startswith assert
or assret.
files:
Doc/library/unittest.mock.rst | 8 +++++++-
Lib/unittest/mock.py | 8 ++++++--
Lib/unittest/test/testmock/testmock.py | 11 +++++++++++
Misc/NEWS | 3 +++
4 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/Doc/library/unittest.mock.rst b/Doc/library/unittest.mock.rst
--- a/Doc/library/unittest.mock.rst
+++ b/Doc/library/unittest.mock.rst
@@ -198,7 +198,7 @@
the `new_callable` argument to `patch`.
-.. class:: Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, **kwargs)
+.. class:: Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs)
Create a new `Mock` object. `Mock` takes several optional arguments
that specify the behaviour of the Mock object:
@@ -235,6 +235,12 @@
this is a new Mock (created on first access). See the
:attr:`return_value` attribute.
+ * `unsafe`: By default if any attribute starts with *assert* or
+ *assret* will raise an `AttributeError`. Passing `unsafe=True` will allow
+ access to these attributes.
+
+ .. versionadded:: 3.5
+
* `wraps`: Item for the mock object to wrap. If `wraps` is not None then
calling the Mock will pass the call through to the wrapped object
(returning the real result). Attribute access on the mock will return a
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -379,7 +379,7 @@
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
@@ -409,6 +409,7 @@
__dict__['_mock_mock_calls'] = _CallList()
__dict__['method_calls'] = _CallList()
+ __dict__['_mock_unsafe'] = unsafe
if kwargs:
self.configure_mock(**kwargs)
@@ -565,13 +566,16 @@
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:
diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py
--- a/Lib/unittest/test/testmock/testmock.py
+++ b/Lib/unittest/test/testmock/testmock.py
@@ -1187,6 +1187,17 @@
m = mock.create_autospec(object(), name='sweet_func')
self.assertIn('sweet_func', repr(m))
+ #Issue21238
+ def test_mock_unsafe(self):
+ m = Mock()
+ with self.assertRaises(AttributeError):
+ m.assert_foo_call()
+ with self.assertRaises(AttributeError):
+ m.assret_foo_call()
+ m = Mock(unsafe=True)
+ m.assert_foo_call()
+ m.assret_foo_call()
+
def test_mock_add_spec(self):
class _One(object):
one = 1
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -50,6 +50,9 @@
Library
-------
+- Issue #21238: New keyword argument `unsafe` to Mock. It raises
+ `AttributeError` incase of an attribute startswith assert or assret.
+
- Issue #20896: ssl.get_server_certificate() now uses PROTOCOL_SSLv23, not
PROTOCOL_SSLv3, for maximum compatibility.
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list