You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(107) |
Dec
(67) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(76) |
Feb
(125) |
Mar
(72) |
Apr
(13) |
May
(18) |
Jun
(12) |
Jul
(129) |
Aug
(47) |
Sep
(1) |
Oct
(36) |
Nov
(128) |
Dec
(124) |
2002 |
Jan
(59) |
Feb
|
Mar
(14) |
Apr
(14) |
May
(72) |
Jun
(9) |
Jul
(3) |
Aug
(5) |
Sep
(18) |
Oct
(65) |
Nov
(28) |
Dec
(12) |
2003 |
Jan
(10) |
Feb
(2) |
Mar
(4) |
Apr
(33) |
May
(21) |
Jun
(9) |
Jul
(29) |
Aug
(34) |
Sep
(4) |
Oct
(8) |
Nov
(15) |
Dec
(4) |
2004 |
Jan
(26) |
Feb
(12) |
Mar
(11) |
Apr
(9) |
May
(7) |
Jun
|
Jul
(5) |
Aug
|
Sep
(3) |
Oct
(7) |
Nov
(1) |
Dec
(10) |
2005 |
Jan
(2) |
Feb
(72) |
Mar
(16) |
Apr
(39) |
May
(48) |
Jun
(97) |
Jul
(57) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(100) |
Dec
(24) |
2006 |
Jan
(15) |
Feb
(34) |
Mar
(33) |
Apr
(31) |
May
(79) |
Jun
(64) |
Jul
(41) |
Aug
(64) |
Sep
(31) |
Oct
(46) |
Nov
(55) |
Dec
(37) |
2007 |
Jan
(32) |
Feb
(61) |
Mar
(11) |
Apr
(58) |
May
(46) |
Jun
(30) |
Jul
(94) |
Aug
(93) |
Sep
(86) |
Oct
(69) |
Nov
(125) |
Dec
(177) |
2008 |
Jan
(169) |
Feb
(97) |
Mar
(74) |
Apr
(113) |
May
(120) |
Jun
(334) |
Jul
(215) |
Aug
(237) |
Sep
(72) |
Oct
(189) |
Nov
(126) |
Dec
(160) |
2009 |
Jan
(180) |
Feb
(45) |
Mar
(98) |
Apr
(140) |
May
(151) |
Jun
(71) |
Jul
(107) |
Aug
(119) |
Sep
(73) |
Oct
(121) |
Nov
(14) |
Dec
(6) |
2010 |
Jan
(13) |
Feb
(9) |
Mar
(10) |
Apr
(64) |
May
(3) |
Jun
(16) |
Jul
(7) |
Aug
(23) |
Sep
(17) |
Oct
(37) |
Nov
(5) |
Dec
(8) |
2011 |
Jan
(10) |
Feb
(11) |
Mar
(77) |
Apr
(11) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <pj...@us...> - 2009-03-29 23:21:16
|
Revision: 6117 http://jython.svn.sourceforge.net/jython/?rev=6117&view=rev Author: pjenvey Date: 2009-03-29 23:21:00 +0000 (Sun, 29 Mar 2009) Log Message: ----------- fix failing tests: always compile the compiled version, incase the bytecode magic changes Modified Paths: -------------- trunk/jython/Lib/test/classimport.jar trunk/jython/Lib/test/classimport_Lib.jar trunk/jython/Lib/test/test_classpathimporter.py Modified: trunk/jython/Lib/test/classimport.jar =================================================================== (Binary files differ) Modified: trunk/jython/Lib/test/classimport_Lib.jar =================================================================== (Binary files differ) Modified: trunk/jython/Lib/test/test_classpathimporter.py =================================================================== --- trunk/jython/Lib/test/test_classpathimporter.py 2009-03-29 22:13:47 UTC (rev 6116) +++ trunk/jython/Lib/test/test_classpathimporter.py 2009-03-29 23:21:00 UTC (rev 6117) @@ -1,9 +1,15 @@ +import os +import py_compile +import shutil +import sys +import tempfile import unittest -import sys +import zipfile from test import test_support from java.lang import Thread class ClasspathImporterTestCase(unittest.TestCase): + def setUp(self): self.orig_context = Thread.currentThread().contextClassLoader self.orig_path = sys.path @@ -11,32 +17,7 @@ def tearDown(self): Thread.currentThread().contextClassLoader = self.orig_context sys.path = self.orig_path - try: - del sys.modules['flat_in_jar'] - del sys.modules['jar_pkg'] - del sys.modules['jar_pkg.prefer_compiled'] - except KeyError: - pass - def setClassLoaderAndCheck(self, jar, prefix): - Thread.currentThread().contextClassLoader = test_support.make_jar_classloader(jar) - import flat_in_jar - self.assertEquals(flat_in_jar.value, 7) - import jar_pkg - self.assertEquals(prefix + '/jar_pkg/__init__$py.class', jar_pkg.__file__) - from jar_pkg import prefer_compiled - self.assertEquals(prefix + '/jar_pkg/prefer_compiled$py.class', prefer_compiled.__file__) - self.assert_(prefer_compiled.compiled) - self.assertRaises(NameError, __import__, 'flat_bad') - self.assertRaises(NameError, __import__, 'jar_pkg.bad') - - def test_default_pyclasspath(self): - self.setClassLoaderAndCheck("classimport.jar", "__pyclasspath__") - - def test_path_in_pyclasspath(self): - sys.path = ['__pyclasspath__/Lib'] - self.setClassLoaderAndCheck("classimport_Lib.jar", "__pyclasspath__/Lib") - # I don't like the checked in jar file bug1239.jar. The *one* thing I # liked about the tests in bugtests/ is that you could create a java file, # compile it, jar it and destroy the jar when done. Maybe when we move to @@ -54,8 +35,65 @@ sys.path.append("Lib/test/bug1126/bug1126.jar") import org.subpackage + +class PyclasspathImporterTestCase(unittest.TestCase): + + def setUp(self): + self.orig_context = Thread.currentThread().contextClassLoader + self.orig_path = sys.path + self.temp_dir = tempfile.mkdtemp() + self.modules = sys.modules.keys() + + def tearDown(self): + Thread.currentThread().contextClassLoader = self.orig_context + sys.path = self.orig_path + shutil.rmtree(self.temp_dir) + for module in sys.modules.keys(): + if module not in self.modules: + del sys.modules[module] + + def setClassLoaderAndCheck(self, orig_jar, prefix, compile_path=''): + # Create a new jar and compile prefer_compiled into it + orig_jar = test_support.findfile(orig_jar) + jar = os.path.join(self.temp_dir, os.path.basename(orig_jar)) + shutil.copy(orig_jar, jar) + + code = os.path.join(self.temp_dir, 'prefer_compiled.py') + fp = open(code, 'w') + fp.write('compiled = True') + fp.close() + py_compile.compile(code) + zip = zipfile.ZipFile(jar, 'a') + zip.write(os.path.join(self.temp_dir, 'prefer_compiled$py.class'), + os.path.join(compile_path, 'jar_pkg', + 'prefer_compiled$py.class')) + zip.close() + zip = zipfile.ZipFile(jar) + + Thread.currentThread().contextClassLoader = test_support.make_jar_classloader(jar) + import flat_in_jar + self.assertEquals(flat_in_jar.value, 7) + import jar_pkg + self.assertEquals(prefix + '/jar_pkg/__init__.py', jar_pkg.__file__) + from jar_pkg import prefer_compiled + self.assertEquals(prefix + '/jar_pkg/prefer_compiled$py.class', prefer_compiled.__file__) + self.assert_(prefer_compiled.compiled) + self.assertRaises(NameError, __import__, 'flat_bad') + self.assertRaises(NameError, __import__, 'jar_pkg.bad') + + def test_default_pyclasspath(self): + self.setClassLoaderAndCheck('classimport.jar', '__pyclasspath__') + + def test_path_in_pyclasspath(self): + sys.path = ['__pyclasspath__/Lib'] + self.setClassLoaderAndCheck('classimport_Lib.jar', + '__pyclasspath__/Lib', 'Lib') + + def test_main(): - test_support.run_unittest(ClasspathImporterTestCase) + test_support.run_unittest(ClasspathImporterTestCase, + PyclasspathImporterTestCase) + if __name__ == '__main__': test_main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-03-29 22:13:53
|
Revision: 6116 http://jython.svn.sourceforge.net/jython/?rev=6116&view=rev Author: thobes Date: 2009-03-29 22:13:47 +0000 (Sun, 29 Mar 2009) Log Message: ----------- Decoupled the compiler. Added a compiler facade and added a dispatcher that enables loading different kinds of code objects from .class-files. This enables having multiple compilers and different code implementations. Modified Paths: -------------- trunk/jython/src/org/python/compiler/Module.java trunk/jython/src/org/python/core/Py.java Added Paths: ----------- trunk/jython/src/org/python/compiler/LegacyCompiler.java trunk/jython/src/org/python/core/CodeBootstrap.java trunk/jython/src/org/python/core/CodeLoader.java trunk/jython/src/org/python/core/CompilerFacade.java trunk/jython/src/org/python/core/PyRunnableBootstrap.java trunk/jython/src/org/python/core/PythonCodeBundle.java trunk/jython/src/org/python/core/PythonCompiler.java Added: trunk/jython/src/org/python/compiler/LegacyCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/LegacyCompiler.java (rev 0) +++ trunk/jython/src/org/python/compiler/LegacyCompiler.java 2009-03-29 22:13:47 UTC (rev 6116) @@ -0,0 +1,72 @@ +package org.python.compiler; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; + +import org.python.antlr.base.mod; +import org.python.core.BytecodeLoader; +import org.python.core.CompilerFlags; +import org.python.core.Py; +import org.python.core.PyCode; +import org.python.core.PythonCodeBundle; +import org.python.core.PythonCompiler; + +public class LegacyCompiler implements PythonCompiler { + + public PythonCodeBundle compile(mod node, String name, String filename, + boolean linenumbers, boolean printResults, CompilerFlags cflags) { + return new LazyLegacyBundle(node, name, filename, linenumbers, + printResults, cflags); + } + + private static class LazyLegacyBundle implements PythonCodeBundle { + + private final mod node; + private final String name; + private final String filename; + private final boolean linenumbers; + private final boolean printResults; + private final CompilerFlags cflags; + private ByteArrayOutputStream ostream = null; + + public LazyLegacyBundle(mod node, String name, String filename, + boolean linenumbers, boolean printResults, CompilerFlags cflags) { + this.node = node; + this.name = name; + this.filename = filename; + this.linenumbers = linenumbers; + this.printResults = printResults; + this.cflags = cflags; + } + + public PyCode loadCode() throws Exception { + return BytecodeLoader.makeCode(name, ostream().toByteArray(), + filename); + } + + public void writeTo(OutputStream stream) throws Exception { + if (this.ostream != null) { + stream.write(ostream.toByteArray()); + } else { + Module.compile(node, stream, name, filename, linenumbers, + printResults, cflags); + } + } + + public void saveCode(String directory) throws Exception { + // FIXME: this is slightly broken, it should use the directory + Py.saveClassFile(name, ostream()); + } + + private ByteArrayOutputStream ostream() throws Exception { + if (ostream == null) { + ostream = new ByteArrayOutputStream(); + Module.compile(node, ostream, name, filename, linenumbers, + printResults, cflags); + } + return ostream; + } + + } + +} Modified: trunk/jython/src/org/python/compiler/Module.java =================================================================== --- trunk/jython/src/org/python/compiler/Module.java 2009-03-29 22:11:34 UTC (rev 6115) +++ trunk/jython/src/org/python/compiler/Module.java 2009-03-29 22:13:47 UTC (rev 6116) @@ -12,10 +12,14 @@ import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; +import org.python.core.CodeBootstrap; import org.python.core.CodeFlag; +import org.python.core.CodeLoader; import org.python.core.CompilerFlags; import org.python.core.Py; import org.python.core.PyException; +import org.python.core.PyRunnableBootstrap; +import org.objectweb.asm.Type; import org.python.antlr.ParseException; import org.python.antlr.PythonTree; import org.python.antlr.ast.Suite; @@ -547,10 +551,26 @@ c.dup(); c.ldc(classfile.name); c.invokespecial(classfile.name, "<init>", "(" + $str + ")V"); + c.invokevirtual(classfile.name, "getMain", "()" + $pyCode); + String bootstrap = Type.getDescriptor(CodeBootstrap.class); + c.invokestatic(Type.getInternalName(CodeLoader.class), + CodeLoader.SIMPLE_FACTORY_METHOD_NAME, + "(" + $pyCode + ")" + bootstrap); c.aload(0); - c.invokestatic("org/python/core/Py", "runMain", "(" + $pyRunnable + $strArr + ")V"); + c.invokestatic("org/python/core/Py", "runMain", "(" + bootstrap + $strArr + ")V"); c.return_(); } + + public void addBootstrap() throws IOException { + Code c = classfile.addMethod(CodeLoader.GET_BOOTSTRAP_METHOD_NAME, + "()" + Type.getDescriptor(CodeBootstrap.class), + ACC_PUBLIC | ACC_STATIC); + c.ldc(Type.getType("L" + classfile.name + ";")); + c.invokestatic(Type.getInternalName(PyRunnableBootstrap.class), + PyRunnableBootstrap.REFLECTION_METHOD_NAME, + "(" + $clss + ")" + Type.getDescriptor(CodeBootstrap.class)); + c.areturn(); + } public void addConstants(Code c) throws IOException { classfile.addField("self", "L"+classfile.name+";", @@ -605,6 +625,7 @@ addInit(); addRunnable(); addMain(); + addBootstrap(); addFunctions(); Added: trunk/jython/src/org/python/core/CodeBootstrap.java =================================================================== --- trunk/jython/src/org/python/core/CodeBootstrap.java (rev 0) +++ trunk/jython/src/org/python/core/CodeBootstrap.java 2009-03-29 22:13:47 UTC (rev 6116) @@ -0,0 +1,7 @@ +package org.python.core; + +public interface CodeBootstrap { + + PyCode loadCode(CodeLoader loader); + +} Added: trunk/jython/src/org/python/core/CodeLoader.java =================================================================== --- trunk/jython/src/org/python/core/CodeLoader.java (rev 0) +++ trunk/jython/src/org/python/core/CodeLoader.java 2009-03-29 22:13:47 UTC (rev 6116) @@ -0,0 +1,60 @@ +package org.python.core; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +public final class CodeLoader { + + public static final String GET_BOOTSTRAP_METHOD_NAME = "getCodeBootstrap"; + public final String name; + public final String filename; + + private CodeLoader(String name, String filename) { + this.name = name; + this.filename = filename; + } + + public static boolean canLoad(Class<?> cls) { + try { + Method getBootstrap = cls.getMethod(GET_BOOTSTRAP_METHOD_NAME); + return Modifier.isStatic(getBootstrap.getModifiers()); + } catch (Exception e) { + return false; + } + } + + public static PyCode loadCode(Class<?> cls, String name, String filename) + throws SecurityException, NoSuchMethodException, + IllegalArgumentException, IllegalAccessException, + InvocationTargetException { + Method getBootstrap = cls.getMethod(GET_BOOTSTRAP_METHOD_NAME); + CodeBootstrap bootstrap = (CodeBootstrap) getBootstrap.invoke(null); + return loadCode(bootstrap, name, filename); + } + + public static PyCode loadCode(Class<?> cls) throws SecurityException, + IllegalArgumentException, NoSuchMethodException, + IllegalAccessException, InvocationTargetException { + return loadCode(cls, null, null); + } + + public static PyCode loadCode(CodeBootstrap bootstrap, String name, + String filename) { + return bootstrap.loadCode(new CodeLoader(name, filename)); + } + + public static PyCode loadCode(CodeBootstrap bootstrap) { + return loadCode(bootstrap, null, null); + } + + public static final String SIMPLE_FACTORY_METHOD_NAME = "createSimpleBootstrap"; + + public static CodeBootstrap createSimpleBootstrap(final PyCode code) { + return new CodeBootstrap() { + public PyCode loadCode(CodeLoader loader) { + return code; + } + }; + } +} Added: trunk/jython/src/org/python/core/CompilerFacade.java =================================================================== --- trunk/jython/src/org/python/core/CompilerFacade.java (rev 0) +++ trunk/jython/src/org/python/core/CompilerFacade.java 2009-03-29 22:13:47 UTC (rev 6116) @@ -0,0 +1,39 @@ +package org.python.core; + +import org.python.antlr.base.mod; +import org.python.compiler.LegacyCompiler; + +/** + * Facade for different compiler implementations. + * + * The static methods of this class act as a Facade for the compiler subsystem. + * This is so that the rest of Jython (even generated code) can statically link + * to the static interface of this class, while allowing for different + * implementations of the various components of the compiler subsystem. + * + * @author Tobias Ivarsson + */ +public class CompilerFacade { + + private static volatile PythonCompiler compiler = loadDefaultCompiler(); + + public static void setCompiler(PythonCompiler compiler) { + CompilerFacade.compiler = compiler; + } + + private static PythonCompiler loadDefaultCompiler() { + return new LegacyCompiler(); + } + + public static PyCode compile(mod node, String name, String filename, + boolean linenumbers, boolean printResults, CompilerFlags cflags) { + try { + PythonCodeBundle bundle = compiler.compile(node, name, filename, + linenumbers, printResults, cflags); + bundle.saveCode(Options.proxyDebugDirectory); + return bundle.loadCode(); + } catch (Throwable t) { + throw ParserFacade.fixParseError(null, t, filename); + } + } +} Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-03-29 22:11:34 UTC (rev 6115) +++ trunk/jython/src/org/python/core/Py.java 2009-03-29 22:13:47 UTC (rev 6116) @@ -862,9 +862,19 @@ * Called by the code generated in {@link Module#addMain()} */ public static void runMain(PyRunnable main, String[] args) throws Exception { + runMain(new PyRunnableBootstrap(main), args); + } + + /** + * Initializes a default PythonInterpreter and runs the code loaded from the + * {@link CodeBootstrap} as __main__ Called by the code generated in + * {@link Module#addMain()} + */ + public static void runMain(CodeBootstrap main, String[] args) + throws Exception { PySystemState.initialize(null, null, args, main.getClass().getClassLoader()); try { - imp.createFromCode("__main__", main.getMain()); + imp.createFromCode("__main__", CodeLoader.loadCode(main)); } catch (PyException e) { Py.getSystemState().callExitFunc(); if (Py.matchException(e, Py.SystemExit)) { @@ -1648,6 +1658,8 @@ public static PyCode compile_flags(mod node, String name, String filename, boolean linenumbers, boolean printResults, CompilerFlags cflags) { + return CompilerFacade.compile(node, name, filename, linenumbers, printResults, cflags); + /* try { ByteArrayOutputStream ostream = new ByteArrayOutputStream(); Module.compile(node, ostream, name, filename, linenumbers, printResults, cflags); @@ -1658,6 +1670,7 @@ } catch (Throwable t) { throw ParserFacade.fixParseError(null, t, filename); } + */ } public static PyCode compile_flags(mod node, String filename, Added: trunk/jython/src/org/python/core/PyRunnableBootstrap.java =================================================================== --- trunk/jython/src/org/python/core/PyRunnableBootstrap.java (rev 0) +++ trunk/jython/src/org/python/core/PyRunnableBootstrap.java 2009-03-29 22:13:47 UTC (rev 6116) @@ -0,0 +1,43 @@ +package org.python.core; + +import java.lang.reflect.Constructor; + +public class PyRunnableBootstrap implements CodeBootstrap { + + public static final String REFLECTION_METHOD_NAME = "getFilenameConstructorReflectionBootstrap"; + private final PyRunnable runnable; + + PyRunnableBootstrap(PyRunnable runnable) { + this.runnable = runnable; + } + + public PyCode loadCode(CodeLoader loader) { + return runnable.getMain(); + } + + public static CodeBootstrap getFilenameConstructorReflectionBootstrap( + Class<? extends PyRunnable> cls) { + final Constructor<? extends PyRunnable> constructor; + try { + constructor = cls.getConstructor(String.class); + } catch (Exception e) { + throw new IllegalArgumentException( + "PyRunnable class does not specify apropriate constructor.", + e); + } + return new CodeBootstrap() { + + public PyCode loadCode(CodeLoader loader) { + try { + return constructor.newInstance(loader.filename).getMain(); + } catch (Exception e) { + throw new IllegalArgumentException( + "PyRunnable class constructor does not support instantiation protocol.", + e); + } + } + + }; + } + +} Added: trunk/jython/src/org/python/core/PythonCodeBundle.java =================================================================== --- trunk/jython/src/org/python/core/PythonCodeBundle.java (rev 0) +++ trunk/jython/src/org/python/core/PythonCodeBundle.java 2009-03-29 22:13:47 UTC (rev 6116) @@ -0,0 +1,13 @@ +package org.python.core; + +import java.io.OutputStream; + +public interface PythonCodeBundle { + + PyCode loadCode() throws Exception; + + void writeTo(OutputStream stream) throws Exception; + + void saveCode(String directory) throws Exception; + +} Added: trunk/jython/src/org/python/core/PythonCompiler.java =================================================================== --- trunk/jython/src/org/python/core/PythonCompiler.java (rev 0) +++ trunk/jython/src/org/python/core/PythonCompiler.java 2009-03-29 22:13:47 UTC (rev 6116) @@ -0,0 +1,11 @@ +package org.python.core; + +import org.python.antlr.base.mod; + +public interface PythonCompiler { + + PythonCodeBundle compile(mod node, String name, String filename, + boolean linenumbers, boolean printResults, CompilerFlags cflags) + throws Exception; + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-03-29 22:11:45
|
Revision: 6115 http://jython.svn.sourceforge.net/jython/?rev=6115&view=rev Author: thobes Date: 2009-03-29 22:11:34 +0000 (Sun, 29 Mar 2009) Log Message: ----------- Patched the compiler paths for type stafety. The kind is now an enum (from builtin.compile and down) The compile methods now return PyCode (from builtin.compile and down) This simplifies the compiler paths, the check for if AST or code should be returned is now in only one place and the parser dispatch is simpler(less code) Modified Paths: -------------- trunk/jython/Lib/codeop.py trunk/jython/src/org/python/Version.java trunk/jython/src/org/python/antlr/BaseParser.java trunk/jython/src/org/python/antlr/ast/AstModule.java trunk/jython/src/org/python/compiler/Future.java trunk/jython/src/org/python/compiler/Module.java trunk/jython/src/org/python/compiler/pbc/Bytecode.java trunk/jython/src/org/python/core/CompilerFlags.java trunk/jython/src/org/python/core/ParserFacade.java trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/PyBaseCode.java trunk/jython/src/org/python/core/PyBytecode.java trunk/jython/src/org/python/core/PyFrame.java trunk/jython/src/org/python/core/PyTableCode.java trunk/jython/src/org/python/core/__builtin__.java trunk/jython/src/org/python/core/imp.java trunk/jython/src/org/python/util/InteractiveInterpreter.java trunk/jython/src/org/python/util/PythonInterpreter.java trunk/jython/src/org/python/util/jython.java trunk/jython/tests/java/org/python/antlr/PythonTreeTester.java Added Paths: ----------- trunk/jython/src/org/python/core/CodeFlag.java trunk/jython/src/org/python/core/CompileMode.java trunk/jython/src/org/python/core/FutureFeature.java trunk/jython/src/org/python/core/Pragma.java trunk/jython/src/org/python/core/PragmaReceiver.java Removed Paths: ------------- trunk/jython/src/org/python/antlr/ExpressionParser.java trunk/jython/src/org/python/antlr/InteractiveParser.java trunk/jython/src/org/python/antlr/ModuleParser.java Modified: trunk/jython/Lib/codeop.py =================================================================== --- trunk/jython/Lib/codeop.py 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/Lib/codeop.py 2009-03-29 22:11:34 UTC (rev 6115) @@ -57,8 +57,8 @@ """ # import internals, not guaranteed interface -from org.python.core import Py,CompilerFlags -from org.python.core.PyTableCode import PyCF_DONT_IMPLY_DEDENT +from org.python.core import Py,CompilerFlags,CompileMode +from org.python.core.CompilerFlags import PyCF_DONT_IMPLY_DEDENT # public interface @@ -84,6 +84,7 @@ """ if symbol not in ['single','eval']: raise ValueError,"symbol arg must be either single or eval" + symbol = CompileMode.getMode(symbol) return Py.compile_command_flags(source,filename,symbol,Py.getCompilerFlags(),0) class Compile: @@ -95,6 +96,7 @@ self._cflags = CompilerFlags() def __call__(self, source, filename, symbol): + symbol = CompileMode.getMode(symbol) return Py.compile_flags(source, filename, symbol, self._cflags) class CommandCompiler: @@ -128,5 +130,6 @@ """ if symbol not in ['single','eval']: raise ValueError,"symbol arg must be either single or eval" + symbol = CompileMode.getMode(symbol) return Py.compile_command_flags(source,filename,symbol,self._cflags,0) Modified: trunk/jython/src/org/python/Version.java =================================================================== --- trunk/jython/src/org/python/Version.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/Version.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -3,8 +3,14 @@ import java.io.InputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; import java.util.Properties; +import java.util.Set; +import org.python.core.CodeFlag; + /** * Jython version information. * @@ -36,6 +42,10 @@ /** Short version of branch, e.g. asm. */ public static String SHORT_BRANCH; + /** The flags that are set by default in a code object. */ + private static final Collection<CodeFlag> defaultCodeFlags = Arrays.asList( + CodeFlag.CO_NESTED, CodeFlag.CO_GENERATOR_ALLOWED); + private static final String headURL = "$HeadURL$"; @@ -144,4 +154,8 @@ public static String getVersion() { return String.format("%.80s (%.80s) %.80s", PY_VERSION, getBuildInfo(), getVM()); } + + public static Set<CodeFlag> getDefaultCodeFlags() { + return EnumSet.copyOf(defaultCodeFlags); + } } Modified: trunk/jython/src/org/python/antlr/BaseParser.java =================================================================== --- trunk/jython/src/org/python/antlr/BaseParser.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/BaseParser.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,15 +1,31 @@ package org.python.antlr; import org.antlr.runtime.CharStream; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; import org.antlr.runtime.Token; +import org.python.antlr.base.mod; public class BaseParser { - protected CharStream charStream; - protected boolean partial; - protected String filename; - protected String encoding; + protected final CharStream charStream; + @Deprecated + protected final boolean partial; + protected final String filename; + protected final String encoding; protected ErrorHandler errorHandler = new FailFastHandler(); + + public BaseParser(CharStream stream, String filename, String encoding) { + this(stream, filename, encoding, false); + } + + @Deprecated + public BaseParser(CharStream stream, String filename, String encoding, boolean partial) { + this.charStream = stream; + this.filename = filename; + this.encoding = encoding; + this.partial = partial; + } public void setAntlrErrorHandler(ErrorHandler eh) { this.errorHandler = eh; @@ -25,4 +41,60 @@ return super.nextToken(); } } + + private CharStream charStream(boolean single) { + return charStream; + } + + private PythonParser setupParser(boolean single) { + PythonLexer lexer = new PyLexer(this.charStream(single)); + lexer.setErrorHandler(errorHandler); + CommonTokenStream tokens = new CommonTokenStream(lexer); + PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename, single); + tokens = new CommonTokenStream(indentedSource); + PythonParser parser = new PythonParser(tokens, encoding); + parser.setErrorHandler(errorHandler); + parser.setTreeAdaptor(new PythonTreeAdaptor()); + return parser; + } + + public mod parseExpression() { + mod tree = null; + PythonParser parser = setupParser(false); + try { + PythonParser.eval_input_return r = parser.eval_input(); + tree = (mod)r.tree; + } catch (RecognitionException e) { + //XXX: this can't happen. Need to strip the throws from antlr + // generated code. + } + return tree; + } + + public mod parseInteractive() { + mod tree = null; + PythonParser parser = setupParser(true); + try { + PythonParser.single_input_return r = parser.single_input(); + tree = (mod)r.tree; + } catch (RecognitionException e) { + //I am only throwing ParseExceptions, but "throws RecognitionException" still gets + //into the generated code. + System.err.println("FIXME: pretty sure this can't happen -- but needs to be checked"); + } + return tree; + } + + public mod parseModule() { + mod tree = null; + PythonParser parser = setupParser(false); + try { + PythonParser.file_input_return r = parser.file_input(); + tree = (mod)r.tree; + } catch (RecognitionException e) { + //XXX: this can't happen. Need to strip the throws from antlr + // generated code. + } + return tree; + } } Deleted: trunk/jython/src/org/python/antlr/ExpressionParser.java =================================================================== --- trunk/jython/src/org/python/antlr/ExpressionParser.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/ExpressionParser.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,36 +0,0 @@ -package org.python.antlr; - -import org.antlr.runtime.CharStream; -import org.antlr.runtime.CommonTokenStream; -import org.antlr.runtime.RecognitionException; -import org.python.antlr.base.mod; - -public class ExpressionParser extends BaseParser { - - public ExpressionParser(CharStream cs, String filename, String encoding) { - this.charStream = cs; - this.filename = filename; - this.encoding = encoding; - } - - public mod parse() { - mod tree = null; - PythonLexer lexer = new PyLexer(this.charStream); - lexer.setErrorHandler(errorHandler); - CommonTokenStream tokens = new CommonTokenStream(lexer); - PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename); - tokens = new CommonTokenStream(indentedSource); - PythonParser parser = new PythonParser(tokens, encoding); - parser.setErrorHandler(errorHandler); - parser.setTreeAdaptor(new PythonTreeAdaptor()); - - try { - PythonParser.eval_input_return r = parser.eval_input(); - tree = (mod)r.tree; - } catch (RecognitionException e) { - //XXX: this can't happen. Need to strip the throws from antlr - // generated code. - } - return tree; - } -} Deleted: trunk/jython/src/org/python/antlr/InteractiveParser.java =================================================================== --- trunk/jython/src/org/python/antlr/InteractiveParser.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/InteractiveParser.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,41 +0,0 @@ -package org.python.antlr; - -import java.io.BufferedReader; -import java.io.IOException; - -import org.antlr.runtime.CommonTokenStream; -import org.antlr.runtime.RecognitionException; -import org.python.antlr.base.mod; - -public class InteractiveParser extends BaseParser { - - private BufferedReader bufreader; - - public InteractiveParser(BufferedReader br, String filename, String encoding) { - this.bufreader = br; - this.filename = filename; - this.encoding = encoding; - } - - public mod parse() throws IOException { - mod tree = null; - PythonLexer lexer = new PyLexer(new NoCloseReaderStream(bufreader)); - lexer.setErrorHandler(errorHandler); - CommonTokenStream tokens = new CommonTokenStream(lexer); - PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename, true); - tokens = new CommonTokenStream(indentedSource); - PythonParser parser = new PythonParser(tokens, encoding); - parser.setErrorHandler(errorHandler); - parser.setTreeAdaptor(new PythonTreeAdaptor()); - - try { - PythonParser.single_input_return r = parser.single_input(); - tree = (mod)r.tree; - } catch (RecognitionException e) { - //I am only throwing ParseExceptions, but "throws RecognitionException" still gets - //into the generated code. - System.err.println("FIXME: pretty sure this can't happen -- but needs to be checked"); - } - return tree; - } -} Deleted: trunk/jython/src/org/python/antlr/ModuleParser.java =================================================================== --- trunk/jython/src/org/python/antlr/ModuleParser.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/ModuleParser.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,39 +0,0 @@ -package org.python.antlr; - -import org.antlr.runtime.CharStream; -import org.antlr.runtime.CommonTokenStream; -import org.antlr.runtime.RecognitionException; -import org.python.antlr.base.mod; - -public class ModuleParser extends BaseParser { - public ModuleParser(CharStream cs, String filename, String encoding) { - this(cs, filename, encoding, false); - } - - public ModuleParser(CharStream cs, String filename, String encoding, boolean partial) { - this.charStream = cs; - this.filename = filename; - this.encoding = encoding; - this.partial = partial; - } - - public mod file_input() { - mod tree = null; - PythonLexer lexer = new PyLexer(this.charStream); - lexer.setErrorHandler(errorHandler); - CommonTokenStream tokens = new CommonTokenStream(lexer); - PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename); - tokens = new CommonTokenStream(indentedSource); - PythonParser parser = new PythonParser(tokens, encoding); - parser.setErrorHandler(errorHandler); - parser.setTreeAdaptor(new PythonTreeAdaptor()); - try { - PythonParser.file_input_return r = parser.file_input(); - tree = (mod)r.tree; - } catch (RecognitionException e) { - //XXX: this can't happen. Need to strip the throws from antlr - // generated code. - } - return tree; - } -} Modified: trunk/jython/src/org/python/antlr/ast/AstModule.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/AstModule.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/ast/AstModule.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -8,12 +8,12 @@ import org.python.antlr.op.*; import org.python.core.AstList; import org.python.core.ClassDictInit; +import org.python.core.CompilerFlags; import org.python.core.imp; import org.python.core.Py; import org.python.core.PyInteger; import org.python.core.PyObject; import org.python.core.PyString; -import org.python.core.PyTableCode; import org.python.core.PyType; import org.python.antlr.AST; @@ -27,7 +27,7 @@ dict.__setitem__("__doc__", Py.None); dict.__setitem__("__name__", new PyString("_ast")); dict.__setitem__("__version__", new PyString("62047")); - dict.__setitem__("PyCF_ONLY_AST", new PyInteger(PyTableCode.PyCF_ONLY_AST)); + dict.__setitem__("PyCF_ONLY_AST", new PyInteger(CompilerFlags.PyCF_ONLY_AST)); dict.__setitem__("astlist", AstList.TYPE); Modified: trunk/jython/src/org/python/compiler/Future.java =================================================================== --- trunk/jython/src/org/python/compiler/Future.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/compiler/Future.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -8,73 +8,65 @@ import org.python.antlr.ast.Interactive; import org.python.antlr.ast.Module; import org.python.antlr.ast.Str; +import org.python.antlr.ast.alias; import org.python.antlr.base.mod; import org.python.antlr.base.stmt; +import org.python.core.CodeFlag; +import org.python.core.FutureFeature; +import org.python.core.Pragma; +import org.python.core.PragmaReceiver; +import java.util.EnumSet; import java.util.List; +import java.util.Set; public class Future { + Set<FutureFeature> featureSet = EnumSet.noneOf(FutureFeature.class); + private final PragmaReceiver features = new PragmaReceiver() { - private boolean division = false; - private boolean with_statement = false; - private boolean absolute_import = false; + public void add(Pragma pragma) { + if (pragma instanceof FutureFeature) { + FutureFeature feature = (FutureFeature) pragma; + featureSet.add(feature); + } + } - private static final String FUTURE = "__future__"; + }; private boolean check(ImportFrom cand) throws Exception { - if (!cand.getInternalModule().equals(FUTURE)) + if (!cand.getInternalModule().equals(FutureFeature.MODULE_NAME)) return false; - int n = cand.getInternalNames().size(); - if (n == 0) { - throw new ParseException("future statement does not support import *", cand); + if (cand.getInternalNames().isEmpty()) { + throw new ParseException( + "future statement does not support import *", cand); } - for (int i = 0; i < n; i++) { - String feature = cand.getInternalNames().get(i).getInternalName(); - // *known* features - if (feature.equals("nested_scopes")) { - continue; + try { + for (alias feature : cand.getInternalNames()) { + // *known* features + FutureFeature.addFeature(feature.getInternalName(), features); } - if (feature.equals("division")) { - division = true; - continue; - } - if (feature.equals("generators")) { - continue; - } - if (feature.equals("with_statement")) { - with_statement = true; - continue; - } - if (feature.equals("absolute_import")) { - absolute_import = true; - continue; - } - if (feature.equals("braces")) { - throw new ParseException("not a chance", cand); - } - if (feature.equals("GIL") || feature.equals("global_interpreter_lock")) { - throw new ParseException("Never going to happen!", cand); - } - throw new ParseException("future feature " + feature + " is not defined", cand); + } catch (ParseException pe) { + throw new ParseException(pe.getMessage(), cand); } return true; } - public void preprocessFutures(mod node, - org.python.core.CompilerFlags cflags) - throws Exception - { + public void preprocessFutures(mod node, org.python.core.CompilerFlags cflags) + throws Exception { if (cflags != null) { - division = cflags.division; - with_statement = cflags.with_statement; - absolute_import = cflags.absolute_import; + if (cflags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) + FutureFeature.division.addTo(features); + if (cflags.isFlagSet(CodeFlag.CO_FUTURE_WITH_STATEMENT)) + FutureFeature.with_statement.addTo(features); + if (cflags.isFlagSet(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT)) + FutureFeature.absolute_import.addTo(features); } int beg = 0; List<stmt> suite = null; if (node instanceof Module) { suite = ((Module) node).getInternalBody(); - if (suite.size() > 0 && suite.get(0) instanceof Expr && - ((Expr) suite.get(0)).getInternalValue() instanceof Str) { + if (suite.size() > 0 && suite.get(0) instanceof Expr + && ((Expr) suite.get(0)).getInternalValue() instanceof Str) { beg++; } } else if (node instanceof Interactive) { @@ -85,45 +77,36 @@ for (int i = beg; i < suite.size(); i++) { stmt s = suite.get(i); - if (!(s instanceof ImportFrom)) - break; + if (!(s instanceof ImportFrom)) break; s.from_future_checked = true; - if (!check((ImportFrom)s)) - break; + if (!check((ImportFrom) s)) break; } if (cflags != null) { - cflags.division = cflags.division || division; + for (FutureFeature feature : featureSet) { + feature.setFlag(cflags); + } } - if (cflags != null) { - cflags.with_statement = cflags.with_statement || with_statement; - } - if (cflags != null) { - cflags.absolute_import = cflags.absolute_import || absolute_import; - } } - public static void checkFromFuture(ImportFrom node) throws Exception { - if (node.from_future_checked) - return; - if (node.getInternalModule().equals(FUTURE)) { - throw new ParseException("from __future__ imports must occur " + - "at the beginning of the file",node); + if (node.from_future_checked) return; + if (node.getInternalModule().equals(FutureFeature.MODULE_NAME)) { + throw new ParseException("from __future__ imports must occur " + + "at the beginning of the file", node); } node.from_future_checked = true; } public boolean areDivisionOn() { - return division; + return featureSet.contains(FutureFeature.division); } public boolean withStatementSupported() { - return with_statement; + return featureSet.contains(FutureFeature.with_statement); } public boolean isAbsoluteImportOn() { - return absolute_import; + return featureSet.contains(FutureFeature.absolute_import); } - } Modified: trunk/jython/src/org/python/compiler/Module.java =================================================================== --- trunk/jython/src/org/python/compiler/Module.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/compiler/Module.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -12,6 +12,7 @@ import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; +import org.python.core.CodeFlag; import org.python.core.CompilerFlags; import org.python.core.Py; import org.python.core.PyException; @@ -506,17 +507,17 @@ code.jy_npurecell = scope.jy_npurecell; if (compiler.optimizeGlobals) { - code.moreflags |= org.python.core.PyTableCode.CO_OPTIMIZED; + code.moreflags |= org.python.core.CodeFlag.CO_OPTIMIZED.flag; } if (compiler.my_scope.generator) { - code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR; + code.moreflags |= org.python.core.CodeFlag.CO_GENERATOR.flag; } if (cflags != null) { - if (cflags.generator_allowed) { - code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR_ALLOWED; + if (cflags.isFlagSet(CodeFlag.CO_GENERATOR_ALLOWED)) { + code.moreflags |= org.python.core.CodeFlag.CO_GENERATOR_ALLOWED.flag; } - if (cflags.division) { - code.moreflags |= org.python.core.PyTableCode.CO_FUTUREDIVISION; + if (cflags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) { + code.moreflags |= org.python.core.CodeFlag.CO_FUTURE_DIVISION.flag; } } Modified: trunk/jython/src/org/python/compiler/pbc/Bytecode.java =================================================================== --- trunk/jython/src/org/python/compiler/pbc/Bytecode.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/compiler/pbc/Bytecode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -14,6 +14,8 @@ import java.util.List; import java.util.Map; import java.util.Set; + +import org.python.core.CodeFlag; import org.python.core.Py; import org.python.core.Opcode; import org.python.core.PyBaseCode; @@ -25,7 +27,7 @@ private int co_argcount = 0; private int co_stacksize = 0; - private int co_flags = PyBaseCode.CO_OPTIMIZED | PyBaseCode.CO_NEWLOCALS; // typical usage + private int co_flags = CodeFlag.CO_OPTIMIZED.flag | CodeFlag.CO_NEWLOCALS.flag; // typical usage // co_filename = '<generated code>' // co_name = '<lambda>' // co_firstlineno = 0 @@ -135,7 +137,7 @@ public void YIELD_VALUE() { stackchange(1, 1); - co_flags |= PyBaseCode.CO_GENERATOR; + co_flags |= CodeFlag.CO_GENERATOR.flag; emit(Opcode.YIELD_VALUE); } Added: trunk/jython/src/org/python/core/CodeFlag.java =================================================================== --- trunk/jython/src/org/python/core/CodeFlag.java (rev 0) +++ trunk/jython/src/org/python/core/CodeFlag.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,106 @@ +package org.python.core; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; + +/** + * Represents flags that can be set on code objects. + * + * @author Tobias Ivarsson + */ +public enum CodeFlag { + /** + * Denotes that the code block uses fast locals. + */ + CO_OPTIMIZED(0x0001), + /** + * Denotes that a new dictionary should be created for the code block. + */ + CO_NEWLOCALS(0x0002), + /** + * The compiled code block has a varargs argument. + */ + CO_VARARGS(0x0004), + /** + * The compiled code block has a varkeyword argument. + */ + CO_VARKEYWORDS(0x0008), + /** + * The compiled code block is a generator code block. + */ + CO_GENERATOR(0x0020), + /** + * Denotes that nested scopes are enabled in the code block. + */ + CO_NESTED(0x0010), + /** + * Denotes that generators are enabled in the code block. + */ + CO_GENERATOR_ALLOWED(0x1000), + /** + * Standard division of integers returns float, truncating division needs to + * be enforced. + */ + CO_FUTURE_DIVISION(0x2000), + /** + * Absolute import. + */ + CO_FUTURE_ABSOLUTE_IMPORT(0x4000), + /** + * With statement. + */ + CO_FUTURE_WITH_STATEMENT(0x8000); + + public final int flag; + private static Iterable<CodeFlag> allFlags = Collections.unmodifiableList(Arrays.asList(values())); + + private CodeFlag(int flag) { + this.flag = flag; + } + + public boolean isFlagBitSetIn(int flags) { + return (flags & flag) != 0; + } + + static Iterable<CodeFlag> parse(final int flags) { + return new Iterable<CodeFlag>() { + + public Iterator<CodeFlag> iterator() { + return new Iterator<CodeFlag>() { + Iterator<CodeFlag> all = allFlags.iterator(); + CodeFlag next = null; + + public boolean hasNext() { + if (next != null) { + return true; + } + while (all.hasNext()) { + CodeFlag flag = all.next(); + if (flag.isFlagBitSetIn(flags)) { + next = flag; + return true; + } + } + return false; + } + + public CodeFlag next() { + if (hasNext()) try { + return next; + } finally { + next = null; + } + throw new IllegalStateException(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + }; + } + + }; + } +} Added: trunk/jython/src/org/python/core/CompileMode.java =================================================================== --- trunk/jython/src/org/python/core/CompileMode.java (rev 0) +++ trunk/jython/src/org/python/core/CompileMode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,33 @@ +package org.python.core; + +import org.python.antlr.BaseParser; +import org.python.antlr.base.mod; + +public enum CompileMode { + eval { + @Override + mod dispatch(BaseParser parser) { + return parser.parseExpression(); + } + }, + single { + @Override + mod dispatch(BaseParser parser) { + return parser.parseInteractive(); + } + }, + exec { + @Override + mod dispatch(BaseParser parser) { + return parser.parseModule(); + } + }; + abstract mod dispatch(BaseParser parser); + + public static CompileMode getMode(String mode) { + if (!mode.equals("exec") && !mode.equals("eval") && !mode.equals("single")) { + throw Py.ValueError("compile() arg 3 must be 'exec' or 'eval' or 'single'"); + } + return valueOf(mode); + } +} Modified: trunk/jython/src/org/python/core/CompilerFlags.java =================================================================== --- trunk/jython/src/org/python/core/CompilerFlags.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/CompilerFlags.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,79 +1,104 @@ -// At some future point this will also be extended - in conjunction with Py#compileFlags - to add -// support for a compiler factory that user code can choose in place of the normal compiler. +// At some future point this will also be extended - in conjunction with +// Py#compileFlags - to add +// support for a compiler factory that user code can choose in place of the +// normal compiler. // (Perhaps a better name might have been "CompilerOptions".) package org.python.core; -public class CompilerFlags { +import java.util.Set; - private int co_flags; +import org.python.Version; - public boolean optimized; - public boolean newlocals; - public boolean varargs; - public boolean varkeywords; - public boolean generator; - - public boolean nested_scopes = true; - public boolean division; - public boolean generator_allowed = true; - public boolean with_statement; - public boolean absolute_import; - +public class CompilerFlags { + // These flags don't mean anything to the code, only to the compiler + public static final int PyCF_SOURCE_IS_UTF8 = 0x0100; + public static final int PyCF_DONT_IMPLY_DEDENT = 0x0200; + public static final int PyCF_ONLY_AST = 0x0400; public boolean only_ast; public boolean dont_imply_dedent; public boolean source_is_utf8; public String encoding; + private final Set<CodeFlag> flags = Version.getDefaultCodeFlags(); - public CompilerFlags() {} + public CompilerFlags() { + } public CompilerFlags(int co_flags) { - this.co_flags = co_flags; - optimized = isEnabled(PyBaseCode.CO_OPTIMIZED); - newlocals = isEnabled(PyBaseCode.CO_NEWLOCALS); - varargs = isEnabled(PyBaseCode.CO_VARARGS); - varkeywords = isEnabled(PyBaseCode.CO_VARKEYWORDS); - generator = isEnabled(PyBaseCode.CO_GENERATOR); - nested_scopes = isEnabled(PyBaseCode.CO_NESTED); - division = isEnabled(PyBaseCode.CO_FUTUREDIVISION); - generator_allowed = isEnabled(PyBaseCode.CO_GENERATOR_ALLOWED); - absolute_import = isEnabled(PyBaseCode.CO_FUTURE_ABSOLUTE_IMPORT); - with_statement = isEnabled(PyBaseCode.CO_WITH_STATEMENT); - only_ast = isEnabled(PyBaseCode.PyCF_ONLY_AST); - dont_imply_dedent = isEnabled(PyBaseCode.PyCF_DONT_IMPLY_DEDENT); - source_is_utf8 = isEnabled(PyBaseCode.PyCF_SOURCE_IS_UTF8); + for (CodeFlag flag : CodeFlag.parse(co_flags)) { + setFlag(flag); + } + only_ast = isEnabled(co_flags, PyCF_ONLY_AST); + dont_imply_dedent = isEnabled(co_flags, PyCF_DONT_IMPLY_DEDENT); + source_is_utf8 = isEnabled(co_flags, PyCF_SOURCE_IS_UTF8); } - private boolean isEnabled(int codeConstant) { + private boolean isEnabled(int co_flags, int codeConstant) { return (co_flags & codeConstant) != 0; } + public int toBits() { + int bits = (only_ast ? PyCF_ONLY_AST : 0) + | (dont_imply_dedent ? PyCF_DONT_IMPLY_DEDENT : 0) + | (source_is_utf8 ? PyCF_SOURCE_IS_UTF8 : 0); + for (CodeFlag flag : flags) { + bits |= flag.flag; + } + return bits; + } + + public void setFlag(CodeFlag flag) { + flags.add(flag); + } + + public boolean isFlagSet(CodeFlag flag) { + return flags.contains(flag); + } + @Override public String toString() { - return String.format("CompilerFlags[division=%s nested_scopes=%s generators=%s " - + "with_statement=%s absolute_import=%s only_ast=%s " - + "dont_imply_dedent=%s source_is_utf8=%s]", division, nested_scopes, - generator_allowed, with_statement, absolute_import, only_ast, - dont_imply_dedent, source_is_utf8); + return String.format( + "CompilerFlags[division=%s nested_scopes=%s generators=%s " + + "with_statement=%s absolute_import=%s only_ast=%s " + + "dont_imply_dedent=%s source_is_utf8=%s]", + isFlagSet(CodeFlag.CO_FUTURE_DIVISION), + isFlagSet(CodeFlag.CO_NESTED), + isFlagSet(CodeFlag.CO_GENERATOR_ALLOWED), + isFlagSet(CodeFlag.CO_FUTURE_WITH_STATEMENT), + isFlagSet(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT), only_ast, + dont_imply_dedent, source_is_utf8); } - public int toBits() { - return (optimized ? PyBaseCode.CO_OPTIMIZED : 0) | - (newlocals ? PyBaseCode.CO_NEWLOCALS : 0) | - (varargs ? PyBaseCode.CO_VARARGS : 0) | - (varkeywords ? PyBaseCode.CO_VARKEYWORDS : 0) | - (generator ? PyBaseCode.CO_GENERATOR : 0) | - (nested_scopes ? PyBaseCode.CO_NESTED : 0) | - (division ? PyBaseCode.CO_FUTUREDIVISION : 0) | - (generator_allowed ? PyBaseCode.CO_GENERATOR_ALLOWED : 0) | - (absolute_import ? PyBaseCode.CO_FUTURE_ABSOLUTE_IMPORT : 0) | - (with_statement ? PyBaseCode.CO_WITH_STATEMENT : 0) | - (only_ast ? PyBaseCode.PyCF_ONLY_AST : 0) | - (dont_imply_dedent ? PyBaseCode.PyCF_DONT_IMPLY_DEDENT : 0) | - (source_is_utf8 ? PyBaseCode.PyCF_SOURCE_IS_UTF8 : 0); + public static CompilerFlags getCompilerFlags() { + return getCompilerFlags(0, null); } + private static final int CO_ALL_FEATURES = CompilerFlags.PyCF_DONT_IMPLY_DEDENT + | CompilerFlags.PyCF_ONLY_AST + | CompilerFlags.PyCF_SOURCE_IS_UTF8 + | CodeFlag.CO_NESTED.flag + | CodeFlag.CO_GENERATOR_ALLOWED.flag + | CodeFlag.CO_FUTURE_DIVISION.flag + | CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT.flag + | CodeFlag.CO_FUTURE_WITH_STATEMENT.flag; + + public static CompilerFlags getCompilerFlags(int flags, PyFrame frame) { + if ((flags & ~CO_ALL_FEATURES) != 0) { + throw Py.ValueError("compile(): unrecognised flags"); + } + return getCompilerFlags(new CompilerFlags(flags), frame); + } + + public static CompilerFlags getCompilerFlags(CompilerFlags flags, + PyFrame frame) { + if (frame != null && frame.f_code != null) { + return frame.f_code.co_flags.combine(flags); + } else { + return flags; + } + } + // this will not strictly be an OR once we have other options, like a compiler factory // in that case, we would assume public CompilerFlags combine(CompilerFlags flags) { Added: trunk/jython/src/org/python/core/FutureFeature.java =================================================================== --- trunk/jython/src/org/python/core/FutureFeature.java (rev 0) +++ trunk/jython/src/org/python/core/FutureFeature.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,101 @@ +package org.python.core; + +import org.python.antlr.ParseException; + +public enum FutureFeature implements Pragma { + /** + * Enables nested scopes. + */ + nested_scopes(CodeFlag.CO_NESTED), + /** + * Makes integer / integer division return float. + */ + division(CodeFlag.CO_FUTURE_DIVISION), + /** + * Enables generators. + */ + generators(CodeFlag.CO_GENERATOR_ALLOWED), + /** + * Enables absolute imports. + */ + absolute_import(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT), + /** + * Enables the with statement. + */ + with_statement(CodeFlag.CO_FUTURE_WITH_STATEMENT), + /** + * Use braces for block delimiters instead of indentation. + */ + braces { + @Override + public void addTo(PragmaReceiver features) { + throw new ParseException("not a chance"); + } + }, + /** + * Enable the Global Interpreter Lock in Jython. + */ + GIL { + @Override + public void addTo(PragmaReceiver features) { + throw new ParseException("Never going to happen!"); + } + }, + /** + * Enable the Global Interpreter Lock in Jython. + */ + global_interpreter_lock { + @Override + public void addTo(PragmaReceiver features) { + GIL.addTo(features); + } + }; + + public static final String MODULE_NAME = "__future__"; + public static final PragmaModule PRAGMA_MODULE = new PragmaModule( + MODULE_NAME) { + + @Override + public Pragma getPragma(String name) { + return getFeature(name); + } + + @Override + public Pragma getStarPragma() { + throw new ParseException("future feature * is not defined"); + } + }; + private final CodeFlag flag; + + private FutureFeature(CodeFlag flag) { + this.flag = flag; + } + + private FutureFeature() { + this(null); + } + + public void addTo(PragmaReceiver features) { + features.add(this); + } + + public static void addFeature(String featureName, PragmaReceiver features) { + getFeature(featureName).addTo(features); + } + + private static FutureFeature getFeature(String featureName) { + try { + return valueOf(featureName); + } catch (IllegalArgumentException ex) { + throw new ParseException("future feature " + featureName + + " is not defined"); + } + } + + public void setFlag(CompilerFlags cflags) { + if (flag != null) { + cflags.setFlag(flag); + } + } + +} Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/ParserFacade.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -23,10 +23,7 @@ import org.antlr.runtime.CommonTokenStream; import org.python.antlr.BaseParser; -import org.python.antlr.ExpressionParser; -import org.python.antlr.InteractiveParser; import org.python.antlr.ParseException; -import org.python.antlr.ModuleParser; import org.python.antlr.NoCloseReaderStream; import org.python.antlr.PythonTree; import org.python.antlr.PythonLexer; @@ -111,30 +108,23 @@ * PyIndentationErrors. */ private static mod parse(ExpectedEncodingBufferedReader reader, - String kind, + CompileMode kind, String filename, CompilerFlags cflags) throws Throwable { reader.mark(MARK_LIMIT); // We need the ability to move back on the // reader, for the benefit of fixParseError and // validPartialSentence - if (kind.equals("eval")) { + if (kind != null) { CharStream cs = new NoCloseReaderStream(reader); - ExpressionParser e = new ExpressionParser(cs, filename, cflags.encoding); - return e.parse(); - } else if (kind.equals("single")) { - InteractiveParser i = new InteractiveParser(reader, filename, cflags.encoding); - return i.parse(); - } else if (kind.equals("exec")) { - CharStream cs = new NoCloseReaderStream(reader); - ModuleParser g = new ModuleParser(cs, filename, cflags.encoding); - return g.file_input(); + BaseParser parser = new BaseParser(cs, filename, cflags.encoding); + return kind.dispatch(parser); } else { throw Py.ValueError("parse kind must be eval, exec, or single"); } } public static mod parse(InputStream stream, - String kind, + CompileMode kind, String filename, CompilerFlags cflags) { ExpectedEncodingBufferedReader bufReader = null; @@ -151,7 +141,7 @@ } public static mod parse(String string, - String kind, + CompileMode kind, String filename, CompilerFlags cflags) { ExpectedEncodingBufferedReader bufReader = null; @@ -166,7 +156,7 @@ } public static mod partialParse(String string, - String kind, + CompileMode kind, String filename, CompilerFlags cflags, boolean stdprompt) { @@ -186,7 +176,7 @@ } } - private static boolean validPartialSentence(BufferedReader bufreader, String kind, String filename) { + private static boolean validPartialSentence(BufferedReader bufreader, CompileMode kind, String filename) { PythonLexer lexer = null; try { bufreader.reset(); @@ -197,14 +187,16 @@ PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename); tokens = new CommonTokenStream(indentedSource); PythonPartial parser = new PythonPartial(tokens); - if (kind.equals("single")) { + switch (kind) { + case single: parser.single_input(); - } else if (kind.equals("eval")) { + break; + case eval: parser.eval_input(); - } else { + break; + default: return false; } - } catch (Exception e) { return lexer.eofWhileNested; } Added: trunk/jython/src/org/python/core/Pragma.java =================================================================== --- trunk/jython/src/org/python/core/Pragma.java (rev 0) +++ trunk/jython/src/org/python/core/Pragma.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,46 @@ +package org.python.core; + +import org.python.antlr.ParseException; + +public interface Pragma { + void addTo(PragmaReceiver receiver); + + public abstract class PragmaModule { + public final String name; + + protected PragmaModule(String name) { + this.name = name; + } + + public abstract Pragma getPragma(String name); + + public abstract Pragma getStarPragma(); + } + + public final class ForbiddenPragmaModule extends PragmaModule { + private final String message; + + public ForbiddenPragmaModule(String name) { + this(name, "pragma " + name + " is not allowed in this context."); + } + + public ForbiddenPragmaModule(String name, String message) { + super(name); + this.message = message; + } + + @Override + public Pragma getPragma(String name) { + throw new ParseException(message); + } + + @Override + public Pragma getStarPragma() { + throw new ParseException(message); + } + + public void addTo(PragmaReceiver receiver) { + throw new ParseException(message); + } + } +} Added: trunk/jython/src/org/python/core/PragmaReceiver.java =================================================================== --- trunk/jython/src/org/python/core/PragmaReceiver.java (rev 0) +++ trunk/jython/src/org/python/core/PragmaReceiver.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,5 @@ +package org.python.core; + +public interface PragmaReceiver { + void add(Pragma pragma); +} Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/Py.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1218,7 +1218,7 @@ String contents = null; if (o instanceof PyString) { if (o instanceof PyUnicode) { - flags |= PyBaseCode.PyCF_SOURCE_IS_UTF8; + flags |= CompilerFlags.PyCF_SOURCE_IS_UTF8; } contents = o.toString(); } else if (o instanceof PyFile) { @@ -1231,7 +1231,7 @@ throw Py.TypeError( "exec: argument 1 must be string, code or file object"); } - code = (PyCode)Py.compile_flags(contents, "<string>", "exec", + code = (PyCode)Py.compile_flags(contents, "<string>", CompileMode.exec, getCompilerFlags(flags, false)); } Py.runCode(code, locals, globals); @@ -1603,41 +1603,31 @@ } public static CompilerFlags getCompilerFlags() { - return getCompilerFlags(0, false); + return CompilerFlags.getCompilerFlags(); } public static CompilerFlags getCompilerFlags(int flags, boolean dont_inherit) { - CompilerFlags cflags = null; + final PyFrame frame; if (dont_inherit) { - cflags = new CompilerFlags(flags); + frame = null; } else { - PyFrame frame = Py.getFrame(); - if (frame != null && frame.f_code != null) { - cflags = frame.f_code.co_flags.combine(flags); - } else { - cflags = new CompilerFlags(flags); - } + frame = Py.getFrame(); } - return cflags; + return CompilerFlags.getCompilerFlags(flags, frame); } public static CompilerFlags getCompilerFlags(CompilerFlags flags, boolean dont_inherit) { - CompilerFlags cflags = null; + final PyFrame frame; if (dont_inherit) { - cflags = flags; + frame = null; } else { - PyFrame frame = Py.getFrame(); - if (frame != null && frame.f_code != null) { - cflags = frame.f_code.co_flags.combine(flags); - } else { - cflags = flags; - } + frame = Py.getFrame(); } - return cflags; + return CompilerFlags.getCompilerFlags(flags, frame); } // w/o compiler-flags - public static PyObject compile(InputStream istream, String filename, String kind) { + public static PyCode compile(InputStream istream, String filename, CompileMode kind) { return compile_flags(istream, filename, kind, new CompilerFlags()); } @@ -1655,13 +1645,10 @@ * @param cflags Compiler flags * @return Code object for the compiled module */ - public static PyObject compile_flags(mod node, String name, String filename, + public static PyCode compile_flags(mod node, String name, String filename, boolean linenumbers, boolean printResults, CompilerFlags cflags) { try { - if (cflags != null && cflags.only_ast) { - return Py.java2py(node); - } ByteArrayOutputStream ostream = new ByteArrayOutputStream(); Module.compile(node, ostream, name, filename, linenumbers, printResults, cflags); @@ -1673,17 +1660,17 @@ } } - public static PyObject compile_flags(mod node, String filename, - String kind, CompilerFlags cflags) { + public static PyCode compile_flags(mod node, String filename, + CompileMode kind, CompilerFlags cflags) { return Py.compile_flags(node, getName(), filename, true, - kind.equals("single"), cflags); + kind == CompileMode.single, cflags); } /** * Compiles python source code coming from a file or another external stream */ - public static PyObject compile_flags(InputStream istream, String filename, - String kind, CompilerFlags cflags) { + public static PyCode compile_flags(InputStream istream, String filename, + CompileMode kind, CompilerFlags cflags) { mod node = ParserFacade.parse(istream, kind, filename, cflags); return Py.compile_flags(node, filename, kind, cflags); } @@ -1694,8 +1681,8 @@ * DO NOT use this for PyString input. Use * {@link #compile_flags(byte[], String, String, CompilerFlags)} instead. */ - public static PyObject compile_flags(String data, String filename, - String kind, CompilerFlags cflags) { + public static PyCode compile_flags(String data, String filename, + CompileMode kind, CompilerFlags cflags) { if (data.contains("\0")) { throw Py.TypeError("compile() expected string without null bytes"); } @@ -1709,7 +1696,7 @@ } public static PyObject compile_command_flags(String string, String filename, - String kind, CompilerFlags cflags, boolean stdprompt) { + CompileMode kind, CompilerFlags cflags, boolean stdprompt) { mod node = ParserFacade.partialParse(string + "\n", kind, filename, cflags, stdprompt); if (node == null) { Modified: trunk/jython/src/org/python/core/PyBaseCode.java =================================================================== --- trunk/jython/src/org/python/core/PyBaseCode.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/PyBaseCode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -17,30 +17,7 @@ public int co_nlocals; public boolean varargs, varkwargs; - final public static int CO_OPTIMIZED = 0x0001; - final public static int CO_NEWLOCALS = 0x0002; - final public static int CO_VARARGS = 0x0004; - final public static int CO_VARKEYWORDS = 0x0008; - final public static int CO_GENERATOR = 0x0020; - // these are defined in __future__.py - final public static int CO_NESTED = 0x0010; - final public static int CO_GENERATOR_ALLOWED = 0x0; - final public static int CO_FUTUREDIVISION = 0x2000; - final public static int CO_FUTURE_ABSOLUTE_IMPORT = 0x4000; - final public static int CO_WITH_STATEMENT = 0x8000; - - //XXX: I'm not positive that this is the right place for these constants. - final public static int PyCF_SOURCE_IS_UTF8 = 0x0100; - final public static int PyCF_DONT_IMPLY_DEDENT = 0x0200; - final public static int PyCF_ONLY_AST = 0x0400; - - final public static int CO_ALL_FEATURES = PyCF_DONT_IMPLY_DEDENT|PyCF_ONLY_AST| - PyCF_SOURCE_IS_UTF8|CO_NESTED| - CO_GENERATOR_ALLOWED| CO_FUTUREDIVISION| - CO_FUTURE_ABSOLUTE_IMPORT|CO_WITH_STATEMENT; - - public boolean hasFreevars() { return co_freevars != null && co_freevars.length > 0; } @@ -135,7 +112,7 @@ return call(Py.EmptyObjects, Py.NoKeywords, globals, defaults, closure); PyFrame frame = new PyFrame(this, globals); - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); @@ -149,7 +126,7 @@ Py.NoKeywords, globals, defaults, closure); PyFrame frame = new PyFrame(this, globals); frame.f_fastlocals[0] = arg1; - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); @@ -164,7 +141,7 @@ PyFrame frame = new PyFrame(this, globals); frame.f_fastlocals[0] = arg1; frame.f_fastlocals[1] = arg2; - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); @@ -181,7 +158,7 @@ frame.f_fastlocals[0] = arg1; frame.f_fastlocals[1] = arg2; frame.f_fastlocals[2] = arg3; - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); @@ -297,7 +274,7 @@ co_name, argcount)); } - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); Modified: trunk/jython/src/org/python/core/PyBytecode.java =================================================================== --- trunk/jython/src/org/python/core/PyBytecode.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/PyBytecode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -75,8 +75,8 @@ co_freevars = freevars; co_name = name; co_flags = new CompilerFlags(flags); - varargs = co_flags.varargs; - varkwargs = co_flags.varkeywords; + varargs = co_flags.isFlagSet(CodeFlag.CO_VARARGS); + varkwargs = co_flags.isFlagSet(CodeFlag.CO_VARKEYWORDS); co_stacksize = stacksize; co_consts = constants; @@ -420,7 +420,7 @@ PyObject b = stack.pop(); PyObject a = stack.pop(); - if (!co_flags.division) { + if (!co_flags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) { stack.push(a._div(b)); } else { stack.push(a._truediv(b)); @@ -530,7 +530,7 @@ case Opcode.INPLACE_DIVIDE: { PyObject b = stack.pop(); PyObject a = stack.pop(); - if (!co_flags.division) { + if (!co_flags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) { stack.push(a._idiv(b)); } else { stack.push(a._itruediv(b)); @@ -1248,7 +1248,7 @@ throw ts.exception; } - if (co_flags.generator && why == Why.RETURN && retval == Py.None) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR) && why == Why.RETURN && retval == Py.None) { f.f_lasti = -1; } Modified: trunk/jython/src/org/python/core/PyFrame.java =================================================================== --- trunk/jython/src/org/python/core/PyFrame.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/PyFrame.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -62,7 +62,7 @@ // This needs work to be efficient with multiple interpreter states if (locals == null && code != null) { // ! f_fastlocals needed for arg passing too - if (code.co_flags.optimized || code.nargs > 0) { + if (code.co_flags.isFlagSet(CodeFlag.CO_OPTIMIZED) || code.nargs > 0) { if (code.co_nlocals > 0) { // internal: may change f_fastlocals = new PyObject[code.co_nlocals - code.jy_npurecell]; @@ -191,7 +191,7 @@ PyObject o = f_fastlocals[i]; if (o != null) f_locals.__setitem__(f_code.co_varnames[i], o); } - if (!f_code.co_flags.optimized) { + if (!f_code.co_flags.isFlagSet(CodeFlag.CO_OPTIMIZED)) { f_fastlocals = null; } } Modified: trunk/jython/src/org/python/core/PyTableCode.java =================================================================== --- trunk/jython/src/org/python/core/PyTableCode.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/PyTableCode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -45,12 +45,12 @@ co_name = name; if (varargs) { co_argcount -= 1; - co_flags.varargs = true; + co_flags.setFlag(CodeFlag.CO_VARARGS); } this.varkwargs = varkwargs; if (varkwargs) { co_argcount -= 1; - co_flags.varkeywords = true; + co_flags.setFlag(CodeFlag.CO_VARKEYWORDS); } co_flags = new CompilerFlags(co_flags.toBits() | moreflags); this.funcs = funcs; Modified: trunk/jython/src/org/python/core/__builtin__.java =================================================================== --- trunk/jython/src/org/python/core/__builtin__.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/__builtin__.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -527,7 +527,7 @@ PyCode code; try { - code = (PyCode)Py.compile_flags(file, name, "exec", cflags); + code = (PyCode)Py.compile_flags(file, name, CompileMode.exec, cflags); } finally { try { file.close(); @@ -1526,45 +1526,41 @@ public static PyObject compile(PyObject source, String filename, String mode, int flags, boolean dont_inherit) { - if ((flags & ~PyBaseCode.CO_ALL_FEATURES) != 0) { - throw Py.ValueError("compile(): unrecognised flags"); - } - if (!mode.equals("exec") && !mode.equals("eval") && !mode.equals("single")) { - throw Py.ValueError("compile() arg 3 must be 'exec' or 'eval' or 'single'"); - } + CompilerFlags cflags = Py.getCompilerFlags(flags, dont_inherit); + CompileMode kind = CompileMode.getMode(mode); - mod ast = py2node(source); - if (ast != null) { - return Py.compile_flags(ast, filename, mode, Py.getCompilerFlags(flags, dont_inherit)); - } - - if (!(source instanceof PyString)) { - throw Py.TypeError("expected a readable buffer object"); - } - if (source instanceof PyUnicode) { - flags |= PyBaseCode.PyCF_SOURCE_IS_UTF8; - } - return Py.compile_flags(((PyString)source).toString(), filename, mode, - Py.getCompilerFlags(flags, dont_inherit)); + return compile(source, filename, kind, cflags, dont_inherit); } - public static PyObject compile(PyObject source, String filename, String mode, CompilerFlags flags, + public static PyObject compile(PyObject source, String filename, CompileMode kind, CompilerFlags cflags, boolean dont_inherit) { - if (!mode.equals("exec") && !mode.equals("eval") && !mode.equals("single")) { - throw Py.ValueError("compile() arg 3 must be 'exec' or 'eval' or 'single'"); - } - + cflags = Py.getCompilerFlags(cflags, dont_inherit); + mod ast = py2node(source); - if (ast != null) { - return Py.compile_flags(ast, filename, mode, Py.getCompilerFlags(flags, dont_inherit)); + if (ast == null) { + if (!(source instanceof PyString)) { + ... [truncated message content] |
From: <pj...@us...> - 2009-03-29 20:07:48
|
Revision: 6114 http://jython.svn.sourceforge.net/jython/?rev=6114&view=rev Author: pjenvey Date: 2009-03-29 20:07:31 +0000 (Sun, 29 Mar 2009) Log Message: ----------- o workaround our shebang line issues (#1112) by using /usr/bin/env when we can o make installed scripts executable Modified Paths: -------------- trunk/jython/Lib/distutils/command/build_scripts.py trunk/jython/Lib/distutils/command/install_scripts.py Modified: trunk/jython/Lib/distutils/command/build_scripts.py =================================================================== --- trunk/jython/Lib/distutils/command/build_scripts.py 2009-03-29 20:00:29 UTC (rev 6113) +++ trunk/jython/Lib/distutils/command/build_scripts.py 2009-03-29 20:07:31 UTC (rev 6114) @@ -94,18 +94,18 @@ if adjust: log.info("copying and adjusting %s -> %s", script, self.build_dir) + if not sysconfig.python_build: + executable = self.executable + else: + executable = os.path.join( + sysconfig.get_config_var("BINDIR"), + "python" + sysconfig.get_config_var("EXE")) + executable = fix_jython_executable(executable, post_interp) if not self.dry_run: outf = open(outfile, "w") - if not sysconfig.python_build: - outf.write("#!%s%s\n" % - (self.executable, - post_interp)) - else: - outf.write("#!%s%s\n" % - (os.path.join( - sysconfig.get_config_var("BINDIR"), - "python" + sysconfig.get_config_var("EXE")), - post_interp)) + outf.write("#!%s%s\n" % + (executable, + post_interp)) outf.writelines(f.readlines()) outf.close() if f: @@ -115,7 +115,7 @@ f.close() self.copy_file(script, outfile) - if os.name == 'posix': + if hasattr(os, 'chmod'): for file in outfiles: if self.dry_run: log.info("changing mode of %s", file) @@ -130,3 +130,29 @@ # copy_scripts () # class build_scripts + + +def is_sh(executable): + """Determine if the specified executable is a .sh (contains a #! line)""" + try: + fp = open(executable) + magic = fp.read(2) + fp.close() + except IOError, OSError: + return executable + return magic == '#!' + + +def fix_jython_executable(executable, options): + if sys.platform.startswith('java') and is_sh(executable): + # Workaround Jython's sys.executable being a .sh (an invalid + # shebang line interpreter) + if options: + # Can't apply the workaround, leave it broken + log.warn("WARNING: Unable to adapt shebang line for Jython," + " the following script is NOT executable\n" + " see http://bugs.jython.org/issue1112 for" + " more information.") + else: + return '/usr/bin/env %s' % executable + return executable Modified: trunk/jython/Lib/distutils/command/install_scripts.py =================================================================== --- trunk/jython/Lib/distutils/command/install_scripts.py 2009-03-29 20:00:29 UTC (rev 6113) +++ trunk/jython/Lib/distutils/command/install_scripts.py 2009-03-29 20:07:31 UTC (rev 6114) @@ -46,7 +46,7 @@ if not self.skip_build: self.run_command('build_scripts') self.outfiles = self.copy_tree(self.build_dir, self.install_dir) - if os.name == 'posix': + if hasattr(os, 'chmod'): # Set the executable bits (owner, group, and world) on # all the scripts we just installed. for file in self.get_outputs(): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-29 20:00:42
|
Revision: 6113 http://jython.svn.sourceforge.net/jython/?rev=6113&view=rev Author: pjenvey Date: 2009-03-29 20:00:29 +0000 (Sun, 29 Mar 2009) Log Message: ----------- from: http://svn.python.org/projects/python/branches/release25-maint/Lib/distutils/command/build_scripts.py@59668 http://svn.python.org/projects/python/branches/release25-maint/Lib/distutils/command/build_scripts.py@37828 Added Paths: ----------- trunk/jython/Lib/distutils/command/build_scripts.py trunk/jython/Lib/distutils/command/install_scripts.py Added: trunk/jython/Lib/distutils/command/build_scripts.py =================================================================== --- trunk/jython/Lib/distutils/command/build_scripts.py (rev 0) +++ trunk/jython/Lib/distutils/command/build_scripts.py 2009-03-29 20:00:29 UTC (rev 6113) @@ -0,0 +1,132 @@ +"""distutils.command.build_scripts + +Implements the Distutils 'build_scripts' command.""" + +# This module should be kept compatible with Python 2.1. + +__revision__ = "$Id: build_scripts.py 59668 2008-01-02 18:59:36Z guido.van.rossum $" + +import sys, os, re +from stat import ST_MODE +from distutils import sysconfig +from distutils.core import Command +from distutils.dep_util import newer +from distutils.util import convert_path +from distutils import log + +# check if Python is called on the first line with this expression +first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$') + +class build_scripts (Command): + + description = "\"build\" scripts (copy and fixup #! line)" + + user_options = [ + ('build-dir=', 'd', "directory to \"build\" (copy) to"), + ('force', 'f', "forcibly build everything (ignore file timestamps"), + ('executable=', 'e', "specify final destination interpreter path"), + ] + + boolean_options = ['force'] + + + def initialize_options (self): + self.build_dir = None + self.scripts = None + self.force = None + self.executable = None + self.outfiles = None + + def finalize_options (self): + self.set_undefined_options('build', + ('build_scripts', 'build_dir'), + ('force', 'force'), + ('executable', 'executable')) + self.scripts = self.distribution.scripts + + def get_source_files(self): + return self.scripts + + def run (self): + if not self.scripts: + return + self.copy_scripts() + + + def copy_scripts (self): + """Copy each script listed in 'self.scripts'; if it's marked as a + Python script in the Unix way (first line matches 'first_line_re', + ie. starts with "\#!" and contains "python"), then adjust the first + line to refer to the current Python interpreter as we copy. + """ + self.mkpath(self.build_dir) + outfiles = [] + for script in self.scripts: + adjust = 0 + script = convert_path(script) + outfile = os.path.join(self.build_dir, os.path.basename(script)) + outfiles.append(outfile) + + if not self.force and not newer(script, outfile): + log.debug("not copying %s (up-to-date)", script) + continue + + # Always open the file, but ignore failures in dry-run mode -- + # that way, we'll get accurate feedback if we can read the + # script. + try: + f = open(script, "r") + except IOError: + if not self.dry_run: + raise + f = None + else: + first_line = f.readline() + if not first_line: + self.warn("%s is an empty file (skipping)" % script) + continue + + match = first_line_re.match(first_line) + if match: + adjust = 1 + post_interp = match.group(1) or '' + + if adjust: + log.info("copying and adjusting %s -> %s", script, + self.build_dir) + if not self.dry_run: + outf = open(outfile, "w") + if not sysconfig.python_build: + outf.write("#!%s%s\n" % + (self.executable, + post_interp)) + else: + outf.write("#!%s%s\n" % + (os.path.join( + sysconfig.get_config_var("BINDIR"), + "python" + sysconfig.get_config_var("EXE")), + post_interp)) + outf.writelines(f.readlines()) + outf.close() + if f: + f.close() + else: + if f: + f.close() + self.copy_file(script, outfile) + + if os.name == 'posix': + for file in outfiles: + if self.dry_run: + log.info("changing mode of %s", file) + else: + oldmode = os.stat(file)[ST_MODE] & 07777 + newmode = (oldmode | 0555) & 07777 + if newmode != oldmode: + log.info("changing mode of %s from %o to %o", + file, oldmode, newmode) + os.chmod(file, newmode) + + # copy_scripts () + +# class build_scripts Added: trunk/jython/Lib/distutils/command/install_scripts.py =================================================================== --- trunk/jython/Lib/distutils/command/install_scripts.py (rev 0) +++ trunk/jython/Lib/distutils/command/install_scripts.py 2009-03-29 20:00:29 UTC (rev 6113) @@ -0,0 +1,66 @@ +"""distutils.command.install_scripts + +Implements the Distutils 'install_scripts' command, for installing +Python scripts.""" + +# contributed by Bastian Kleineidam + +# This module should be kept compatible with Python 2.1. + +__revision__ = "$Id: install_scripts.py 37828 2004-11-10 22:23:15Z loewis $" + +import os +from distutils.core import Command +from distutils import log +from stat import ST_MODE + +class install_scripts (Command): + + description = "install scripts (Python or otherwise)" + + user_options = [ + ('install-dir=', 'd', "directory to install scripts to"), + ('build-dir=','b', "build directory (where to install from)"), + ('force', 'f', "force installation (overwrite existing files)"), + ('skip-build', None, "skip the build steps"), + ] + + boolean_options = ['force', 'skip-build'] + + + def initialize_options (self): + self.install_dir = None + self.force = 0 + self.build_dir = None + self.skip_build = None + + def finalize_options (self): + self.set_undefined_options('build', ('build_scripts', 'build_dir')) + self.set_undefined_options('install', + ('install_scripts', 'install_dir'), + ('force', 'force'), + ('skip_build', 'skip_build'), + ) + + def run (self): + if not self.skip_build: + self.run_command('build_scripts') + self.outfiles = self.copy_tree(self.build_dir, self.install_dir) + if os.name == 'posix': + # Set the executable bits (owner, group, and world) on + # all the scripts we just installed. + for file in self.get_outputs(): + if self.dry_run: + log.info("changing mode of %s", file) + else: + mode = ((os.stat(file)[ST_MODE]) | 0555) & 07777 + log.info("changing mode of %s to %o", file, mode) + os.chmod(file, mode) + + def get_inputs (self): + return self.distribution.scripts or [] + + def get_outputs(self): + return self.outfiles or [] + +# class install_scripts This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-27 23:22:15
|
Revision: 6112 http://jython.svn.sourceforge.net/jython/?rev=6112&view=rev Author: pjenvey Date: 2009-03-27 23:21:59 +0000 (Fri, 27 Mar 2009) Log Message: ----------- fix type serialization broken by the now fully qualified type names thanks Sergei fixes #1282 Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2009-03-27 21:44:57 UTC (rev 6111) +++ trunk/jython/Lib/test/test_java_integration.py 2009-03-27 23:21:59 UTC (rev 6112) @@ -10,8 +10,9 @@ from java.lang import (ClassCastException, ExceptionInInitializerError, String, Runnable, System, Runtime, Math, Byte) from java.math import BigDecimal, BigInteger -from java.io import (File, FileInputStream, FileNotFoundException, FileOutputStream, FileWriter, - OutputStreamWriter, UnsupportedEncodingException) +from java.io import (ByteArrayInputStream, ByteArrayOutputStream, File, FileInputStream, + FileNotFoundException, FileOutputStream, FileWriter, ObjectInputStream, + ObjectOutputStream, OutputStreamWriter, UnsupportedEncodingException) from java.util import ArrayList, Date, HashMap, Hashtable, StringTokenizer, Vector from java.awt import Dimension, Color, Component, Container @@ -425,6 +426,19 @@ self.assertRaises(TypeError, __import__, "org.python.tests.mro.ConfusedOnImport") self.assertRaises(TypeError, GetitemAdder.addPostdefined) +class SerializationTest(unittest.TestCase): + + def test_java_serialization(self): + date_list = [Date(), Date()] + output = ByteArrayOutputStream() + serializer = ObjectOutputStream(output) + serializer.writeObject(date_list) + serializer.close() + + input = ByteArrayInputStream(output.toByteArray()) + unserializer = ObjectInputStream(input) + self.assertEqual(date_list, unserializer.readObject()) + def test_main(): test_support.run_unittest(InstantiationTest, BeanTest, @@ -439,7 +453,8 @@ JavaStringTest, JavaDelegationTest, SecurityManagerTest, - JavaWrapperCustomizationTest) + JavaWrapperCustomizationTest, + SerializationTest) if __name__ == "__main__": test_main() Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-03-27 21:44:57 UTC (rev 6111) +++ trunk/jython/src/org/python/core/PyType.java 2009-03-27 23:21:59 UTC (rev 6112) @@ -1376,7 +1376,7 @@ /** Used when serializing this type. */ protected Object writeReplace() { - return new TypeResolver(underlying_class, getModule().toString(), name); + return new TypeResolver(underlying_class, getModule().toString(), getName()); } private interface OnType { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-27 21:45:11
|
Revision: 6111 http://jython.svn.sourceforge.net/jython/?rev=6111&view=rev Author: pjenvey Date: 2009-03-27 21:44:57 +0000 (Fri, 27 Mar 2009) Log Message: ----------- reduce our CHMs' concurrencyLevel to 2 from 16 to reduce allocation. speeds up pybench by 10% Modified Paths: -------------- trunk/jython/src/org/python/core/PyDictionary.java trunk/jython/src/org/python/core/PySet.java trunk/jython/src/org/python/core/PyStringMap.java trunk/jython/src/org/python/modules/PyTeeIterator.java trunk/jython/src/org/python/util/Generic.java Modified: trunk/jython/src/org/python/core/PyDictionary.java =================================================================== --- trunk/jython/src/org/python/core/PyDictionary.java 2009-03-27 20:34:45 UTC (rev 6110) +++ trunk/jython/src/org/python/core/PyDictionary.java 2009-03-27 21:44:57 UTC (rev 6111) @@ -4,20 +4,19 @@ import java.util.AbstractSet; import java.util.ArrayList; import java.util.Collection; -import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.ConcurrentMap; import org.python.expose.ExposedClassMethod; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; import org.python.expose.MethodType; +import org.python.util.Generic; /** @@ -34,7 +33,7 @@ * Create an empty dictionary. */ public PyDictionary() { - table = new ConcurrentHashMap<PyObject, PyObject>(); + table = Generic.concurrentMap(); } /** @@ -42,14 +41,15 @@ */ public PyDictionary(PyType subtype) { super(subtype); - table = new ConcurrentHashMap<PyObject, PyObject>(); + table = Generic.concurrentMap(); } /** * Create a new dictionary which is based on given map. */ public PyDictionary(Map<PyObject, PyObject> t) { - table = new ConcurrentHashMap<PyObject, PyObject>(t); + table = Generic.concurrentMap(); + table.putAll(t); } /** @@ -57,7 +57,8 @@ */ public PyDictionary(PyType subtype, Map<PyObject, PyObject> t) { super(subtype); - table = new ConcurrentHashMap<PyObject, PyObject>(t); + table = Generic.concurrentMap(); + table.putAll(t); } Modified: trunk/jython/src/org/python/core/PySet.java =================================================================== --- trunk/jython/src/org/python/core/PySet.java 2009-03-27 20:34:45 UTC (rev 6110) +++ trunk/jython/src/org/python/core/PySet.java 2009-03-27 21:44:57 UTC (rev 6111) @@ -2,12 +2,13 @@ import java.util.Iterator; import java.util.NoSuchElementException; +import java.util.Set; -import org.python.core.util.ConcurrentHashSet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; import org.python.expose.MethodType; +import org.python.util.Generic; @ExposedType(name = "set", base = PyObject.class) public class PySet extends BaseSet { @@ -15,17 +16,22 @@ public static final PyType TYPE = PyType.fromClass(PySet.class); public PySet() { - super(new ConcurrentHashSet<PyObject>()); + super(concurrentSet()); } public PySet(PyType type) { - super(type, new ConcurrentHashSet<PyObject>()); + super(type, concurrentSet()); } public PySet(PyObject data) { - super(_update(new ConcurrentHashSet<PyObject>(), data)); + super(_update(concurrentSet(), data)); } + /** Contextualize the needed Set<PyObject> type paramaters (generics workaround). */ + private static Set<PyObject> concurrentSet() { + return Generic.concurrentSet(); + } + @ExposedNew @ExposedMethod final void set___init__(PyObject[] args, String[] kwds) { Modified: trunk/jython/src/org/python/core/PyStringMap.java =================================================================== --- trunk/jython/src/org/python/core/PyStringMap.java 2009-03-27 20:34:45 UTC (rev 6110) +++ trunk/jython/src/org/python/core/PyStringMap.java 2009-03-27 21:44:57 UTC (rev 6111) @@ -9,6 +9,8 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import org.python.util.Generic; + /** * Special fast dict implementation for __dict__ instances. Allows interned String keys in addition * to PyObject unlike PyDictionary. @@ -22,11 +24,13 @@ } public PyStringMap(int capacity) { - table = new ConcurrentHashMap<Object, PyObject>(capacity); + table = new ConcurrentHashMap<Object, PyObject>(capacity, Generic.CHM_LOAD_FACTOR, + Generic.CHM_CONCURRENCY_LEVEL); } public PyStringMap(Map<Object, PyObject> map) { - table = new ConcurrentHashMap<Object, PyObject>(map); + table = Generic.concurrentMap(); + table.putAll(map); } public PyStringMap(PyObject elements[]) { Modified: trunk/jython/src/org/python/modules/PyTeeIterator.java =================================================================== --- trunk/jython/src/org/python/modules/PyTeeIterator.java 2009-03-27 20:34:45 UTC (rev 6110) +++ trunk/jython/src/org/python/modules/PyTeeIterator.java 2009-03-27 21:44:57 UTC (rev 6111) @@ -1,7 +1,6 @@ package org.python.modules; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import org.python.core.Py; import org.python.core.PyException; @@ -12,6 +11,7 @@ import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; +import org.python.util.Generic; @ExposedType(name = "itertools.tee", base = PyObject.class, isBaseType = false) public class PyTeeIterator extends PyIterator { @@ -45,7 +45,7 @@ throw Py.ValueError("n must be >= 0"); } PyObject iterator = iterable.__iter__(); - Map<Integer, PyObject> buffer = new ConcurrentHashMap<Integer, PyObject>(); + Map<Integer, PyObject> buffer = Generic.concurrentMap(); int[] offsets = new int[n]; PyTeeIterator[] tees = new PyTeeIterator[n]; for (int i = 0; i < n; i++) { Modified: trunk/jython/src/org/python/util/Generic.java =================================================================== --- trunk/jython/src/org/python/util/Generic.java 2009-03-27 20:34:45 UTC (rev 6110) +++ trunk/jython/src/org/python/util/Generic.java 2009-03-27 21:44:57 UTC (rev 6111) @@ -6,7 +6,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import org.python.core.util.ConcurrentHashSet; + /** * Static methods to make instances of collections with their generic types inferred from what * they're being assigned to. The idea is stolen from <code>Sets</code>, <code>Lists</code> and @@ -14,7 +18,16 @@ * Collections</a>. */ public class Generic { + /** + * Our default ConcurrentHashMap sizes. Only concurreny level differs from + * ConcurrentHashMap's defaults: it's significantly lower to reduce allocation cost. + */ + public static final int CHM_INITIAL_CAPACITY = 16; + public static final float CHM_LOAD_FACTOR = 0.75f; + public static final int CHM_CONCURRENCY_LEVEL = 2; + + /** * Makes a List with its generic type inferred from whatever it's being assigned to. */ public static <T> List<T> list() { @@ -40,6 +53,15 @@ } /** + * Makes a ConcurrentMap using generic types inferred from whatever this is being + * assigned to. + */ + public static <K, V> ConcurrentMap<K, V> concurrentMap() { + return new ConcurrentHashMap<K, V>(CHM_INITIAL_CAPACITY, CHM_LOAD_FACTOR, + CHM_CONCURRENCY_LEVEL); + } + + /** * Makes a Set using the generic type inferred from whatever this is being assigned to. */ public static <T> Set<T> set() { @@ -57,4 +79,13 @@ } return s; } + + /** + * Makes a Set, ensuring safe concurrent operations, using generic types inferred from + * whatever this is being assigned to. + */ + public static <T> Set<T> concurrentSet() { + return new ConcurrentHashSet<T>(CHM_INITIAL_CAPACITY, CHM_LOAD_FACTOR, + CHM_CONCURRENCY_LEVEL); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-27 20:34:59
|
Revision: 6110 http://jython.svn.sourceforge.net/jython/?rev=6110&view=rev Author: pjenvey Date: 2009-03-27 20:34:45 +0000 (Fri, 27 Mar 2009) Log Message: ----------- prefer the parent ConcurrentMap interface Modified Paths: -------------- trunk/jython/src/org/python/core/util/ConcurrentHashSet.java Modified: trunk/jython/src/org/python/core/util/ConcurrentHashSet.java =================================================================== --- trunk/jython/src/org/python/core/util/ConcurrentHashSet.java 2009-03-27 19:03:30 UTC (rev 6109) +++ trunk/jython/src/org/python/core/util/ConcurrentHashSet.java 2009-03-27 20:34:45 UTC (rev 6110) @@ -9,6 +9,7 @@ import java.util.Iterator; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; /** * A Set backed by ConcurrentHashMap. @@ -16,7 +17,7 @@ public class ConcurrentHashSet<E> extends AbstractSet<E> implements Serializable { /** The backing Map. */ - private final ConcurrentHashMap<E, Object> map; + private final ConcurrentMap<E, Object> map; /** Backing's KeySet. */ private transient Set<E> keySet; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-27 19:03:55
|
Revision: 6109 http://jython.svn.sourceforge.net/jython/?rev=6109&view=rev Author: pjenvey Date: 2009-03-27 19:03:30 +0000 (Fri, 27 Mar 2009) Log Message: ----------- have java integration translate faux-floats (objects implementing __float__) to Java floats patch from zyasoft fixes #1198 Modified Paths: -------------- trunk/jython/Lib/test/test_float_jy.py trunk/jython/src/org/python/core/PyObject.java Modified: trunk/jython/Lib/test/test_float_jy.py =================================================================== --- trunk/jython/Lib/test/test_float_jy.py 2009-03-26 16:49:14 UTC (rev 6108) +++ trunk/jython/Lib/test/test_float_jy.py 2009-03-27 19:03:30 UTC (rev 6109) @@ -98,7 +98,13 @@ # regression in 2.5 alphas self.assertEqual(4.0 ** Foo(), 16.0) + def test_faux(self): + class F(object): + def __float__(self): + return 1.6 + self.assertEqual(math.cos(1.6), math.cos(F())) + def test_main(): test_support.run_unittest(FloatTestCase) Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-03-26 16:49:14 UTC (rev 6108) +++ trunk/jython/src/org/python/core/PyObject.java 2009-03-27 19:03:30 UTC (rev 6109) @@ -264,6 +264,20 @@ if (c.isInstance(getJavaProxy())) { return javaProxy; } + + // convert faux floats + // XXX: should also convert faux ints, but that breaks test_java_visibility + // (ReflectedArgs resolution) + if (c == Double.TYPE || c == Double.class || c == Float.TYPE || c == Float.class) { + try { + return __float__().getValue(); + } catch (PyException pye) { + if (!Py.matchException(pye, Py.AttributeError)) { + throw pye; + } + } + } + return Py.NoConversion; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-26 16:49:28
|
Revision: 6108 http://jython.svn.sourceforge.net/jython/?rev=6108&view=rev Author: pjenvey Date: 2009-03-26 16:49:14 +0000 (Thu, 26 Mar 2009) Log Message: ----------- fix lack of tracing when creating exceptions thanks jha fixes #1249 Modified Paths: -------------- trunk/jython/src/org/python/core/PyException.java Modified: trunk/jython/src/org/python/core/PyException.java =================================================================== --- trunk/jython/src/org/python/core/PyException.java 2009-03-22 14:00:52 UTC (rev 6107) +++ trunk/jython/src/org/python/core/PyException.java 2009-03-26 16:49:14 UTC (rev 6108) @@ -49,6 +49,11 @@ if (traceback != null) { this.traceback = traceback; isReRaise = true; + } else { + PyFrame frame = Py.getFrame(); + if (frame != null && frame.tracefunc != null) { + frame.tracefunc = frame.tracefunc.traceException(frame, this); + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-03-22 14:00:56
|
Revision: 6107 http://jython.svn.sourceforge.net/jython/?rev=6107&view=rev Author: zyasoft Date: 2009-03-22 14:00:52 +0000 (Sun, 22 Mar 2009) Log Message: ----------- Fixes #1140: now uses pkgutil.get_loader.get_data to properly get the data files used by unicodedata data files were not being imported properly, as required for a standalone jar. Thanks Olivier Samyn for the initial version of the patch! Modified Paths: -------------- trunk/jython/Lib/unicodedata.py Modified: trunk/jython/Lib/unicodedata.py =================================================================== --- trunk/jython/Lib/unicodedata.py 2009-03-22 03:00:51 UTC (rev 6106) +++ trunk/jython/Lib/unicodedata.py 2009-03-22 14:00:52 UTC (rev 6107) @@ -1,19 +1,18 @@ -from __future__ import with_statement from bisect import bisect_left import operator -import os import java.lang.Character -# this is intended as a stopgap measure; at the very least it should -# be refactored so that we can avoid its slow startup time +# XXX - this is intended as a stopgap measure until 2.5.1, which will have a Java implementation # requires java 6 for `normalize` function +# only has one version of the database +# does not normalized ideographs -# XXX - change so we bind against the specific version _codepoints = {} _eaw = {} _names = {} _segments = [] _eaw_segments = [] +Nonesuch = object() def get_int(col): try: @@ -35,63 +34,53 @@ except: return None -def init(path): - with open(os.path.join(path, 'UnicodeData.txt')) as data: - for row in data: - cols = row.split(';') - codepoint = int(cols[0], 16) - name = cols[1] - if name == '<CJK Ideograph, Last>': - lookup_name = 'CJK UNIFIED IDEOGRAPH' - else: - lookup_name = name - data = ( - cols[2], - get_int(cols[3]), - cols[4], - cols[5], - get_int(cols[6]), - get_int(cols[7]), - get_numeric(cols[8]), - get_yn(cols[9]), - lookup_name, - ) +def init_unicodedata(data): + for row in data: + cols = row.split(';') + codepoint = int(cols[0], 16) + name = cols[1] + if name == '<CJK Ideograph, Last>': + lookup_name = 'CJK UNIFIED IDEOGRAPH' + else: + lookup_name = name + data = ( + cols[2], + get_int(cols[3]), + cols[4], + cols[5], + get_int(cols[6]), + get_int(cols[7]), + get_numeric(cols[8]), + get_yn(cols[9]), + lookup_name, + ) - if name.find('First') >= 0: - start = codepoint - elif name.find('Last') >= 0: - _segments.append((start, (start, codepoint), data)) - else: - _names[name] = unichr(codepoint) - _codepoints[codepoint] = data + if name.find('First') >= 0: + start = codepoint + elif name.find('Last') >= 0: + _segments.append((start, (start, codepoint), data)) + else: + _names[name] = unichr(codepoint) + _codepoints[codepoint] = data -def init_east_asian_width(path): - with open(os.path.join(path, 'EastAsianWidth.txt')) as data: - for row in data: - if row.startswith('#'): - continue - row = row.partition('#')[0] - cols = row.split(';') - if len(cols) < 2: - continue - cr = cols[0].split('..') - width = cols[1].rstrip() - if len(cr) == 1: - codepoint = int(cr[0], 16) - _eaw[codepoint] = width - else: - start = int(cr[0], 16) - end = int(cr[1], 16) - _eaw_segments.append((start, (start, end), width)) +def init_east_asian_width(data): + for row in data: + if row.startswith('#'): + continue + row = row.partition('#')[0] + cols = row.split(';') + if len(cols) < 2: + continue + cr = cols[0].split('..') + width = cols[1].rstrip() + if len(cr) == 1: + codepoint = int(cr[0], 16) + _eaw[codepoint] = width + else: + start = int(cr[0], 16) + end = int(cr[1], 16) + _eaw_segments.append((start, (start, end), width)) - -# this doesn't work in general, but it should be ok in this case since -# core libraries don't go through a zip import; see PEP 302 if we -# actually need to do any loader magic -my_path = os.path.dirname(__file__) -init(my_path) -init_east_asian_width(my_path) - # xxx - need to normalize the segments, so # <CJK Ideograph, Last> ==> CJK UNIFIED IDEOGRAPH; # may need to do some sort of analysis against CPython for the normalization! @@ -124,7 +113,6 @@ return segment[2] return None -Nonesuch = object() def get_codepoint(unichr, fn=None): if not(isinstance(unichr, unicode)): @@ -225,3 +213,17 @@ except ImportError: pass + + +def init(): + import pkgutil + import os.path + import StringIO + import sys + + my_path = os.path.dirname(__file__) + loader = pkgutil.get_loader('unicodedata') + init_unicodedata(StringIO.StringIO(loader.get_data(os.path.join(my_path,'UnicodeData.txt')))) + init_east_asian_width(StringIO.StringIO(loader.get_data(os.path.join(my_path,'EastAsianWidth.txt')))) + +init() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-03-22 03:00:56
|
Revision: 6106 http://jython.svn.sourceforge.net/jython/?rev=6106&view=rev Author: zyasoft Date: 2009-03-22 03:00:51 +0000 (Sun, 22 Mar 2009) Log Message: ----------- dict() now can be constructed from a Map in user-level code. This fixes bug #1146. Modified Paths: -------------- trunk/jython/Lib/test/test_dict_jy.py trunk/jython/src/org/python/core/PyDictionary.java Modified: trunk/jython/Lib/test/test_dict_jy.py =================================================================== --- trunk/jython/Lib/test/test_dict_jy.py 2009-03-21 22:29:19 UTC (rev 6105) +++ trunk/jython/Lib/test/test_dict_jy.py 2009-03-22 03:00:51 UTC (rev 6106) @@ -1,4 +1,5 @@ from test import test_support +import java import unittest class DictInitTest(unittest.TestCase): @@ -93,9 +94,29 @@ raise CustomKeyError("custom message") self.assertRaises(CustomKeyError, lambda: DerivedDict()['foo']) +class JavaIntegrationTest(unittest.TestCase): + "Tests for instantiating dicts from Java maps and hashtables" + def test_hashmap(self): + x = java.util.HashMap() + x.put('a', 1) + x.put('b', 2) + x.put('c', 3) + x.put((1,2), "xyz") + y = dict(x) + self.assertEqual(set(y.items()), set([('a', 1), ('b', 2), ('c', 3), ((1,2), "xyz")])) + def test_hashtable(self): + x = java.util.Hashtable() + x.put('a', 1) + x.put('b', 2) + x.put('c', 3) + x.put((1,2), "xyz") + y = dict(x) + self.assertEqual(set(y.items()), set([('a', 1), ('b', 2), ('c', 3), ((1,2), "xyz")])) + + def test_main(): - test_support.run_unittest(DictInitTest, DictCmpTest, DerivedDictTest) + test_support.run_unittest(DictInitTest, DictCmpTest, DerivedDictTest, JavaIntegrationTest) if __name__ == '__main__': test_main() Modified: trunk/jython/src/org/python/core/PyDictionary.java =================================================================== --- trunk/jython/src/org/python/core/PyDictionary.java 2009-03-21 22:29:19 UTC (rev 6105) +++ trunk/jython/src/org/python/core/PyDictionary.java 2009-03-22 03:00:51 UTC (rev 6106) @@ -4,6 +4,7 @@ import java.util.AbstractSet; import java.util.ArrayList; import java.util.Collection; +import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -421,7 +422,12 @@ } if (nargs == 1) { PyObject arg = args[0]; - if (arg.__findattr__("keys") != null) { + + Object proxy = arg.getJavaProxy(); + if (proxy instanceof Map) { + merge((Map)proxy); + } + else if (arg.__findattr__("keys") != null) { merge(arg); } else { mergeFromSeq(arg); @@ -432,6 +438,13 @@ } } + private void merge(Map<Object,Object> other) { + for (Entry<Object,Object> entry : other.entrySet()) { + dict___setitem__(Py.java2py(entry.getKey()), Py.java2py(entry.getValue())); + } + } + + /** * Merge another PyObject that supports keys() with this * dict. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-21 22:29:35
|
Revision: 6105 http://jython.svn.sourceforge.net/jython/?rev=6105&view=rev Author: pjenvey Date: 2009-03-21 22:29:19 +0000 (Sat, 21 Mar 2009) Log Message: ----------- o reenable test_profile, tweak the output to: - <string>:0 -> <string>:1 - don't test for profiling of Java (builtin) functions: http://bugs.jython.org/issue1281 Modified Paths: -------------- trunk/jython/Lib/test/output/test_profile trunk/jython/Lib/test/regrtest.py Modified: trunk/jython/Lib/test/output/test_profile =================================================================== --- trunk/jython/Lib/test/output/test_profile 2009-03-21 22:27:42 UTC (rev 6104) +++ trunk/jython/Lib/test/output/test_profile 2009-03-21 22:29:19 UTC (rev 6105) @@ -1,15 +1,10 @@ test_profile - 127 function calls (107 primitive calls) in 1.000 CPU seconds + 98 function calls (78 primitive calls) in 1.000 CPU seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) - 4 0.000 0.000 0.000 0.000 :0(append) - 4 0.000 0.000 0.000 0.000 :0(exc_info) - 12 0.000 0.000 0.012 0.001 :0(hasattr) - 8 0.000 0.000 0.000 0.000 :0(range) - 1 0.000 0.000 0.000 0.000 :0(setprofile) - 1 0.000 0.000 1.000 1.000 <string>:1(<module>) + 1 0.000 0.000 1.000 1.000 <string>:0(<module>) 0 0.000 0.000 profile:0(profiler) 1 0.000 0.000 1.000 1.000 profile:0(testfunc()) 8 0.064 0.008 0.080 0.010 test_profile.py:103(subhelper) @@ -26,17 +21,10 @@ Ordered by: standard name Function called... -:0(append) -> -:0(exc_info) -> -:0(hasattr) -> test_profile.py:115(__getattr__)(12) 0.028 -:0(range) -> -:0(setprofile) -> -<string>:1(<module>) -> test_profile.py:30(testfunc)(1) 1.000 +<string>:0(<module>) -> test_profile.py:30(testfunc)(1) 1.000 profile:0(profiler) -> profile:0(testfunc())(1) 1.000 -profile:0(testfunc()) -> :0(setprofile)(1) 0.000 - <string>:1(<module>)(1) 1.000 -test_profile.py:103(subhelper) -> :0(range)(8) 0.000 - test_profile.py:115(__getattr__)(16) 0.028 +profile:0(testfunc()) -> <string>:0(<module>)(1) 1.000 +test_profile.py:103(subhelper) -> test_profile.py:115(__getattr__)(16) 0.028 test_profile.py:115(__getattr__) -> test_profile.py:30(testfunc) -> test_profile.py:40(factorial)(1) 0.170 test_profile.py:60(helper)(2) 0.600 @@ -46,31 +34,24 @@ test_profile.py:60(helper) -> test_profile.py:78(helper1)(4) 0.120 test_profile.py:89(helper2_indirect)(2) 0.140 test_profile.py:93(helper2)(6) 0.400 -test_profile.py:78(helper1) -> :0(append)(4) 0.000 - :0(exc_info)(4) 0.000 - :0(hasattr)(4) 0.012 +test_profile.py:78(helper1) -> test_profile.py:115(__getattr__)(4) 0.028 test_profile.py:89(helper2_indirect) -> test_profile.py:40(factorial)(2) 0.170 test_profile.py:93(helper2)(2) 0.400 -test_profile.py:93(helper2) -> :0(hasattr)(8) 0.012 - test_profile.py:103(subhelper)(8) 0.080 +test_profile.py:93(helper2) -> test_profile.py:103(subhelper)(8) 0.080 + test_profile.py:115(__getattr__)(8) 0.028 Ordered by: standard name Function was called by... -:0(append) <- test_profile.py:78(helper1)(4) 0.120 -:0(exc_info) <- test_profile.py:78(helper1)(4) 0.120 -:0(hasattr) <- test_profile.py:78(helper1)(4) 0.120 - test_profile.py:93(helper2)(8) 0.400 -:0(range) <- test_profile.py:103(subhelper)(8) 0.080 -:0(setprofile) <- profile:0(testfunc())(1) 1.000 -<string>:1(<module>) <- profile:0(testfunc())(1) 1.000 +<string>:0(<module>) <- profile:0(testfunc())(1) 1.000 profile:0(profiler) <- profile:0(testfunc()) <- profile:0(profiler)(1) 0.000 test_profile.py:103(subhelper) <- test_profile.py:93(helper2)(8) 0.400 -test_profile.py:115(__getattr__) <- :0(hasattr)(12) 0.012 +test_profile.py:115(__getattr__) <- test_profile.py:78(helper1)(4) 0.120 + test_profile.py:93(helper2)(8) 0.400 test_profile.py:103(subhelper)(16) 0.080 -test_profile.py:30(testfunc) <- <string>:1(<module>)(1) 1.000 +test_profile.py:30(testfunc) <- <string>:0(<module>)(1) 1.000 test_profile.py:40(factorial) <- test_profile.py:30(testfunc)(1) 1.000 test_profile.py:40(factorial)(20) 0.170 test_profile.py:89(helper2_indirect)(2) 0.140 Modified: trunk/jython/Lib/test/regrtest.py =================================================================== --- trunk/jython/Lib/test/regrtest.py 2009-03-21 22:27:42 UTC (rev 6104) +++ trunk/jython/Lib/test/regrtest.py 2009-03-21 22:29:19 UTC (rev 6105) @@ -1476,7 +1476,6 @@ test_multibytecodec test_multibytecodec_support test_peepholer - test_profile test_pyclbr test_stringprep test_threadsignals This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-21 22:28:01
|
Revision: 6104 http://jython.svn.sourceforge.net/jython/?rev=6104&view=rev Author: pjenvey Date: 2009-03-21 22:27:42 +0000 (Sat, 21 Mar 2009) Log Message: ----------- test_profile from: http://svn.python.org/projects/python/branches/release25-maint/Lib/test/output/test_profile@42269 Modified Paths: -------------- trunk/jython/Lib/test/output/test_profile Modified: trunk/jython/Lib/test/output/test_profile =================================================================== --- trunk/jython/Lib/test/output/test_profile 2009-03-21 21:23:22 UTC (rev 6103) +++ trunk/jython/Lib/test/output/test_profile 2009-03-21 22:27:42 UTC (rev 6104) @@ -1,17 +1,84 @@ test_profile - 53 function calls in 1.000 CPU seconds + 127 function calls (107 primitive calls) in 1.000 CPU seconds Ordered by: standard name ncalls tottime percall cumtime percall filename:lineno(function) - 1 0.000 0.000 1.000 1.000 <string>:0(<module>) + 4 0.000 0.000 0.000 0.000 :0(append) + 4 0.000 0.000 0.000 0.000 :0(exc_info) + 12 0.000 0.000 0.012 0.001 :0(hasattr) + 8 0.000 0.000 0.000 0.000 :0(range) + 1 0.000 0.000 0.000 0.000 :0(setprofile) + 1 0.000 0.000 1.000 1.000 <string>:1(<module>) 0 0.000 0.000 profile:0(profiler) 1 0.000 0.000 1.000 1.000 profile:0(testfunc()) - 1 0.400 0.400 1.000 1.000 test_profile.py:21(testfunc) - 2 0.080 0.040 0.600 0.300 test_profile.py:30(helper) - 4 0.116 0.029 0.120 0.030 test_profile.py:48(helper1) - 8 0.312 0.039 0.400 0.050 test_profile.py:56(helper2) - 8 0.064 0.008 0.080 0.010 test_profile.py:66(subhelper) - 28 0.028 0.001 0.028 0.001 test_profile.py:78(__getattr__) + 8 0.064 0.008 0.080 0.010 test_profile.py:103(subhelper) + 28 0.028 0.001 0.028 0.001 test_profile.py:115(__getattr__) + 1 0.270 0.270 1.000 1.000 test_profile.py:30(testfunc) + 23/3 0.150 0.007 0.170 0.057 test_profile.py:40(factorial) + 20 0.020 0.001 0.020 0.001 test_profile.py:53(mul) + 2 0.040 0.020 0.600 0.300 test_profile.py:60(helper) + 4 0.116 0.029 0.120 0.030 test_profile.py:78(helper1) + 2 0.000 0.000 0.140 0.070 test_profile.py:89(helper2_indirect) + 8 0.312 0.039 0.400 0.050 test_profile.py:93(helper2) + Ordered by: standard name + +Function called... +:0(append) -> +:0(exc_info) -> +:0(hasattr) -> test_profile.py:115(__getattr__)(12) 0.028 +:0(range) -> +:0(setprofile) -> +<string>:1(<module>) -> test_profile.py:30(testfunc)(1) 1.000 +profile:0(profiler) -> profile:0(testfunc())(1) 1.000 +profile:0(testfunc()) -> :0(setprofile)(1) 0.000 + <string>:1(<module>)(1) 1.000 +test_profile.py:103(subhelper) -> :0(range)(8) 0.000 + test_profile.py:115(__getattr__)(16) 0.028 +test_profile.py:115(__getattr__) -> +test_profile.py:30(testfunc) -> test_profile.py:40(factorial)(1) 0.170 + test_profile.py:60(helper)(2) 0.600 +test_profile.py:40(factorial) -> test_profile.py:40(factorial)(20) 0.170 + test_profile.py:53(mul)(20) 0.020 +test_profile.py:53(mul) -> +test_profile.py:60(helper) -> test_profile.py:78(helper1)(4) 0.120 + test_profile.py:89(helper2_indirect)(2) 0.140 + test_profile.py:93(helper2)(6) 0.400 +test_profile.py:78(helper1) -> :0(append)(4) 0.000 + :0(exc_info)(4) 0.000 + :0(hasattr)(4) 0.012 +test_profile.py:89(helper2_indirect) -> test_profile.py:40(factorial)(2) 0.170 + test_profile.py:93(helper2)(2) 0.400 +test_profile.py:93(helper2) -> :0(hasattr)(8) 0.012 + test_profile.py:103(subhelper)(8) 0.080 + + + Ordered by: standard name + +Function was called by... +:0(append) <- test_profile.py:78(helper1)(4) 0.120 +:0(exc_info) <- test_profile.py:78(helper1)(4) 0.120 +:0(hasattr) <- test_profile.py:78(helper1)(4) 0.120 + test_profile.py:93(helper2)(8) 0.400 +:0(range) <- test_profile.py:103(subhelper)(8) 0.080 +:0(setprofile) <- profile:0(testfunc())(1) 1.000 +<string>:1(<module>) <- profile:0(testfunc())(1) 1.000 +profile:0(profiler) <- +profile:0(testfunc()) <- profile:0(profiler)(1) 0.000 +test_profile.py:103(subhelper) <- test_profile.py:93(helper2)(8) 0.400 +test_profile.py:115(__getattr__) <- :0(hasattr)(12) 0.012 + test_profile.py:103(subhelper)(16) 0.080 +test_profile.py:30(testfunc) <- <string>:1(<module>)(1) 1.000 +test_profile.py:40(factorial) <- test_profile.py:30(testfunc)(1) 1.000 + test_profile.py:40(factorial)(20) 0.170 + test_profile.py:89(helper2_indirect)(2) 0.140 +test_profile.py:53(mul) <- test_profile.py:40(factorial)(20) 0.170 +test_profile.py:60(helper) <- test_profile.py:30(testfunc)(2) 1.000 +test_profile.py:78(helper1) <- test_profile.py:60(helper)(4) 0.600 +test_profile.py:89(helper2_indirect) <- test_profile.py:60(helper)(2) 0.600 +test_profile.py:93(helper2) <- test_profile.py:60(helper)(6) 0.600 + test_profile.py:89(helper2_indirect)(2) 0.140 + + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-03-21 21:23:26
|
Revision: 6103 http://jython.svn.sourceforge.net/jython/?rev=6103&view=rev Author: zyasoft Date: 2009-03-21 21:23:22 +0000 (Sat, 21 Mar 2009) Log Message: ----------- Reinstated PythonInterpreter#setErr(java.io.Writer), #setOut(java.io.Writer) (but deprecating). This uses PyFileWriter which implements a file-like interface sufficient for stdout/stderr usage. Fixes #1266 Modified Paths: -------------- trunk/jython/src/org/python/core/StdoutWrapper.java trunk/jython/src/org/python/util/PythonInterpreter.java Added Paths: ----------- trunk/jython/Lib/test/test_pythoninterpreter_jy.py trunk/jython/src/org/python/core/PyFileWriter.java Added: trunk/jython/Lib/test/test_pythoninterpreter_jy.py =================================================================== --- trunk/jython/Lib/test/test_pythoninterpreter_jy.py (rev 0) +++ trunk/jython/Lib/test/test_pythoninterpreter_jy.py 2009-03-21 21:23:22 UTC (rev 6103) @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +import java.io.StringWriter +import sys +import traceback +import unittest +import test.test_support + + +def exec_code_in_pi(function, out, err, locals=None): + """Runs code in a separate context: (thread, PySystemState, PythonInterpreter)""" + + def function_context(): + from org.python.core import Py + from org.python.util import PythonInterpreter + from org.python.core import PySystemState + + ps = PySystemState() + pi = PythonInterpreter({}, ps) + if locals: + pi.setLocals(locals) + pi.setOut(out) + pi.setErr(err) + try: + pi.exec(function.func_code) + except: + print '-'*60 + traceback.print_exc(file=sys.stdout) + print '-'*60 + + + import threading + context = threading.Thread(target=function_context) + context.start() + context.join() + + +class InterpreterTest(unittest.TestCase): + + # in these tests, note the promotion to unicode by java.io.Writer, + # because these are character-oriented streams. caveat emptor! + + def test_pi_out_unicode(self): + source_text = [ + u'Some text', + 'Plain text', + u'\u1000\u2000\u3000\u4000', + # Some language names from wikipedia + u'Català · Česky · Dansk · Deutsch · English · Español · Esperanto · Français · Bahasa Indonesia · Italiano · Magyar · Nederlands · 日本語 · Norsk (bokmål) · Polski · Português · Русский · Română · Slovenčina · Suomi · Svenska · Türkçe · Українська · Volapük · 中文', + ] + + def f(): + global text + for x in text: + print x + out = java.io.StringWriter() + err = java.io.StringWriter() + exec_code_in_pi(f, out, err, {'text': source_text}) + output_text = out.toString().splitlines() + for source, output in zip(source_text, output_text): + self.assertEquals(source, output) + + def test_pi_out(self): + def f(): + print 42 + out = java.io.StringWriter() + err = java.io.StringWriter() + exec_code_in_pi(f, out, err) + self.assertEquals(u"42\n", out.toString()) + + def test_more_output(self): + def f(): + for i in xrange(42): + print "*" * i + out = java.io.StringWriter() + err = java.io.StringWriter() + exec_code_in_pi(f, out, err) + output = out.toString().splitlines() + for i, line in enumerate(output): + self.assertEquals(line, u'*' * i) + self.assertEquals(42, len(output)) + + + +def test_main(): + test.test_support.run_unittest(InterpreterTest) + +if __name__ == "__main__": + test_main() Added: trunk/jython/src/org/python/core/PyFileWriter.java =================================================================== --- trunk/jython/src/org/python/core/PyFileWriter.java (rev 0) +++ trunk/jython/src/org/python/core/PyFileWriter.java 2009-03-21 21:23:22 UTC (rev 6103) @@ -0,0 +1,83 @@ +// A file-like object for writing to java.io.Writer objects; +// only to be used for stdout, stderr in PythonInterpreter#setOut(Writer), #setErr(Writer) +// (for backwards compatibility) +// +// no attempts to close etc at shutdown are done for this object (unlike PyFile), +// since again just for PythonInterpreter +// nor is this exposed as a type +package org.python.core; + +import java.io.Writer; +import java.io.IOException; + +public class PyFileWriter extends PyObject { + + private final Writer writer; + private boolean closed; + public boolean softspace = false; + + public PyFileWriter(Writer writer) { + this.writer = writer; + closed = false; + } + + public boolean closed() { + return closed; + } + + public void checkClosed() { + if (closed()) { + throw Py.ValueError("I/O operation on closed file"); + } + } + + public synchronized void flush() { + checkClosed(); + try { + writer.flush(); + } catch (IOException e) { + throw Py.IOError(e); + } + } + + public void close() { + try { + writer.close(); + closed = true; + } catch (IOException e) { + throw Py.IOError(e); + } + } + + public void write(PyObject o) { + if (o instanceof PyUnicode) { + write(((PyUnicode) o).string); + } else if (o instanceof PyString) { + write(((PyString) o).string); + } else { + throw Py.TypeError("write requires a string as its argument"); + } + } + + public synchronized void write(String s) { + checkClosed(); + try { + writer.write(s); + } catch (IOException e) { + throw Py.IOError(e); + } + } + + public synchronized void writelines(PyObject a) { + checkClosed(); + PyObject iter = Py.iter(a, "writelines() requires an iterable argument"); + + PyObject item = null; + while ((item = iter.__iternext__()) != null) { + if (!(item instanceof PyString)) { + throw Py.TypeError("writelines() argument must be a sequence of strings"); + } + write(item); + } + } +} Modified: trunk/jython/src/org/python/core/StdoutWrapper.java =================================================================== --- trunk/jython/src/org/python/core/StdoutWrapper.java 2009-03-20 01:16:13 UTC (rev 6102) +++ trunk/jython/src/org/python/core/StdoutWrapper.java 2009-03-21 21:23:22 UTC (rev 6103) @@ -122,6 +122,36 @@ file.softspace = false; } file.flush(); + } else if (obj instanceof PyFileWriter) { + PyFileWriter file = (PyFileWriter)obj; + if (file.softspace) { + file.write(" "); + file.softspace = false; + } + + // since we are outputting directly to a character stream, + // avoid doing an encoding + String s; + if (o instanceof PyString) { + s = ((PyString)o).string; + } else { + s = o.toString(); + } + int len = s.length(); + file.write(s); + if (o instanceof PyString) { + if (len == 0 || !Character.isWhitespace(s.charAt(len - 1)) + || s.charAt(len - 1) == ' ') { + file.softspace = space; + } + } else { + file.softspace = space; + } + if (newline) { + file.write("\n"); + file.softspace = false; + } + file.flush(); } else { PyObject ss = obj.__findattr__("softspace"); if (ss != null && ss.__nonzero__()) { Modified: trunk/jython/src/org/python/util/PythonInterpreter.java =================================================================== --- trunk/jython/src/org/python/util/PythonInterpreter.java 2009-03-20 01:16:13 UTC (rev 6102) +++ trunk/jython/src/org/python/util/PythonInterpreter.java 2009-03-21 21:23:22 UTC (rev 6103) @@ -7,6 +7,7 @@ import org.python.core.PyCode; import org.python.core.PyException; import org.python.core.PyFile; +import org.python.core.PyFileWriter; import org.python.core.PyModule; import org.python.core.PyObject; import org.python.core.PyString; @@ -90,6 +91,11 @@ systemState.stdout = outStream; } + /** @deprecated */ + public void setOut(java.io.Writer outStream) { + setOut(new PyFileWriter(outStream)); + } + /** * Set a java.io.OutputStream to use for the standard output stream * @@ -104,6 +110,11 @@ systemState.stderr = outStream; } + /** @deprecated */ + public void setErr(java.io.Writer outStream) { + setErr(new PyFileWriter(outStream)); + } + public void setErr(java.io.OutputStream outStream) { setErr(new PyFile(outStream)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-20 01:16:30
|
Revision: 6102 http://jython.svn.sourceforge.net/jython/?rev=6102&view=rev Author: pjenvey Date: 2009-03-20 01:16:13 +0000 (Fri, 20 Mar 2009) Log Message: ----------- o test_import/threadsignals fail, not skip o test_dummy_thread passes, dummy_threading is broken: http://bugs.jython.org/issue1279 Modified Paths: -------------- trunk/jython/Lib/test/regrtest.py Modified: trunk/jython/Lib/test/regrtest.py =================================================================== --- trunk/jython/Lib/test/regrtest.py 2009-03-17 19:07:37 UTC (rev 6101) +++ trunk/jython/Lib/test/regrtest.py 2009-03-20 01:16:13 UTC (rev 6102) @@ -1399,8 +1399,6 @@ test_curses test_dbm test_dl - test_dummy_thread - test_dummy_threading test_email_codecs test_fcntl test_fork1 @@ -1410,7 +1408,6 @@ test_hotshot test_imageop test_imgfile - test_import test_ioctl test_largefile test_linuxaudiodev @@ -1441,7 +1438,6 @@ test_sundry test_symtable test_tcl - test_threadsignals test_timeout test_unicode_file test_wait3 @@ -1471,9 +1467,11 @@ test_codecmaps_tw test_compiler test_dis + test_dummy_threading test_eof test_frozen test_gc + test_import test_iterlen test_multibytecodec test_multibytecodec_support @@ -1481,6 +1479,7 @@ test_profile test_pyclbr test_stringprep + test_threadsignals test_transformer test_ucn test_unicodedata This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-17 19:07:41
|
Revision: 6101 http://jython.svn.sourceforge.net/jython/?rev=6101&view=rev Author: fwierzbicki Date: 2009-03-17 19:07:37 +0000 (Tue, 17 Mar 2009) Log Message: ----------- Added NEWS item for issue1261. Modified Paths: -------------- trunk/jython/NEWS Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-03-17 19:02:03 UTC (rev 6100) +++ trunk/jython/NEWS 2009-03-17 19:07:37 UTC (rev 6101) @@ -3,6 +3,7 @@ Jython 2.5.0 rc 1 Bugs fixed (new numbering due to move to Roundup) - [ 1272 ] ASTList ClassCastException + - [ 1261 ] jython -c "import sys; sys.exit(1)" not giving correct exit code. - [ 1215 ] extra spaces in import statement break importing Jython 2.5.0 a0 - b3 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-17 19:02:22
|
Revision: 6100 http://jython.svn.sourceforge.net/jython/?rev=6100&view=rev Author: fwierzbicki Date: 2009-03-17 19:02:03 +0000 (Tue, 17 Mar 2009) Log Message: ----------- darn forgot to update NEWS. Modified Paths: -------------- trunk/jython/NEWS Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-03-17 19:00:26 UTC (rev 6099) +++ trunk/jython/NEWS 2009-03-17 19:02:03 UTC (rev 6100) @@ -2,6 +2,7 @@ Jython 2.5.0 rc 1 Bugs fixed (new numbering due to move to Roundup) + - [ 1272 ] ASTList ClassCastException - [ 1215 ] extra spaces in import statement break importing Jython 2.5.0 a0 - b3 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-17 19:00:41
|
Revision: 6099 http://jython.svn.sourceforge.net/jython/?rev=6099&view=rev Author: fwierzbicki Date: 2009-03-17 19:00:26 +0000 (Tue, 17 Mar 2009) Log Message: ----------- Applied patch from http://bugs.jython.org/issue1148 to AstList to fix ClassCastException for slices. Also merged the test included in issue1148 into test_ast_jy.py with some small changes, especially the formatting to fit with pep 8 style. Thanks Geoffrey French (MrMeanie)! Modified Paths: -------------- trunk/jython/Lib/test/test_ast_jy.py trunk/jython/src/org/python/core/AstList.java Modified: trunk/jython/Lib/test/test_ast_jy.py =================================================================== --- trunk/jython/Lib/test/test_ast_jy.py 2009-03-17 02:59:34 UTC (rev 6098) +++ trunk/jython/Lib/test/test_ast_jy.py 2009-03-17 19:00:26 UTC (rev 6099) @@ -2,25 +2,40 @@ future""" import unittest +import ast from test import test_support -from ast import PyCF_ONLY_AST +def srcExprToTree(source, kind='exec'): + return compile(source, '<module>', kind, ast.PyCF_ONLY_AST) + class TestCompile(unittest.TestCase): def test_compile_ast(self): - node = compile("1/2", '<unknown>', 'exec', PyCF_ONLY_AST) + node = srcExprToTree("1/2") compile(node, "<string>", 'exec') def test_alias_trim(self): - node = compile("import os. path", '<unknown>', 'exec', PyCF_ONLY_AST) + node = srcExprToTree("import os. path") self.assertEquals(node.body[0].names[0].name, "os.path") - node = compile("import os .path", '<unknown>', 'exec', PyCF_ONLY_AST) + node = srcExprToTree("import os .path") self.assertEquals(node.body[0].names[0].name, "os.path") - node = compile("import os . path", '<unknown>', 'exec', PyCF_ONLY_AST) + node = srcExprToTree("import os . path") self.assertEquals(node.body[0].names[0].name, "os.path") + def test_cmpop(self): + expr = srcExprToTree('a < b < c', 'eval') + compare = expr.body + self.assert_(isinstance(compare.ops[0], ast.Lt)) + self.assert_(isinstance(compare.comparators[0], ast.Name)) + self.assert_(isinstance(compare.ops[1], ast.Lt)) + self.assert_(isinstance(compare.comparators[1], ast.Name)) + self.assert_(isinstance(compare.ops[1:][0], ast.Lt)) + self.assert_(isinstance(compare.comparators[1:][0], ast.Name)) + z = zip( compare.ops[1:], compare.comparators[1:]) + self.assert_(isinstance(z[0][0], ast.Lt)) + self.assert_(isinstance(z[0][1], ast.Name)) #============================================================================== Modified: trunk/jython/src/org/python/core/AstList.java =================================================================== --- trunk/jython/src/org/python/core/AstList.java 2009-03-17 02:59:34 UTC (rev 6098) +++ trunk/jython/src/org/python/core/AstList.java 2009-03-17 19:00:26 UTC (rev 6099) @@ -376,14 +376,14 @@ List newList = data.subList(start, stop); if(step == 1) { newList = data.subList(start, stop); - return new AstList(newList); + return new AstList(newList, adapter); } int j = 0; for(int i = start; j < n; i += step) { newList.set(j, data.get(i)); j++; } - return new AstList(newList); + return new AstList(newList, adapter); } public void insert(int index, PyObject o) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-17 02:59:38
|
Revision: 6098 http://jython.svn.sourceforge.net/jython/?rev=6098&view=rev Author: pjenvey Date: 2009-03-17 02:59:34 +0000 (Tue, 17 Mar 2009) Log Message: ----------- whitespace Modified Paths: -------------- trunk/jython/src/org/python/core/util/importer.java Modified: trunk/jython/src/org/python/core/util/importer.java =================================================================== --- trunk/jython/src/org/python/core/util/importer.java 2009-03-16 23:26:18 UTC (rev 6097) +++ trunk/jython/src/org/python/core/util/importer.java 2009-03-17 02:59:34 UTC (rev 6098) @@ -74,12 +74,12 @@ private SearchOrderEntry[] makeSearchOrder(){ return new SearchOrderEntry[] { - new SearchOrderEntry(getSeparator() + "__init__$py.class", - EnumSet.of(EntryType.IS_PACKAGE, EntryType.IS_BYTECODE)), - new SearchOrderEntry(getSeparator() + "__init__.py", - EnumSet.of(EntryType.IS_PACKAGE, EntryType.IS_SOURCE)), - new SearchOrderEntry("$py.class", EnumSet.of(EntryType.IS_BYTECODE)), - new SearchOrderEntry(".py", EnumSet.of(EntryType.IS_SOURCE)),}; + new SearchOrderEntry(getSeparator() + "__init__$py.class", + EnumSet.of(EntryType.IS_PACKAGE, EntryType.IS_BYTECODE)), + new SearchOrderEntry(getSeparator() + "__init__.py", + EnumSet.of(EntryType.IS_PACKAGE, EntryType.IS_SOURCE)), + new SearchOrderEntry("$py.class", EnumSet.of(EntryType.IS_BYTECODE)), + new SearchOrderEntry(".py", EnumSet.of(EntryType.IS_SOURCE)),}; } protected final PyObject importer_find_module(String fullname, String path) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-16 23:26:39
|
Revision: 6097 http://jython.svn.sourceforge.net/jython/?rev=6097&view=rev Author: pjenvey Date: 2009-03-16 23:26:18 +0000 (Mon, 16 Mar 2009) Log Message: ----------- o re-enable test_unicode w/out the idna test o test_marshal now passes Modified Paths: -------------- trunk/jython/Lib/test/regrtest.py trunk/jython/Lib/test/test_unicode.py Modified: trunk/jython/Lib/test/regrtest.py =================================================================== --- trunk/jython/Lib/test/regrtest.py 2009-03-14 23:23:10 UTC (rev 6096) +++ trunk/jython/Lib/test/regrtest.py 2009-03-16 23:26:18 UTC (rev 6097) @@ -1475,7 +1475,6 @@ test_frozen test_gc test_iterlen - test_marshal test_multibytecodec test_multibytecodec_support test_peepholer @@ -1484,7 +1483,6 @@ test_stringprep test_transformer test_ucn - test_unicode test_unicodedata test_zipimport """, Modified: trunk/jython/Lib/test/test_unicode.py =================================================================== --- trunk/jython/Lib/test/test_unicode.py 2009-03-14 23:23:10 UTC (rev 6096) +++ trunk/jython/Lib/test/test_unicode.py 2009-03-16 23:26:18 UTC (rev 6097) @@ -712,6 +712,9 @@ self.assertEqual(x, y) def test_main(): + if test_support.is_jython: + # http://bugs.jython.org/issue1153 + del UnicodeTest.test_codecs_idna test_support.run_unittest(UnicodeTest) if __name__ == "__main__": This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-14 23:23:24
|
Revision: 6096 http://jython.svn.sourceforge.net/jython/?rev=6096&view=rev Author: pjenvey Date: 2009-03-14 23:23:10 +0000 (Sat, 14 Mar 2009) Log Message: ----------- maintain the exit code fixes #1261, test_cmd_line's test_directories Modified Paths: -------------- trunk/jython/src/shell/jython Modified: trunk/jython/src/shell/jython =================================================================== --- trunk/jython/src/shell/jython 2009-03-14 23:21:30 UTC (rev 6095) +++ trunk/jython/src/shell/jython 2009-03-14 23:23:10 UTC (rev 6096) @@ -214,6 +214,7 @@ "${JAVA_CMD[@]}" $JAVA_OPTS "${java_args[@]}" -Dpython.home="$JYTHON_HOME" \ -Dpython.executable="$PRG" org.python.util.jython $JYTHON_OPTS "$@" +JYTHON_STATUS=$? if [ -n "$profile_requested" ] ; then echo "Profiling results:" @@ -231,3 +232,5 @@ echo "JYTHON_HOME: Jython installation directory" >&2 echo "JYTHON_OPTS: default command line arguments" >&2 fi + +exit $JYTHON_STATUS This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-14 23:21:51
|
Revision: 6095 http://jython.svn.sourceforge.net/jython/?rev=6095&view=rev Author: pjenvey Date: 2009-03-14 23:21:30 +0000 (Sat, 14 Mar 2009) Log Message: ----------- o gracefully handle a System.getenv SecurityException on startup o grant more permissions needed for test_java_integration's test_nonexistent_import_with_security Modified Paths: -------------- trunk/jython/Lib/test/python_home.policy trunk/jython/src/org/python/core/PySystemState.java Modified: trunk/jython/Lib/test/python_home.policy =================================================================== --- trunk/jython/Lib/test/python_home.policy 2009-03-13 01:33:46 UTC (rev 6094) +++ trunk/jython/Lib/test/python_home.policy 2009-03-14 23:21:30 UTC (rev 6095) @@ -1,5 +1,8 @@ grant codeBase "file:${python.home}/-" { + permission java.io.FilePermission "<<ALL FILES>>", "read,write"; + permission java.lang.RuntimePermission "accessDeclaredMembers"; + permission java.lang.RuntimePermission "createClassLoader"; + permission java.lang.RuntimePermission "getProtectionDomain"; permission java.util.PropertyPermission "*", "read,write"; - permission java.io.FilePermission "<<ALL FILES>>", "read,write"; }; Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-03-13 01:33:46 UTC (rev 6094) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-03-14 23:21:30 UTC (rev 6095) @@ -400,12 +400,18 @@ } /** - * Initialize the environ dict from System.getenv. - * + * Initialize the environ dict from System.getenv. environ may be empty when the + * security policy doesn't grant us access. */ public void initEnviron() { environ = new PyDictionary(); - for (Map.Entry<String, String> entry : System.getenv().entrySet()) { + Map<String, String> env; + try { + env = System.getenv(); + } catch (SecurityException se) { + return; + } + for (Map.Entry<String, String> entry : env.entrySet()) { environ.__setitem__(Py.newString(entry.getKey()), Py.newString(entry.getValue())); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-13 02:22:33
|
Revision: 6094 http://jython.svn.sourceforge.net/jython/?rev=6094&view=rev Author: fwierzbicki Date: 2009-03-13 01:33:46 +0000 (Fri, 13 Mar 2009) Log Message: ----------- Fix for http://bugs.jython.org/issue1215: extra spaces in import statement break importing. Modified Paths: -------------- trunk/jython/Lib/test/test_ast_jy.py trunk/jython/NEWS trunk/jython/grammar/Python.g trunk/jython/src/org/python/antlr/GrammarActions.java Modified: trunk/jython/Lib/test/test_ast_jy.py =================================================================== --- trunk/jython/Lib/test/test_ast_jy.py 2009-03-11 17:13:03 UTC (rev 6093) +++ trunk/jython/Lib/test/test_ast_jy.py 2009-03-13 01:33:46 UTC (rev 6094) @@ -11,6 +11,17 @@ node = compile("1/2", '<unknown>', 'exec', PyCF_ONLY_AST) compile(node, "<string>", 'exec') + def test_alias_trim(self): + node = compile("import os. path", '<unknown>', 'exec', PyCF_ONLY_AST) + self.assertEquals(node.body[0].names[0].name, "os.path") + + node = compile("import os .path", '<unknown>', 'exec', PyCF_ONLY_AST) + self.assertEquals(node.body[0].names[0].name, "os.path") + + node = compile("import os . path", '<unknown>', 'exec', PyCF_ONLY_AST) + self.assertEquals(node.body[0].names[0].name, "os.path") + + #============================================================================== def test_main(verbose=None): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-03-11 17:13:03 UTC (rev 6093) +++ trunk/jython/NEWS 2009-03-13 01:33:46 UTC (rev 6094) @@ -1,7 +1,11 @@ Jython NEWS -Jython 2.5 +Jython 2.5.0 rc 1 Bugs fixed (new numbering due to move to Roundup) + - [ 1215 ] extra spaces in import statement break importing + +Jython 2.5.0 a0 - b3 + Bugs fixed (new numbering due to move to Roundup) - [ 1126 ] ImportError raised for Java subpackages import - [ 1111 ] keyword arguments not supported on __import__ - [ 1567212 ] Jython $py.class bytecode doesn't include the .py's mtime Modified: trunk/jython/grammar/Python.g =================================================================== --- trunk/jython/grammar/Python.g 2009-03-11 17:13:03 UTC (rev 6093) +++ trunk/jython/grammar/Python.g 2009-03-13 01:33:46 UTC (rev 6094) @@ -739,13 +739,13 @@ import_from : FROM (d+=DOT* dotted_name | d+=DOT+) IMPORT (STAR - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.text), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), actions.makeStarAlias($STAR), actions.makeLevel($d)]) | i1=import_as_names - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.text), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), actions.makeAliases($i1.atypes), actions.makeLevel($d)]) | LPAREN i2=import_as_names COMMA? RPAREN - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.text), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), actions.makeAliases($i2.atypes), actions.makeLevel($d)]) ) ; @@ -778,7 +778,7 @@ : dotted_name (AS NAME)? { - $atype = new alias($NAME, $dotted_name.text, $NAME.text); + $atype = new alias($NAME, $dotted_name.name, $NAME.text); } ; @@ -791,8 +791,10 @@ ; //dotted_name: NAME ('.' NAME)* -dotted_name - : NAME (DOT attr)* +dotted_name returns [String name] + : NAME (DOT dn+=attr)* { + $name = actions.makeDottedText($NAME, $dn); + } ; //global_stmt: 'global' NAME (',' NAME)* Modified: trunk/jython/src/org/python/antlr/GrammarActions.java =================================================================== --- trunk/jython/src/org/python/antlr/GrammarActions.java 2009-03-11 17:13:03 UTC (rev 6093) +++ trunk/jython/src/org/python/antlr/GrammarActions.java 2009-03-13 01:33:46 UTC (rev 6094) @@ -723,4 +723,17 @@ return s; } + public String makeDottedText(Token name, List<PythonTree> c) { + final String dot = "."; + if (c == null || c.isEmpty()) { + return name.getText(); + } + StringBuilder b = new StringBuilder(name.getText()); + for (PythonTree t : c) { + b.append(dot); + b.append(t.getToken().getText()); + } + return b.toString(); + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-03-11 17:13:16
|
Revision: 6093 http://jython.svn.sourceforge.net/jython/?rev=6093&view=rev Author: otmarhumbel Date: 2009-03-11 17:13:03 +0000 (Wed, 11 Mar 2009) Log Message: ----------- added --print option Modified Paths: -------------- trunk/jython/src/shell/jython.bat Modified: trunk/jython/src/shell/jython.bat =================================================================== --- trunk/jython/src/shell/jython.bat 2009-03-10 19:30:29 UTC (rev 6092) +++ trunk/jython/src/shell/jython.bat 2009-03-11 17:13:03 UTC (rev 6093) @@ -126,6 +126,11 @@ goto :nextArg ) +if ["%_CMP%"] == ["--print"] ( + set _PRINT=print + goto :nextArg +) + rem now unescape _D, _S and _Q set _CMP=%_CMP:_D="% set _CMP=%_CMP:_S='% @@ -167,7 +172,12 @@ set CLASSPATH=%_CP:"=% ) ) -%_JAVA_CMD% %_JAVA_OPTS% %_JAVA_STACK% %_BOOT_CP% -Dpython.home=%_JYTHON_HOME% -Dpython.executable="%~f0" -classpath "%CLASSPATH%" org.python.util.jython %_JYTHON_OPTS% %_JYTHON_ARGS% %_ARGS% +set _FULL_CMD=%_JAVA_CMD% %_JAVA_OPTS% %_JAVA_STACK% %_BOOT_CP% -Dpython.home=%_JYTHON_HOME% -Dpython.executable="%~f0" -classpath "%CLASSPATH%" org.python.util.jython %_JYTHON_OPTS% %_JYTHON_ARGS% %_ARGS% +if defined _PRINT ( + echo %_FULL_CMD% +) else ( + %_FULL_CMD% +) set E=%ERRORLEVEL% :cleanup @@ -177,12 +187,14 @@ set _CMP2= set _CP= set _BOOT_CP= +set _FULL_CMD= set _JAVA_CMD= set _JAVA_OPTS= set _JAVA_STACK= set _JYTHON_HOME= set _JYTHON_OPTS= set _JYTHON_ARGS= +set _PRINT= set _TRIMMED_JAVA_HOME= set _TRIMMED_JYTHON_HOME= set _TRIMMED_JYTHON_OPTS= This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |