From jython-checkins at python.org Fri Aug 2 02:44:24 2019 From: jython-checkins at python.org (jeff.allen) Date: Fri, 02 Aug 2019 06:44:24 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Travis_CI=3A_Use_declarati?= =?utf-8?q?ve_style?= Message-ID: <20190802064424.1.491751425869DEE3@mg.python.org> https://hg.python.org/jython/rev/08a0353ff03f changeset: 8266:08a0353ff03f user: cclauss date: Fri Aug 02 07:08:11 2019 +0100 summary: Travis CI: Use declarative style Exact same functionality but done in declarative style which is more compact and easier to understand. files: .travis.yml | 48 ++++++++++++++++------------------------ 1 files changed, 19 insertions(+), 29 deletions(-) diff --git a/.travis.yml b/.travis.yml --- a/.travis.yml +++ b/.travis.yml @@ -1,42 +1,32 @@ language: java -notifications: - email: - recipients: - - jython-dev at lists.sourceforge.net - -install: ant - -os: - - linux - - osx - -env: - matrix: - - CUSTOM_JDK="default" - - CUSTOM_JDK="openjdk7" - - CUSTOM_JDK="oraclejdk8" +addons: + homebrew: + update: true + packages: ant matrix: - exclude: - # On OSX, run with default JDK only. - - os: osx - env: CUSTOM_JDK="openjdk7" - - os: osx - env: CUSTOM_JDK="oraclejdk8" - # On Linux, run with specific JDKs only. - - os: linux - env: CUSTOM_JDK="default" + include: + - jdk: openjdk7 + # - jdk: openjdk8 + - jdk: oraclejdk8 + # - jdk: oraclejdk9 + # - jdk: oraclejdk11 # times out + - os: osx + name: "JDK: oraclejdk10 Java on macOS" + install: export JAVA_HOME=$(/usr/libexec/java_home) addons: hostname: jyshort before_install: - cat /etc/hosts # optionally check the content *after* - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then export JAVA_HOME=$(/usr/libexec/java_home); fi - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; fi - - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install ant; fi - - if [ "$TRAVIS_OS_NAME" == "linux" ]; then jdk_switcher use "$CUSTOM_JDK"; fi + +install: ant script: ant && ant regrtest-travis +notifications: + email: + recipients: + - jython-dev at lists.sourceforge.net -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Fri Aug 2 02:44:24 2019 From: jython-checkins at python.org (jeff.allen) Date: Fri, 02 Aug 2019 06:44:24 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Skip_failing_test_in_test?= =?utf-8?q?=5Fsignal=2E_bjo_=232790_refers=2E?= Message-ID: <20190802064424.1.8AEEF3AB78ACD914@mg.python.org> https://hg.python.org/jython/rev/4737cc222b7b changeset: 8265:4737cc222b7b user: Jeff Allen date: Thu Aug 01 19:47:35 2019 +0100 summary: Skip failing test in test_signal. bjo #2790 refers. files: Lib/test/test_signal.py | 13 ++++++++++--- 1 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -22,9 +22,7 @@ if (sys.platform[:3] in ('win', 'os2') or sys.platform == 'riscos' or (test_support.is_jython and os._name == 'nt')): - raise test_support.TestSkipped("Can't test signal on %s" % \ - sys.platform) - + raise unittest.SkipTest("Can't test signal on %s" % sys.platform) class HandlerBCalled(Exception): pass @@ -208,6 +206,8 @@ self.assertRaises(TypeError, signal.signal, signal.SIGUSR1, None) + @unittest.skipIf(test_support.is_jython, + "getsignal is equivalent but not identical (bjo #2790)") def test_getsignal(self): hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler) self.assertEquals(signal.getsignal(signal.SIGHUP), @@ -215,6 +215,13 @@ signal.signal(signal.SIGHUP, hup) self.assertEquals(signal.getsignal(signal.SIGHUP), hup) + def test_getsignal_jy(self): + hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler) + self.assertEquals(signal.getsignal(signal.SIGHUP), + self.trivial_signal_handler) + signal.signal(signal.SIGHUP, hup) + #self.assertEquals(signal.getsignal(signal.SIGHUP), hup) + class WakeupSignalTests(unittest.TestCase): TIMEOUT_FULL = 10 -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Fri Aug 2 02:44:24 2019 From: jython-checkins at python.org (jeff.allen) Date: Fri, 02 Aug 2019 06:44:24 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Choose_Travis_CI_distribut?= =?utf-8?q?ions_to_match_JDKs?= Message-ID: <20190802064424.1.297EA5EAEEA17DD4@mg.python.org> https://hg.python.org/jython/rev/15d80d250e51 changeset: 8267:15d80d250e51 user: Jeff Allen date: Fri Aug 02 07:19:27 2019 +0100 summary: Choose Travis CI distributions to match JDKs Unfortunately complex matrix of Linux distribution and available JDKs. Installs ant for OSX and Linux xenial. files: .travis.yml | 49 ++++++++++++++++++++++++---------------- build.xml | 9 ++++--- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml --- a/.travis.yml +++ b/.travis.yml @@ -1,30 +1,39 @@ language: java addons: - homebrew: - update: true - packages: ant - -matrix: - include: - - jdk: openjdk7 - # - jdk: openjdk8 - - jdk: oraclejdk8 - # - jdk: oraclejdk9 - # - jdk: oraclejdk11 # times out - - os: osx - name: "JDK: oraclejdk10 Java on macOS" - install: export JAVA_HOME=$(/usr/libexec/java_home) - -addons: hostname: jyshort -before_install: - - cat /etc/hosts # optionally check the content *after* + homebrew: # only active on osx + update: true + packages: + - ant + + +matrix: + include: + - os: linux + dist: precise + jdk: oraclejdk7 -install: ant + - os: linux + dist: xenial + addons: + apt: + packages: + - ant + jdk: openjdk11 -script: ant && ant regrtest-travis + - os: osx + osx_image: xcode9.3 # Last supporting Java 8 + jdk: oraclejdk8 + + +install: + - ant developer-build + + +script: + - ant regrtest-travis notifications: email: diff --git a/build.xml b/build.xml --- a/build.xml +++ b/build.xml @@ -1106,13 +1106,14 @@ - - + + + @@ -1124,13 +1125,13 @@ - - + + -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Sat Aug 3 07:00:41 2019 From: jython-checkins at python.org (jeff.allen) Date: Sat, 03 Aug 2019 11:00:41 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Fix_failures_in_test=5Fjav?= =?utf-8?q?a=5Fvisibility_emerging_at_Java_12=2E?= Message-ID: <20190803110041.1.4436CF691BC47360@mg.python.org> https://hg.python.org/jython/rev/393337d071bb changeset: 8268:393337d071bb user: Jeff Allen date: Fri Aug 02 21:52:43 2019 +0100 summary: Fix failures in test_java_visibility emerging at Java 12. A new package has been added that must be opened. Otherwise, disrespect for Java accessibility is punished with a stack dump. files: Lib/test/test_java_visibility.py | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/Lib/test/test_java_visibility.py b/Lib/test/test_java_visibility.py --- a/Lib/test/test_java_visibility.py +++ b/Lib/test/test_java_visibility.py @@ -267,6 +267,8 @@ self.add_opens("java.desktop", "java.awt.geom") for package in ("lang", "util", "nio", "nio.charset"): self.add_opens("java.base", "java." + package) + if test_support.get_java_version() >= (12,): + self.add_opens("java.base", "java.lang.constant") self.command.append(fn) self.assertEquals(subprocess.call(self.command), 0) -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Sat Aug 3 07:00:41 2019 From: jython-checkins at python.org (jeff.allen) Date: Sat, 03 Aug 2019 11:00:41 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Update_Bouncy_Castle_JARs_?= =?utf-8?q?to_version_1=2E62_=28again=29=2E?= Message-ID: <20190803110041.1.A96B183B817FE490@mg.python.org> https://hg.python.org/jython/rev/a02f17fee0c3 changeset: 8269:a02f17fee0c3 user: Jeff Allen date: Fri Aug 02 23:01:25 2019 +0100 summary: Update Bouncy Castle JARs to version 1.62 (again). Restores update accidentally reverted. Also corrects the JAR file names which are missing a dot (-162, rather than -1.62), when taken from the project's web site, comapred with maven.org. (The SHA-1 sums are valid.) files: extlibs/bcpkix-jdk15on-1.61.jar | Bin extlibs/bcpkix-jdk15on-1.62.jar | 0 extlibs/bcprov-jdk15on-1.61.jar | Bin extlibs/bcprov-jdk15on-1.62.jar | 0 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/extlibs/bcpkix-jdk15on-1.61.jar b/extlibs/bcpkix-jdk15on-1.61.jar deleted file mode 100644 index c9657cdbe99a935787404edc2a83d1e6b1732cf9..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch [stripped] diff --git a/extlibs/bcpkix-jdk15on-162.jar b/extlibs/bcpkix-jdk15on-1.62.jar rename from extlibs/bcpkix-jdk15on-162.jar rename to extlibs/bcpkix-jdk15on-1.62.jar diff --git a/extlibs/bcprov-jdk15on-1.61.jar b/extlibs/bcprov-jdk15on-1.61.jar deleted file mode 100644 index 1fdff384b720e6ac563c80a6bdf7e8bc9f883367..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 GIT binary patch [stripped] diff --git a/extlibs/bcprov-jdk15on-162.jar b/extlibs/bcprov-jdk15on-1.62.jar rename from extlibs/bcprov-jdk15on-162.jar rename to extlibs/bcprov-jdk15on-1.62.jar -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Sat Aug 3 07:00:41 2019 From: jython-checkins at python.org (jeff.allen) Date: Sat, 03 Aug 2019 11:00:41 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Travic_CI=3A_add_openjdk12?= Message-ID: <20190803110041.1.9903960A4ADFADF9@mg.python.org> https://hg.python.org/jython/rev/c580d90273d7 changeset: 8270:c580d90273d7 user: Jeff Allen date: Sat Aug 03 08:34:16 2019 +0100 summary: Travic CI: add openjdk12 files: .travis.yml | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/.travis.yml b/.travis.yml --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,14 @@ - ant jdk: openjdk11 + - os: linux + dist: xenial + addons: + apt: + packages: + - ant + jdk: openjdk12 + - os: osx osx_image: xcode9.3 # Last supporting Java 8 jdk: oraclejdk8 -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Thu Aug 8 02:45:47 2019 From: jython-checkins at python.org (jeff.allen) Date: Thu, 08 Aug 2019 06:45:47 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Move_current_logging_metho?= =?utf-8?q?ds_to_PrePy=2E?= Message-ID: <20190808064547.1.EA1F0E34DF5A4C82@mg.python.org> https://hg.python.org/jython/rev/011472a1af03 changeset: 8271:011472a1af03 user: Jeff Allen date: Sun Aug 04 12:32:08 2019 +0100 summary: Move current logging methods to PrePy. It should be possible to use logging methods without waking the sleeping giant that is the Jython Runtime. Also, simplify Options.java, starting with the verbosity control. files: src/org/python/core/Options.java | 122 ++++++++---------- src/org/python/core/PrePy.java | 45 +++++++ src/org/python/core/Py.java | 31 ---- 3 files changed, 102 insertions(+), 96 deletions(-) diff --git a/src/org/python/core/Options.java b/src/org/python/core/Options.java --- a/src/org/python/core/Options.java +++ b/src/org/python/core/Options.java @@ -77,7 +77,7 @@ * Py.DEBUG for varying levels of informative messages from Jython. Normally * this option is set from the command line. */ - public static int verbose = Py.MESSAGE; + public static int verbose = PrePy.MESSAGE; /** * Set by the {@code -i} option to the interpreter command, to ask for an interactive session to @@ -161,16 +161,15 @@ * CacheBuilderSpec string and affects how the SRE_STATE cache will behave/evict * cached PyString -> int[] code points. */ - public static final String sreCacheSpecDefault = "weakKeys,concurrencyLevel=4,maximumWeight=2621440,expireAfterAccess=30s"; + public static final String sreCacheSpecDefault = + "weakKeys,concurrencyLevel=4,maximumWeight=2621440,expireAfterAccess=30s"; public static String sreCacheSpec = sreCacheSpecDefault; // // ####### END OF OPTIONS // - private Options() { - ; - } + private Options() {} private static boolean getBooleanOption(String name, boolean defaultValue) { String prop = PySystemState.registry.getProperty(name); @@ -188,74 +187,67 @@ return prop; } - /** - * Initialize the static fields from the registry options. - */ + /** Initialize the static fields from the registry options. */ public static void setFromRegistry() { // Set the more unusual options - Options.showJavaExceptions = getBooleanOption( - PYTHON_OPTIONS_SHOW_JAVA_EXCEPTIONS, - Options.showJavaExceptions); - - Options.includeJavaStackInExceptions = getBooleanOption( - PYTHON_OPTIONS_INCLUDE_JAVA_STACK_IN_EXCEPTIONS, - Options.includeJavaStackInExceptions); - - Options.showPythonProxyExceptions = getBooleanOption( - PYTHON_OPTIONS_SHOW_PYTHON_PROXY_EXCEPTIONS, - Options.showPythonProxyExceptions); - - Options.respectJavaAccessibility = getBooleanOption( - PYTHON_SECURITY_RESPECT_JAVA_ACCESSIBILITY, - Options.respectJavaAccessibility); - - Options.proxyDebugDirectory = getStringOption( - PYTHON_OPTIONS_PROXY_DEBUG_DIRECTORY, - Options.proxyDebugDirectory); + showJavaExceptions = + getBooleanOption(PYTHON_OPTIONS_SHOW_JAVA_EXCEPTIONS, showJavaExceptions); + includeJavaStackInExceptions = getBooleanOption( + PYTHON_OPTIONS_INCLUDE_JAVA_STACK_IN_EXCEPTIONS, includeJavaStackInExceptions); + showPythonProxyExceptions = getBooleanOption( + PYTHON_OPTIONS_SHOW_PYTHON_PROXY_EXCEPTIONS, showPythonProxyExceptions); + respectJavaAccessibility = getBooleanOption( + PYTHON_SECURITY_RESPECT_JAVA_ACCESSIBILITY, respectJavaAccessibility); + proxyDebugDirectory = + getStringOption(PYTHON_OPTIONS_PROXY_DEBUG_DIRECTORY, proxyDebugDirectory); // verbosity is more complicated: - String prop = PySystemState.registry.getProperty(PYTHON_VERBOSE); - if (prop != null) { - if (prop.equalsIgnoreCase("error")) { - Options.verbose = Py.ERROR; - } else if (prop.equalsIgnoreCase("warning")) { - Options.verbose = Py.WARNING; - } else if (prop.equalsIgnoreCase("message")) { - Options.verbose = Py.MESSAGE; - } else if (prop.equalsIgnoreCase("comment")) { - Options.verbose = Py.COMMENT; - } else if (prop.equalsIgnoreCase("debug")) { - Options.verbose = Py.DEBUG; - } else { - throw Py.ValueError("Illegal verbose option setting: '" + prop - + "'"); - } + String prop; + switch ((prop = getStringOption(PYTHON_VERBOSE, "")).toLowerCase()) { + case "": + break; + case "error": + verbose = PrePy.ERROR; + break; + case "warning": + verbose = PrePy.WARNING; + break; + case "message": + verbose = PrePy.MESSAGE; + break; + case "comment": + verbose = PrePy.COMMENT; + break; + case "debug": + verbose = PrePy.DEBUG; + break; + default: + throw new IllegalArgumentException("Invalid verbose option: '" + prop + "'"); } - Options.caseok = getBooleanOption(PYTHON_OPTIONS_CASE_OK, - Options.caseok); - - Options.Qnew = getBooleanOption(PYTHON_OPTIONS_Q_NEW, Options.Qnew); + caseok = getBooleanOption(PYTHON_OPTIONS_CASE_OK, caseok); + Qnew = getBooleanOption(PYTHON_OPTIONS_Q_NEW, Qnew); - prop = PySystemState.registry.getProperty(PYTHON_DIVISION_WARNING); - if (prop != null) { - if (prop.equalsIgnoreCase("old")) { - Options.division_warning = 0; - } else if (prop.equalsIgnoreCase("warn")) { - Options.division_warning = 1; - } else if (prop.equalsIgnoreCase("warnall")) { - Options.division_warning = 2; - } else { - throw Py.ValueError("Illegal division_warning option " - + "setting: '" + prop + "'"); - } + switch ((prop = getStringOption(PYTHON_DIVISION_WARNING, "")).toLowerCase()) { + case "": + break; + case "old": + division_warning = 0; + break; + case "warn": + division_warning = 1; + break; + case "warnall": + division_warning = 2; + break; + default: + throw new IllegalArgumentException( + "Invalid division_warning option: '" + prop + "'"); } - Options.sreCacheSpec = getStringOption(PYTHON_SRE_CACHESPEC, - Options.sreCacheSpec); - Options.inspect |= getStringOption(PYTHON_INSPECT, "").length() > 0; - Options.importSite = getBooleanOption(PYTHON_IMPORT_SITE, - Options.importSite); - Options.no_site = !Options.importSite; + sreCacheSpec = getStringOption(PYTHON_SRE_CACHESPEC, sreCacheSpec); + inspect |= getStringOption(PYTHON_INSPECT, "").length() > 0; + importSite = getBooleanOption(PYTHON_IMPORT_SITE, importSite); + no_site = !importSite; } } diff --git a/src/org/python/core/PrePy.java b/src/org/python/core/PrePy.java --- a/src/org/python/core/PrePy.java +++ b/src/org/python/core/PrePy.java @@ -30,6 +30,51 @@ // Do not refer to any PyObject, Py export or PySystemState in this class. public class PrePy { + // Logging convenience functions are here so they may work before the Jython runtime starts. + + /** {@link Options#verbose} level indicating an error that prevents correct results. */ + public static final int ERROR = -1; + /** {@link Options#verbose} level indicating an unexpected event, still working correctly. */ + public static final int WARNING = 0; + /** {@link Options#verbose} level for messages that confirm correct functioning. */ + public static final int MESSAGE = 1; + /** {@link Options#verbose} level providing detail during correct functioning. */ + public static final int COMMENT = 2; + /** {@link Options#verbose} level providing detail in support of debugging or tracing. */ + public static final int DEBUG = 3; + + /** Log a message at a specified level (if that level be not below the threshold). */ + public static void maybeWrite(String type, String msg, int level) { + if (level <= Options.verbose) { + System.err.println(type + ": " + msg); + } + } + + /** Submit a message to logging at the severity level ERROR. */ + public static void writeError(String type, String msg) { + maybeWrite(type, msg, ERROR); + } + + /** Submit a message to logging at the severity level WARNING. */ + public static void writeWarning(String type, String msg) { + maybeWrite(type, msg, WARNING); + } + + /** Submit a message to logging at the severity level MESSAGE. */ + public static void writeMessage(String type, String msg) { + maybeWrite(type, msg, MESSAGE); + } + + /** Submit a message to logging at the severity level COMMENT. */ + public static void writeComment(String type, String msg) { + maybeWrite(type, msg, COMMENT); + } + + /** Submit a message to logging at the severity level DEBUG. */ + public static void writeDebug(String type, String msg) { + maybeWrite(type, msg, DEBUG); + } + /** * Get the System properties if we are allowed to. Configuration values set via * {@code -Dprop=value} to the java command will be found here. If a security manager prevents diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java --- a/src/org/python/core/Py.java +++ b/src/org/python/core/Py.java @@ -2319,37 +2319,6 @@ public static void printResult(PyObject ret) { Py.getThreadState().getSystemState().invoke("displayhook", ret); } - public static final int ERROR = -1; - public static final int WARNING = 0; - public static final int MESSAGE = 1; - public static final int COMMENT = 2; - public static final int DEBUG = 3; - - public static void maybeWrite(String type, String msg, int level) { - if (level <= Options.verbose) { - System.err.println(type + ": " + msg); - } - } - - public static void writeError(String type, String msg) { - maybeWrite(type, msg, ERROR); - } - - public static void writeWarning(String type, String msg) { - maybeWrite(type, msg, WARNING); - } - - public static void writeMessage(String type, String msg) { - maybeWrite(type, msg, MESSAGE); - } - - public static void writeComment(String type, String msg) { - maybeWrite(type, msg, COMMENT); - } - - public static void writeDebug(String type, String msg) { - maybeWrite(type, msg, DEBUG); - } public static void saveClassFile(String name, ByteArrayOutputStream bytestream) { String dirname = Options.proxyDebugDirectory; -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Thu Aug 8 02:45:47 2019 From: jython-checkins at python.org (jeff.allen) Date: Thu, 08 Aug 2019 06:45:47 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Route_console_messages_int?= =?utf-8?q?o_Java_logging_=28addresses_=232778=29=2E?= Message-ID: <20190808064547.1.1A9CF9550FCFBC77@mg.python.org> https://hg.python.org/jython/rev/5e3bd2044a51 changeset: 8272:5e3bd2044a51 user: Jeff Allen date: Wed Aug 07 22:45:47 2019 +0100 summary: Route console messages into Java logging (addresses #2778). With this change, console messages generated with Py.writeDebug etc. are converted to java.util.logging messages of corresponding severity, and so may be controlled or routed using a logging.properties file. In particular, the path now is open to obtain timestamped messages. Direct use of Options.verbose is deprecated, but clients that modify it, then call the classic Py.write* methods end up adjusting the console logging level and so the effect what they expect (nearly). files: NEWS | 10 + registry | 7 +- src/org/python/core/Options.java | 137 +++++++++++------- src/org/python/core/PrePy.java | 141 ++++++++++++++++++- src/org/python/util/jython.java | 119 ++++++++++++++- 5 files changed, 343 insertions(+), 71 deletions(-) diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -76,6 +76,16 @@ - Experimentally, we use Gradle to build a JAR and POM that may be cited as a dependency by other projects. The Jython project would like to know if this is being done suitably for downstream use. + - The registry setting (or Java property) "python.verbose", and direct use of the global + org.python.core.Options.verbose are DEPRECATED: use a Java logging properties file instead. + Console messages are now produced via java.util.logging (JUL), and the logger "org.python" + or its descendants. The jython command configures a ConsoleLogger for "org.python" and by + default a format for messages generally similar to that in v2.7.1, preceded by the logger + name and JUL severity. The volume of messages is controlled by your logging preferences, but + by default is unchanged from v2.7.1. Each -v option on the command line makes the logging + one step finer on the JUL scale. Error messages from Python and stack traces are unaffected. + When embedded in your application, Jython makes no logging configuration changes: messages + from the "org.python" name space merge with those of your application. Jython 2.7.2a1 Bugs fixed diff --git a/registry b/registry --- a/registry +++ b/registry @@ -31,9 +31,10 @@ #python.packages.directories = java.ext.dirs # up to Java 8 #python.packages.directories # undefined from Java 9 -# Set verbosity to error, warning, message, comment, or debug -# for varying levels of informative messages from Jython. Normally -# this option is set from the command line. +# DEPRECATED way to set the verbosity of messages output by Jython. If +# specified, "python.verbose" will set logging level for "org.python" when +# the runtime is initialised. It is better to use java.util.logging +# preferences (and the -v option) which work from the start of execution. #python.verbose = message # Jython ships with a JLine console (http://jline.sourceforge.net/) out of the diff --git a/src/org/python/core/Options.java b/src/org/python/core/Options.java --- a/src/org/python/core/Options.java +++ b/src/org/python/core/Options.java @@ -3,35 +3,34 @@ import static org.python.core.RegistryKey.*; +import java.util.logging.Level; + /** - * A class with static fields for each of the settable options. The options from - * registry and command line is copied into the fields here and the rest of - * Jython checks these fields. + * A class with static fields for each of the settable options. The options from registry and + * command line is copied into the fields here and the rest of Jython checks these fields. */ public class Options { // Jython options. Some of these can be set from the command line // options, but all can be controlled through the Jython registry /** - * when an exception occurs in Java code, and it is not caught, should the - * interpreter print out the Java exception in the traceback? + * when an exception occurs in Java code, and it is not caught, should the interpreter print out + * the Java exception in the traceback? */ public static boolean showJavaExceptions = false; /** - * If true, exceptions raised from Python code will include a Java stack - * trace in addition to the Python traceback. This can slow raising - * considerably. + * If true, exceptions raised from Python code will include a Java stack trace in addition to + * the Python traceback. This can slow raising considerably. * * @see org.python.core.RegistryKey#PYTHON_OPTIONS_INCLUDE_JAVA_STACK_IN_EXCEPTIONS */ public static boolean includeJavaStackInExceptions = true; /** - * When true, python exception raised in overridden methods will be shown on - * stderr. This option is remarkably useful when python is used for - * implementing CORBA server. Some CORBA servers will turn python exception - * (say a NameError) into an anonymous user exception without any + * When true, python exception raised in overridden methods will be shown on stderr. This option + * is remarkably useful when python is used for implementing CORBA server. Some CORBA servers + * will turn python exception (say a NameError) into an anonymous user exception without any * stacktrace. Setting this option will show the stacktrace. * * @see org.python.core.RegistryKey#PYTHON_OPTIONS_SHOW_PYTHON_PROXY_EXCEPTIONS @@ -39,10 +38,9 @@ public static boolean showPythonProxyExceptions = false; /** - * If true, Jython respects Java the accessibility flag for fields, - * methods, and constructors. This means you can only access public members. - * Set this to false to access all members by toggling the accessible flag - * on the member. + * If true, Jython respects Java the accessibility flag for fields, methods, and constructors. + * This means you can only access public members. Set this to false to access all members by + * toggling the accessible flag on the member. * * @see org.python.core.RegistryKey#PYTHON_SECURITY_RESPECT_JAVA_ACCESSIBILITY */ @@ -73,11 +71,16 @@ public static boolean no_site = false; /** - * Set verbosity to Py.ERROR, Py.WARNING, Py.MESSAGE, Py.COMMENT, or - * Py.DEBUG for varying levels of informative messages from Jython. Normally - * this option is set from the command line. + * Verbosity of informative messages from Jython, retained as a field for reasons of + * backward-compatibility. Normally this option should be allowed to find its value indirectly + * through {@code java.util.logging}, as adjusted by the command line {@code -v} option. + * + * @deprecated Use {@link Py#getLoggingLevel()}, + * {@link Py#setLoggingLevel(java.util.logging.Level)}, or {@code java.util.logging} + * preferences to configure logging levels. */ - public static int verbose = PrePy.MESSAGE; + @Deprecated + public static int verbose = PrePy.verbosityFromLevel(PrePy.getLoggingLevel()); /** * Set by the {@code -i} option to the interpreter command, to ask for an interactive session to @@ -95,16 +98,15 @@ public static boolean inspect = false; /** - * A directory where the dynamically generated classes are written. Nothing is - * ever read from here, it is only for debugging purposes. + * A directory where the dynamically generated classes are written. Nothing is ever read from + * here, it is only for debugging purposes. */ public static String proxyDebugDirectory; /** - * If true, Jython will use the first module found on sys.path where java - * File.isFile() returns true. Setting this to true have no effect on - * unix-type filesystems. On Windows/HFS+ systems setting it to true will - * enable Jython-2.0 behaviour. + * If true, Jython will use the first module found on sys.path where java File.isFile() returns + * true. Setting this to true have no effect on unix-type filesystems. On Windows/HFS+ systems + * setting it to true will enable Jython-2.0 behaviour. * * @see org.python.core.RegistryKey#PYTHON_OPTIONS_CASE_OK */ @@ -117,8 +119,7 @@ */ public static boolean Qnew = false; - /** Force stdin, stdout and stderr to be unbuffered, and opened in - * binary mode */ + /** Force stdin, stdout and stderr to be unbuffered, and opened in binary mode */ public static boolean unbuffered = false; /** Whether -3 (py3k warnings) was enabled via the command line. */ @@ -136,7 +137,7 @@ */ public static boolean no_user_site = false; - //XXX: place holder + // XXX: place holder public static int bytes_warning = 0; /** @@ -157,9 +158,8 @@ public static int division_warning = 0; /** - * Cache spec for the SRE_STATE code point cache. The value maps to the - * CacheBuilderSpec string and affects how the SRE_STATE cache will behave/evict - * cached PyString -> int[] code points. + * Cache spec for the SRE_STATE code point cache. The value maps to the CacheBuilderSpec string + * and affects how the SRE_STATE cache will behave/evict cached PyString -> int[] code points. */ public static final String sreCacheSpecDefault = "weakKeys,concurrencyLevel=4,maximumWeight=2621440,expireAfterAccess=30s"; @@ -189,45 +189,82 @@ /** Initialize the static fields from the registry options. */ public static void setFromRegistry() { - // Set the more unusual options + showJavaExceptions = getBooleanOption(PYTHON_OPTIONS_SHOW_JAVA_EXCEPTIONS, showJavaExceptions); includeJavaStackInExceptions = getBooleanOption( PYTHON_OPTIONS_INCLUDE_JAVA_STACK_IN_EXCEPTIONS, includeJavaStackInExceptions); - showPythonProxyExceptions = getBooleanOption( - PYTHON_OPTIONS_SHOW_PYTHON_PROXY_EXCEPTIONS, showPythonProxyExceptions); - respectJavaAccessibility = getBooleanOption( - PYTHON_SECURITY_RESPECT_JAVA_ACCESSIBILITY, respectJavaAccessibility); + showPythonProxyExceptions = getBooleanOption(PYTHON_OPTIONS_SHOW_PYTHON_PROXY_EXCEPTIONS, + showPythonProxyExceptions); + respectJavaAccessibility = getBooleanOption(PYTHON_SECURITY_RESPECT_JAVA_ACCESSIBILITY, + respectJavaAccessibility); proxyDebugDirectory = getStringOption(PYTHON_OPTIONS_PROXY_DEBUG_DIRECTORY, proxyDebugDirectory); - // verbosity is more complicated: + // Legacy python.verbose if used may countermand logging.properties::org.python.level + setLoggingFromRegistry(); + + caseok = getBooleanOption(PYTHON_OPTIONS_CASE_OK, caseok); + Qnew = getBooleanOption(PYTHON_OPTIONS_Q_NEW, Qnew); + + setDivisionWarningFromRegistry(); + + sreCacheSpec = getStringOption(PYTHON_SRE_CACHESPEC, sreCacheSpec); + inspect |= getStringOption(PYTHON_INSPECT, "").length() > 0; + importSite = getBooleanOption(PYTHON_IMPORT_SITE, importSite); + no_site = !importSite; + } + + /** + * Set the logging level from {@link RegistryKey#PYTHON_VERBOSE}. We recognise the traditional + * Jython names and those used by {@code java.util.logging}. If that key is present in the + * Jython registry it will determine the level or the logger named "org.python". + */ + private static void setLoggingFromRegistry() { String prop; switch ((prop = getStringOption(PYTHON_VERBOSE, "")).toLowerCase()) { - case "": + case "": // Leave it as it is. + break; + case "off": + PrePy.setLoggingLevel(Level.OFF); break; case "error": - verbose = PrePy.ERROR; + case "severe": + PrePy.setLoggingLevel(Level.SEVERE); break; case "warning": - verbose = PrePy.WARNING; + case "warn": + PrePy.setLoggingLevel(Level.WARNING); break; case "message": - verbose = PrePy.MESSAGE; + case "info": + PrePy.setLoggingLevel(Level.INFO); break; case "comment": - verbose = PrePy.COMMENT; + case "config": + PrePy.setLoggingLevel(Level.CONFIG); break; case "debug": - verbose = PrePy.DEBUG; + case "fine": + PrePy.setLoggingLevel(Level.FINE); + break; + case "finer": + PrePy.setLoggingLevel(Level.FINER); + break; + case "finest": + PrePy.setLoggingLevel(Level.FINEST); + break; + case "all": + PrePy.setLoggingLevel(Level.ALL); break; default: throw new IllegalArgumentException("Invalid verbose option: '" + prop + "'"); } + } - caseok = getBooleanOption(PYTHON_OPTIONS_CASE_OK, caseok); - Qnew = getBooleanOption(PYTHON_OPTIONS_Q_NEW, Qnew); - + /** Set {@link division_warning} from {@link RegistryKey#PYTHON_DIVISION_WARNING}. */ + private static void setDivisionWarningFromRegistry() { + String prop; switch ((prop = getStringOption(PYTHON_DIVISION_WARNING, "")).toLowerCase()) { case "": break; @@ -244,10 +281,6 @@ throw new IllegalArgumentException( "Invalid division_warning option: '" + prop + "'"); } + } - sreCacheSpec = getStringOption(PYTHON_SRE_CACHESPEC, sreCacheSpec); - inspect |= getStringOption(PYTHON_INSPECT, "").length() > 0; - importSite = getBooleanOption(PYTHON_IMPORT_SITE, importSite); - no_site = !importSite; - } } diff --git a/src/org/python/core/PrePy.java b/src/org/python/core/PrePy.java --- a/src/org/python/core/PrePy.java +++ b/src/org/python/core/PrePy.java @@ -11,6 +11,8 @@ import java.net.URLConnection; import java.security.AccessControlException; import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; import jnr.posix.util.Platform; @@ -30,7 +32,10 @@ // Do not refer to any PyObject, Py export or PySystemState in this class. public class PrePy { - // Logging convenience functions are here so they may work before the Jython runtime starts. + // Logging functions are here so they may be used without starting the Jython runtime. + + /** Our name-spaced root logger is "org.python". */ + protected static final Logger logger = Logger.getLogger("org.python"); /** {@link Options#verbose} level indicating an error that prevents correct results. */ public static final int ERROR = -1; @@ -43,10 +48,136 @@ /** {@link Options#verbose} level providing detail in support of debugging or tracing. */ public static final int DEBUG = 3; - /** Log a message at a specified level (if that level be not below the threshold). */ - public static void maybeWrite(String type, String msg, int level) { - if (level <= Options.verbose) { - System.err.println(type + ": " + msg); + static final Level[] LEVELS = {// + Level.OFF, // + Level.SEVERE, // Legacy: ERROR + Level.WARNING, // Legacy: WARNING + Level.INFO, // Legacy: MESSAGE + Level.CONFIG, // Legacy: COMMENT + Level.FINE, // Legacy: DEBUG + Level.FINER, Level.FINEST, Level.ALL}; + + /** + * Translate from the traditional "verbosity" system to JUL Level. We allow Jython verbosity + * values beyond the conventional range, treating values <{@link #ERROR} as {@code ERROR} + * (that is {@code Level.SEVERE}) and values >{@link #DEBUG} (that is {@code Level.FINE}) as + * {@code FINER}, {@code FINEST} and {@code ALL}. + * + * @param verbosity any integer verbosity, where the runtime default {@link #MESSAGE} = 1 + * @return a corresponding level where the default {@link #MESSAGE} produces {@code Level.INFO}. + */ + public static Level levelFromVerbosity(int verbosity) { + if (verbosity < ERROR) { + return Level.OFF; + } else if (verbosity >= LEVELS.length + (ERROR - 1)) { + return Level.ALL; + } else { + // Bound the index to the LEVELS array. + int index = verbosity - (ERROR - 1); + return LEVELS[index]; + } + } + + /** + * Translate from JUL Level to equivalent in the traditional "verbosity" system. We return + * Jython verbosity values beyond the conventional range, enough to enumerate the Java standard + * levels (e.g {@code FINER} returns 4 and {@code ALL} returns 6 ). + * + * @param level {@code java.util.logging.Level} to translate. + * @return integer verbosity, where the runtime default {@code INFO} = 1 + */ + public static int verbosityFromLevel(Level level) { + /* + * Find the least verbose setting v such that events at the given level or above will be + * logged by Jython, that is, v such that levelFromVerbosity(v) is a threshold no higher + * than the given level. We allow Jython verbosity values beyond the conventional range (e.g + * level==FINER), according to the range of values in the LEVELS array. + */ + int intLevel = level.intValue(); + int index = 0, v = ERROR - 1; // = OFF + while (index < LEVELS.length && LEVELS[index].intValue() > intLevel) { + assert LEVELS[index] == levelFromVerbosity(v); + index += 1; + v += 1; + } + return v; + } + + /** + * Convenience function to get the effective level of a given Logger, looking up the parent + * chain. + */ + private static Level getEffectiveLoggingLevel(Logger logger) { + Level level; + while ((level = logger.getLevel()) == null) { + logger = logger.getParent(); + } + return level; + } + + /** Convenience function to get the effective level of Logger "org.python". */ + public static Level getLoggingLevel() { + return getEffectiveLoggingLevel(logger); + } + + /** + * Used by {@link #maybeWrite(Level, String)}, the terminus of all verbosity-based logging + * calls, to detect changes made directly to {@link Options#verbose}. + */ + private static int savedVerbosity = Py.MESSAGE; + + /** + * Set the level of the Jython logger "org.python" using the standard {@code java.util.logging} + * scale. For backward compatibility with the traditional "verbosity" system, make a + * corresponding setting of {@link Options#verbose}. + */ + @SuppressWarnings("deprecation") + public static void setLoggingLevel(Level newLevel) { + Level currentLevel = getLoggingLevel(); + if (newLevel != currentLevel) { + try { + logger.setLevel(newLevel); + currentLevel = newLevel; + } catch (SecurityException se) { + logger.warning("A security manager prevented a change to the logging level."); + } + } + savedVerbosity = Options.verbose = verbosityFromLevel(currentLevel); + } + + /** + * Adjust the level of the Jython logger "org.python" using the traditional "verbosity" system: + * the bigger the number, the lower the logging threshold. This is primarily for the + * command-line Jython, where each "-v" increases the verbosity by one, on the + * {@code java.util.logging} scale. + * + * @param n increment on the scale {@code 1=INFO, 2=CONFIG, 3=FINE, ... } + */ + public static void increaseLoggingLevel(int n) { + int v = verbosityFromLevel(getLoggingLevel()); + setLoggingLevel(levelFromVerbosity(v + n)); + } + + /** + * Ensure that the logging system threshold is adjusted to match the legacy + * {@link Options#verbose} in the event that that has changed since we last looked. + */ + @SuppressWarnings("deprecation") + private static void syncLoggingLevel() { + if (Options.verbose != savedVerbosity) { + Level level = levelFromVerbosity(savedVerbosity = Options.verbose); + setLoggingLevel(level); + } + } + + /** Log a message at a specified level (if that level is not below the threshold). */ + @SuppressWarnings("deprecation") + public static void maybeWrite(String type, String msg, int verbosity) { + // If the caller is using the legacy logging system they may have changed Options.verbose. + syncLoggingLevel(); + if (verbosity <= Options.verbose) { + // Formulate the message in legacy style, then as a log message + logger.log(levelFromVerbosity(verbosity), "{0}: {1}", new Object[] {type, msg}); } } diff --git a/src/org/python/util/jython.java b/src/org/python/util/jython.java --- a/src/org/python/util/jython.java +++ b/src/org/python/util/jython.java @@ -10,6 +10,10 @@ import java.util.LinkedList; import java.util.List; import java.util.Properties; +import java.util.logging.ConsoleHandler; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -38,6 +42,54 @@ OK, ERROR, NOT_RUN, NO_FILE } + /** The root of the Jython Logger hierarchy, named "org.python". */ + public static final Logger logger;// = Logger.getLogger("org.python"); + + /** + * The default format for console log messages in the command-line Jython. See + * {@code java.util.logging.SimpleFormatter} for an explanation of the syntax. + *

+ * This format is used in the absence of other logging preferences. Jython tests for definitions + * in the system properties of {@code java.util.logging.config.class}, + * {@code java.util.logging.config.file}, and {@code java.util.logging.SimpleFormatter.format} + * and if none of these is defined, it sets the last of them to this value. + *

+ * You can choose something else, for example to log with millisecond time stamps, launch Jython + * as:

+     * jython -vv -J-Djava.util.logging.SimpleFormatter.format="[%1$tT.%1$tL] %3$s: (%4$s) %5$s%n"
+     * 
Depending on your shell, the argument may need quoting or escaping. + */ + public static final String CONSOLE_LOG_FORMAT = "%3$s %4$s %5$s%n"; + + static { + SecurityException exception = null; + try { + // Jython console messages (-v option) are emitted using SimpleFormatter + configureSimpleFormatter(CONSOLE_LOG_FORMAT); + } catch (SecurityException se) { + // Unable to access the necessary system properties. Give up on custom logging. + exception = se; + } + + // Whether we can configure it or not, we can still _use_ logging. + logger = Logger.getLogger("org.python"); + + if (exception == null) { + try { + // Make our "org.python" logger do its own output and not propagate to root. + setConsoleHandler(logger); + } catch (SecurityException se) { + // This probably means no logging finer than INFO (so none enabled by -v) + exception = se; + } + } + + if (exception != null) { + logger.log(Level.WARNING, "Unable to format console messages: {0}", + exception.getMessage()); + } + } + // An instance of this class will provide the console (python.console) by default. private static final String PYTHON_CONSOLE_CLASS = "org.python.util.JLineConsole"; @@ -75,7 +127,7 @@ + "-u : unbuffered binary stdout and stderr\n" // + "(also PYTHONUNBUFFERED=x)\n" // + " see man page for details on internal buffering relating to '-u'\n" - + "-v : verbose (trace import statements)\n" + + "-v : verbose (emit more \"org.python\" log messages)\n" // + "(also PYTHONVERBOSE=x)\n" + " can be supplied multiple times to increase verbosity\n" + "-V : print the Python version number and exit (also --version)\n" @@ -113,6 +165,45 @@ } /** + * Try to set the format for SimpleFormatter if no other mechanism has been provided, and + * security allows it. + * + * @param format to set for {@code java.util.logging.SimpleFormatter} + * @throws SecurityException if not allowed to read or set necessary properties. + */ + private static void configureSimpleFormatter(String format) throws SecurityException { + final String CLASS_KEY = "java.util.logging.config.class"; + String className = System.getProperty(CLASS_KEY); + if (className == null) { + final String FILE_KEY = "java.util.logging.config.file"; + String fileName = System.getProperty(FILE_KEY); + if (fileName == null) { + final String FORMAT_KEY = "java.util.logging.SimpleFormatter.format"; + String currentFormat = System.getProperty(FORMAT_KEY); + if (currentFormat == null) { + // Note that this sets the format for _all_ console logging + System.setProperty(FORMAT_KEY, format); + } + } + } + } + + /** + * Customise the logger so that it does not propagate to its parent and has its own + * {@code Handler} accepting all messages. The level set on the logger alone therefore controls + * whether messages are emitted to the console. + * + * @param logger to adjust (always "python.org") + * @throws SecurityException if no permission to adjust logging + */ + private static void setConsoleHandler(Logger logger) throws SecurityException { + logger.setUseParentHandlers(false); + Handler handler = new ConsoleHandler(); + handler.setLevel(Level.ALL); + logger.addHandler(handler); + } + + /** * Runs a JAR file, by executing the code found in the file __run__.py, which should be in the * root of the JAR archive. Note that {@code __name__} is set to the base name of the JAR file * and not to "__main__" (for historical reasons). This method does not handle @@ -384,6 +475,8 @@ public static void main(String[] args) { // Parse the command line options CommandLineOptions opts = CommandLineOptions.parse(args); + + // Choose the basic action switch (opts.action) { case VERSION: System.err.printf("Jython %s\n", Version.PY_VERSION); @@ -397,6 +490,9 @@ // Let's run some Python! ... } + // Adjust relative to the level set by java.util.logging. + PrePy.increaseLoggingLevel(opts.verbosity); + // Get system properties (or empty set if we're prevented from accessing them) Properties preProperties = PrePy.getSystemProperties(); addDefaultsFromEnvironment(preProperties); @@ -417,8 +513,7 @@ // We'll be going interactive eventually. condition an interactive console. if (PrePy.haveConsole()) { // Set the default console type if nothing else has - addDefault(preProperties, RegistryKey.PYTHON_CONSOLE, - PYTHON_CONSOLE_CLASS); + addDefault(preProperties, RegistryKey.PYTHON_CONSOLE, PYTHON_CONSOLE_CLASS); } } @@ -455,7 +550,7 @@ */ InteractiveConsole interp = new InteractiveConsole(); - if (Options.verbose > Py.MESSAGE || (!haveScript && stdinIsInteractive)) { + if (opts.verbosity > 0 || (!haveScript && stdinIsInteractive)) { // Verbose or going interactive immediately: produce sign on messages. System.err.println(InteractiveConsole.getDefaultBanner()); if (Options.importSite) { @@ -721,6 +816,8 @@ boolean version = false; /** -jar option. */ boolean jar = false; + /** Count of -v options. */ + int verbosity = 0; /** Collects definitions made with the -D option directly to Jython (not java -D). */ Properties properties = new Properties(); @@ -736,12 +833,12 @@ /** Valid long-name options. */ static final char JAR_OPTION = '\u2615'; - static final OptionScanner.LongSpec[] PROGRAM_LONG_OPTS = { - new OptionScanner.LongSpec("--", OptionScanner.DONE), - new OptionScanner.LongSpec("--help", 'h'), - new OptionScanner.LongSpec("--version", 'V'), - new OptionScanner.LongSpec("-jar", JAR_OPTION, true), // Yes, just one dash. - }; + static final OptionScanner.LongSpec[] PROGRAM_LONG_OPTS = + {new OptionScanner.LongSpec("--", OptionScanner.DONE), + new OptionScanner.LongSpec("--help", 'h'), + new OptionScanner.LongSpec("--version", 'V'), + new OptionScanner.LongSpec("-jar", JAR_OPTION, true), // Yes, just one dash. + }; /** * Parse the arguments into the static {@link Options} and a returned instance of this @@ -892,7 +989,7 @@ break; case 'v': - Options.verbose++; + verbosity++; break; case 'x': -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Sat Aug 10 15:19:41 2019 From: jython-checkins at python.org (jeff.allen) Date: Sat, 10 Aug 2019 19:19:41 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Fix_regression_in_test=5Fb?= =?utf-8?q?ytecodetools=5Fjy?= Message-ID: <20190810191941.1.5F38AFF0A1B0499F@mg.python.org> https://hg.python.org/jython/rev/88117c673998 changeset: 8273:88117c673998 user: Jeff Allen date: Thu Aug 08 22:34:14 2019 +0100 summary: Fix regression in test_bytecodetools_jy The previous method of suppressing warnings (redirect System.err) no longer works, now that we use a java.util.logging. files: Lib/test/test_bytecodetools_jy.py | 18 ++++++------------ src/org/python/core/PrePy.java | 14 +++++++++----- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Lib/test/test_bytecodetools_jy.py b/Lib/test/test_bytecodetools_jy.py --- a/Lib/test/test_bytecodetools_jy.py +++ b/Lib/test/test_bytecodetools_jy.py @@ -36,32 +36,26 @@ def faulty_callback(self, name, byte, klass): raise Exception("test exception") + def faulty_callback2(self, name, byte, klass, bogus): return def test_faulty_callback(self): - import java.lang.System as Sys - import java.io.PrintStream as PrintStream - import java.io.OutputStream as OutputStream - - class NullOutputStream(OutputStream): - def write(self, b): pass - def write(self, buf, offset, len): pass - - syserr = Sys.err - Sys.setErr(PrintStream(NullOutputStream())) - tools.register(self.faulty_callback) tools.register(self.assert_callback) tools.register(self.faulty_callback2) self.count=0 try: + # Suppress the warning otherwise produced + from org.python.core import Py + from java.util.logging import Level + level = Py.setLoggingLevel(Level.SEVERE) eval("42+1") finally: self.assertTrue(tools.unregister(self.faulty_callback)) self.assertTrue(tools.unregister(self.faulty_callback2)) self.assertTrue(tools.unregister(self.assert_callback)) - Sys.setErr(syserr) + Py.setLoggingLevel(level) self.assertEqual(self.count, 1) diff --git a/src/org/python/core/PrePy.java b/src/org/python/core/PrePy.java --- a/src/org/python/core/PrePy.java +++ b/src/org/python/core/PrePy.java @@ -130,19 +130,23 @@ * Set the level of the Jython logger "org.python" using the standard {@code java.util.logging} * scale. For backward compatibility with the traditional "verbosity" system, make a * corresponding setting of {@link Options#verbose}. + * + * @param newLevel to set + * @return previous logging level */ @SuppressWarnings("deprecation") - public static void setLoggingLevel(Level newLevel) { - Level currentLevel = getLoggingLevel(); - if (newLevel != currentLevel) { + public static Level setLoggingLevel(Level newLevel) { + Level previousLevel = getLoggingLevel(); + if (newLevel != previousLevel) { try { logger.setLevel(newLevel); - currentLevel = newLevel; } catch (SecurityException se) { logger.warning("A security manager prevented a change to the logging level."); + newLevel = previousLevel; } } - savedVerbosity = Options.verbose = verbosityFromLevel(currentLevel); + savedVerbosity = Options.verbose = verbosityFromLevel(newLevel); + return previousLevel; } /** -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Sat Aug 10 15:19:41 2019 From: jython-checkins at python.org (jeff.allen) Date: Sat, 10 Aug 2019 19:19:41 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Make_logging_lazy_througho?= =?utf-8?q?ut_the_import_mechanism=2E?= Message-ID: <20190810191941.1.5D0DF9130B3052A8@mg.python.org> https://hg.python.org/jython/rev/0b15dd7f2572 changeset: 8274:0b15dd7f2572 user: Jeff Allen date: Sat Aug 10 18:13:48 2019 +0100 summary: Make logging lazy throughout the import mechanism. We use logging's ability to accept a template and parameters. As we are rewritimg the messages, we also make them somewhat more like CPython. files: src/org/python/core/ClasspathPyImporter.java | 6 +- src/org/python/core/JavaImporter.java | 12 +- src/org/python/core/PrePy.java | 1 + src/org/python/core/Py.java | 37 +++---- src/org/python/core/SyspathArchive.java | 7 +- src/org/python/core/imp.java | 46 ++++---- src/org/python/core/packagecache/CachedJarsPackageManager.java | 51 +++++---- src/org/python/core/packagecache/PathPackageManager.java | 17 +- src/org/python/core/packagecache/SysPackageManager.java | 31 +++-- src/org/python/core/util/importer.java | 9 +- src/org/python/modules/_imp.java | 23 ++- src/org/python/modules/zipimport/zipimporter.java | 6 +- tests/java/org/python/core/packagecache/CachedJarsOver64kTest.java | 2 +- 13 files changed, 139 insertions(+), 109 deletions(-) diff --git a/src/org/python/core/ClasspathPyImporter.java b/src/org/python/core/ClasspathPyImporter.java --- a/src/org/python/core/ClasspathPyImporter.java +++ b/src/org/python/core/ClasspathPyImporter.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.Map; +import java.util.logging.Level; import org.python.core.util.FileUtil; import org.python.core.util.StringUtil; @@ -213,9 +214,10 @@ return null; } - private InputStream tryClassLoader(String fullFilename, ClassLoader loader, String name) { + private InputStream tryClassLoader(String fullFilename, ClassLoader loader, String place) { if (loader != null) { - Py.writeDebug("import", "trying " + fullFilename + " in " + name + " class loader"); + logger.log(Level.FINE, "# trying {0} in {1} class loader", + new Object[] {fullFilename, place}); return loader.getResourceAsStream(fullFilename); } return null; diff --git a/src/org/python/core/JavaImporter.java b/src/org/python/core/JavaImporter.java --- a/src/org/python/core/JavaImporter.java +++ b/src/org/python/core/JavaImporter.java @@ -1,5 +1,8 @@ package org.python.core; +import java.util.logging.Logger; +import java.util.logging.Level; + /** * Load Java classes. */ @@ -7,7 +10,9 @@ public class JavaImporter extends PyObject { public static final String JAVA_IMPORT_PATH_ENTRY = "__classpath__"; + private static Logger log = Logger.getLogger("org.python.import"); + @Override public PyObject __call__(PyObject args[], String keywords[]) { if(args[0].toString().endsWith(JAVA_IMPORT_PATH_ENTRY)){ return this; @@ -35,11 +40,11 @@ * otherwise */ public PyObject find_module(String name, PyObject path) { - Py.writeDebug("import", "trying " + name - + " in packagemanager for path " + path); + log.log(Level.FINE, "# trying {0} in package manager for path {1}", + new Object[] {name, path}); PyObject ret = PySystemState.packageManager.lookupName(name.intern()); if (ret != null) { - Py.writeComment("import", "'" + name + "' as java package"); + log.log(Level.CONFIG, "import {0} # as java package", name); return this; } return Py.None; @@ -54,6 +59,7 @@ * * @return a string representation of the object. */ + @Override public String toString() { return this.getType().toString(); } diff --git a/src/org/python/core/PrePy.java b/src/org/python/core/PrePy.java --- a/src/org/python/core/PrePy.java +++ b/src/org/python/core/PrePy.java @@ -36,6 +36,7 @@ /** Our name-spaced root logger is "org.python". */ protected static final Logger logger = Logger.getLogger("org.python"); + protected static final Logger importLogger = Logger.getLogger("org.python.import"); /** {@link Options#verbose} level indicating an error that prevents correct results. */ public static final int ERROR = -1; diff --git a/src/org/python/core/Py.java b/src/org/python/core/Py.java --- a/src/org/python/core/Py.java +++ b/src/org/python/core/Py.java @@ -4,7 +4,6 @@ import java.io.ByteArrayOutputStream; import java.io.CharArrayWriter; import java.io.File; -import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -22,6 +21,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.List; +import java.util.logging.Level; import org.python.antlr.base.mod; import org.python.core.adapter.ClassicPyObjectAdapter; @@ -33,8 +33,6 @@ import jline.console.UserInterruptException; import jnr.constants.Constant; import jnr.constants.platform.Errno; -import jnr.posix.POSIX; -import jnr.posix.POSIXFactory; import jnr.posix.util.Platform; public final class Py extends PrePy { @@ -1074,19 +1072,14 @@ ClassLoader classLoader = Py.getSystemState().getClassLoader(); if (classLoader != null) { - if (reason != null) { - writeDebug("import", "trying " + name + " as " + reason + " in sys.classLoader"); - } + findClassTrying(name, reason, classLoader, "sys.classLoader"); return loadAndInitClass(name, classLoader); } if (!syspathJavaLoaderRestricted) { try { classLoader = imp.getSyspathJavaLoader(); - if (classLoader != null && reason != null) { - writeDebug("import", - "trying " + name + " as " + reason + " in SysPathJavaLoader"); - } + findClassTrying(name, reason, classLoader, "SysPathJavaLoader"); } catch (SecurityException e) { syspathJavaLoaderRestricted = true; } @@ -1094,10 +1087,7 @@ if (syspathJavaLoaderRestricted) { classLoader = imp.getParentClassLoader(); - if (classLoader != null && reason != null) { - writeDebug("import", - "trying " + name + " as " + reason + " in Jython's parent class loader"); - } + findClassTrying(name, reason, classLoader, "Jython's parent class loader"); } if (classLoader != null) { @@ -1115,12 +1105,17 @@ } } - if (reason != null) { - writeDebug("import", "trying " + name + " as " + reason - + " in context class loader, for backwards compatibility"); + classLoader = Thread.currentThread().getContextClassLoader(); + findClassTrying(name, reason, classLoader, + "context class loader, for backwards compatibility"); + return loadAndInitClass(name, classLoader); + } + + private static void findClassTrying(String name, String reason, ClassLoader cl, String place) { + if (cl != null && reason != null && importLogger.isLoggable(Level.FINE)) { + importLogger.log(Level.FINE, "# trying {0} as {1} in {2}", + new Object[] {name, reason, place}); } - - return loadAndInitClass(name, Thread.currentThread().getContextClassLoader()); } /** @@ -1160,11 +1155,11 @@ // An alias to express intent (since boolean flags aren't exactly obvious). // We *need* to initialize classes on findClass/findClassEx, so that import // statements can trigger static initializers - private static Class loadAndInitClass(String name, ClassLoader loader) throws ClassNotFoundException { + private static Class loadAndInitClass(String name, ClassLoader loader) + throws ClassNotFoundException { return Class.forName(name, true, loader); } - public static void initProxy(PyProxy proxy, String module, String pyclass, Object[] args) { if (proxy._getPyInstance() != null) { diff --git a/src/org/python/core/SyspathArchive.java b/src/org/python/core/SyspathArchive.java --- a/src/org/python/core/SyspathArchive.java +++ b/src/org/python/core/SyspathArchive.java @@ -1,5 +1,6 @@ package org.python.core; import java.io.*; +import java.util.logging.Logger; import java.util.zip.*; @Untraversable @@ -87,8 +88,9 @@ int off = 0; while (len > 0) { int l = istream.read(buffer, off, buffer.length - off); - if (l < 0) + if (l < 0) { return null; + } off += l; len -= l; } @@ -97,12 +99,13 @@ } /* + private static Logger logger = Logger.getLogger("org.python.import"); protected void finalize() { System.out.println("closing zip file " + toString()); try { zipFile.close(); } catch (IOException e) { - Py.writeDebug("import", "closing zipEntry failed"); + logger.log(Level.FINE, "closing zipEntry failed"); } } */ diff --git a/src/org/python/core/imp.java b/src/org/python/core/imp.java --- a/src/org/python/core/imp.java +++ b/src/org/python/core/imp.java @@ -13,6 +13,8 @@ import java.io.InputStream; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; +import java.util.logging.Logger; +import java.util.logging.Level; /** * Utility functions for "import" support. @@ -24,7 +26,7 @@ */ public class imp { - private static final String IMPORT_LOG = "import"; + private static Logger logger = Logger.getLogger("org.python.import"); private static final String UNKNOWN_SOURCEFILE = ""; @@ -304,8 +306,8 @@ } // Execute the PyCode object (run the module body) to populate the module __dict__ - Py.writeComment(IMPORT_LOG, - String.format("import %s # precompiled from %s", name, compiledName)); + logger.log(Level.CONFIG, "import {0} # precompiled from {1}", + new Object[] {name, compiledName}); return createFromCode(name, code, compiledName); } @@ -482,23 +484,18 @@ fop.write(compiledSource); fop.close(); return compiledFilename; - } catch (IOException exc) { - // If we can't write the cache file, just log and continue - Py.writeDebug(IMPORT_LOG, "Unable to write to source cache file '" + compiledFilename - + "' due to " + exc); - return null; - } catch (SecurityException exc) { - // If we can't write the cache file, just log and continue - Py.writeDebug(IMPORT_LOG, "Unable to write to source cache file '" + compiledFilename - + "' due to " + exc); + } catch (IOException | SecurityException exc) { + // If we can't write the cache file, just logger and continue + logger.log(Level.FINE, "Unable to write to source cache file ''{0}'' due to {1}", + new Object[] {compiledFilename, exc}); return null; } finally { if (fop != null) { try { fop.close(); } catch (IOException e) { - Py.writeDebug(IMPORT_LOG, "Unable to close source cache file '" - + compiledFilename + "' due to " + e); + logger.log(Level.FINE, "Unable to close source cache file ''{0}'' due to {1}", + new Object[] {compiledFilename, e}); } } } @@ -573,7 +570,7 @@ outFilename = cacheCompiledSource(filename, outFilename, bytes); } - Py.writeComment(IMPORT_LOG, "'" + name + "' as " + filename); + logger.log(Level.CONFIG, "import {0} # from {1}", new Object[]{name, filename}); PyCode code = BytecodeLoader.makeCode(name + "$py", bytes, filename); return createFromCode(name, code, filename); @@ -616,7 +613,7 @@ } 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)); + logger.log(Level.WARNING, "{0} __file__ is unknown", name); } ReentrantLock importLock = Py.getSystemState().getImportLock(); @@ -778,19 +775,20 @@ * @return */ private static PyObject loadBuiltin(String name) { + final String MSG = "import {0} # builtin"; if (name == "sys") { - Py.writeComment(IMPORT_LOG, "'" + name + "' as sys in builtin modules"); + logger.log(Level.CONFIG, MSG, name); return Py.java2py(Py.getSystemState()); } if (name == "__builtin__") { - Py.writeComment(IMPORT_LOG, "'" + name + "' as __builtin__ in builtin modules"); + logger.log(Level.CONFIG, MSG, new Object[] {name, name}); return new PyModule("__builtin__", Py.getSystemState().builtins); } String mod = PySystemState.getBuiltin(name); if (mod != null) { - Class c = Py.findClassEx(mod, "builtin modules"); + Class c = Py.findClassEx(mod, "builtin module"); if (c != null) { - Py.writeComment(IMPORT_LOG, "'" + name + "' as " + mod + " in builtin modules"); + logger.log(Level.CONFIG, "import {0} # builtin {1}", new Object[] {name, mod}); try { if (PyObject.class.isAssignableFrom(c)) { // xxx ok? return PyType.fromClass(c); @@ -917,7 +915,7 @@ if (haveCompiled) { // We have the compiled file and will use that if it is not out of date - Py.writeDebug(IMPORT_LOG, "trying precompiled " + compiledFile.getPath()); + logger.log(Level.FINE, "# trying precompiled {0}", compiledFile.getPath()); long classTime = compiledFile.lastModified(); if (classTime >= pyTime) { // The compiled file does not appear out of date relative to the source. @@ -931,14 +929,14 @@ } // The compiled class is not present, is out of date, or using it failed somehow. - Py.writeDebug(IMPORT_LOG, "trying source " + sourceFile.getPath()); + logger.log(Level.FINE, "# trying source {0}", sourceFile.getPath()); return createFromSource(modName, makeStream(sourceFile), displaySourceName, compiledFile.getPath(), pyTime); } else if (haveCompiled) { // There is no source, try loading compiled - Py.writeDebug(IMPORT_LOG, - "trying precompiled with no source " + compiledFile.getPath()); + logger.log(Level.FINE, "# trying precompiled with no source {0}", + compiledFile.getPath()); return createFromPyClass(modName, makeStream(compiledFile), // false, // throw ImportError here if this fails displaySourceName, displayCompiledName, NO_MTIME, CodeImport.compiled_only); diff --git a/src/org/python/core/packagecache/CachedJarsPackageManager.java b/src/org/python/core/packagecache/CachedJarsPackageManager.java --- a/src/org/python/core/packagecache/CachedJarsPackageManager.java +++ b/src/org/python/core/packagecache/CachedJarsPackageManager.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -42,33 +43,39 @@ */ public abstract class CachedJarsPackageManager extends PackageManager { + protected static Logger logger = Logger.getLogger("org.python.import"); + /** * Message log method - hook. This default implementation does nothing. * - * @param msg message text + * @param msg message template (see java.text.MessageFormat) + * @param params parameters to insert */ - protected void message(String msg) {} + protected void message(String msg, Object... params) {} /** * Warning log method - hook. This default implementation does nothing. * - * @param warn warning text + * @param msg message template (see java.text.MessageFormat) + * @param params parameters to insert */ - protected void warning(String warn) {} + protected void warning(String msg, Object... params) {} /** * Comment log method - hook. This default implementation does nothing. * - * @param msg message text + * @param msg message template (see java.text.MessageFormat) + * @param params parameters to insert */ - protected void comment(String msg) {} + protected void comment(String msg, Object... params) {} /** * Debug log method - hook. This default implementation does nothing. * - * @param msg message text + * @param msg message template (see java.text.MessageFormat) + * @param params parameters to insert */ - protected void debug(String msg) {} + protected void debug(String msg, Object... params) {} /** * Filter class/pkg by name helper method - hook. The default implementation is used by @@ -338,7 +345,7 @@ if (writeCache && (entry == null || !(new File(entry.cachefile).exists()))) { // We intend to use a cache but there is no valid existing file. - comment("processing new jar, '" + jarcanon + "'"); + comment("processing new jar ''{0}''", jarcanon); // Create a base-name for the cache file String jarname; @@ -377,7 +384,7 @@ // Update the index entry for the cache file we shall eventually write. this.indexModified = true; if (entry.mtime != 0) { - comment("processing modified jar, '" + jarcanon + "'"); + comment("processing modified jar ''{0}''", jarcanon); } entry.mtime = mtime; } @@ -415,8 +422,7 @@ } catch (IOException ioe) { // Skip the bad JAR with a message - warning("skipping bad jar, '" - + (jarfile != null ? jarfile.toString() : jarurl.toString()) + "'"); + warning("skipping bad jar ''{0}''", (jarfile != null ? jarfile : jarurl).toString()); } } @@ -450,7 +456,7 @@ String cachefile = entry.cachefile; long mtime = entry.mtime; - debug("reading cache, '" + jarcanon + "'"); + debug("reading cache of ''{0}''", jarcanon); DataInputStream istream = null; try { @@ -458,8 +464,8 @@ String old_jarcanon = istream.readUTF(); long old_mtime = istream.readLong(); if ((!old_jarcanon.equals(jarcanon)) || (old_mtime != mtime)) { - comment("invalid cache file: " + cachefile + ", " + jarcanon + ":" + old_jarcanon - + ", " + mtime + ":" + old_mtime); + comment("invalid cache file: {0} for new:{1}({3}), old:{2}({4})", cachefile, jarcanon, + old_jarcanon, mtime, old_mtime); deleteCacheFile(cachefile); return null; } @@ -512,7 +518,7 @@ ostream = outCreateCacheFile(entry, brandNew); ostream.writeUTF(jarcanon); ostream.writeLong(entry.mtime); - comment("rewriting cachefile for '" + jarcanon + "'"); + comment("rewriting cache for ''{0}''", jarcanon); for (Entry kv : zipPackages.entrySet()) { String classes = kv.getValue(); @@ -524,7 +530,7 @@ } } } catch (IOException ioe) { - warning("can't write cache file for '" + jarcanon + "'"); + warning("failed to write cache for ''{0}'' ({1})", jarcanon, ioe.getMessage()); } finally { if (ostream != null) { try { @@ -539,11 +545,11 @@ /** Scan a Java module, creating package objects. */ protected void addModuleToPackages(Path modulePath) { try { - comment("reading packages from " + modulePath); + comment("reading packages from ''{0}''", modulePath); Map packages = getModularPackages(modulePath); addPackages(packages, modulePath.toUri().toString()); } catch (IOException ioe) { - warning("skipping bad module, '" + modulePath + "'" + ioe); + warning("skipping bad module ''{0}'' ({1})", modulePath, ioe.getMessage()); } } @@ -708,7 +714,7 @@ ostream.writeLong(xentry.mtime); } } catch (IOException ioe) { - warning("can't write index file"); + warning("failed to write index file ({0})", ioe.getMessage()); } finally { if (ostream != null) { try { @@ -841,12 +847,11 @@ try { if (!aCachedir1.isDirectory() && aCachedir1.mkdirs() == false) { - warning("can't create package cache dir, '" + aCachedir1 + "'"); + warning("failed to create cache dir ''{0}''", aCachedir1); return false; } } catch (AccessControlException ace) { - warning("The java security manager isn't allowing access to the package cache dir, '" - + aCachedir1 + "'"); + warning("Not permitted to access cache ''{0}'' ({1})", aCachedir1, ace.getMessage()); return false; } diff --git a/src/org/python/core/packagecache/PathPackageManager.java b/src/org/python/core/packagecache/PathPackageManager.java --- a/src/org/python/core/packagecache/PathPackageManager.java +++ b/src/org/python/core/packagecache/PathPackageManager.java @@ -3,6 +3,13 @@ package org.python.core.packagecache; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.logging.Level; + import org.python.core.Py; import org.python.core.PyJavaPackage; import org.python.core.PyList; @@ -11,12 +18,6 @@ import org.python.core.imp; import org.python.core.util.RelativeFile; -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilenameFilter; -import java.io.IOException; - /** * Path package manager. Gathering classes info dynamically from a set of directories in path * {@link #searchPath}, and statically from a set of jars, like {@link CachedJarsPackageManager}. @@ -56,7 +57,7 @@ f.listFiles(m); boolean exists = m.packageExists(); if (exists) { - Py.writeComment("import", "java package as '" + f.getAbsolutePath() + "'"); + logger.log(Level.CONFIG, "# trying {0}", f.getAbsolutePath()); } return exists; } @@ -186,7 +187,7 @@ this.searchPath.append(Py.newStringOrUnicode(dir.getCanonicalPath())); } } catch (IOException e) { - warning("skipping bad directory, '" + dir + "'"); + warning("# skipping bad directory {0} ({1})", dir, e.getMessage()); } } diff --git a/src/org/python/core/packagecache/SysPackageManager.java b/src/org/python/core/packagecache/SysPackageManager.java --- a/src/org/python/core/packagecache/SysPackageManager.java +++ b/src/org/python/core/packagecache/SysPackageManager.java @@ -24,30 +24,34 @@ import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; /** * System package manager. Used by org.python.core.PySystemState. */ public class SysPackageManager extends PathPackageManager { + private static Logger pkglog = Logger.getLogger("org.python.package"); + @Override - protected void message(String msg) { - Py.writeMessage("*sys-package-mgr*", msg); + protected void message(String msg, Object... params) { + pkglog.log(Level.INFO, msg, params); } @Override - protected void warning(String warn) { - Py.writeWarning("*sys-package-mgr*", warn); + protected void warning(String msg, Object... params) { + pkglog.log(Level.WARNING, msg, params); } @Override - protected void comment(String msg) { - Py.writeComment("*sys-package-mgr*", msg); + protected void comment(String msg, Object... params) { + pkglog.log(Level.CONFIG, msg, params); } @Override - protected void debug(String msg) { - Py.writeDebug("*sys-package-mgr*", msg); + protected void debug(String msg, Object... params) { + pkglog.log(Level.FINE, msg, params); } public SysPackageManager(File cachedir, Properties registry) { @@ -142,7 +146,7 @@ Files.walkFileTree(moduleDir, visitor); } catch (IOException e) { - warning("error enumerating Java modules in " + moduleDir + ": " + e.getMessage()); + warning("error enumerating Java modules in {0}: {1}", moduleDir, e.getMessage()); } } @@ -185,7 +189,7 @@ Set directories = split(registry.getProperty( - RegistryKey.PYTHON_PACKAGES_DIRECTORIES, + RegistryKey.PYTHON_PACKAGES_DIRECTORIES, defaultDirectories)); for (String name : directories) { // Each property defines a path string containing directories @@ -206,16 +210,17 @@ @Override public void notifyPackageImport(String pkg, String name) { if (pkg != null && pkg.length() > 0) { - name = pkg + '.' + name; + comment("import {0} # as java package {1}.{0}", name); + } else { + comment("import {0} # as java package", name); } - Py.writeComment("import", "'" + name + "' as java package"); } @Override public Class findClass(String pkg, String name) { Class c = super.findClass(pkg, name); if (c != null) { - Py.writeComment("import", "'" + name + "' as java class"); + comment("import {0} # as java class", name); } return c; } diff --git a/src/org/python/core/util/importer.java b/src/org/python/core/util/importer.java --- a/src/org/python/core/util/importer.java +++ b/src/org/python/core/util/importer.java @@ -4,6 +4,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.EnumSet; +import java.util.logging.Logger; +import java.util.logging.Level; import org.python.core.BytecodeLoader; import org.python.core.Py; @@ -20,6 +22,8 @@ */ public abstract class importer extends PyObject { + protected static Logger logger = Logger.getLogger("org.python.import"); + static enum EntryType { IS_SOURCE, IS_BYTECODE, IS_PACKAGE }; @@ -114,7 +118,8 @@ mod.__dict__.__setitem__("__path__", pkgpath); } imp.createFromCode(fullname, moduleCodeData.code, moduleCodeData.path); - Py.writeDebug("import", "import " + fullname + " # loaded from " + moduleCodeData.path); + logger.log(Level.FINE, "import {0} # loaded from {1}", + new Object[] {fullname, moduleCodeData.path}); return mod; } @@ -199,7 +204,7 @@ String searchPath = path + suffix; String fullSearchPath = fullPath + suffix; - Py.writeDebug("import", "# trying " + searchPath); + logger.log(Level.FINE, "# trying {0}", searchPath); T tocEntry = makeEntry(searchPath); if (tocEntry == null) { continue; diff --git a/src/org/python/modules/_imp.java b/src/org/python/modules/_imp.java --- a/src/org/python/modules/_imp.java +++ b/src/org/python/modules/_imp.java @@ -1,8 +1,13 @@ package org.python.modules; -import org.python.core.__builtin__; -import org.python.core.imp; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + import org.python.core.Py; import org.python.core.PyFile; import org.python.core.PyList; @@ -11,10 +16,8 @@ import org.python.core.PyString; import org.python.core.PySystemState; import org.python.core.PyTuple; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; +import org.python.core.__builtin__; +import org.python.core.imp; /* * A bogus implementation of the CPython builtin module "imp". @@ -37,6 +40,8 @@ public static final int PY_FROZEN = 7; public static final int IMP_HOOK = 9; + private static Logger logger = Logger.getLogger("org.python.import"); + private static class ModuleInfo { PyObject file; String filename; @@ -95,7 +100,7 @@ return new ModuleInfo(Py.None, new File(displayDirName, name).getPath(), "", "", PKG_DIRECTORY); } else { - Py.writeDebug("import", "trying source " + dir.getPath()); + logger.log(Level.FINE, "# trying directory {0}", dir.getPath()); sourceName = name + ".py"; compiledName = imp.makeCompiledFilename(sourceName); sourceFile = new File(directoryName, sourceName); @@ -105,7 +110,7 @@ if (sourceFile.isFile() && caseok(sourceFile, sourceName)) { if (!preferSource && compiledFile.isFile() && caseok(compiledFile, compiledName)) { - Py.writeDebug("import", "trying precompiled " + compiledFile.getPath()); + logger.log(Level.FINE, "# trying precompiled {0}", compiledFile.getPath()); long pyTime = sourceFile.lastModified(); long classTime = compiledFile.lastModified(); if (classTime >= pyTime) { @@ -120,7 +125,7 @@ } // If no source, try loading precompiled - Py.writeDebug("import", "trying " + compiledFile.getPath()); + logger.log(Level.FINE, "# trying precompiled {0}", compiledFile.getPath()); if (compiledFile.isFile() && caseok(compiledFile, compiledName)) { return new ModuleInfo(newFile(compiledFile), new File(displayDirName, compiledName).getPath(), diff --git a/src/org/python/modules/zipimport/zipimporter.java b/src/org/python/modules/zipimport/zipimporter.java --- a/src/org/python/modules/zipimport/zipimporter.java +++ b/src/org/python/modules/zipimport/zipimporter.java @@ -6,6 +6,8 @@ import java.io.InputStream; import java.util.Date; import java.util.Enumeration; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -49,6 +51,8 @@ "a zipfile. ZipImportError is raised if 'archivepath' doesn't point to\n" + "a valid Zip archive."); + private static Logger log = Logger.getLogger("org.python.import"); + /** Path to the Zip archive */ public String archive; @@ -315,7 +319,7 @@ try { return new ZipBundle(zipArchive, zipArchive.getInputStream(dataEntry)); } catch (IOException ioe) { - Py.writeDebug("import", "zipimporter.getDataStream exception: " + ioe.toString()); + log.log(Level.FINE, "zipimporter.getDataStream exception: {0}", ioe.toString()); throw zipimport.ZipImportError("zipimport: can not open file: " + archive); } } diff --git a/tests/java/org/python/core/packagecache/CachedJarsOver64kTest.java b/tests/java/org/python/core/packagecache/CachedJarsOver64kTest.java --- a/tests/java/org/python/core/packagecache/CachedJarsOver64kTest.java +++ b/tests/java/org/python/core/packagecache/CachedJarsOver64kTest.java @@ -41,7 +41,7 @@ } @Override - protected void warning(String msg){ + protected void warning(String msg, Object... params) { failed = true; } -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Mon Aug 12 17:50:03 2019 From: jython-checkins at python.org (jeff.allen) Date: Mon, 12 Aug 2019 21:50:03 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Restore_xml-apis_JAR_to_su?= =?utf-8?q?pport_modjy_tests=2E?= Message-ID: <20190812215003.1.0F3F329DD1C3AB6A@mg.python.org> https://hg.python.org/jython/rev/3fe1d0f6c919 changeset: 8275:3fe1d0f6c919 user: Jeff Allen date: Mon Aug 12 21:05:21 2019 +0100 summary: Restore xml-apis JAR to support modjy tests. Also, a -XX:MaxPermSize=128m JVM argument appears necessary to make the tests run on Windows. Currently they still fail because a test file test_apps_dir/invocation_tests.py is missing. files: extlibs/mockrunner-0.4.1/jar/xml-apis-2.11.0.jar | Bin extlibs/mockrunner-0.4.1/readme.txt | 11 ++++++++- tests/modjy/build.xml | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/extlibs/mockrunner-0.4.1/jar/xml-apis-2.11.0.jar b/extlibs/mockrunner-0.4.1/jar/xml-apis-2.11.0.jar new file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..46733464fc746776c331ecc51061f3a05e662fd1 GIT binary patch [stripped] diff --git a/extlibs/mockrunner-0.4.1/readme.txt b/extlibs/mockrunner-0.4.1/readme.txt --- a/extlibs/mockrunner-0.4.1/readme.txt +++ b/extlibs/mockrunner-0.4.1/readme.txt @@ -1,2 +1,9 @@ -This contains the minimal set of jars from mockrunner-0.4.1 to run the modjy tests against j2ee1.3 -with jdk1.5. +This contains the minimal set of jars from mockrunner-0.4.1 to run the modjy +tests against j2ee1.3 with jdk1.5. + +These are run from the main Jython directory as part of "ant test", +or from tests/modjy with "ant". In the latter case, JYTHON_HOME must +be set to the project/dist folder and MOCKRUNNER_HOME to this folder. + +xml-apis-*.jar is added to mockrunner because it is needed for these tests, +but not for Jython generally. diff --git a/tests/modjy/build.xml b/tests/modjy/build.xml --- a/tests/modjy/build.xml +++ b/tests/modjy/build.xml @@ -58,6 +58,7 @@ + -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Mon Aug 12 17:50:03 2019 From: jython-checkins at python.org (jeff.allen) Date: Mon, 12 Aug 2019 21:50:03 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Disable_failing_modjy_test?= =?utf-8?q?s_=28see_=232794=29_pending_fix=2E?= Message-ID: <20190812215003.1.390454EFAED21D7E@mg.python.org> https://hg.python.org/jython/rev/64c631805349 changeset: 8276:64c631805349 user: Jeff Allen date: Mon Aug 12 22:37:58 2019 +0100 summary: Disable failing modjy tests (see #2794) pending fix. files: tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java b/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java --- a/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java +++ b/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java @@ -194,6 +194,10 @@ assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); } + /* + * 5 tests are disabled until we can supply invocation_tests.py, missing from the code base. + * See https://bugs.jython.org/issue2794 . + * protected void callableQueryAppInvocationTestSetUp() throws Exception { baseSetUp(); setRealPath("/test_apps_dir", "test_apps_dir"); @@ -254,5 +258,6 @@ String result = getOutput(); assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); } - + * + */ } -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Sat Aug 17 14:47:48 2019 From: jython-checkins at python.org (jeff.allen) Date: Sat, 17 Aug 2019 18:47:48 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Removal_of_=22snapshot=22_?= =?utf-8?q?as_a_build_level=2E?= Message-ID: <20190817184748.1.10C351ED359B23A2@mg.python.org> https://hg.python.org/jython/rev/d26df166fa51 changeset: 8277:d26df166fa51 user: Jeff Allen date: Sat Aug 17 15:01:43 2019 +0100 summary: Removal of "snapshot" as a build level. The "snapshot" build level has long been disabled. It was incompatible with sys.hexversion and enabling it creates a (trivial) test failure. Removal permits some simplification of the init ant target and we can indicate "snapshot" status in the version string. files: build.xml | 206 +++++++++--- src/org/python/core/PySystemState.java | 4 +- 2 files changed, 150 insertions(+), 60 deletions(-) diff --git a/build.xml b/build.xml --- a/build.xml +++ b/build.xml @@ -4,26 +4,33 @@ Use case 1: developer build (in your local Jython copy) ------------------------------------------------------- - - call target 'developer-build' (the default for this build.xml) - +Use the command: + ant developer-build +Or just: + ant This build will create directories /build and /dist below basedir. +Use case 2: build an installer for the current version +------------------------------------------------------ +Choose a name for the snapshot (here SNAPSHOT). Use the command: + ant -Dsnapshot.name=SNAPSHOT installer -Use case 2: full build for a release (using hg checkout) +Use case 3: full build for a release (using hg checkout) --------------------------------------------------------- - make sure you have access to the Jython mercurial repository (http://hg.python.org/jython) - - override ant.properties (if necessary) - - call target 'full-build' + - override ant.properties to define necessary properties + - Use the command: + ant full-build' -This build will create a working directory named -full_build at the same level as your local directories -jython and installer. It will contain a big -jython_installer-${jython.version}.jar file suitable for installation. +This will create a working directory named full_build at the same +level as your working directory. It will contain a big JAR called +jython_installer-${jython.version}.jar. -To build older releases, it may be necessary to use an older -build.xml, too (with the corresponding tag). For example it is not -possible to build Release_2_2alpha1 with this version of build.xml. +This will build the release artefacts as if the current version +development state wer a viable release. If you want a real version +from history, check out the corresponding tag. These instructions may +be different for that tag. Note on targets --------------- @@ -39,7 +46,6 @@ 2. in the same directory as this build.xml file The first setting of a property wins. Further settings are ignored. - Actions for a release --------------------- See http://wiki.python.org/jython/JythonDeveloperGuide/HowToReleaseJython @@ -63,9 +69,12 @@ - + - + @@ -76,38 +85,65 @@ + + - - - + + - + - + + + + + + + + + + + + + + - - + + + + + + - - - + + + + + + + + + + + @@ -180,11 +216,24 @@ + + + + + + + + + + + @@ -196,15 +245,27 @@ + + + + + + + + + + + - + + @@ -213,16 +274,28 @@ - + - + . Build environment for ${ant.project.name} (Note: if ${propertyname} is displayed, then the property is not set) + --- build Jython version --- + jython.version = '${jython.version}' + jython.release_level = '${jython.release_level}' + snapshot.name = '${snapshot.name}' + snapshot.suffix = '${snapshot.suffix}' + jython.dev.jar = '${jython.dev.jar}' + jython.deploy.jar = '${jython.deploy.jar}' + jython.standalone.jar = '${jython.standalone.jar}' + jython.javadoc.jar = '${jython.javadoc.jar}' + jython.sources.jar = '${jython.sources.jar}' --- optional libraries --- oracle location = '${oracle.jar}' informix location = '${informix.jar}' @@ -249,8 +322,8 @@ nowarn = '${nowarn}' test = '${test}' test.source.dir = '${test.source.dir}' - --- properties (used for full-build only) --- - checkout.dir = '${checkout.dir}' + --- properties only used for a full-build --- + checkout.dir = '${checkout.dir}' javahl.dir = '${javahl.dir}' do.snapshot.build = '${do.snapshot.build}' snapshot.revision = '${snapshot.revision}' @@ -260,7 +333,8 @@ - + @@ -332,7 +406,7 @@ - @@ -351,6 +425,7 @@ + @@ -358,11 +433,13 @@ + + @@ -376,7 +453,7 @@ - + @@ -729,35 +806,47 @@ - + copy misc files from ${jython.base.dir} - + + + + + + + + + + + + copy sources from ${jython.base.dir} - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + @@ -846,7 +935,9 @@ - + compiling installer from ${installer.src.dir} - + copy installer icon to ${dist.dir} diff --git a/src/org/python/core/PySystemState.java b/src/org/python/core/PySystemState.java --- a/src/org/python/core/PySystemState.java +++ b/src/org/python/core/PySystemState.java @@ -940,7 +940,7 @@ } try { // user registry has precedence over installed registry - File homeFile = new File(registry.getProperty(USER_HOME), + File homeFile = new File(registry.getProperty(USER_HOME), ".jython"); addRegistryFile(homeFile); addRegistryFile(new File(prefix, "registry")); @@ -1238,8 +1238,6 @@ s = "candidate"; } else if (Version.PY_RELEASE_LEVEL == 0x0F) { s = "final"; - } else if (Version.PY_RELEASE_LEVEL == 0xAA) { - s = "snapshot"; } else { throw new RuntimeException( "Illegal value for PY_RELEASE_LEVEL: " + Version.PY_RELEASE_LEVEL); -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Sat Aug 17 14:47:49 2019 From: jython-checkins at python.org (jeff.allen) Date: Sat, 17 Aug 2019 18:47:49 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Provide_CPython_licence_to?= =?utf-8?q?_copy_during_full-build_=28fixes_=232330=29=2E?= Message-ID: <20190817184749.1.703B70AD5EB2C7FD@mg.python.org> https://hg.python.org/jython/rev/40004e96dbc5 changeset: 8278:40004e96dbc5 user: Jeff Allen date: Sat Aug 17 18:12:41 2019 +0100 summary: Provide CPython licence to copy during full-build (fixes #2330). Rather than cloning from the (now legacy) CPython hg repository, we provide our own copy. Old text in our licence (history section) is updated to name files correctly. files: LICENSE.txt | 10 +- NEWS | 1 + build.xml | 8 +- lib-python/LICENSE.txt | 748 +++++++++++++++++++++++++++++ 4 files changed, 760 insertions(+), 7 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt --- a/LICENSE.txt +++ b/LICENSE.txt @@ -188,13 +188,15 @@ Python Software Foundation contributor agreements and releases are covered under the Python Software Foundation license version 2. -The standard library is covered by the Python Software Foundation -license as well. See the Lib/LICENSE file for details. +The Python standard library developed for CPython is also used in Jython, and +(like Jython itself) is provided under the Python Software Foundation +license. See the file LICENSE_CPython.txt for details. The zxJDBC package was written by Brian Zimmer and originally licensed under the GNU Public License. The package is now covered by the Jython Software License. -The command line interpreter is covered by the Apache Software -License. See the org/apache/LICENSE file for details. +Elements of the supporting libraries (appearing renamed in some Jython JARs) +are covered by the Apache Software License. See the file LICENSE_Apache.txt +for details. diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Development tip Bugs fixed + - [ 2330 ] full-build fails to copy CPython License - [ 2651 ] Travis builds failing with *** buffer overflow detected *** - [ 2703 ] JycompileAntTask cannot find ...ant.taskdefs.MatchingTask - [ 2708 ] test_urllib2net fails (on Travis CI) diff --git a/build.xml b/build.xml --- a/build.xml +++ b/build.xml @@ -801,9 +801,11 @@ - - copy CPython LICENSE from ${checkout.dir}/python - + + copy CPython license from ${jython.base.dir}/lib-python + diff --git a/lib-python/LICENSE.txt b/lib-python/LICENSE.txt new file mode 100644 --- /dev/null +++ b/lib-python/LICENSE.txt @@ -0,0 +1,748 @@ +A. HISTORY OF THE SOFTWARE +========================== + +Python was created in the early 1990s by Guido van Rossum at Stichting +Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands +as a successor of a language called ABC. Guido remains Python's +principal author, although it includes many contributions from others. + +In 1995, Guido continued his work on Python at the Corporation for +National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) +in Reston, Virginia where he released several versions of the +software. + +In May 2000, Guido and the Python core development team moved to +BeOpen.com to form the BeOpen PythonLabs team. In October of the same +year, the PythonLabs team moved to Digital Creations, which became +Zope Corporation. In 2001, the Python Software Foundation (PSF, see +https://www.python.org/psf/) was formed, a non-profit organization +created specifically to own Python-related Intellectual Property. +Zope Corporation was a sponsoring member of the PSF. + +All Python releases are Open Source (see http://www.opensource.org for +the Open Source Definition). Historically, most, but not all, Python +releases have also been GPL-compatible; the table below summarizes +the various releases. + + Release Derived Year Owner GPL- + from compatible? (1) + + 0.9.0 thru 1.2 1991-1995 CWI yes + 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes + 1.6 1.5.2 2000 CNRI no + 2.0 1.6 2000 BeOpen.com no + 1.6.1 1.6 2001 CNRI yes (2) + 2.1 2.0+1.6.1 2001 PSF no + 2.0.1 2.0+1.6.1 2001 PSF yes + 2.1.1 2.1+2.0.1 2001 PSF yes + 2.1.2 2.1.1 2002 PSF yes + 2.1.3 2.1.2 2002 PSF yes + 2.2 and above 2.1.1 2001-now PSF yes + +Footnotes: + +(1) GPL-compatible doesn't mean that we're distributing Python under + the GPL. All Python licenses, unlike the GPL, let you distribute + a modified version without making your changes open source. The + GPL-compatible licenses make it possible to combine Python with + other software that is released under the GPL; the others don't. + +(2) According to Richard Stallman, 1.6.1 is not GPL-compatible, + because its license has a choice of law clause. According to + CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 + is "not incompatible" with the GPL. + +Thanks to the many outside volunteers who have worked under Guido's +direction to make these releases possible. + + +B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON +=============================================================== + +PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 +-------------------------------------------- + +1. This LICENSE AGREEMENT is between the Python Software Foundation +("PSF"), and the Individual or Organization ("Licensee") accessing and +otherwise using this software ("Python") in source or binary form and +its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, PSF hereby +grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, +analyze, test, perform and/or display publicly, prepare derivative works, +distribute, and otherwise use Python alone or in any derivative version, +provided, however, that PSF's License Agreement and PSF's notice of copyright, +i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation; +All Rights Reserved" are retained in Python alone or in any derivative version +prepared by Licensee. + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python. + +4. PSF is making Python available to Licensee on an "AS IS" +basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. Nothing in this License Agreement shall be deemed to create any +relationship of agency, partnership, or joint venture between PSF and +Licensee. This License Agreement does not grant permission to use PSF +trademarks or trade name in a trademark sense to endorse or promote +products or services of Licensee, or any third party. + +8. By copying, installing or otherwise using Python, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 +------------------------------------------- + +BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 + +1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an +office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the +Individual or Organization ("Licensee") accessing and otherwise using +this software in source or binary form and its associated +documentation ("the Software"). + +2. Subject to the terms and conditions of this BeOpen Python License +Agreement, BeOpen hereby grants Licensee a non-exclusive, +royalty-free, world-wide license to reproduce, analyze, test, perform +and/or display publicly, prepare derivative works, distribute, and +otherwise use the Software alone or in any derivative version, +provided, however, that the BeOpen Python License is retained in the +Software, alone or in any derivative version prepared by Licensee. + +3. BeOpen is making the Software available to Licensee on an "AS IS" +basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE +SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS +AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY +DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +5. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +6. This License Agreement shall be governed by and interpreted in all +respects by the law of the State of California, excluding conflict of +law provisions. Nothing in this License Agreement shall be deemed to +create any relationship of agency, partnership, or joint venture +between BeOpen and Licensee. This License Agreement does not grant +permission to use BeOpen trademarks or trade names in a trademark +sense to endorse or promote products or services of Licensee, or any +third party. As an exception, the "BeOpen Python" logos available at +http://www.pythonlabs.com/logos.html may be used according to the +permissions granted on that web page. + +7. By copying, installing or otherwise using the software, Licensee +agrees to be bound by the terms and conditions of this License +Agreement. + + +CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 +--------------------------------------- + +1. This LICENSE AGREEMENT is between the Corporation for National +Research Initiatives, having an office at 1895 Preston White Drive, +Reston, VA 20191 ("CNRI"), and the Individual or Organization +("Licensee") accessing and otherwise using Python 1.6.1 software in +source or binary form and its associated documentation. + +2. Subject to the terms and conditions of this License Agreement, CNRI +hereby grants Licensee a nonexclusive, royalty-free, world-wide +license to reproduce, analyze, test, perform and/or display publicly, +prepare derivative works, distribute, and otherwise use Python 1.6.1 +alone or in any derivative version, provided, however, that CNRI's +License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) +1995-2001 Corporation for National Research Initiatives; All Rights +Reserved" are retained in Python 1.6.1 alone or in any derivative +version prepared by Licensee. Alternately, in lieu of CNRI's License +Agreement, Licensee may substitute the following text (omitting the +quotes): "Python 1.6.1 is made available subject to the terms and +conditions in CNRI's License Agreement. This Agreement together with +Python 1.6.1 may be located on the Internet using the following +unique, persistent identifier (known as a handle): 1895.22/1013. This +Agreement may also be obtained from a proxy server on the Internet +using the following URL: http://hdl.handle.net/1895.22/1013". + +3. In the event Licensee prepares a derivative work that is based on +or incorporates Python 1.6.1 or any part thereof, and wants to make +the derivative work available to others as provided herein, then +Licensee hereby agrees to include in any such work a brief summary of +the changes made to Python 1.6.1. + +4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" +basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND +DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS +FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT +INFRINGE ANY THIRD PARTY RIGHTS. + +5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON +1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS +A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, +OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. + +6. This License Agreement will automatically terminate upon a material +breach of its terms and conditions. + +7. This License Agreement shall be governed by the federal +intellectual property law of the United States, including without +limitation the federal copyright law, and, to the extent such +U.S. federal law does not apply, by the law of the Commonwealth of +Virginia, excluding Virginia's conflict of law provisions. +Notwithstanding the foregoing, with regard to derivative works based +on Python 1.6.1 that incorporate non-separable material that was +previously distributed under the GNU General Public License (GPL), the +law of the Commonwealth of Virginia shall govern this License +Agreement only as to issues arising under or with respect to +Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this +License Agreement shall be deemed to create any relationship of +agency, partnership, or joint venture between CNRI and Licensee. This +License Agreement does not grant permission to use CNRI trademarks or +trade name in a trademark sense to endorse or promote products or +services of Licensee, or any third party. + +8. By clicking on the "ACCEPT" button where indicated, or by copying, +installing or otherwise using Python 1.6.1, Licensee agrees to be +bound by the terms and conditions of this License Agreement. + + ACCEPT + + +CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 +-------------------------------------------------- + +Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, +The Netherlands. All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + +Additional Conditions for this Windows binary build +--------------------------------------------------- + +This program is linked with and uses Microsoft Distributable Code, +copyrighted by Microsoft Corporation. The Microsoft Distributable Code +includes the following files: + +msvcr90.dll +msvcp90.dll +msvcm90.dll + +If you further distribute programs that include the Microsoft +Distributable Code, you must comply with the restrictions on +distribution specified by Microsoft. In particular, you must require +distributors and external end users to agree to terms that protect the +Microsoft Distributable Code at least as much as Microsoft's own +requirements for the Distributable Code. See Microsoft's documentation +(included in its developer tools and on its website at microsoft.com) +for specific details. + +Redistribution of the Windows binary build of the Python interpreter +complies with this agreement, provided that you do not: + +- alter any copyright, trademark or patent notice in Microsoft's +Distributable Code; + +- use Microsoft's trademarks in your programs' names or in a way that +suggests your programs come from or are endorsed by Microsoft; + +- distribute Microsoft's Distributable Code to run on a platform other +than Microsoft operating systems, run-time technologies or application +platforms; or + +- include Microsoft Distributable Code in malicious, deceptive or +unlawful programs. + +These restrictions apply only to the Microsoft Distributable Code as +defined above, not to Python itself or any programs running on the +Python interpreter. The redistribution of the Python interpreter and +libraries is governed by the Python Software License included with this +file, or by other licenses as marked. + + +This copy of Python includes a copy of bzip2, which is licensed under the following terms: + + +-------------------------------------------------------------------------- + +This program, "bzip2", the associated library "libbzip2", and all +documentation, are copyright (C) 1996-2010 Julian R Seward. All +rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. The origin of this software must not be misrepresented; you must + not claim that you wrote the original software. If you use this + software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + +3. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + +4. The name of the author may not be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Julian Seward, jseward at bzip.org +bzip2/libbzip2 version 1.0.6 of 6 September 2010 + +-------------------------------------------------------------------------- + +This copy of Python includes a copy of Berkeley DB, which is licensed under the following terms: + +/*- + * $Id: LICENSE,v 12.9 2008/02/07 17:12:17 mark Exp $ + */ + +The following is the license that applies to this copy of the Berkeley DB +software. For a license to use the Berkeley DB software under conditions +other than those described here, or to purchase support for this software, +please contact Oracle at berkeleydb-info_us at oracle.com. + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +/* + * Copyright (c) 1990,2008 Oracle. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Redistributions in any form must be accompanied by information on + * how to obtain complete source code for the DB software and any + * accompanying software that uses the DB software. The source code + * must either be included in the distribution or be available for no + * more than the cost of distribution plus a nominal fee, and must be + * freely redistributable under reasonable conditions. For an + * executable file, complete source code means the source code for all + * modules it contains. It does not include source code for modules or + * files that typically accompany the major components of the operating + * system on which the executable file runs. + * + * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR + * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Copyright (c) 1990, 1993, 1994, 1995 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * Copyright (c) 1995, 1996 + * The President and Fellows of Harvard University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +/*** + * ASM: a very small and fast Java bytecode manipulation framework + * Copyright (c) 2000-2005 INRIA, France Telecom + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +This copy of Python includes a copy of openssl, which is licensed under the following terms: + + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a double license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core at openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core at openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay at cryptsoft.com). This product includes software written by Tim + * Hudson (tjh at cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay at cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay at cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh at cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay at cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh at cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + +This copy of Python includes a copy of Tcl, which is licensed under the following terms: + +This software is copyrighted by the Regents of the University of +California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState +Corporation and other parties. The following terms apply to all files +associated with the software unless explicitly disclaimed in +individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" +in the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (b) (3) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. + +This copy of Python includes a copy of Tk, which is licensed under the following terms: + +This software is copyrighted by the Regents of the University of +California, Sun Microsystems, Inc., and other parties. The following +terms apply to all files associated with the software unless explicitly +disclaimed in individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" +in the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (b) (3) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. + +This copy of Python includes a copy of Tix, which is licensed under the following terms: + +Copyright (c) 1993-1999 Ioi Kim Lam. +Copyright (c) 2000-2001 Tix Project Group. +Copyright (c) 2004 ActiveState + +This software is copyrighted by the above entities +and other parties. The following terms apply to all files associated +with the software unless explicitly disclaimed in individual files. + +The authors hereby grant permission to use, copy, modify, distribute, +and license this software and its documentation for any purpose, provided +that existing copyright notices are retained in all copies and that this +notice is included verbatim in any distributions. No written agreement, +license, or royalty fee is required for any of the authorized uses. +Modifications to this software may be copyrighted by their authors +and need not follow the licensing terms described here, provided that +the new terms are clearly indicated on the first page of each file where +they apply. + +IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +MODIFICATIONS. + +GOVERNMENT USE: If you are acquiring this software on behalf of the +U.S. government, the Government shall have only "Restricted Rights" +in the software and related documentation as defined in the Federal +Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you +are acquiring the software on behalf of the Department of Defense, the +software shall be classified as "Commercial Computer Software" and the +Government shall have only "Restricted Rights" as defined in Clause +252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the +authors grant the U.S. Government and others acting in its behalf +permission to use and distribute the software in accordance with the +terms specified in this license. + +---------------------------------------------------------------------- + +Parts of this software are based on the Tcl/Tk software copyrighted by +the Regents of the University of California, Sun Microsystems, Inc., +and other parties. The original license terms of the Tcl/Tk software +distribution is included in the file docs/license.tcltk. + +Parts of this software are based on the HTML Library software +copyrighted by Sun Microsystems, Inc. The original license terms of +the HTML Library software distribution is included in the file +docs/license.html_lib. -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Mon Aug 19 16:40:09 2019 From: jython-checkins at python.org (jeff.allen) Date: Mon, 19 Aug 2019 20:40:09 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Make_README=2Etxt_a_templa?= =?utf-8?q?te_for_build=2Exml_to_fill_out=2E?= Message-ID: <20190819204009.1.AD418152307346CB@mg.python.org> https://hg.python.org/jython/rev/d358cc5a1d28 changeset: 8279:d358cc5a1d28 user: Jeff Allen date: Mon Aug 19 21:38:38 2019 +0100 summary: Make README.txt a template for build.xml to fill out. README.txt is now a template into which version and other information is written at build time. This change also reorganises the code concerned with calculating the version string. A propertry is provided such that: $ ant "-Dsnapshot.name=TEST" installer creates an installer for a version identifying as 2.7.2a1-TEST and delivers a README.txt describing it as a snapshot. files: README.txt | 39 ++++++---- build.xml | 147 +++++++++++++++++++++++++--------------- 2 files changed, 112 insertions(+), 74 deletions(-) diff --git a/README.txt b/README.txt --- a/README.txt +++ b/README.txt @@ -1,9 +1,11 @@ Jython: Python for the Java Platform -Welcome to Jython 2.7.2a1. +Welcome to Jython @jython.version at . + at snapshot.banner@ -This is an alpha release of the 2.7.2 version of Jython. Along with -language and runtime compatibility with CPython 2.7, Jython 2.7 +This is @readme.release@ release of the @jython.version.short@ version of Jython. + +Along with language and runtime compatibility with CPython 2.7, Jython 2.7 provides substantial support of the Python ecosystem. This includes built-in support of pip/setuptools (you can use with bin/pip) and a native launcher for Windows (bin/jython.exe). @@ -11,24 +13,27 @@ Jim Baker presented a talk at PyCon 2015 about Jython 2.7, including demos of new features: https://www.youtube.com/watch?v=hLm3garVQFo -The release was compiled on OSX using JDK 7 and requires a minimum of -Java 7 to run. +This release was compiled on @os.name@ using @java.vendor@ Java +version @java.version@ and requires a minimum of Java @jdk.target.version@ to run. -Please try this release out and report any bugs at -http://bugs.jython.org You can test your installation of Jython (not -the standalone jar) by running the regression tests, with the command: +You can test your installation of Jython (not the standalone jar) by running the +regression tests, with the command: + +jython -m test.regrtest -e -jython -m test.regrtest -e -m regrtest_memo.txt - -For Windows, there is a simple script to do this: jython_regrtest.bat. -In either case, the memo file regrtest_memo.txt will be useful in the -bug report if you see test failures. The regression tests can take -about half an hour. +The regression tests can take about forty minutes. At the time of writing, these +tests are known to fail: + test___all__ + test_java_visibility + test_jy_internals + test_pep277 + test_ssl_jy +Please report other bugs at http://bugs.jython.org . See ACKNOWLEDGMENTS for details about Jython's copyright, license, contributors, and mailing lists; and NEWS for detailed release notes, including bugs fixed, backwards breaking changes, and new features. -We sincerely thank all who contributed to this release of Jython, -through bug reports, patches, pull requests, documentation changes, -email and conversation in all media. +The developers extend their thanks to all who contributed to this release +of Jython, through bug reports, patches, pull requests, documentation changes, +email and conversation in any media. diff --git a/build.xml b/build.xml --- a/build.xml +++ b/build.xml @@ -82,42 +82,48 @@ - + + - - - - - - - - - - - + + + - + + + + + + + + + + + + + + - + - - - - @@ -125,15 +131,20 @@ + + + - + + + - - + + @@ -281,16 +292,19 @@ - + + + . Build environment for ${ant.project.name} (Note: if ${propertyname} is displayed, then the property is not set) --- build Jython version --- - jython.version = '${jython.version}' - jython.release_level = '${jython.release_level}' - snapshot.name = '${snapshot.name}' - snapshot.suffix = '${snapshot.suffix}' + jython.version.short = '${jython.version.short}' + jython.release = '${jython.release}' + jython.version = '${jython.version}' + snapshot.name = '${snapshot.name}' + snapshot.suffix = '${snapshot.suffix}' jython.dev.jar = '${jython.dev.jar}' jython.deploy.jar = '${jython.deploy.jar}' jython.standalone.jar = '${jython.standalone.jar}' @@ -382,7 +396,7 @@ - + @@ -453,7 +467,7 @@ - + @@ -471,21 +485,41 @@ jython.build.hg_version=${build.hg.version} - - - - - ======================= - -------------------------- + + + + + + + + + + + + + + -This is a snapshot build. -It reflects the current development status. + + +------------------------------------------------------------------------- +This is a snapshot build. It reflects the current development status. +The text for the next official release will continue: +------------------------------------------------------------------------- -The readme text for the next release will be like: - - + + + + + + + + + + + + + @@ -533,7 +567,7 @@ --> - + - + @@ -801,13 +835,6 @@ - - copy CPython license from ${jython.base.dir}/lib-python - - - copy misc files from ${jython.base.dir} @@ -817,7 +844,6 @@ - @@ -825,7 +851,7 @@ copy sources from ${jython.base.dir} @@ -909,7 +935,10 @@ - + + @@ -938,8 +967,9 @@ + compiling installer from ${installer.src.dir} + copy installer classes to ${dist.dir} @@ -960,6 +991,7 @@ + copy installer icon to ${dist.dir} @@ -969,6 +1001,7 @@ + building installer .jar file -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Sun Aug 25 04:33:35 2019 From: jython-checkins at python.org (jeff.allen) Date: Sun, 25 Aug 2019 08:33:35 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Remove_actual_clone_operat?= =?utf-8?q?ion_from_build=2Exml_and_refactor=2E?= Message-ID: <20190825083335.1.6DE3DA20AD185FB4@mg.python.org> https://hg.python.org/jython/rev/517cd4d0c1c3 changeset: 8280:517cd4d0c1c3 user: Jeff Allen date: Sat Aug 24 18:05:42 2019 +0100 summary: Remove actual clone operation from build.xml and refactor. This removal simplifies the structure of the build (no work.dir). The consequent risk of releasing from a polluted baseline is mitgated by the target force-snapshot-if-polluted. It is now easier to build an installer intended as a snapshot release. Parts of build.xml have been heavily restructured in order to sequence the logic behind this idea, probably improving them. Resource type filelist/file replaces fileset/path for specifying JARs. Some rough edges remain but it's already a lot for one change set. files: README.txt | 23 +- build.xml | 741 +++++++++++++++++++++++----------------- 2 files changed, 430 insertions(+), 334 deletions(-) diff --git a/README.txt b/README.txt --- a/README.txt +++ b/README.txt @@ -2,27 +2,26 @@ Welcome to Jython @jython.version at . @snapshot.banner@ - This is @readme.release@ release of the @jython.version.short@ version of Jython. Along with language and runtime compatibility with CPython 2.7, Jython 2.7 -provides substantial support of the Python ecosystem. This includes -built-in support of pip/setuptools (you can use with bin/pip) and a -native launcher for Windows (bin/jython.exe). +provides substantial support of the Python ecosystem. This includes built-in +support of pip/setuptools (you can use with bin/pip) and a native launcher +for Windows (bin/jython.exe). -Jim Baker presented a talk at PyCon 2015 about Jython 2.7, including -demos of new features: https://www.youtube.com/watch?v=hLm3garVQFo +Jim Baker presented a talk at PyCon 2015 about Jython 2.7, including demos +of new features: https://www.youtube.com/watch?v=hLm3garVQFo This release was compiled on @os.name@ using @java.vendor@ Java version @java.version@ and requires a minimum of Java @jdk.target.version@ to run. -You can test your installation of Jython (not the standalone jar) by running the -regression tests, with the command: +You can test your installation of Jython (not the standalone jar) by +running the regression tests, with the command: jython -m test.regrtest -e -The regression tests can take about forty minutes. At the time of writing, these -tests are known to fail: +The regression tests can take about forty minutes. At the time of writing, +these tests are known to fail: test___all__ test_java_visibility test_jy_internals @@ -35,5 +34,5 @@ including bugs fixed, backwards breaking changes, and new features. The developers extend their thanks to all who contributed to this release -of Jython, through bug reports, patches, pull requests, documentation changes, -email and conversation in any media. +of Jython, through bug reports, patches, pull requests, documentation +changes, email and conversation in any media. diff --git a/build.xml b/build.xml --- a/build.xml +++ b/build.xml @@ -1,36 +1,50 @@ - + - + + -Use case 1: developer build (in your local Jython copy) -------------------------------------------------------- +Case 1: developer build +----------------------- Use the command: ant developer-build -Or just: +or just: ant -This build will create directories /build and /dist below basedir. +as it is the default target. This build will create directories +/build and /dist below ${basedir}. +Jython will identify its version with a trailing "+". -Use case 2: build an installer for the current version +Case 2: build an installer for the development version ------------------------------------------------------ -Choose a name for the snapshot (here SNAPSHOT). Use the command: - ant -Dsnapshot.name=SNAPSHOT installer +Use the command: + ant installer +An installer built this way does not include javadoc or source +JARs unless you build them first. It will be versioned as a +snapshot, e.g. ${jython.release}-SNAPSHOT. You can choose another name +for the snapshot, via a property: + ant -Dsnapshot.name=MYTEST installer -Use case 3: full build for a release (using hg checkout) ---------------------------------------------------------- - - make sure you have access to the Jython mercurial repository - (http://hg.python.org/jython) - - override ant.properties to define necessary properties - - Use the command: - ant full-build' +Case 3: full build for a release (use clean, tagged checkout) +------------------------------------------------------------- +You do not have to have access to the Jython mercurial +repository, but you do need to be at the root of a checked-out +(i.e. newly cloned) source tree. The release aretefacts will be +marked as a snapshot (not an official release) if any of the +following apply: +- there is no .hg directory (this is not a repo), +- the source tree contains any extraneous files, +- files have been edited and not committed, +- the current state is not tagged with correct release, +- you supply the snapshot.name property. -This will create a working directory named full_build at the same -level as your working directory. It will contain a big JAR called -jython_installer-${jython.version}.jar. +This will create a big jython-installer-${jython.release}.jar, +in the artefacts directory. -This will build the release artefacts as if the current version -development state wer a viable release. If you want a real version -from history, check out the corresponding tag. These instructions may -be different for that tag. +See also https://jython-devguide.rtfd.io/en/latest/release_jy.html Note on targets --------------- @@ -39,48 +53,40 @@ attribute. Use ant -p to display these targets. All other targets may behave unpredictably if called directly. - Where ant looks for ant.properties ---------------------------------- 1. in user.home 2. in the same directory as this build.xml file The first setting of a property wins. Further settings are ignored. -Actions for a release ---------------------- -See http://wiki.python.org/jython/JythonDeveloperGuide/HowToReleaseJython - - An example ant.properties file: ------------------------------- # - zxJDBC -oracle.jar=C:/workspace/HEAD/for_development/bisdevsrv28/jboss/server/infra/lib/ojdbc14.jar -#informix.jar=${basedir}/../externals/external-jars/ifxjdbc.jar +oracle.jar = ../support/ojdbc6.jar +informix.jar = ../support/jdbc-4.10.12.jar # - option for javac (build.compiler=modern is a global option to use standard jdk 1.7/1.8) #build.compiler=modern #jdk.target.version=1.7 #debug=false #deprecation=off - - + + - - - - - - + depends="full-preinit, full-check, init, all-jars, jar-installer" + description="build releasable artefacts. (Use a fresh checkout for a real release)" /> @@ -101,8 +107,6 @@ - - @@ -136,37 +140,9 @@ value="${jython.version.short}${jython.release.str}${jython.release.num}" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -175,59 +151,25 @@ - + + + - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - + @@ -244,56 +186,157 @@ - - - - - - + - - - - - - + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + description="dump the properties computed for a regular build without running it" /> . @@ -305,164 +348,174 @@ jython.version = '${jython.version}' snapshot.name = '${snapshot.name}' snapshot.suffix = '${snapshot.suffix}' - jython.dev.jar = '${jython.dev.jar}' - jython.deploy.jar = '${jython.deploy.jar}' - jython.standalone.jar = '${jython.standalone.jar}' - jython.javadoc.jar = '${jython.javadoc.jar}' - jython.sources.jar = '${jython.sources.jar}' + jython.dev.jar = '${jython.dev.jar}' + jython.deploy.jar = '${jython.deploy.jar}' + jython.standalone.jar = '${jython.standalone.jar}' + jython.javadoc.jar = '${jython.javadoc.jar}' + jython.sources.jar = '${jython.sources.jar}' + jar.update = '${jar.update}' --- optional libraries --- - oracle location = '${oracle.jar}' - informix location = '${informix.jar}' - oracle = '${oracle.present}' - informix = '${informix.present}' + informix = '${informix.jar}' + informix.present = '${informix.present}' + oracle = '${oracle.jar}' + oracle.present = '${oracle.present}' --- properties --- - work.dir = '${work.dir}' - jython.base.dir = '${jython.base.dir}' - source.dir = '${source.dir}' - output.dir = '${output.dir}' - compile.dir = '${compile.dir}' - exposed.dir = '${exposed.dir}' - gensrc.dir = '${gensrc.dir}' - dist.dir = '${dist.dir}' - apidoc.dir = '${apidoc.dir}' - templates.dir = '${templates.dir}' - templates.lazy = '${templates.lazy}' - python.lib = '${python.lib}' - build.compiler = '${build.compiler}' - jdk.target.version = '${jdk.target.version}' - jdk.source.version = '${jdk.source.version}' - deprecation = '${deprecation}' - debug = '${debug}' - nowarn = '${nowarn}' - test = '${test}' - test.source.dir = '${test.source.dir}' - --- properties only used for a full-build --- - checkout.dir = '${checkout.dir}' - javahl.dir = '${javahl.dir}' - do.snapshot.build = '${do.snapshot.build}' - snapshot.revision = '${snapshot.revision}' - do.checkout = '${do.checkout}' + jython.base.dir = '${jython.base.dir}' + source.dir = '${source.dir}' + output.dir = '${output.dir}' + compile.dir = '${compile.dir}' + exposed.dir = '${exposed.dir}' + gensrc.dir = '${gensrc.dir}' + dist.dir = '${dist.dir}' + apidoc.dir = '${apidoc.dir}' + templates.dir = '${templates.dir}' + templates.lazy = '${templates.lazy}' + python.lib = '${python.lib}' + --- compiler options --- + build.compiler = '${build.compiler}' + jdk.target.version = '${jdk.target.version}' + jdk.source.version = '${jdk.source.version}' + deprecation = '${deprecation}' + debug = '${debug}' + nowarn = '${nowarn}' + main.classpath = '${ant.refid:main.classpath}' + --- test config --- + test = '${test}' + test.source.dir = '${test.source.dir}' + - - - - - - + + --- properties only used for a full-build --- + hg.present = '${hg.present}' + build.hg.is_unmodified = '${build.hg.is_unmodified}' + build.hg.is_clean = '${build.hg.is_clean}' + build.hg.is_tagged = '${build.hg.is_tagged}' + build.hg.branch = '${build.hg.branch}' + build.hg.tag = '${build.hg.tag}' + build.hg.version = '${build.hg.version}' + + + + - - - - - - - - - + + + + - - + - - - - - - - - - + + + + - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - + + - - + + + + + + + - - - - - - + + + + + + + - - - + + + + + + + - - - - + + + + + + + + + + + + + + build.hg.branch = ${build.hg.branch} + build.hg.version = ${build.hg.version} + build.hg.tag = ${build.hg.tag} + build.hg.status = ${build.hg.status} - - - - - - - - - - - + + + + + + + + +Version-controlled files have been edited since the last commit - build is a snapshot. + +${build.hg.status} + - + + +Workspace contains uncontrolled files - build is a snapshot. - - - - +${build.hg.status} + - - - - - - - - - - + + +Change set ${build.hg.version} is not tagged v${jython.release} - build is a snapshot. + - + @@ -501,13 +554,16 @@ + ------------------------------------------------------------------------- This is a snapshot build. It reflects the current development status. -The text for the next official release will continue: -------------------------------------------------------------------------- +The text for the next official release will continue ... +------------------------------------------------------------------------- + + @@ -523,7 +579,7 @@ - + - + - - + + + + + + + + + + + + + + - + - + @@ -567,7 +638,7 @@ --> - + - - + + @@ -618,7 +689,7 @@ - + @@ -649,14 +720,17 @@ + - - + + @@ -728,6 +802,9 @@ + + +
@@ -741,18 +818,20 @@ - - - + + + + +
- + @@ -760,20 +839,25 @@
+
- + - + - + @@ -785,10 +869,13 @@ + + +
- + @@ -805,6 +892,7 @@ + - - + + + + - + + + + @@ -841,17 +936,15 @@ - - copy sources from ${jython.base.dir} @@ -893,6 +986,11 @@ + + + @@ -916,13 +1014,15 @@ excludes="test/**,lib2to3/tests/**,lib2to3/tests/data/myfixes/**"/> - + + + @@ -947,30 +1047,26 @@ - + + - + - - - - + + - - - - compiling installer from ${installer.src.dir} building installer .jar file - + + @@ -1028,7 +1125,7 @@
- + -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Sun Aug 25 04:33:36 2019 From: jython-checkins at python.org (jeff.allen) Date: Sun, 25 Aug 2019 08:33:36 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Move_test_reports_out_of_d?= =?utf-8?q?ist_to_the_top_level?= Message-ID: <20190825083336.1.3825F4FB7B461C49@mg.python.org> https://hg.python.org/jython/rev/f2a079664406 changeset: 8281:f2a079664406 user: Jeff Allen date: Sun Aug 25 08:10:01 2019 +0100 summary: Move test reports out of dist to the top level It seems to belong here rather than where we build the distribution. Other tidying up of names, now we don't need a variable base dir, and some formatting improvements. files: .hgignore | 3 +- build.xml | 166 ++++++++++++++++++++++++----------------- 2 files changed, 98 insertions(+), 71 deletions(-) diff --git a/.hgignore b/.hgignore --- a/.hgignore +++ b/.hgignore @@ -28,13 +28,14 @@ .DS_Store .settings __pycache__ -ant.properties bin +ant.properties build build2 cachedir dist +reports profile.txt out diff --git a/build.xml b/build.xml --- a/build.xml +++ b/build.xml @@ -141,32 +141,35 @@ - - - - - + + - - - + + + + + - - - - - + + + + - - + + + + + + + + - - - - - + + + + @@ -360,9 +363,9 @@ oracle = '${oracle.jar}' oracle.present = '${oracle.present}' --- properties --- - jython.base.dir = '${jython.base.dir}' + basedir = '${basedir}' source.dir = '${source.dir}' - output.dir = '${output.dir}' + build.dir = '${build.dir}' compile.dir = '${compile.dir}' exposed.dir = '${exposed.dir}' gensrc.dir = '${gensrc.dir}' @@ -382,6 +385,7 @@ --- test config --- test = '${test}' test.source.dir = '${test.source.dir}' + reports.dir = '${reports.dir}' @@ -398,21 +402,21 @@ - - - + + - - - + + @@ -477,10 +481,12 @@ + + @@ -540,7 +546,7 @@ - + @@ -586,7 +592,8 @@ source="${jdk.source.version}" debug="${debug}" deprecation="${deprecation}" - nowarn="${nowarn}"> + nowarn="${nowarn}" + includeantruntime="false"> @@ -602,7 +609,7 @@ - + @@ -612,7 +619,7 @@ @@ -623,8 +630,8 @@ - - + + @@ -645,6 +652,7 @@ debug="${debug}" deprecation="${deprecation}" nowarn="${nowarn}" + includeantruntime="true" memoryMaximumSize="1024m" fork="true" encoding="UTF-8"> @@ -656,14 +664,15 @@ - + nowarn="${nowarn}" + includeantruntime="false"> @@ -675,6 +684,7 @@ debug="${debug}" deprecation="${deprecation}" nowarn="${nowarn}" + includeantruntime="false" encoding="UTF-8"> @@ -723,7 +733,7 @@ + includesfile="${basedir}/CoreExposed.includes"/> @@ -921,7 +931,7 @@ - + @@ -931,9 +941,9 @@ - copy misc files from ${jython.base.dir} + copy misc files from ${basedir} - + @@ -947,9 +957,9 @@ depends="copy-bin, copy-lib, brand-readme, copy-misc-files" if="full-build"> - copy sources from ${jython.base.dir} + copy sources from ${basedir} - + @@ -971,9 +981,9 @@ - copy the demo files from ${jython.base.dir}/Demo + copy the demo files from ${basedir}/Demo - + @@ -991,7 +1001,7 @@ Loke lecences and the README. --> - + @@ -1016,7 +1026,7 @@ - + @@ -1032,17 +1042,17 @@ - + - - + - + @@ -1052,10 +1062,10 @@ $dist.dir/javalib/*, to be available when using jython-dev.jar --> - + - + @@ -1076,7 +1086,7 @@ debug="${debug}" deprecation="${deprecation}" nowarn="${nowarn}" - /> + includeantruntime="false" /> copy installer classes to ${dist.dir} @@ -1136,10 +1146,10 @@ - - @@ -1152,12 +1162,21 @@ - - - + + + + + + + + + + + - @@ -1190,7 +1209,7 @@ - + @@ -1258,10 +1277,11 @@ - + @@ -1275,6 +1295,7 @@ + @@ -1287,10 +1308,11 @@ + @@ -1301,11 +1323,12 @@ - + + @@ -1315,15 +1338,16 @@ - + + @@ -1343,6 +1367,7 @@ + @@ -1360,13 +1385,14 @@ - - - + + + - + -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Mon Aug 26 15:52:50 2019 From: jython-checkins at python.org (jeff.allen) Date: Mon, 26 Aug 2019 19:52:50 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Further_tweaks_to_=22snaps?= =?utf-8?q?hot=22_and_properties_logic_in_build=2Exml?= Message-ID: <20190826195250.1.1AE5A7057B68684C@mg.python.org> https://hg.python.org/jython/rev/684117a13ee3 changeset: 8283:684117a13ee3 user: Jeff Allen date: Mon Aug 26 15:05:21 2019 +0100 summary: Further tweaks to "snapshot" and properties logic in build.xml Logic leading to the "snapshot" version of the readme is fixed. Placeholders are gone from the manifests of JARs (#2613 fix verified). We avoid repeated calls to hg and the building of a JAR when we can, and sometimes when we can't (but a clean build sorts it out). files: NEWS | 1 + build.xml | 192 ++++++++++++++++++++++++----------------- 2 files changed, 115 insertions(+), 78 deletions(-) diff --git a/NEWS b/NEWS --- a/NEWS +++ b/NEWS @@ -5,6 +5,7 @@ Development tip Bugs fixed + - [ 2613 ] MANIFEST.MF contains unfilled placeholders - [ 2330 ] full-build fails to copy CPython License - [ 2651 ] Travis builds failing with *** buffer overflow detected *** - [ 2703 ] JycompileAntTask cannot find ...ant.taskdefs.MatchingTask diff --git a/build.xml b/build.xml --- a/build.xml +++ b/build.xml @@ -74,18 +74,16 @@ - - @@ -316,17 +314,16 @@ - + + - - - + test.classpath = '${ant.refid:test.classpath}' --> - + --- properties only used for a full-build --- hg.present = '${hg.present}' build.hg.is_unmodified = '${build.hg.is_unmodified}' @@ -425,23 +423,57 @@ + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + +${message} + +${build.hg.status} + + - - - + + + + + + @@ -449,7 +481,13 @@ + + + + + + @@ -457,7 +495,13 @@ + + + + + + @@ -467,64 +511,53 @@ - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - -Version-controlled files have been edited since the last commit - build is a snapshot. - -${build.hg.status} - - - - - -Workspace contains uncontrolled files - build is a snapshot. - -${build.hg.status} - - - - - -Change set ${build.hg.version} is not tagged v${jython.release} - build is a snapshot. - - - - - - - - @@ -549,6 +582,7 @@ + @@ -560,18 +594,18 @@ - - + + ------------------------------------------------------------------------- This is a snapshot build. It reflects the current development status. -The text for the next official release will continue ... +The text for an official release would continue like ... ------------------------------------------------------------------------- - - - + + + @@ -645,6 +679,8 @@ --> + + - @@ -850,7 +885,7 @@
@@ -953,9 +988,7 @@
- + copy sources from ${basedir} @@ -1075,7 +1108,7 @@ + depends="jar-standalone, copy-full" > compiling installer from ${installer.src.dir} + + +
-- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Mon Aug 26 15:52:50 2019 From: jython-checkins at python.org (jeff.allen) Date: Mon, 26 Aug 2019 19:52:50 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Provide_dummy_hg_metadata_?= =?utf-8?q?when_no_hg_or_no_repo=2E?= Message-ID: <20190826195250.1.793AAA04ED249E6F@mg.python.org> https://hg.python.org/jython/rev/af1c9f681386 changeset: 8284:af1c9f681386 user: Jeff Allen date: Mon Aug 26 18:34:11 2019 +0100 summary: Provide dummy hg metadata when no hg or no repo. Quite likely corrects a regression. build.xml tolerates (again) the possibility it cannot execute hg, or .hg is missing. The Jython you build signs on as "Jython 2.7.2a1+ (uncontrolled:+, ... )" files: build.xml | 59 +++++++++++++++++++++++++++++++++--------- 1 files changed, 46 insertions(+), 13 deletions(-) diff --git a/build.xml b/build.xml --- a/build.xml +++ b/build.xml @@ -387,7 +387,7 @@ + depends="hg-is-unmodified, hg-is-clean, hg-is-tagged, hg-branch, dump" > --- properties only used for a full-build --- hg.present = '${hg.present}' build.hg.is_unmodified = '${build.hg.is_unmodified}' @@ -470,10 +470,7 @@ - - - - + @@ -519,8 +516,27 @@ + + + + + + + + - + + + + + + + + + @@ -533,25 +549,42 @@ - + - - - - + + + + + + + + + + + + + + Writing hg and build metadata to version.properties. jython.version = ${jython.version} build.hg.branch = ${build.hg.branch} -- Repository URL: https://hg.python.org/jython From jython-checkins at python.org Mon Aug 26 15:52:50 2019 From: jython-checkins at python.org (jeff.allen) Date: Mon, 26 Aug 2019 19:52:50 +0000 Subject: [Jython-checkins] =?utf-8?q?jython=3A_Correct_the_Java_version_i?= =?utf-8?q?n_the_skip_at_test=5Fload=5Fcert=5Fchain?= Message-ID: <20190826195250.1.41C1DAE61F9F655D@mg.python.org> https://hg.python.org/jython/rev/c9c627efc911 changeset: 8282:c9c627efc911 user: Jeff Allen date: Sun Aug 25 16:57:36 2019 +0100 summary: Correct the Java version in the skip at test_load_cert_chain files: Lib/test/test_ssl.py | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -900,7 +900,7 @@ with self.assertRaises(TypeError): ctx.verify_flags = None - @unittest.skipIf(support.is_jython and support.get_java_version() < (8,), + @unittest.skipIf(support.is_jython and support.get_java_version() < (1,8), "Fails on Java 7. See bjo #2770") def test_load_cert_chain(self): ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) -- Repository URL: https://hg.python.org/jython