Skip to content

Commit

Permalink
Handle 'mocker.patch' being used without source code
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoddemus committed Nov 20, 2019
1 parent 420fe64 commit d3d4c4a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
1.12.1 (2019-11-20)
-------------------

* Fix error if ``mocker.patch`` is used in code where the source file
is not available, for example stale ``.pyc`` files (`#169`_).

.. _#169: https://github.com/pytest-dev/pytest-mock/issues/169#issuecomment-555729265

1.12.0 (2019-11-19)
-------------------

Expand Down
3 changes: 3 additions & 0 deletions src/pytest_mock/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ def _enforce_no_with_context(self, stack):
caller = stack[2]
frame = caller[0]
info = inspect.getframeinfo(frame)
if info.code_context is None:
# no source code available (#169)
return
code_context = " ".join(info.code_context).strip()

if code_context.startswith("with mocker."):
Expand Down
38 changes: 38 additions & 0 deletions tests/test_pytest_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -753,3 +753,41 @@ def test_abort_patch_context_manager(mocker):
)

assert str(excinfo.value) == expected_error_msg


def test_abort_patch_context_manager_with_stale_pyc(testdir):
"""Ensure we don't trigger an error in case the frame where mocker.patch is being
used doesn't have a 'context' (#169)"""
import compileall

py_fn = testdir.makepyfile(
c="""
class C:
x = 1
def check(mocker):
mocker.patch.object(C, "x", 2)
assert C.x == 2
"""
)
testdir.syspathinsert()

testdir.makepyfile(
"""
from c import check
def test_foo(mocker):
check(mocker)
"""
)
result = testdir.runpytest()
result.stdout.fnmatch_lines("* 1 passed *")

kwargs = {"legacy": True} if sys.version_info[0] >= 3 else {}
assert compileall.compile_file(str(py_fn), **kwargs)

pyc_fn = str(py_fn) + "c"
assert os.path.isfile(pyc_fn)

py_fn.remove()
result = testdir.runpytest()
result.stdout.fnmatch_lines("* 1 passed *")

0 comments on commit d3d4c4a

Please sign in to comment.