Lokasi ngalangkungan proxy:   [ UP ]  
[Ngawartoskeun bug]   [Panyetelan cookie]                
Skip to content

Commit 8c14534

Browse files
committed
Closes Issue 21238: New keyword argument unsafe to Mock.
It raises `AttributeError` incase of an attribute startswith assert or assret.
1 parent c3ac9af commit 8c14534

4 files changed

Lines changed: 27 additions & 3 deletions

File tree

Doc/library/unittest.mock.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ a `MagicMock` for you. You can specify an alternative class of `Mock` using
198198
the `new_callable` argument to `patch`.
199199

200200

201-
.. class:: Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, **kwargs)
201+
.. class:: Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs)
202202

203203
Create a new `Mock` object. `Mock` takes several optional arguments
204204
that specify the behaviour of the Mock object:
@@ -235,6 +235,12 @@ the `new_callable` argument to `patch`.
235235
this is a new Mock (created on first access). See the
236236
:attr:`return_value` attribute.
237237

238+
* `unsafe`: By default if any attribute starts with *assert* or
239+
*assret* will raise an `AttributeError`. Passing `unsafe=True` will allow
240+
access to these attributes.
241+
242+
.. versionadded:: 3.5
243+
238244
* `wraps`: Item for the mock object to wrap. If `wraps` is not None then
239245
calling the Mock will pass the call through to the wrapped object
240246
(returning the real result). Attribute access on the mock will return a

Lib/unittest/mock.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ def __new__(cls, *args, **kw):
379379
def __init__(
380380
self, spec=None, wraps=None, name=None, spec_set=None,
381381
parent=None, _spec_state=None, _new_name='', _new_parent=None,
382-
_spec_as_instance=False, _eat_self=None, **kwargs
382+
_spec_as_instance=False, _eat_self=None, unsafe=False, **kwargs
383383
):
384384
if _new_parent is None:
385385
_new_parent = parent
@@ -409,6 +409,7 @@ def __init__(
409409
__dict__['_mock_mock_calls'] = _CallList()
410410

411411
__dict__['method_calls'] = _CallList()
412+
__dict__['_mock_unsafe'] = unsafe
412413

413414
if kwargs:
414415
self.configure_mock(**kwargs)
@@ -565,13 +566,16 @@ def configure_mock(self, **kwargs):
565566

566567

567568
def __getattr__(self, name):
568-
if name == '_mock_methods':
569+
if name in {'_mock_methods', '_mock_unsafe'}:
569570
raise AttributeError(name)
570571
elif self._mock_methods is not None:
571572
if name not in self._mock_methods or name in _all_magics:
572573
raise AttributeError("Mock object has no attribute %r" % name)
573574
elif _is_magic(name):
574575
raise AttributeError(name)
576+
if not self._mock_unsafe:
577+
if name.startswith(('assert', 'assret')):
578+
raise AttributeError(name)
575579

576580
result = self._mock_children.get(name)
577581
if result is _deleted:

Lib/unittest/test/testmock/testmock.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,17 @@ def test_create_autospec_with_name(self):
11871187
m = mock.create_autospec(object(), name='sweet_func')
11881188
self.assertIn('sweet_func', repr(m))
11891189

1190+
#Issue21238
1191+
def test_mock_unsafe(self):
1192+
m = Mock()
1193+
with self.assertRaises(AttributeError):
1194+
m.assert_foo_call()
1195+
with self.assertRaises(AttributeError):
1196+
m.assret_foo_call()
1197+
m = Mock(unsafe=True)
1198+
m.assert_foo_call()
1199+
m.assret_foo_call()
1200+
11901201
def test_mock_add_spec(self):
11911202
class _One(object):
11921203
one = 1

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ Core and Builtins
5050
Library
5151
-------
5252

53+
- Issue #21238: New keyword argument `unsafe` to Mock. It raises
54+
`AttributeError` incase of an attribute startswith assert or assret.
55+
5356
- Issue #20896: ssl.get_server_certificate() now uses PROTOCOL_SSLv23, not
5457
PROTOCOL_SSLv3, for maximum compatibility.
5558

0 commit comments

Comments
 (0)