From: <fwi...@us...> - 2009-06-22 16:39:01
|
Revision: 6494 http://jython.svn.sourceforge.net/jython/?rev=6494&view=rev Author: fwierzbicki Date: 2009-06-22 16:38:12 +0000 (Mon, 22 Jun 2009) Log Message: ----------- Upgraded to ANTLR 3.1.3 Modified Paths: -------------- trunk/jython/.classpath trunk/jython/NEWS trunk/jython/build.xml Added Paths: ----------- trunk/jython/extlibs/antlr-3.1.3.jar trunk/jython/extlibs/antlr-runtime-3.1.3.jar Removed Paths: ------------- trunk/jython/extlibs/antlr-3.1.2.jar trunk/jython/extlibs/antlr-runtime-3.1.2.jar Modified: trunk/jython/.classpath =================================================================== --- trunk/jython/.classpath 2009-06-22 08:43:07 UTC (rev 6493) +++ trunk/jython/.classpath 2009-06-22 16:38:12 UTC (rev 6494) @@ -14,7 +14,7 @@ <classpathentry kind="lib" path="extlibs/postgresql-8.3-603.jdbc4.jar"/> <classpathentry kind="lib" path="extlibs/servlet-api-2.5.jar"/> <classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/> - <classpathentry kind="lib" path="extlibs/antlr-runtime-3.1.2.jar"/> + <classpathentry kind="lib" path="extlibs/antlr-runtime-3.1.3.jar"/> <classpathentry kind="lib" path="extlibs/asm-3.1.jar"/> <classpathentry kind="lib" path="extlibs/asm-commons-3.1.jar"/> <classpathentry kind="lib" path="extlibs/constantine-0.4.jar"/> Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-06-22 08:43:07 UTC (rev 6493) +++ trunk/jython/NEWS 2009-06-22 16:38:12 UTC (rev 6494) @@ -1,5 +1,9 @@ Jython NEWS +Jython 2.5.1 + New Features + - Upgraded to ANTLR 3.1.3 + Jython 2.5.0 The same as rc4. Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-06-22 08:43:07 UTC (rev 6493) +++ trunk/jython/build.xml 2009-06-22 16:38:12 UTC (rev 6494) @@ -152,7 +152,7 @@ <pathelement path="${extlibs.dir}/mysql-connector-java-5.1.6.jar" /> <pathelement path="${extlibs.dir}/postgresql-8.3-603.jdbc4.jar" /> <pathelement path="${extlibs.dir}/antlr-2.7.7.jar" /> - <pathelement path="${extlibs.dir}/antlr-3.1.2.jar" /> + <pathelement path="${extlibs.dir}/antlr-3.1.3.jar" /> <pathelement path="${extlibs.dir}/stringtemplate-3.2.jar" /> <pathelement path="${extlibs.dir}/asm-3.1.jar" /> @@ -546,7 +546,7 @@ <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="extlibs/jarjar-0.7.jar"/> <jarjar destfile="${dist.dir}/${jython.deploy.jar}"> <zipfileset src="${dist.dir}/${jython.dev.jar}"/> - <zipfileset src="extlibs/antlr-runtime-3.1.2.jar"/> + <zipfileset src="extlibs/antlr-runtime-3.1.3.jar"/> <rule pattern="org.antlr.runtime.**" result="org.python.antlr.runtime.@1"/> <zipfileset src="extlibs/asm-3.1.jar"/> <zipfileset src="extlibs/asm-commons-3.1.jar"/> Deleted: trunk/jython/extlibs/antlr-3.1.2.jar =================================================================== (Binary files differ) Added: trunk/jython/extlibs/antlr-3.1.3.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/antlr-3.1.3.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Deleted: trunk/jython/extlibs/antlr-runtime-3.1.2.jar =================================================================== (Binary files differ) Added: trunk/jython/extlibs/antlr-runtime-3.1.3.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/antlr-runtime-3.1.3.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-06-29 02:23:58
|
Revision: 6500 http://jython.svn.sourceforge.net/jython/?rev=6500&view=rev Author: cgroves Date: 2009-06-29 02:23:57 +0000 (Mon, 29 Jun 2009) Log Message: ----------- Adding a test for bug #1381 that doesn't actually cause the problem described Modified Paths: -------------- trunk/jython/Lib/test/test_java_visibility.py Added Paths: ----------- trunk/jython/tests/java/org/python/tests/DisagreeingInterfaceOverrides.java Modified: trunk/jython/Lib/test/test_java_visibility.py =================================================================== --- trunk/jython/Lib/test/test_java_visibility.py 2009-06-23 07:50:56 UTC (rev 6499) +++ trunk/jython/Lib/test/test_java_visibility.py 2009-06-29 02:23:57 UTC (rev 6500) @@ -3,10 +3,11 @@ import subprocess import sys from test import test_support -from java.lang import Byte, Class -from java.util import ArrayList, Collections, HashMap, Observable, Observer -from org.python.tests import (Coercions, HiddenSuper, InterfaceCombination, Invisible, Matryoshka, - OnlySubclassable, OtherSubVisible, SomePyMethods, SubVisible, Visible, VisibleOverride) +from java.lang import Byte, Class, Integer +from java.util import ArrayList, Collections, HashMap, LinkedList, Observable, Observer +from org.python.tests import (Coercions, DisagreeingInterfaceOverrides, HiddenSuper, + InterfaceCombination, Invisible, Matryoshka, OnlySubclassable, OtherSubVisible, + SomePyMethods, SubVisible, Visible, VisibleOverride) from org.python.tests import VisibilityResults as Results class VisibilityTest(unittest.TestCase): @@ -155,6 +156,16 @@ synchList.add("a string") self.assertEquals("a string", synchList.remove(0)) + def test_interface_methods_merged(self): + '''Checks that implementing interfaces that use the same method name are all reachable. + + Bug #1381''' + imp = DisagreeingInterfaceOverrides.Implementation() + self.assertEquals("String", imp.call("string argument")) + self.assertEquals("int", imp.call(Integer(7))) + self.assertEquals("List", imp.call(LinkedList())) + self.assertEquals("ArrayList", imp.call(ArrayList())) + class JavaClassTest(unittest.TestCase): def test_class_methods_visible(self): self.assertFalse(HashMap.isInterface(), Added: trunk/jython/tests/java/org/python/tests/DisagreeingInterfaceOverrides.java =================================================================== --- trunk/jython/tests/java/org/python/tests/DisagreeingInterfaceOverrides.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/DisagreeingInterfaceOverrides.java 2009-06-29 02:23:57 UTC (rev 6500) @@ -0,0 +1,51 @@ +package org.python.tests; + +import java.util.ArrayList; +import java.util.List; + +/** + * Part of a test for issue #1381. It checks that Jython finds the proper overridden method when + * dealing with several interfaces. The test itself is in + * Lib/test_java_visibility.py#test_interface_methods_merged + */ +public class DisagreeingInterfaceOverrides { + + public interface StringArg { + + String call(String arg); + } + + public interface IntArg { + + String call(int arg); + } + + public interface ListArg { + + String call(List<Object> arg); + } + + public interface ArrayListArg { + + String call(List<Object> arg); + } + + public static class Implementation implements StringArg, IntArg, ListArg, ArrayListArg { + + public String call(String arg) { + return "String"; + } + + public String call(int arg) { + return "int"; + } + + public String call(List<Object> arg) { + return "List"; + } + + public String call(ArrayList<Object> arg) { + return "ArrayList"; + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-06-30 06:10:13
|
Revision: 6504 http://jython.svn.sourceforge.net/jython/?rev=6504&view=rev Author: cgroves Date: 2009-06-30 06:09:12 +0000 (Tue, 30 Jun 2009) Log Message: ----------- Add a test from Sven Reimers that actually tickles issue 1381 and fix it. Modified Paths: -------------- trunk/jython/Lib/test/test_java_visibility.py trunk/jython/src/org/python/core/PyJavaType.java Added Paths: ----------- trunk/jython/tests/java/org/python/tests/RedundantInterfaceDeclarations.java Removed Paths: ------------- trunk/jython/tests/java/org/python/tests/DisagreeingInterfaceOverrides.java Modified: trunk/jython/Lib/test/test_java_visibility.py =================================================================== --- trunk/jython/Lib/test/test_java_visibility.py 2009-06-29 06:25:28 UTC (rev 6503) +++ trunk/jython/Lib/test/test_java_visibility.py 2009-06-30 06:09:12 UTC (rev 6504) @@ -5,10 +5,11 @@ from test import test_support from java.lang import Byte, Class, Integer from java.util import ArrayList, Collections, HashMap, LinkedList, Observable, Observer -from org.python.tests import (Coercions, DisagreeingInterfaceOverrides, HiddenSuper, - InterfaceCombination, Invisible, Matryoshka, OnlySubclassable, OtherSubVisible, - SomePyMethods, SubVisible, Visible, VisibleOverride) +from org.python.tests import (Coercions, HiddenSuper, InterfaceCombination, Invisible, Matryoshka, + OnlySubclassable, OtherSubVisible, SomePyMethods, SubVisible, Visible, VisibleOverride) from org.python.tests import VisibilityResults as Results +from org.python.tests.RedundantInterfaceDeclarations import (Implementation, ExtraClass, + ExtraString, ExtraStringAndClass, ExtraClassAndString) class VisibilityTest(unittest.TestCase): def test_invisible(self): @@ -157,14 +158,14 @@ self.assertEquals("a string", synchList.remove(0)) def test_interface_methods_merged(self): - '''Checks that implementing interfaces that use the same method name are all reachable. + '''Checks that declaring an interface redundantly doesn't hide merged methods. Bug #1381''' - imp = DisagreeingInterfaceOverrides.Implementation() - self.assertEquals("String", imp.call("string argument")) - self.assertEquals("int", imp.call(Integer(7))) - self.assertEquals("List", imp.call(LinkedList())) - self.assertEquals("ArrayList", imp.call(ArrayList())) + for impl in Implementation, ExtraString, ExtraClass, ExtraStringAndClass, ExtraClassAndString: + instance = impl() + self.assertEquals("String", instance.call("string argument")) + self.assertEquals("int", instance.call(7)) + self.assertEquals("Class", instance.call(LinkedList)) class JavaClassTest(unittest.TestCase): def test_class_methods_visible(self): Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2009-06-29 06:25:28 UTC (rev 6503) +++ trunk/jython/src/org/python/core/PyJavaType.java 2009-06-30 06:09:12 UTC (rev 6504) @@ -199,6 +199,12 @@ // mro continue; } + if (baseClass != null && iface.isAssignableFrom(baseClass)) { + // Don't include redundant interfaces. If the redundant interface has methods + // that were combined with methods of the same name from other interfaces higher + // in the hierarchy, adding it here hides the forms from those interfaces. + continue; + } visibleBases.add(PyType.fromClassSkippingInners(iface, needsInners)); } if (javaProxy == Object.class) { Deleted: trunk/jython/tests/java/org/python/tests/DisagreeingInterfaceOverrides.java =================================================================== --- trunk/jython/tests/java/org/python/tests/DisagreeingInterfaceOverrides.java 2009-06-29 06:25:28 UTC (rev 6503) +++ trunk/jython/tests/java/org/python/tests/DisagreeingInterfaceOverrides.java 2009-06-30 06:09:12 UTC (rev 6504) @@ -1,51 +0,0 @@ -package org.python.tests; - -import java.util.ArrayList; -import java.util.List; - -/** - * Part of a test for issue #1381. It checks that Jython finds the proper overridden method when - * dealing with several interfaces. The test itself is in - * Lib/test_java_visibility.py#test_interface_methods_merged - */ -public class DisagreeingInterfaceOverrides { - - public interface StringArg { - - String call(String arg); - } - - public interface IntArg { - - String call(int arg); - } - - public interface ListArg { - - String call(List<Object> arg); - } - - public interface ArrayListArg { - - String call(List<Object> arg); - } - - public static class Implementation implements StringArg, IntArg, ListArg, ArrayListArg { - - public String call(String arg) { - return "String"; - } - - public String call(int arg) { - return "int"; - } - - public String call(List<Object> arg) { - return "List"; - } - - public String call(ArrayList<Object> arg) { - return "ArrayList"; - } - } -} Copied: trunk/jython/tests/java/org/python/tests/RedundantInterfaceDeclarations.java (from rev 6503, trunk/jython/tests/java/org/python/tests/DisagreeingInterfaceOverrides.java) =================================================================== --- trunk/jython/tests/java/org/python/tests/RedundantInterfaceDeclarations.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/RedundantInterfaceDeclarations.java 2009-06-30 06:09:12 UTC (rev 6504) @@ -0,0 +1,49 @@ +package org.python.tests; + +/** + * Part of a test for issue #1381. It checks that Jython finds the proper implementation of an + * interface method when dealing with classes that have redundant declarations of implementing + * interfaces. The test itself is in Lib/test_java_visibility.py#test_interface_methods_merged + */ +public class RedundantInterfaceDeclarations { + + public interface IntArg { + + String call(int arg); + } + + public interface ClassArg { + + String call(Class<?> arg); + } + + public interface StringArg extends ClassArg { + + String call(String name); + } + + public static abstract class AbstractImplementation implements StringArg, IntArg { + + public String call(Class<?> arg) { + return "Class"; + } + } + + public static class Implementation extends AbstractImplementation implements StringArg { + public String call(String name) { + return "String"; + } + + public String call(int arg) { + return "int"; + } + } + + public static class ExtraString extends Implementation implements StringArg {} + + public static class ExtraClass extends Implementation implements ClassArg {} + + public static class ExtraStringAndClass extends Implementation implements StringArg, ClassArg {} + + public static class ExtraClassAndString extends Implementation implements ClassArg, StringArg {} +} Property changes on: trunk/jython/tests/java/org/python/tests/RedundantInterfaceDeclarations.java ___________________________________________________________________ Added: svn:mergeinfo + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-07-05 18:07:54
|
Revision: 6509 http://jython.svn.sourceforge.net/jython/?rev=6509&view=rev Author: fwierzbicki Date: 2009-07-05 18:07:53 +0000 (Sun, 05 Jul 2009) Log Message: ----------- PythonPartial now has it's own lexer. Modified Paths: -------------- trunk/jython/grammar/PythonPartial.g trunk/jython/src/org/python/antlr/BaseParser.java trunk/jython/src/org/python/core/ParserFacade.java trunk/jython/tests/java/org/python/antlr/PythonPartialTester.java Modified: trunk/jython/grammar/PythonPartial.g =================================================================== --- trunk/jython/grammar/PythonPartial.g 2009-07-05 14:55:44 UTC (rev 6508) +++ trunk/jython/grammar/PythonPartial.g 2009-07-05 18:07:53 UTC (rev 6509) @@ -59,7 +59,7 @@ * */ -parser grammar PythonPartial; +grammar PythonPartial; options { tokenVocab=Python; @@ -90,6 +90,78 @@ } } +@lexer::header { +package org.python.antlr; +} + +@lexer::members { +/** Handles context-sensitive lexing of implicit line joining such as + * the case where newline is ignored in cases like this: + * a = [3, + * 4] + */ + +//For use in partial parsing. +public boolean eofWhileNested = false; +public boolean partial = false; + +int implicitLineJoiningLevel = 0; +int startPos=-1; + +//If you want to use another error recovery mechanism change this +//and the same one in the parser. +private ErrorHandler errorHandler; + + public void setErrorHandler(ErrorHandler eh) { + this.errorHandler = eh; + } + + /** + * Taken directly from antlr's Lexer.java -- needs to be re-integrated every time + * we upgrade from Antlr (need to consider a Lexer subclass, though the issue would + * remain). + */ + public Token nextToken() { + while (true) { + state.token = null; + state.channel = Token.DEFAULT_CHANNEL; + state.tokenStartCharIndex = input.index(); + state.tokenStartCharPositionInLine = input.getCharPositionInLine(); + state.tokenStartLine = input.getLine(); + state.text = null; + if ( input.LA(1)==CharStream.EOF ) { + if (implicitLineJoiningLevel > 0) { + eofWhileNested = true; + } + return Token.EOF_TOKEN; + } + try { + mTokens(); + if ( state.token==null ) { + emit(); + } + else if ( state.token==Token.SKIP_TOKEN ) { + continue; + } + return state.token; + } catch (NoViableAltException nva) { + errorHandler.reportError(this, nva); + errorHandler.recover(this, nva); // throw out current char and try again + } catch (FailedPredicateException fp) { + //XXX: added this for failed STRINGPART -- the FailedPredicateException + // hides a NoViableAltException. This should be the only + // FailedPredicateException that gets thrown by the lexer. + errorHandler.reportError(this, fp); + errorHandler.recover(this, fp); // throw out current char and try again + } catch (RecognitionException re) { + errorHandler.reportError(this, re); + // match() routine has already called recover() + } + } + } +} + + //single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE single_input @@ -934,3 +1006,318 @@ ; +AS : 'as' ; +ASSERT : 'assert' ; +BREAK : 'break' ; +CLASS : 'class' ; +CONTINUE : 'continue' ; +DEF : 'def' ; +DELETE : 'del' ; +ELIF : 'elif' ; +EXCEPT : 'except' ; +EXEC : 'exec' ; +FINALLY : 'finally' ; +FROM : 'from' ; +FOR : 'for' ; +GLOBAL : 'global' ; +IF : 'if' ; +IMPORT : 'import' ; +IN : 'in' ; +IS : 'is' ; +LAMBDA : 'lambda' ; +ORELSE : 'else' ; +PASS : 'pass' ; +PRINT : 'print' ; +RAISE : 'raise' ; +RETURN : 'return' ; +TRY : 'try' ; +WHILE : 'while' ; +WITH : 'with' ; +YIELD : 'yield' ; + +LPAREN : '(' {implicitLineJoiningLevel++;} ; + +RPAREN : ')' {implicitLineJoiningLevel--;} ; + +LBRACK : '[' {implicitLineJoiningLevel++;} ; + +RBRACK : ']' {implicitLineJoiningLevel--;} ; + +COLON : ':' ; + +COMMA : ',' ; + +SEMI : ';' ; + +PLUS : '+' ; + +MINUS : '-' ; + +STAR : '*' ; + +SLASH : '/' ; + +VBAR : '|' ; + +AMPER : '&' ; + +LESS : '<' ; + +GREATER : '>' ; + +ASSIGN : '=' ; + +PERCENT : '%' ; + +BACKQUOTE : '`' ; + +LCURLY : '{' {implicitLineJoiningLevel++;} ; + +RCURLY : '}' {implicitLineJoiningLevel--;} ; + +CIRCUMFLEX : '^' ; + +TILDE : '~' ; + +EQUAL : '==' ; + +NOTEQUAL : '!=' ; + +ALT_NOTEQUAL: '<>' ; + +LESSEQUAL : '<=' ; + +LEFTSHIFT : '<<' ; + +GREATEREQUAL : '>=' ; + +RIGHTSHIFT : '>>' ; + +PLUSEQUAL : '+=' ; + +MINUSEQUAL : '-=' ; + +DOUBLESTAR : '**' ; + +STAREQUAL : '*=' ; + +DOUBLESLASH : '//' ; + +SLASHEQUAL : '/=' ; + +VBAREQUAL : '|=' ; + +PERCENTEQUAL : '%=' ; + +AMPEREQUAL : '&=' ; + +CIRCUMFLEXEQUAL : '^=' ; + +LEFTSHIFTEQUAL : '<<=' ; + +RIGHTSHIFTEQUAL : '>>=' ; + +DOUBLESTAREQUAL : '**=' ; + +DOUBLESLASHEQUAL : '//=' ; + +DOT : '.' ; + +AT : '@' ; + +AND : 'and' ; + +OR : 'or' ; + +NOT : 'not' ; + +FLOAT + : '.' DIGITS (Exponent)? + | DIGITS '.' Exponent + | DIGITS ('.' (DIGITS (Exponent)?)? | Exponent) + ; + +LONGINT + : INT ('l'|'L') + ; + +fragment +Exponent + : ('e' | 'E') ( '+' | '-' )? DIGITS + ; + +INT : // Hex + '0' ('x' | 'X') ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' )+ + | // Octal + '0' ( '0' .. '7' )* + | '1'..'9' DIGITS* + ; + +COMPLEX + : DIGITS+ ('j'|'J') + | FLOAT ('j'|'J') + ; + +fragment +DIGITS : ( '0' .. '9' )+ ; + +NAME: ( 'a' .. 'z' | 'A' .. 'Z' | '_') + ( 'a' .. 'z' | 'A' .. 'Z' | '_' | '0' .. '9' )* + ; + +/** Match various string types. Note that greedy=false implies ''' + * should make us exit loop not continue. + */ +STRING + : ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? + ( '\'\'\'' (options {greedy=false;}:TRIAPOS)* '\'\'\'' + | '"""' (options {greedy=false;}:TRIQUOTE)* '"""' + | '"' (ESC|~('\\'|'\n'|'"'))* '"' + | '\'' (ESC|~('\\'|'\n'|'\''))* '\'' + ) { + if (state.tokenStartLine != input.getLine()) { + state.tokenStartLine = input.getLine(); + state.tokenStartCharPositionInLine = -2; + } + } + ; + +STRINGPART + : ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? + ( '\'\'\'' ~('\'\'\'')* + | '"""' ~('"""')* + ) + ; + +/** the two '"'? cause a warning -- is there a way to avoid that? */ +fragment +TRIQUOTE + : '"'? '"'? (ESC|~('\\'|'"'))+ + ; + +/** the two '\''? cause a warning -- is there a way to avoid that? */ +fragment +TRIAPOS + : '\''? '\''? (ESC|~('\\'|'\''))+ + ; + +fragment +ESC + : '\\' . + ; + +/** Consume a newline and any whitespace at start of next line + * unless the next line contains only white space, in that case + * emit a newline. + */ +CONTINUED_LINE + : '\\' ('\r')? '\n' (' '|'\t')* { $channel=HIDDEN; } + ( c1=COMMENT + | nl=NEWLINE + | + ) { + if (input.LA(1) == -1) { + emit(new CommonToken(TRAILBACKSLASH,"\\")); + } + } + ; + +/** Treat a sequence of blank lines as a single blank line. If + * nested within a (..), {..}, or [..], then ignore newlines. + * If the first newline starts in column one, they are to be ignored. + * + * Frank Wierzbicki added: Also ignore FORMFEEDS (\u000C). + */ +NEWLINE +@init { + int newlines = 0; +} + : (('\u000C')?('\r')? '\n' {newlines++; } )+ { + if ( startPos==0 || implicitLineJoiningLevel>0 ) + $channel=HIDDEN; + } + ; + +WS : {startPos>0}?=> (' '|'\t'|'\u000C')+ {$channel=HIDDEN;} + ; + +/** Grab everything before a real symbol. Then if newline, kill it + * as this is a blank line. If whitespace followed by comment, kill it + * as it's a comment on a line by itself. + * + * Ignore leading whitespace when nested in [..], (..), {..}. + */ +LEADING_WS +@init { + int spaces = 0; + int newlines = 0; +} + : {startPos==0}?=> + ( {implicitLineJoiningLevel>0}? ( ' ' | '\t' )+ {$channel=HIDDEN;} + | ( ' ' { spaces++; } + | '\t' { spaces += 8; spaces -= (spaces \% 8); } + )+ + ( ('\r')? '\n' {newlines++; } + )* { + if (input.LA(1) != -1 || newlines == 0) { + // make a string of n spaces where n is column number - 1 + char[] indentation = new char[spaces]; + for (int i=0; i<spaces; i++) { + indentation[i] = ' '; + } + CommonToken c = new CommonToken(LEADING_WS,new String(indentation)); + c.setLine(input.getLine()); + c.setCharPositionInLine(input.getCharPositionInLine()); + c.setStartIndex(input.index() - 1); + c.setStopIndex(input.index() - 1); + emit(c); + // kill trailing newline if present and then ignore + if (newlines != 0) { + if (state.token!=null) { + state.token.setChannel(HIDDEN); + } else { + $channel=HIDDEN; + } + } + } else { + // make a string of n newlines + char[] nls = new char[newlines]; + for (int i=0; i<newlines; i++) { + nls[i] = '\n'; + } + CommonToken c = new CommonToken(NEWLINE,new String(nls)); + c.setLine(input.getLine()); + c.setCharPositionInLine(input.getCharPositionInLine()); + c.setStartIndex(input.index() - 1); + c.setStopIndex(input.index() - 1); + emit(c); + } + } + ) + ; + +/** Comments not on line by themselves are turned into newlines. + + b = a # end of line comment + + or + + a = [1, # weird + 2] + + This rule is invoked directly by nextToken when the comment is in + first column or when comment is on end of nonwhitespace line. + + Only match \n here if we didn't start on left edge; let NEWLINE return that. + Kill if newlines if we live on a line by ourselves + + Consume any leading whitespace if it starts on left edge. + */ +COMMENT +@init { + $channel=HIDDEN; +} + : {startPos==0}?=> (' '|'\t')* '#' (~'\n')* '\n'+ + | '#' (~'\n')* // let NEWLINE handle \n unless char pos==0 for '#' + ; + Modified: trunk/jython/src/org/python/antlr/BaseParser.java =================================================================== --- trunk/jython/src/org/python/antlr/BaseParser.java 2009-07-05 14:55:44 UTC (rev 6508) +++ trunk/jython/src/org/python/antlr/BaseParser.java 2009-07-05 18:07:53 UTC (rev 6509) @@ -41,7 +41,18 @@ return super.nextToken(); } } - + + public static class PyPartialLexer extends PythonPartialLexer { + public PyPartialLexer(CharStream lexer) { + super(lexer); + } + + public Token nextToken() { + startPos = getCharPositionInLine(); + return super.nextToken(); + } + } + private CharStream charStream(boolean single) { return charStream; } Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2009-07-05 14:55:44 UTC (rev 6508) +++ trunk/jython/src/org/python/core/ParserFacade.java 2009-07-05 18:07:53 UTC (rev 6509) @@ -25,7 +25,8 @@ import org.python.antlr.NoCloseReaderStream; import org.python.antlr.ParseException; import org.python.antlr.PythonLexer; -import org.python.antlr.PythonPartial; +import org.python.antlr.PythonPartialLexer; +import org.python.antlr.PythonPartialParser; import org.python.antlr.PythonTokenSource; import org.python.antlr.PythonTree; import org.python.antlr.base.mod; @@ -183,16 +184,15 @@ } private static boolean validPartialSentence(BufferedReader bufreader, CompileMode kind, String filename) { - PythonLexer lexer = null; + PythonPartialLexer lexer = null; try { bufreader.reset(); CharStream cs = new NoCloseReaderStream(bufreader); - lexer = new BaseParser.PyLexer(cs); - lexer.partial = true; + lexer = new BaseParser.PyPartialLexer(cs); CommonTokenStream tokens = new CommonTokenStream(lexer); PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename); tokens = new CommonTokenStream(indentedSource); - PythonPartial parser = new PythonPartial(tokens); + PythonPartialParser parser = new PythonPartialParser(tokens); switch (kind) { case single: parser.single_input(); Modified: trunk/jython/tests/java/org/python/antlr/PythonPartialTester.java =================================================================== --- trunk/jython/tests/java/org/python/antlr/PythonPartialTester.java 2009-07-05 14:55:44 UTC (rev 6508) +++ trunk/jython/tests/java/org/python/antlr/PythonPartialTester.java 2009-07-05 18:07:53 UTC (rev 6509) @@ -14,12 +14,12 @@ try { PythonTree result = null; CharStream input = new ANTLRFileStream(args[0]); - PythonLexer lexer = new BaseParser.PyLexer(input); + PythonPartialLexer lexer = new BaseParser.PyPartialLexer(input); CommonTokenStream tokens = new CommonTokenStream(lexer); //PythonTokenSource indentedSource = new PythonTokenSource(tokens); PythonTokenSource indentedSource = new PythonTokenSource(tokens, "<test>"); tokens = new CommonTokenStream(indentedSource); - PythonPartial parser = new PythonPartial(tokens); + PythonPartialParser parser = new PythonPartialParser(tokens); parser.single_input(); System.out.println("SUCCEED"); } catch (ParseException e) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-07-06 13:47:23
|
Revision: 6512 http://jython.svn.sourceforge.net/jython/?rev=6512&view=rev Author: fwierzbicki Date: 2009-07-06 13:47:19 +0000 (Mon, 06 Jul 2009) Log Message: ----------- Fix for http://bugs.jython.org/issue1365 "continuation lines fail in interactive interpreter". Modified Paths: -------------- trunk/jython/NEWS trunk/jython/grammar/PythonPartial.g Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-07-05 22:58:57 UTC (rev 6511) +++ trunk/jython/NEWS 2009-07-06 13:47:19 UTC (rev 6512) @@ -5,6 +5,7 @@ - Upgraded to ANTLR 3.1.3 - [ 1859477 ] Dynamically loaded ServletFilters like PyServlet Bugs Fixed + - [ 1365 ] continuation lines fail in interactive interpreter - [ 1377 ] Event names shadowed by a field name on Java types leads to a NPE - [ 1381 ] Redundant declarations of interface implementation hides overriden methods Modified: trunk/jython/grammar/PythonPartial.g =================================================================== --- trunk/jython/grammar/PythonPartial.g 2009-07-05 22:58:57 UTC (rev 6511) +++ trunk/jython/grammar/PythonPartial.g 2009-07-06 13:47:19 UTC (rev 6512) @@ -1047,6 +1047,8 @@ : ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? ( '\'\'\'' ~('\'\'\'')* | '"""' ~('"""')* + | '"' (ESC|~('\\'|'\n'|'"'))* CONTINUED_LINE + | '\'' (ESC|~('\\'|'\n'|'\''))* CONTINUED_LINE ) ; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-07-06 16:31:41
|
Revision: 6514 http://jython.svn.sourceforge.net/jython/?rev=6514&view=rev Author: fwierzbicki Date: 2009-07-06 16:31:40 +0000 (Mon, 06 Jul 2009) Log Message: ----------- Tightened interactive parse of partial strings. Two of the commented out tests for test_codeop now pass. Unfortunately one new test fails, but it is less serious than the two that are now fixed, so commented it out for now. Modified Paths: -------------- trunk/jython/Lib/test/test_codeop.py trunk/jython/grammar/PythonPartial.g Modified: trunk/jython/Lib/test/test_codeop.py =================================================================== --- trunk/jython/Lib/test/test_codeop.py 2009-07-06 14:15:32 UTC (rev 6513) +++ trunk/jython/Lib/test/test_codeop.py 2009-07-06 16:31:40 UTC (rev 6514) @@ -138,7 +138,7 @@ ai("\n\ndef x():\n pass") ai("a = 9+ \\") - #ai("a = 'a\\") + ai("a = 'a\\") ai("a = '''xy") ai("","eval") @@ -147,7 +147,7 @@ ai("(\n\n\n","eval") ai("(9+","eval") ai("9+ \\","eval") - #ai("lambda z: \\","eval") + ai("lambda z: \\","eval") #Did not work in Jython 2.5rc2 see first issue in # http://bugs.jython.org/issue1354 @@ -170,7 +170,7 @@ #ai("a = 9+ \\\n") ai("a = 'a\\ ") - ai("a = 'a\\\n") + #ai("a = 'a\\\n") ai("a = 1","eval") #ai("a = (","eval") Modified: trunk/jython/grammar/PythonPartial.g =================================================================== --- trunk/jython/grammar/PythonPartial.g 2009-07-06 14:15:32 UTC (rev 6513) +++ trunk/jython/grammar/PythonPartial.g 2009-07-06 16:31:40 UTC (rev 6514) @@ -718,7 +718,8 @@ | FLOAT | COMPLEX | (STRING)+ - | STRINGPART + | TRISTRINGPART + | STRINGPART TRAILBACKSLASH ; //listmaker: test ( list_for | (',' test)* [','] ) @@ -1043,15 +1044,21 @@ } ; -STRINGPART +TRISTRINGPART : ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? ( '\'\'\'' ~('\'\'\'')* | '"""' ~('"""')* - | '"' (ESC|~('\\'|'\n'|'"'))* CONTINUED_LINE + ) + ; + +STRINGPART + : ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? + ( '"' (ESC|~('\\'|'\n'|'"'))* CONTINUED_LINE | '\'' (ESC|~('\\'|'\n'|'\''))* CONTINUED_LINE ) ; + /** the two '"'? cause a warning -- is there a way to avoid that? */ fragment TRIQUOTE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-07-07 03:41:55
|
Revision: 6517 http://jython.svn.sourceforge.net/jython/?rev=6517&view=rev Author: pjenvey Date: 2009-07-07 03:41:42 +0000 (Tue, 07 Jul 2009) Log Message: ----------- convert unicode hashlib input to str via defaultencoding fixes #1189 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/modules/_hashlib.java Added Paths: ----------- trunk/jython/Lib/test/test_hashlib_jy.py Added: trunk/jython/Lib/test/test_hashlib_jy.py =================================================================== --- trunk/jython/Lib/test/test_hashlib_jy.py (rev 0) +++ trunk/jython/Lib/test/test_hashlib_jy.py 2009-07-07 03:41:42 UTC (rev 6517) @@ -0,0 +1,23 @@ +# encoding: utf-8 +"""Misc hashlib tests + +Made for Jython. +""" +import hashlib +import unittest +from test import test_support + +class HashlibTestCase(unittest.TestCase): + + def test_unicode(self): + self.assertEqual(hashlib.md5(u'foo').hexdigest(), + 'acbd18db4cc2f85cedef654fccc4a4d8') + self.assertRaises(UnicodeEncodeError, hashlib.md5, u'Gráin amháiñ') + + +def test_main(): + test_support.run_unittest(HashlibTestCase) + + +if __name__ == '__main__': + test_main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-07-07 02:24:24 UTC (rev 6516) +++ trunk/jython/NEWS 2009-07-07 03:41:42 UTC (rev 6517) @@ -9,6 +9,7 @@ - [ 1365 ] continuation lines fail in interactive interpreter - [ 1377 ] Event names shadowed by a field name on Java types leads to a NPE - [ 1381 ] Redundant declarations of interface implementation hides overriden methods + - [ 1189 ] MD5 hash is incorrectly calculated when string contains non-latin chars and using python md5 lib Jython 2.5.0 The same as rc4. Modified: trunk/jython/src/org/python/modules/_hashlib.java =================================================================== --- trunk/jython/src/org/python/modules/_hashlib.java 2009-07-07 02:24:24 UTC (rev 6516) +++ trunk/jython/src/org/python/modules/_hashlib.java 2009-07-07 03:41:42 UTC (rev 6517) @@ -7,10 +7,11 @@ import java.util.Map; import org.python.core.ClassDictInit; +import org.python.core.Py; import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyType; -import org.python.core.Py; +import org.python.core.PyUnicode; import org.python.core.util.StringUtil; import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; @@ -105,7 +106,7 @@ public static final PyType TYPE = PyType.fromClass(Hash.class); - /** The hash algorithm name */ + /** The hash algorithm name. */ @ExposedGet public String name; @@ -121,14 +122,6 @@ put("sha-512", 128); }}; - private static final MessageDigest getDigest(String name) { - try { - return MessageDigest.getInstance(name); - } catch (NoSuchAlgorithmException nsae) { - throw Py.ValueError("unsupported hash type"); - } - } - public Hash(String name) { this(name, getDigest(name)); } @@ -139,6 +132,14 @@ this.digest = digest; } + private static final MessageDigest getDigest(String name) { + try { + return MessageDigest.getInstance(name); + } catch (NoSuchAlgorithmException nsae) { + throw Py.ValueError("unsupported hash type"); + } + } + /** * Clone the underlying MessageDigest. * @@ -171,6 +172,9 @@ throw Py.TypeError("update() argument 1 must be string or read-only buffer, not " + obj.getType().fastGetName()); } + if (obj instanceof PyUnicode) { + obj = obj.__str__(); + } byte[] bytes = ((PyString)obj).toBytes(); digest.update(bytes); } @@ -232,6 +236,7 @@ return Py.newInteger(size); } + @Override public String toString() { return String.format("<%s HASH object @ %s>", name, Py.idstr(this)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-07-07 21:13:07
|
Revision: 6525 http://jython.svn.sourceforge.net/jython/?rev=6525&view=rev Author: amak Date: 2009-07-07 21:13:06 +0000 (Tue, 07 Jul 2009) Log Message: ----------- Javadoc corrections. Modified Paths: -------------- trunk/jython/build.xml trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-07-07 19:31:47 UTC (rev 6524) +++ trunk/jython/build.xml 2009-07-07 21:13:06 UTC (rev 6525) @@ -626,7 +626,7 @@ source="${jdk.source.version}" public="true" breakiterator="yes" - packagenames="org.python.core, org.python.util, com.ziclix.python.sql" + packagenames="org.python.core, org.python.util, com.ziclix.python.sql, com.xhaus.modjy" windowtitle="Jython API documentation" bottom="<a href='http://www.jython.org' target='_top'>Jython homepage</a>" > Modified: trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java =================================================================== --- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-07-07 19:31:47 UTC (rev 6524) +++ trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-07-07 21:13:06 UTC (rev 6525) @@ -54,9 +54,11 @@ protected HttpServlet modjyServlet; /** - * Read configuration 1. Both context and servlet parameters are included in the set, so that + * Read configuration + * 1. Both context and servlet parameters are included in the set, so that * the definition of some parameters (e.g python.*) can be shared between multiple WSGI - * servlets. 2. servlet params take precedence over context parameters + * servlets. + * 2. servlet params take precedence over context parameters */ protected Properties readConfiguration() { Properties props = new Properties(); @@ -77,8 +79,11 @@ } /** - * Initialise the modjy servlet. 1. Read the configuration 2. Initialise the jython runtime 3. - * Setup, in relation to the J2EE servlet environment 4. Create the jython-implemented servlet + * Initialise the modjy servlet. + * 1. Read the configuration + * 2. Initialise the jython runtime + * 3. Setup, in relation to the J2EE servlet environment + * 4. Create the jython-implemented servlet * 5. Initialise the jython-implemented servlet */ @Override @@ -110,9 +115,9 @@ /** * Actually service the incoming request. Simply delegate to the jython servlet. * - * @param request + * @param req * - The incoming HttpServletRequest - * @param response + * @param resp * - The outgoing HttpServletResponse */ @Override @@ -131,8 +136,6 @@ * - The properties from which config options are found * @param systemState * - The PySystemState corresponding to the interpreter servicing requests - * @returns A String giving the path to the modjy.jar file (which is used only for error - * reporting) */ protected void setupEnvironment(PythonInterpreter interp, Properties props, @@ -144,7 +147,7 @@ * Do all processing in relation to the lib-python subdirectory of WEB-INF * * @param interp - * - The PythinInterpreter used to service requests + * - The PythonInterpreter used to service requests * @param systemState * - The PySystemState whose path should be updated */ @@ -167,6 +170,8 @@ /** * Process an individual file .pth file in the lib-python directory * + * @param interp + * - The PythonInterpreter which will execute imports * @param systemState * - The PySystemState whose path should be updated * @param pythonLibPath This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-07-11 06:47:51
|
Revision: 6527 http://jython.svn.sourceforge.net/jython/?rev=6527&view=rev Author: zyasoft Date: 2009-07-11 06:47:49 +0000 (Sat, 11 Jul 2009) Log Message: ----------- Added the ContextManager interface and supporting code to enable context mgmt through the with-statement to be efficiently inlined by the JVM. The ContextManager interface allows for direct calls via invokeinterface of __enter__ and __exit__ instead of requiring getattr. ContextGuard is used to wrap managers that don't support this Java interface. threading.Lock (=RLock) and Condition are now written in Java for performance and support the new ContextManager protocol. This addresses some of the performance issues that Tobias blogged on http://journal.thobe.org/2009/06/performance-of-synchronization.html Bumped bytecode magic. Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/Lib/threading.py trunk/jython/src/org/python/compiler/CodeCompiler.java trunk/jython/src/org/python/core/imp.java trunk/jython/src/org/python/modules/Setup.java trunk/jython/src/org/python/modules/_collections/Collections.java trunk/jython/src/org/python/modules/_collections/PyDeque.java Added Paths: ----------- trunk/jython/src/org/python/core/ContextGuard.java trunk/jython/src/org/python/core/ContextManager.java trunk/jython/src/org/python/modules/_threading/ trunk/jython/src/org/python/modules/_threading/Condition.java trunk/jython/src/org/python/modules/_threading/Lock.java trunk/jython/src/org/python/modules/_threading/_threading.java Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2009-07-09 01:47:52 UTC (rev 6526) +++ trunk/jython/CoreExposed.includes 2009-07-11 06:47:49 UTC (rev 6527) @@ -41,25 +41,27 @@ org/python/core/PyType.class org/python/core/PyUnicode.class org/python/core/PyXRange.class +org/python/modules/PyStruct.class +org/python/modules/PyTeeIterator.class org/python/modules/_codecs$EncodingMap.class +org/python/modules/_collections/PyDefaultDict.class +org/python/modules/_collections/PyDeque.class org/python/modules/_csv/PyDialect.class org/python/modules/_csv/PyReader.class org/python/modules/_csv/PyWriter.class org/python/modules/_functools/PyPartial.class +org/python/modules/_hashlib$Hash.class +org/python/modules/_threading/Condition.class +org/python/modules/_threading/Lock.class org/python/modules/_weakref/CallableProxyType.class +org/python/modules/_weakref/ProxyType.class org/python/modules/_weakref/ReferenceType.class -org/python/modules/_weakref/ProxyType.class -org/python/modules/_hashlib$Hash.class -org/python/modules/_collections/PyDefaultDict.class -org/python/modules/_collections/PyDeque.class org/python/modules/operator$PyAttrGetter.class org/python/modules/operator$PyItemGetter.class org/python/modules/random/PyRandom.class org/python/modules/thread/PyLocal.class org/python/modules/time/PyTimeTuple.class org/python/modules/zipimport/zipimporter.class -org/python/modules/PyStruct.class -org/python/modules/PyTeeIterator.class org/python/antlr/AST.class org/python/antlr/ast/alias.class org/python/antlr/ast/arguments.class Modified: trunk/jython/Lib/threading.py =================================================================== --- trunk/jython/Lib/threading.py 2009-07-09 01:47:52 UTC (rev 6526) +++ trunk/jython/Lib/threading.py 2009-07-11 06:47:49 UTC (rev 6527) @@ -5,6 +5,7 @@ from org.python.util import jython from thread import _newFunctionThread from thread import _local as local +from _threading import Lock, RLock, Condition import java.lang.Thread import weakref @@ -55,78 +56,7 @@ global _trace_hook _trace_hook = func -def RLock(*args, **kwargs): - return _RLock(*args, **kwargs) -class _RLock(object): - def __init__(self): - self._lock = ReentrantLock() - self.__owner = None - - def acquire(self, blocking=1): - if blocking: - self._lock.lock() - self.__owner = currentThread() - return True - else: - return self._lock.tryLock() - - def __enter__(self): - self.acquire() - return self - - def release(self): - assert self._lock.isHeldByCurrentThread(), \ - "release() of un-acquire()d lock" - self.__owner = None - self._lock.unlock() - - def __exit__(self, t, v, tb): - self.release() - - def locked(self): - return self._lock.isLocked() - - def _is_owned(self): - return self._lock.isHeldByCurrentThread() - -Lock = _RLock - -class Condition(object): - def __init__(self, lock=None): - if lock is None: - lock = RLock() - self._lock = lock - self._condition = lock._lock.newCondition() - - def acquire(self): - return self._lock.acquire() - - def __enter__(self): - self.acquire() - return self - - def release(self): - return self._lock.release() - - def __exit__(self, t, v, tb): - self.release() - - def wait(self, timeout=None): - if timeout: - return self._condition.awaitNanos(int(timeout * 1e9)) - else: - return self._condition.await() - - def notify(self): - return self._condition.signal() - - def notifyAll(self): - return self._condition.signalAll() - - def _is_owned(self): - return self._lock._lock.isHeldByCurrentThread() - class Semaphore(object): def __init__(self, value=1): if value < 0: Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-09 01:47:52 UTC (rev 6526) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -72,6 +72,8 @@ import org.python.antlr.base.mod; import org.python.antlr.base.stmt; import org.python.core.CompilerFlags; +import org.python.core.ContextGuard; +import org.python.core.ContextManager; import org.python.core.PyComplex; import org.python.core.PyFloat; import org.python.core.PyInteger; @@ -85,6 +87,7 @@ import org.objectweb.asm.Type; import org.objectweb.asm.commons.Method; + public class CodeCompiler extends Visitor implements Opcodes, ClassConstants //, PythonGrammarTreeConstants { @@ -324,10 +327,7 @@ public int makeArray(java.util.List<? extends PythonTree> nodes) throws Exception { // XXX: This should produce an array on the stack (if possible) instead of a local - // the caller is responsible for freeing. All callers are incorrectly freeing the - // array reference -- they do call freeLocal, but without nullifying the reference - // in the local. This is causing short term memory leaks - // (e.g. test_weakref.test_getweakrefs) + // the caller is responsible for freeing. int n; if (nodes == null) @@ -2276,24 +2276,24 @@ final Label label_catch = new Label(); final Label label_end = new Label(); - final Method getattr = Method.getMethod("org.python.core.PyObject __getattr__ (String)"); - final Method call = Method.getMethod("org.python.core.PyObject __call__ (org.python.core.ThreadState)"); - final Method call3 = Method.getMethod("org.python.core.PyObject __call__ (org.python.core.ThreadState,org.python.core.PyObject,org.python.core.PyObject,org.python.core.PyObject)"); + final Method contextGuard_getManager = Method.getMethod("org.python.core.ContextManager getManager (org.python.core.PyObject)"); + final Method __enter__ = Method.getMethod("org.python.core.PyObject __enter__ (org.python.core.ThreadState)"); + final Method __exit__ = Method.getMethod("boolean __exit__ (org.python.core.ThreadState,org.python.core.PyObject,org.python.core.PyObject,org.python.core.PyObject)"); // mgr = (EXPR) visit(node.getInternalContext_expr()); + + // wrap the manager with the ContextGuard (or get it directly if it supports the ContextManager interface) + code.invokestatic(Type.getType(ContextGuard.class).getInternalName(), contextGuard_getManager.getName(), contextGuard_getManager.getDescriptor()); code.dup(); - code.ldc("__exit__"); - code.invokevirtual(Type.getType(PyObject.class).getInternalName(), getattr.getName(), getattr.getDescriptor()); - final int __exit__ = code.getLocal("org/python/core/PyObject"); - code.astore(__exit__); + final int mgr_tmp = code.getLocal(Type.getType(ContextManager.class).getInternalName()); + code.astore(mgr_tmp); + // value = mgr.__enter__() - code.ldc("__enter__"); - code.invokevirtual(Type.getType(PyObject.class).getInternalName(), getattr.getName(), getattr.getDescriptor()); loadThreadState(); - code.invokevirtual(Type.getType(PyObject.class).getInternalName(), call.getName(), call.getDescriptor()); + code.invokeinterface(Type.getType(ContextManager.class).getInternalName(), __enter__.getName(), __enter__.getDescriptor()); int value_tmp = code.getLocal("org/python/core/PyObject"); code.astore(value_tmp); @@ -2311,13 +2311,12 @@ @Override public void finalBody(CodeCompiler compiler) throws Exception { - compiler.code.aload(__exit__); + compiler.code.aload(mgr_tmp); loadThreadState(); compiler.getNone(); compiler.code.dup(); compiler.code.dup(); - compiler.code.invokevirtual(Type.getType(PyObject.class).getInternalName(), - call3.getName(), call3.getDescriptor()); + compiler.code.invokeinterface(Type.getType(ContextManager.class).getInternalName(), __exit__.getName(), __exit__.getDescriptor()); compiler.code.pop(); } }; @@ -2364,7 +2363,7 @@ // # The exceptional case is handled here // exc = False # implicit // if not exit(*sys.exc_info()): - code.aload(__exit__); + code.aload(mgr_tmp); loadThreadState(); code.aload(ts_tmp); code.getfield("org/python/core/PyException", "type", $pyObj); @@ -2374,8 +2373,7 @@ code.freeLocal(ts_tmp); code.getfield("org/python/core/PyException", "traceback", "Lorg/python/core/PyTraceback;"); code.checkcast("org/python/core/PyObject"); - code.invokevirtual(Type.getType(PyObject.class).getInternalName(), call3.getName(), call3.getDescriptor()); - code.invokevirtual("org/python/core/PyObject", "__nonzero__", "()Z"); + code.invokeinterface(Type.getType(ContextManager.class).getInternalName(), __exit__.getName(), __exit__.getDescriptor()); code.ifne(label_end); // raise // # The exception is swallowed if exit() returns true @@ -2384,7 +2382,7 @@ code.athrow(); code.label(label_end); - code.freeLocal(__exit__); + code.freeLocal(mgr_tmp); handler.addExceptionHandlers(label_catch); return null; Added: trunk/jython/src/org/python/core/ContextGuard.java =================================================================== --- trunk/jython/src/org/python/core/ContextGuard.java (rev 0) +++ trunk/jython/src/org/python/core/ContextGuard.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -0,0 +1,33 @@ +package org.python.core; + +/** Straightens the call path for some common cases + */ + +// XXX - add support for generators in conjunction w/ contextlib.contextmanager + +public class ContextGuard implements ContextManager { + + private final PyObject __enter__method; + private final PyObject __exit__method; + + private ContextGuard(PyObject manager) { + __enter__method = manager.__getattr__("__enter__"); + __exit__method = manager.__getattr__("__exit__"); + } + + public PyObject __enter__(ThreadState ts) { + return __enter__method.__call__(ts); + } + + public boolean __exit__(ThreadState ts, PyObject type, PyObject value, PyObject traceback) { + return __exit__method.__call__(ts, type, value, traceback).__nonzero__(); + } + + public static ContextManager getManager(PyObject manager) { + if (manager instanceof ContextManager) { + return (ContextManager) manager; + } else { + return new ContextGuard(manager); + } + } +} Added: trunk/jython/src/org/python/core/ContextManager.java =================================================================== --- trunk/jython/src/org/python/core/ContextManager.java (rev 0) +++ trunk/jython/src/org/python/core/ContextManager.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -0,0 +1,11 @@ +package org.python.core; + +/** A <code>PyObject</code> that provides <code>__enter__</code> and <code>__exit__</code> methods for use in the with-statement. + * + * Implementing context managers can then be potentially inlined by the JVM. + */ + +public interface ContextManager { + public PyObject __enter__(ThreadState ts); + public boolean __exit__(ThreadState ts, PyObject type, PyObject value, PyObject traceback); +} Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2009-07-09 01:47:52 UTC (rev 6526) +++ trunk/jython/src/org/python/core/imp.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -20,7 +20,7 @@ private static final String UNKNOWN_SOURCEFILE = "<unknown>"; - private static final int APIVersion = 23; + private static final int APIVersion = 24; public static final int NO_MTIME = -1; Modified: trunk/jython/src/org/python/modules/Setup.java =================================================================== --- trunk/jython/src/org/python/modules/Setup.java 2009-07-09 01:47:52 UTC (rev 6526) +++ trunk/jython/src/org/python/modules/Setup.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -55,6 +55,7 @@ "_csv:org.python.modules._csv._csv", "_systemrestart", "_ast:org.python.antlr.ast.AstModule", - "_marshal" + "_marshal", + "_threading:org.python.modules._threading._threading" }; } Modified: trunk/jython/src/org/python/modules/_collections/Collections.java =================================================================== --- trunk/jython/src/org/python/modules/_collections/Collections.java 2009-07-09 01:47:52 UTC (rev 6526) +++ trunk/jython/src/org/python/modules/_collections/Collections.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -1,7 +1,6 @@ package org.python.modules._collections; import org.python.core.ClassDictInit; -import org.python.core.PyType; import org.python.core.PyObject; /** Modified: trunk/jython/src/org/python/modules/_collections/PyDeque.java =================================================================== --- trunk/jython/src/org/python/modules/_collections/PyDeque.java 2009-07-09 01:47:52 UTC (rev 6526) +++ trunk/jython/src/org/python/modules/_collections/PyDeque.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -2,19 +2,11 @@ import org.python.core.PyIterator; import org.python.core.PyObject; -import org.python.core.PySequenceIter; import org.python.core.PyTuple; import org.python.core.PyType; import org.python.core.Py; import org.python.core.PyException; -import org.python.core.PyInteger; -import org.python.core.PyLong; -import org.python.core.PyNewWrapper; -import org.python.core.PyMethodDescr; import org.python.core.PyBuiltinCallable; -import org.python.core.PyBuiltinMethod; -import org.python.core.PyBuiltinMethodNarrow; -import org.python.core.PyString; import org.python.core.ThreadState; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; Added: trunk/jython/src/org/python/modules/_threading/Condition.java =================================================================== --- trunk/jython/src/org/python/modules/_threading/Condition.java (rev 0) +++ trunk/jython/src/org/python/modules/_threading/Condition.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -0,0 +1,120 @@ +package org.python.modules._threading; + +import org.python.core.ContextManager; +import org.python.core.Py; +import org.python.core.PyNewWrapper; +import org.python.core.PyObject; +import org.python.core.PyType; +import org.python.core.ThreadState; +import org.python.expose.ExposedType; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; + +@ExposedType(name = "_threading.Condition") +public class Condition extends PyObject implements ContextManager { + + public static final PyType TYPE = PyType.fromClass(Condition.class); + private final Lock _lock; + private final java.util.concurrent.locks.Condition _condition; + + public Condition() { + this(new Lock()); + } + + public Condition(Lock lock) { + _lock = lock; + _condition = lock._lock.newCondition(); + } + + @ExposedNew + final static PyObject Condition___new__ (PyNewWrapper new_, boolean init, + PyType subtype, PyObject[] args, String[] keywords) { + final int nargs = args.length; + if (nargs == 1) { + return new Condition((Lock)args[0]); + } + return new Condition(); + } + + public boolean acquire() { + return Condition_acquire(); + } + + @ExposedMethod + final boolean Condition_acquire() { + return _lock.acquire(); + } + + public PyObject __enter__(ThreadState ts) { + _lock.acquire(); + return this; + } + + @ExposedMethod + final PyObject Condition___enter__() { + Condition_acquire(); + return this; + } + + public void release() { + Condition_release(); + } + + @ExposedMethod + final void Condition_release() { + _lock.release(); + } + + public boolean __exit__(ThreadState ts, PyObject type, PyObject value, PyObject traceback) { + _lock.release(); + return false; + } + + @ExposedMethod + final boolean Condition___exit__(PyObject type, PyObject value, PyObject traceback) { + Condition_release(); + return false; + } + + public void wait$(PyObject timeout) throws InterruptedException { + Condition_wait(timeout); + } + + @ExposedMethod(defaults = "Py.None") + final void Condition_wait(PyObject timeout) throws InterruptedException { + if (timeout == Py.None) { + _condition.await(); + } else { + long nanos = (long) (timeout.__float__().asDouble() * 1e9); + _condition.awaitNanos(nanos); + } + } + + public void notify$() { + Condition_notify(); + } + + @ExposedMethod + final void Condition_notify() { + _condition.signal(); + } + + public void notifyAll$() { + Condition_notifyAll(); + } + + @ExposedMethod + final void Condition_notifyAll() { + _condition.signalAll(); + } + + public boolean _is_owned() { + return Condition__is_owned(); + } + + @ExposedMethod + final boolean Condition__is_owned() { + return _lock._lock.isHeldByCurrentThread(); + } +} + Added: trunk/jython/src/org/python/modules/_threading/Lock.java =================================================================== --- trunk/jython/src/org/python/modules/_threading/Lock.java (rev 0) +++ trunk/jython/src/org/python/modules/_threading/Lock.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -0,0 +1,101 @@ +package org.python.modules._threading; + +import java.util.concurrent.locks.ReentrantLock; +import org.python.core.ContextManager; +import org.python.core.Py; +import org.python.core.PyNewWrapper; +import org.python.core.PyObject; +import org.python.core.PyType; +import org.python.core.ThreadState; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedType; + +@ExposedType(name = "_threading.Lock") +public class Lock extends PyObject implements ContextManager { + + public static final PyType TYPE = PyType.fromClass(Lock.class); + final ReentrantLock _lock; + + public Lock() { + _lock = new ReentrantLock(); + } + + @ExposedNew + final static PyObject Lock___new__ (PyNewWrapper new_, boolean init, + PyType subtype, PyObject[] args, String[] keywords) { + final int nargs = args.length; + return new Lock(); + } + + + @ExposedMethod(defaults = "true") + final boolean Lock_acquire(boolean blocking) { + if (blocking) { + _lock.lock(); + return true; + } else { + return _lock.tryLock(); + } + } + + public boolean acquire() { + return Lock_acquire(true); + } + + public boolean acquire(boolean blocking) { + return Lock_acquire(blocking); + } + + @ExposedMethod + final PyObject Lock___enter__() { + _lock.lock(); + return this; + } + + public PyObject __enter__(ThreadState ts) { + _lock.lock(); + return this; + } + + @ExposedMethod + final void Lock_release() { + if (!_lock.isHeldByCurrentThread()) { + throw Py.AssertionError("release() of un-acquire()d lock"); + } + _lock.unlock(); + } + + public void release() { + Lock_release(); + } + + @ExposedMethod + final boolean Lock___exit__(PyObject type, PyObject value, PyObject traceback) { + _lock.unlock(); + return false; + } + + public boolean __exit__(ThreadState ts, PyObject type, PyObject value, PyObject traceback) { + _lock.unlock(); + return false; + } + + @ExposedMethod + final boolean Lock_locked() { + return _lock.isLocked(); + } + + public boolean locked() { + return Lock_locked(); + } + + @ExposedMethod + final boolean Lock__is_owned() { + return _lock.isHeldByCurrentThread(); + } + + public boolean _is_owned() { + return Lock__is_owned(); + } +} Added: trunk/jython/src/org/python/modules/_threading/_threading.java =================================================================== --- trunk/jython/src/org/python/modules/_threading/_threading.java (rev 0) +++ trunk/jython/src/org/python/modules/_threading/_threading.java 2009-07-11 06:47:49 UTC (rev 6527) @@ -0,0 +1,15 @@ +package org.python.modules._threading; + +import org.python.core.ClassDictInit; +import org.python.core.Py; +import org.python.core.PyObject; + +public class _threading implements ClassDictInit { + + public static void classDictInit(PyObject dict) { + dict.__setitem__("__name__", Py.newString("_threading")); + dict.__setitem__("Lock", Lock.TYPE); + dict.__setitem__("RLock", Lock.TYPE); + dict.__setitem__("Condition", Condition.TYPE); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-07-11 23:22:26
|
Revision: 6529 http://jython.svn.sourceforge.net/jython/?rev=6529&view=rev Author: pjenvey Date: 2009-07-11 23:22:13 +0000 (Sat, 11 Jul 2009) Log Message: ----------- don't encode unicode when printing to an intercepted stream thanks Pekka Klarck fixes #1802339 Modified Paths: -------------- trunk/jython/Lib/test/test_unicode_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/StdoutWrapper.java Modified: trunk/jython/Lib/test/test_unicode_jy.py =================================================================== --- trunk/jython/Lib/test/test_unicode_jy.py 2009-07-11 22:38:33 UTC (rev 6528) +++ trunk/jython/Lib/test/test_unicode_jy.py 2009-07-11 23:22:13 UTC (rev 6529) @@ -6,6 +6,7 @@ import re import sys import unittest +from StringIO import StringIO from test import test_support class UnicodeTestCase(unittest.TestCase): @@ -156,9 +157,25 @@ self.assertEquals(u"\u00e7%s" % "foo", u"\u00e7foo") +class UnicodeStdIOTestCase(unittest.TestCase): + + def setUp(self): + self.stdout = sys.stdout + + def tearDown(self): + sys.stdout = self.stdout + + def test_intercepted_stdout(self): + msg = u'Circle is 360\u00B0' + sys.stdout = StringIO() + print msg, + self.assertEqual(sys.stdout.getvalue(), msg) + + def test_main(): test_support.run_unittest(UnicodeTestCase, - UnicodeFormatTestCase) + UnicodeFormatTestCase, + UnicodeStdIOTestCase) if __name__ == "__main__": Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-07-11 22:38:33 UTC (rev 6528) +++ trunk/jython/NEWS 2009-07-11 23:22:13 UTC (rev 6529) @@ -10,6 +10,7 @@ - [ 1377 ] Event names shadowed by a field name on Java types leads to a NPE - [ 1381 ] Redundant declarations of interface implementation hides overriden methods - [ 1189 ] MD5 hash is incorrectly calculated when string contains non-latin chars and using python md5 lib + - [ 1802339 ] Problem printing unicode when stdout intercepted Jython 2.5.0 The same as rc4. Modified: trunk/jython/src/org/python/core/StdoutWrapper.java =================================================================== --- trunk/jython/src/org/python/core/StdoutWrapper.java 2009-07-11 22:38:33 UTC (rev 6528) +++ trunk/jython/src/org/python/core/StdoutWrapper.java 2009-07-11 23:22:13 UTC (rev 6529) @@ -41,6 +41,7 @@ return obj; } + @Override public void flush() { PyObject obj = myFile(); if (obj instanceof PyFile) { @@ -64,10 +65,12 @@ } } + @Override public void write(int i) { write(new String(new char[] { (char) i })); } + @Override public void write(byte[] data, int off, int len) { write(StringUtil.fromBytes(data, off, len)); } @@ -112,10 +115,10 @@ } else { s = o.__str__().toString(); } + file.write(s); - int len = s.length(); - file.write(s); if (o instanceof PyString) { + int len = s.length(); if (len == 0 || !Character.isWhitespace(s.charAt(len - 1)) || s.charAt(len - 1) == ' ') { file.softspace = space; @@ -123,6 +126,7 @@ } else { file.softspace = space; } + if (newline) { file.write("\n"); file.softspace = false; @@ -143,9 +147,10 @@ } else { s = o.toString(); } - int len = s.length(); file.write(s); + if (o instanceof PyString) { + int len = s.length(); if (len == 0 || !Character.isWhitespace(s.charAt(len - 1)) || s.charAt(len - 1) == ' ') { file.softspace = space; @@ -153,6 +158,7 @@ } else { file.softspace = space; } + if (newline) { file.write("\n"); file.softspace = false; @@ -164,11 +170,15 @@ obj.invoke("write", Py.Space); obj.__setattr__("softspace", Py.Zero); } - PyString string = o.__str__(); - String s = o.toString(); - int len = s.length(); - obj.invoke("write", string); + + if (!(o instanceof PyUnicode)) { + o = o.__str__(); + } + obj.invoke("write", o); + if (o instanceof PyString) { + String s = o.toString(); + int len = s.length(); if (len == 0 || !Character.isWhitespace(s.charAt(len - 1)) || s.charAt(len - 1) == ' ') { obj.__setattr__("softspace", space ? Py.One : Py.Zero); @@ -176,6 +186,7 @@ } else { obj.__setattr__("softspace", space ? Py.One : Py.Zero); } + if (newline) { obj.invoke("write", Py.Newline); obj.__setattr__("softspace", Py.Zero); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-07-12 05:41:47
|
Revision: 6532 http://jython.svn.sourceforge.net/jython/?rev=6532&view=rev Author: cgroves Date: 2009-07-12 05:41:43 +0000 (Sun, 12 Jul 2009) Log Message: ----------- Set the name of the produced proxy class to the value from __javaclass__ if it's set in the Python class. Modified Paths: -------------- trunk/jython/Lib/test/test_java_subclasses.py trunk/jython/NEWS trunk/jython/src/org/python/compiler/Module.java trunk/jython/src/org/python/core/MakeProxies.java trunk/jython/src/org/python/core/PyType.java trunk/jython/src/org/python/core/util/StringUtil.java Modified: trunk/jython/Lib/test/test_java_subclasses.py =================================================================== --- trunk/jython/Lib/test/test_java_subclasses.py 2009-07-12 00:53:25 UTC (rev 6531) +++ trunk/jython/Lib/test/test_java_subclasses.py 2009-07-12 05:41:43 UTC (rev 6532) @@ -321,10 +321,35 @@ self.assertEquals(len(called), 1) +class SettingJavaClassNameTest(unittest.TestCase): + def test_setting_name(self): + class Fixedname(Runnable): + __javaname__ = 'name.set.in.Python' + def run(self): + pass + self.assertEquals('name.set.in.Python', Fixedname().getClass().name) + try: + class NumberPackageName(Runnable): + __javaname__ = 'ok.7.ok' + def run(self): + pass + self.fail("Shouldn't be able to set a package name that starts with a digit") + except TypeError: + pass + try: + class LiteralPackageName(Runnable): + __javaname__ = 'ok.true.ok' + def run(self): + pass + self.fail("Shouldn't be able to use a Java literal as a package name") + except TypeError: + pass + def test_main(): test_support.run_unittest(InterfaceTest, TableModelTest, AutoSuperTest, PythonSubclassesTest, AbstractOnSyspathTest, - ContextClassloaderTest) + ContextClassloaderTest, + SettingJavaClassNameTest) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-07-12 00:53:25 UTC (rev 6531) +++ trunk/jython/NEWS 2009-07-12 05:41:43 UTC (rev 6532) @@ -4,6 +4,8 @@ New Features - Upgraded to ANTLR 3.1.3 - [ 1859477 ] Dynamically loaded ServletFilters like PyServlet + - Setting __javaname__ in classes subclassing Java classes or implementing Java interfaces sets + the name of the produced proxy class. Bugs Fixed - [ 1366 ] parsing of lamda expression fails - [ 1365 ] continuation lines fail in interactive interpreter Modified: trunk/jython/src/org/python/compiler/Module.java =================================================================== --- trunk/jython/src/org/python/compiler/Module.java 2009-07-12 00:53:25 UTC (rev 6531) +++ trunk/jython/src/org/python/compiler/Module.java 2009-07-12 05:41:43 UTC (rev 6532) @@ -12,6 +12,11 @@ import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.python.antlr.ParseException; +import org.python.antlr.PythonTree; +import org.python.antlr.ast.Suite; +import org.python.antlr.base.mod; import org.python.core.CodeBootstrap; import org.python.core.CodeFlag; import org.python.core.CodeLoader; @@ -19,11 +24,7 @@ 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; -import org.python.antlr.base.mod; +import org.python.core.util.StringUtil; class PyIntegerConstant extends Constant implements ClassConstants, Opcodes { @@ -365,20 +366,7 @@ } List codes; - private boolean isJavaIdentifier(String s) { - char[] chars = s.toCharArray(); - if (chars.length == 0) - return false; - if (!Character.isJavaIdentifierStart(chars[0])) - return false; - for(int i=1; i<chars.length; i++) { - if (!Character.isJavaIdentifierPart(chars[i])) - return false; - } - return true; - } - //XXX: this can probably go away now that we can probably just copy the list. private List<String> toNameAr(List names,boolean nullok) { int sz = names.size(); @@ -423,7 +411,7 @@ code.id = codes.size(); //Better names in the future? - if (isJavaIdentifier(name)) + if (StringUtil.isJavaIdentifier(name)) code.fname = name+"$"+code.id; else code.fname = "f$"+code.id; @@ -549,7 +537,7 @@ 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), @@ -655,7 +643,7 @@ String name, String filename, boolean linenumbers, boolean printResults, CompilerFlags cflags) - throws Exception + throws Exception { compile(node, ostream, name, filename, linenumbers, printResults, cflags, org.python.core.imp.NO_MTIME); } Modified: trunk/jython/src/org/python/core/MakeProxies.java =================================================================== --- trunk/jython/src/org/python/core/MakeProxies.java 2009-07-12 00:53:25 UTC (rev 6531) +++ trunk/jython/src/org/python/core/MakeProxies.java 2009-07-12 05:41:43 UTC (rev 6532) @@ -8,6 +8,7 @@ import org.python.compiler.AdapterMaker; import org.python.compiler.JavaMaker; +import org.python.core.util.StringUtil; class MakeProxies { @@ -51,13 +52,24 @@ List<Class<?>> vinterfaces, String className, String proxyName, PyObject dict) { Class<?>[] interfaces = vinterfaces.toArray(new Class<?>[vinterfaces.size()]); - String fullProxyName = proxyPrefix + proxyName + "$" + proxyNumber++; + String fullProxyName; + PyObject customProxyName = dict.__finditem__("__javaname__"); + if (customProxyName != null) { + fullProxyName = Py.tojava(customProxyName, String.class); + if (!StringUtil.isJavaClassName(fullProxyName)) { + throw Py.TypeError(fullProxyName + " isn't a valid Java class name. Classes " + + "must be valid Java identifiers: " + + "http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#40625"); + } + } else { + fullProxyName = proxyPrefix + proxyName + "$" + proxyNumber++; + } String pythonModuleName; PyObject mn = dict.__finditem__("__module__"); if (mn == null) { pythonModuleName = "foo"; } else { - pythonModuleName = (String) mn.__tojava__(String.class); + pythonModuleName = Py.tojava(mn, String.class); } JavaMaker jm = new JavaMaker(superclass, interfaces, Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-07-12 00:53:25 UTC (rev 6531) +++ trunk/jython/src/org/python/core/PyType.java 2009-07-12 05:41:43 UTC (rev 6532) @@ -579,11 +579,9 @@ if (module != null) { proxyName = module.toString() + "$" + proxyName; } - Class<?> proxyClass = MakeProxies.makeProxy(baseProxyClass, interfaces, name, proxyName, - dict); - javaProxy = proxyClass; + javaProxy = MakeProxies.makeProxy(baseProxyClass, interfaces, name, proxyName, dict); - PyType proxyType = PyType.fromClass(proxyClass); + PyType proxyType = PyType.fromClass((Class<?>)javaProxy); List<PyObject> cleanedBases = Generic.list(); boolean addedProxyType = false; for (PyObject base : bases) { Modified: trunk/jython/src/org/python/core/util/StringUtil.java =================================================================== --- trunk/jython/src/org/python/core/util/StringUtil.java 2009-07-12 00:53:25 UTC (rev 6531) +++ trunk/jython/src/org/python/core/util/StringUtil.java 2009-07-12 05:41:43 UTC (rev 6532) @@ -3,8 +3,10 @@ import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; +import java.util.Set; import org.python.core.Py; +import org.python.util.Generic; /** * String Utility methods. @@ -84,4 +86,47 @@ chars[0] = Character.toLowerCase(c0); return new String(chars); } + + /** + * Returns true if each segment of <code>name</code> produced by splitting it on '.' is a valid + * Java identifier. + */ + public static boolean isJavaClassName(String name) { + for (String segment : name.split("\\.")) { + if (!isJavaIdentifier(segment)) { + return false; + } + } + return true; + } + + /** + * Returns true if ident is a valid Java identifier as defined by + * http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#40625 + */ + public static boolean isJavaIdentifier(String ident) { + if (ident.isEmpty() || JAVA_LITERALS.contains(ident)) { + return false; + } + int cp = ident.codePointAt(0); + if (!Character.isJavaIdentifierStart(cp)) { + return false; + } + for (int i = Character.charCount(cp); i < ident.length(); i += Character.charCount(cp)) { + cp = ident.codePointAt(i); + if (!Character.isJavaIdentifierPart(cp)) { + return false; + } + } + return true; + } + + // True false and null are just literals, the rest are keywords + private static final Set<String> JAVA_LITERALS = Generic.set("abstract", "continue", "for", + "new", "switch", "assert", "default", "goto", "package", "synchronized", "boolean", "do", + "if", "private", "this", "break", "double", "implements", "protected", "throw", "byte", + "else", "import", "public", "throws", "case", "enum", "instanceof", "return", "transient", + "catch", "extends", "int", "short", "try", "char", "final", "interface", "static", "void", + "class", "finally", "long", "strictfp", "volatile", "const", "float", "native", "super", + "while", "true", "false", "null"); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-07-12 08:07:52
|
Revision: 6533 http://jython.svn.sourceforge.net/jython/?rev=6533&view=rev Author: cgroves Date: 2009-07-12 08:07:51 +0000 (Sun, 12 Jul 2009) Log Message: ----------- Add javaproxy_dir to sys, and if it's set, compile Java proxies to that directory. Modified Paths: -------------- trunk/jython/Lib/test/test_java_subclasses.py trunk/jython/src/org/python/core/MakeProxies.java trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/PySystemState.java Added Paths: ----------- trunk/jython/Lib/test/import_as_java_class.py trunk/jython/Lib/test/static_proxy.py Added: trunk/jython/Lib/test/import_as_java_class.py =================================================================== --- trunk/jython/Lib/test/import_as_java_class.py (rev 0) +++ trunk/jython/Lib/test/import_as_java_class.py 2009-07-12 08:07:51 UTC (rev 6533) @@ -0,0 +1,7 @@ +# Part of test_java_subclasses.StaticProxyCompilationTest +from java.lang import Class + +# Grab the proxy class statically compiled by the containing test +cls = Class.forName("test.static_proxy.RunnableImpl") +# Instantiating the proxy class should import the module containing it and create the Python side +assert cls.newInstance().meth() == 78 Added: trunk/jython/Lib/test/static_proxy.py =================================================================== --- trunk/jython/Lib/test/static_proxy.py (rev 0) +++ trunk/jython/Lib/test/static_proxy.py 2009-07-12 08:07:51 UTC (rev 6533) @@ -0,0 +1,11 @@ +# Part of test_java_subclasses.StaticProxyCompilationTest. This needs to be its own module +# so the statically compiled proxy can import it. +from java.lang import Runnable + +class RunnableImpl(Runnable): + __javaname__ = "test.static_proxy.RunnableImpl" + def run(self): + pass + + def meth(self): + return 78 Modified: trunk/jython/Lib/test/test_java_subclasses.py =================================================================== --- trunk/jython/Lib/test/test_java_subclasses.py 2009-07-12 05:41:43 UTC (rev 6532) +++ trunk/jython/Lib/test/test_java_subclasses.py 2009-07-12 08:07:51 UTC (rev 6533) @@ -1,6 +1,8 @@ '''Tests subclassing Java classes in Python''' import os import sys +import tempfile +import subprocess import unittest from test import test_support @@ -345,6 +347,26 @@ except TypeError: pass +class StaticProxyCompilationTest(unittest.TestCase): + def setUp(self): + self.orig_proxy_dir = sys.javaproxy_dir + sys.javaproxy_dir = tempfile.mkdtemp() + + def tearDown(self): + sys.javaproxy_dir = self.orig_proxy_dir + + def test_proxies_without_classloader(self): + # importing with proxy_dir set compiles RunnableImpl there + import static_proxy + + # Use the existing environment with the proxy dir added on the classpath + env = dict(os.environ) + env["CLASSPATH"] = sys.javaproxy_dir + script = test_support.findfile("import_as_java_class.py") + self.assertEquals(subprocess.call([sys.executable, "-J-Dpython.cachedir.skip=true", + script], env=env), + 0) + def test_main(): test_support.run_unittest(InterfaceTest, TableModelTest, @@ -352,4 +374,5 @@ PythonSubclassesTest, AbstractOnSyspathTest, ContextClassloaderTest, - SettingJavaClassNameTest) + SettingJavaClassNameTest, + StaticProxyCompilationTest) Modified: trunk/jython/src/org/python/core/MakeProxies.java =================================================================== --- trunk/jython/src/org/python/core/MakeProxies.java 2009-07-12 05:41:43 UTC (rev 6532) +++ trunk/jython/src/org/python/core/MakeProxies.java 2009-07-12 08:07:51 UTC (rev 6533) @@ -61,6 +61,10 @@ "must be valid Java identifiers: " + "http://java.sun.com/docs/books/jls/second_edition/html/lexical.doc.html#40625"); } + Class<?> proxy = Py.findClass(fullProxyName); + if (proxy != null) { + return proxy; + } } else { fullProxyName = proxyPrefix + proxyName + "$" + proxyNumber++; } @@ -81,7 +85,11 @@ jm.build(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); jm.classfile.write(bytes); - Py.saveClassFile(fullProxyName, bytes); + if (customProxyName != null) { + Py.saveClassFile(fullProxyName, bytes, Py.getSystemState().javaproxy_dir); + } else { + Py.saveClassFile(fullProxyName, bytes); + } return makeClass(superclass, vinterfaces, jm.myClass, bytes); } catch (Exception exc) { Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-07-12 05:41:43 UTC (rev 6532) +++ trunk/jython/src/org/python/core/Py.java 2009-07-12 08:07:51 UTC (rev 6533) @@ -830,8 +830,9 @@ public static void initProxy(PyProxy proxy, String module, String pyclass, Object[] args) { - if (proxy._getPyInstance() != null) + if (proxy._getPyInstance() != null) { return; + } ThreadState ts = getThreadState(); PyObject instance = ts.getInitializingProxy(); if (instance != null) { @@ -1759,14 +1760,17 @@ } public static void saveClassFile(String name, ByteArrayOutputStream bytestream) { - String dirname = Options.proxyDebugDirectory; + saveClassFile(name, bytestream, Options.proxyDebugDirectory); + } + + public static void saveClassFile(String name, ByteArrayOutputStream baos, String dirname) { if (dirname == null) { return; } - - byte[] bytes = bytestream.toByteArray(); + byte[] bytes = baos.toByteArray(); File dir = new File(dirname); File file = makeFilename(name, dir); + new File(file.getParent()).mkdirs(); try { FileOutputStream o = new FileOutputStream(file); Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-07-12 05:41:43 UTC (rev 6532) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-07-12 08:07:51 UTC (rev 6533) @@ -40,6 +40,7 @@ public static final String PYTHON_CACHEDIR_SKIP = "python.cachedir.skip"; public static final String PYTHON_CONSOLE_ENCODING = "python.console.encoding"; protected static final String CACHEDIR_DEFAULT_NAME = "cachedir"; + public static final String PYTHON_JAVAPROXYDIR = "python.javaproxydir"; public static final String JYTHON_JAR = "jython.jar"; public static final String JYTHON_DEV_JAR = "jython-dev.jar"; @@ -138,6 +139,13 @@ public PyObject last_type = Py.None; public PyObject last_traceback = Py.None; + private static String defaultJavaProxyDir; + + /** + * The directory where named Java proxies are written. + */ + public String javaproxy_dir; + public PyObject __name__ = new PyString("sys"); public PyObject __dict__; @@ -189,6 +197,8 @@ __dict__.invoke("update", getType().fastGetDict()); __dict__.__setitem__("displayhook", __displayhook__); __dict__.__setitem__("excepthook", __excepthook__); + + javaproxy_dir = defaultJavaProxyDir; } void reload() throws PyIgnoreMethodTag { @@ -857,6 +867,8 @@ // other initializations initBuiltins(registry); initStaticFields(); + defaultJavaProxyDir = registry.getProperty(PYTHON_JAVAPROXYDIR); + // Initialize the path (and add system defaults) defaultPath = initPath(registry, standalone, jarFileName); defaultArgv = initArgv(argv); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-07-13 16:32:48
|
Revision: 6536 http://jython.svn.sourceforge.net/jython/?rev=6536&view=rev Author: fwierzbicki Date: 2009-07-13 16:32:44 +0000 (Mon, 13 Jul 2009) Log Message: ----------- Fix for http://bugs.jython.org/issue645615 "cannot import through symbolic links". Now only explicitely enforcing case sensative imports on Windows and Mac. In the presense of both case insensative systems and symlinks there may be a performance penalty, as we walk the directory looking for exact matches in this case. This is the same method used in CPython. Modified Paths: -------------- trunk/jython/Lib/test/test_import_jy.py trunk/jython/NEWS trunk/jython/build.xml trunk/jython/src/org/python/core/imp.java Added Paths: ----------- trunk/jython/src/org/python/core/util/PlatformUtil.java Modified: trunk/jython/Lib/test/test_import_jy.py =================================================================== --- trunk/jython/Lib/test/test_import_jy.py 2009-07-13 15:29:30 UTC (rev 6535) +++ trunk/jython/Lib/test/test_import_jy.py 2009-07-13 16:32:44 UTC (rev 6536) @@ -164,6 +164,28 @@ def test_sys_modules_deletion(self): self.assertRaises(ZeroDivisionError, __import__, 'test.module_deleter') + #XXX: this is probably a good test to push upstream to CPython. + if hasattr(os, "symlink"): + def test_symlinks(self): + # Ensure imports work over symlinks. Did not work in Jython from + # 2.1 to 2.5.0, fixed in 2.5.1 See + # http://bugs.jython.org/issue645615. + sym = test_support.TESTFN+"1" + try: + os.mkdir(test_support.TESTFN) + init = os.path.join(test_support.TESTFN, "__init__.py") + fp = open(init, 'w') + fp.write("test = 'imported'") + fp.close() + os.symlink(test_support.TESTFN, sym) + module = os.path.basename(sym) + module_obj = __import__(module) + self.assertEquals(module_obj.test, 'imported') + + finally: + shutil.rmtree(test_support.TESTFN) + test_support.unlink(sym) + def test_main(): test_support.run_unittest(MislabeledImportTestCase, OverrideBuiltinsImportTestCase, Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-07-13 15:29:30 UTC (rev 6535) +++ trunk/jython/NEWS 2009-07-13 16:32:44 UTC (rev 6536) @@ -7,6 +7,7 @@ - Setting __javaname__ in classes subclassing Java classes or implementing Java interfaces sets the name of the produced proxy class. Bugs Fixed + - [ 645615 ] cannot import through symbolic links - [ 1366 ] parsing of lamda expression fails - [ 1365 ] continuation lines fail in interactive interpreter - [ 1377 ] Event names shadowed by a field name on Java types leads to a NPE Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-07-13 15:29:30 UTC (rev 6535) +++ trunk/jython/build.xml 2009-07-13 16:32:44 UTC (rev 6536) @@ -158,6 +158,7 @@ <pathelement path="${extlibs.dir}/asm-3.1.jar" /> <pathelement path="${extlibs.dir}/asm-commons-3.1.jar" /> <pathelement path="${extlibs.dir}/constantine-0.4.jar" /> + <pathelement path="${extlibs.dir}/jna.jar"/> <pathelement path="${extlibs.dir}/jna-posix.jar"/> </path> Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2009-07-13 15:29:30 UTC (rev 6535) +++ trunk/jython/src/org/python/core/imp.java 2009-07-13 16:32:44 UTC (rev 6536) @@ -11,6 +11,7 @@ import org.python.compiler.Module; import org.python.core.util.FileUtil; +import org.python.core.util.PlatformUtil; /** * Utility functions for "import" support. @@ -527,12 +528,26 @@ } public static boolean caseok(File file, String filename) { - if (Options.caseok) { + if (Options.caseok || !PlatformUtil.isCaseInsensitive()) { return true; } try { File canFile = new File(file.getCanonicalPath()); - return filename.regionMatches(0, canFile.getName(), 0, filename.length()); + boolean match = filename.regionMatches(0, canFile.getName(), 0, filename.length()); + if (!match) { + //possibly a symlink. Get parent and look for exact match in listdir() + //This is what CPython does in the case of Mac OS X and Cygwin. + //XXX: This will be a performance hit, maybe jdk7 nio2 can give us a better + // method? + File parent = file.getParentFile(); + String[] children = parent.list(); + for (String c: children) { + if (c.equals(filename)) { + return true; + } + } + } + return match; } catch (IOException exc) { return false; } Added: trunk/jython/src/org/python/core/util/PlatformUtil.java =================================================================== --- trunk/jython/src/org/python/core/util/PlatformUtil.java (rev 0) +++ trunk/jython/src/org/python/core/util/PlatformUtil.java 2009-07-13 16:32:44 UTC (rev 6536) @@ -0,0 +1,24 @@ +// Copyright (c) 2009 Jython project +package org.python.core.util; + +// Note: Sun does not sponsor the jna project, even though the package name +// might imply otherwise. +import com.sun.jna.Platform; + +/** + * Methods for testing the platform/operating system that we are on. + */ +public class PlatformUtil { + + /** + * @return True if the operating system we are on is case insensitive, + * where case insensitive means that a file that is stored as FOO + * can be accessed as (for example) FoO. + */ + //Currently we just check to see if we are on windows or macs, which are + //commonly (though not always!) case insensitive. There are certainly cases + //where this is not sufficient, like the case of mounted filesystems. + public static boolean isCaseInsensitive() { + return Platform.isMac() || Platform.isWindows(); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-23 05:15:01
|
Revision: 6567 http://jython.svn.sourceforge.net/jython/?rev=6567&view=rev Author: nriley Date: 2009-07-23 05:14:58 +0000 (Thu, 23 Jul 2009) Log Message: ----------- Merged revisions 6285,6541,6551,6559-6565 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/branches/jsr223 ........ r6285 | zyasoft | 2009-05-02 01:13:13 -0500 (Sat, 02 May 2009) | 2 lines Some initial code, just to get it going. ........ r6541 | nriley | 2009-07-17 00:27:51 -0500 (Fri, 17 Jul 2009) | 1 line JSR 223 support for compile and eval of Strings. ........ r6551 | nriley | 2009-07-20 12:35:01 -0500 (Mon, 20 Jul 2009) | 1 line JSR 223: test Python exceptions as well as syntax errors. ........ r6559 | nriley | 2009-07-22 16:15:39 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: support for compile and eval with Readers. ........ r6560 | nriley | 2009-07-22 18:51:47 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: fix comments in ParserFacade. ........ r6561 | nriley | 2009-07-22 18:52:00 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: set PySystemState for separate compile/execute. ........ r6562 | nriley | 2009-07-22 18:52:08 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: standardize argument naming. ........ r6563 | nriley | 2009-07-22 18:52:19 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: bindings support. ........ r6564 | nriley | 2009-07-22 22:12:10 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: getInterface support; clean up and factor exception transformation. ........ r6565 | nriley | 2009-07-22 22:12:52 -0500 (Wed, 22 Jul 2009) | 1 line JSR 223: Invocable implementation. ........ Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/build.xml trunk/jython/src/org/python/core/ParserFacade.java trunk/jython/src/org/python/util/PythonInterpreter.java Added Paths: ----------- trunk/jython/src/META-INF/ trunk/jython/src/META-INF/services/ trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory trunk/jython/src/org/python/jsr223/ trunk/jython/src/org/python/jsr223/PyScriptEngine.java trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java trunk/jython/tests/java/org/python/jsr223/ trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java Removed Paths: ------------- trunk/jython/src/META-INF/services/ trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory trunk/jython/src/org/python/jsr223/PyScriptEngine.java trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java Property Changed: ---------------- trunk/jython/ trunk/jython/tests/java/org/python/tests/RedundantInterfaceDeclarations.java Property changes on: trunk/jython ___________________________________________________________________ Modified: svnmerge-integrated - /branches/jsr223:1-6284 /branches/pbcvm:1-6045 + /branches/jsr223:1-6566 /branches/pbcvm:1-6045 Modified: svn:mergeinfo - /branches/newstyle-java-types:5564-5663,5666-5729 + /branches/jsr223:6285-6565 /branches/newstyle-java-types:5564-5663,5666-5729 Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2009-07-23 03:26:56 UTC (rev 6566) +++ trunk/jython/CoreExposed.includes 2009-07-23 05:14:58 UTC (rev 6567) @@ -43,6 +43,7 @@ org/python/core/PyXRange.class org/python/modules/PyStruct.class org/python/modules/PyTeeIterator.class +org/python/jsr223/PyScriptEngineScope.class org/python/modules/_codecs$EncodingMap.class org/python/modules/_collections/PyDefaultDict.class org/python/modules/_collections/PyDeque.class Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-07-23 03:26:56 UTC (rev 6566) +++ trunk/jython/build.xml 2009-07-23 05:14:58 UTC (rev 6567) @@ -506,6 +506,10 @@ </copy> <!-- grammar must now be up to date --> <property name="antlr.notneeded" value="true" /> + + <copy todir="${compile.dir}/META-INF/services"> + <fileset dir="${source.dir}/META-INF/services" /> + </copy> </target> <!-- Deleted: trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory =================================================================== --- branches/jsr223/src/META-INF/services/javax.script.ScriptEngineFactory 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory 2009-07-23 05:14:58 UTC (rev 6567) @@ -1 +0,0 @@ -org.python.jsr223.PyScriptEngineFactory Copied: trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory (from rev 6565, branches/jsr223/src/META-INF/services/javax.script.ScriptEngineFactory) =================================================================== --- trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory (rev 0) +++ trunk/jython/src/META-INF/services/javax.script.ScriptEngineFactory 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1 @@ +org.python.jsr223.PyScriptEngineFactory Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2009-07-23 03:26:56 UTC (rev 6566) +++ trunk/jython/src/org/python/core/ParserFacade.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -10,6 +10,7 @@ import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Reader; +import java.io.StringReader; import java.io.Writer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; @@ -108,6 +109,34 @@ } /** + * Parse Python source as either an expression (if possible) or module. + * + * Designed for use by a JSR 223 implementation: "the Scripting API does not distinguish + * between scripts which return values and those which do not, nor do they make the + * corresponding distinction between evaluating or executing objects." (SCR.4.2.1) + */ + public static mod parseExpressionOrModule(Reader reader, + String filename, + CompilerFlags cflags) { + ExpectedEncodingBufferedReader bufReader = null; + try { + bufReader = prepBufReader(reader, cflags, filename); + // first, try parsing as an expression + return parse(bufReader, CompileMode.eval, filename, cflags ); + } catch (Throwable t) { + try { + // then, try parsing as a module + bufReader.reset(); + return parse(bufReader, CompileMode.exec, filename, cflags); + } catch (Throwable tt) { + throw fixParseError(bufReader, tt, filename); + } + } finally { + close(bufReader); + } + } + + /** * Internal parser entry point. * * Users of this method should call fixParseError on any Throwable thrown @@ -130,6 +159,21 @@ } } + public static mod parse(Reader reader, + CompileMode kind, + String filename, + CompilerFlags cflags) { + ExpectedEncodingBufferedReader bufReader = null; + try { + bufReader = prepBufReader(reader, cflags, filename); + return parse(bufReader, kind, filename, cflags ); + } catch (Throwable t) { + throw fixParseError(bufReader, t, filename); + } finally { + close(bufReader); + } + } + public static mod parse(InputStream stream, CompileMode kind, String filename, @@ -222,6 +266,22 @@ } } + private static ExpectedEncodingBufferedReader prepBufReader(Reader reader, + CompilerFlags cflags, + String filename) + throws IOException { + cflags.source_is_utf8 = true; + cflags.encoding = "utf-8"; + + BufferedReader bufferedReader = new BufferedReader(reader); + bufferedReader.mark(MARK_LIMIT); + if (findEncoding(bufferedReader) != null) + throw new ParseException("encoding declaration in Unicode string"); + bufferedReader.reset(); + + return new ExpectedEncodingBufferedReader(bufferedReader, null); + } + private static ExpectedEncodingBufferedReader prepBufReader(InputStream input, CompilerFlags cflags, String filename, @@ -289,20 +349,10 @@ CompilerFlags cflags, String filename) throws IOException { - byte[] stringBytes; - if (cflags.source_is_utf8) { - // Passed unicode, re-encode the String to raw bytes - // NOTE: This could be more efficient if we duplicate - // prepBufReader/adjustForBOM/readEncoding to work on Readers, instead of - // encoding - ByteArrayOutputStream out = new ByteArrayOutputStream(); - Writer w = new OutputStreamWriter(out, "utf-8"); - w.write(string); - w.close(); - stringBytes = out.toByteArray(); - } else { - stringBytes = StringUtil.toBytes(string); - } + if (cflags.source_is_utf8) + return prepBufReader(new StringReader(string), cflags, filename); + + byte[] stringBytes = StringUtil.toBytes(string); return prepBufReader(new ByteArrayInputStream(stringBytes), cflags, filename, true, false); } Deleted: trunk/jython/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngine.java 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/src/org/python/jsr223/PyScriptEngine.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,210 +0,0 @@ -package org.python.jsr223; - -import java.lang.reflect.Method; -import org.python.core.*; -import java.io.Reader; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Proxy; -import javax.script.AbstractScriptEngine; -import javax.script.Bindings; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.Invocable; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptException; -import javax.script.SimpleBindings; -import org.python.util.PythonInterpreter; - -public class PyScriptEngine extends AbstractScriptEngine implements Compilable, Invocable { - - private final PythonInterpreter interp; - private final ScriptEngineFactory factory; - private final PyModule module; - - PyScriptEngine(ScriptEngineFactory factory) { - this.factory = factory; - interp = new PythonInterpreter(new PyScriptEngineScope(this, context)); - module = (PyModule)Py.getSystemState().modules.__finditem__("__main__"); - } - - public Object eval(String script, ScriptContext context) throws ScriptException { - return eval(compileScript(script, context)); - } - - private Object eval(PyCode code) throws ScriptException { - try { - return interp.eval(code).__tojava__(Object.class); - } catch (PyException pye) { - throw scriptException(pye); - } - } - - public Object eval(Reader reader, ScriptContext context) throws ScriptException { - return eval(compileScript(reader, context)); - } - - public Bindings createBindings() { - return new SimpleBindings(); - } - - public ScriptEngineFactory getFactory() { - return factory; - } - - public CompiledScript compile(String script) throws ScriptException { - return new PyCompiledScript(compileScript(script, context)); - } - - public CompiledScript compile(Reader reader) throws ScriptException { - return new PyCompiledScript(compileScript(reader, context)); - } - - private PyCode compileScript(String script, ScriptContext context) throws ScriptException { - try { - String filename = (String) context.getAttribute(ScriptEngine.FILENAME); - if (filename == null) - return interp.compile(script); - else - return interp.compile(script, filename); - } catch (PyException pye) { - throw scriptException(pye); - } - } - - private PyCode compileScript(Reader reader, ScriptContext context) throws ScriptException { - try { - String filename = (String) context.getAttribute(ScriptEngine.FILENAME); - if (filename == null) - return interp.compile(reader); - else - return interp.compile(reader, filename); - } catch (PyException pye) { - throw scriptException(pye); - } - } - - public Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException { - try { - if (!(thiz instanceof PyObject)) - thiz = Py.java2py(thiz); - return ((PyObject) thiz).invoke(name, java2py(args)).__tojava__(Object.class); - } catch (PyException pye) { - return throwInvokeException(pye, name); - } - } - - public Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException { - try { - PyObject function = interp.get(name); - if (function == null) - throw new NoSuchMethodException(name); - return function.__call__(java2py(args)).__tojava__(Object.class); - } catch (PyException pye) { - return throwInvokeException(pye, name); - } - } - - public <T> T getInterface(Class<T> clazz) { - return getInterface(module, clazz); - } - - public <T> T getInterface(Object obj, Class<T> clazz) { - if (obj == null) - throw new IllegalArgumentException("object expected"); - if (clazz == null || !clazz.isInterface()) - throw new IllegalArgumentException("interface expected"); - final Object thiz = Py.java2py(obj); - return (T) Proxy.newProxyInstance( - clazz.getClassLoader(), - new Class[] { clazz }, - new InvocationHandler() { - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - try { - return ((PyObject) thiz).invoke(method.getName(), java2py(args)).__tojava__(Object.class); - } catch (PyException pye) { - return throwInvokeException(pye, method.getName()); - } - } - }); - } - - private static Object throwInvokeException(PyException pye, String methodName) - throws ScriptException, NoSuchMethodException { - if (Py.matchException(pye, Py.AttributeError)) { - throw new NoSuchMethodException(methodName); - } - throw scriptException(pye); - } - - private static ScriptException scriptException(PyException pye) { - ScriptException se = null; - try { - pye.normalize(); - - PyObject type = pye.type; - PyObject value = pye.value; - PyTraceback tb = pye.traceback; - - if (__builtin__.isinstance(value, Py.SyntaxError)) { - PyObject filename = value.__findattr__("filename"); - PyObject lineno = value.__findattr__("lineno"); - PyObject offset = value.__findattr__("offset"); - value = value.__findattr__("msg"); - - se = new ScriptException( - Py.formatException(type, value), - filename == null ? "<script>" : filename.toString(), - lineno == null ? 0 : lineno.asInt(), - offset == null ? 0 : offset.asInt()); - } else if (tb != null) { - String filename; - if (tb.tb_frame == null || tb.tb_frame.f_code == null) - filename = null; - else - filename = tb.tb_frame.f_code.co_filename; - - se = new ScriptException( - Py.formatException(type, value), - filename, - tb.tb_lineno); - } else { - se = new ScriptException(Py.formatException(type, value)); - } - se.initCause(pye); - return se; - } catch (Exception ee) { - se = new ScriptException(pye); - } - return se; - } - - private static PyObject[] java2py(Object[] args) { - PyObject wrapped[] = new PyObject[args.length]; - for (int i = 0; i < args.length; i++) { - wrapped[i] = Py.java2py(args[i]); - } - return wrapped; - } - - private class PyCompiledScript extends CompiledScript { - private PyCode code; - private PySystemState systemState; - - PyCompiledScript(PyCode code) { - this.code = code; - this.systemState = Py.getSystemState(); - } - - public ScriptEngine getEngine() { - return PyScriptEngine.this; - } - - public Object eval(ScriptContext ctx) throws ScriptException { - // can't read filename from context at this point - Py.setSystemState(systemState); - return PyScriptEngine.this.eval(code); - } - } -} Copied: trunk/jython/src/org/python/jsr223/PyScriptEngine.java (from rev 6565, branches/jsr223/src/org/python/jsr223/PyScriptEngine.java) =================================================================== --- trunk/jython/src/org/python/jsr223/PyScriptEngine.java (rev 0) +++ trunk/jython/src/org/python/jsr223/PyScriptEngine.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1,210 @@ +package org.python.jsr223; + +import java.lang.reflect.Method; +import org.python.core.*; +import java.io.Reader; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import javax.script.AbstractScriptEngine; +import javax.script.Bindings; +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.Invocable; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptException; +import javax.script.SimpleBindings; +import org.python.util.PythonInterpreter; + +public class PyScriptEngine extends AbstractScriptEngine implements Compilable, Invocable { + + private final PythonInterpreter interp; + private final ScriptEngineFactory factory; + private final PyModule module; + + PyScriptEngine(ScriptEngineFactory factory) { + this.factory = factory; + interp = new PythonInterpreter(new PyScriptEngineScope(this, context)); + module = (PyModule)Py.getSystemState().modules.__finditem__("__main__"); + } + + public Object eval(String script, ScriptContext context) throws ScriptException { + return eval(compileScript(script, context)); + } + + private Object eval(PyCode code) throws ScriptException { + try { + return interp.eval(code).__tojava__(Object.class); + } catch (PyException pye) { + throw scriptException(pye); + } + } + + public Object eval(Reader reader, ScriptContext context) throws ScriptException { + return eval(compileScript(reader, context)); + } + + public Bindings createBindings() { + return new SimpleBindings(); + } + + public ScriptEngineFactory getFactory() { + return factory; + } + + public CompiledScript compile(String script) throws ScriptException { + return new PyCompiledScript(compileScript(script, context)); + } + + public CompiledScript compile(Reader reader) throws ScriptException { + return new PyCompiledScript(compileScript(reader, context)); + } + + private PyCode compileScript(String script, ScriptContext context) throws ScriptException { + try { + String filename = (String) context.getAttribute(ScriptEngine.FILENAME); + if (filename == null) + return interp.compile(script); + else + return interp.compile(script, filename); + } catch (PyException pye) { + throw scriptException(pye); + } + } + + private PyCode compileScript(Reader reader, ScriptContext context) throws ScriptException { + try { + String filename = (String) context.getAttribute(ScriptEngine.FILENAME); + if (filename == null) + return interp.compile(reader); + else + return interp.compile(reader, filename); + } catch (PyException pye) { + throw scriptException(pye); + } + } + + public Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException { + try { + if (!(thiz instanceof PyObject)) + thiz = Py.java2py(thiz); + return ((PyObject) thiz).invoke(name, java2py(args)).__tojava__(Object.class); + } catch (PyException pye) { + return throwInvokeException(pye, name); + } + } + + public Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException { + try { + PyObject function = interp.get(name); + if (function == null) + throw new NoSuchMethodException(name); + return function.__call__(java2py(args)).__tojava__(Object.class); + } catch (PyException pye) { + return throwInvokeException(pye, name); + } + } + + public <T> T getInterface(Class<T> clazz) { + return getInterface(module, clazz); + } + + public <T> T getInterface(Object obj, Class<T> clazz) { + if (obj == null) + throw new IllegalArgumentException("object expected"); + if (clazz == null || !clazz.isInterface()) + throw new IllegalArgumentException("interface expected"); + final Object thiz = Py.java2py(obj); + return (T) Proxy.newProxyInstance( + clazz.getClassLoader(), + new Class[] { clazz }, + new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + try { + return ((PyObject) thiz).invoke(method.getName(), java2py(args)).__tojava__(Object.class); + } catch (PyException pye) { + return throwInvokeException(pye, method.getName()); + } + } + }); + } + + private static Object throwInvokeException(PyException pye, String methodName) + throws ScriptException, NoSuchMethodException { + if (pye.match(Py.AttributeError)) { + throw new NoSuchMethodException(methodName); + } + throw scriptException(pye); + } + + private static ScriptException scriptException(PyException pye) { + ScriptException se = null; + try { + pye.normalize(); + + PyObject type = pye.type; + PyObject value = pye.value; + PyTraceback tb = pye.traceback; + + if (__builtin__.isinstance(value, Py.SyntaxError)) { + PyObject filename = value.__findattr__("filename"); + PyObject lineno = value.__findattr__("lineno"); + PyObject offset = value.__findattr__("offset"); + value = value.__findattr__("msg"); + + se = new ScriptException( + Py.formatException(type, value), + filename == null ? "<script>" : filename.toString(), + lineno == null ? 0 : lineno.asInt(), + offset == null ? 0 : offset.asInt()); + } else if (tb != null) { + String filename; + if (tb.tb_frame == null || tb.tb_frame.f_code == null) + filename = null; + else + filename = tb.tb_frame.f_code.co_filename; + + se = new ScriptException( + Py.formatException(type, value), + filename, + tb.tb_lineno); + } else { + se = new ScriptException(Py.formatException(type, value)); + } + se.initCause(pye); + return se; + } catch (Exception ee) { + se = new ScriptException(pye); + } + return se; + } + + private static PyObject[] java2py(Object[] args) { + PyObject wrapped[] = new PyObject[args.length]; + for (int i = 0; i < args.length; i++) { + wrapped[i] = Py.java2py(args[i]); + } + return wrapped; + } + + private class PyCompiledScript extends CompiledScript { + private PyCode code; + private PySystemState systemState; + + PyCompiledScript(PyCode code) { + this.code = code; + this.systemState = Py.getSystemState(); + } + + public ScriptEngine getEngine() { + return PyScriptEngine.this; + } + + public Object eval(ScriptContext ctx) throws ScriptException { + // can't read filename from context at this point + Py.setSystemState(systemState); + return PyScriptEngine.this.eval(code); + } + } +} Deleted: trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngineFactory.java 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,95 +0,0 @@ -package org.python.jsr223; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import org.python.Version; -import org.python.core.Py; - -public class PyScriptEngineFactory implements ScriptEngineFactory { - - public String getEngineName() { - return "jython"; - } - - public String getEngineVersion() { - return String.format("%s.%s.%s", Version.PY_MAJOR_VERSION, Version.PY_MINOR_VERSION, Version.PY_MICRO_VERSION); - } - - public List<String> getExtensions() { - return Collections.unmodifiableList(Arrays.asList("py")); - } - - public String getLanguageName() { - return "python"; - } - - public String getLanguageVersion() { - return "2.5.0"; - } - - public Object getParameter(String key) { - if (key.equals(ScriptEngine.ENGINE)) { - return getEngineName(); - } else if (key.equals(ScriptEngine.ENGINE_VERSION)) { - return getEngineVersion(); - } else if (key.equals(ScriptEngine.NAME)) { - return getEngineName(); - } else if (key.equals(ScriptEngine.LANGUAGE)) { - return getLanguageName(); - } else if (key.equals(ScriptEngine.LANGUAGE_VERSION)) { - return getLanguageVersion(); - } else if (key.equals("THREADING")) { - return "MULTITHREADED"; - } else { - return null; - } - - } - - public String getMethodCallSyntax(String obj, String m, String... args) { - StringBuilder buffer = new StringBuilder(); - buffer.append(String.format("%s.%s(", obj, m)); - int i = args.length; - for (String arg : args) { - buffer.append(arg); - if (i-- > 0) { - buffer.append(", "); - } - } - buffer.append(")"); - return buffer.toString(); - } - - // presumably a unicode string - public String getOutputStatement(String toDisplay) { - StringBuilder buffer = new StringBuilder(toDisplay.length() + 8); - buffer.append("print "); - buffer.append(Py.newUnicode(toDisplay).__repr__()); - return buffer.toString(); - } - - public String getProgram(String... statements) { - StringBuilder buffer = new StringBuilder(); - for (String statement : statements) { - buffer.append(statement); - buffer.append("\n"); - } - return buffer.toString(); - } - - public ScriptEngine getScriptEngine() { - return new PyScriptEngine(this); - } - - public List<String> getMimeTypes() { - return Collections.EMPTY_LIST; - } - - public List<String> getNames() { - return Collections.unmodifiableList(Arrays.asList("python", "jython")); - } - -} Copied: trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java (from rev 6565, branches/jsr223/src/org/python/jsr223/PyScriptEngineFactory.java) =================================================================== --- trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java (rev 0) +++ trunk/jython/src/org/python/jsr223/PyScriptEngineFactory.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1,95 @@ +package org.python.jsr223; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import org.python.Version; +import org.python.core.Py; + +public class PyScriptEngineFactory implements ScriptEngineFactory { + + public String getEngineName() { + return "jython"; + } + + public String getEngineVersion() { + return String.format("%s.%s.%s", Version.PY_MAJOR_VERSION, Version.PY_MINOR_VERSION, Version.PY_MICRO_VERSION); + } + + public List<String> getExtensions() { + return Collections.unmodifiableList(Arrays.asList("py")); + } + + public String getLanguageName() { + return "python"; + } + + public String getLanguageVersion() { + return "2.5.0"; + } + + public Object getParameter(String key) { + if (key.equals(ScriptEngine.ENGINE)) { + return getEngineName(); + } else if (key.equals(ScriptEngine.ENGINE_VERSION)) { + return getEngineVersion(); + } else if (key.equals(ScriptEngine.NAME)) { + return getEngineName(); + } else if (key.equals(ScriptEngine.LANGUAGE)) { + return getLanguageName(); + } else if (key.equals(ScriptEngine.LANGUAGE_VERSION)) { + return getLanguageVersion(); + } else if (key.equals("THREADING")) { + return "MULTITHREADED"; + } else { + return null; + } + + } + + public String getMethodCallSyntax(String obj, String m, String... args) { + StringBuilder buffer = new StringBuilder(); + buffer.append(String.format("%s.%s(", obj, m)); + int i = args.length; + for (String arg : args) { + buffer.append(arg); + if (i-- > 0) { + buffer.append(", "); + } + } + buffer.append(")"); + return buffer.toString(); + } + + // presumably a unicode string + public String getOutputStatement(String toDisplay) { + StringBuilder buffer = new StringBuilder(toDisplay.length() + 8); + buffer.append("print "); + buffer.append(Py.newUnicode(toDisplay).__repr__()); + return buffer.toString(); + } + + public String getProgram(String... statements) { + StringBuilder buffer = new StringBuilder(); + for (String statement : statements) { + buffer.append(statement); + buffer.append("\n"); + } + return buffer.toString(); + } + + public ScriptEngine getScriptEngine() { + return new PyScriptEngine(this); + } + + public List<String> getMimeTypes() { + return Collections.EMPTY_LIST; + } + + public List<String> getNames() { + return Collections.unmodifiableList(Arrays.asList("python", "jython")); + } + +} Deleted: trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java =================================================================== --- branches/jsr223/src/org/python/jsr223/PyScriptEngineScope.java 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,101 +0,0 @@ -package org.python.jsr223; - -import java.util.List; -import javax.script.Bindings; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import org.python.core.Py; -import org.python.core.PyList; -import org.python.core.PyObject; -import org.python.core.PyString; -import org.python.core.PyType; -import org.python.expose.ExposedType; -import org.python.expose.ExposedGet; -import org.python.expose.ExposedMethod; - -@ExposedType(name = "scope", isBaseType = false) -public final class PyScriptEngineScope extends PyObject { - public static final PyType TYPE = PyType.fromClass(PyScriptEngineScope.class); - - private final ScriptContext context; - private final ScriptEngine engine; - - PyScriptEngineScope(ScriptEngine engine, ScriptContext context) { - this.context = context; - this.engine = engine; - } - - @ExposedGet(name = "context") - public PyObject pyGetContext() { - return Py.java2py(context); - } - - @ExposedGet(name = "engine") - public PyObject pyGetEngine() { - return Py.java2py(engine); - } - - @ExposedMethod - public PyObject scope_keys() { - PyList members = new PyList(); - synchronized (context) { - List<Integer> scopes = context.getScopes(); - for (int scope : scopes) { - Bindings bindings = context.getBindings(scope); - if (bindings == null) - continue; - for (String key : bindings.keySet()) - members.append(new PyString(key)); - } - } - members.sort(); - return members; - } - - // Not necessary for functionality; present to satisfy __builtin__.PyMapping_check - @ExposedMethod - public PyObject __getitem__(PyObject key) { - return super.__getitem__(key); - } - - public PyObject __finditem__(PyObject key) { - return __finditem__(key.asString()); - } - - public PyObject __finditem__(String key) { - synchronized (context) { - int scope = context.getAttributesScope(key); - if (scope == -1) - return null; - return Py.java2py(context.getAttribute(key, scope)); - } - } - - @ExposedMethod - public void __setitem__(PyObject key, PyObject value) { - __setitem__(key.asString(), value); - } - - public void __setitem__(String key, PyObject value) { - synchronized (context) { - int scope = context.getAttributesScope(key); - if (scope == -1) - scope = ScriptContext.ENGINE_SCOPE; - context.setAttribute(key, value.__tojava__(Object.class), scope); - } - } - - @ExposedMethod - public void __delitem__(PyObject key) { - __delitem__(key.asString()); - } - - public void __delitem__(String key) { - synchronized (context) { - int scope = context.getAttributesScope(key); - if (scope == -1) - throw Py.KeyError(key); - context.removeAttribute(key, scope); - } - } -} Copied: trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java (from rev 6565, branches/jsr223/src/org/python/jsr223/PyScriptEngineScope.java) =================================================================== --- trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java (rev 0) +++ trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1,101 @@ +package org.python.jsr223; + +import java.util.List; +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import org.python.core.Py; +import org.python.core.PyList; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PyType; +import org.python.expose.ExposedType; +import org.python.expose.ExposedGet; +import org.python.expose.ExposedMethod; + +@ExposedType(name = "scope", isBaseType = false) +public final class PyScriptEngineScope extends PyObject { + public static final PyType TYPE = PyType.fromClass(PyScriptEngineScope.class); + + private final ScriptContext context; + private final ScriptEngine engine; + + PyScriptEngineScope(ScriptEngine engine, ScriptContext context) { + this.context = context; + this.engine = engine; + } + + @ExposedGet(name = "context") + public PyObject pyGetContext() { + return Py.java2py(context); + } + + @ExposedGet(name = "engine") + public PyObject pyGetEngine() { + return Py.java2py(engine); + } + + @ExposedMethod + public PyObject scope_keys() { + PyList members = new PyList(); + synchronized (context) { + List<Integer> scopes = context.getScopes(); + for (int scope : scopes) { + Bindings bindings = context.getBindings(scope); + if (bindings == null) + continue; + for (String key : bindings.keySet()) + members.append(new PyString(key)); + } + } + members.sort(); + return members; + } + + // Not necessary for functionality; present to satisfy __builtin__.PyMapping_check + @ExposedMethod + public PyObject __getitem__(PyObject key) { + return super.__getitem__(key); + } + + public PyObject __finditem__(PyObject key) { + return __finditem__(key.asString()); + } + + public PyObject __finditem__(String key) { + synchronized (context) { + int scope = context.getAttributesScope(key); + if (scope == -1) + return null; + return Py.java2py(context.getAttribute(key, scope)); + } + } + + @ExposedMethod + public void __setitem__(PyObject key, PyObject value) { + __setitem__(key.asString(), value); + } + + public void __setitem__(String key, PyObject value) { + synchronized (context) { + int scope = context.getAttributesScope(key); + if (scope == -1) + scope = ScriptContext.ENGINE_SCOPE; + context.setAttribute(key, value.__tojava__(Object.class), scope); + } + } + + @ExposedMethod + public void __delitem__(PyObject key) { + __delitem__(key.asString()); + } + + public void __delitem__(String key) { + synchronized (context) { + int scope = context.getAttributesScope(key); + if (scope == -1) + throw Py.KeyError(key); + context.removeAttribute(key, scope); + } + } +} Modified: trunk/jython/src/org/python/util/PythonInterpreter.java =================================================================== --- trunk/jython/src/org/python/util/PythonInterpreter.java 2009-07-23 03:26:56 UTC (rev 6566) +++ trunk/jython/src/org/python/util/PythonInterpreter.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,10 +1,17 @@ package org.python.util; +import java.io.FilterReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; import java.util.Properties; +import org.python.antlr.base.mod; import org.python.core.CompileMode; import org.python.core.CompilerFlags; +import org.python.core.ParserFacade; import org.python.core.Py; +import org.python.core.PyCode; import org.python.core.PyException; import org.python.core.PyFile; import org.python.core.PyFileWriter; @@ -12,6 +19,7 @@ import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyStringMap; +import org.python.core.PySyntaxError; import org.python.core.PySystemState; import org.python.core.__builtin__; @@ -131,6 +139,14 @@ } /** + * Evaluate a Python code object and return the result + */ + public PyObject eval(PyObject code) { + setState(); + return __builtin__.eval(code, locals, locals); + } + + /** * Execute a string of Python source in the local namespace */ public void exec(String s) { @@ -167,6 +183,29 @@ Py.flushLine(); } + /** + * Compile a string of Python source as either an expression (if possible) or module. + * + * Designed for use by a JSR 223 implementation: "the Scripting API does not distinguish + * between scripts which return values and those which do not, nor do they make the + * corresponding distinction between evaluating or executing objects." (SCR.4.2.1) + */ + public PyCode compile(String script) { + return compile(script, "<script>"); + } + public PyCode compile(Reader reader) { + return compile(reader, "<script>"); + } + public PyCode compile(String script, String filename) { + return compile(new StringReader(script), filename); + } + public PyCode compile(Reader reader, String filename) { + mod node = ParserFacade.parseExpressionOrModule(reader, filename, cflags); + setState(); + return Py.compile_flags(node, filename, CompileMode.eval, cflags); + } + + public PyObject getLocals() { return locals; } Deleted: trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java =================================================================== --- branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-23 03:12:52 UTC (rev 6565) +++ trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -1,156 +0,0 @@ -package org.python.jsr223; - -import java.io.IOException; -import java.io.StringReader; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.Invocable; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import javax.script.SimpleScriptContext; -import junit.framework.TestCase; -import org.python.core.PyString; - -public class ScriptEngineTest extends TestCase { - - public void testEvalString() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - assertNull(pythonEngine.eval("x = 5")); - assertEquals(Integer.valueOf(5), pythonEngine.eval("x")); - } - - public void testSyntaxError() { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - try { - pythonEngine.eval("5q"); - } catch (ScriptException e) { - assertEquals(e.getColumnNumber(), 1); - assertEquals(e.getLineNumber(), 1); - assertTrue(e.getMessage().startsWith("SyntaxError: ")); - return; - } - assertTrue("Expected a ScriptException", false); - } - - public void testPythonException() { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - try { - pythonEngine.eval("pass\ndel undefined"); - } catch (ScriptException e) { - assertEquals(e.getLineNumber(), 2); - assertTrue(e.getMessage().startsWith("NameError: ")); - return; - } - assertTrue("Expected a ScriptException", false); - } - - public void testScriptFilename() { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - SimpleScriptContext scriptContext = new SimpleScriptContext(); - scriptContext.setAttribute(ScriptEngine.FILENAME, "sample.py", ScriptContext.ENGINE_SCOPE); - try { - pythonEngine.eval("foo", scriptContext); - } catch (ScriptException e) { - assertEquals("sample.py", e.getFileName()); - return; - } - assertTrue("Expected a ScriptException", false); - } - - public void testCompileEvalString() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - CompiledScript five = ((Compilable)pythonEngine).compile("5"); - assertEquals(Integer.valueOf(5), five.eval()); - } - - public void testEvalReader() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - assertNull(pythonEngine.eval(new StringReader("x = 5"))); - assertEquals(Integer.valueOf(5), pythonEngine.eval(new StringReader("x"))); - } - - public void testCompileEvalReader() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - CompiledScript five = ((Compilable)pythonEngine).compile(new StringReader("5")); - assertEquals(Integer.valueOf(5), five.eval()); - } - - public void testBindings() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - - pythonEngine.put("a", 42); - assertEquals(Integer.valueOf(42), pythonEngine.eval("a")); - assertNull(pythonEngine.eval("x = 5")); - assertEquals(Integer.valueOf(5), pythonEngine.get("x")); - assertNull(pythonEngine.eval("del x")); - assertNull(pythonEngine.get("x")); - } - - public void testInvoke() throws ScriptException, NoSuchMethodException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - Invocable invocableEngine = (Invocable)pythonEngine; - - assertNull(pythonEngine.eval("def f(x): return abs(x)")); - assertEquals(Integer.valueOf(5), invocableEngine.invokeFunction("f", Integer.valueOf(-5))); - assertEquals("spam", invocableEngine.invokeMethod(new PyString(" spam "), "strip")); - assertEquals("spam", invocableEngine.invokeMethod(" spam ", "strip")); - } - - public void testInvokeFunctionNoSuchMethod() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); - - try { - invocableEngine.invokeFunction("undefined"); - } catch (NoSuchMethodException e) { - return; - } - assertTrue("Expected a NoSuchMethodException", false); - } - - public void testInvokeMethodNoSuchMethod() throws ScriptException { - ScriptEngineManager manager = new ScriptEngineManager(); - Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); - - try { - invocableEngine.invokeMethod("eggs", "undefined"); - } catch (NoSuchMethodException e) { - return; - } - assertTrue("Expected a NoSuchMethodException", false); - } - - public void testGetInterface() throws ScriptException, IOException { - ScriptEngineManager manager = new ScriptEngineManager(); - ScriptEngine pythonEngine = manager.getEngineByName("python"); - Invocable invocableEngine = (Invocable)pythonEngine; - - assertNull(pythonEngine.eval("def read(cb): return 1")); - Readable readable = invocableEngine.getInterface(Readable.class); - assertEquals(1, readable.read(null)); - - assertNull(pythonEngine.eval( - "class C(object):\n" + - " def read(self, cb): return 2\n" + - "c = C()")); - readable = invocableEngine.getInterface(pythonEngine.get("c"), Readable.class); - assertEquals(2, readable.read(null)); - } -} Copied: trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java (from rev 6565, branches/jsr223/tests/java/org/python/jsr223/ScriptEngineTest.java) =================================================================== --- trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java (rev 0) +++ trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java 2009-07-23 05:14:58 UTC (rev 6567) @@ -0,0 +1,156 @@ +package org.python.jsr223; + +import java.io.IOException; +import java.io.StringReader; +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.Invocable; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import javax.script.SimpleScriptContext; +import junit.framework.TestCase; +import org.python.core.PyString; + +public class ScriptEngineTest extends TestCase { + + public void testEvalString() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + assertNull(pythonEngine.eval("x = 5")); + assertEquals(Integer.valueOf(5), pythonEngine.eval("x")); + } + + public void testSyntaxError() { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + try { + pythonEngine.eval("5q"); + } catch (ScriptException e) { + assertEquals(e.getColumnNumber(), 1); + assertEquals(e.getLineNumber(), 1); + assertTrue(e.getMessage().startsWith("SyntaxError: ")); + return; + } + assertTrue("Expected a ScriptException", false); + } + + public void testPythonException() { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + try { + pythonEngine.eval("pass\ndel undefined"); + } catch (ScriptException e) { + assertEquals(e.getLineNumber(), 2); + assertTrue(e.getMessage().startsWith("NameError: ")); + return; + } + assertTrue("Expected a ScriptException", false); + } + + public void testScriptFilename() { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + SimpleScriptContext scriptContext = new SimpleScriptContext(); + scriptContext.setAttribute(ScriptEngine.FILENAME, "sample.py", ScriptContext.ENGINE_SCOPE); + try { + pythonEngine.eval("foo", scriptContext); + } catch (ScriptException e) { + assertEquals("sample.py", e.getFileName()); + return; + } + assertTrue("Expected a ScriptException", false); + } + + public void testCompileEvalString() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + CompiledScript five = ((Compilable)pythonEngine).compile("5"); + assertEquals(Integer.valueOf(5), five.eval()); + } + + public void testEvalReader() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + assertNull(pythonEngine.eval(new StringReader("x = 5"))); + assertEquals(Integer.valueOf(5), pythonEngine.eval(new StringReader("x"))); + } + + public void testCompileEvalReader() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + CompiledScript five = ((Compilable)pythonEngine).compile(new StringReader("5")); + assertEquals(Integer.valueOf(5), five.eval()); + } + + public void testBindings() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + pythonEngine.put("a", 42); + assertEquals(Integer.valueOf(42), pythonEngine.eval("a")); + assertNull(pythonEngine.eval("x = 5")); + assertEquals(Integer.valueOf(5), pythonEngine.get("x")); + assertNull(pythonEngine.eval("del x")); + assertNull(pythonEngine.get("x")); + } + + public void testInvoke() throws ScriptException, NoSuchMethodException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + Invocable invocableEngine = (Invocable)pythonEngine; + + assertNull(pythonEngine.eval("def f(x): return abs(x)")); + assertEquals(Integer.valueOf(5), invocableEngine.invokeFunction("f", Integer.valueOf(-5))); + assertEquals("spam", invocableEngine.invokeMethod(new PyString(" spam "), "strip")); + assertEquals("spam", invocableEngine.invokeMethod(" spam ", "strip")); + } + + public void testInvokeFunctionNoSuchMethod() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); + + try { + invocableEngine.invokeFunction("undefined"); + } catch (NoSuchMethodException e) { + return; + } + assertTrue("Expected a NoSuchMethodException", false); + } + + public void testInvokeMethodNoSuchMethod() throws ScriptException { + ScriptEngineManager manager = new ScriptEngineManager(); + Invocable invocableEngine = (Invocable)manager.getEngineByName("python"); + + try { + invocableEngine.invokeMethod("eggs", "undefined"); + } catch (NoSuchMethodException e) { + return; + } + assertTrue("Expected a NoSuchMethodException", false); + } + + public void testGetInterface() throws ScriptException, IOException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + Invocable invocableEngine = (Invocable)pythonEngine; + + assertNull(pythonEngine.eval("def read(cb): return 1")); + Readable readable = invocableEngine.getInterface(Readable.class); + assertEquals(1, readable.read(null)); + + assertNull(pythonEngine.eval( + "class C(object):\n" + + " def read(self, cb): return 2\n" + + "c = C()")); + readable = invocableEngine.getInterface(pythonEngine.get("c"), Readable.class); + assertEquals(2, readable.read(null)); + } +} Property changes on: trunk/jython/tests/java/org/python/tests/RedundantInterfaceDeclarations.java ___________________________________________________________________ Modified: svn:mergeinfo - + /branches/jsr223/tests/java/org/python/tests/RedundantInterfaceDeclarations.java:6285-6565 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-23 07:38:03
|
Revision: 6571 http://jython.svn.sourceforge.net/jython/?rev=6571&view=rev Author: nriley Date: 2009-07-23 07:37:58 +0000 (Thu, 23 Jul 2009) Log Message: ----------- Support JSR 223 on JDK 5 with LiveTribe implementation; update NEWS. Modified Paths: -------------- trunk/jython/NEWS trunk/jython/build.xml Added Paths: ----------- trunk/jython/extlibs/livetribe-jsr223-2.0.5.jar Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-07-23 06:31:56 UTC (rev 6570) +++ trunk/jython/NEWS 2009-07-23 07:37:58 UTC (rev 6571) @@ -6,6 +6,7 @@ - [ 1859477 ] Dynamically loaded ServletFilters like PyServlet - Setting __javaname__ in classes subclassing Java classes or implementing Java interfaces sets the name of the produced proxy class. + - Built in JSR 223 scripting engine, with LiveTribe JSR 223 implementation for JDK 5 Bugs Fixed - [ 645615 ] cannot import through symbolic links - [ 1366 ] parsing of lamda expression fails @@ -14,6 +15,8 @@ - [ 1381 ] Redundant declarations of interface implementation hides overriden methods - [ 1189 ] MD5 hash is incorrectly calculated when string contains non-latin chars and using python md5 lib - [ 1802339 ] Problem printing unicode when stdout intercepted + - [ 1145 ] Jython 2.5 compatibility problem with JSR 223 + - [ 1400 ] Evaluating expression via JSR 223 ScriptEngine returns null instead of True/False Jython 2.5.0 The same as rc4. Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-07-23 06:31:56 UTC (rev 6570) +++ trunk/jython/build.xml 2009-07-23 07:37:58 UTC (rev 6571) @@ -185,6 +185,7 @@ <pathelement path="${extlibs.dir}/antlr-2.7.7.jar" /> <pathelement path="${extlibs.dir}/antlr-3.1.3.jar" /> <pathelement path="${extlibs.dir}/stringtemplate-3.2.jar" /> + <pathelement path="${extlibs.dir}/livetribe-jsr223-2.0.5.jar" /> <pathelement path="${extlibs.dir}/asm-3.1.jar" /> <pathelement path="${extlibs.dir}/asm-commons-3.1.jar" /> Added: trunk/jython/extlibs/livetribe-jsr223-2.0.5.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/livetribe-jsr223-2.0.5.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-07-27 19:30:14
|
Revision: 6593 http://jython.svn.sourceforge.net/jython/?rev=6593&view=rev Author: fwierzbicki Date: 2009-07-27 19:30:01 +0000 (Mon, 27 Jul 2009) Log Message: ----------- Get our Lexer to properly fail for trailing whitespace in single mode. Modified Paths: -------------- trunk/jython/Lib/test/test_codeop.py trunk/jython/grammar/Python.g trunk/jython/src/org/python/antlr/BaseParser.java Modified: trunk/jython/Lib/test/test_codeop.py =================================================================== --- trunk/jython/Lib/test/test_codeop.py 2009-07-27 17:22:32 UTC (rev 6592) +++ trunk/jython/Lib/test/test_codeop.py 2009-07-27 19:30:01 UTC (rev 6593) @@ -133,8 +133,8 @@ ai("def x():\n\n") ai("def x():\n pass") - #ai("def x():\n pass\n ") - #ai("def x():\n pass\n ") + ai("def x():\n pass\n ") + ai("def x():\n pass\n ") ai("\n\ndef x():\n pass") ai("a = 9+ \\") Modified: trunk/jython/grammar/Python.g =================================================================== --- trunk/jython/grammar/Python.g 2009-07-27 17:22:32 UTC (rev 6592) +++ trunk/jython/grammar/Python.g 2009-07-27 19:30:01 UTC (rev 6593) @@ -209,6 +209,7 @@ //For use in partial parsing. public boolean eofWhileNested = false; public boolean partial = false; +public boolean single = false; int implicitLineJoiningLevel = 0; int startPos=-1; @@ -1967,6 +1968,8 @@ $channel=HIDDEN; } } + } else if (this.single && newlines == 1) { + throw new ParseException("Trailing space in single mode."); } else { // make a string of n newlines char[] nls = new char[newlines]; Modified: trunk/jython/src/org/python/antlr/BaseParser.java =================================================================== --- trunk/jython/src/org/python/antlr/BaseParser.java 2009-07-27 17:22:32 UTC (rev 6592) +++ trunk/jython/src/org/python/antlr/BaseParser.java 2009-07-27 19:30:01 UTC (rev 6593) @@ -32,10 +32,16 @@ } public static class PyLexer extends PythonLexer { - public PyLexer(CharStream lexer) { + public PyLexer(CharStream lexer, boolean single) { super(lexer); + this.single = single; } + public PyLexer(CharStream lexer) { + this(lexer, false); + } + + public Token nextToken() { startPos = getCharPositionInLine(); return super.nextToken(); @@ -53,12 +59,8 @@ } } - private CharStream charStream(boolean single) { - return charStream; - } - private PythonParser setupParser(boolean single) { - PythonLexer lexer = new PyLexer(this.charStream(single)); + PythonLexer lexer = new PyLexer(charStream, single); lexer.setErrorHandler(errorHandler); CommonTokenStream tokens = new CommonTokenStream(lexer); PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename, single); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-07-27 20:39:19
|
Revision: 6594 http://jython.svn.sourceforge.net/jython/?rev=6594&view=rev Author: fwierzbicki Date: 2009-07-27 20:39:10 +0000 (Mon, 27 Jul 2009) Log Message: ----------- Now handling trailing backslashes in single mode more like CPython. Modified Paths: -------------- trunk/jython/Lib/test/test_codeop.py trunk/jython/grammar/PythonPartial.g Modified: trunk/jython/Lib/test/test_codeop.py =================================================================== --- trunk/jython/Lib/test/test_codeop.py 2009-07-27 19:30:01 UTC (rev 6593) +++ trunk/jython/Lib/test/test_codeop.py 2009-07-27 20:39:10 UTC (rev 6594) @@ -168,9 +168,9 @@ ai("\n\n if 1: pass\n\npass") - #ai("a = 9+ \\\n") + ai("a = 9+ \\\n") ai("a = 'a\\ ") - #ai("a = 'a\\\n") + ai("a = 'a\\\n") ai("a = 1","eval") #ai("a = (","eval") Modified: trunk/jython/grammar/PythonPartial.g =================================================================== --- trunk/jython/grammar/PythonPartial.g 2009-07-27 19:30:01 UTC (rev 6593) +++ trunk/jython/grammar/PythonPartial.g 2009-07-27 20:39:10 UTC (rev 6594) @@ -1085,12 +1085,21 @@ * emit a newline. */ CONTINUED_LINE +@init { + boolean extraNewlines = false; +} : '\\' ('\r')? '\n' (' '|'\t')* { $channel=HIDDEN; } ( COMMENT | nl=NEWLINE + { + extraNewlines = true; + } | ) { if (input.LA(1) == -1) { + if (extraNewlines) { + throw new ParseException("invalid syntax"); + } emit(new CommonToken(TRAILBACKSLASH,"\\")); } } @@ -1103,10 +1112,7 @@ * Frank Wierzbicki added: Also ignore FORMFEEDS (\u000C). */ NEWLINE -@init { - int newlines = 0; -} - : (('\u000C')?('\r')? '\n' {newlines++; } )+ { + : (('\u000C')?('\r')? '\n' )+ { if ( startPos==0 || implicitLineJoiningLevel>0 ) $channel=HIDDEN; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-07-30 14:43:05
|
Revision: 6607 http://jython.svn.sourceforge.net/jython/?rev=6607&view=rev Author: fwierzbicki Date: 2009-07-30 14:42:55 +0000 (Thu, 30 Jul 2009) Log Message: ----------- Statement "try:" was not working in interactive mode. Added tests for the basic try: partial sentences. Modified Paths: -------------- trunk/jython/Lib/test/test_codeop.py trunk/jython/grammar/PythonPartial.g Modified: trunk/jython/Lib/test/test_codeop.py =================================================================== --- trunk/jython/Lib/test/test_codeop.py 2009-07-30 14:36:21 UTC (rev 6606) +++ trunk/jython/Lib/test/test_codeop.py 2009-07-30 14:42:55 UTC (rev 6607) @@ -195,6 +195,11 @@ ai("(a,b") ai("(a,b,") + ai("try:") + ai("try:\n pass\nexcept:") + ai("try:\n pass\nfinally:") + ai("try:\n pass\nexcept:\n pass\nfinally:") + def test_invalid(self): ai = self.assertInvalid ai("a b") Modified: trunk/jython/grammar/PythonPartial.g =================================================================== --- trunk/jython/grammar/PythonPartial.g 2009-07-30 14:36:21 UTC (rev 6606) +++ trunk/jython/grammar/PythonPartial.g 2009-07-30 14:42:55 UTC (rev 6607) @@ -522,7 +522,7 @@ : TRY COLON suite ( except_clause+ (ORELSE COLON suite)? (FINALLY COLON suite)? | FINALLY COLON suite - ) + )? ; //with_stmt: 'with' test [ with_var ] ':' suite This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2009-07-31 19:20:35
|
Revision: 6618 http://jython.svn.sourceforge.net/jython/?rev=6618&view=rev Author: nriley Date: 2009-07-31 19:20:24 +0000 (Fri, 31 Jul 2009) Log Message: ----------- stdin redirection for JSR 223 and PythonInterpreter, contributed by Jim White. Fixes #1408. Modified Paths: -------------- trunk/jython/src/org/python/core/PyFileWriter.java trunk/jython/src/org/python/jsr223/PyScriptEngine.java trunk/jython/src/org/python/util/PythonInterpreter.java Added Paths: ----------- trunk/jython/src/org/python/core/PyFileReader.java trunk/jython/tests/java/org/python/jsr223/ScriptEngineIOTest.java Added: trunk/jython/src/org/python/core/PyFileReader.java =================================================================== --- trunk/jython/src/org/python/core/PyFileReader.java (rev 0) +++ trunk/jython/src/org/python/core/PyFileReader.java 2009-07-31 19:20:24 UTC (rev 6618) @@ -0,0 +1,176 @@ +// A file-like object for reading from java.io.Reader objects; +// only to be used for stdin in PythonInterpreter#setIn(Reader) +// (for JSR 223 support) + +package org.python.core; + +import java.io.Reader; +import java.io.IOException; +import java.io.BufferedReader; + + +public class PyFileReader extends PyObject +{ + static final int DEFAULT_BUF_SIZE = 1024; + + private final BufferedReader reader; + private boolean closed; + + private char[] reuseableBuffer = null; + + public PyFileReader(Reader reader) + { + this.reader = (reader instanceof BufferedReader) ? (BufferedReader) reader : new BufferedReader(reader); + 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(); + } + + public void close() + { + try { + if (!closed()) { + reader.close(); + closed = true; + } + } catch (IOException e) { + throw Py.IOError(e); + } + } + + protected char[] needBuffer(int size) + { + if (reuseableBuffer == null) { + if (size > DEFAULT_BUF_SIZE) + return new char[size]; + + reuseableBuffer = new char[DEFAULT_BUF_SIZE]; + } + + if (size <= reuseableBuffer.length) + return reuseableBuffer; + + return new char[size]; + } + + public PyString read(int n) + { + if (n < 0) { + synchronized(reader) { + checkClosed(); + + final StringBuilder sb = new StringBuilder(); + + final char[] cbuf = needBuffer(DEFAULT_BUF_SIZE); + final int buflen = cbuf.length; + + while (true) { + try { + final int x = reader.read(cbuf, 0, buflen); + + if (x < 0) + break; + + sb.append(cbuf, 0, x); + + if (x < buflen) + break; + } catch (IOException e) { + throw Py.IOError(e); + } + } + + return new PyString(sb.toString()); + } + } + + synchronized(reader) { + checkClosed(); + + final char[] cbuf = needBuffer(n); + final int buflen = cbuf.length; + + try { + final int x = reader.read(cbuf, 0, n); + + if (x < 1) + return new PyString(""); + + return new PyString(new String(cbuf, 0, x)); + } catch (IOException e) { + throw Py.IOError(e); + } + } + } + + public PyString read() + { + return read(-1); + } + + public PyString readline(int max) + { + if (!(max < 0)) + throw Py.NotImplementedError("size argument to readline not implemented for PyFileReader"); + + synchronized (reader) { + try { + final String line = reader.readLine(); + + if (line == null) { + return new PyString(""); + } else { + return new PyString(line + "\n"); + } + } catch (IOException e) { + throw Py.IOError(e); + } + } + } + + public PyString readline() + { + return readline(-1); + } + + public PyObject readlines(final int sizehint) { + synchronized (reader) { + checkClosed(); + final PyList list = new PyList(); + int size = 0; + do { + final PyString line = readline(-1); + int len = line.string.length(); + if (len == 0) { + // EOF + break; + } + size += len; + list.append(line); + } while (sizehint <= 0 || size < sizehint); + + return list; + } + } + + public PyObject readlines() { + return readlines(0); + } + + +} Modified: trunk/jython/src/org/python/core/PyFileWriter.java =================================================================== --- trunk/jython/src/org/python/core/PyFileWriter.java 2009-07-31 19:20:05 UTC (rev 6617) +++ trunk/jython/src/org/python/core/PyFileWriter.java 2009-07-31 19:20:24 UTC (rev 6618) @@ -1,6 +1,6 @@ // 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) +// (for backwards compatibility and JSR 223 support) // // no attempts to close etc at shutdown are done for this object (unlike PyFile), // since again just for PythonInterpreter Modified: trunk/jython/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- trunk/jython/src/org/python/jsr223/PyScriptEngine.java 2009-07-31 19:20:05 UTC (rev 6617) +++ trunk/jython/src/org/python/jsr223/PyScriptEngine.java 2009-07-31 19:20:24 UTC (rev 6618) @@ -36,6 +36,7 @@ @SuppressWarnings("deprecation") private Object eval(PyCode code, ScriptContext context) throws ScriptException { try { + interp.setIn(context.getReader()); interp.setOut(context.getWriter()); interp.setErr(context.getErrorWriter()); return interp.eval(code).__tojava__(Object.class); Modified: trunk/jython/src/org/python/util/PythonInterpreter.java =================================================================== --- trunk/jython/src/org/python/util/PythonInterpreter.java 2009-07-31 19:20:05 UTC (rev 6617) +++ trunk/jython/src/org/python/util/PythonInterpreter.java 2009-07-31 19:20:24 UTC (rev 6618) @@ -19,6 +19,7 @@ import org.python.core.PyStringMap; import org.python.core.PySystemState; import org.python.core.__builtin__; +import org.python.core.PyFileReader; /** * The PythonInterpreter class is a standard wrapper for a Jython interpreter for use embedding in a @@ -88,6 +89,30 @@ } /** + * Set the Python object to use for the standard input stream + * + * @param inStream + * Python file-like object to use as input stream + */ + public void setIn(PyObject inStream) { + systemState.stdin = inStream; + } + + public void setIn(java.io.Reader inStream) { + setIn(new PyFileReader(inStream)); + } + + /** + * Set a java.io.InputStream to use for the standard input stream + * + * @param inStream + * InputStream to use as input stream + */ + public void setIn(java.io.InputStream inStream) { + setIn(new PyFile(inStream)); + } + + /** * Set the Python object to use for the standard output stream * * @param outStream Added: trunk/jython/tests/java/org/python/jsr223/ScriptEngineIOTest.java =================================================================== --- trunk/jython/tests/java/org/python/jsr223/ScriptEngineIOTest.java (rev 0) +++ trunk/jython/tests/java/org/python/jsr223/ScriptEngineIOTest.java 2009-07-31 19:20:24 UTC (rev 6618) @@ -0,0 +1,81 @@ +package org.python.jsr223; + +import javax.script.ScriptEngine; +import javax.script.ScriptException; +import javax.script.ScriptEngineFactory; + +import junit.framework.TestCase; + +import java.io.StringReader; +import java.io.StringWriter; + +public class ScriptEngineIOTest extends TestCase +{ + ScriptEngineFactory pythonEngineFactory; + ScriptEngine pythonEngine; + + public void setUp() throws ScriptException + { + pythonEngineFactory = new PyScriptEngineFactory(); + pythonEngine = new PyScriptEngine(pythonEngineFactory); + } + + public void testEvalString() throws ScriptException + { + assertNull(pythonEngine.eval("x = 5")); + assertEquals(Integer.valueOf(5), pythonEngine.eval("x")); + } + + public void testReadline() throws ScriptException + { + final String testString = "Shazaam Batman!\n"; + + pythonEngine.getContext().setReader(new StringReader(testString)); + + assertNull(pythonEngine.eval("import sys")); + assertEquals(testString, pythonEngine.eval("sys.stdin.readline()")); + } + + public void testReadlines() throws ScriptException + { + final String testString = "Holy Smokes Batman!\nBIF!\r\n\nKAPOW!!!\rTHE END."; + + pythonEngine.getContext().setReader(new StringReader(testString)); + + assertNull(pythonEngine.eval("import sys")); + final Object o = pythonEngine.eval("''.join(sys.stdin.readlines())"); + + assertEquals("Holy Smokes Batman!\nBIF!\n\nKAPOW!!!\nTHE END.\n", o); + } + + public void testWriter() throws ScriptException + { + final StringWriter sw = new StringWriter(); + + pythonEngine.getContext().setWriter(sw); + + final String testString = "It is a wonderful world."; + + assertNull(pythonEngine.eval("print '" + testString + "',")); + assertEquals(testString, sw.toString()); + } + + public void testErrorWriter() throws ScriptException + { + final StringWriter stdout = new StringWriter(); + final StringWriter stderr = new StringWriter(); + + pythonEngine.getContext().setWriter(stdout); + pythonEngine.getContext().setErrorWriter(stderr); + + final String testString1 = "It is a wonderful world."; + final String testString2 = "Stuff happens!"; + + assertNull(pythonEngine.eval("import sys")); + assertNull(pythonEngine.eval("sys.stdout.write('" + testString1 + "')")); + assertNull(pythonEngine.eval("sys.stderr.write('" + testString2 + "')")); + + assertEquals(testString1, stdout.toString()); + assertEquals(testString2, stderr.toString()); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-08-03 01:14:40
|
Revision: 6626 http://jython.svn.sourceforge.net/jython/?rev=6626&view=rev Author: cgroves Date: 2009-08-02 23:52:18 +0000 (Sun, 02 Aug 2009) Log Message: ----------- Use the Java class name instead of _new_impl for Java constructors. Fixes issue #1393 Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/src/org/python/core/PyJavaType.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2009-08-02 21:30:31 UTC (rev 6625) +++ trunk/jython/Lib/test/test_java_integration.py 2009-08-02 23:52:18 UTC (rev 6626) @@ -36,6 +36,13 @@ def test_str_doesnt_coerce_to_int(self): self.assertRaises(TypeError, Date, '99-01-01', 1, 1) + def test_class_in_failed_constructor(self): + try: + Dimension(123, 456, 789) + except TypeError, exc: + self.failUnless("java.awt.Dimension" in exc.message) + + class BeanTest(unittest.TestCase): def test_shared_names(self): self.failUnless(callable(Vector.size), Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2009-08-02 21:30:31 UTC (rev 6625) +++ trunk/jython/src/org/python/core/PyJavaType.java 2009-08-02 23:52:18 UTC (rev 6626) @@ -457,7 +457,7 @@ dict.__setitem__(prop.__name__, prop); } - final PyReflectedConstructor reflctr = new PyReflectedConstructor("_new_impl"); + final PyReflectedConstructor reflctr = new PyReflectedConstructor(name); Constructor<?>[] constructors; // No matter the security manager, trying to set the constructor on class to accessible // blows up @@ -475,8 +475,7 @@ } if (PyObject.class.isAssignableFrom(forClass)) { PyObject new_ = new PyNewWrapper(forClass, "__new__", -1, -1) { - - public PyObject new_impl(boolean init, + @Override public PyObject new_impl(boolean init, PyType subtype, PyObject[] args, String[] keywords) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-08-04 00:06:26
|
Revision: 6628 http://jython.svn.sourceforge.net/jython/?rev=6628&view=rev Author: thobes Date: 2009-08-04 00:06:16 +0000 (Tue, 04 Aug 2009) Log Message: ----------- Imported patches by "Andrea" for issues 1412 and 1419, also for {PyList,PyTuple}.toArray(Object[]); as well as adding link to core javadoc. Modified Paths: -------------- trunk/jython/build.xml trunk/jython/src/org/python/core/PyList.java trunk/jython/src/org/python/core/PyTuple.java trunk/jython/src/org/python/core/PythonTraceFunction.java Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-08-03 06:30:19 UTC (rev 6627) +++ trunk/jython/build.xml 2009-08-04 00:06:16 UTC (rev 6628) @@ -634,6 +634,7 @@ windowtitle="Jython API documentation" bottom="<a href='http://www.jython.org' target='_top'>Jython homepage</a>" > + <link href="http://java.sun.com/j2se/1.5.0/docs/api/" /> <classpath refid="javadoc.classpath" /> </javadoc> </target> Modified: trunk/jython/src/org/python/core/PyList.java =================================================================== --- trunk/jython/src/org/python/core/PyList.java 2009-08-03 06:30:19 UTC (rev 6627) +++ trunk/jython/src/org/python/core/PyList.java 2009-08-04 00:06:16 UTC (rev 6628) @@ -17,6 +17,8 @@ import java.util.List; import java.util.ListIterator; +import java.lang.reflect.Array; + @ExposedType(name = "list", base = PyObject.class) public class PyList extends PySequenceList implements List { @@ -977,7 +979,7 @@ @Override public synchronized int indexOf(Object o) { - return list.indexOf(o); + return list.indexOf(Py.java2py(o)); } @Override @@ -1134,15 +1136,18 @@ @Override public synchronized Object[] toArray(Object[] a) { - Object copy[] = list.toArray(); - if (a.length < copy.length) { - a = copy; + int size = size(); + Class<?> type = a.getClass().getComponentType(); + if (a.length < size) { + a = (Object[])Array.newInstance(type, size); } - for (int i = 0; i < copy.length; i++) { - a[i] = ((PyObject) copy[i]).__tojava__(Object.class); + for (int i = 0; i < size; i++) { + a[i] = list.get(i).__tojava__(type); } - if (a.length > copy.length) { - a[copy.length] = null; + if (a.length > size) { + for (int i = size; i < a.length; i++) { + a[i] = null; + } } return a; } Modified: trunk/jython/src/org/python/core/PyTuple.java =================================================================== --- trunk/jython/src/org/python/core/PyTuple.java 2009-08-03 06:30:19 UTC (rev 6627) +++ trunk/jython/src/org/python/core/PyTuple.java 2009-08-04 00:06:16 UTC (rev 6628) @@ -7,6 +7,8 @@ import java.util.List; import java.util.ListIterator; +import java.lang.reflect.Array; + import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; @@ -494,7 +496,7 @@ @Override public int indexOf(Object o) { - return getList().indexOf(o); + return getList().indexOf(Py.java2py(o)); } @Override @@ -543,11 +545,12 @@ @Override public Object[] toArray(Object[] converted) { - if (converted.length != array.length) { - converted = new Object[array.length]; + Class<?> type = converted.getClass().getComponentType(); + if (converted.length < array.length) { + converted = (Object[])Array.newInstance(type, array.length); } for (int i = 0; i < array.length; i++) { - converted[i] = array[i].__tojava__(Object.class); + converted[i] = type.cast(array[i].__tojava__(type)); } if (array.length < converted.length) { for (int i = array.length; i < converted.length; i++) { Modified: trunk/jython/src/org/python/core/PythonTraceFunction.java =================================================================== --- trunk/jython/src/org/python/core/PythonTraceFunction.java 2009-08-03 06:30:19 UTC (rev 6627) +++ trunk/jython/src/org/python/core/PythonTraceFunction.java 2009-08-04 00:06:16 UTC (rev 6628) @@ -52,8 +52,9 @@ } public TraceFunction traceException(PyFrame frame, PyException exc) { - return safeCall(frame, - "exception", - new PyTuple(exc.type, exc.value, exc.traceback)); + // We must avoid passing a null to a PyTuple + PyObject safeTraceback = exc.traceback == null ? Py.None : exc.traceback; + return safeCall(frame, "exception", + new PyTuple(exc.type, exc.value, safeTraceback)); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-08-04 19:54:23
|
Revision: 6629 http://jython.svn.sourceforge.net/jython/?rev=6629&view=rev Author: fwierzbicki Date: 2009-08-04 19:54:15 +0000 (Tue, 04 Aug 2009) Log Message: ----------- cleanup of antlr/adapter/*Adapter classes in prep to fix http://bugs.jython.org/issue1415. Checked in change to asdl_antlr.py but haven't applied it yet (since this generates lots of changes in the check in that obscures the real changes). Next checkin will apply the codegen. Modified Paths: -------------- trunk/jython/ast/asdl_antlr.py trunk/jython/src/org/python/antlr/adapter/AliasAdapter.java trunk/jython/src/org/python/antlr/adapter/AstAdapters.java trunk/jython/src/org/python/antlr/adapter/CmpopAdapter.java trunk/jython/src/org/python/antlr/adapter/ComprehensionAdapter.java trunk/jython/src/org/python/antlr/adapter/ExcepthandlerAdapter.java trunk/jython/src/org/python/antlr/adapter/ExprAdapter.java trunk/jython/src/org/python/antlr/adapter/IdentifierAdapter.java trunk/jython/src/org/python/antlr/adapter/KeywordAdapter.java trunk/jython/src/org/python/antlr/adapter/SliceAdapter.java trunk/jython/src/org/python/antlr/adapter/StmtAdapter.java Modified: trunk/jython/ast/asdl_antlr.py =================================================================== --- trunk/jython/ast/asdl_antlr.py 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/ast/asdl_antlr.py 2009-08-04 19:54:15 UTC (rev 6629) @@ -481,10 +481,10 @@ self.emit("@ExposedMethod", depth) self.emit("public void %s___init__(PyObject[] args, String[] keywords) {" % clsname, depth) self.emit('ArgParser ap = new ArgParser("%s", args, keywords, new String[]' % clsname, depth + 1) - self.emit('{%s}, %s);' % (fpargs, len(fields)), depth + 2) + self.emit('{%s}, 0);' % fpargs, depth + 2) i = 0 for f in fields: - self.emit("set%s(ap.getPyObject(%s));" % (self.processFieldName(f.name), + self.emit("set%s(ap.getPyObject(%s, Py.None));" % (self.processFieldName(f.name), str(i)), depth+1) i += 1 if str(name) in ('stmt', 'expr', 'excepthandler'): Modified: trunk/jython/src/org/python/antlr/adapter/AliasAdapter.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/AliasAdapter.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/AliasAdapter.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -10,24 +10,25 @@ public class AliasAdapter implements AstAdapter { public Object py2ast(PyObject o) { - if (o == null) { - return o; - } if (o instanceof alias) { return o; } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to alias node"); + return null; } public PyObject ast2py(Object o) { + if (o == null) { + return Py.None; + } return (PyObject)o; } public List iter2ast(PyObject iter) { List<alias> aliases = new ArrayList<alias>(); - for(Object o : (Iterable)iter) { - aliases.add((alias)py2ast((PyObject)o)); + if (iter != Py.None) { + for(Object o : (Iterable)iter) { + aliases.add((alias)py2ast((PyObject)o)); + } } return aliases; } Modified: trunk/jython/src/org/python/antlr/adapter/AstAdapters.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/AstAdapters.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/AstAdapters.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -60,12 +60,11 @@ return (expr)exprAdapter.py2ast(o); } - public static int py2int(Object o) { + public static Integer py2int(Object o) { if (o == null || o instanceof Integer) { return (Integer)o; } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to int node"); + return null; } public static String py2identifier(PyObject o) { @@ -75,7 +74,8 @@ public static expr_contextType py2expr_context(Object o) { if (o == null || o instanceof expr_contextType) { return (expr_contextType)o; - } else if (o instanceof PyObject) { + } + if (o instanceof PyObject && o != Py.None) { switch (((PyObject)o).asInt()) { case 1: return expr_contextType.Load; @@ -89,10 +89,11 @@ return expr_contextType.AugStore; case 6: return expr_contextType.Param; + default: + return expr_contextType.UNDEFINED; } } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to expr_context node"); + return expr_contextType.UNDEFINED; } public static slice py2slice(PyObject o) { @@ -105,17 +106,16 @@ //XXX: Unnecessary but needs to be fixed in the code generation of asdl_antlr.py public static Object py2string(Object o) { - if (o == null || o instanceof PyString) { + if (o instanceof PyString) { return o; } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to string node"); + return null; } public static operatorType py2operator(Object o) { if (o == null || o instanceof operatorType) { return (operatorType)o; - } else if (o instanceof PyObject) { + } else if (o instanceof PyObject && o != Py.None) { switch (((PyObject)o).asInt()) { case 1: return operatorType.Add; @@ -141,10 +141,11 @@ return operatorType.BitAnd; case 12: return operatorType.FloorDiv; + default: + return operatorType.UNDEFINED; } } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to operator node"); + return operatorType.UNDEFINED; } public static PyObject operator2py(operatorType o) { @@ -173,8 +174,9 @@ return new BitAnd(); case FloorDiv: return new FloorDiv(); + default: + return Py.None; } - return Py.None; } public static PyObject boolop2py(boolopType o) { @@ -183,8 +185,9 @@ return new And(); case Or: return new Or(); + default: + return Py.None; } - return Py.None; } public static PyObject cmpop2py(cmpopType o) { @@ -209,8 +212,9 @@ return new In(); case NotIn: return new NotIn(); + default: + return Py.None; } - return Py.None; } public static PyObject unaryop2py(unaryopType o) { @@ -223,8 +227,9 @@ return new UAdd(); case USub: return new USub(); + default: + return Py.None; } - return Py.None; } @@ -242,31 +247,33 @@ return new AugStore(); case Param: return new Param(); + default: + return Py.None; } - return Py.None; } public static boolopType py2boolop(Object o) { if (o == null || o instanceof boolopType) { return (boolopType)o; - } else if (o instanceof PyObject) { + } + if (o instanceof PyObject && o != Py.None) { switch (((PyObject)o).asInt()) { case 1: return boolopType.And; case 2: return boolopType.Or; + default: + return boolopType.UNDEFINED; } } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to boolop node"); + return boolopType.UNDEFINED; } public static arguments py2arguments(Object o) { - if (o == null || o instanceof arguments) { + if (o instanceof arguments) { return (arguments)o; } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to arguments node"); + return null; } //XXX: clearly this isn't necessary -- need to adjust the code generation. @@ -275,18 +282,17 @@ } public static Boolean py2bool(Object o) { - if (o == null || o instanceof Boolean) { + if (o instanceof Boolean) { return (Boolean)o; } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to Boolean node"); + return null; } public static unaryopType py2unaryop(Object o) { if (o == null || o instanceof unaryopType) { return (unaryopType)o; } - if (o instanceof PyObject) { + if (o instanceof PyObject && o != Py.None) { switch (((PyObject)o).asInt()) { case 1: return unaryopType.Invert; @@ -296,10 +302,10 @@ return unaryopType.UAdd; case 4: return unaryopType.USub; + default: + return unaryopType.UNDEFINED; } } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to unaryop node"); + return unaryopType.UNDEFINED; } - } Modified: trunk/jython/src/org/python/antlr/adapter/CmpopAdapter.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/CmpopAdapter.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/CmpopAdapter.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -20,34 +20,39 @@ public class CmpopAdapter implements AstAdapter { public Object py2ast(PyObject o) { - switch ((o).asInt()) { - case 1: - return cmpopType.Eq; - case 2: - return cmpopType.NotEq; - case 3: - return cmpopType.Lt; - case 4: - return cmpopType.LtE; - case 5: - return cmpopType.Gt; - case 6: - return cmpopType.GtE; - case 7: - return cmpopType.Is; - case 8: - return cmpopType.IsNot; - case 9: - return cmpopType.In; - case 10: - return cmpopType.NotIn; + if (o != Py.None) { + switch ((o).asInt()) { + case 1: + return cmpopType.Eq; + case 2: + return cmpopType.NotEq; + case 3: + return cmpopType.Lt; + case 4: + return cmpopType.LtE; + case 5: + return cmpopType.Gt; + case 6: + return cmpopType.GtE; + case 7: + return cmpopType.Is; + case 8: + return cmpopType.IsNot; + case 9: + return cmpopType.In; + case 10: + return cmpopType.NotIn; + default: + return cmpopType.UNDEFINED; + } } - - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to cmpop node"); + return cmpopType.UNDEFINED; } public PyObject ast2py(Object o) { + if (o == null) { + return Py.None; + } switch ((cmpopType)o) { case Eq: return new Eq(); @@ -69,14 +74,17 @@ return new In(); case NotIn: return new NotIn(); + default: + return Py.None; } - return Py.None; } public List iter2ast(PyObject iter) { List<cmpopType> cmpops = new ArrayList<cmpopType>(); - for(Object o : (Iterable)iter) { - cmpops.add((cmpopType)py2ast((PyObject)o)); + if (iter != Py.None) { + for(Object o : (Iterable)iter) { + cmpops.add((cmpopType)py2ast((PyObject)o)); + } } return cmpops; } Modified: trunk/jython/src/org/python/antlr/adapter/ComprehensionAdapter.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/ComprehensionAdapter.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/ComprehensionAdapter.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -10,24 +10,25 @@ public class ComprehensionAdapter implements AstAdapter { public Object py2ast(PyObject o) { - if (o == null) { - return o; - } if (o instanceof comprehension) { return o; } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to comprehension node"); + return null; } public PyObject ast2py(Object o) { + if (o == null) { + return Py.None; + } return (PyObject)o; } public List iter2ast(PyObject iter) { List<comprehension> comprehensions = new ArrayList<comprehension>(); - for(Object o : (Iterable)iter) { - comprehensions.add((comprehension)py2ast((PyObject)o)); + if (iter != Py.None) { + for(Object o : (Iterable)iter) { + comprehensions.add((comprehension)py2ast((PyObject)o)); + } } return comprehensions; } Modified: trunk/jython/src/org/python/antlr/adapter/ExcepthandlerAdapter.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/ExcepthandlerAdapter.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/ExcepthandlerAdapter.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -10,27 +10,26 @@ public class ExcepthandlerAdapter implements AstAdapter { public Object py2ast(PyObject o) { - if (o == null) { - return o; - } if (o instanceof ExceptHandler) { return o; } - - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to excepthandler node"); + return null; } public PyObject ast2py(Object o) { + if (o == null) { + return Py.None; + } return (PyObject)o; } public List iter2ast(PyObject iter) { List<ExceptHandler> excepthandlers = new ArrayList<ExceptHandler>(); - for(Object o : (Iterable)iter) { - excepthandlers.add((ExceptHandler)py2ast((PyObject)o)); + if (iter != Py.None) { + for(Object o : (Iterable)iter) { + excepthandlers.add((ExceptHandler)py2ast((PyObject)o)); + } } return excepthandlers; } - } Modified: trunk/jython/src/org/python/antlr/adapter/ExprAdapter.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/ExprAdapter.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/ExprAdapter.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -18,30 +18,32 @@ public class ExprAdapter implements AstAdapter { public Object py2ast(PyObject o) { - if (o == null || o instanceof expr) { + if (o instanceof expr) { return o; - } else if (o instanceof PyInteger || o instanceof PyLong || o instanceof PyFloat || o instanceof PyComplex) { + } + if (o instanceof PyInteger || o instanceof PyLong || o instanceof PyFloat || o instanceof PyComplex) { return new Num(o); - } else if (o instanceof PyString || o instanceof PyUnicode) { + } + if (o instanceof PyString || o instanceof PyUnicode) { return new Str(o); - } else if (o == Py.None) { - return null; } - - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to expr node"); + return null; } public PyObject ast2py(Object o) { + if (o == null) { + return Py.None; + } return (PyObject)o; } public List iter2ast(PyObject iter) { List<expr> exprs = new ArrayList<expr>(); - for(Object o : (Iterable)iter) { - exprs.add((expr)py2ast((PyObject)o)); + if (iter != Py.None) { + for(Object o : (Iterable)iter) { + exprs.add((expr)py2ast((PyObject)o)); + } } return exprs; } - } Modified: trunk/jython/src/org/python/antlr/adapter/IdentifierAdapter.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/IdentifierAdapter.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/IdentifierAdapter.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -3,25 +3,33 @@ import java.util.ArrayList; import java.util.List; +import org.python.core.Py; import org.python.core.PyObject; import org.python.core.PyString; public class IdentifierAdapter implements AstAdapter { public Object py2ast(PyObject o) { + if (o == null || o == Py.None) { + return null; + } return o.toString(); } public PyObject ast2py(Object o) { + if (o == null) { + return Py.None; + } return new PyString(o.toString()); } public List iter2ast(PyObject iter) { List<String> identifiers = new ArrayList<String>(); - for(Object o : (Iterable)iter) { - identifiers.add((String)py2ast((PyObject)o)); + if (iter != Py.None) { + for(Object o : (Iterable)iter) { + identifiers.add((String)py2ast((PyObject)o)); + } } return identifiers; } - } Modified: trunk/jython/src/org/python/antlr/adapter/KeywordAdapter.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/KeywordAdapter.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/KeywordAdapter.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -10,25 +10,25 @@ public class KeywordAdapter implements AstAdapter { public Object py2ast(PyObject o) { - if (o == null) { - return o; - } if (o instanceof keyword) { return o; } - - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to keyword node"); + return null; } public PyObject ast2py(Object o) { + if (o == null) { + return Py.None; + } return (PyObject)o; } public List iter2ast(PyObject iter) { List<keyword> keywords = new ArrayList<keyword>(); - for(Object o : (Iterable)iter) { - keywords.add((keyword)py2ast((PyObject)o)); + if (iter != Py.None) { + for(Object o : (Iterable)iter) { + keywords.add((keyword)py2ast((PyObject)o)); + } } return keywords; } Modified: trunk/jython/src/org/python/antlr/adapter/SliceAdapter.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/SliceAdapter.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/SliceAdapter.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -10,27 +10,26 @@ public class SliceAdapter implements AstAdapter { public Object py2ast(PyObject o) { - if (o == null) { - return o; - } if (o instanceof slice) { return o; } - - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to slice node"); + return null; } public PyObject ast2py(Object o) { + if (o == null) { + return Py.None; + } return (PyObject)o; } public List iter2ast(PyObject iter) { List<slice> slices = new ArrayList<slice>(); - for(Object o : (Iterable)iter) { - slices.add((slice)py2ast((PyObject)o)); + if (iter != Py.None) { + for(Object o : (Iterable)iter) { + slices.add((slice)py2ast((PyObject)o)); + } } return slices; } - } Modified: trunk/jython/src/org/python/antlr/adapter/StmtAdapter.java =================================================================== --- trunk/jython/src/org/python/antlr/adapter/StmtAdapter.java 2009-08-04 00:06:16 UTC (rev 6628) +++ trunk/jython/src/org/python/antlr/adapter/StmtAdapter.java 2009-08-04 19:54:15 UTC (rev 6629) @@ -10,24 +10,25 @@ public class StmtAdapter implements AstAdapter { public Object py2ast(PyObject o) { - if (o == null) { - return o; - } if (o instanceof stmt) { return o; } - //FIXME: investigate the right exception - throw Py.TypeError("Can't convert " + o.getClass().getName() + " to stmt node"); + return null; } public PyObject ast2py(Object o) { + if (o == null) { + return Py.None; + } return (PyObject)o; } public List iter2ast(PyObject iter) { List<stmt> stmts = new ArrayList<stmt>(); - for(Object o : (Iterable)iter) { - stmts.add((stmt)py2ast((PyObject)o)); + if (iter != Py.None) { + for(Object o : (Iterable)iter) { + stmts.add((stmt)py2ast((PyObject)o)); + } } return stmts; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-08-04 23:50:50
|
Revision: 6630 http://jython.svn.sourceforge.net/jython/?rev=6630&view=rev Author: fwierzbicki Date: 2009-08-04 23:50:44 +0000 (Tue, 04 Aug 2009) Log Message: ----------- Another step towards fixing #1415. Now handling arg parsing of AST nodes more like CPython (well, once the AST codegen is done). Modified Paths: -------------- trunk/jython/ast/asdl_antlr.py trunk/jython/src/org/python/antlr/AST.java trunk/jython/src/org/python/core/ArgParser.java Modified: trunk/jython/ast/asdl_antlr.py =================================================================== --- trunk/jython/ast/asdl_antlr.py 2009-08-04 19:54:15 UTC (rev 6629) +++ trunk/jython/ast/asdl_antlr.py 2009-08-04 23:50:44 UTC (rev 6630) @@ -481,7 +481,7 @@ self.emit("@ExposedMethod", depth) self.emit("public void %s___init__(PyObject[] args, String[] keywords) {" % clsname, depth) self.emit('ArgParser ap = new ArgParser("%s", args, keywords, new String[]' % clsname, depth + 1) - self.emit('{%s}, 0);' % fpargs, depth + 2) + self.emit('{%s}, %s, true);' % (fpargs, len(fields)), depth + 2) i = 0 for f in fields: self.emit("set%s(ap.getPyObject(%s, Py.None));" % (self.processFieldName(f.name), Modified: trunk/jython/src/org/python/antlr/AST.java =================================================================== --- trunk/jython/src/org/python/antlr/AST.java 2009-08-04 19:54:15 UTC (rev 6629) +++ trunk/jython/src/org/python/antlr/AST.java 2009-08-04 23:50:44 UTC (rev 6630) @@ -1,5 +1,7 @@ package org.python.antlr; +import org.python.core.Py; +import org.python.core.PyException; import org.python.core.PyObject; import org.python.core.PyType; import org.python.expose.ExposedType; @@ -15,4 +17,21 @@ super(objtype); } + public static boolean check(int nargs, int expected, boolean takesZeroArgs) { + if (nargs == expected) { + return true; + } + if (takesZeroArgs && nargs == 0) { + return true; + } + return false; + } + + public static PyException unexpectedCall(int expected, String name) { + String message = " constructor takes 0 positional arguments"; + if (expected != 0) { + message = " constructor takes either 0 or " + expected + " arguments"; + } + return Py.TypeError(name + message); + } } Modified: trunk/jython/src/org/python/core/ArgParser.java =================================================================== --- trunk/jython/src/org/python/core/ArgParser.java 2009-08-04 19:54:15 UTC (rev 6629) +++ trunk/jython/src/org/python/core/ArgParser.java 2009-08-04 23:50:44 UTC (rev 6630) @@ -3,6 +3,8 @@ import java.util.HashSet; import java.util.Set; +import org.python.antlr.AST; + /** * A utility class for handling mixed positional and keyword arguments. * @@ -122,6 +124,16 @@ } } + public ArgParser(String funcname, PyObject[] args, String[] kws, + String[] paramnames, int minargs, boolean takesZeroArgs) { + this(funcname, args, kws); + this.params = paramnames; + check(); + if (!AST.check(args.length - kws.length, minargs, takesZeroArgs)) { + throw AST.unexpectedCall(minargs, funcname); + } + } + /** * Return a required argument as a String. * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-08-04 23:56:57
|
Revision: 6632 http://jython.svn.sourceforge.net/jython/?rev=6632&view=rev Author: fwierzbicki Date: 2009-08-04 23:56:50 +0000 (Tue, 04 Aug 2009) Log Message: ----------- Added test and NEWS for http://bugs.jython.org/issue1415 "ast Node creation fails with no arg constructors". Modified Paths: -------------- trunk/jython/Lib/test/test_ast_jy.py trunk/jython/NEWS Modified: trunk/jython/Lib/test/test_ast_jy.py =================================================================== --- trunk/jython/Lib/test/test_ast_jy.py 2009-08-04 23:52:49 UTC (rev 6631) +++ trunk/jython/Lib/test/test_ast_jy.py 2009-08-04 23:56:50 UTC (rev 6632) @@ -37,6 +37,115 @@ self.assert_(isinstance(z[0][0], ast.Lt)) self.assert_(isinstance(z[0][1], ast.Name)) + def test_empty_init(self): + # Jython 2.5.0 did not allow empty constructors for many ast node types + # but CPython ast nodes do allow this. For the moment, I don't see a + # reason to allow construction of the super types (like ast.AST and + # ast.stmt) as well as the op types that are implemented as enums in + # Jython (like boolop), but I've left them in but commented out for + # now. We may need them in the future since CPython allows this, but + # it may fall under implementation detail. + + #ast.AST() + ast.Add() + ast.And() + ast.Assert() + ast.Assign() + ast.Attribute() + ast.AugAssign() + ast.AugLoad() + ast.AugStore() + ast.BinOp() + ast.BitAnd() + ast.BitOr() + ast.BitXor() + ast.BoolOp() + ast.Break() + ast.Call() + ast.ClassDef() + ast.Compare() + ast.Continue() + ast.Del() + ast.Delete() + ast.Dict() + ast.Div() + ast.Ellipsis() + ast.Eq() + ast.Exec() + ast.Expr() + ast.Expression() + ast.ExtSlice() + ast.FloorDiv() + ast.For() + ast.FunctionDef() + ast.GeneratorExp() + ast.Global() + ast.Gt() + ast.GtE() + ast.If() + ast.IfExp() + ast.Import() + ast.ImportFrom() + ast.In() + ast.Index() + ast.Interactive() + ast.Invert() + ast.Is() + ast.IsNot() + ast.LShift() + ast.Lambda() + ast.List() + ast.ListComp() + ast.Load() + ast.Lt() + ast.LtE() + ast.Mod() + ast.Module() + ast.Mult() + ast.Name() + ast.Not() + ast.NotEq() + ast.NotIn() + ast.Num() + ast.Or() + ast.Param() + ast.Pass() + ast.Pow() + ast.Print() + ast.RShift() + ast.Raise() + ast.Repr() + ast.Return() + ast.Slice() + ast.Store() + ast.Str() + ast.Sub() + ast.Subscript() + ast.Suite() + ast.TryExcept() + ast.TryFinally() + ast.Tuple() + ast.UAdd() + ast.USub() + ast.UnaryOp() + ast.While() + ast.With() + ast.Yield() + ast.alias() + ast.arguments() + #ast.boolop() + #ast.cmpop() + ast.comprehension() + #ast.excepthandler() + #ast.expr() + #ast.expr_context() + ast.keyword() + #ast.mod() + #ast.operator() + #ast.slice() + #ast.stmt() + #ast.unaryop() + #============================================================================== def test_main(verbose=None): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-08-04 23:52:49 UTC (rev 6631) +++ trunk/jython/NEWS 2009-08-04 23:56:50 UTC (rev 6632) @@ -8,6 +8,7 @@ the name of the produced proxy class. - Built in JSR 223 scripting engine, with LiveTribe JSR 223 implementation for JDK 5 Bugs Fixed + - [ 1415 ] ast Node creation fails with no arg constructors - [ 645615 ] cannot import through symbolic links - [ 1366 ] parsing of lamda expression fails - [ 1365 ] continuation lines fail in interactive interpreter This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-08-13 02:50:10
|
Revision: 6665 http://jython.svn.sourceforge.net/jython/?rev=6665&view=rev Author: fwierzbicki Date: 2009-08-13 02:49:57 +0000 (Thu, 13 Aug 2009) Log Message: ----------- Adjusted BinOp lineno and col_offset to align better with CPython. Modified Paths: -------------- trunk/jython/grammar/Python.g trunk/jython/src/org/python/antlr/GrammarActions.java Modified: trunk/jython/grammar/Python.g =================================================================== --- trunk/jython/grammar/Python.g 2009-08-13 01:54:15 UTC (rev 6664) +++ trunk/jython/grammar/Python.g 2009-08-13 02:49:57 UTC (rev 6665) @@ -1180,16 +1180,18 @@ shift_expr @init { List ops = new ArrayList(); + List toks = new ArrayList(); } @after { if (!ops.isEmpty()) { - $shift_expr.tree = actions.makeBinOp($left.tree, ops, $right); + $shift_expr.tree = actions.makeBinOp($left.tree, ops, $right, toks); } } : left=arith_expr ( ( shift_op right+=arith_expr { ops.add($shift_op.op); + toks.add($shift_op.start); } )+ | @@ -1209,16 +1211,18 @@ arith_expr @init { List ops = new ArrayList(); + List toks = new ArrayList(); } @after { if (!ops.isEmpty()) { - $arith_expr.tree = actions.makeBinOp($left.tree, ops, $right); + $arith_expr.tree = actions.makeBinOp($left.tree, ops, $right, toks); } } : left=term ( (arith_op right+=term { ops.add($arith_op.op); + toks.add($arith_op.start); } )+ | @@ -1246,16 +1250,18 @@ term @init { List ops = new ArrayList(); + List toks = new ArrayList(); } @after { if (!ops.isEmpty()) { - $term.tree = actions.makeBinOp($left.tree, ops, $right); + $term.tree = actions.makeBinOp($left.tree, ops, $right, toks); } } : left=factor ( (term_op right+=factor { ops.add($term_op.op); + toks.add($term_op.start); } )+ | Modified: trunk/jython/src/org/python/antlr/GrammarActions.java =================================================================== --- trunk/jython/src/org/python/antlr/GrammarActions.java 2009-08-13 01:54:15 UTC (rev 6664) +++ trunk/jython/src/org/python/antlr/GrammarActions.java 2009-08-13 02:49:57 UTC (rev 6665) @@ -658,12 +658,12 @@ return current; } - BinOp makeBinOp(PythonTree left, List ops, List rights) { + BinOp makeBinOp(PythonTree left, List ops, List rights, List toks) { BinOp current = new BinOp(left, castExpr(left), (operatorType)ops.get(0), castExpr(rights.get(0))); for (int i = 1; i< rights.size(); i++) { expr right = castExpr(rights.get(i)); operatorType op = (operatorType)ops.get(i); - current = new BinOp(left, current, op, right); + current = new BinOp((Token)toks.get(i), current, op, right); } return current; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |