From fd4485a5407564cc2900e47405d0d665db499988 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 2 Aug 2014 18:01:28 -0300 Subject: [PATCH 1/2] Fixed assertionrewrite._read_pyc to handle corrupted pyc files properly This seems to be the cause for issues #437 and #301. --HG-- branch : assertionrewrite-currupted-pyc --- _pytest/assertion/rewrite.py | 5 ++++- testing/test_assertrewrite.py | 22 ++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index 95bf4117d..589dc07d2 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -308,7 +308,10 @@ def _read_pyc(source, pyc): if (len(data) != 8 or data[:4] != imp.get_magic() or struct.unpack(" strip_bytes + pyc.write(contents[:strip_bytes], mode='wb') + + assert _read_pyc(source, str(pyc)) is None # no error From cc092afd3b1306230449d09e34f7fceec9c1b4c1 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Mon, 4 Aug 2014 20:38:50 -0300 Subject: [PATCH 2/2] updated CHANGELOG and trace error message as requested in review fixes issue #437 --HG-- branch : assertionrewrite-currupted-pyc --- CHANGELOG | 3 +++ _pytest/assertion/rewrite.py | 15 ++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 88ac07419..cfeb5da10 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ NEXT ----------------------------------- +- fix issue437 where assertion rewriting could cause pytest-xdist slaves + to collect different tests. + - fix issue547 capsys/capfd also work when output capturing ("-s") is disabled. - address issue170: allow pytest.mark.xfail(...) to specify expected exceptions via diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index 589dc07d2..1f791de5e 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -131,7 +131,7 @@ class AssertionRewritingHook(object): 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, state.trace) if co is None: state.trace("rewriting %r" % (fn,)) co = _rewrite_test(state, fn_pypath) @@ -289,11 +289,13 @@ def _make_rewritten_pyc(state, fn, pyc, co): if _write_pyc(state, co, fn, proc_pyc): os.rename(proc_pyc, pyc) -def _read_pyc(source, pyc): +def _read_pyc(source, pyc, trace=None): """Possibly read a pytest pyc containing rewritten code. Return rewritten code if successful or None if not. """ + if trace is None: + trace = lambda x: None try: fp = open(pyc, "rb") except IOError: @@ -302,18 +304,21 @@ def _read_pyc(source, pyc): try: mtime = int(source.mtime()) data = fp.read(8) - except EnvironmentError: + except EnvironmentError as e: + trace('_read_pyc(%s): EnvironmentError %s' % (source, e)) return None # Check for invalid or out of date pyc file. if (len(data) != 8 or data[:4] != imp.get_magic() or struct.unpack("