Author: Benjamin Peterson <[email protected]>
Branch: py3k
Changeset: r53484:794e8ba95264
Date: 2012-03-13 15:40 -0500
http://bitbucket.org/pypy/pypy/changeset/794e8ba95264/
Log: give __file__ python3 semantics and add __cached__
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -852,11 +852,17 @@
pycode = ec.compiler.compile(source, pathname, 'exec', 0)
return pycode
-def exec_code_module(space, w_mod, code_w):
+def exec_code_module(space, w_mod, code_w, pathname, cpathname):
w_dict = space.getattr(w_mod, space.wrap('__dict__'))
space.call_method(w_dict, 'setdefault',
space.wrap('__builtins__'),
space.wrap(space.builtin))
+ if pathname is not None:
+ w_pathname = get_sourcefile(space, pathname)
+ if w_pathname is None:
+ w_pathname = code_w.w_filename
+ space.setitem(w_dict, space.wrap("__file__"), w_pathname)
+ space.setitem(w_dict, space.wrap("__cached__"), space.wrap(cpathname))
code_w.exec_code(space, w_dict, w_dict)
def rightmost_sep(filename):
@@ -895,28 +901,44 @@
right = rightmost_sep(pathname)
if right < 0:
- raise ValueError()
+ return None
left = rightmost_sep(pathname[:right]) + 1
assert left >= 0
if pathname[left:right] != '__pycache__':
- raise ValueError()
+ return None
# Now verify that the path component to the right of the last
# slash has two dots in it.
rightpart = pathname[right + 1:]
dot0 = rightpart.find('.') + 1
if dot0 <= 0:
- raise ValueError
+ return None
dot1 = rightpart[dot0:].find('.') + 1
if dot1 <= 0:
- raise ValueError
+ return None
# Too many dots?
if rightpart[dot0 + dot1:].find('.') >= 0:
- raise ValueError
+ return None
result = pathname[:left] + rightpart[:dot0] + 'py'
return result
+def get_sourcefile(space, filename):
+ l = len(filename)
+ if l < 5 or filename[-4:-1].lower() != ".py":
+ return space.wrap(filename)
+ py = make_source_pathname(filename)
+ if py is None:
+ py = filename[:-1]
+ try:
+ st = os.stat(py)
+ except OSError:
+ pass
+ else:
+ if stat.S_ISREG(st.st_mode):
+ return space.wrap(py)
+ return space.wrap(filename)
+
@jit.dont_look_inside
def load_source_module(space, w_modulename, w_mod, pathname, source,
write_pyc=True):
@@ -944,7 +966,7 @@
code_w = read_compiled_module(space, cpathname, stream.readall())
finally:
stream.close()
- space.setattr(w_mod, w('__file__'), w(cpathname))
+ pathname = cpathname
else:
code_w = parse_source_module(space, pathname, source)
@@ -953,7 +975,7 @@
write_compiled_module(space, code_w, cpathname, mode, mtime)
update_code_filenames(space, code_w, pathname)
- exec_code_module(space, w_mod, code_w)
+ exec_code_module(space, w_mod, code_w, pathname, cpathname)
return w_mod
@@ -1048,7 +1070,7 @@
"Bad magic number in %s", cpathname)
#print "loading pyc file:", cpathname
code_w = read_compiled_module(space, cpathname, source)
- exec_code_module(space, w_mod, code_w)
+ exec_code_module(space, w_mod, code_w, cpathname, cpathname)
return w_mod
diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py
--- a/pypy/module/imp/interp_imp.py
+++ b/pypy/module/imp/interp_imp.py
@@ -222,9 +222,8 @@
The .pyc/.pyo file does not need to exist; this simply returns the path to
the .py file calculated to correspond to the .pyc/.pyo file. If path
does not conform to PEP 3147 format, ValueError will be raised."""
- try:
- sourcename = importing.make_source_pathname(pathname)
- except ValueError:
+ sourcename = importing.make_source_pathname(pathname)
+ if sourcename is None:
raise operationerrfmt(space.w_ValueError,
"Not a PEP 3147 pyc path: %s", pathname)
return space.wrap(sourcename)
diff --git a/pypy/module/imp/test/test_import.py
b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -163,6 +163,13 @@
def w_exec_(self, cmd, ns):
exec(cmd, ns)
+ def test_file_and_cached(self):
+ import compiled.x
+ assert "__pycache__" not in compiled.x.__file__
+ assert compiled.x.__file__.endswith(".py")
+ assert "__pycache__" in compiled.x.__cached__
+ assert compiled.x.__cached__.endswith(".pyc")
+
def test_set_sys_modules_during_import(self):
from evil_pkg import evil
assert evil.a == 42
@@ -373,6 +380,7 @@
import readonly.x # cannot write x.pyc, but should not crash
finally:
os.chmod(p, 0o775)
+ assert "__pycache__" in readonly.x.__cached__
def test__import__empty_string(self):
raises(ValueError, __import__, "")
@@ -1217,17 +1225,14 @@
def test_import_possibly_from_pyc(self):
from compiled import x
- if self.usepycfiles:
- assert x.__file__.endswith('.pyc')
- else:
- assert x.__file__.endswith('.py')
+ assert x.__file__.endswith('.py')
try:
from compiled import lone
except ImportError:
assert not self.lonepycfiles, "should have found 'lone.pyc'"
else:
assert self.lonepycfiles, "should not have found 'lone.pyc'"
- assert lone.__file__.endswith('.pyc')
+ assert lone.__cached__.endswith('.pyc')
class AppTestNoLonePycFile(AppTestNoPycFile):
spaceconfig = {
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit