[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