Mercurial > jython
changeset 8329:2a77fdc4417c
Allow source-last-modified != $py.class mtime (addresses #2862)
We allow up to 2 seconds discrepancy in the logic that decides whether
to re-compile .py source to $py.class files. This is to accommodate the
rounding of last-modified time that occurs when storing and extracting
files from a JAR, as during installation. We choose to round times down
when JARring and allow 2 seconds positive difference in the check.
This has benefits beyond #2862, in avoiding spurious recompilation, so
is made a distinct commit.
At the same time the implications of #2862 are arguably not addressed
fully until the JAR cache is made user-local.
author | Jeff Allen <ja.py@farowl.co.uk> |
---|---|
date | Fri, 21 Feb 2020 08:32:01 +0000 |
parents | 96bb13434427 |
children | 33ea06302061 |
files | Lib/test/test_import.py build.xml installer/src/java/org/python/util/install/JarInstaller.java src/org/python/core/imp.java |
diffstat | 4 files changed, 22 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/Lib/test/test_import.py +++ b/Lib/test/test_import.py @@ -142,9 +142,9 @@ class ImportTests(unittest.TestCase): # Write a Python file, make it read-only and import it with open(fname, 'w') as f: f.write("x = 'original'\n") - # Tweak the mtime of the source to ensure pyc gets updated later + # Tweak the mtime of the source 10s later to ensure compiled looks out of date s = os.stat(fname) - os.utime(fname, (s.st_atime, s.st_mtime-100000000)) + os.utime(fname, (s.st_atime, s.st_mtime+10000)) os.chmod(fname, 0400) m1 = __import__(TESTFN) self.assertEqual(m1.x, 'original')
--- a/build.xml +++ b/build.xml @@ -1190,7 +1190,7 @@ The text for an official release would c </copy> <echo>building installer .jar file</echo> - <jar destfile="${dist.dir}/jython-installer.jar" update="${jar.update}"> + <jar destfile="${dist.dir}/jython-installer.jar" update="${jar.update}" roundup="false"> <fileset dir="${dist.dir}"> <exclude name="jython-installer.jar"/> <exclude name="${jython.dev.jar}"/>
--- a/installer/src/java/org/python/util/install/JarInstaller.java +++ b/installer/src/java/org/python/util/install/JarInstaller.java @@ -49,7 +49,7 @@ public class JarInstaller { * <li>generate the start scripts * <li>run ensurepip if selected * </ul> - * + * * @param targetDirectory * @param installationType */ @@ -102,8 +102,9 @@ public class JarInstaller { } } // exclude build.xml when not installing source - if (!installationType.installSources() && zipEntryName.equals("build.xml")) + if (!installationType.installSources() && zipEntryName.equals("build.xml")) { exclude = true; + } // handle exclusion of core Lib files if (!exclude) { exclude = shouldExcludeFile(installationType, @@ -182,9 +183,9 @@ public class JarInstaller { try { String command[]; if (Installation.isWindows()) { - command = new String[]{ bindir.resolve("jython.exe").toString(), "-m", "ensurepip" }; + command = new String[] {bindir.resolve("jython.exe").toString(), "-m", "ensurepip"}; } else { - command = new String[]{ Paths.get(".", "jython").toString(), "-m", "ensurepip"}; + command = new String[] {Paths.get(".", "jython").toString(), "-m", "ensurepip"}; } ChildProcess childProcess = new ChildProcess(command); childProcess.setCWD(bindir);
--- a/src/org/python/core/imp.java +++ b/src/org/python/core/imp.java @@ -7,6 +7,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.util.Date; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; @@ -396,10 +397,16 @@ public class imp { } } - // Check source-last-modified time fossilised in the class file against that expected + /* + * The source-last-modified time is fossilised in the class file. The source may have been + * installed from a JAR, and this will have resulted in rounding of the last-modified time + * down (see build.xml::jar-sources) to the nearest 2 seconds. + */ if (testing && sourceLastModified != NO_MTIME) { - long mtime = ar.getMTime(); - if (sourceLastModified != mtime) { + long diff = ar.getMTime() - sourceLastModified; + if (diff > 2000L) { // = 2000 milliseconds + logger.log(Level.FINE, "# {0} time is {1} ms later than source", + new Object[] {name, diff}); return null; } } @@ -925,6 +932,10 @@ public class imp { if (ret != null) { return ret; } + } else { + logger.log(Level.FINE, + "# {0} dated ({1,date} {1,time,long}) < ({2,date} {2,time,long})", + new Object[] {name, new Date(classTime), new Date(pyTime)}); } }