Skip to content

Commit d3d4c4a

Browse files
committed
Handle 'mocker.patch' being used without source code
Fix #169
1 parent 420fe64 commit d3d4c4a

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

CHANGELOG.rst

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
1.12.1 (2019-11-20)
2+
-------------------
3+
4+
* Fix error if ``mocker.patch`` is used in code where the source file
5+
is not available, for example stale ``.pyc`` files (`#169`_).
6+
7+
.. _#169: https://github.com/pytest-dev/pytest-mock/issues/169#issuecomment-555729265
8+
19
1.12.0 (2019-11-19)
210
-------------------
311

src/pytest_mock/plugin.py

+3
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ def _enforce_no_with_context(self, stack):
160160
caller = stack[2]
161161
frame = caller[0]
162162
info = inspect.getframeinfo(frame)
163+
if info.code_context is None:
164+
# no source code available (#169)
165+
return
163166
code_context = " ".join(info.code_context).strip()
164167

165168
if code_context.startswith("with mocker."):

tests/test_pytest_mock.py

+38
Original file line numberDiff line numberDiff line change
@@ -753,3 +753,41 @@ def test_abort_patch_context_manager(mocker):
753753
)
754754

755755
assert str(excinfo.value) == expected_error_msg
756+
757+
758+
def test_abort_patch_context_manager_with_stale_pyc(testdir):
759+
"""Ensure we don't trigger an error in case the frame where mocker.patch is being
760+
used doesn't have a 'context' (#169)"""
761+
import compileall
762+
763+
py_fn = testdir.makepyfile(
764+
c="""
765+
class C:
766+
x = 1
767+
768+
def check(mocker):
769+
mocker.patch.object(C, "x", 2)
770+
assert C.x == 2
771+
"""
772+
)
773+
testdir.syspathinsert()
774+
775+
testdir.makepyfile(
776+
"""
777+
from c import check
778+
def test_foo(mocker):
779+
check(mocker)
780+
"""
781+
)
782+
result = testdir.runpytest()
783+
result.stdout.fnmatch_lines("* 1 passed *")
784+
785+
kwargs = {"legacy": True} if sys.version_info[0] >= 3 else {}
786+
assert compileall.compile_file(str(py_fn), **kwargs)
787+
788+
pyc_fn = str(py_fn) + "c"
789+
assert os.path.isfile(pyc_fn)
790+
791+
py_fn.remove()
792+
result = testdir.runpytest()
793+
result.stdout.fnmatch_lines("* 1 passed *")

0 commit comments

Comments
 (0)