Author: Benjamin Peterson <benja...@python.org> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit