Message331937
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? |
|
Date |
User |
Action |
Args |
2018-12-16 20:43:27 | jaraco | set | recipients:
+ jaraco |
2018-12-16 20:43:27 | jaraco | set | messageid: <1544993007.41.0.788709270274.issue35512@psf.upfronthosting.co.za> |
2018-12-16 20:43:27 | jaraco | link | issue35512 messages |
2018-12-16 20:43:26 | jaraco | create | |
|