fix assertion rewriting in read-only directories (refs #60)
This commit is contained in:
parent
f3bc197afb
commit
14ceaf2459
|
@ -1,6 +1,7 @@
|
||||||
Changes between 2.1.0 and 2.1.1.DEV
|
Changes between 2.1.0 and 2.1.1.DEV
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
|
||||||
|
- fix assertion rewriting in read-only directories
|
||||||
- fix issue59: provide system-out/err tags for junitxml output
|
- fix issue59: provide system-out/err tags for junitxml output
|
||||||
- fix assertion rewriting on boolean operations with 3 or more operands
|
- fix assertion rewriting on boolean operations with 3 or more operands
|
||||||
|
|
||||||
|
|
|
@ -90,16 +90,26 @@ class AssertionRewritingHook(object):
|
||||||
# cached pyc is always a complete, valid pyc. Operations on it must be
|
# cached pyc is always a complete, valid pyc. Operations on it must be
|
||||||
# atomic. POSIX's atomic rename comes in handy.
|
# atomic. POSIX's atomic rename comes in handy.
|
||||||
cache_dir = os.path.join(fn_pypath.dirname, "__pycache__")
|
cache_dir = os.path.join(fn_pypath.dirname, "__pycache__")
|
||||||
|
try:
|
||||||
py.path.local(cache_dir).ensure(dir=True)
|
py.path.local(cache_dir).ensure(dir=True)
|
||||||
|
except py.error.EACCES:
|
||||||
|
state.trace("read only directory: %r" % (fn_pypath.dirname,))
|
||||||
|
write = False
|
||||||
|
else:
|
||||||
|
write = True
|
||||||
cache_name = fn_pypath.basename[:-3] + "." + PYTEST_TAG + ".pyc"
|
cache_name = fn_pypath.basename[:-3] + "." + PYTEST_TAG + ".pyc"
|
||||||
pyc = os.path.join(cache_dir, cache_name)
|
pyc = os.path.join(cache_dir, cache_name)
|
||||||
|
# Notice that even if we're in a read-only directory, I'm going to check
|
||||||
|
# for a cached pyc. This may not be optimal...
|
||||||
co = _read_pyc(fn_pypath, pyc)
|
co = _read_pyc(fn_pypath, pyc)
|
||||||
if co is None:
|
if co is None:
|
||||||
state.trace("rewriting %r" % (fn,))
|
state.trace("rewriting %r" % (fn,))
|
||||||
co = _make_rewritten_pyc(state, fn_pypath, pyc)
|
co = _rewrite_test(state, fn_pypath)
|
||||||
if co is None:
|
if co is None:
|
||||||
# Probably a SyntaxError in the module.
|
# Probably a SyntaxError in the test.
|
||||||
return None
|
return None
|
||||||
|
if write:
|
||||||
|
_make_rewritten_pyc(state, fn_pypath, pyc, co)
|
||||||
else:
|
else:
|
||||||
state.trace("found cached rewritten pyc for %r" % (fn,))
|
state.trace("found cached rewritten pyc for %r" % (fn,))
|
||||||
self.modules[name] = co, pyc
|
self.modules[name] = co, pyc
|
||||||
|
@ -135,12 +145,8 @@ def _write_pyc(co, source_path, pyc):
|
||||||
finally:
|
finally:
|
||||||
fp.close()
|
fp.close()
|
||||||
|
|
||||||
def _make_rewritten_pyc(state, fn, pyc):
|
def _rewrite_test(state, fn):
|
||||||
"""Try to rewrite *fn* and dump the rewritten code to *pyc*.
|
"""Try to read and rewrite *fn* and return the code object."""
|
||||||
|
|
||||||
Return the code object of the rewritten module on success. Return None if
|
|
||||||
there are problems parsing or compiling the module.
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
source = fn.read("rb")
|
source = fn.read("rb")
|
||||||
except EnvironmentError:
|
except EnvironmentError:
|
||||||
|
@ -159,6 +165,10 @@ def _make_rewritten_pyc(state, fn, pyc):
|
||||||
# assertion rewriting, but I don't know of a fast way to tell.
|
# assertion rewriting, but I don't know of a fast way to tell.
|
||||||
state.trace("failed to compile: %r" % (fn,))
|
state.trace("failed to compile: %r" % (fn,))
|
||||||
return None
|
return None
|
||||||
|
return co
|
||||||
|
|
||||||
|
def _make_rewritten_pyc(state, fn, pyc, co):
|
||||||
|
"""Try to dump rewritten code to *pyc*."""
|
||||||
if sys.platform.startswith("win"):
|
if sys.platform.startswith("win"):
|
||||||
# Windows grants exclusive access to open files and doesn't have atomic
|
# Windows grants exclusive access to open files and doesn't have atomic
|
||||||
# rename, so just write into the final file.
|
# rename, so just write into the final file.
|
||||||
|
|
|
@ -266,3 +266,14 @@ class TestAssertionRewrite:
|
||||||
return False
|
return False
|
||||||
assert myany(A() < 0)
|
assert myany(A() < 0)
|
||||||
assert "<MY42 object> < 0" in getmsg(f)
|
assert "<MY42 object> < 0" in getmsg(f)
|
||||||
|
|
||||||
|
|
||||||
|
class TestRewriteOnImport:
|
||||||
|
|
||||||
|
def test_readonly(self, testdir):
|
||||||
|
sub = testdir.mkdir("testing")
|
||||||
|
sub.join("test_readonly.py").write("""
|
||||||
|
def test_rewritten():
|
||||||
|
assert "@py_builtins" in globals()""")
|
||||||
|
sub.chmod(320)
|
||||||
|
assert testdir.runpytest().ret == 0
|
||||||
|
|
Loading…
Reference in New Issue