[Jython-checkins] jython (merge default -> default): Merge Gradle build script addition to trunk.
jeff.allen
jython-checkins at python.org
Wed Jul 11 14:53:19 EDT 2018
https://hg.python.org/jython/rev/ebd8868b8323
changeset: 8171:ebd8868b8323
parent: 8169:e546ad3d85bd
parent: 8170:921c66481876
user: Jeff Allen <ja.py at farowl.co.uk>
date: Wed Jul 11 19:46:40 2018 +0100
summary:
Merge Gradle build script addition to trunk.
files:
.gitignore | 6 +
.hgignore | 6 +
build.gradle | 755 ++++++++++
gradle/wrapper/gradle-wrapper.jar | Bin
gradle/wrapper/gradle-wrapper.properties | 5 +
gradlew | 172 ++
gradlew.bat | 84 +
settings.gradle | 5 +
tests/java/org/python/core/BaseBytesTest.java | 12 +-
tests/java/org/python/core/PyBufferTest.java | 2 +-
tests/java/org/python/core/PyByteArrayTest.java | 27 +-
11 files changed, 1057 insertions(+), 17 deletions(-)
diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,9 @@
*.swp
\#*
*~
+
+.gradle
+
# IntelliJ files
*.eml
*.ipr
@@ -32,8 +35,11 @@
__pycache__
ant.properties
bin
+
build
+build2
cachedir
dist
target
+
profile.txt
diff --git a/.hgignore b/.hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -8,6 +8,9 @@
*.swp
\#*
*~
+
+.gradle
+
# IntelliJ files
*.eml
*.ipr
@@ -27,8 +30,11 @@
__pycache__
ant.properties
bin
+
build
+build2
cachedir
dist
+
profile.txt
out
diff --git a/build.gradle b/build.gradle
new file mode 100644
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,755 @@
+/*
+ * Gradle build for Jython. See also settings.gradle.
+ *
+ * This is an attempt to build a distributable JAR using Gradle that could be
+ * cited as a dependency by other Gradle or Maven projects, when they use the
+ * Jython interpreter from Java (under JSR-223 or directly).
+ *
+ * At present, the build is additional to the Ant build that remains the
+ * primary and reliable support for development, for test, and to build the
+ * Jython installers.
+ *
+ * The delivered jar should contain only Jython project material (Java classes
+ * and the Python library) while the many JARs Jython depends on will be cited
+ * in the accompanying metadata as dependencies.
+ *
+ * The Jython source structure does not follow the standard convention for
+ * Gradle. This script deals with that without changing it, but it uses a build
+ * directory (build2) entirely separate from Ant's, in which generated and
+ * compiled material is posted conformant with Gradle conventions. This means
+ * that the later tasks Gradle provides (test and jar) do not need so much
+ * customisation.
+ */
+
+plugins {
+ id 'java-library'
+ id 'antlr'
+ // XXX Add maven and use it.
+}
+
+import java.text.SimpleDateFormat
+
+// ---------------- Determine the version of Jython ----------------------------
+
+/*
+ * This one string will be used to name the generated JAR and version-stamp the
+ * application. It should be all you have to edit to version a release built
+ * here. But of course you have to do it the hard way too (see build.xml) as
+ * long as Ant is also used.
+ */
+// <major> . <minor> ( . <micro> )? ( <release> <serial> )? ([-+] <word>? )?
+
+version = '2.7.2a1+'
+
+// Valid examples (please preserve in comments):
+//version = '2.7.2a2'
+//version = '2.7.2b1'
+//version = '2.7.2rc1'
+//version = '2.7.2'
+
+
+// ---------------- Miscellaneous configuration --------------------------------
+
+
+// Separate the Gradle build from that of Ant
+buildDir = file('build2')
+ext {
+ buildDate = new Date()
+ // Java source generated by ANTLR
+ antlrGenDir = "$buildDir/gensrc/org/python/antlr"
+ // This is where we assemble the standard library pre-JAR
+ buildLibDir = "$buildDir/resources/main/Lib/"
+ compiledLibDir = "$buildDir/classes/main/Lib/"
+}
+
+
+repositories {
+ /*
+ * Jython is distributed through Maven Central. Get our dependencies there
+ * too.
+ */
+ mavenCentral()
+}
+
+sourceSets {
+
+ main { // Non-standard locations must be specified explicitly
+
+ antlr {
+ srcDirs = ['grammar']
+ exclude 'Base.g' // Not used (and produces errors)
+ }
+
+ java {
+ srcDirs = ['src', project.ext.antlrGenDir]
+ exclude 'com/**' // for now
+ }
+
+ // output.resourcesDir = project.ext.assemblyDir
+
+ resources {
+ // Resources in project root, but this invites an explosion:
+ // srcDirs = ['']
+ // ... so claim no sources:
+ srcDirs = []
+ // and fix it in task processResources
+ }
+ }
+
+ test { // Non-standard locations must be specified explicitly
+
+ java {
+ srcDirs = ['tests/java']
+ exclude 'com/**' // XXX for now
+ }
+ }
+}
+
+dependencies {
+ /*
+ * These must correspond fairly exactly with the external libraries (JARs)
+ * mentioned in the Ant build.xml.
+ */
+
+ // Using a version available from repo (not 'extlibs/servlet-api-2.5' as in build.xml)
+ implementation group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
+
+ // implementation 'mysql-connector-java-5.1.42-bin'
+ // implementation 'postgresql-42.1.1.jre7'
+
+ // pin to Antlr 3.1.3 until we upgrade parsing
+ antlr 'org.antlr:antlr:3.1.3' // use ANTLR version 3
+ implementation 'org.antlr:antlr-runtime:3.1.3'
+ implementation 'org.antlr:stringtemplate:3.2.1'
+
+ implementation group: 'org.apache.commons', name: 'commons-compress', version: '1.14'
+
+ // pin to ASM 5.2 until we upgrade compilation
+ implementation group: 'org.ow2.asm', name: 'asm', version: '5.2'
+ implementation group: 'org.ow2.asm', name: 'asm-commons', version: '5.2'
+ implementation group: 'org.ow2.asm', name: 'asm-util', version: '5.2'
+
+ implementation group: 'com.google.guava', name: 'guava', version: '22.0-android'
+ implementation group: 'com.ibm.icu', name: 'icu4j', version: '59.1'
+
+ implementation group: 'com.carrotsearch', name: 'java-sizeof', version: '0.0.5'
+
+ implementation group: 'com.github.jnr', name: 'jffi', version: '1.2.16'
+ implementation group: 'com.github.jnr', name: 'jnr-netdb', version: '1.1.6'
+ implementation group: 'com.github.jnr', name: 'jnr-ffi', version: '2.1.7'
+ implementation group: 'com.github.jnr', name: 'jnr-posix', version: '3.0.44'
+ implementation group: 'com.github.jnr', name: 'jnr-constants', version: '0.9.9'
+
+ implementation group: 'jline', name: 'jline', version: '2.14.5'
+
+ implementation group: 'io.netty', name: 'netty-buffer', version: '4.1.24.Final'
+ implementation group: 'io.netty', name: 'netty-codec', version: '4.1.24.Final'
+ implementation group: 'io.netty', name: 'netty-common', version: '4.1.24.Final'
+ implementation group: 'io.netty', name: 'netty-handler', version: '4.1.24.Final'
+ implementation group: 'io.netty', name: 'netty-resolver', version: '4.1.24.Final'
+ implementation group: 'io.netty', name: 'netty-transport', version: '4.1.24.Final'
+
+ // Used implicitly in the Ant build, must be explicit here
+ implementation group: 'org.apache.ant', name: 'ant', version: '1.9.7'
+
+ testImplementation group: 'junit', name: 'junit', version: '4.10'
+
+}
+
+// ---------------- Resource Processing ----------------------------------------
+
+/*
+ * Jython brings several files we could treat as resources, but they do not sit
+ * in the Gradle-conventional 'main/resources' directory, rather are in the
+ * project root or rub shoulders with the java source. Pick them individually.
+ */
+processResources {
+ from(file('.')) {
+ include 'LICENSE.txt'
+ }
+ from(file('src')) {
+ include 'META-INF/**'
+ include 'org/python/modules/ucnhash.dat'
+ }
+}
+
+// ---------------- ANTLR Task -------------------------------------------------
+
+generateGrammarSource {
+ maxHeapSize = "512m"
+ outputDirectory = file(project.ext.antlrGenDir)
+}
+
+// ---------------- Expose Task ------------------------------------------------
+
+/*
+ * The exposer operates between two (somewhat fixed) directories. We follow
+ * the Gradle-conventional directory structure (not the legacy one).
+ */
+ext {
+ compileDir = "$buildDir/classes/java/main/"
+ exposedDir = "$buildDir/classes/exposed/main/"
+}
+
+configurations {
+ expose.extendsFrom(implementation)
+}
+
+dependencies {
+ // Put our compiled classes on the path of the expose (Ant) task
+ expose files("$buildDir/classes/java/main")
+}
+
+// A (Gradle) task to run the Ant task 'expose'.
+task expose (group: 'Custom', dependsOn: compileJava) {
+
+ description = 'Expose Java types to Python using their annotations.'
+
+ // Allow Gradle to infer the need to regenreate the outputs
+ inputs.files(fileTree("${project.ext.compileDir}/org/python"))
+ outputs.dir(project.ext.exposedDir)
+
+ doLast {
+ /*
+ * Define an Ant task called 'expose' in the project's AntBuilder.
+ * We can't define it until ExposeTask has been compiled.
+ */
+ ant.taskdef(
+ name: 'expose',
+ classname: 'org.python.expose.generate.ExposeTask',
+ classpath: configurations.expose.asPath
+ )
+
+ // Use the Gradle-conventional directory structure (not the legacy one).
+ ant.expose(
+ srcdir: file(project.ext.compileDir),
+ destdir: mkdir(file(project.ext.exposedDir)),
+ includesfile: file('CoreExposed.includes')
+ )
+ }
+}
+
+// ---------------- Version-related file generation ----------------------------
+
+/*
+ * Write the information that org.python.Version reads from
+ * org/python/version.properties in the class file structure. The inputs to
+ * this are: information from Mercurial (hg command required); project.version;
+ * and project.ext.buildDate. The task works quite hard to decode
+ * project.version, which must have the correct form, to deduce whether you
+ * really intend this to be a release. If anything comes after the release
+ * number, typically it's a '+' sign, the version becomes a snapshot.
+ */
+task generateVersionInfo(
+ type: WriteProperties,
+ description: 'Write the version information as properties') {
+
+ outputFile = file("${processResources.destinationDir}/org/python/version.properties")
+ comment = ' Jython version information (from build.gradle)'
+
+ // Create the properties when the task runs. But do it before the write!
+ doFirst {
+ /*
+ * Query Mercurial for version and tagging.
+ */
+ String hgOutput = 'hg identify -ibt'.execute().text
+ hgOutput = hgOutput.split('\n', 2)[0]
+
+ // <revision-id>(+)? <branch> <tag>
+ String[] parts = hgOutput.split(/\s+/, 3)
+ if (parts.length != 3) {
+ throw new IllegalArgumentException(
+ "Cannot split Mercurial output '$hgOutput' into 3")
+ }
+ def (ident, branch, tag) = parts
+ property('jython.build.hg_branch', branch)
+ property('jython.build.hg_tag', tag)
+ property('jython.build.hg_version', ident)
+
+ /*
+ * Decompose the version string into elements for Jython to access as
+ * properties. (The Ant build.xml requires them to be set in parts, but
+ * we can work it out from the .)
+ */
+ // <major>.<minor>(.<micro>)(<release><serial>)?([-+]<snapshot>)?
+ def versionRegex = /(\d+)\.(\d+)(\.(\d+))?((a|b|rc)(\d+))?([-+]\w*)?/
+ def versionMatcher = project.version =~ versionRegex
+ if (versionMatcher.count != 1) {
+ throw new IllegalArgumentException(
+ "Cannot parse project version string '${project.version}'")
+ }
+ // In principle it could match more than once: take the leftmost
+ def versionResult = versionMatcher[0]
+
+
+ // Useful debug
+ /*
+ for (int i=0; i < versionResult.size(); i++) {
+ String part = versionResult[i]
+ println "versionResult[$i] = $part"
+ } */
+
+ // <major>.<minor> means <major>.<minor>.0
+ String major = versionResult[1]
+ String minor = versionResult[2]
+ String micro = versionResult[3] ? versionResult[4] : '0'
+
+ // Convert the optional <release><serial> to numbers
+ int SNAPSHOT = 0xaa
+ int level = 0, serial = 0
+ if (versionResult[5]) {
+ // This is some kind of pre-final release (unless snapshaot)
+ serial = versionResult[7] as int
+ switch (versionResult[6]) {
+ case 'a': level = 0xa; break // ALPHA release
+ case 'b': level = 0xb; break // BETA release
+ case 'rc': level = 0xc; break // release candidate
+ }
+ } else {
+ // Not marked as a/b/rc so ostensibly a final release.
+ level = 0xf
+ }
+
+ // Except, if there was something after the version we decoded ...
+ if (versionResult[8]) {
+ level = SNAPSHOT // it's snapshot or dev version of some kind
+ serial = 0
+ }
+
+ property('jython.version', project.version)
+ property('jython.major_version', major)
+ property('jython.minor_version', minor)
+ property('jython.micro_version', micro)
+ property('jython.release_level', level)
+ property('jython.release_serial', serial)
+
+ /*
+ * Time-stamp the build. In the time part, the ':' gets escaped to
+ * '\:', consistent with Properties.store(), unlike the Ant build.
+ */
+ property('jython.build.time',
+ (new SimpleDateFormat('HH:mm:ss'))
+ .format(project.ext.buildDate))
+ property('jython.build.date',
+ (new SimpleDateFormat('MMM d yyyy'))
+ .format(project.ext.buildDate))
+
+ /*
+ * Remind the developer about tagging it if it looks like a release,
+ * or to adjust project.version if we're moving on from the release.
+ */
+ if (level != SNAPSHOT) {
+ def L = [0:'', 10:'a', 11:'b', 12:'rc', 15:'']
+ String release = "$major.$minor.$micro${L[level]}${serial?:''}"
+ println "This build is versioned for distribution as $release"
+ if (tag == 'tip' || ident.endsWith('+')) {
+ println "If this really is distributable, " +
+ "don't forget to tag it in the repository.\n" +
+ "Alternatively, add a suffix to version = " +
+ "'${project.version}' in build.gradle to shut this up."
+ }
+ }
+ }
+}
+
+// Attach this task to processResources
+processResources.dependsOn(generateVersionInfo)
+
+
+// ---------------- Copy Python Library ----------------------------------------
+
+/*
+ * The default behaviour of the Java plug-in is to make a JAR of the classes in
+ * the "main" source set. We need a more complex assembly that provides users
+ * with exposed classes instead of their plain counterparts, and also various
+ * configuration files and the Python library.
+ *
+ * These copies include the tests, so we can test things :), but a subsequent
+ * JarTask of the build should exclude them as necessary.
+ */
+
+ext {
+ libPython = 'lib-python/2.7'
+ libJython = 'Lib'
+}
+
+
+/*
+ * Copy the Python standard library. We take this from a distribution of
+ * CPython, but take only the files specified in CPythonLib.includes in the
+ * project root.
+ */
+task copyLib(
+ type: Copy,
+ description: 'Merge lib-python and Jython Lib during assembly') {
+
+ into "${project.ext.buildLibDir}"
+
+ // Copy Jython Lib, with precedence over CPython files of the same name
+ from file(project.ext.libJython)
+ exclude 'test/'
+ exclude '**/*.class'
+ duplicatesStrategy = DuplicatesStrategy.INCLUDE
+
+ // Allow Gradle to infer the need to regenerate the outputs
+ inputs.dir project.ext.libJython
+ inputs.dir project.ext.libPython
+ inputs.file file('CPythonLib.includes')
+ outputs.dir project.ext.buildLibDir
+
+ doFirst {
+ // Select the CPython stdlib files by making a list.
+ def cPythonLibIncludes = []
+ // Read list from CPythonLib.includes, stripping comments and spaces.
+ file('CPythonLib.includes').eachLine { line ->
+ def trimmed = line.split('#', 2)[0].trim()
+ if (trimmed.length() > 0) {
+ cPythonLibIncludes << trimmed
+ }
+ }
+ // Copy the subset as specified by the list
+ project.copy {
+ from file(project.ext.libPython)
+ include cPythonLibIncludes
+ exclude '**/*.pyc', '**/*.pyd'
+ into project.ext.buildLibDir
+ duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+ }
+ }
+
+ /*
+ <target name="copy-cpythonlib">
+ <copy todir="${dist.dir}/Lib">
+ <fileset dir="${python.lib}" excludes="** /*.pyc, ** /*.pyo"
+ includesfile="${jython.base.dir}/CPythonLib.includes">
+ <!-- The include file gets all of lib-python/2.7's test directory, but we only want the ones from Jython's Lib. -->
+ <present present="srconly" targetdir="${jython.base.dir}/Lib"/>
+ </fileset>
+ </copy>
+ </target>
+ */
+}
+
+
+
+
+// ---------------- Jython-Compile Python --------------------------------------
+
+/*
+ * Compile the Python modules to .class files for the JAR. Whereas Jython runs
+ * happily with a concrete Lib folder, creating and caching the .class files,
+ * when Jython is supplied as a JAR, we prefer to compile the class files once
+ * in advance.
+ */
+
+configurations {
+ pycompile.extendsFrom(implementation)
+}
+
+dependencies {
+ // Jython as built so far should be on the path of the jycompile (Ant) task
+ pycompile files("$buildDir/classes/exposed/main")
+ pycompile files("$buildDir/classes/java/main")
+ pycompile files("$buildDir/resources/main")
+}
+
+// A (Gradle) task to run the Ant task 'jycompile' (not pycompile).
+task pycompile(
+ group: 'Custom',
+ description: 'Compile the Python modules to .class files for the JAR') {
+
+ dependsOn compileJava
+ dependsOn expose
+ dependsOn copyLib
+
+ // Allow Gradle to infer the need to regenerate the outputs
+ inputs.dir project.ext.buildLibDir
+ outputs.dir project.ext.compiledLibDir
+
+ doFirst {
+ /*
+ * Define an Ant task called 'jycompile' in the project's AntBuilder.
+ * We can't define it until JythoncAntTask has been compiled, so this
+ * must happen during the execution of the task (early).
+ */
+ ant.taskdef(
+ name: 'jycompile',
+ classname: 'org.python.util.JycompileAntTask',
+ classpath: configurations.pycompile.asPath
+ )
+ }
+
+ doLast {
+ /*
+ * Now use the 'jycompile' Ant task tocompile the Python source we
+ * supply to users. The exclusions are copied from build.xml, as also
+ * is this comment:
+ <!-- One might think that the exclusion of lib2to3/tests/** is
+ recursive, but one would be wrong ;) It's actually only
+ two levels, so for now the workaround is to also include
+ data/myfixes/**
+
+ This exclusion for lib2to3/tests/ in general is necessary
+ because data/infinite_recursion.py is not compileable by
+ Jython - it's too large and will exceed Java method
+ limits for the top level script; nor is
+ data/py3_test_grammar.py - it's Python 3. Meanwhile
+ refactor.get_all_fix_names depends on having *.py, not
+ exclusively $py.class, files available in
+ lib2to3/tests/data/myfixes/**. -->
+ */
+ def exclusions = ['test/**', 'lib2to3/tests/**',
+ 'lib2to3/tests/data/myfixes/**']
+ ant.jycompile(
+ srcdir: project.ext.buildLibDir,
+ destdir: project.ext.compiledLibDir,
+ excludes: exclusions.join(',') // Yes, it's that way round :o
+ )
+ }
+
+}
+
+
+// ---------------- Building the JAR -------------------------------------------
+
+/*
+ * The default behaviour of the Java plug-in is to make a JAR of the classes in
+ * the "main" source set. We need a more complex operation that provides users
+ * with exposed classes instead of their plain counterparts, and also various
+ * configuration files and the Python library.
+ *
+ * Much of the assembly has taken place already in selective copying to the
+ * build directory by tasks processResources and copyLib.
+ */
+
+task jar(type: Jar, overwrite: true) {
+
+ dependsOn pycompile
+
+ /*
+ * This is a custom replacement Jar task so that we may control the
+ * order of adding classes. Exposed versions of identically-named classes
+ * supersede (by arriving first) those directly from compilation.
+ */
+ exclude 'org/python/expose/generate/**' // The expose tool itself
+
+ // Add the exposed classes to the JAR first
+ from expose
+
+ // Add other compiled classes but without overwriting the exposed ones
+ duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+ from compileJava
+
+ // Add the resources
+ from processResources
+
+ // Add Python library
+ preserveFileTimestamps = true
+ from file(project.ext.buildLibDir).parent
+ from file(project.ext.compiledLibDir).parent
+
+ manifest {
+ // These attribute values are based on inspecting the ant build
+ attributes ([
+ 'Main-Class': 'org.python.util.jython',
+ 'Built-By': 'Mistake',
+ ])
+
+ attributes( [ // Build-Info section
+ 'version': project.version,
+ 'build-compiler': 'modern',
+ 'jdk-target-version': '1.7',
+ 'debug': true,
+ ], 'Build-Info' )
+ }
+
+}
+
+
+// ---------------- Java unit tests --------------------------------------------
+
+ext {
+ //distDir = relativePath("$buildDir/assembly")
+ testSourceDir = relativePath('tests/java')
+}
+
+
+dependencies {
+ // Put the exposed classes on the path of the test tasks
+ testImplementation files(expose)
+}
+
+// Ensure exposed classes are ahead of standard path
+sourceSets.test {
+ compileClasspath = files(expose.outputs) + compileClasspath
+ runtimeClasspath = files(expose.outputs) + runtimeClasspath
+ // println "runtimeClasspath = ${runtimeClasspath.asPath}"
+}
+
+compileTestJava {
+ dependsOn expose
+}
+
+test {
+
+ dependsOn copyLib
+
+ // Stop on first test failure
+ failFast = true
+
+ // Properties as defined in Ant target javatest-basepath
+ //systemProperty 'python.home', project.ext.distDir
+ // XXX Not sure of all that python.home is used for in tests.
+ systemProperty 'python.home', file(copyLib.destinationDir).parent
+ systemProperty 'python.test.source.dir', project.ext.testSourceDir
+ // Place cache outside the targets for jar task
+ systemProperty 'python.cachedir', "${project.buildDir}/cachedir"
+
+ // Include/exclude based on Ant target javatest-basepath
+ include '**/*Test*'
+ exclude '**/InterpTestCase'
+ exclude '**/jythonTest*' // Must run interactively
+ exclude 'org/python/antlr/**'
+ exclude 'org/python/tests/imp/**' // See build.xml:importest
+
+ // Some additional exclusions or else the task fails
+ // FIXME: leaves stdin/out/err as PyFileWriter that has no fileno()
+ // causing _ioTest to fail.
+ exclude '**/jsr223/*'
+ // FIXME: Tests that hard-code directory paths (use a symbol):
+ exclude 'org/python/compiler/custom_proxymaker/**'
+ exclude 'org/python/compiler/JavaMakerSmokeTest.class'
+ // FIXME: Failing test finds project root from test class location
+ exclude 'org/python/core/PySystemState_registry_Test.class'
+ // FIXME: Fails as sys._jy_console not set when run under Gradle
+ exclude 'org/python/util/InterpreterTest.class'
+ // FIXME: Failing test, see issue 2410
+ exclude 'org/python/core/PySystemStateTest.class'
+
+ doFirst {
+ println "systemProperties = $systemProperties"
+ }
+
+ /* From build.xml :
+
+ <target name="javatest-basepath" depends="developer-build">
+ <mkdir dir="${junit.reports}"/>
+ <junit fork="true" printsummary="true">
+ <formatter type="xml"/>
+ <sysproperty key="python.home" value="${dist.dir}"/>
+ <sysproperty key="python.test.source.dir" value="${test.source.dir}"/>
+ <classpath refid="test.classpath"/>
+ <batchtest todir="${junit.reports}" skipNonTests="true">
+ <fileset dir="${test.source.dir}" includes="** /*Test*.java">
+ <exclude name="** /InterpTestCase.java" />
+ <exclude name="** /jythonTest*" /> <!-- Must run interactively -->
+ <exclude name="org/python/antlr/**" />
+ <exclude name="org/python/tests/imp/**" /> <!-- See importest -->
+ <exclude name=".classpath" />
+ <exclude name=".project" />
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ <target name="importest" depends="developer-build" description="run all the JUnit tests that need tests/python in the path.">
+ <mkdir dir="${junit.reports}"/>
+ <junit fork="true" printsummary="true">
+ <formatter type="xml"/>
+ <sysproperty key="python.home" value="${dist.dir}"/>
+ <sysproperty key="python.test.source.dir" value="${test.source.dir}"/>
+ <classpath refid="test.classpath"/>
+ <classpath refid="test.classpath"/>
+ <classpath>
+ <pathelement location="${jython.base.dir}/tests/python"/>
+ </classpath>
+ <batchtest todir="${junit.reports}">
+ <fileset dir="${test.source.dir}" includes="org/python/tests/imp/*Test*.java">
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
+ */
+}
+
+// ---------------- Miscellaneous fettling of the prepare phase ----------------
+
+// Source is globally UTF-8 (well, nearly).
+tasks.withType(JavaCompile) {
+ options.encoding = "UTF-8"
+}
+
+
+
+// ---------------- Tasks for debugging ----------------------------------------
+
+
+task dumpCP {
+ doLast {
+ //println('configurations.testCompile:')
+ //configurations.testCompile.each { println it }
+ //println('configurations.testRuntime:')
+ //configurations.testRuntime.each { println it }
+ println('configurations.expose:')
+ configurations.expose.each { println it }
+ println('configurations.pycompile:')
+ configurations.pycompile.each { println it }
+ }
+}
+
+
+task dumpex {
+ doLast {
+ int n = project.ext.exposedDir.length()
+ Set<String> exposedClasses = new TreeSet()
+ //println "*** files in ${project.ext.exposedDir}:"
+ for (f in fileTree(project.ext.exposedDir)) {
+ //println project.relativePath(f).substring(n)
+ exposedClasses.add( project.relativePath(f).substring(n) )
+ }
+ //for (f in exposedClasses) { println f }
+
+ println "${fileTree(project.ext.compileDir).size()} compiled classes."
+
+ n = project.ext.compileDir.length()
+ int countx = 0
+ for (f in fileTree(project.ext.compileDir)) {
+ //println project.relativePath(f).substring(n)
+ String name = project.relativePath(f).substring(n)
+ if (name in exposedClasses) { countx += 1 }
+ }
+ println "${exposedClasses.size()} classes from ${countx} exposed."
+
+ def compiledToJar = fileTree(project.ext.compileDir).filter({
+ File f -> !(project.relativePath(f).substring(n) in exposedClasses)
+ })
+
+ println "${compiledToJar.size()} to be jarred (after filtering)."
+
+ int counti = 0
+ for (f in fileTree(project.ext.compileDir)) {
+ String name = project.relativePath(f).substring(n)
+ String exposed = (name in exposedClasses) ? "EXPOSED" : ""
+ // println "${name} ${exposed}"
+ if (exposed) { counti += 1 }
+ }
+
+ println "${counti} in overlap."
+ }
+}
+
+
+task dump {
+ doLast {
+ // Debug
+ println '*** source sets ***'
+ for ( sourceSet in sourceSets ) {
+ println " ${sourceSet}"
+ // for ( name in sourceSet.asMap.keys ) {
+ // sourceDirectorySet = sourceSet.asMap[name]
+ // println " $name = $sourceDirectorySet"
+ // }
+ }
+ }
+}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..91ca28c8b802289c3a438766657a5e98f20eff03
GIT binary patch
[stripped]
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,84 @@
+ at if "%DEBUG%" == "" @echo off
+ at rem ##########################################################################
+ at rem
+ at rem Gradle startup script for Windows
+ at rem
+ at rem ##########################################################################
+
+ at rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+ at rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+ at rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+ at rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+ at rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+ at rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+ at rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+ at rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,5 @@
+/*
+ * Gradle settings for Jython. See also build.gradle.
+ */
+
+rootProject.name = 'jython'
diff --git a/tests/java/org/python/core/BaseBytesTest.java b/tests/java/org/python/core/BaseBytesTest.java
--- a/tests/java/org/python/core/BaseBytesTest.java
+++ b/tests/java/org/python/core/BaseBytesTest.java
@@ -217,7 +217,7 @@
// Local constructor from byte[]
int[] aRef = toInts("Chaque coquillage incrusté");
BaseBytes a = getInstance(aRef);
- System.out.println(toString(a));
+ // System.out.println(toString(a));
assertEquals(aRef.length, a.size());
// init(int) at various sizes
@@ -237,7 +237,7 @@
BaseBytes a = getInstance(aRef);
// Copy constructor b = bytes(a)
BaseBytes b = getInstance(a);
- System.out.println(toString(b));
+ // System.out.println(toString(b));
assertEquals(a.size(), b.size());
// assertEquals(a.storage, b.storage); // Supposed to share?
// Check we got the same bytes
@@ -254,7 +254,7 @@
// Make an Iterable<? extends PyObject> of that
Iterable<? extends PyObject> ia = iterableBytes(aRef);
BaseBytes a = getInstance(ia);
- System.out.println(toString(a));
+ // System.out.println(toString(a));
assertEquals(aRef.length, a.size());
checkInts(aRef, a);
@@ -319,7 +319,7 @@
PyObject aRef = boobyPrize[dip];
try {
BaseBytes a = getInstance(brantub[dip]);
- System.out.println(toString(a));
+ // System.out.println(toString(a));
fail("Exception not thrown for " + brantub[dip]);
} catch (PyException pye) {
// System.out.println(pye);
@@ -452,7 +452,7 @@
try {
a.pyset(start, x);
- System.out.println(toString(a));
+ // System.out.println(toString(a));
fail(String.format("Exception not thrown for pyset(%d,%s)", start, x));
} catch (PyException pye) {
// System.out.println(pye);
@@ -476,7 +476,7 @@
try {
a.setslice(start, stop, step, x);
- System.out.println(toString(a));
+ // System.out.println(toString(a));
fail(String.format("Exception not thrown for setslice(%d,%d,%d,%s)", start, stop, step,
x));
} catch (PyException pye) {
diff --git a/tests/java/org/python/core/PyBufferTest.java b/tests/java/org/python/core/PyBufferTest.java
--- a/tests/java/org/python/core/PyBufferTest.java
+++ b/tests/java/org/python/core/PyBufferTest.java
@@ -60,7 +60,7 @@
protected int verbosity = 0;
/** Print a list of the test material. (From JUnit 4.12 use Parameters(name)). */
- protected static final boolean PRINT_KEY = true;
+ protected static final boolean PRINT_KEY = false;
/** Size of some large arrays. */
static final int LONG = 1000;
diff --git a/tests/java/org/python/core/PyByteArrayTest.java b/tests/java/org/python/core/PyByteArrayTest.java
--- a/tests/java/org/python/core/PyByteArrayTest.java
+++ b/tests/java/org/python/core/PyByteArrayTest.java
@@ -12,6 +12,9 @@
*/
public class PyByteArrayTest extends BaseBytesTest {
+ /** This program may be used to display operation time, but this is not necessary for tests. */
+ final static boolean SHOW_OPERATION_TIMES = false;
+
/**
* Constructor required by JUnit.
*
@@ -963,11 +966,13 @@
* slice to replace is simple and contiguous (2-argument slice).
*/
public void testSetsliceTime() {
- int verbose = 1;
- timeSetslice(50, 100, SMALL, 2 * SMALL, verbose);
- timeSetslice(50, 100, MEDIUM, MEDIUM, verbose);
- timeSetslice(500, 20, LARGE, LARGE / 5, verbose);
- // timeSetslice(1000, 4, HUGE, HUGE/5, verbose);
+ if (SHOW_OPERATION_TIMES) {
+ int verbose = 1;
+ timeSetslice(50, 100, SMALL, 2 * SMALL, verbose);
+ timeSetslice(50, 100, MEDIUM, MEDIUM, verbose);
+ timeSetslice(500, 20, LARGE, LARGE / 5, verbose);
+ timeSetslice(1000, 4, HUGE, HUGE/5, verbose);
+ }
}
/**
@@ -1388,11 +1393,13 @@
* slice to replace is extended (3-argument slice).
*/
public void testDelsliceTime3() {
- int verbose = 1;
- timeDelslice3(50, 100, SMALL, verbose);
- timeDelslice3(50, 100, MEDIUM, verbose);
- timeDelslice3(20, 4, LARGE, verbose);
- // timeDelslice3(10, 1, HUGE, verbose);
+ if (SHOW_OPERATION_TIMES) {
+ int verbose = 1;
+ timeDelslice3(50, 100, SMALL, verbose);
+ timeDelslice3(50, 100, MEDIUM, verbose);
+ timeDelslice3(20, 4, LARGE, verbose);
+ timeDelslice3(10, 1, HUGE, verbose);
+ }
}
/**
--
Repository URL: https://hg.python.org/jython
More information about the Jython-checkins
mailing list