This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author jaraco
Recipients jaraco
Date 2018-12-16.20:43:26
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1544993007.41.0.788709270274.issue35512@psf.upfronthosting.co.za>
In-reply-to
Content
Originally [reported in testing-cabal/mock#405](https://github.com/testing-cabal/mock/issues/405), I believe I've discovered an inconsistency that manifests as a flaw:

`patch` and `patch.object` allow the target to be specified as string referring to the target object and this object is resolved at the time the patch effected, not when the patch is declared. `patch.dict` contrarily seems to resolve the dict eagerly, when the patch is declared. Observe with this pytest:

```
import mock


target = dict(a=1)

@mock.patch.dict('test_patch_dict.target', dict(b=2))
def test_after_patch():
	assert target == dict(a=2, b=2)

target = dict(a=2)
```

Here's the output:

```
$ rwt mock pytest -- -m pytest test_patch_dict.py
Collecting mock
  Using cached mock-2.0.0-py2.py3-none-any.whl
Collecting pbr>=0.11 (from mock)
  Using cached pbr-3.0.0-py2.py3-none-any.whl
Collecting six>=1.9 (from mock)
  Using cached six-1.10.0-py2.py3-none-any.whl
Installing collected packages: pbr, six, mock
Successfully installed mock-2.0.0 pbr-3.0.0 six-1.10.0
====================================== test session starts =======================================
platform darwin -- Python 3.6.1, pytest-3.0.5, py-1.4.33, pluggy-0.4.0
rootdir: /Users/jaraco, inifile: 
collected 1 items 

test_patch_dict.py F

============================================ FAILURES ============================================
________________________________________ test_after_patch ________________________________________

    @mock.patch.dict('test_patch_dict.target', dict(b=2))
    def test_after_patch():
>   	assert target == dict(a=2, b=2)
E    assert {'a': 2} == {'a': 2, 'b': 2}
E      Omitting 1 identical items, use -v to show
E      Right contains more items:
E      {'b': 2}
E      Use -v to get the full diff

test_patch_dict.py:8: AssertionError
==================================== 1 failed in 0.05 seconds ====================================
```

The target is unpatched because `test_patch_dict.target` was resolved during decoration rather than during test run.

Removing the initial assignment of `target = dict(a=1)`, the failure is thus:

```
______________________________ ERROR collecting test_patch_dict.py _______________________________
ImportError while importing test module '/Users/jaraco/test_patch_dict.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-pcm3552g/mock/mock.py:1197: in _dot_lookup
    return getattr(thing, comp)
E   AttributeError: module 'test_patch_dict' has no attribute 'target'

During handling of the above exception, another exception occurred:
<frozen importlib._bootstrap>:942: in _find_and_load_unlocked
    ???
E   AttributeError: module 'test_patch_dict' has no attribute '__path__'

During handling of the above exception, another exception occurred:
test_patch_dict.py:4: in <module>
    @mock.patch.dict('test_patch_dict.target', dict(b=2))
/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-pcm3552g/mock/mock.py:1708: in __init__
    in_dict = _importer(in_dict)
/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-pcm3552g/mock/mock.py:1210: in _importer
    thing = _dot_lookup(thing, comp, import_path)
/var/folders/c6/v7hnmq453xb6p2dbz1gqc6rr0000gn/T/rwt-pcm3552g/mock/mock.py:1199: in _dot_lookup
    __import__(import_path)
E   ModuleNotFoundError: No module named 'test_patch_dict.target'; 'test_patch_dict' is not a package
!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
==================================== 1 error in 0.41 seconds =====================================
```

Is there any reason `patch.dict` doesn't have a similar deferred resolution behavior as its sister methods?
History
Date User Action Args
2018-12-16 20:43:27jaracosetrecipients: + jaraco
2018-12-16 20:43:27jaracosetmessageid: <1544993007.41.0.788709270274.issue35512@psf.upfronthosting.co.za>
2018-12-16 20:43:27jaracolinkissue35512 messages
2018-12-16 20:43:26jaracocreate