From: <pj...@us...> - 2008-11-22 23:23:56
|
Revision: 5601 http://jython.svn.sourceforge.net/jython/?rev=5601&view=rev Author: pjenvey Date: 2008-11-22 23:23:48 +0000 (Sat, 22 Nov 2008) Log Message: ----------- use the compiled filename for __file__ when appropriate. make imp responsible for setting __file__ instead of the compiler being involved fixes #1138 Modified Paths: -------------- trunk/jython/Lib/inspect.py trunk/jython/Lib/test/test_chdir.py trunk/jython/Lib/test/test_import_jy.py trunk/jython/Lib/test/test_inspect.py trunk/jython/Lib/warnings.py trunk/jython/src/org/python/compiler/CodeCompiler.java trunk/jython/src/org/python/compiler/Module.java trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/imp.java trunk/jython/src/org/python/modules/imp.java Modified: trunk/jython/Lib/inspect.py =================================================================== --- trunk/jython/Lib/inspect.py 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/Lib/inspect.py 2008-11-22 23:23:48 UTC (rev 5601) @@ -383,6 +383,8 @@ filename = getfile(object) if string.lower(filename[-4:]) in ('.pyc', '.pyo'): filename = filename[:-4] + '.py' + elif filename.endswith('$py.class'): + filename = filename[:-9] + '.py' for suffix, mode, kind in imp.get_suffixes(): if 'b' in mode and string.lower(filename[-len(suffix):]) == suffix: # Looks like a binary file. We want to only return a text file. Modified: trunk/jython/Lib/test/test_chdir.py =================================================================== --- trunk/jython/Lib/test/test_chdir.py 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/Lib/test/test_chdir.py 2008-11-22 23:23:48 UTC (rev 5601) @@ -361,14 +361,8 @@ __import__(self.mod_name) self.assert_(self.mod_name in sys.modules) mod = sys.modules[self.mod_name] + self.assertEqual(mod.__file__, self.mod_name + COMPILED_SUFFIX) - # XXX: Jython's import has a bug where it doesn't use the - # $py.class filename when it exists along with the .py file - if sys.platform.startswith('java'): - self.assertEqual(mod.__file__, self.mod_name + '.py') - else: - self.assertEqual(mod.__file__, self.mod_name + COMPILED_SUFFIX) - def test_compile_dest(self): py_compile.compile(self.basename1, self.basename1[:-3] + Modified: trunk/jython/Lib/test/test_import_jy.py =================================================================== --- trunk/jython/Lib/test/test_import_jy.py 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/Lib/test/test_import_jy.py 2008-11-22 23:23:48 UTC (rev 5601) @@ -73,14 +73,8 @@ fp.close() module_obj = __import__('foo.test') self.assertEquals(module_obj.test.baz, 'testtest') - # XXX: Jython's import has a bug where it doesn't use the - # $py.class filename when it exists along with the .py file - if sys.platform.startswith('java'): - self.assertEqual(module_obj.test.init_file, - os.path.join('foo', '__init__.py')) - else: - self.assertEqual(module_obj.test.init_file, - os.path.join('foo', '__init__' + COMPILED_SUFFIX)) + self.assertEqual(module_obj.test.init_file, + os.path.join('foo', '__init__' + COMPILED_SUFFIX)) # Ensure a recompile of __init__$py.class wasn't triggered to # satisfy the abnormal import Modified: trunk/jython/Lib/test/test_inspect.py =================================================================== --- trunk/jython/Lib/test/test_inspect.py 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/Lib/test/test_inspect.py 2008-11-22 23:23:48 UTC (rev 5601) @@ -20,6 +20,8 @@ modfile = mod.__file__ if modfile.endswith(('c', 'o')): modfile = modfile[:-1] +elif modfile.endswith('$py.class'): + modfile = modfile[:-9] + '.py' import __builtin__ Modified: trunk/jython/Lib/warnings.py =================================================================== --- trunk/jython/Lib/warnings.py 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/Lib/warnings.py 2008-11-22 23:23:48 UTC (rev 5601) @@ -48,6 +48,8 @@ fnl = filename.lower() if fnl.endswith((".pyc", ".pyo")): filename = filename[:-1] + elif fnl.endswith("$py.class"): + filename = filename[:-9] + '.py' else: if module == "__main__": try: Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2008-11-22 23:23:48 UTC (rev 5601) @@ -303,12 +303,6 @@ visit(((Expr) suite.body[0]).value); code.invokevirtual("org/python/core/PyFrame", "setglobal", "(" +$str + $pyObj + ")V"); } - if (module.setFile) { - loadFrame(); - code.ldc("__file__"); - module.filename.get(code); - code.invokevirtual("org/python/core/PyFrame", "setglobal", "(" +$str + $pyObj + ")V"); - } traverse(suite); return null; } Modified: trunk/jython/src/org/python/compiler/Module.java =================================================================== --- trunk/jython/src/org/python/compiler/Module.java 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/src/org/python/compiler/Module.java 2008-11-22 23:23:48 UTC (rev 5601) @@ -293,7 +293,6 @@ String sfilename; public Constant mainCode; public boolean linenumbers; - public boolean setFile=true; Future futures; Hashtable scopes; @@ -636,12 +635,10 @@ public static void compile(modType node, OutputStream ostream, String name, String filename, boolean linenumbers, boolean printResults, - boolean setFile, org.python.core.CompilerFlags cflags) throws Exception { Module module = new Module(name, filename, linenumbers); - module.setFile = setFile; if (cflags == null) { cflags = new CompilerFlags(); } @@ -649,7 +646,6 @@ new ScopesCompiler(module, module.scopes).parse(node); //Add __doc__ if it exists - //Add __file__ for filename (if it exists?) Constant main = module.PyCode(node, "<module>", false, null, false, printResults, 0, Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/src/org/python/core/Py.java 2008-11-22 23:23:48 UTC (rev 5601) @@ -1708,8 +1708,7 @@ return Py.java2py(node); } ByteArrayOutputStream ostream = new ByteArrayOutputStream(); - Module.compile(node, ostream, name, filename, linenumbers, - printResults, false, cflags); + Module.compile(node, ostream, name, filename, linenumbers, printResults, cflags); saveClassFile(name, ostream); Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/src/org/python/core/imp.java 2008-11-22 23:23:48 UTC (rev 5601) @@ -7,9 +7,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; import java.util.concurrent.locks.ReentrantLock; import org.python.core.util.FileUtil; @@ -22,9 +19,9 @@ private static final String UNKNOWN_SOURCEFILE = "<unknown>"; - public static final int APIVersion = 16; + public static final int APIVersion = 17; - //This should change to 0 for Python 2.7 and 3.0 see PEP 328 + // This should change to 0 for Python 2.7 and 3.0 see PEP 328 public static final int DEFAULT_LEVEL = -1; /** A non-empty fromlist for __import__'ing sub-modules. */ @@ -88,15 +85,15 @@ } } - static PyObject createFromPyClass(String name, InputStream fp, - boolean testing, String fileName) { + static PyObject createFromPyClass(String name, InputStream fp, boolean testing, + String sourceName, String compiledName) { byte[] data = readCode(name, fp, testing); if (testing && data == null) { return null; } PyCode code; try { - code = BytecodeLoader.makeCode(name + "$py", data, fileName); + code = BytecodeLoader.makeCode(name + "$py", data, sourceName); } catch (Throwable t) { if (testing) { return null; @@ -105,14 +102,14 @@ } } - Py.writeComment(IMPORT_LOG, "'" + name + "' as " + fileName); + Py.writeComment(IMPORT_LOG, String.format("import %s # precompiled from %s", name, + compiledName)); - return createFromCode(name, code, fileName); + return createFromCode(name, code, compiledName); } public static byte[] readCode(String name, InputStream fp, boolean testing) { byte[] data = readBytes(fp); - int n = data.length; int api; try { @@ -209,7 +206,6 @@ filename, true, false, - true, null); return ofp.toByteArray(); } catch(Throwable t) { @@ -256,6 +252,15 @@ if (c instanceof PyTableCode) { code = (PyTableCode) c; } + + if (moduleLocation != null) { + module.__setattr__("__file__", new PyString(moduleLocation)); + } else if (module.__findattr__("__file__") == null) { + // Should probably never happen (but maybe with an odd custom builtins, or + // Java Integration) + Py.writeDebug(IMPORT_LOG, String.format("Warning: %s __file__ is unknown", name)); + } + try { PyFrame f = new PyFrame(code, module.__dict__, module.__dict__, null); code.call(f); @@ -263,12 +268,6 @@ Py.getSystemState().modules.__delitem__(name.intern()); throw t; } - if(moduleLocation != null) { - module.__setattr__("__file__", - new PyString(moduleLocation)); - }else{ - Py.writeDebug(IMPORT_LOG, "No fileName known to set __file__ for " + name + "."); - } return module; } @@ -419,23 +418,25 @@ return load_module.__call__(new PyObject[] { new PyString(name) }); } - public static PyObject loadFromCompiled(String name, InputStream stream, - String filename) { - return createFromPyClass(name, stream, false, filename); + public static PyObject loadFromCompiled(String name, InputStream stream, String sourceName, + String compiledName) { + return createFromPyClass(name, stream, false, sourceName, compiledName); } static PyObject loadFromSource(PySystemState sys, String name, String modName, String entry) { - + String dirName = sys.getPath(entry); String sourceName = "__init__.py"; String compiledName = "__init__$py.class"; - String directoryName = sys.getPath(entry); - // displayDirName is for identification purposes (e.g. - // __file__): when null it forces java.io.File to be a - // relative path (e.g. foo/bar.py instead of /tmp/foo/bar.py) + // display names are for identification purposes (e.g. __file__): when entry is + // null it forces java.io.File to be a relative path (e.g. foo/bar.py instead of + // /tmp/foo/bar.py) String displayDirName = entry.equals("") ? null : entry.toString(); + String displaySourceName = new File(new File(displayDirName, name), sourceName).getPath(); + String displayCompiledName = new File(new File(displayDirName, name), + compiledName).getPath(); // First check for packages - File dir = new File(directoryName, name); + File dir = new File(dirName, name); File sourceFile = new File(dir, sourceName); File compiledFile = new File(dir, compiledName); @@ -445,48 +446,38 @@ Py.writeDebug(IMPORT_LOG, "trying source " + dir.getPath()); sourceName = name + ".py"; compiledName = name + "$py.class"; - sourceFile = new File(directoryName, sourceName); - compiledFile = new File(directoryName, compiledName); + displaySourceName = new File(displayDirName, sourceName).getPath(); + displayCompiledName = new File(displayDirName, compiledName).getPath(); + sourceFile = new File(dirName, sourceName); + compiledFile = new File(dirName, compiledName); } else { PyModule m = addModule(modName); PyObject filename = new PyString(new File(displayDirName, name).getPath()); - m.__dict__.__setitem__("__path__", new PyList( - new PyObject[] { filename })); - m.__dict__.__setitem__("__file__", filename); + m.__dict__.__setitem__("__path__", new PyList(new PyObject[] {filename})); } if (sourceFile.isFile() && caseok(sourceFile, sourceName)) { - String filename; - if (pkg) { - filename = new File(new File(displayDirName, name), sourceName).getPath(); - } else { - filename = new File(displayDirName, sourceName).getPath(); - } - if(compiledFile.isFile() && caseok(compiledFile, compiledName)) { - Py.writeDebug(IMPORT_LOG, "trying precompiled " - + compiledFile.getPath()); + if (compiledFile.isFile() && caseok(compiledFile, compiledName)) { + Py.writeDebug(IMPORT_LOG, "trying precompiled " + compiledFile.getPath()); long pyTime = sourceFile.lastModified(); long classTime = compiledFile.lastModified(); - if(classTime >= pyTime) { - // XXX: filename should use compiledName here (not - // sourceName), but this currently breaks source - // code printed out in tracebacks - PyObject ret = createFromPyClass(modName, makeStream(compiledFile), - true, filename); - if(ret != null) { + if (classTime >= pyTime) { + PyObject ret = createFromPyClass(modName, makeStream(compiledFile), true, + displaySourceName, displayCompiledName); + if (ret != null) { return ret; } } } - return createFromSource(modName, makeStream(sourceFile), filename, + return createFromSource(modName, makeStream(sourceFile), displaySourceName, compiledFile.getPath()); } + // If no source, try loading precompiled - Py.writeDebug(IMPORT_LOG, "trying precompiled with no source " - + compiledFile.getPath()); - if(compiledFile.isFile() && caseok(compiledFile, compiledName)) { - String filename = new File(displayDirName, compiledName).getPath(); - return createFromPyClass(modName, makeStream(compiledFile), true, filename); + Py.writeDebug(IMPORT_LOG, "trying precompiled with no source " + compiledFile.getPath()); + if (compiledFile.isFile() && caseok(compiledFile, compiledName)) { + return createFromPyClass(modName, makeStream(compiledFile), true, displaySourceName, + displayCompiledName); } return null; } Modified: trunk/jython/src/org/python/modules/imp.java =================================================================== --- trunk/jython/src/org/python/modules/imp.java 2008-11-22 22:37:49 UTC (rev 5600) +++ trunk/jython/src/org/python/modules/imp.java 2008-11-22 23:23:48 UTC (rev 5601) @@ -186,13 +186,13 @@ if (o == Py.NoConversion) { throw Py.TypeError("must be a file-like object"); } + String compiledName; switch (type) { case PY_SOURCE: // XXX: This should load the accompanying byte // code file instead, if it exists String resolvedFilename = sys.getPath(filename.toString()); - String compiledName = - org.python.core.imp.makeCompiledFilename(resolvedFilename); + compiledName = org.python.core.imp.makeCompiledFilename(resolvedFilename); if (name.endsWith(".__init__")) { name = name.substring(0, name.length() - ".__init__".length()); } else if (name.equals("__init__")) { @@ -204,8 +204,15 @@ compiledName); break; case PY_COMPILED: + compiledName = filename.toString(); + // XXX: Ideally we wouldn't care about sourceName here (see + // http://bugs.jython.org/issue1605847 msg3805) + String sourceName = compiledName; + if (compiledName.endsWith("$py.class")) { + sourceName = compiledName.substring(0, compiledName.length() - 9) + ".py"; + } mod = org.python.core.imp.loadFromCompiled( - name.intern(), (InputStream)o, filename.toString()); + name.intern(), (InputStream)o, sourceName, filename.toString()); break; case PKG_DIRECTORY: PyModule m = org.python.core.imp.addModule(name); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |