mirror of https://github.com/python/cpython
gh-119600: mock: do not access attributes of original when new_callable is set (#119601)
In order to patch flask.g e.g. as in #84982, that proxies getattr must not be invoked. For that, mock must not try to read from the original object. In some cases that is unavoidable, e.g. when doing autospec. However, patch("flask.g", new_callable=MagicMock) should be entirely safe.
This commit is contained in:
parent
6efe346069
commit
422c4fc855
|
@ -14,3 +14,14 @@ class SomeClass(object):
|
|||
|
||||
class X(object):
|
||||
pass
|
||||
|
||||
# A standin for weurkzeug.local.LocalProxy - issue 119600
|
||||
def _inaccessible(*args, **kwargs):
|
||||
raise AttributeError
|
||||
|
||||
|
||||
class OpaqueProxy:
|
||||
__getattribute__ = _inaccessible
|
||||
|
||||
|
||||
g = OpaqueProxy()
|
||||
|
|
|
@ -2045,6 +2045,13 @@ class PatchTest(unittest.TestCase):
|
|||
with self.assertRaises(TypeError):
|
||||
test()
|
||||
|
||||
def test_patch_proxy_object(self):
|
||||
@patch("test.test_unittest.testmock.support.g", new_callable=MagicMock())
|
||||
def test(_):
|
||||
pass
|
||||
|
||||
test()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
@ -1508,13 +1508,12 @@ class _patch(object):
|
|||
if isinstance(original, type):
|
||||
# If we're patching out a class and there is a spec
|
||||
inherit = True
|
||||
if spec is None and _is_async_obj(original):
|
||||
Klass = AsyncMock
|
||||
else:
|
||||
Klass = MagicMock
|
||||
_kwargs = {}
|
||||
|
||||
# Determine the Klass to use
|
||||
if new_callable is not None:
|
||||
Klass = new_callable
|
||||
elif spec is None and _is_async_obj(original):
|
||||
Klass = AsyncMock
|
||||
elif spec is not None or spec_set is not None:
|
||||
this_spec = spec
|
||||
if spec_set is not None:
|
||||
|
@ -1527,7 +1526,12 @@ class _patch(object):
|
|||
Klass = AsyncMock
|
||||
elif not_callable:
|
||||
Klass = NonCallableMagicMock
|
||||
else:
|
||||
Klass = MagicMock
|
||||
else:
|
||||
Klass = MagicMock
|
||||
|
||||
_kwargs = {}
|
||||
if spec is not None:
|
||||
_kwargs['spec'] = spec
|
||||
if spec_set is not None:
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Fix :func:`unittest.mock.patch` to not read attributes of the target when
|
||||
``new_callable`` is set. Patch by Robert Collins.
|
Loading…
Reference in New Issue