From 643ab120f46323fb72881443837ece1d07c8d303 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 25 Jul 2011 21:40:38 -0500 Subject: [PATCH] only try to create the __pycache__ dir (not a tree to it) fixes #60 Also, improve error handling surrounding __pycache__ creation. --- CHANGELOG | 1 + _pytest/assertion/rewrite.py | 41 +++++++++++++++++++++++++---------- testing/test_assertrewrite.py | 24 ++++++++++++++++++++ 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 59c39cb3a..b00315248 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ Changes between 2.1.0 and 2.1.1.DEV ---------------------------------------------- +- fix error conditions involving the creation of __pycache__ - fix assertion rewriting on inserts involving strings containing '%' - fix assertion rewriting on calls with a ** arg - don't cache rewritten modules if bytecode generation is disabled diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py index dbb648e57..9699cc121 100644 --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -2,6 +2,7 @@ import ast import collections +import errno import itertools import imp import marshal @@ -97,15 +98,23 @@ class AssertionRewritingHook(object): cache_dir = os.path.join(fn_pypath.dirname, "__pycache__") if write: try: - py.path.local(cache_dir).ensure(dir=True) - except py.error.EACCES: - state.trace("read only directory: %r" % (fn_pypath.dirname,)) - write = False - except py.error.EEXIST: - state.trace("failure to create directory: %r" % ( - fn_pypath.dirname,)) - raise - #write = False + os.mkdir(cache_dir) + except OSError: + e = sys.exc_info()[1].errno + if e == errno.EEXIST: + # Either the __pycache__ directory already exists (the + # common case) or it's blocked by a non-dir node. In the + # latter case, we'll ignore it in _write_pyc. + pass + elif e == errno.ENOTDIR: + # One of the path components was not a directory, likely + # because we're in a zip file. + write = False + elif e == errno.EACCES: + state.trace("read only directory: %r" % (fn_pypath.dirname,)) + write = False + else: + raise cache_name = fn_pypath.basename[:-3] + "." + PYTEST_TAG + ".pyc" pyc = os.path.join(cache_dir, cache_name) # Notice that even if we're in a read-only directory, I'm going to check @@ -146,13 +155,21 @@ def _write_pyc(co, source_path, pyc): # little reason deviate, and I hope sometime to be able to use # imp.load_compiled to load them. (See the comment in load_module above.) mtime = int(source_path.mtime()) - fp = open(pyc, "wb") + try: + fp = open(pyc, "wb") + except IOError: + if sys.exc_info()[1].errno == errno.ENOTDIR: + # This happens when we get a EEXIST in find_module creating the + # __pycache__ directory and __pycache__ is by some non-dir node. + return False + raise try: fp.write(imp.get_magic()) fp.write(struct.pack("