Skip to content

Commit 06bb61b

Browse files
committed
Don't fail if imp can't find the source for a .pyc file. #2038
1 parent cbf261c commit 06bb61b

4 files changed

Lines changed: 41 additions & 2 deletions

File tree

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ Michael Birtwell
101101
Michael Droettboom
102102
Michael Seifert
103103
Mike Lundy
104+
Ned Batchelder
104105
Nicolas Delaby
105106
Oleg Pidsadnyi
106107
Oliver Bestwalter

CHANGELOG.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55

66
*
77

8-
*
8+
* Cope gracefully with a .pyc file with no matching .py file (`#2038`_). Thanks
9+
`@nedbat`_.
910

1011
*
1112

1213
*
1314

15+
.. _@nedbat: https://github.com/nedbat
16+
17+
.. _#2038: https://github.com/pytest-dev/pytest/issues/2038
18+
1419

1520
3.0.4
1621
=====

_pytest/assertion/rewrite.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,12 @@ def find_module(self, name, path=None):
8080
tp = desc[2]
8181
if tp == imp.PY_COMPILED:
8282
if hasattr(imp, "source_from_cache"):
83-
fn = imp.source_from_cache(fn)
83+
try:
84+
fn = imp.source_from_cache(fn)
85+
except ValueError:
86+
# Python 3 doesn't like orphaned but still-importable
87+
# .pyc files.
88+
fn = fn[:-1]
8489
else:
8590
fn = fn[:-1]
8691
elif tp != imp.PY_SOURCE:

testing/test_assertrewrite.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1+
import glob
12
import os
3+
import py_compile
24
import stat
35
import sys
46
import zipfile
7+
58
import py
69
import pytest
710

@@ -480,6 +483,31 @@ def test_no_bytecode():
480483
monkeypatch.setenv("PYTHONDONTWRITEBYTECODE", "1")
481484
assert testdir.runpytest_subprocess().ret == 0
482485

486+
def test_orphaned_pyc_file(self, testdir):
487+
if sys.version_info < (3, 0) and hasattr(sys, 'pypy_version_info'):
488+
pytest.skip("pypy2 doesn't run orphaned pyc files")
489+
490+
testdir.makepyfile("""
491+
import orphan
492+
def test_it():
493+
assert orphan.value == 17
494+
""")
495+
testdir.makepyfile(orphan="""
496+
value = 17
497+
""")
498+
py_compile.compile("orphan.py")
499+
os.remove("orphan.py")
500+
501+
# Python 3 puts the .pyc files in a __pycache__ directory, and will
502+
# not import from there without source. It will import a .pyc from
503+
# the source location though.
504+
if not os.path.exists("orphan.pyc"):
505+
pycs = glob.glob("__pycache__/orphan.*.pyc")
506+
assert len(pycs) == 1
507+
os.rename(pycs[0], "orphan.pyc")
508+
509+
assert testdir.runpytest().ret == 0
510+
483511
@pytest.mark.skipif('"__pypy__" in sys.modules')
484512
def test_pyc_vs_pyo(self, testdir, monkeypatch):
485513
testdir.makepyfile("""

0 commit comments

Comments
 (0)