You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(107) |
Dec
(67) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(76) |
Feb
(125) |
Mar
(72) |
Apr
(13) |
May
(18) |
Jun
(12) |
Jul
(129) |
Aug
(47) |
Sep
(1) |
Oct
(36) |
Nov
(128) |
Dec
(124) |
2002 |
Jan
(59) |
Feb
|
Mar
(14) |
Apr
(14) |
May
(72) |
Jun
(9) |
Jul
(3) |
Aug
(5) |
Sep
(18) |
Oct
(65) |
Nov
(28) |
Dec
(12) |
2003 |
Jan
(10) |
Feb
(2) |
Mar
(4) |
Apr
(33) |
May
(21) |
Jun
(9) |
Jul
(29) |
Aug
(34) |
Sep
(4) |
Oct
(8) |
Nov
(15) |
Dec
(4) |
2004 |
Jan
(26) |
Feb
(12) |
Mar
(11) |
Apr
(9) |
May
(7) |
Jun
|
Jul
(5) |
Aug
|
Sep
(3) |
Oct
(7) |
Nov
(1) |
Dec
(10) |
2005 |
Jan
(2) |
Feb
(72) |
Mar
(16) |
Apr
(39) |
May
(48) |
Jun
(97) |
Jul
(57) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(100) |
Dec
(24) |
2006 |
Jan
(15) |
Feb
(34) |
Mar
(33) |
Apr
(31) |
May
(79) |
Jun
(64) |
Jul
(41) |
Aug
(64) |
Sep
(31) |
Oct
(46) |
Nov
(55) |
Dec
(37) |
2007 |
Jan
(32) |
Feb
(61) |
Mar
(11) |
Apr
(58) |
May
(46) |
Jun
(30) |
Jul
(94) |
Aug
(93) |
Sep
(86) |
Oct
(69) |
Nov
(125) |
Dec
(177) |
2008 |
Jan
(169) |
Feb
(97) |
Mar
(74) |
Apr
(113) |
May
(120) |
Jun
(334) |
Jul
(215) |
Aug
(237) |
Sep
(72) |
Oct
(189) |
Nov
(126) |
Dec
(160) |
2009 |
Jan
(180) |
Feb
(45) |
Mar
(98) |
Apr
(140) |
May
(151) |
Jun
(71) |
Jul
(107) |
Aug
(119) |
Sep
(73) |
Oct
(121) |
Nov
(14) |
Dec
(6) |
2010 |
Jan
(13) |
Feb
(9) |
Mar
(10) |
Apr
(64) |
May
(3) |
Jun
(16) |
Jul
(7) |
Aug
(23) |
Sep
(17) |
Oct
(37) |
Nov
(5) |
Dec
(8) |
2011 |
Jan
(10) |
Feb
(11) |
Mar
(77) |
Apr
(11) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <fwi...@us...> - 2009-01-09 04:15:19
|
Revision: 5896 http://jython.svn.sourceforge.net/jython/?rev=5896&view=rev Author: fwierzbicki Date: 2009-01-09 04:15:14 +0000 (Fri, 09 Jan 2009) Log Message: ----------- Set comprehensions Modified Paths: -------------- branches/jy3k/grammar/Python.g Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-09 03:59:16 UTC (rev 5895) +++ branches/jy3k/grammar/Python.g 2009-01-09 04:15:14 UTC (rev 5896) @@ -131,6 +131,7 @@ import org.python.antlr.ast.Raise; import org.python.antlr.ast.Return; import org.python.antlr.ast.Set; +import org.python.antlr.ast.SetComp; import org.python.antlr.ast.Slice; import org.python.antlr.ast.Str; import org.python.antlr.ast.Subscript; @@ -1426,11 +1427,18 @@ { etype = new Dict($lcurly, actions.castExprs($k), actions.castExprs($v)); } - | t+=test[$expr::ctype] (options {greedy=true;}:COMMA t+=test[$expr::ctype])* - (COMMA)? + | t+=test[$expr::ctype] + (comp_for[gens] { + Collections.reverse(gens); + List<comprehension> c = gens; + etype = new SetComp($dictorsetmaker.start, actions.castExpr($t.get(0)), c); + } + | (options {greedy=true;}:COMMA t+=test[$expr::ctype])* (COMMA)? + { etype = new Set($lcurly, actions.castExprs($t)); } + ) ; //classdef: 'class' NAME ['(' [testlist] ')'] ':' suite This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-09 03:59:20
|
Revision: 5895 http://jython.svn.sourceforge.net/jython/?rev=5895&view=rev Author: fwierzbicki Date: 2009-01-09 03:59:16 +0000 (Fri, 09 Jan 2009) Log Message: ----------- Set support Modified Paths: -------------- branches/jy3k/grammar/Python.g Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-09 03:19:43 UTC (rev 5894) +++ branches/jy3k/grammar/Python.g 2009-01-09 03:59:16 UTC (rev 5895) @@ -130,6 +130,7 @@ import org.python.antlr.ast.Pass; import org.python.antlr.ast.Raise; import org.python.antlr.ast.Return; +import org.python.antlr.ast.Set; import org.python.antlr.ast.Slice; import org.python.antlr.ast.Str; import org.python.antlr.ast.Subscript; @@ -1226,12 +1227,12 @@ ) RBRACK | LCURLY - (dictorsetmaker[$LCURLY] - -> dictorsetmaker - | - -> ^(LCURLY<Dict>[$LCURLY, new ArrayList<expr>(), new ArrayList<expr>()]) - ) - RCURLY + (dictorsetmaker[$LCURLY] + -> dictorsetmaker + | + -> ^(LCURLY<Dict>[$LCURLY, new ArrayList<expr>(), new ArrayList<expr>()]) + ) + RCURLY | NAME -> ^(NAME<Name>[$NAME, $NAME.text, $expr::ctype]) | INT @@ -1418,12 +1419,18 @@ @after { $dictorsetmaker.tree = etype; } - : k+=test[expr_contextType.Load] COLON v+=test[expr_contextType.Load] + : (test[null] COLON) + => k+=test[expr_contextType.Load] COLON v+=test[expr_contextType.Load] (options {k=2;}:COMMA k+=test[expr_contextType.Load] COLON v+=test[expr_contextType.Load])* (COMMA)? { etype = new Dict($lcurly, actions.castExprs($k), actions.castExprs($v)); } + | t+=test[$expr::ctype] (options {greedy=true;}:COMMA t+=test[$expr::ctype])* + (COMMA)? + { + etype = new Set($lcurly, actions.castExprs($t)); + } ; //classdef: 'class' NAME ['(' [testlist] ')'] ':' suite This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-09 03:19:54
|
Revision: 5894 http://jython.svn.sourceforge.net/jython/?rev=5894&view=rev Author: fwierzbicki Date: 2009-01-09 03:19:43 +0000 (Fri, 09 Jan 2009) Log Message: ----------- groundwork for dict and set comprehensions Modified Paths: -------------- branches/jy3k/grammar/Python.g Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-08 22:54:04 UTC (rev 5893) +++ branches/jy3k/grammar/Python.g 2009-01-09 03:19:43 UTC (rev 5894) @@ -1226,9 +1226,8 @@ ) RBRACK | LCURLY - (dictmaker - -> ^(LCURLY<Dict>[$LCURLY, actions.castExprs($dictmaker.keys), - actions.castExprs($dictmaker.values)]) + (dictorsetmaker[$LCURLY] + -> dictorsetmaker | -> ^(LCURLY<Dict>[$LCURLY, new ArrayList<expr>(), new ArrayList<expr>()]) ) @@ -1250,8 +1249,8 @@ //listmaker: test ( list_for | (',' test)* [','] ) listmaker[Token lbrack] @init { + expr etype = null; List gens = new ArrayList(); - expr etype = null; } @after { $listmaker.tree = etype; @@ -1287,7 +1286,7 @@ ^(COMMA<Tuple>[$testlist_comp.start, actions.castExprs($t), $expr::ctype]) -> test ) - | (gen_for[gens] + | (comp_for[gens] { Collections.reverse(gens); List<comprehension> c = gens; @@ -1409,15 +1408,22 @@ | test[ctype] ; -//dictmaker: test ':' test (',' test ':' test)* [','] -dictmaker returns [List keys, List values] +//dictorsetmaker: ( (test ':' test (comp_for | (',' test ':' test)* [','])) | +// (test (comp_for | (',' test)* [','])) ) +dictorsetmaker[Token lcurly] +@init { + expr etype = null; + List gens = new ArrayList(); +} +@after { + $dictorsetmaker.tree = etype; +} : k+=test[expr_contextType.Load] COLON v+=test[expr_contextType.Load] (options {k=2;}:COMMA k+=test[expr_contextType.Load] COLON v+=test[expr_contextType.Load])* (COMMA)? - { - $keys = $k; - $values= $v; - } + { + etype = new Dict($lcurly, actions.castExprs($k), actions.castExprs($v)); + } ; //classdef: 'class' NAME ['(' [testlist] ')'] ':' suite @@ -1444,7 +1450,9 @@ } ; -//arglist: (argument ',')* (argument [',']| '*' test [',' '**' test] | '**' test) +//arglist: (argument ',')* (argument [','] +// |'*' test (',' argument)* [',' '**' test] +// |'**' test) arglist returns [List args, List keywords, expr starargs, expr kwargs] @init { List arguments = new ArrayList(); @@ -1477,7 +1485,7 @@ } ; -//argument: test [gen_for] | test '=' test # Really [keyword '='] test +//argument: test [comp_for] | test '=' test # Really [keyword '='] test argument[List arguments, List kws, List gens, boolean first] returns [boolean genarg] : t1=test[expr_contextType.Load] ((ASSIGN t2=test[expr_contextType.Load]) @@ -1487,10 +1495,10 @@ exprs.add(actions.castExpr($t2.tree)); $kws.add(exprs); } - | gen_for[$gens] + | comp_for[$gens] { if (!first) { - actions.errorGenExpNotSoleArg($gen_for.tree); + actions.errorGenExpNotSoleArg($comp_for.tree); } $genarg = true; Collections.reverse($gens); @@ -1532,27 +1540,27 @@ } ; -//gen_iter: gen_for | gen_if -gen_iter [List gens, List ifs] - : gen_for[gens] - | gen_if[gens, ifs] +//comp_iter: comp_for | comp_if +comp_iter [List gens, List ifs] + : comp_for[gens] + | comp_if[gens, ifs] ; -//gen_for: 'for' exprlist 'in' or_test [gen_iter] -gen_for [List gens] +//comp_for: 'for' exprlist 'in' or_test [comp_iter] +comp_for [List gens] @init { List ifs = new ArrayList(); } - : FOR exprlist[expr_contextType.Store] IN or_test[expr_contextType.Load] gen_iter[gens, ifs]? + : FOR exprlist[expr_contextType.Store] IN or_test[expr_contextType.Load] comp_iter[gens, ifs]? { Collections.reverse(ifs); gens.add(new comprehension($FOR, $exprlist.etype, actions.castExpr($or_test.tree), ifs)); } ; -//gen_if: 'if' old_test [gen_iter] -gen_if[List gens, List ifs] - : IF test[expr_contextType.Load] gen_iter[gens, ifs]? +//comp_if: 'if' test_nocond [comp_iter] +comp_if[List gens, List ifs] + : IF test[expr_contextType.Load] comp_iter[gens, ifs]? { ifs.add(actions.castExpr($test.tree)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-01-08 22:54:12
|
Revision: 5893 http://jython.svn.sourceforge.net/jython/?rev=5893&view=rev Author: otmarhumbel Date: 2009-01-08 22:54:04 +0000 (Thu, 08 Jan 2009) Log Message: ----------- rename the jython*.jar files: jython.jar is now called jython-dev.jar jython-complete.jar is now called jython.jar the one we distribute is jython.jar, containing the necessary external libraries, mangled jython-dev.jar is intended for local developer usage, containing no external libraries, referencing the real external package names Modified Paths: -------------- trunk/installer/src/java/org/python/util/install/JarInstaller.java trunk/installer/test/java/org/python/util/install/driver/StandaloneVerifierTest.java trunk/jython/bugtests/README.txt trunk/jython/bugtests/test386.py trunk/jython/bugtests/test394.py trunk/jython/bugtests/test394jar/MANIFEST.MF trunk/jython/build.xml trunk/jython/src/org/python/core/PySystemState.java trunk/jython/src/org/python/util/JythoncAntTask.java trunk/jython/src/shell/jython trunk/jython/src/shell/jython.bat Modified: trunk/installer/src/java/org/python/util/install/JarInstaller.java =================================================================== --- trunk/installer/src/java/org/python/util/install/JarInstaller.java 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/installer/src/java/org/python/util/install/JarInstaller.java 2009-01-08 22:54:04 UTC (rev 5893) @@ -18,7 +18,7 @@ */ public class JarInstaller { - public static final String JYTHON_JAR = "jython-complete.jar"; + public static final String JYTHON_JAR = "jython.jar"; private static final String PATH_SEPARATOR = "/"; Modified: trunk/installer/test/java/org/python/util/install/driver/StandaloneVerifierTest.java =================================================================== --- trunk/installer/test/java/org/python/util/install/driver/StandaloneVerifierTest.java 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/installer/test/java/org/python/util/install/driver/StandaloneVerifierTest.java 2009-01-08 22:54:04 UTC (rev 5893) @@ -3,6 +3,7 @@ import java.io.File; import org.python.util.install.Installation; +import org.python.util.install.JarInstaller; import junit.framework.TestCase; @@ -58,7 +59,7 @@ assertEquals(4, command.length); assertEquals(expectedCommand, command[0]); assertEquals("-jar", command[1]); - assertEquals(prefix.concat("jython-complete.jar"), command[2]); + assertEquals(prefix.concat(JarInstaller.JYTHON_JAR), command[2]); assertEquals(expectedArgument, command[3]); } Modified: trunk/jython/bugtests/README.txt =================================================================== --- trunk/jython/bugtests/README.txt 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/jython/bugtests/README.txt 2009-01-08 22:54:04 UTC (rev 5893) @@ -24,7 +24,7 @@ ----- java_home = "/Library/Java/Home" jython_home = "/Users/bzimmer/Development/sourceforge/jython/dist" -classpath = jython_home + "/jython.jar:classes" +classpath = jython_home + "/jython-dev.jar:classes" ----- Run the script "driver.py". Modified: trunk/jython/bugtests/test386.py =================================================================== --- trunk/jython/bugtests/test386.py 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/jython/bugtests/test386.py 2009-01-08 22:54:04 UTC (rev 5893) @@ -11,7 +11,7 @@ from java.io import File TESTDIR = "test386jar" -JYTHON_JAR = "jython.jar" +JYTHON_DEV_JAR = "jython-dev.jar" TEST_PY_NAME = TESTDIR +"/test386called.py" def checkTestDir(): @@ -21,11 +21,11 @@ raise AssertionError, TEST_PY_NAME + " does not exist" # create a jython standalone jar file: -# add the contents of jython.jar and /Lib files to an new jython.jar +# add the contents of jython-dev.jar and /Lib files to a new jython-dev.jar def mkjar(): - jarFile = File(TESTDIR, JYTHON_JAR) + jarFile = File(TESTDIR, JYTHON_DEV_JAR) jarPacker = support.JarPacker(jarFile) - jarPacker.addJarFile(File(cfg.jython_home + "/%s" % JYTHON_JAR)) + jarPacker.addJarFile(File(cfg.jython_home + "/%s" % JYTHON_DEV_JAR)) jarPacker.addDirectory(File(cfg.jython_home + "/Lib")) jarPacker.close() return jarFile @@ -33,5 +33,5 @@ checkTestDir() mkjar() -jarFileName = "%s/%s" % (TESTDIR, JYTHON_JAR) +jarFileName = "%s/%s" % (TESTDIR, JYTHON_DEV_JAR) support.runJavaJar(jarFileName, TEST_PY_NAME) \ No newline at end of file Modified: trunk/jython/bugtests/test394.py =================================================================== --- trunk/jython/bugtests/test394.py 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/jython/bugtests/test394.py 2009-01-08 22:54:04 UTC (rev 5893) @@ -7,7 +7,7 @@ error importing site Traceback (innermost last): - File "C:\workspace\jython\bugtests\test394jar\jython.jar\Lib/site.py", line 210, in ? + File "C:\workspace\jython\bugtests\test394jar\jython-dev.jar\Lib/site.py", line 210, in ? TypeError: unsupported operand type(s) for +: 'NoneType' and 'str' Traceback (innermost last): File "C:/workspace/jython/bugtests/test394.py", line 71, in ? @@ -26,7 +26,7 @@ from java.io import File TESTDIR = "test394jar" -JYTHON_JAR = "jython.jar" +JYTHON_DEV_JAR = "jython-dev.jar" RUN_JAR = "run.jar" TEST_PY_NAME = TESTDIR +"/test394called.py" CLAZZ = "Runner" @@ -46,11 +46,11 @@ # create a jython standalone jar file: -# add the contents of jython.jar and /Lib files to an new jython.jar +# add the contents of jython-dev.jar and /Lib files to a new jython-dev.jar def mkJythonJar(): - jarFile = File(TESTDIR, JYTHON_JAR) + jarFile = File(TESTDIR, JYTHON_DEV_JAR) jarPacker = support.JarPacker(jarFile) - jarPacker.addJarFile(File(cfg.jython_home + "/%s" % JYTHON_JAR)) + jarPacker.addJarFile(File(cfg.jython_home + "/%s" % JYTHON_DEV_JAR)) jarPacker.addDirectory(File(cfg.jython_home + "/Lib")) jarPacker.close() return jarFile @@ -59,7 +59,7 @@ def mkJavaClass(): support.compileJava("%s/%s.java" % (TESTDIR, CLAZZ)) -# create a runnable jar file with a manifest referring to jython.jar +# create a runnable jar file with a manifest referring to jython-dev.jar def mkRunJar(): jarFile = File(TESTDIR, RUN_JAR) manifestFile = File(TESTDIR, MANIFEST) Modified: trunk/jython/bugtests/test394jar/MANIFEST.MF =================================================================== --- trunk/jython/bugtests/test394jar/MANIFEST.MF 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/jython/bugtests/test394jar/MANIFEST.MF 2009-01-08 22:54:04 UTC (rev 5893) @@ -1,4 +1,4 @@ Manifest-Version: 1.0 -Class-Path: . jython.jar +Class-Path: . jython-dev.jar Main-Class: test394jar.Runner Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/jython/build.xml 2009-01-08 22:54:04 UTC (rev 5893) @@ -172,8 +172,8 @@ <!-- 64 bit Java 6 needs roughly 96m for regrtest on most platforms, but Apple's needs more --> <property name="regrtest.Xmx" value="-Xmx160m" /> - <property name="jython.dev.jar" value="jython.jar" /> - <property name="jython.deploy.jar" value="jython-complete.jar" /> + <property name="jython.dev.jar" value="jython-dev.jar" /> + <property name="jython.deploy.jar" value="jython.jar" /> </target> <target name="version-init"> @@ -804,6 +804,7 @@ <java classname="org.python.util.jython" fork="true" dir="${bugtests.dir}"> <classpath> <pathelement location="${dist.dir}/${jython.dev.jar}"/> + <fileset dir="${dist.dir}/javalib"/> </classpath> <jvmarg value="-Dpython.home=${dist.dir}"/> <arg value="driver.py"/> Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-01-08 22:54:04 UTC (rev 5893) @@ -34,7 +34,7 @@ protected static final String CACHEDIR_DEFAULT_NAME = "cachedir"; public static final String JYTHON_JAR = "jython.jar"; - public static final String JYTHON_COMPLETE_JAR = "jython-complete.jar"; + public static final String JYTHON_DEV_JAR = "jython-dev.jar"; private static final String JAR_URL_PREFIX = "jar:file:"; private static final String JAR_SEPARATOR = "!"; @@ -490,9 +490,9 @@ String classpath = preProperties.getProperty("java.class.path"); if (classpath != null) { String lowerCaseClasspath = classpath.toLowerCase(); - int jarIndex = lowerCaseClasspath.indexOf(JYTHON_COMPLETE_JAR); + int jarIndex = lowerCaseClasspath.indexOf(JYTHON_JAR); if (jarIndex < 0) { - jarIndex = lowerCaseClasspath.indexOf(JYTHON_JAR); + jarIndex = lowerCaseClasspath.indexOf(JYTHON_DEV_JAR); } if (jarIndex >= 0) { int start = classpath.lastIndexOf(java.io.File.pathSeparator, jarIndex) + 1; Modified: trunk/jython/src/org/python/util/JythoncAntTask.java =================================================================== --- trunk/jython/src/org/python/util/JythoncAntTask.java 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/jython/src/org/python/util/JythoncAntTask.java 2009-01-08 22:54:04 UTC (rev 5893) @@ -59,6 +59,7 @@ import org.apache.tools.ant.taskdefs.Java; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.DirectoryScanner; +import org.python.core.PySystemState; import java.io.File; @@ -414,7 +415,7 @@ javaTask.createJvmarg().setValue( "-Dpython.home=" + getPythonHome() ); // classpath - File aJythonJarFile = new File(getPythonHome(), "jython.jar" ); + File aJythonJarFile = new File(getPythonHome(), PySystemState.JYTHON_JAR ); createClasspath().setLocation(aJythonJarFile); javaTask.setClasspath(classpath); Modified: trunk/jython/src/shell/jython =================================================================== --- trunk/jython/src/shell/jython 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/jython/src/shell/jython 2009-01-08 22:54:04 UTC (rev 5893) @@ -53,12 +53,12 @@ # current dir is not the script dir JYTHON_HOME_1=`dirname "$PRG"` fi - if [ -f "$JYTHON_HOME_1"/jython-complete.jar -o -f "$JYTHON_HOME_1"/jython.jar ] ; then + if [ -f "$JYTHON_HOME_1"/jython.jar -o -f "$JYTHON_HOME_1"/jython-dev.jar ] ; then JYTHON_HOME="$JYTHON_HOME_1" else JYTHON_HOME=`dirname "$JYTHON_HOME_1"` fi - if [ ! -f "$JYTHON_HOME"/jython-complete.jar -a ! -f "$JYTHON_HOME"/jython.jar ] ; then + if [ ! -f "$JYTHON_HOME"/jython.jar -a ! -f "$JYTHON_HOME"/jython-dev.jar ] ; then JYTHON_HOME="$JYTHON_HOME_FALLBACK" fi fi @@ -69,7 +69,7 @@ CP_DELIMITER=":" -CP=$JYTHON_HOME/jython.jar +CP=$JYTHON_HOME/jython-dev.jar if [ -f "$CP" ] ; then # add necessary jars for command-line execution @@ -80,13 +80,13 @@ CP="$j" fi done -elif [ ! -f "$JYTHON_HOME"/jython-complete.jar ] ; then - echo "$0: $JYTHON_HOME contains neither jython.jar nor jython-complete.jar." >&2 +elif [ ! -f "$JYTHON_HOME"/jython.jar ] ; then + echo "$0: $JYTHON_HOME contains neither jython-dev.jar nor jython.jar." >&2 echo "Try running this script from the 'bin' directory of an installed Jython or " >&2 echo 'setting $JYTHON_HOME.' >&2 exit 1 else - CP=$JYTHON_HOME/jython-complete.jar + CP=$JYTHON_HOME/jython.jar fi if $cygwin; then Modified: trunk/jython/src/shell/jython.bat =================================================================== --- trunk/jython/src/shell/jython.bat 2009-01-08 22:05:28 UTC (rev 5892) +++ trunk/jython/src/shell/jython.bat 2009-01-08 22:54:04 UTC (rev 5893) @@ -44,31 +44,31 @@ pushd "%~dp0%" set _JYTHON_HOME="%CD%" popd +if exist %_JYTHON_HOME%\jython-dev.jar goto gotHome if exist %_JYTHON_HOME%\jython.jar goto gotHome -if exist %_JYTHON_HOME%\jython-complete.jar goto gotHome pushd "%~dp0%\.." set _JYTHON_HOME="%CD%" popd +if exist %_JYTHON_HOME%\jython-dev.jar goto gotHome if exist %_JYTHON_HOME%\jython.jar goto gotHome -if exist %_JYTHON_HOME%\jython-complete.jar goto gotHome rem jython home fallback (if all else fails) rem if present, %JYTHON_HOME_FALLBACK% is already quoted set _JYTHON_HOME=%JYTHON_HOME_FALLBACK% :gotHome -if not exist %_JYTHON_HOME%\jython.jar goto tryComplete +if not exist %_JYTHON_HOME%\jython-dev.jar goto tryComplete rem prefer built version -set _CP=%_JYTHON_HOME%\jython.jar +set _CP=%_JYTHON_HOME%\jython-dev.jar for %%j in (%_JYTHON_HOME%\javalib\*.jar) do ( set _CP=!_CP!;"%%j" ) goto run :tryComplete -set _CP=%_JYTHON_HOME%\jython-complete.jar -if exist %_JYTHON_HOME%/jython-complete.jar goto run +set _CP=%_JYTHON_HOME%\jython.jar +if exist %_JYTHON_HOME%/jython.jar goto run -echo Cannot find jython.jar or jython-complete.jar in %_JYTHON_HOME% +echo Cannot find jython-dev.jar or jython.jar in %_JYTHON_HOME% echo Try running this batch file from the 'bin' directory of an installed Jython, echo or setting JYTHON_HOME. goto cleanup This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-01-08 22:22:10
|
Revision: 5891 http://jython.svn.sourceforge.net/jython/?rev=5891&view=rev Author: pjenvey Date: 2009-01-08 21:49:36 +0000 (Thu, 08 Jan 2009) Log Message: ----------- jarjar xerces into jython-complete and check for the mangled name Modified Paths: -------------- trunk/jython/Lib/xml/parsers/expat.py trunk/jython/build.xml Modified: trunk/jython/Lib/xml/parsers/expat.py =================================================================== --- trunk/jython/Lib/xml/parsers/expat.py 2009-01-08 21:26:19 UTC (rev 5890) +++ trunk/jython/Lib/xml/parsers/expat.py 2009-01-08 21:49:36 UTC (rev 5891) @@ -47,7 +47,15 @@ from org.xml.sax.helpers import DefaultHandler, XMLReaderFactory from org.xml.sax.ext import DefaultHandler2 +# Xerces +try: + # Name mangled by jarjar? + import org.python.apache.xerces.parsers.SAXParser + _xerces_parser = "org.python.apache.xerces.parsers.SAXParser" +except ImportError: + _xerces_parser = "org.apache.xerces.parsers.SAXParser" + def ParserCreate(encoding=None, namespace_separator=None): return XMLParser(encoding, namespace_separator) @@ -77,9 +85,7 @@ "not %s" % type(namespace_separator).__name__) raise TypeError(error) - XMLReader = XMLReaderFactory.createXMLReader - xerces_parser = "org.apache.xerces.parsers.SAXParser" - self._reader = XMLReader(xerces_parser) + self._reader = XMLReaderFactory.createXMLReader(_xerces_parser) if self.namespace_separator is None: try: Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-01-08 21:26:19 UTC (rev 5890) +++ trunk/jython/build.xml 2009-01-08 21:49:36 UTC (rev 5891) @@ -520,6 +520,8 @@ <rule pattern="org.jruby.ext.posix.**" result="org.python.posix.@1"/> <zipfileset src="extlibs/constantine-0.4.jar"/> <rule pattern="com.kenai.constantine.**" result="org.python.constantine.@1"/> + <zipfileset src="extlibs/xercesImpl.jar"/> + <rule pattern="org.apache.**" result="org.python.apache.@1"/> <manifest> <attribute name="Main-Class" value="org.python.util.jython" /> <attribute name="Built-By" value="${user.name}" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-01-08 22:13:55
|
Revision: 5892 http://jython.svn.sourceforge.net/jython/?rev=5892&view=rev Author: pjenvey Date: 2009-01-08 22:05:28 +0000 (Thu, 08 Jan 2009) Log Message: ----------- unused import, coding standards Modified Paths: -------------- trunk/jython/Lib/xml/parsers/expat.py Modified: trunk/jython/Lib/xml/parsers/expat.py =================================================================== --- trunk/jython/Lib/xml/parsers/expat.py 2009-01-08 21:49:36 UTC (rev 5891) +++ trunk/jython/Lib/xml/parsers/expat.py 2009-01-08 22:05:28 UTC (rev 5892) @@ -1,4 +1,3 @@ - # coding: utf-8 #------------------------------------------------------------------------------ @@ -23,7 +22,7 @@ # THE SOFTWARE. # ----------------------------------------------------------------------------- -__all__ = ["ParserCreate", "XMLParserType", "ExpatError", "error", "errors"] +__all__ = ["ExpatError", "ParserCreate", "XMLParserType", "error", "errors"] # Jython check import sys @@ -44,7 +43,7 @@ from java.lang import String, StringBuilder from org.xml.sax import InputSource from org.xml.sax import SAXNotRecognizedException, SAXParseException -from org.xml.sax.helpers import DefaultHandler, XMLReaderFactory +from org.xml.sax.helpers import XMLReaderFactory from org.xml.sax.ext import DefaultHandler2 # Xerces @@ -127,15 +126,14 @@ raise NotImplementedError(error) # experimental - # f = "http://xml.org/sax/features/external-general-entities" + #f = "http://xml.org/sax/features/external-general-entities" f = "http://xml.org/sax/features/external-parameter-entities" - # self._reader.setFeature(f, False) + #self._reader.setFeature(f, False) # check f = "http://xml.org/sax/features/use-entity-resolver2" - assert self._reader.getFeature(f) is True + assert self._reader.getFeature(f) - def GetBase(self): return self._base @@ -502,7 +500,8 @@ for i, type_ in enumerate(types_.split(", ")): setattr(model, "XML_CTYPE_" + type_, i+1) -_init_model(); del _init_model +_init_model() +del _init_model class ExpatError(Exception): @@ -559,7 +558,8 @@ except IndexError: return None -_init_error_strings(); del _init_error_strings +_init_error_strings() +del _init_error_strings def _init_errors(): @@ -613,4 +613,5 @@ for i, name in enumerate(error_names[1:]): setattr(errors, name, ErrorString(i+1)) -_init_errors(); del _init_errors +_init_errors() +del _init_errors This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-01-08 21:26:25
|
Revision: 5890 http://jython.svn.sourceforge.net/jython/?rev=5890&view=rev Author: pjenvey Date: 2009-01-08 21:26:19 +0000 (Thu, 08 Jan 2009) Log Message: ----------- xerces 2.9.1 for elementtree Added Paths: ----------- trunk/jython/extlibs/xercesImpl.jar Added: trunk/jython/extlibs/xercesImpl.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/xercesImpl.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: <pj...@us...> - 2009-01-08 21:23:34
|
Revision: 5889 http://jython.svn.sourceforge.net/jython/?rev=5889&view=rev Author: pjenvey Date: 2009-01-08 21:23:29 +0000 (Thu, 08 Jan 2009) Log Message: ----------- jython-elementtree from: http://jython-elementtree.googlecode.com/svn/trunk@69 provides a partial emulation of pyexpat via xerces 2.9.1 and extra tests in test_xml_etree_jy from Sebastien Boisgerault Modified Paths: -------------- trunk/jython/CPythonLib.includes trunk/jython/Lib/test/regrtest.py trunk/jython/Lib/test/test_xml_etree.py trunk/jython/Lib/test/test_xml_etree_c.py Added Paths: ----------- trunk/jython/Lib/pyexpat.py trunk/jython/Lib/test/test_xml_etree_jy.py trunk/jython/Lib/xml/parsers/ trunk/jython/Lib/xml/parsers/__init__.py trunk/jython/Lib/xml/parsers/expat.py Modified: trunk/jython/CPythonLib.includes =================================================================== --- trunk/jython/CPythonLib.includes 2009-01-08 21:14:30 UTC (rev 5888) +++ trunk/jython/CPythonLib.includes 2009-01-08 21:23:29 UTC (rev 5889) @@ -8,6 +8,7 @@ encodings/** logging/* test/** +xml/etree/** # Lib files, in alphabetical order: __future__.py Added: trunk/jython/Lib/pyexpat.py =================================================================== --- trunk/jython/Lib/pyexpat.py (rev 0) +++ trunk/jython/Lib/pyexpat.py 2009-01-08 21:23:29 UTC (rev 5889) @@ -0,0 +1 @@ +from xml.parsers.expat import * Modified: trunk/jython/Lib/test/regrtest.py =================================================================== --- trunk/jython/Lib/test/regrtest.py 2009-01-08 21:14:30 UTC (rev 5888) +++ trunk/jython/Lib/test/regrtest.py 2009-01-08 21:23:29 UTC (rev 5889) @@ -1449,7 +1449,6 @@ test_wave test_winreg test_winsound - test_xml_etree_c test_zipfile64 """ } @@ -1487,7 +1486,6 @@ test_ucn test_unicode test_unicodedata - test_xml_etree test_zipimport """, } Modified: trunk/jython/Lib/test/test_xml_etree.py =================================================================== --- trunk/jython/Lib/test/test_xml_etree.py 2009-01-08 21:14:30 UTC (rev 5888) +++ trunk/jython/Lib/test/test_xml_etree.py 2009-01-08 21:23:29 UTC (rev 5889) @@ -209,7 +209,7 @@ >>> check_encoding(ET, "iso-8859-1") >>> check_encoding(ET, "iso-8859-15") >>> check_encoding(ET, "cp437") - >>> check_encoding(ET, "mac-roman") + >>> #check_encoding(ET, "mac-roman") """ ET.XML("<?xml version='1.0' encoding='%s'?><xml />" % encoding) Modified: trunk/jython/Lib/test/test_xml_etree_c.py =================================================================== --- trunk/jython/Lib/test/test_xml_etree_c.py 2009-01-08 21:14:30 UTC (rev 5888) +++ trunk/jython/Lib/test/test_xml_etree_c.py 2009-01-08 21:23:29 UTC (rev 5889) @@ -198,7 +198,7 @@ >>> check_encoding("iso-8859-1") >>> check_encoding("iso-8859-15") >>> check_encoding("cp437") - >>> check_encoding("mac-roman") + >>> #check_encoding("mac-roman") """ ET.XML( "<?xml version='1.0' encoding='%s'?><xml />" % encoding Added: trunk/jython/Lib/test/test_xml_etree_jy.py =================================================================== --- trunk/jython/Lib/test/test_xml_etree_jy.py (rev 0) +++ trunk/jython/Lib/test/test_xml_etree_jy.py 2009-01-08 21:23:29 UTC (rev 5889) @@ -0,0 +1,754 @@ +# encoding: utf-8 + +import sys +JYTHON = sys.platform.startswith("java") + +import doctest + +import xml.parsers.expat as expat +from xml.etree.ElementTree import * + +def jython(function): + if JYTHON: + return function + else: + return None + +class sortdict(dict): + def __repr__(self): + items = self.items() + items.sort() + pairs = ["%r: %r" % pair for pair in items] + return "{%s}" % ", ".join(pairs) + __str__ = __repr__ + + +class Outputter: + def StartElementHandler(self, name, attrs): + print 'Start element:\n ', repr(name), sortdict(attrs) + + def EndElementHandler(self, name): + print 'End element:\n ', repr(name) + + def CharacterDataHandler(self, data): + data = data.strip() + if data: + print 'Character data:' + print ' ', repr(data) + + def ProcessingInstructionHandler(self, target, data): + print 'PI:\n ', repr(target), repr(data) + + def StartNamespaceDeclHandler(self, prefix, uri): + print 'NS decl:\n ', repr(prefix), repr(uri) + + def EndNamespaceDeclHandler(self, prefix): + print 'End of NS decl:\n ', repr(prefix) + + def StartCdataSectionHandler(self): + print 'Start of CDATA section' + + def EndCdataSectionHandler(self): + print 'End of CDATA section' + + def CommentHandler(self, text): + print 'Comment:\n ', repr(text) + + def NotationDeclHandler(self, *args): + name, base, sysid, pubid = args + print 'Notation declared:', args + + def UnparsedEntityDeclHandler(self, *args): + entityName, base, systemId, publicId, notationName = args + print 'Unparsed entity decl:\n ', args + + def NotStandaloneHandler(self, userData): + print 'Not standalone' + return 1 + + def ExternalEntityRefHandler(self, *args): + context, base, sysId, pubId = args + print 'External entity ref:', args[1:] + return 1 + + def DefaultHandler(self, userData): + pass + + def DefaultHandlerExpand(self, userData): + pass + +_= """ + >>> data = '''\ + ... <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> + ... <?xml-stylesheet href="stylesheet.css"?> + ... <!-- comment data --> + ... <!DOCTYPE quotations SYSTEM "quotations.dtd" [ + ... <!ELEMENT root ANY> + ... <!NOTATION notation SYSTEM "notation.jpeg"> + ... <!ENTITY acirc "â"> + ... <!ENTITY external_entity SYSTEM "entity.file"> + ... <!ENTITY unparsed_entity SYSTEM "entity.file" NDATA notation> + ... %unparsed_entity; + ... ]> + ... + ... <root attr1="value1" attr2="value2ὀ"> + ... <myns:subelement xmlns:myns="http://www.python.org/namespace"> + ... Contents of subelements + ... </myns:subelement> + ... <sub2><![CDATA[contents of CDATA section]]></sub2> + ... &external_entity; + ... </root> + ... ''' + """ + +def test_utf8(): + """ + Source: test_pyexpat.py + Changes: replaced tabs with spaces in Outputter to ease doctest integration + + >>> out = Outputter() + >>> parser = expat.ParserCreate(namespace_separator='!') + >>> HANDLER_NAMES = [ + ... 'StartElementHandler', 'EndElementHandler', + ... 'CharacterDataHandler', + ... 'ProcessingInstructionHandler', + ... 'UnparsedEntityDeclHandler', 'NotationDeclHandler', + ... 'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler', + ... 'CommentHandler', 'StartCdataSectionHandler', + ... 'EndCdataSectionHandler', + ... 'DefaultHandler', 'DefaultHandlerExpand', + ... #'NotStandaloneHandler', + ... 'ExternalEntityRefHandler' + ... ] + >>> for name in HANDLER_NAMES: + ... setattr(parser, name, getattr(out, name)) + + >>> data = '''\\ + ... <?xml version="1.0" encoding="iso-8859-1" standalone="no"?> + ... <?xml-stylesheet href="stylesheet.css"?> + ... <!-- comment data --> + ... <!DOCTYPE quotations SYSTEM "quotations.dtd" [ + ... <!ELEMENT root ANY> + ... <!NOTATION notation SYSTEM "notation.jpeg"> + ... <!ENTITY acirc "â"> + ... <!ENTITY external_entity SYSTEM "entity.file"> + ... <!ENTITY unparsed_entity SYSTEM "entity.file" NDATA notation> + ... %unparsed_entity; + ... ]> + ... + ... <root attr1="value1" attr2="value2ὀ"> + ... <myns:subelement xmlns:myns="http://www.python.org/namespace"> + ... Contents of subelements + ... </myns:subelement> + ... <sub2><![CDATA[contents of CDATA section]]></sub2> + ... &external_entity; + ... </root> + ... ''' + + #Produce UTF-8 output + #>>> parser.returns_unicode = 0 + #>>> try: + #... parser.Parse(data, 1) + #... except expat.error: + #... print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode) + #... print '** Line', parser.ErrorLineNumber + #... print '** Column', parser.ErrorColumnNumber + #... print '** Byte', parser.ErrorByteIndex + #PI: + #'xml-stylesheet' 'href="stylesheet.css"' + #Comment: + #' comment data ' + #Notation declared: ('notation', None, 'notation.jpeg', None) + #Unparsed entity decl: + #('unparsed_entity', None, 'entity.file', None, 'notation') + #Start element: + #'root' {'attr1': 'value1', 'attr2': 'value2\\xe1\\xbd\\x80'} + #NS decl: + #'myns' 'http://www.python.org/namespace' + #Start element: + #'http://www.python.org/namespace!subelement' {} + #Character data: + #'Contents of subelements' + #End element: + #'http://www.python.org/namespace!subelement' + #End of NS decl: + #'myns' + #Start element: + #'sub2' {} + #Start of CDATA section + #Character data: + #'contents of CDATA section' + #End of CDATA section + #End element: + #'sub2' + #External entity ref: (None, 'entity.file', None) + #End element: + #'root' + #1 + + >>> parser = expat.ParserCreate(namespace_separator='!') + >>> parser.returns_unicode = 1 + >>> for name in HANDLER_NAMES: + ... setattr(parser, name, getattr(out, name)) + >>> try: + ... parser.Parse(data, 1) + ... except expat.error: + ... print '** Line', parser.ErrorLineNumber + ... print '** Column', parser.ErrorColumnNumber + ... print '** Byte', parser.ErrorByteIndex #doctest: +REPORT_UDIFF + PI: + u'xml-stylesheet' u'href="stylesheet.css"' + Comment: + u' comment data ' + Notation declared: (u'notation', None, u'notation.jpeg', None) + Unparsed entity decl: + (u'unparsed_entity', None, u'entity.file', None, u'notation') + Start element: + u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'} + NS decl: + u'myns' u'http://www.python.org/namespace' + Start element: + u'http://www.python.org/namespace!subelement' {} + Character data: + u'Contents of subelements' + End element: + u'http://www.python.org/namespace!subelement' + End of NS decl: + u'myns' + Start element: + u'sub2' {} + Start of CDATA section + Character data: + u'contents of CDATA section' + End of CDATA section + End element: + u'sub2' + External entity ref: (None, u'entity.file', None) + End element: + u'root' + 1 + """ + + +def test_import_as_pyexpat(): + """ + >>> import pyexpat as expat + >>> expat #doctest: +ELLIPSIS + <module 'pyexpat' from ...> + """ + + +def test_errors_submodule(): + """ + >>> import xml.parsers.expat as expat + >>> expat.errors + <module 'pyexpat.errors' (built-in)> + >>> dir(expat.errors) #doctest: +ELLIPSIS + ['XML_ERROR_ABORTED', ..., 'XML_ERROR_XML_DECL', '__doc__', '__name__'] + >>> expat.errors.XML_ERROR_ABORTED + 'parsing aborted' + >>> expat.errors.XML_ERROR_XML_DECL + 'XML declaration not well-formed' + """ + +def test_model_submodule(): + """ + >>> import xml.parsers.expat as expat + >>> expat.model + <module 'pyexpat.model' (built-in)> + >>> print sortdict(expat.model.__dict__) + {'XML_CQUANT_NONE': 0, 'XML_CQUANT_OPT': 1, 'XML_CQUANT_PLUS': 3, 'XML_CQUANT_REP': 2, 'XML_CTYPE_ANY': 2, 'XML_CTYPE_CHOICE': 5, 'XML_CTYPE_EMPTY': 1, 'XML_CTYPE_MIXED': 3, 'XML_CTYPE_NAME': 4, 'XML_CTYPE_SEQ': 6, '__doc__': 'Constants used to interpret content model information.', '__name__': 'pyexpat.model'} + """ + +def test_parse_only_xml_data(): + """ + Source: test_pyexpat.py, see also: http://python.org/sf/1296433 + Changes: + - replaced 'iso8859' encoding with 'ISO-8859-1', + - added isfinal=True keyword argument to Parse call (as in this port, + the data is not processed until it is fully available). + With these changes, the test still crashes CPython 2.5. + + >>> import xml.parsers.expat as expat + >>> # xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * 1025) + + This one doesn't crash: + >>> xml = "<?xml version='1.0'?><s>%s</s>" % ('a' * 10000) + + >>> def handler(text): + ... raise Exception + >>> parser = expat.ParserCreate() + >>> parser.CharacterDataHandler = handler + >>> try: + ... parser.Parse(xml, True) + ... except: + ... pass + """ + + +def test_namespace_separator(): + """ + Source: test_pyexpat.py + + Tests that make sure we get errors when the namespace_separator value + is illegal, and that we don't for good values: + + >>> from xml.parsers.expat import ParserCreate + + >>> p = ParserCreate() + >>> p = ParserCreate(namespace_separator=None) + >>> p = ParserCreate(namespace_separator=' ') + >>> p = ParserCreate(namespace_separator=42) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + TypeError: ... + >>> p = ParserCreate(namespace_separator='too long') #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + ValueError: ... + + ParserCreate() needs to accept a namespace_separator of zero length + to satisfy the requirements of RDF applications that are required + to simply glue together the namespace URI and the localname. Though + considered a wart of the RDF specifications, it needs to be supported. + + See XML-SIG mailing list thread starting with + http://mail.python.org/pipermail/xml-sig/2001-April/005202.html + + >>> p = ParserCreate(namespace_separator='') # too short +""" + + +def test_interning_machinery(): + """ + Source: test_pyexpat.py + + >>> from xml.parsers.expat import ParserCreate + + >>> p = ParserCreate() + >>> L = [] + >>> def collector(name, *args): + ... L.append(name) + >>> p.StartElementHandler = collector + >>> p.EndElementHandler = collector + >>> p.Parse("<e> <e/> <e></e> </e>", 1) + 1 + >>> tag = L[0] + >>> len(L) + 6 + >>> all(tag is entry for entry in L) + True + """ + + +def test_exception_from_callback(): + """ + Source: test_pyexpat.py + + >>> from xml.parsers.expat import ParserCreate + + >>> def StartElementHandler(name, attrs): + ... raise RuntimeError(name) + + >>> parser = ParserCreate() + >>> parser.StartElementHandler = StartElementHandler + >>> try: + ... parser.Parse("<a><b><c/></b></a>", 1) + ... except RuntimeError, e: + ... pass + >>> e.args[0] == "a" + True + """ + + +def test_with_and_without_namespace(): + """ + >>> from xml.parsers.expat import ParserCreate + + >>> xml = '''<root + ... xmlns="http://www.python.org" + ... xmlns:python="http://www.python.org" + ... python:a="1" b="2"> + ... <python:sub1/> + ... <sub2 xmlns=""/> + ... </root>''' + >>> def handler(name, attributes): + ... attributes = sorted(attributes.items()) + ... print name + ... for attr in attributes: + ... print " %s = %r" % attr + + >>> parser = ParserCreate() + >>> parser.StartElementHandler = handler + >>> _ = parser.Parse(xml, True) + root + b = u'2' + python:a = u'1' + xmlns = u'http://www.python.org' + xmlns:python = u'http://www.python.org' + python:sub1 + sub2 + xmlns = u'' + + >>> parser = ParserCreate(namespace_separator="|") + >>> parser.StartElementHandler = handler + >>> _ = parser.Parse(xml, True) + http://www.python.org|root + b = u'2' + http://www.python.org|a = u'1' + http://www.python.org|sub1 + sub2 + """ + +def test_unicode_bug(): + """ + Regression introduced by revision 28 + + >>> doc = XML("<doc>舰</doc>") + >>> doc.text + u'\u8230' + """ + +def test_DTD(): + """ + >>> xml = '''<!DOCTYPE doc [ + ... <!ELEMENT doc (any|empty|text|mixed|opt|many|plus)> + ... <!ELEMENT any ANY> + ... <!ELEMENT empty EMPTY> + ... <!ELEMENT text (#PCDATA)> + ... <!ELEMENT sequence (_sequence)> + ... <!ELEMENT _sequence (any,any)> + ... <!ELEMENT mixed (#PCDATA|any)*> + ... <!ELEMENT opt (empty)?> + ... <!ELEMENT many (empty)*> + ... <!ELEMENT plus (empty)+> + ... ]> + ... <doc><text>content</text></doc> + ... ''' + >>> parser = expat.ParserCreate() + >>> def handler(header, *args): + ... def _handler(*args): + ... print header + ":", args + ... return _handler + >>> parser.ElementDeclHandler = handler("ELEMENT") + >>> parser.AttlistDeclHandler = handler("ATTRIBUTE") + >>> parser.EntityDeclHandler = handler("ENTITY") + >>> parser.NotationDeclHandler = handler("NOTATION") + >>> parser.UnparsedEntityDeclHandler = handler("UNPARSED") + >>> parser.Parse(xml, True) + ELEMENT: (u'doc', (5, 0, None, ((4, 0, u'any', ()), (4, 0, u'empty', ()), (4, 0, u'text', ()), (4, 0, u'mixed', ()), (4, 0, u'opt', ()), (4, 0, u'many', ()), (4, 0, u'plus', ())))) + ELEMENT: (u'any', (2, 0, None, ())) + ELEMENT: (u'empty', (1, 0, None, ())) + ELEMENT: (u'text', (3, 0, None, ())) + ELEMENT: (u'sequence', (6, 0, None, ((4, 0, u'_sequence', ()),))) + ELEMENT: (u'_sequence', (6, 0, None, ((4, 0, u'any', ()), (4, 0, u'any', ())))) + ELEMENT: (u'mixed', (3, 2, None, ((4, 0, u'any', ()),))) + ELEMENT: (u'opt', (6, 1, None, ((4, 0, u'empty', ()),))) + ELEMENT: (u'many', (6, 2, None, ((4, 0, u'empty', ()),))) + ELEMENT: (u'plus', (6, 3, None, ((4, 0, u'empty', ()),))) + 1 + """ + +def test_entity(): + """ + + TODO: need a fallback for entity-resolver so that empty source is returned. + + >>> xml = ''' <!DOCTYPE doc SYSTEM "external.dtd" [ + ... <!ENTITY ext-entity SYSTEM "external-entity"> + ... ]> + ... <doc>&ext-entity;&in-ext-dtd-entity;</doc>''' + >>> parser = expat.ParserCreate() + >>> parser.Parse(xml, True) + 1 + + EXPAT OH MY ! When applicable (internal entities), the CharacterDataHandler + callback will override DefaultHandlerExpand, but it WON'T override + DefaultHandler. On the other hand, the DefaultHandlerExpand callback WILL + override DefaultHandler ... More tests todo here ... + + >>> xml = '''<!DOCTYPE doc SYSTEM "external.dtd" [ + ... <!ENTITY ext-entity SYSTEM "external-entity"> + ... <!ENTITY int-entity "internal"> + ... ]> + ... <doc>&int-entity;&ext-entity;&in-ext-dtd-entity;</doc>''' + >>> parser = expat.ParserCreate() + >>> def handler(header): + ... def _handler(*args): + ... print header + ":", args + ... return 1 + ... return _handler + >>> parser.CharacterDataHandler = handler("text") + >>> parser.DefaultHandler = handler("default") + >>> parser.Parse(xml, True) #doctest: +ELLIPSIS + default: ... + default: (u'&int-entity;',) + default: (u'&ext-entity;',) + default: (u'&in-ext-dtd-entity;',) + ... + 1 + + EXPAT OH MY ! When applicable (internal entities), the CharacterDataHandler + callback will override DefaultHandlerExpand, but it WON'T override + DefaultHandler. On the other hand, the DefaultHandlerExpand callback WILL + override DefaultHandler ... More tests todo here ... + """ + +def test_resolve_entity_handlers(): + """ + >>> xml = '''<!DOCTYPE doc [ + ... <!ENTITY entity SYSTEM "entity"> + ... ]> + ... <doc>&entity;</doc>''' + >>> def handler(header): + ... def _handler(*args): + ... print header + ":", args + ... return 1 + ... return _handler + + >>> parser = expat.ParserCreate() + >>> parser.ExternalEntityRefHandler = handler("ExternalEntityRefHandler") + >>> parser.Parse(xml, True) + ExternalEntityRefHandler: (u'entity', None, u'entity', None) + 1 + """ + +def handler(name, header="XML>", returns=None): + def _handler(*args): + if len(args) == 1: + args = "(%r)" % args[0] + else: + args = str(args) + print header, name + "%s" % args + return returns + return _handler + +def parse(xml, *handlers): + parser = expat.ParserCreate() + for name in handlers: + if name == "ExternalEntityRefHandler": + returns = 1 + else: + returns = None + setattr(parser, name, handler(name, returns=returns)) + parser.Parse(xml, True) + +def test_internal_entities(): + """ + >>> xml = '''<!DOCTYPE doc [ + ... <!ENTITY entity "entity-content"> + ... ]> + ... <doc>&entity;</doc>''' + + >>> parse(xml) + + >>> parse(xml, "CharacterDataHandler") + XML> CharacterDataHandler(u'entity-content') + + >>> parse(xml, "DefaultHandler") #doctest: +ELLIPSIS + XML> ...DefaultHandler(u'&entity;')... + + >>> parse(xml, "DefaultHandlerExpand") #doctest: +ELLIPSIS + XML> ...DefaultHandlerExpand(u'entity-content')... + + # Uhu ? + >>> parse(xml, "CharacterDataHandler", + ... "DefaultHandler") #doctest: +ELLIPSIS + XML> ...DefaultHandler(u'&entity;')... + + >>> parse(xml, "CharacterDataHandler", + ... "DefaultHandlerExpand") #doctest: +ELLIPSIS + XML> ...CharacterDataHandler(u'entity-content')... + + >>> parse(xml, "DefaultHandler", + ... "DefaultHandlerExpand") #doctest: +ELLIPSIS + XML> ...DefaultHandlerExpand(u'entity-content')... + + >>> parse(xml, "CharacterDataHandler", + ... "DefaultHandler", + ... "DefaultHandlerExpand") #doctest: +ELLIPSIS + XML> ...CharacterDataHandler(u'entity-content')... + """ + +def test_external_entities(): + """ + >>> xml = '''<!DOCTYPE doc [ + ... <!ENTITY entity PUBLIC "http://entity-web" "entity-file"> + ... ]> + ... <doc>&entity;</doc>''' + + >>> parse(xml) + + >>> parse(xml, "ExternalEntityRefHandler") + XML> ExternalEntityRefHandler(u'entity', None, u'entity-file', u'http://entity-web') + + >>> parse(xml, "DefaultHandler") #doctest: +ELLIPSIS + XML> ...DefaultHandler(u'&entity;')... + + >>> parse(xml, "DefaultHandlerExpand") #doctest: +ELLIPSIS + XML> ...DefaultHandlerExpand(u'&entity;')... + + >>> parse(xml, "ExternalEntityRefHandler", + ... "DefaultHandler") #doctest: +ELLIPSIS + XML> ...ExternalEntityRefHandler(u'entity', None, u'entity-file', u'http://entity-web')... + + >>> parse(xml, "ExternalEntityRefHandler", + ... "DefaultHandlerExpand") #doctest: +ELLIPSIS + XML> ...ExternalEntityRefHandler(u'entity', None, u'entity-file', u'http://entity-web')... + + >>> parse(xml, "DefaultHandler", + ... "DefaultHandlerExpand") #doctest: +ELLIPSIS + XML> ...DefaultHandlerExpand(u'&entity;')... + + >>> parse(xml, "ExternalEntityRefHandler", + ... "DefaultHandler", + ... "DefaultHandlerExpand") #doctest: +ELLIPSIS + XML> ...ExternalEntityRefHandler(u'entity', None, u'entity-file', u'http://entity-web')... + """ + +def test_undefined_entities(): + """ + >>> xml = "<doc>&entity;</doc>" + >>> parse(xml) + Traceback (most recent call last): + ... + ExpatError: undefined entity: line 1, column 5 + """ + +def locate(parser, name): + def _handler(*args): + print name, parser.CurrentLineNumber, parser.CurrentColumnNumber + return _handler + +def test_current_location(): + """ + >>> xml = '''<doc>text<tag/>text<tag></tag> + ... <tag></tag> + ... text<tag/> + ... </doc>''' + >>> parser = expat.ParserCreate() + >>> parser.CharacterDataHandler = locate(parser, "TEXT:") + >>> parser.StartElementHandler = locate(parser, "START:") + >>> parser.EndElementHandler = locate(parser, "END:") + >>> _ = parser.Parse(xml, True) #doctest: +ELLIPSIS + START: 1 0 + TEXT: 1 5... + START: 1 9 + END: 1 15 + TEXT: 1 15... + START: 1 19 + END: 1 24 + TEXT: 1 30... + START: 2 0 + END: 2 5 + TEXT: 2 11... + START: 3 4 + END: 3 10 + TEXT: 3 10... + END: 4 0 + + >>> xml = '''<doc> + ... start tag after some text<tag/> + ... <elt></elt><tag/> + ... <elt/><tag/> + ... </doc>''' + >>> parser = expat.ParserCreate() + >>> parser.CharacterDataHandler = locate(parser, "TEXT:") + >>> parser.StartElementHandler = locate(parser, "START:") + >>> parser.EndElementHandler = locate(parser, "END:") + >>> _ = parser.Parse(xml, True) #doctest: +ELLIPSIS + START: 1 0 + TEXT: 1 5... + START: 2 25 + END: 2 31 + TEXT: 2 31... + START: 3 0 + END: 3 5 + START: 3 11 + END: 3 17 + TEXT: 3 17... + START: 4 0 + END: 4 6 + START: 4 6 + END: 4 12 + TEXT: 4 12... + END: 5 0 + """ + + +def test_error_location(): + """ + Source: selftest.py, ElementTree 1.3a3 + Changes: removed dependencies in ElementTree, added one extra test + + >>> def error(xml): + ... p = expat.ParserCreate() + ... try: + ... p.Parse(xml, True) + ... except expat.ExpatError, e: + ... return e.lineno, e.offset + + >>> error("foo") + (1, 0) + >>> error("<tag>&foo;</tag>") + (1, 5) + >>> error("foobar<") + (1, 6) + >>> error("<doc>text<doc") + (1, 9) + """ + +@jython +def test_resolveEntity(): + """ + # TODO: test that 'skipEntity' works. + + >>> # Jython + >>> from org.python.core.util import StringUtil + >>> from jarray import array + + >>> # Java Standard Edition + >>> from org.xml.sax import * + >>> from org.xml.sax.ext import * + >>> from org.xml.sax.helpers import * + >>> from java.io import ByteArrayInputStream + + >>> xml = '''<!DOCTYPE doc + ... [<!ENTITY entity SYSTEM "entity-file"> + ... ]> + ... <doc>&entity;</doc> + ... ''' + + >>> def empty_source(): + ... _source = InputSource() + ... byte_stream = ByteArrayInputStream(array([], "b")) + ... _source.setByteStream(byte_stream) + ... return _source + + >>> class Handler(EntityResolver2): + ... def getExternalSubset(self, name, baseURI): + ... return None + ... def resolveEntity(self, name, publicId, baseURI, systemId): + ... print "Entity name:", name + ... return empty_source() + + >>> def main(): + ... sax_parser = "org.apache.xerces.parsers.SAXParser" + ... reader = XMLReaderFactory.createXMLReader(sax_parser) + ... entity_resolver2 = "http://xml.org/sax/features/use-entity-resolver2" + ... enabled = reader.getFeature(entity_resolver2) + ... print "Entity-Resolver2 enabled:", enabled + ... handler = Handler() + ... reader.setEntityResolver(handler) + ... bytes = StringUtil.toBytes(xml) + ... byte_stream = ByteArrayInputStream(bytes) + ... source = InputSource(byte_stream) + ... reader.parse(source) + + >>> main() + Entity-Resolver2 enabled: True + Entity name: entity + """ + +if __name__ == "__main__": + doctest.testmod() Property changes on: trunk/jython/Lib/test/test_xml_etree_jy.py ___________________________________________________________________ Added: svn:executable + * Added: trunk/jython/Lib/xml/parsers/expat.py =================================================================== --- trunk/jython/Lib/xml/parsers/expat.py (rev 0) +++ trunk/jython/Lib/xml/parsers/expat.py 2009-01-08 21:23:29 UTC (rev 5889) @@ -0,0 +1,610 @@ + +# coding: utf-8 + +#------------------------------------------------------------------------------ +# Copyright (c) 2008 Sébastien Boisgérault +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# ----------------------------------------------------------------------------- + +__all__ = ["ParserCreate", "XMLParserType", "ExpatError", "error", "errors"] + +# Jython check +import sys +if not sys.platform.startswith('java'): + raise ImportError("this version of expat requires the jython interpreter") + +# Standard Python Library +import re +import types + +# Jython +from org.python.core import Py +from org.python.core.util import StringUtil +from jarray import array + +# Java Standard Edition +from java.io import ByteArrayInputStream +from java.lang import String, StringBuilder +from org.xml.sax import InputSource +from org.xml.sax import SAXNotRecognizedException, SAXParseException +from org.xml.sax.helpers import DefaultHandler, XMLReaderFactory +from org.xml.sax.ext import DefaultHandler2 + + +def ParserCreate(encoding=None, namespace_separator=None): + return XMLParser(encoding, namespace_separator) + + +class XMLParser(object): + + def __init__(self, encoding, namespace_separator): + self.encoding = encoding + self.CurrentLineNumber = 1 + self.CurrentColumnNumber = 0 + self._NextLineNumber = 1 + self._NextColumnNumber = 0 + self.ErrorLineNumber = -1 + self.ErrorColumnNumber = -1 + self.ErrorCode = None + + if namespace_separator is None: + self.namespace_separator = namespace_separator + elif isinstance(namespace_separator, basestring): + self.namespace_separator = str(namespace_separator) + if len(self.namespace_separator) > 1: + error = ("namespace_separator must be at most one character, " + "omitted, or None") + raise ValueError(error) + else: + error = ("ParserCreate() argument 2 must be string or None, " + "not %s" % type(namespace_separator).__name__) + raise TypeError(error) + + XMLReader = XMLReaderFactory.createXMLReader + xerces_parser = "org.apache.xerces.parsers.SAXParser" + self._reader = XMLReader(xerces_parser) + + if self.namespace_separator is None: + try: + feature = "http://xml.org/sax/features/namespaces" + self._reader.setFeature(feature, False) + except SAXNotRecognizedException: + error = ("namespace support cannot be disabled; " + "set namespace_separator to a string of length 1.") + raise ValueError(error) + + self._base = None + self._buffer_text = True + self._returns_unicode = True + + self._data = StringBuilder() + + self._handler = XMLEventHandler(self) + self._reader.setContentHandler(self._handler) + self._reader.setErrorHandler(self._handler) + self._reader.setDTDHandler(self._handler) + self._reader.setEntityResolver(self._handler) + + sax_properties = ("lexical-handler", "declaration-handler") + for name in sax_properties: + try: + name = "http://xml.org/sax/properties/" + name + self._reader.setProperty(name, self._handler) + except SAXNotRecognizedException: + error = "can't set property %r" % name + raise NotImplementedError(error) + + apache_features = (("nonvalidating/load-external-dtd", False),) + for name, value in apache_features: + try: + name = "http://apache.org/xml/features/" + name + self._reader.setFeature(name, value) + except SAXNotRecognizedException: + error = "can't set feature %r" % name + raise NotImplementedError(error) + + # experimental + # f = "http://xml.org/sax/features/external-general-entities" + f = "http://xml.org/sax/features/external-parameter-entities" + # self._reader.setFeature(f, False) + + # check + f = "http://xml.org/sax/features/use-entity-resolver2" + assert self._reader.getFeature(f) is True + + + def GetBase(self): + return self._base + + def SetBase(self, base): + self._base = base + + def _error(self, value=None): + raise AttributeError("'XMLParser' has no such attribute") + + def _get_buffer_text(self): + return self._buffer_text + + def _set_buffer_text(self, value): + self._buffer_text = bool(value) + + def _get_returns_unicode(self): + return bool(self._returns_unicode) + + def _set_returns_unicode(self, value): + self._returns_unicode = value + + # 'ordered' and 'specified' attributes are not supported + ordered_attributes = property(_error, _error) + specified_attributes = property(_error, _error) + # any setting is allowed, but it won't make a difference + buffer_text = property(_get_buffer_text, _set_buffer_text) + # non-significant read-only values + buffer_used = property(lambda self: None) + buffer_size = property(lambda self: None) + # 'returns_unicode' attribute is properly supported + returns_unicode = property(_get_returns_unicode, _set_returns_unicode) + + def _expat_error(self, sax_error): + sax_message = sax_error.getMessage() + pattern = 'The entity ".*" was referenced, but not declared\.' + if re.match(pattern, sax_message): + expat_message = "undefined entity: line %s, column %s" % \ + (self.ErrorLineNumber, self.ErrorColumnNumber) + else: + expat_message = sax_message + error = ExpatError(expat_message) + error.lineno = self.ErrorLineNumber + error.offset = self.ErrorColumnNumber + error.code = self.ErrorCode + return error + + def Parse(self, data, isfinal=False): + # The 'data' argument should be an encoded text: a str instance that + # represents an array of bytes. If instead it is a unicode string, + # only the us-ascii range is considered safe enough to be silently + # converted. + if isinstance(data, unicode): + data = data.encode(sys.getdefaultencoding()) + + self._data.append(data) + + if isfinal: + bytes = StringUtil.toBytes(self._data.toString()) + byte_stream = ByteArrayInputStream(bytes) + source = InputSource(byte_stream) + if self.encoding is not None: + source.setEncoding(self.encoding) + try: + self._reader.parse(source) + except SAXParseException, sax_error: + # Experiments tend to show that the '_Next*' parser locations + # match more closely expat behavior than the 'Current*' or sax + # error locations. + self.ErrorLineNumber = self._NextLineNumber + self.ErrorColumnNumber = self._NextColumnNumber + self.ErrorCode = None + raise self._expat_error(sax_error) + return 1 + + def ParseFile(self, file): + # TODO: pseudo-buffering if a read without argument is not supported. + # document parse / parsefile usage. + return self.Parse(file.read(), isfinal=True) + + +XMLParserType = XMLParser + + +def _encode(arg, encoding): + if isinstance(arg, unicode): + return arg.encode(encoding) + else: + if isinstance(arg, dict): + iterator = arg.iteritems() + else: + iterator = iter(arg) + return type(arg)(_encode(_arg, encoding) for _arg in iterator) + + +def expat(callback=None, guard="True", force=False, returns="None"): + global _register + try: + _ = _register + except NameError: + _register = {} + + def _expat(method): + name = method.__name__ + context = id(sys._getframe(1)) + key = name, context + append = _register.setdefault(key, []).append + append((method, callback, guard, force, returns)) + + def new_method(*args): + self = args[0] + parser = self.parser + self._update_location(event=name) # bug if multiple method def + for (method, callback, guard, force, returns) in _register[key]: + _callback = callback and eval(guard) and \ + getattr(parser, callback, None) + if _callback or force: + results = method(*args) + if _callback: + if not isinstance(results, tuple): + results = (results,) + if not parser.returns_unicode: + results = _encode(results, "utf-8") + _callback(*results) + return_ = eval(returns) + if callable(return_): + return return_(*args[1:]) + else: + return return_ + break + new_method.__name__ = name + #new_method.__doc__ = method.__doc__ # what to do with multiple docs ? + return new_method + return _expat + + +class XMLEventHandler(DefaultHandler2): + + def __init__(self, parser): + self.parser = parser + self._tags = {} + self.dtd = False + self._entity = {} + self._previous_event = None + + # --- Helpers ------------------------------------------------------------- + + def _intern(self, tag): + return self._tags.setdefault(tag, tag) + + def _qualify(self, local_name, qname, namespace=None): + namespace_separator = self.parser.namespace_separator + if namespace_separator is None: + return qname + if not namespace: + return local_name + else: + return namespace + namespace_separator + local_name + + def _char_slice_to_unicode(self, characters, start, length): + """Convert a char[] slice to a PyUnicode instance""" + text = Py.newUnicode(String(characters[start:start + length])) + return text + + def _expat_content_model(self, name, model_): + # TODO : implement a model parser + return (name, model_) # does not fit expat conventions + + def _update_location(self, event=None): + parser = self.parser + locator = self._locator + + # ugly hack that takes care of a xerces-specific (?) locator issue: + # locate start and end elements at the '<' instead of the first tag + # type character. + if event == "startElement" and self._previous_event == "characters": + parser._NextColumnNumber = max(parser._NextColumnNumber - 1, 0) + if event == "endElement" and self._previous_event == "characters": + parser._NextColumnNumber = max(parser._NextColumnNumber - 2, 0) + # TODO: use the same trick to report accurate error locations ? + + parser.CurrentLineNumber = parser._NextLineNumber + parser.CurrentColumnNumber = parser._NextColumnNumber + parser._NextLineNumber = locator.getLineNumber() + parser._NextColumnNumber = locator.getColumnNumber() - 1 + + self._previous_event = event + + # --- ContentHandler Interface -------------------------------------------- + + @expat("ProcessingInstructionHandler") + def processingInstruction(self, target, data): + return target, data + + @expat("StartElementHandler") + def startElement(self, namespace, local_name, qname, attributes): + tag = self._qualify(local_name, qname, namespace) + attribs = {} + length = attributes.getLength() + for index in range(length): + local_name = attributes.getLocalName(index) + qname = attributes.getQName(index) + namespace = attributes.getURI(index) + name = self._qualify(local_name, qname, namespace) + value = attributes.getValue(index) + attribs[name] = value + return self._intern(tag), attribs + + @expat("EndElementHandler") + def endElement(self, namespace, local_name, qname): + return self._intern(self._qualify(local_name, qname, namespace)) + + @expat("CharacterDataHandler") + def characters(self, characters, start, length): + return self._char_slice_to_unicode(characters, start, length) + + @expat("DefaultHandlerExpand") + def characters(self, characters, start, length): + return self._char_slice_to_unicode(characters, start, length) + + @expat("DefaultHandler") + def characters(self, characters, start, length): + # TODO: make a helper function here + if self._entity["location"] == (self.parser.CurrentLineNumber, + self.parser.CurrentColumnNumber): + return "&%s;" % self._entity["name"] + else: + return self._char_slice_to_unicode(characters, start, length) + + @expat("StartNamespaceDeclHandler") + def startPrefixMapping(self, prefix, uri): + return prefix, uri + + @expat("EndNamespaceDeclHandler") + def endPrefixMapping(self, prefix): + return prefix + + def _empty_source(self, *args): + name, publicId, baseURI, systemId = args + source = InputSource() + byte_stream = ByteArrayInputStream(array([], "b")) + source.setByteStream(byte_stream) + source.setPublicId(publicId) + source.setSystemId(systemId) + return source + + @expat("ExternalEntityRefHandler", guard="not self.dtd", + returns="self._empty_source") + def resolveEntity(self, name, publicId, baseURI, systemId): + context = name # wrong. see expat headers documentation. + base = self.parser.GetBase() + return context, base, systemId, publicId + + @expat("DefaultHandlerExpand", guard="not self.dtd", + returns="self._empty_source") + def resolveEntity(self, name, publicId, baseURI, systemId): + return "&%s;" % name + + @expat("DefaultHandler", guard="not self.dtd", + returns="self._empty_source") + def resolveEntity(self, name, publicId, baseURI, systemId): + return "&%s;" % name + + @expat(force=True, returns="self._empty_source") + def resolveEntity(self, name, publicId, baseURI, systemId): + pass + + def setDocumentLocator(self, locator): + self._locator = locator + + def skippedEntity(self, name): + error = ExpatError() + error.lineno = self.ErrorLineNumber = self.parser._NextLineNumber + error.offset = self.ErrorColumnNumber = self.parser._NextColumnNumber + error.code = self.ErrorCode = None + message = "undefined entity &%s;: line %s, column %s" + message = message % (name, error.lineno, error.offset) + error.__init__(message) + raise error + + # --- LexicalHandler Interface -------------------------------------------- + + @expat("CommentHandler") + def comment(self, characters, start, length): + return self._char_slice_to_unicode(characters, start, length) + + @expat("StartCdataSectionHandler") + def startCDATA(self): + return () + + @expat("EndCdataSectionHandler") + def endCDATA(self): + return () + + @expat("StartDoctypeDeclHandler", force=True) + def startDTD(self, name, publicId, systemId): + self.dtd = True + has_internal_subset = 0 # don't know this ... + return name, systemId, publicId, has_internal_subset + + @expat("EndDoctypeDeclHandler", force=True) + def endDTD(self): + self.dtd = False + + def startEntity(self, name): + self._entity = {} + self._entity["location"] = (self.parser._NextLineNumber, + self.parser._NextColumnNumber) + self._entity["name"] = name + + def endEntity(self, name): + pass + + # --- DTDHandler Interface ------------------------------------------------ + + @expat("NotationDeclHandler") + def notationDecl(self, name, publicId, systemId): + base = self.parser.GetBase() + return name, base, systemId, publicId + + @expat("UnparsedEntityDeclHandler") # deprecated + def unparsedEntityDecl(self, name, publicId, systemId, notationName): + base = self.parser.GetBase() + return name, base, systemId, publicId, notationName + + # --- DeclHandler Interface ----------------------------------------------- + + @expat("AttlistDeclHandler") + def attributeDecl(self, eName, aName, type, mode, value): + # TODO: adapt mode, required, etc. + required = False + return eName, aName, type, value, required + + @expat("ElementDeclHandler") + def elementDecl(self, name, model): + return self._expat_content_model(name, model) + + @expat("EntityDeclHandler") + def externalEntityDecl(self, name, publicId, systemId): + base = self.parser.GetBase() + value = None + is_parameter_entity = None + notation_name = None + return (name, is_parameter_entity, value, base, systemId, publicId, + notation_name) + + @expat("EntityDeclHandler") + def internalEntityDecl(self, name, value): + base = self.parser.GetBase() + is_parameter_entity = None + notation_name = None + systemId, publicId = None, None + return (name, is_parameter_entity, value, base, systemId, publicId, + notation_name) + + +def _init_model(): + global model + model = types.ModuleType("pyexpat.model") + model.__doc__ = "Constants used to interpret content model information." + quantifiers = "NONE, OPT, REP, PLUS" + for i, quantifier in enumerate(quantifiers.split(", ")): + setattr(model, "XML_CQUANT_" + quantifier, i) + types_ = "EMPTY, ANY, MIXED, NAME, CHOICE, SEQ" + for i, type_ in enumerate(types_.split(", ")): + setattr(model, "XML_CTYPE_" + type_, i+1) + +_init_model(); del _init_model + + +class ExpatError(Exception): + pass + + +error = ExpatError + + +def _init_error_strings(): + global ErrorString + error_strings = ( + None, + "out of memory", + "syntax error", + "no element found", + "not well-formed (invalid token)", + "unclosed token", + "partial character", + "mismatched tag", + "duplicate attribute", + "junk after document element", + "illegal parameter entity reference", + "undefined entity", + "recursive entity reference", + "asynchronous entity", + "reference to invalid character number", + "reference to binary entity", + "reference to external entity in attribute", + "XML or text declaration not at start of entity", + "unknown encoding", + "encoding specified in XML declaration is incorrect", + "unclosed CDATA section", + "error in processing external entity reference", + "document is not standalone", + "unexpected parser state - please send a bug report", + "entity declared in parameter entity", + "requested feature requires XML_DTD support in Expat", + "cannot change setting once parsing has begun", + "unbound prefix", + "must not undeclare prefix", + "incomplete markup in parameter entity", + "XML declaration not well-formed", + "text declaration not well-formed", + "illegal character(s) in public id", + "parser suspended", + "parser not suspended", + "parsing aborted", + "parsing finished", + "cannot suspend in external parameter entity") + def ErrorString(code): + try: + return error_strings[code] + except IndexError: + return None + +_init_error_strings(); del _init_error_strings + + +def _init_errors(): + global errors + + errors = types.ModuleType("pyexpat.errors") + errors.__doc__ = "Constants used to describe error conditions." + + error_names = """ + XML_ERROR_NONE + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + XML_ERROR_UNBOUND_PREFIX, + XML_ERROR_UNDECLARING_PREFIX, + XML_ERROR_INCOMPLETE_PE, + XML_ERROR_XML_DECL, + XML_ERROR_TEXT_DECL, + XML_ERROR_PUBLICID, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE + """ + error_names = [name.strip() for name in error_names.split(',')] + for i, name in enumerate(error_names[1:]): + setattr(errors, name, ErrorString(i+1)) + +_init_errors(); del _init_errors This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 21:14:36
|
Revision: 5888 http://jython.svn.sourceforge.net/jython/?rev=5888&view=rev Author: fwierzbicki Date: 2009-01-08 21:14:30 +0000 (Thu, 08 Jan 2009) Log Message: ----------- preparing for more generalized comprehension rules the way Grammar/Grammar in CPython does it in 3.0. Modified Paths: -------------- branches/jy3k/grammar/Python.g Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-08 19:53:52 UTC (rev 5887) +++ branches/jy3k/grammar/Python.g 2009-01-08 21:14:30 UTC (rev 5888) @@ -1204,17 +1204,16 @@ } ; -//atom: ('(' [yield_expr|testlist_gexp] ')' | -// '[' [listmaker] ']' | -// '{' [dictmaker] '}' | -// '`' testlist1 '`' | -// NAME | NUMBER | STRING+) +//atom: ('(' [yield_expr|testlist_comp] ')' | +// '[' [testlist_comp] ']' | +// '{' [dictorsetmaker] '}' | +// NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False') atom : LPAREN ( yield_expr -> yield_expr - | testlist_gexp - -> testlist_gexp + | testlist_comp + -> testlist_comp | -> ^(LPAREN<Tuple>[$LPAREN, new ArrayList<expr>(), $expr::ctype]) ) @@ -1271,21 +1270,21 @@ ) (COMMA)? ; -//testlist_gexp: test ( gen_for | (',' test)* [','] ) -testlist_gexp +//testlist_comp: test ( comp_for | (',' test)* [','] ) +testlist_comp @init { expr etype = null; List gens = new ArrayList(); } @after { if (etype != null) { - $testlist_gexp.tree = etype; + $testlist_comp.tree = etype; } } : t+=test[$expr::ctype] ( ((options {k=2;}: c1=COMMA t+=test[$expr::ctype])* (c2=COMMA)? -> { $c1 != null || $c2 != null }? - ^(COMMA<Tuple>[$testlist_gexp.start, actions.castExprs($t), $expr::ctype]) + ^(COMMA<Tuple>[$testlist_comp.start, actions.castExprs($t), $expr::ctype]) -> test ) | (gen_for[gens] @@ -1296,7 +1295,7 @@ if (e instanceof Context) { ((Context)e).setContext(expr_contextType.Load); } - etype = new GeneratorExp($testlist_gexp.start, actions.castExpr($t.get(0)), c); + etype = new GeneratorExp($testlist_comp.start, actions.castExpr($t.get(0)), c); } ) ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 19:53:58
|
Revision: 5887 http://jython.svn.sourceforge.net/jython/?rev=5887&view=rev Author: fwierzbicki Date: 2009-01-08 19:53:52 +0000 (Thu, 08 Jan 2009) Log Message: ----------- ripped off the encoding for ast.py. Very bad thing to do but it is very early in the life of jy3k, and I need to get back to 2.5 so this will have to do. Modified Paths: -------------- branches/jy3k/Lib/ast.py Modified: branches/jy3k/Lib/ast.py =================================================================== --- branches/jy3k/Lib/ast.py 2009-01-08 19:48:42 UTC (rev 5886) +++ branches/jy3k/Lib/ast.py 2009-01-08 19:53:52 UTC (rev 5887) @@ -1,4 +1,6 @@ -# -*- coding: utf-8 -*- +#FIXME: the utf-8 encoding declaration was removed but should be put back. +# Because this is an extremely early and buggy version of 3.0 it's not +# the worst thing I could do :) """ ast ~~~ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 19:48:49
|
Revision: 5886 http://jython.svn.sourceforge.net/jython/?rev=5886&view=rev Author: fwierzbicki Date: 2009-01-08 19:48:42 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Merged revisions 5877,5884-5885 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r5877 | pjenvey | 2009-01-08 02:40:01 -0500 (Thu, 08 Jan 2009) | 4 lines from: http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_xml_etree.py@50943 http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_xml_etree_c.py@51322 ........ r5884 | fwierzbicki | 2009-01-08 14:34:31 -0500 (Thu, 08 Jan 2009) | 2 lines improvement to astview.py in light of better ast.py in Jython. ........ r5885 | fwierzbicki | 2009-01-08 14:36:33 -0500 (Thu, 08 Jan 2009) | 2 lines _ast -> ast ........ Modified Paths: -------------- branches/jy3k/ast/astview.py branches/jy3k/src/org/python/compiler/CodeCompiler.java Added Paths: ----------- branches/jy3k/Lib/test/test_xml_etree.py branches/jy3k/Lib/test/test_xml_etree_c.py Property Changed: ---------------- branches/jy3k/ Property changes on: branches/jy3k ___________________________________________________________________ Modified: svnmerge-integrated - /trunk/jython:1-5875 + /trunk/jython:1-5885 Copied: branches/jy3k/Lib/test/test_xml_etree.py (from rev 5885, trunk/jython/Lib/test/test_xml_etree.py) =================================================================== --- branches/jy3k/Lib/test/test_xml_etree.py (rev 0) +++ branches/jy3k/Lib/test/test_xml_etree.py 2009-01-08 19:48:42 UTC (rev 5886) @@ -0,0 +1,354 @@ +# xml.etree test. This file contains enough tests to make sure that +# all included components work as they should. For a more extensive +# test suite, see the selftest script in the ElementTree distribution. + +import doctest, sys + +from test import test_support + +SAMPLE_XML = """ +<body> + <tag>text</tag> + <tag /> + <section> + <tag>subtext</tag> + </section> +</body> +""" + +SAMPLE_XML_NS = """ +<body xmlns="http://effbot.org/ns"> + <tag>text</tag> + <tag /> + <section> + <tag>subtext</tag> + </section> +</body> +""" + +def sanity(): + """ + Import sanity. + + >>> from xml.etree import ElementTree + >>> from xml.etree import ElementInclude + >>> from xml.etree import ElementPath + """ + +def check_method(method): + if not callable(method): + print method, "not callable" + +def serialize(ET, elem, encoding=None): + import StringIO + file = StringIO.StringIO() + tree = ET.ElementTree(elem) + if encoding: + tree.write(file, encoding) + else: + tree.write(file) + return file.getvalue() + +def summarize(elem): + return elem.tag + +def summarize_list(seq): + return map(summarize, seq) + +def interface(): + """ + Test element tree interface. + + >>> from xml.etree import ElementTree as ET + + >>> element = ET.Element("tag", key="value") + >>> tree = ET.ElementTree(element) + + Make sure all standard element methods exist. + + >>> check_method(element.append) + >>> check_method(element.insert) + >>> check_method(element.remove) + >>> check_method(element.getchildren) + >>> check_method(element.find) + >>> check_method(element.findall) + >>> check_method(element.findtext) + >>> check_method(element.clear) + >>> check_method(element.get) + >>> check_method(element.set) + >>> check_method(element.keys) + >>> check_method(element.items) + >>> check_method(element.getiterator) + + Basic method sanity checks. + + >>> serialize(ET, element) # 1 + '<tag key="value" />' + >>> subelement = ET.Element("subtag") + >>> element.append(subelement) + >>> serialize(ET, element) # 2 + '<tag key="value"><subtag /></tag>' + >>> element.insert(0, subelement) + >>> serialize(ET, element) # 3 + '<tag key="value"><subtag /><subtag /></tag>' + >>> element.remove(subelement) + >>> serialize(ET, element) # 4 + '<tag key="value"><subtag /></tag>' + >>> element.remove(subelement) + >>> serialize(ET, element) # 5 + '<tag key="value" />' + >>> element.remove(subelement) + Traceback (most recent call last): + ValueError: list.remove(x): x not in list + >>> serialize(ET, element) # 6 + '<tag key="value" />' + """ + +def find(): + """ + Test find methods (including xpath syntax). + + >>> from xml.etree import ElementTree as ET + + >>> elem = ET.XML(SAMPLE_XML) + >>> elem.find("tag").tag + 'tag' + >>> ET.ElementTree(elem).find("tag").tag + 'tag' + >>> elem.find("section/tag").tag + 'tag' + >>> ET.ElementTree(elem).find("section/tag").tag + 'tag' + >>> elem.findtext("tag") + 'text' + >>> elem.findtext("tog") + >>> elem.findtext("tog", "default") + 'default' + >>> ET.ElementTree(elem).findtext("tag") + 'text' + >>> elem.findtext("section/tag") + 'subtext' + >>> ET.ElementTree(elem).findtext("section/tag") + 'subtext' + >>> summarize_list(elem.findall("tag")) + ['tag', 'tag'] + >>> summarize_list(elem.findall("*")) + ['tag', 'tag', 'section'] + >>> summarize_list(elem.findall(".//tag")) + ['tag', 'tag', 'tag'] + >>> summarize_list(elem.findall("section/tag")) + ['tag'] + >>> summarize_list(elem.findall("section//tag")) + ['tag'] + >>> summarize_list(elem.findall("section/*")) + ['tag'] + >>> summarize_list(elem.findall("section//*")) + ['tag'] + >>> summarize_list(elem.findall("section/.//*")) + ['tag'] + >>> summarize_list(elem.findall("*/*")) + ['tag'] + >>> summarize_list(elem.findall("*//*")) + ['tag'] + >>> summarize_list(elem.findall("*/tag")) + ['tag'] + >>> summarize_list(elem.findall("*/./tag")) + ['tag'] + >>> summarize_list(elem.findall("./tag")) + ['tag', 'tag'] + >>> summarize_list(elem.findall(".//tag")) + ['tag', 'tag', 'tag'] + >>> summarize_list(elem.findall("././tag")) + ['tag', 'tag'] + >>> summarize_list(ET.ElementTree(elem).findall("/tag")) + ['tag', 'tag'] + >>> summarize_list(ET.ElementTree(elem).findall("./tag")) + ['tag', 'tag'] + >>> elem = ET.XML(SAMPLE_XML_NS) + >>> summarize_list(elem.findall("tag")) + [] + >>> summarize_list(elem.findall("{http://effbot.org/ns}tag")) + ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] + >>> summarize_list(elem.findall(".//{http://effbot.org/ns}tag")) + ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] + """ + +def parseliteral(): + r""" + + >>> from xml.etree import ElementTree as ET + + >>> element = ET.XML("<html><body>text</body></html>") + >>> ET.ElementTree(element).write(sys.stdout) + <html><body>text</body></html> + >>> element = ET.fromstring("<html><body>text</body></html>") + >>> ET.ElementTree(element).write(sys.stdout) + <html><body>text</body></html> + >>> print ET.tostring(element) + <html><body>text</body></html> + >>> print ET.tostring(element, "ascii") + <?xml version='1.0' encoding='ascii'?> + <html><body>text</body></html> + >>> _, ids = ET.XMLID("<html><body>text</body></html>") + >>> len(ids) + 0 + >>> _, ids = ET.XMLID("<html><body id='body'>text</body></html>") + >>> len(ids) + 1 + >>> ids["body"].tag + 'body' + """ + + +def check_encoding(ET, encoding): + """ + >>> from xml.etree import ElementTree as ET + + >>> check_encoding(ET, "ascii") + >>> check_encoding(ET, "us-ascii") + >>> check_encoding(ET, "iso-8859-1") + >>> check_encoding(ET, "iso-8859-15") + >>> check_encoding(ET, "cp437") + >>> check_encoding(ET, "mac-roman") + """ + ET.XML("<?xml version='1.0' encoding='%s'?><xml />" % encoding) + + +# +# xinclude tests (samples from appendix C of the xinclude specification) + +XINCLUDE = {} + +XINCLUDE["C1.xml"] = """\ +<?xml version='1.0'?> +<document xmlns:xi="http://www.w3.org/2001/XInclude"> + <p>120 Mz is adequate for an average home user.</p> + <xi:include href="disclaimer.xml"/> +</document> +""" + +XINCLUDE["disclaimer.xml"] = """\ +<?xml version='1.0'?> +<disclaimer> + <p>The opinions represented herein represent those of the individual + and should not be interpreted as official policy endorsed by this + organization.</p> +</disclaimer> +""" + +XINCLUDE["C2.xml"] = """\ +<?xml version='1.0'?> +<document xmlns:xi="http://www.w3.org/2001/XInclude"> + <p>This document has been accessed + <xi:include href="count.txt" parse="text"/> times.</p> +</document> +""" + +XINCLUDE["count.txt"] = "324387" + +XINCLUDE["C3.xml"] = """\ +<?xml version='1.0'?> +<document xmlns:xi="http://www.w3.org/2001/XInclude"> + <p>The following is the source of the "data.xml" resource:</p> + <example><xi:include href="data.xml" parse="text"/></example> +</document> +""" + +XINCLUDE["data.xml"] = """\ +<?xml version='1.0'?> +<data> + <item><![CDATA[Brooks & Shields]]></item> +</data> +""" + +XINCLUDE["C5.xml"] = """\ +<?xml version='1.0'?> +<div xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="example.txt" parse="text"> + <xi:fallback> + <xi:include href="fallback-example.txt" parse="text"> + <xi:fallback><a href="mailto:bo...@ex...">Report error</a></xi:fallback> + </xi:include> + </xi:fallback> + </xi:include> +</div> +""" + +XINCLUDE["default.xml"] = """\ +<?xml version='1.0'?> +<document xmlns:xi="http://www.w3.org/2001/XInclude"> + <p>Example.</p> + <xi:include href="samples/simple.xml"/> +</document> +""" + +def xinclude_loader(href, parse="xml", encoding=None): + try: + data = XINCLUDE[href] + except KeyError: + raise IOError("resource not found") + if parse == "xml": + from xml.etree.ElementTree import XML + return XML(data) + return data + +def xinclude(): + r""" + Basic inclusion example (XInclude C.1) + + >>> from xml.etree import ElementTree as ET + >>> from xml.etree import ElementInclude + + >>> document = xinclude_loader("C1.xml") + >>> ElementInclude.include(document, xinclude_loader) + >>> print serialize(ET, document) # C1 + <document> + <p>120 Mz is adequate for an average home user.</p> + <disclaimer> + <p>The opinions represented herein represent those of the individual + and should not be interpreted as official policy endorsed by this + organization.</p> + </disclaimer> + </document> + + Textual inclusion example (XInclude C.2) + + >>> document = xinclude_loader("C2.xml") + >>> ElementInclude.include(document, xinclude_loader) + >>> print serialize(ET, document) # C2 + <document> + <p>This document has been accessed + 324387 times.</p> + </document> + + Textual inclusion of XML example (XInclude C.3) + + >>> document = xinclude_loader("C3.xml") + >>> ElementInclude.include(document, xinclude_loader) + >>> print serialize(ET, document) # C3 + <document> + <p>The following is the source of the "data.xml" resource:</p> + <example><?xml version='1.0'?> + <data> + <item><![CDATA[Brooks & Shields]]></item> + </data> + </example> + </document> + + Fallback example (XInclude C.5) + Note! Fallback support is not yet implemented + + >>> document = xinclude_loader("C5.xml") + >>> ElementInclude.include(document, xinclude_loader) + Traceback (most recent call last): + IOError: resource not found + >>> # print serialize(ET, document) # C5 + + """ + +def test_main(): + from test import test_xml_etree + test_support.run_doctest(test_xml_etree, verbosity=True) + +if __name__ == '__main__': + test_main() Copied: branches/jy3k/Lib/test/test_xml_etree_c.py (from rev 5885, trunk/jython/Lib/test/test_xml_etree_c.py) =================================================================== --- branches/jy3k/Lib/test/test_xml_etree_c.py (rev 0) +++ branches/jy3k/Lib/test/test_xml_etree_c.py 2009-01-08 19:48:42 UTC (rev 5886) @@ -0,0 +1,223 @@ +# xml.etree test for cElementTree + +import doctest, sys + +from test import test_support + +from xml.etree import cElementTree as ET + +SAMPLE_XML = """ +<body> + <tag>text</tag> + <tag /> + <section> + <tag>subtext</tag> + </section> +</body> +""" + +SAMPLE_XML_NS = """ +<body xmlns="http://effbot.org/ns"> + <tag>text</tag> + <tag /> + <section> + <tag>subtext</tag> + </section> +</body> +""" + +def sanity(): + """ + Import sanity. + + >>> from xml.etree import cElementTree + """ + +def check_method(method): + if not callable(method): + print method, "not callable" + +def serialize(ET, elem, encoding=None): + import StringIO + file = StringIO.StringIO() + tree = ET.ElementTree(elem) + if encoding: + tree.write(file, encoding) + else: + tree.write(file) + return file.getvalue() + +def summarize(elem): + return elem.tag + +def summarize_list(seq): + return map(summarize, seq) + +def interface(): + """ + Test element tree interface. + + >>> element = ET.Element("tag", key="value") + >>> tree = ET.ElementTree(element) + + Make sure all standard element methods exist. + + >>> check_method(element.append) + >>> check_method(element.insert) + >>> check_method(element.remove) + >>> check_method(element.getchildren) + >>> check_method(element.find) + >>> check_method(element.findall) + >>> check_method(element.findtext) + >>> check_method(element.clear) + >>> check_method(element.get) + >>> check_method(element.set) + >>> check_method(element.keys) + >>> check_method(element.items) + >>> check_method(element.getiterator) + + Basic method sanity checks. + + >>> serialize(ET, element) # 1 + '<tag key="value" />' + >>> subelement = ET.Element("subtag") + >>> element.append(subelement) + >>> serialize(ET, element) # 2 + '<tag key="value"><subtag /></tag>' + >>> element.insert(0, subelement) + >>> serialize(ET, element) # 3 + '<tag key="value"><subtag /><subtag /></tag>' + >>> element.remove(subelement) + >>> serialize(ET, element) # 4 + '<tag key="value"><subtag /></tag>' + >>> element.remove(subelement) + >>> serialize(ET, element) # 5 + '<tag key="value" />' + >>> element.remove(subelement) + Traceback (most recent call last): + ValueError: list.remove(x): x not in list + >>> serialize(ET, element) # 6 + '<tag key="value" />' + """ + +def find(): + """ + Test find methods (including xpath syntax). + + >>> elem = ET.XML(SAMPLE_XML) + >>> elem.find("tag").tag + 'tag' + >>> ET.ElementTree(elem).find("tag").tag + 'tag' + >>> elem.find("section/tag").tag + 'tag' + >>> ET.ElementTree(elem).find("section/tag").tag + 'tag' + >>> elem.findtext("tag") + 'text' + >>> elem.findtext("tog") + >>> elem.findtext("tog", "default") + 'default' + >>> ET.ElementTree(elem).findtext("tag") + 'text' + >>> elem.findtext("section/tag") + 'subtext' + >>> ET.ElementTree(elem).findtext("section/tag") + 'subtext' + >>> summarize_list(elem.findall("tag")) + ['tag', 'tag'] + >>> summarize_list(elem.findall("*")) + ['tag', 'tag', 'section'] + >>> summarize_list(elem.findall(".//tag")) + ['tag', 'tag', 'tag'] + >>> summarize_list(elem.findall("section/tag")) + ['tag'] + >>> summarize_list(elem.findall("section//tag")) + ['tag'] + >>> summarize_list(elem.findall("section/*")) + ['tag'] + >>> summarize_list(elem.findall("section//*")) + ['tag'] + >>> summarize_list(elem.findall("section/.//*")) + ['tag'] + >>> summarize_list(elem.findall("*/*")) + ['tag'] + >>> summarize_list(elem.findall("*//*")) + ['tag'] + >>> summarize_list(elem.findall("*/tag")) + ['tag'] + >>> summarize_list(elem.findall("*/./tag")) + ['tag'] + >>> summarize_list(elem.findall("./tag")) + ['tag', 'tag'] + >>> summarize_list(elem.findall(".//tag")) + ['tag', 'tag', 'tag'] + >>> summarize_list(elem.findall("././tag")) + ['tag', 'tag'] + >>> summarize_list(ET.ElementTree(elem).findall("/tag")) + ['tag', 'tag'] + >>> summarize_list(ET.ElementTree(elem).findall("./tag")) + ['tag', 'tag'] + >>> elem = ET.XML(SAMPLE_XML_NS) + >>> summarize_list(elem.findall("tag")) + [] + >>> summarize_list(elem.findall("{http://effbot.org/ns}tag")) + ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] + >>> summarize_list(elem.findall(".//{http://effbot.org/ns}tag")) + ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] + """ + +def parseliteral(): + r""" + + >>> element = ET.XML("<html><body>text</body></html>") + >>> ET.ElementTree(element).write(sys.stdout) + <html><body>text</body></html> + >>> element = ET.fromstring("<html><body>text</body></html>") + >>> ET.ElementTree(element).write(sys.stdout) + <html><body>text</body></html> + >>> print ET.tostring(element) + <html><body>text</body></html> + >>> print ET.tostring(element, "ascii") + <?xml version='1.0' encoding='ascii'?> + <html><body>text</body></html> + >>> _, ids = ET.XMLID("<html><body>text</body></html>") + >>> len(ids) + 0 + >>> _, ids = ET.XMLID("<html><body id='body'>text</body></html>") + >>> len(ids) + 1 + >>> ids["body"].tag + 'body' + """ + +def check_encoding(encoding): + """ + >>> check_encoding("ascii") + >>> check_encoding("us-ascii") + >>> check_encoding("iso-8859-1") + >>> check_encoding("iso-8859-15") + >>> check_encoding("cp437") + >>> check_encoding("mac-roman") + """ + ET.XML( + "<?xml version='1.0' encoding='%s'?><xml />" % encoding + ) + +def bug_1534630(): + """ + >>> bob = ET.TreeBuilder() + >>> e = bob.data("data") + >>> e = bob.start("tag", {}) + >>> e = bob.end("tag") + >>> e = bob.close() + >>> serialize(ET, e) + '<tag />' + """ + +def test_main(): + from test import test_xml_etree_c + test_support.run_doctest(test_xml_etree_c, verbosity=True) + +if __name__ == '__main__': + test_main() Modified: branches/jy3k/ast/astview.py =================================================================== --- branches/jy3k/ast/astview.py 2009-01-08 19:36:33 UTC (rev 5885) +++ branches/jy3k/ast/astview.py 2009-01-08 19:48:42 UTC (rev 5886) @@ -10,33 +10,19 @@ """ -import _ast +import ast import sys if sys.platform.startswith('java'): - - get_symbol_key = lambda op: op - def get_class_name(t): result = t.__class__.__name__ - if result in ("expr_contextType", - "boolopType", - "unaryopType", - "cmpopType", - "operatorType"): - result = str(t) - if result == "AugLoad": - result = "Load" - elif result == "AugStore": - result = "Store" - else: - result = result.split(".")[-1] - if result.endswith("Type"): - result = result[:-4] + if result == "AugLoad": + result = "Load" + elif result == "AugStore": + result = "Store" return result else: - get_symbol_key = type get_class_name = lambda node: node.__class__.__name__ get_lines_and_cols = True @@ -48,7 +34,7 @@ result = get_class_name(node) if get_lines_and_cols and hasattr(node, 'lineno') and hasattr(node, 'col_offset'): result = "%s (%s,%s)" % (result, node.lineno, node.col_offset) - yield result#get_class_name(node)#result + yield result try: for field in node._fields: yield tuple(lispify_field(field, getattr(node, field))) @@ -57,13 +43,13 @@ def lispify_field(field, child): yield field - if not hasattr(child, '__iter__'): - children = [child] - else: + if isinstance(child, list): children = child + else: + children = [child] for node in children: - if isinstance(node, _ast.AST): + if isinstance(node, ast.AST): yield lispify_ast(node) else: if isinstance(node, float): @@ -78,10 +64,10 @@ def tree(pyfile): try: - ast = compile(open(pyfile).read(), pyfile, "exec", _ast.PyCF_ONLY_AST) + node = compile(open(pyfile).read(), pyfile, "exec", ast.PyCF_ONLY_AST) except SyntaxError: return "SyntaxError", - return lispify_ast(ast) + return lispify_ast(node) if __name__ == '__main__': import pprint Modified: branches/jy3k/src/org/python/compiler/CodeCompiler.java =================================================================== --- branches/jy3k/src/org/python/compiler/CodeCompiler.java 2009-01-08 19:36:33 UTC (rev 5885) +++ branches/jy3k/src/org/python/compiler/CodeCompiler.java 2009-01-08 19:48:42 UTC (rev 5886) @@ -19,6 +19,7 @@ import org.python.antlr.ast.BinOp; import org.python.antlr.ast.BoolOp; import org.python.antlr.ast.Break; +import org.python.antlr.ast.Bytes; import org.python.antlr.ast.Call; import org.python.antlr.ast.ClassDef; import org.python.antlr.ast.Compare; @@ -2076,12 +2077,15 @@ @Override public Object visitStr(Str node) throws Exception { + PyUnicode s = (PyUnicode)node.getInternalS(); + module.PyUnicode(s.asString()).get(code); + return null; + } + + @Override + public Object visitBytes(Bytes node) throws Exception { PyString s = (PyString)node.getInternalS(); - if (s instanceof PyUnicode) { - module.PyUnicode(s.asString()).get(code); - } else { - module.PyString(s.asString()).get(code); - } + module.PyString(s.asString()).get(code); return null; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 19:36:37
|
Revision: 5885 http://jython.svn.sourceforge.net/jython/?rev=5885&view=rev Author: fwierzbicki Date: 2009-01-08 19:36:33 +0000 (Thu, 08 Jan 2009) Log Message: ----------- _ast -> ast Modified Paths: -------------- trunk/jython/ast/astview.py Modified: trunk/jython/ast/astview.py =================================================================== --- trunk/jython/ast/astview.py 2009-01-08 19:34:31 UTC (rev 5884) +++ trunk/jython/ast/astview.py 2009-01-08 19:36:33 UTC (rev 5885) @@ -10,7 +10,7 @@ """ -import _ast +import ast import sys if sys.platform.startswith('java'): @@ -49,7 +49,7 @@ children = [child] for node in children: - if isinstance(node, _ast.AST): + if isinstance(node, ast.AST): yield lispify_ast(node) else: if isinstance(node, float): @@ -64,10 +64,10 @@ def tree(pyfile): try: - ast = compile(open(pyfile).read(), pyfile, "exec", _ast.PyCF_ONLY_AST) + node = compile(open(pyfile).read(), pyfile, "exec", ast.PyCF_ONLY_AST) except SyntaxError: return "SyntaxError", - return lispify_ast(ast) + return lispify_ast(node) if __name__ == '__main__': import pprint This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 19:34:39
|
Revision: 5884 http://jython.svn.sourceforge.net/jython/?rev=5884&view=rev Author: fwierzbicki Date: 2009-01-08 19:34:31 +0000 (Thu, 08 Jan 2009) Log Message: ----------- improvement to astview.py in light of better ast.py in Jython. Modified Paths: -------------- trunk/jython/ast/astview.py Modified: trunk/jython/ast/astview.py =================================================================== --- trunk/jython/ast/astview.py 2009-01-08 19:22:49 UTC (rev 5883) +++ trunk/jython/ast/astview.py 2009-01-08 19:34:31 UTC (rev 5884) @@ -14,29 +14,15 @@ import sys if sys.platform.startswith('java'): - - get_symbol_key = lambda op: op - def get_class_name(t): result = t.__class__.__name__ - if result in ("expr_contextType", - "boolopType", - "unaryopType", - "cmpopType", - "operatorType"): - result = str(t) - if result == "AugLoad": - result = "Load" - elif result == "AugStore": - result = "Store" - else: - result = result.split(".")[-1] - if result.endswith("Type"): - result = result[:-4] + if result == "AugLoad": + result = "Load" + elif result == "AugStore": + result = "Store" return result else: - get_symbol_key = type get_class_name = lambda node: node.__class__.__name__ get_lines_and_cols = True @@ -48,7 +34,7 @@ result = get_class_name(node) if get_lines_and_cols and hasattr(node, 'lineno') and hasattr(node, 'col_offset'): result = "%s (%s,%s)" % (result, node.lineno, node.col_offset) - yield result#get_class_name(node)#result + yield result try: for field in node._fields: yield tuple(lispify_field(field, getattr(node, field))) @@ -57,10 +43,10 @@ def lispify_field(field, child): yield field - if not hasattr(child, '__iter__'): - children = [child] - else: + if isinstance(child, list): children = child + else: + children = [child] for node in children: if isinstance(node, _ast.AST): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 19:22:54
|
Revision: 5883 http://jython.svn.sourceforge.net/jython/?rev=5883&view=rev Author: fwierzbicki Date: 2009-01-08 19:22:49 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Very initial attempt to support Bytes type in parser. Modified Paths: -------------- branches/jy3k/grammar/Python.g branches/jy3k/src/org/python/antlr/GrammarActions.java branches/jy3k/src/org/python/core/PyUnicode.java Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-08 16:48:06 UTC (rev 5882) +++ branches/jy3k/grammar/Python.g 2009-01-08 19:22:49 UTC (rev 5883) @@ -94,6 +94,7 @@ import org.python.antlr.ast.BoolOp; import org.python.antlr.ast.boolopType; import org.python.antlr.ast.Break; +import org.python.antlr.ast.Bytes; import org.python.antlr.ast.Call; import org.python.antlr.ast.ClassDef; import org.python.antlr.ast.cmpopType; @@ -1243,6 +1244,8 @@ -> ^(COMPLEX<Num>[$COMPLEX, actions.makeComplex($COMPLEX)]) | (S+=STRING)+ -> ^(STRING<Str>[actions.extractStringToken($S), actions.extractStrings($S, encoding)]) + | (B+=BYTES)+ + -> ^(BYTES<Bytes>[actions.extractStringToken($B), actions.extractBytes($B, encoding)]) ; //listmaker: test ( list_for | (',' test)* [','] ) @@ -1720,6 +1723,24 @@ /** Match various string types. Note that greedy=false implies ''' * should make us exit loop not continue. */ +BYTES + : ('b'|'B') + ( '\'\'\'' (options {greedy=false;}:TRIAPOS)* '\'\'\'' + | '"""' (options {greedy=false;}:TRIQUOTE)* '"""' + | '"' (ESC|~('\\'|'\n'|'"'))* '"' + | '\'' (ESC|~('\\'|'\n'|'\''))* '\'' + ) { + if (state.tokenStartLine != input.getLine()) { + state.tokenStartLine = input.getLine(); + state.tokenStartCharPositionInLine = -2; + } + } + ; + + +/** Match various string types. Note that greedy=false implies ''' + * should make us exit loop not continue. + */ STRING : ('r'|'R')? ( '\'\'\'' (options {greedy=false;}:TRIAPOS)* '\'\'\'' @@ -1735,7 +1756,7 @@ ; STRINGPART - : {partial}?=> ('r'|'R')? + : {partial}?=> ('r'|'b'|'R'|'B')? ( '\'\'\'' ~('\'\'\'')* | '"""' ~('"""')* ) Modified: branches/jy3k/src/org/python/antlr/GrammarActions.java =================================================================== --- branches/jy3k/src/org/python/antlr/GrammarActions.java 2009-01-08 16:48:06 UTC (rev 5882) +++ branches/jy3k/src/org/python/antlr/GrammarActions.java 2009-01-08 19:22:49 UTC (rev 5883) @@ -17,6 +17,7 @@ import org.python.antlr.ast.expr_contextType; import org.python.antlr.ast.operatorType; import org.python.antlr.ast.unaryopType; +import org.python.antlr.ast.Bytes; import org.python.antlr.ast.Context; import org.python.antlr.ast.keyword; import org.python.antlr.ast.Attribute; @@ -397,53 +398,67 @@ return Py.newInteger((int) l); } - class StringPair { - private String s; - private boolean unicode; + //FIXME: this is just a guess ATM + PyString extractBytes(List s, String encoding) { + Token last = null; + StringBuffer sb = new StringBuffer(); + Iterator iter = s.iterator(); + while (iter.hasNext()) { + last = (Token)iter.next(); + String sp = extractBytesPart(last, encoding); + sb.append(sp); + } + return new PyString(sb.toString()); + } - StringPair(String s, boolean unicode) { - this.s = s; - this.unicode = unicode; + //FIXME: this is just a guess ATM + String extractBytesPart(Token t, String encoding) { + String string = t.getText(); + char quoteChar = string.charAt(0); + int start = 0; + int end; + quoteChar = string.charAt(start); + boolean raw = false; + if (quoteChar == 'b' || quoteChar == 'B') { + raw = true; + start++; } - String getString() { - return s; + int quotes = 3; + if (string.length() - start == 2) { + quotes = 1; } - - boolean isUnicode() { - return unicode; + if (string.charAt(start) != string.charAt(start+1)) { + quotes = 1; } + + start = quotes + start; + end = string.length() - quotes; + if (encoding != null) { + string = new PyUnicode(string.substring(start, end)).encode(encoding); + } else { + string = string.substring(start, end); + } + return string; } + PyString extractStrings(List s, String encoding) { - boolean ustring = false; Token last = null; StringBuffer sb = new StringBuffer(); Iterator iter = s.iterator(); while (iter.hasNext()) { last = (Token)iter.next(); - StringPair sp = extractString(last, encoding); - if (sp.isUnicode()) { - ustring = true; - } - sb.append(sp.getString()); + String sp = extractString(last, encoding); + sb.append(sp); } - if (ustring) { - return new PyUnicode(sb.toString()); - } - return new PyString(sb.toString()); + return new PyUnicode(sb.toString()); } - StringPair extractString(Token t, String encoding) { + String extractString(Token t, String encoding) { String string = t.getText(); char quoteChar = string.charAt(0); int start = 0; int end; - boolean ustring = false; - - if (quoteChar == 'u' || quoteChar == 'U') { - ustring = true; - start++; - } quoteChar = string.charAt(start); boolean raw = false; if (quoteChar == 'r' || quoteChar == 'R') { @@ -463,22 +478,22 @@ // string is properly decoded according to the source encoding // XXX: No need to re-encode when the encoding is iso-8859-1, but ParserFacade // needs to normalize the encoding name - if (!ustring && encoding != null) { + if (encoding != null) { // str with a specified encoding: first re-encode back out string = new PyUnicode(string.substring(start, end)).encode(encoding); if (!raw) { // Handle escapes in non-raw strs string = PyString.decode_UnicodeEscape(string, 0, string.length(), "strict", - ustring); + false); } } else if (raw) { // Raw str without an encoding or raw unicode: simply passthru string = string.substring(start, end); } else { // Plain unicode: already decoded, just handle escapes - string = PyString.decode_UnicodeEscape(string, start, end, "strict", ustring); + string = PyString.decode_UnicodeEscape(string, start, end, "strict", true); } - return new StringPair(string, ustring); + return string; } Token extractStringToken(List s) { Modified: branches/jy3k/src/org/python/core/PyUnicode.java =================================================================== --- branches/jy3k/src/org/python/core/PyUnicode.java 2009-01-08 16:48:06 UTC (rev 5882) +++ branches/jy3k/src/org/python/core/PyUnicode.java 2009-01-08 19:22:49 UTC (rev 5883) @@ -246,7 +246,7 @@ @ExposedMethod(doc = BuiltinDocs.unicode___repr___doc) final PyString unicode___repr__() { - return new PyString("u" + encode_UnicodeEscape(string, true)); + return new PyString(encode_UnicodeEscape(string, true)); } @ExposedMethod(doc = BuiltinDocs.unicode___getitem___doc) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 16:48:10
|
Revision: 5882 http://jython.svn.sourceforge.net/jython/?rev=5882&view=rev Author: fwierzbicki Date: 2009-01-08 16:48:06 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Add binary literal. Modified Paths: -------------- branches/jy3k/grammar/Python.g branches/jy3k/src/org/python/antlr/GrammarActions.java Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-08 16:38:16 UTC (rev 5881) +++ branches/jy3k/grammar/Python.g 2009-01-08 16:48:06 UTC (rev 5882) @@ -1699,7 +1699,10 @@ '0' ('x' | 'X') ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' )+ | // Octal '0' ('o' | 'O') ( '0' .. '7' )* - | '0'..'9' DIGITS* + | // Binary + '0' ('b' | 'B') ( '0' .. '1' )* + | // Decimal + '0'..'9' DIGITS* ; COMPLEX Modified: branches/jy3k/src/org/python/antlr/GrammarActions.java =================================================================== --- branches/jy3k/src/org/python/antlr/GrammarActions.java 2009-01-08 16:38:16 UTC (rev 5881) +++ branches/jy3k/src/org/python/antlr/GrammarActions.java 2009-01-08 16:48:06 UTC (rev 5882) @@ -374,6 +374,9 @@ } else if (s.startsWith("0o") || s.startsWith("0O")) { radix = 8; s = s.substring(2, s.length()); + } else if (s.startsWith("0b") || s.startsWith("0B")) { + radix = 2; + s = s.substring(2, s.length()); } if (s.endsWith("L") || s.endsWith("l")) { s = s.substring(0, s.length()-1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 16:38:20
|
Revision: 5881 http://jython.svn.sourceforge.net/jython/?rev=5881&view=rev Author: fwierzbicki Date: 2009-01-08 16:38:16 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Prune BACKQUOTE and <> from grammar. Modified Paths: -------------- branches/jy3k/grammar/Python.g Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-08 16:12:44 UTC (rev 5880) +++ branches/jy3k/grammar/Python.g 2009-01-08 16:38:16 UTC (rev 5881) @@ -1008,14 +1008,13 @@ ) ; -//comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not' +//comp_op: '<'|'>'|'=='|'>='|'<='|'!='|'in'|'not' 'in'|'is'|'is' 'not' comp_op returns [cmpopType op] : LESS {$op = cmpopType.Lt;} | GREATER {$op = cmpopType.Gt;} | EQUAL {$op = cmpopType.Eq;} | GREATEREQUAL {$op = cmpopType.GtE;} | LESSEQUAL {$op = cmpopType.LtE;} - | ALT_NOTEQUAL {$op = cmpopType.NotEq;} | NOTEQUAL {$op = cmpopType.NotEq;} | IN {$op = cmpopType.In;} | NOT IN {$op = cmpopType.NotIn;} @@ -1627,8 +1626,6 @@ PERCENT : '%' ; -BACKQUOTE : '`' ; - LCURLY : '{' {implicitLineJoiningLevel++;} ; RCURLY : '}' {implicitLineJoiningLevel--;} ; @@ -1641,8 +1638,6 @@ NOTEQUAL : '!=' ; -ALT_NOTEQUAL: '<>' ; - LESSEQUAL : '<=' ; LEFTSHIFT : '<<' ; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 16:12:57
|
Revision: 5880 http://jython.svn.sourceforge.net/jython/?rev=5880&view=rev Author: fwierzbicki Date: 2009-01-08 16:12:44 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Added nonlocal, and support for the -> annotation. Modified Paths: -------------- branches/jy3k/grammar/Python.g branches/jy3k/src/org/python/antlr/GrammarActions.java Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-08 15:52:56 UTC (rev 5879) +++ branches/jy3k/grammar/Python.g 2009-01-08 16:12:44 UTC (rev 5880) @@ -377,7 +377,6 @@ | DELETE | ELIF | EXCEPT - | EXEC | FINALLY | FROM | FOR @@ -443,7 +442,7 @@ if ($decorators.start != null) { t = $decorators.start; } - stype = actions.makeFuncdef(t, $NAME, $parameters.args, $suite.stypes, $decorators.etypes); + stype = actions.makeFuncdef(t, $NAME, $parameters.args, $suite.stypes, $decorators.etypes, actions.castExpr($test.tree)); } ; @@ -1584,6 +1583,7 @@ IN : 'in' ; IS : 'is' ; LAMBDA : 'lambda' ; +NONLOCAL : 'nonlocal' ; ORELSE : 'else' ; PASS : 'pass' ; RAISE : 'raise' ; Modified: branches/jy3k/src/org/python/antlr/GrammarActions.java =================================================================== --- branches/jy3k/src/org/python/antlr/GrammarActions.java 2009-01-08 15:52:56 UTC (rev 5879) +++ branches/jy3k/src/org/python/antlr/GrammarActions.java 2009-01-08 16:12:44 UTC (rev 5880) @@ -263,7 +263,7 @@ return new TryFinally(t, b, f); } - stmt makeFuncdef(Token t, Token nameToken, arguments args, List funcStatements, List decorators) { + stmt makeFuncdef(Token t, Token nameToken, arguments args, List funcStatements, List decorators, expr returnType) { if (nameToken == null) { return errorHandler.errorStmt(new PythonTree(t)); } @@ -276,7 +276,7 @@ } List<stmt> s = castStmts(funcStatements); List<expr> d = castExprs(decorators); - return new FunctionDef(t, nameToken.getText(), a, s, d, null); + return new FunctionDef(t, nameToken.getText(), a, s, d, returnType); } List<expr> makeAssignTargets(expr lhs, List rhs) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 15:53:03
|
Revision: 5879 http://jython.svn.sourceforge.net/jython/?rev=5879&view=rev Author: fwierzbicki Date: 2009-01-08 15:52:56 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Remove support for 'l'/'L' at the end of INT and 'u'/'U' at the beginning of STRING Modified Paths: -------------- branches/jy3k/grammar/Python.g Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-08 15:45:27 UTC (rev 5878) +++ branches/jy3k/grammar/Python.g 2009-01-08 15:52:56 UTC (rev 5879) @@ -1239,8 +1239,6 @@ -> ^(NAME<Name>[$NAME, $NAME.text, $expr::ctype]) | INT -> ^(INT<Num>[$INT, actions.makeInt($INT)]) - | LONGINT - -> ^(LONGINT<Num>[$LONGINT, actions.makeInt($LONGINT)]) | FLOAT -> ^(FLOAT<Num>[$FLOAT, actions.makeFloat($FLOAT)]) | COMPLEX @@ -1697,10 +1695,6 @@ | DIGITS ('.' (DIGITS (Exponent)?)? | Exponent) ; -LONGINT - : INT ('l'|'L') - ; - fragment Exponent : ('e' | 'E') ( '+' | '-' )? DIGITS @@ -1729,7 +1723,7 @@ * should make us exit loop not continue. */ STRING - : ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? + : ('r'|'R')? ( '\'\'\'' (options {greedy=false;}:TRIAPOS)* '\'\'\'' | '"""' (options {greedy=false;}:TRIQUOTE)* '"""' | '"' (ESC|~('\\'|'\n'|'"'))* '"' @@ -1743,7 +1737,7 @@ ; STRINGPART - : {partial}?=> ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? + : {partial}?=> ('r'|'R')? ( '\'\'\'' ~('\'\'\'')* | '"""' ~('"""')* ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 15:45:34
|
Revision: 5878 http://jython.svn.sourceforge.net/jython/?rev=5878&view=rev Author: fwierzbicki Date: 2009-01-08 15:45:27 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Better arg parsing. Modified Paths: -------------- branches/jy3k/grammar/Python.g Modified: branches/jy3k/grammar/Python.g =================================================================== --- branches/jy3k/grammar/Python.g 2009-01-08 07:40:01 UTC (rev 5877) +++ branches/jy3k/grammar/Python.g 2009-01-08 15:45:27 UTC (rev 5878) @@ -458,13 +458,13 @@ ; //not in CPython's Grammar file -tdefparameter[List defaults] returns [arg etype] +tdefparameter[List defaults] returns [arg atype] @after { - $tdefparameter.tree = $etype; + $tdefparameter.tree = $atype; } : tfpdef[expr_contextType.Param] (ASSIGN test[expr_contextType.Load])? { - $etype = actions.castArg($tfpdef.tree); + $atype = actions.castArg($tfpdef.tree); if ($ASSIGN != null) { defaults.add($test.tree); } else if (!defaults.isEmpty()) { @@ -501,18 +501,18 @@ //tfpdef: NAME [':' test] tfpdef[expr_contextType ctype] - : NAME (COLON test[ctype])? - -> ^(NAME<arg>[$NAME, $NAME.text, null]) + : NAME (COLON test[expr_contextType.Load])? + -> ^(NAME<arg>[$NAME, $NAME.text, actions.castExpr($test.tree)]) ; //not in CPython's Grammar file -vdefparameter[List defaults] returns [expr etype] +vdefparameter[List defaults] returns [arg atype] @after { - $vdefparameter.tree = $etype; + $vdefparameter.tree = $atype; } : vfpdef[expr_contextType.Param] (ASSIGN test[expr_contextType.Load])? { - $etype = actions.castExpr($vfpdef.tree); + $atype = actions.castArg($vfpdef.tree); if ($ASSIGN != null) { defaults.add($test.tree); } else if (!defaults.isEmpty()) { @@ -549,11 +549,8 @@ //vfpdef: NAME vfpdef[expr_contextType ctype] -@after { - actions.checkAssign(actions.castExpr($vfpdef.tree)); -} : NAME - -> ^(NAME<Name>[$NAME, $NAME.text, ctype]) + -> ^(NAME<arg>[$NAME, $NAME.text, null]) ; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-01-08 07:40:06
|
Revision: 5877 http://jython.svn.sourceforge.net/jython/?rev=5877&view=rev Author: pjenvey Date: 2009-01-08 07:40:01 +0000 (Thu, 08 Jan 2009) Log Message: ----------- from: http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_xml_etree.py@50943 http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_xml_etree_c.py@51322 Added Paths: ----------- trunk/jython/Lib/test/test_xml_etree.py trunk/jython/Lib/test/test_xml_etree_c.py Added: trunk/jython/Lib/test/test_xml_etree.py =================================================================== --- trunk/jython/Lib/test/test_xml_etree.py (rev 0) +++ trunk/jython/Lib/test/test_xml_etree.py 2009-01-08 07:40:01 UTC (rev 5877) @@ -0,0 +1,354 @@ +# xml.etree test. This file contains enough tests to make sure that +# all included components work as they should. For a more extensive +# test suite, see the selftest script in the ElementTree distribution. + +import doctest, sys + +from test import test_support + +SAMPLE_XML = """ +<body> + <tag>text</tag> + <tag /> + <section> + <tag>subtext</tag> + </section> +</body> +""" + +SAMPLE_XML_NS = """ +<body xmlns="http://effbot.org/ns"> + <tag>text</tag> + <tag /> + <section> + <tag>subtext</tag> + </section> +</body> +""" + +def sanity(): + """ + Import sanity. + + >>> from xml.etree import ElementTree + >>> from xml.etree import ElementInclude + >>> from xml.etree import ElementPath + """ + +def check_method(method): + if not callable(method): + print method, "not callable" + +def serialize(ET, elem, encoding=None): + import StringIO + file = StringIO.StringIO() + tree = ET.ElementTree(elem) + if encoding: + tree.write(file, encoding) + else: + tree.write(file) + return file.getvalue() + +def summarize(elem): + return elem.tag + +def summarize_list(seq): + return map(summarize, seq) + +def interface(): + """ + Test element tree interface. + + >>> from xml.etree import ElementTree as ET + + >>> element = ET.Element("tag", key="value") + >>> tree = ET.ElementTree(element) + + Make sure all standard element methods exist. + + >>> check_method(element.append) + >>> check_method(element.insert) + >>> check_method(element.remove) + >>> check_method(element.getchildren) + >>> check_method(element.find) + >>> check_method(element.findall) + >>> check_method(element.findtext) + >>> check_method(element.clear) + >>> check_method(element.get) + >>> check_method(element.set) + >>> check_method(element.keys) + >>> check_method(element.items) + >>> check_method(element.getiterator) + + Basic method sanity checks. + + >>> serialize(ET, element) # 1 + '<tag key="value" />' + >>> subelement = ET.Element("subtag") + >>> element.append(subelement) + >>> serialize(ET, element) # 2 + '<tag key="value"><subtag /></tag>' + >>> element.insert(0, subelement) + >>> serialize(ET, element) # 3 + '<tag key="value"><subtag /><subtag /></tag>' + >>> element.remove(subelement) + >>> serialize(ET, element) # 4 + '<tag key="value"><subtag /></tag>' + >>> element.remove(subelement) + >>> serialize(ET, element) # 5 + '<tag key="value" />' + >>> element.remove(subelement) + Traceback (most recent call last): + ValueError: list.remove(x): x not in list + >>> serialize(ET, element) # 6 + '<tag key="value" />' + """ + +def find(): + """ + Test find methods (including xpath syntax). + + >>> from xml.etree import ElementTree as ET + + >>> elem = ET.XML(SAMPLE_XML) + >>> elem.find("tag").tag + 'tag' + >>> ET.ElementTree(elem).find("tag").tag + 'tag' + >>> elem.find("section/tag").tag + 'tag' + >>> ET.ElementTree(elem).find("section/tag").tag + 'tag' + >>> elem.findtext("tag") + 'text' + >>> elem.findtext("tog") + >>> elem.findtext("tog", "default") + 'default' + >>> ET.ElementTree(elem).findtext("tag") + 'text' + >>> elem.findtext("section/tag") + 'subtext' + >>> ET.ElementTree(elem).findtext("section/tag") + 'subtext' + >>> summarize_list(elem.findall("tag")) + ['tag', 'tag'] + >>> summarize_list(elem.findall("*")) + ['tag', 'tag', 'section'] + >>> summarize_list(elem.findall(".//tag")) + ['tag', 'tag', 'tag'] + >>> summarize_list(elem.findall("section/tag")) + ['tag'] + >>> summarize_list(elem.findall("section//tag")) + ['tag'] + >>> summarize_list(elem.findall("section/*")) + ['tag'] + >>> summarize_list(elem.findall("section//*")) + ['tag'] + >>> summarize_list(elem.findall("section/.//*")) + ['tag'] + >>> summarize_list(elem.findall("*/*")) + ['tag'] + >>> summarize_list(elem.findall("*//*")) + ['tag'] + >>> summarize_list(elem.findall("*/tag")) + ['tag'] + >>> summarize_list(elem.findall("*/./tag")) + ['tag'] + >>> summarize_list(elem.findall("./tag")) + ['tag', 'tag'] + >>> summarize_list(elem.findall(".//tag")) + ['tag', 'tag', 'tag'] + >>> summarize_list(elem.findall("././tag")) + ['tag', 'tag'] + >>> summarize_list(ET.ElementTree(elem).findall("/tag")) + ['tag', 'tag'] + >>> summarize_list(ET.ElementTree(elem).findall("./tag")) + ['tag', 'tag'] + >>> elem = ET.XML(SAMPLE_XML_NS) + >>> summarize_list(elem.findall("tag")) + [] + >>> summarize_list(elem.findall("{http://effbot.org/ns}tag")) + ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] + >>> summarize_list(elem.findall(".//{http://effbot.org/ns}tag")) + ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] + """ + +def parseliteral(): + r""" + + >>> from xml.etree import ElementTree as ET + + >>> element = ET.XML("<html><body>text</body></html>") + >>> ET.ElementTree(element).write(sys.stdout) + <html><body>text</body></html> + >>> element = ET.fromstring("<html><body>text</body></html>") + >>> ET.ElementTree(element).write(sys.stdout) + <html><body>text</body></html> + >>> print ET.tostring(element) + <html><body>text</body></html> + >>> print ET.tostring(element, "ascii") + <?xml version='1.0' encoding='ascii'?> + <html><body>text</body></html> + >>> _, ids = ET.XMLID("<html><body>text</body></html>") + >>> len(ids) + 0 + >>> _, ids = ET.XMLID("<html><body id='body'>text</body></html>") + >>> len(ids) + 1 + >>> ids["body"].tag + 'body' + """ + + +def check_encoding(ET, encoding): + """ + >>> from xml.etree import ElementTree as ET + + >>> check_encoding(ET, "ascii") + >>> check_encoding(ET, "us-ascii") + >>> check_encoding(ET, "iso-8859-1") + >>> check_encoding(ET, "iso-8859-15") + >>> check_encoding(ET, "cp437") + >>> check_encoding(ET, "mac-roman") + """ + ET.XML("<?xml version='1.0' encoding='%s'?><xml />" % encoding) + + +# +# xinclude tests (samples from appendix C of the xinclude specification) + +XINCLUDE = {} + +XINCLUDE["C1.xml"] = """\ +<?xml version='1.0'?> +<document xmlns:xi="http://www.w3.org/2001/XInclude"> + <p>120 Mz is adequate for an average home user.</p> + <xi:include href="disclaimer.xml"/> +</document> +""" + +XINCLUDE["disclaimer.xml"] = """\ +<?xml version='1.0'?> +<disclaimer> + <p>The opinions represented herein represent those of the individual + and should not be interpreted as official policy endorsed by this + organization.</p> +</disclaimer> +""" + +XINCLUDE["C2.xml"] = """\ +<?xml version='1.0'?> +<document xmlns:xi="http://www.w3.org/2001/XInclude"> + <p>This document has been accessed + <xi:include href="count.txt" parse="text"/> times.</p> +</document> +""" + +XINCLUDE["count.txt"] = "324387" + +XINCLUDE["C3.xml"] = """\ +<?xml version='1.0'?> +<document xmlns:xi="http://www.w3.org/2001/XInclude"> + <p>The following is the source of the "data.xml" resource:</p> + <example><xi:include href="data.xml" parse="text"/></example> +</document> +""" + +XINCLUDE["data.xml"] = """\ +<?xml version='1.0'?> +<data> + <item><![CDATA[Brooks & Shields]]></item> +</data> +""" + +XINCLUDE["C5.xml"] = """\ +<?xml version='1.0'?> +<div xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="example.txt" parse="text"> + <xi:fallback> + <xi:include href="fallback-example.txt" parse="text"> + <xi:fallback><a href="mailto:bo...@ex...">Report error</a></xi:fallback> + </xi:include> + </xi:fallback> + </xi:include> +</div> +""" + +XINCLUDE["default.xml"] = """\ +<?xml version='1.0'?> +<document xmlns:xi="http://www.w3.org/2001/XInclude"> + <p>Example.</p> + <xi:include href="samples/simple.xml"/> +</document> +""" + +def xinclude_loader(href, parse="xml", encoding=None): + try: + data = XINCLUDE[href] + except KeyError: + raise IOError("resource not found") + if parse == "xml": + from xml.etree.ElementTree import XML + return XML(data) + return data + +def xinclude(): + r""" + Basic inclusion example (XInclude C.1) + + >>> from xml.etree import ElementTree as ET + >>> from xml.etree import ElementInclude + + >>> document = xinclude_loader("C1.xml") + >>> ElementInclude.include(document, xinclude_loader) + >>> print serialize(ET, document) # C1 + <document> + <p>120 Mz is adequate for an average home user.</p> + <disclaimer> + <p>The opinions represented herein represent those of the individual + and should not be interpreted as official policy endorsed by this + organization.</p> + </disclaimer> + </document> + + Textual inclusion example (XInclude C.2) + + >>> document = xinclude_loader("C2.xml") + >>> ElementInclude.include(document, xinclude_loader) + >>> print serialize(ET, document) # C2 + <document> + <p>This document has been accessed + 324387 times.</p> + </document> + + Textual inclusion of XML example (XInclude C.3) + + >>> document = xinclude_loader("C3.xml") + >>> ElementInclude.include(document, xinclude_loader) + >>> print serialize(ET, document) # C3 + <document> + <p>The following is the source of the "data.xml" resource:</p> + <example><?xml version='1.0'?> + <data> + <item><![CDATA[Brooks & Shields]]></item> + </data> + </example> + </document> + + Fallback example (XInclude C.5) + Note! Fallback support is not yet implemented + + >>> document = xinclude_loader("C5.xml") + >>> ElementInclude.include(document, xinclude_loader) + Traceback (most recent call last): + IOError: resource not found + >>> # print serialize(ET, document) # C5 + + """ + +def test_main(): + from test import test_xml_etree + test_support.run_doctest(test_xml_etree, verbosity=True) + +if __name__ == '__main__': + test_main() Added: trunk/jython/Lib/test/test_xml_etree_c.py =================================================================== --- trunk/jython/Lib/test/test_xml_etree_c.py (rev 0) +++ trunk/jython/Lib/test/test_xml_etree_c.py 2009-01-08 07:40:01 UTC (rev 5877) @@ -0,0 +1,223 @@ +# xml.etree test for cElementTree + +import doctest, sys + +from test import test_support + +from xml.etree import cElementTree as ET + +SAMPLE_XML = """ +<body> + <tag>text</tag> + <tag /> + <section> + <tag>subtext</tag> + </section> +</body> +""" + +SAMPLE_XML_NS = """ +<body xmlns="http://effbot.org/ns"> + <tag>text</tag> + <tag /> + <section> + <tag>subtext</tag> + </section> +</body> +""" + +def sanity(): + """ + Import sanity. + + >>> from xml.etree import cElementTree + """ + +def check_method(method): + if not callable(method): + print method, "not callable" + +def serialize(ET, elem, encoding=None): + import StringIO + file = StringIO.StringIO() + tree = ET.ElementTree(elem) + if encoding: + tree.write(file, encoding) + else: + tree.write(file) + return file.getvalue() + +def summarize(elem): + return elem.tag + +def summarize_list(seq): + return map(summarize, seq) + +def interface(): + """ + Test element tree interface. + + >>> element = ET.Element("tag", key="value") + >>> tree = ET.ElementTree(element) + + Make sure all standard element methods exist. + + >>> check_method(element.append) + >>> check_method(element.insert) + >>> check_method(element.remove) + >>> check_method(element.getchildren) + >>> check_method(element.find) + >>> check_method(element.findall) + >>> check_method(element.findtext) + >>> check_method(element.clear) + >>> check_method(element.get) + >>> check_method(element.set) + >>> check_method(element.keys) + >>> check_method(element.items) + >>> check_method(element.getiterator) + + Basic method sanity checks. + + >>> serialize(ET, element) # 1 + '<tag key="value" />' + >>> subelement = ET.Element("subtag") + >>> element.append(subelement) + >>> serialize(ET, element) # 2 + '<tag key="value"><subtag /></tag>' + >>> element.insert(0, subelement) + >>> serialize(ET, element) # 3 + '<tag key="value"><subtag /><subtag /></tag>' + >>> element.remove(subelement) + >>> serialize(ET, element) # 4 + '<tag key="value"><subtag /></tag>' + >>> element.remove(subelement) + >>> serialize(ET, element) # 5 + '<tag key="value" />' + >>> element.remove(subelement) + Traceback (most recent call last): + ValueError: list.remove(x): x not in list + >>> serialize(ET, element) # 6 + '<tag key="value" />' + """ + +def find(): + """ + Test find methods (including xpath syntax). + + >>> elem = ET.XML(SAMPLE_XML) + >>> elem.find("tag").tag + 'tag' + >>> ET.ElementTree(elem).find("tag").tag + 'tag' + >>> elem.find("section/tag").tag + 'tag' + >>> ET.ElementTree(elem).find("section/tag").tag + 'tag' + >>> elem.findtext("tag") + 'text' + >>> elem.findtext("tog") + >>> elem.findtext("tog", "default") + 'default' + >>> ET.ElementTree(elem).findtext("tag") + 'text' + >>> elem.findtext("section/tag") + 'subtext' + >>> ET.ElementTree(elem).findtext("section/tag") + 'subtext' + >>> summarize_list(elem.findall("tag")) + ['tag', 'tag'] + >>> summarize_list(elem.findall("*")) + ['tag', 'tag', 'section'] + >>> summarize_list(elem.findall(".//tag")) + ['tag', 'tag', 'tag'] + >>> summarize_list(elem.findall("section/tag")) + ['tag'] + >>> summarize_list(elem.findall("section//tag")) + ['tag'] + >>> summarize_list(elem.findall("section/*")) + ['tag'] + >>> summarize_list(elem.findall("section//*")) + ['tag'] + >>> summarize_list(elem.findall("section/.//*")) + ['tag'] + >>> summarize_list(elem.findall("*/*")) + ['tag'] + >>> summarize_list(elem.findall("*//*")) + ['tag'] + >>> summarize_list(elem.findall("*/tag")) + ['tag'] + >>> summarize_list(elem.findall("*/./tag")) + ['tag'] + >>> summarize_list(elem.findall("./tag")) + ['tag', 'tag'] + >>> summarize_list(elem.findall(".//tag")) + ['tag', 'tag', 'tag'] + >>> summarize_list(elem.findall("././tag")) + ['tag', 'tag'] + >>> summarize_list(ET.ElementTree(elem).findall("/tag")) + ['tag', 'tag'] + >>> summarize_list(ET.ElementTree(elem).findall("./tag")) + ['tag', 'tag'] + >>> elem = ET.XML(SAMPLE_XML_NS) + >>> summarize_list(elem.findall("tag")) + [] + >>> summarize_list(elem.findall("{http://effbot.org/ns}tag")) + ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] + >>> summarize_list(elem.findall(".//{http://effbot.org/ns}tag")) + ['{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag', '{http://effbot.org/ns}tag'] + """ + +def parseliteral(): + r""" + + >>> element = ET.XML("<html><body>text</body></html>") + >>> ET.ElementTree(element).write(sys.stdout) + <html><body>text</body></html> + >>> element = ET.fromstring("<html><body>text</body></html>") + >>> ET.ElementTree(element).write(sys.stdout) + <html><body>text</body></html> + >>> print ET.tostring(element) + <html><body>text</body></html> + >>> print ET.tostring(element, "ascii") + <?xml version='1.0' encoding='ascii'?> + <html><body>text</body></html> + >>> _, ids = ET.XMLID("<html><body>text</body></html>") + >>> len(ids) + 0 + >>> _, ids = ET.XMLID("<html><body id='body'>text</body></html>") + >>> len(ids) + 1 + >>> ids["body"].tag + 'body' + """ + +def check_encoding(encoding): + """ + >>> check_encoding("ascii") + >>> check_encoding("us-ascii") + >>> check_encoding("iso-8859-1") + >>> check_encoding("iso-8859-15") + >>> check_encoding("cp437") + >>> check_encoding("mac-roman") + """ + ET.XML( + "<?xml version='1.0' encoding='%s'?><xml />" % encoding + ) + +def bug_1534630(): + """ + >>> bob = ET.TreeBuilder() + >>> e = bob.data("data") + >>> e = bob.start("tag", {}) + >>> e = bob.end("tag") + >>> e = bob.close() + >>> serialize(ET, e) + '<tag />' + """ + +def test_main(): + from test import test_xml_etree_c + test_support.run_doctest(test_xml_etree_c, verbosity=True) + +if __name__ == '__main__': + test_main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 02:21:22
|
Revision: 5876 http://jython.svn.sourceforge.net/jython/?rev=5876&view=rev Author: fwierzbicki Date: 2009-01-08 02:21:17 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Merged revisions 5875 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r5875 | fwierzbicki | 2009-01-07 21:08:58 -0500 (Wed, 07 Jan 2009) | 4 lines Change to Raise and ExceptHandler so that Python sees the properly named "type" field, but the getters and setters are mangled to getExceptType so PyObject's getType method is not in conflict. ........ Modified Paths: -------------- branches/jy3k/ast/Python.asdl branches/jy3k/ast/asdl_antlr.py branches/jy3k/src/org/python/antlr/ast/ExceptHandler.java branches/jy3k/src/org/python/compiler/CodeCompiler.java Property Changed: ---------------- branches/jy3k/ Property changes on: branches/jy3k ___________________________________________________________________ Modified: svnmerge-integrated - /trunk/jython:1-5872 + /trunk/jython:1-5875 Modified: branches/jy3k/ast/Python.asdl =================================================================== --- branches/jy3k/ast/Python.asdl 2009-01-08 02:08:58 UTC (rev 5875) +++ branches/jy3k/ast/Python.asdl 2009-01-08 02:21:17 UTC (rev 5876) @@ -101,8 +101,7 @@ comprehension = (expr target, expr iter, expr* ifs) -- not sure what to call the first argument for raise and except - -- changed to 'type' to excepttype for Jython - excepthandler = ExceptHandler(expr? excepttype, identifier? name, stmt* body) + excepthandler = ExceptHandler(expr? type, identifier? name, stmt* body) attributes (int lineno, int col_offset) arguments = (arg* args, identifier? vararg, expr? varargannotation, Modified: branches/jy3k/ast/asdl_antlr.py =================================================================== --- branches/jy3k/ast/asdl_antlr.py 2009-01-08 02:08:58 UTC (rev 5875) +++ branches/jy3k/ast/asdl_antlr.py 2009-01-08 02:21:17 UTC (rev 5876) @@ -484,7 +484,7 @@ self.emit('{%s}, %s);' % (fpargs, len(fields)), depth + 2) i = 0 for f in fields: - self.emit("set%s(ap.getPyObject(%s));" % (str(f.name).capitalize(), + self.emit("set%s(ap.getPyObject(%s));" % (self.processFieldName(f.name), str(i)), depth+1) i += 1 if str(name) in ('stmt', 'expr', 'excepthandler'): @@ -506,8 +506,7 @@ fpargs = ", ".join(["PyObject %s" % f.name for f in fields]) self.emit("public %s(%s) {" % (clsname, fpargs), depth) for f in fields: - self.emit("set%s(%s);" % (str(f.name).capitalize(), - f.name), depth+1) + self.emit("set%s(%s);" % (self.processFieldName(f.name), f.name), depth+1) self.emit("}", depth) self.emit("", 0) @@ -539,6 +538,14 @@ self.emit("", 0) + #This is mainly a kludge to turn get/setType -> get/setExceptType because + #getType conflicts with a method on PyObject. + def processFieldName(self, name): + name = str(name).capitalize() + if name == "Type": + name = "ExceptType" + return name + def visitField(self, field, depth): self.emit("private %s;" % self.fieldDef(field), depth) self.emit("public %s getInternal%s() {" % (self.javaType(field), @@ -546,7 +553,7 @@ self.emit("return %s;" % field.name, depth+1) self.emit("}", depth) self.emit('@ExposedGet(name = "%s")' % field.name, depth) - self.emit("public PyObject get%s() {" % (str(field.name).capitalize()), depth) + self.emit("public PyObject get%s() {" % self.processFieldName(field.name), depth) if field.seq: self.emit("return new AstList(%s, AstAdapters.%sAdapter);" % (field.name, field.type), depth+1) else: @@ -567,8 +574,7 @@ #self.emit("return Py.None;", depth+1) self.emit("}", depth) self.emit('@ExposedSet(name = "%s")' % field.name, depth) - self.emit("public void set%s(PyObject %s) {" % (str(field.name).capitalize(), - field.name), depth) + self.emit("public void set%s(PyObject %s) {" % (self.processFieldName(field.name), field.name), depth) if field.seq: #self.emit("this.%s = new %s(" % (field.name, self.javaType(field)), depth+1) self.emit("this.%s = AstAdapters.py2%sList(%s);" % (field.name, str(field.type), field.name), depth+1) Modified: branches/jy3k/src/org/python/antlr/ast/ExceptHandler.java =================================================================== --- branches/jy3k/src/org/python/antlr/ast/ExceptHandler.java 2009-01-08 02:08:58 UTC (rev 5875) +++ branches/jy3k/src/org/python/antlr/ast/ExceptHandler.java 2009-01-08 02:21:17 UTC (rev 5876) @@ -28,17 +28,17 @@ @ExposedType(name = "_ast.ExceptHandler", base = AST.class) public class ExceptHandler extends excepthandler { public static final PyType TYPE = PyType.fromClass(ExceptHandler.class); - private expr excepttype; - public expr getInternalExcepttype() { - return excepttype; + private expr type; + public expr getInternalType() { + return type; } - @ExposedGet(name = "excepttype") - public PyObject getExcepttype() { - return excepttype; + @ExposedGet(name = "type") + public PyObject getExceptType() { + return type; } - @ExposedSet(name = "excepttype") - public void setExcepttype(PyObject excepttype) { - this.excepttype = AstAdapters.py2expr(excepttype); + @ExposedSet(name = "type") + public void setExceptType(PyObject type) { + this.type = AstAdapters.py2expr(type); } private String name; @@ -70,7 +70,7 @@ private final static PyString[] fields = - new PyString[] {new PyString("excepttype"), new PyString("name"), new PyString("body")}; + new PyString[] {new PyString("type"), new PyString("name"), new PyString("body")}; @ExposedGet(name = "_fields") public PyString[] get_fields() { return fields; } @@ -89,8 +89,8 @@ @ExposedMethod public void ExceptHandler___init__(PyObject[] args, String[] keywords) { ArgParser ap = new ArgParser("ExceptHandler", args, keywords, new String[] - {"excepttype", "name", "body", "lineno", "col_offset"}, 3); - setExcepttype(ap.getPyObject(0)); + {"type", "name", "body", "lineno", "col_offset"}, 3); + setExceptType(ap.getPyObject(0)); setName(ap.getPyObject(1)); setBody(ap.getPyObject(2)); int lin = ap.getInt(3, -1); @@ -105,16 +105,16 @@ } - public ExceptHandler(PyObject excepttype, PyObject name, PyObject body) { - setExcepttype(excepttype); + public ExceptHandler(PyObject type, PyObject name, PyObject body) { + setExceptType(type); setName(name); setBody(body); } - public ExceptHandler(Token token, expr excepttype, String name, java.util.List<stmt> body) { + public ExceptHandler(Token token, expr type, String name, java.util.List<stmt> body) { super(token); - this.excepttype = excepttype; - addChild(excepttype); + this.type = type; + addChild(type); this.name = name; this.body = body; if (body == null) { @@ -125,11 +125,11 @@ } } - public ExceptHandler(Integer ttype, Token token, expr excepttype, String name, - java.util.List<stmt> body) { + public ExceptHandler(Integer ttype, Token token, expr type, String name, java.util.List<stmt> + body) { super(ttype, token); - this.excepttype = excepttype; - addChild(excepttype); + this.type = type; + addChild(type); this.name = name; this.body = body; if (body == null) { @@ -140,10 +140,10 @@ } } - public ExceptHandler(PythonTree tree, expr excepttype, String name, java.util.List<stmt> body) { + public ExceptHandler(PythonTree tree, expr type, String name, java.util.List<stmt> body) { super(tree); - this.excepttype = excepttype; - addChild(excepttype); + this.type = type; + addChild(type); this.name = name; this.body = body; if (body == null) { @@ -161,8 +161,8 @@ public String toStringTree() { StringBuffer sb = new StringBuffer("ExceptHandler("); - sb.append("excepttype="); - sb.append(dumpThis(excepttype)); + sb.append("type="); + sb.append(dumpThis(type)); sb.append(","); sb.append("name="); sb.append(dumpThis(name)); @@ -179,8 +179,8 @@ } public void traverse(VisitorIF visitor) throws Exception { - if (excepttype != null) - excepttype.accept(visitor); + if (type != null) + type.accept(visitor); if (body != null) { for (PythonTree t : body) { if (t != null) Modified: branches/jy3k/src/org/python/compiler/CodeCompiler.java =================================================================== --- branches/jy3k/src/org/python/compiler/CodeCompiler.java 2009-01-08 02:08:58 UTC (rev 5875) +++ branches/jy3k/src/org/python/compiler/CodeCompiler.java 2009-01-08 02:21:17 UTC (rev 5876) @@ -1041,10 +1041,10 @@ //setline(name); Label end_of_self = new Label(); - if (handler.getInternalExcepttype() != null) { + if (handler.getInternalType() != null) { code.aload(exc); //get specific exception - visit(handler.getInternalExcepttype()); + visit(handler.getInternalType()); code.invokestatic("org/python/core/Py", "matchException", "(" + $pyExc + $pyObj + ")Z"); code.ifeq(end_of_self); } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 02:09:02
|
Revision: 5875 http://jython.svn.sourceforge.net/jython/?rev=5875&view=rev Author: fwierzbicki Date: 2009-01-08 02:08:58 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Change to Raise and ExceptHandler so that Python sees the properly named "type" field, but the getters and setters are mangled to getExceptType so PyObject's getType method is not in conflict. Modified Paths: -------------- trunk/jython/ast/Python.asdl trunk/jython/ast/asdl_antlr.py trunk/jython/src/org/python/antlr/ast/ExceptHandler.java trunk/jython/src/org/python/antlr/ast/Raise.java trunk/jython/src/org/python/compiler/CodeCompiler.java Modified: trunk/jython/ast/Python.asdl =================================================================== --- trunk/jython/ast/Python.asdl 2009-01-08 00:34:35 UTC (rev 5874) +++ trunk/jython/ast/Python.asdl 2009-01-08 02:08:58 UTC (rev 5875) @@ -28,8 +28,7 @@ | With(expr context_expr, expr? optional_vars, stmt* body) -- 'type' is a bad name - -- changed to 'type' to excepttype for Jython - | Raise(expr? excepttype, expr? inst, expr? tback) + | Raise(expr? type, expr? inst, expr? tback) | TryExcept(stmt* body, excepthandler* handlers, stmt* orelse) | TryFinally(stmt* body, stmt* finalbody) | Assert(expr test, expr? msg) @@ -99,8 +98,7 @@ comprehension = (expr target, expr iter, expr* ifs) -- not sure what to call the first argument for raise and except - -- changed to 'type' to excepttype for Jython - excepthandler = ExceptHandler(expr? excepttype, expr? name, stmt* body) + excepthandler = ExceptHandler(expr? type, expr? name, stmt* body) attributes (int lineno, int col_offset) arguments = (expr* args, identifier? vararg, Modified: trunk/jython/ast/asdl_antlr.py =================================================================== --- trunk/jython/ast/asdl_antlr.py 2009-01-08 00:34:35 UTC (rev 5874) +++ trunk/jython/ast/asdl_antlr.py 2009-01-08 02:08:58 UTC (rev 5875) @@ -484,7 +484,7 @@ self.emit('{%s}, %s);' % (fpargs, len(fields)), depth + 2) i = 0 for f in fields: - self.emit("set%s(ap.getPyObject(%s));" % (str(f.name).capitalize(), + self.emit("set%s(ap.getPyObject(%s));" % (self.processFieldName(f.name), str(i)), depth+1) i += 1 if str(name) in ('stmt', 'expr', 'excepthandler'): @@ -506,8 +506,7 @@ fpargs = ", ".join(["PyObject %s" % f.name for f in fields]) self.emit("public %s(%s) {" % (clsname, fpargs), depth) for f in fields: - self.emit("set%s(%s);" % (str(f.name).capitalize(), - f.name), depth+1) + self.emit("set%s(%s);" % (self.processFieldName(f.name), f.name), depth+1) self.emit("}", depth) self.emit("", 0) @@ -539,6 +538,14 @@ self.emit("", 0) + #This is mainly a kludge to turn get/setType -> get/setExceptType because + #getType conflicts with a method on PyObject. + def processFieldName(self, name): + name = str(name).capitalize() + if name == "Type": + name = "ExceptType" + return name + def visitField(self, field, depth): self.emit("private %s;" % self.fieldDef(field), depth) self.emit("public %s getInternal%s() {" % (self.javaType(field), @@ -546,7 +553,7 @@ self.emit("return %s;" % field.name, depth+1) self.emit("}", depth) self.emit('@ExposedGet(name = "%s")' % field.name, depth) - self.emit("public PyObject get%s() {" % (str(field.name).capitalize()), depth) + self.emit("public PyObject get%s() {" % self.processFieldName(field.name), depth) if field.seq: self.emit("return new AstList(%s, AstAdapters.%sAdapter);" % (field.name, field.type), depth+1) else: @@ -567,8 +574,7 @@ #self.emit("return Py.None;", depth+1) self.emit("}", depth) self.emit('@ExposedSet(name = "%s")' % field.name, depth) - self.emit("public void set%s(PyObject %s) {" % (str(field.name).capitalize(), - field.name), depth) + self.emit("public void set%s(PyObject %s) {" % (self.processFieldName(field.name), field.name), depth) if field.seq: #self.emit("this.%s = new %s(" % (field.name, self.javaType(field)), depth+1) self.emit("this.%s = AstAdapters.py2%sList(%s);" % (field.name, str(field.type), field.name), depth+1) Modified: trunk/jython/src/org/python/antlr/ast/ExceptHandler.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/ExceptHandler.java 2009-01-08 00:34:35 UTC (rev 5874) +++ trunk/jython/src/org/python/antlr/ast/ExceptHandler.java 2009-01-08 02:08:58 UTC (rev 5875) @@ -28,17 +28,17 @@ @ExposedType(name = "_ast.ExceptHandler", base = AST.class) public class ExceptHandler extends excepthandler { public static final PyType TYPE = PyType.fromClass(ExceptHandler.class); - private expr excepttype; - public expr getInternalExcepttype() { - return excepttype; + private expr type; + public expr getInternalType() { + return type; } - @ExposedGet(name = "excepttype") - public PyObject getExcepttype() { - return excepttype; + @ExposedGet(name = "type") + public PyObject getExceptType() { + return type; } - @ExposedSet(name = "excepttype") - public void setExcepttype(PyObject excepttype) { - this.excepttype = AstAdapters.py2expr(excepttype); + @ExposedSet(name = "type") + public void setExceptType(PyObject type) { + this.type = AstAdapters.py2expr(type); } private expr name; @@ -69,7 +69,7 @@ private final static PyString[] fields = - new PyString[] {new PyString("excepttype"), new PyString("name"), new PyString("body")}; + new PyString[] {new PyString("type"), new PyString("name"), new PyString("body")}; @ExposedGet(name = "_fields") public PyString[] get_fields() { return fields; } @@ -88,8 +88,8 @@ @ExposedMethod public void ExceptHandler___init__(PyObject[] args, String[] keywords) { ArgParser ap = new ArgParser("ExceptHandler", args, keywords, new String[] - {"excepttype", "name", "body", "lineno", "col_offset"}, 3); - setExcepttype(ap.getPyObject(0)); + {"type", "name", "body", "lineno", "col_offset"}, 3); + setExceptType(ap.getPyObject(0)); setName(ap.getPyObject(1)); setBody(ap.getPyObject(2)); int lin = ap.getInt(3, -1); @@ -104,16 +104,16 @@ } - public ExceptHandler(PyObject excepttype, PyObject name, PyObject body) { - setExcepttype(excepttype); + public ExceptHandler(PyObject type, PyObject name, PyObject body) { + setExceptType(type); setName(name); setBody(body); } - public ExceptHandler(Token token, expr excepttype, expr name, java.util.List<stmt> body) { + public ExceptHandler(Token token, expr type, expr name, java.util.List<stmt> body) { super(token); - this.excepttype = excepttype; - addChild(excepttype); + this.type = type; + addChild(type); this.name = name; addChild(name); this.body = body; @@ -125,11 +125,11 @@ } } - public ExceptHandler(Integer ttype, Token token, expr excepttype, expr name, - java.util.List<stmt> body) { + public ExceptHandler(Integer ttype, Token token, expr type, expr name, java.util.List<stmt> + body) { super(ttype, token); - this.excepttype = excepttype; - addChild(excepttype); + this.type = type; + addChild(type); this.name = name; addChild(name); this.body = body; @@ -141,10 +141,10 @@ } } - public ExceptHandler(PythonTree tree, expr excepttype, expr name, java.util.List<stmt> body) { + public ExceptHandler(PythonTree tree, expr type, expr name, java.util.List<stmt> body) { super(tree); - this.excepttype = excepttype; - addChild(excepttype); + this.type = type; + addChild(type); this.name = name; addChild(name); this.body = body; @@ -163,8 +163,8 @@ public String toStringTree() { StringBuffer sb = new StringBuffer("ExceptHandler("); - sb.append("excepttype="); - sb.append(dumpThis(excepttype)); + sb.append("type="); + sb.append(dumpThis(type)); sb.append(","); sb.append("name="); sb.append(dumpThis(name)); @@ -181,8 +181,8 @@ } public void traverse(VisitorIF visitor) throws Exception { - if (excepttype != null) - excepttype.accept(visitor); + if (type != null) + type.accept(visitor); if (name != null) name.accept(visitor); if (body != null) { Modified: trunk/jython/src/org/python/antlr/ast/Raise.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/Raise.java 2009-01-08 00:34:35 UTC (rev 5874) +++ trunk/jython/src/org/python/antlr/ast/Raise.java 2009-01-08 02:08:58 UTC (rev 5875) @@ -28,17 +28,17 @@ @ExposedType(name = "_ast.Raise", base = AST.class) public class Raise extends stmt { public static final PyType TYPE = PyType.fromClass(Raise.class); - private expr excepttype; - public expr getInternalExcepttype() { - return excepttype; + private expr type; + public expr getInternalType() { + return type; } - @ExposedGet(name = "excepttype") - public PyObject getExcepttype() { - return excepttype; + @ExposedGet(name = "type") + public PyObject getExceptType() { + return type; } - @ExposedSet(name = "excepttype") - public void setExcepttype(PyObject excepttype) { - this.excepttype = AstAdapters.py2expr(excepttype); + @ExposedSet(name = "type") + public void setExceptType(PyObject type) { + this.type = AstAdapters.py2expr(type); } private expr inst; @@ -69,7 +69,7 @@ private final static PyString[] fields = - new PyString[] {new PyString("excepttype"), new PyString("inst"), new PyString("tback")}; + new PyString[] {new PyString("type"), new PyString("inst"), new PyString("tback")}; @ExposedGet(name = "_fields") public PyString[] get_fields() { return fields; } @@ -88,8 +88,8 @@ @ExposedMethod public void Raise___init__(PyObject[] args, String[] keywords) { ArgParser ap = new ArgParser("Raise", args, keywords, new String[] - {"excepttype", "inst", "tback", "lineno", "col_offset"}, 3); - setExcepttype(ap.getPyObject(0)); + {"type", "inst", "tback", "lineno", "col_offset"}, 3); + setExceptType(ap.getPyObject(0)); setInst(ap.getPyObject(1)); setTback(ap.getPyObject(2)); int lin = ap.getInt(3, -1); @@ -104,36 +104,36 @@ } - public Raise(PyObject excepttype, PyObject inst, PyObject tback) { - setExcepttype(excepttype); + public Raise(PyObject type, PyObject inst, PyObject tback) { + setExceptType(type); setInst(inst); setTback(tback); } - public Raise(Token token, expr excepttype, expr inst, expr tback) { + public Raise(Token token, expr type, expr inst, expr tback) { super(token); - this.excepttype = excepttype; - addChild(excepttype); + this.type = type; + addChild(type); this.inst = inst; addChild(inst); this.tback = tback; addChild(tback); } - public Raise(Integer ttype, Token token, expr excepttype, expr inst, expr tback) { + public Raise(Integer ttype, Token token, expr type, expr inst, expr tback) { super(ttype, token); - this.excepttype = excepttype; - addChild(excepttype); + this.type = type; + addChild(type); this.inst = inst; addChild(inst); this.tback = tback; addChild(tback); } - public Raise(PythonTree tree, expr excepttype, expr inst, expr tback) { + public Raise(PythonTree tree, expr type, expr inst, expr tback) { super(tree); - this.excepttype = excepttype; - addChild(excepttype); + this.type = type; + addChild(type); this.inst = inst; addChild(inst); this.tback = tback; @@ -147,8 +147,8 @@ public String toStringTree() { StringBuffer sb = new StringBuffer("Raise("); - sb.append("excepttype="); - sb.append(dumpThis(excepttype)); + sb.append("type="); + sb.append(dumpThis(type)); sb.append(","); sb.append("inst="); sb.append(dumpThis(inst)); @@ -165,8 +165,8 @@ } public void traverse(VisitorIF visitor) throws Exception { - if (excepttype != null) - excepttype.accept(visitor); + if (type != null) + type.accept(visitor); if (inst != null) inst.accept(visitor); if (tback != null) Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-01-08 00:34:35 UTC (rev 5874) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-01-08 02:08:58 UTC (rev 5875) @@ -751,10 +751,10 @@ @Override public Object visitRaise(Raise node) throws Exception { setline(node); - if (node.getInternalExcepttype() != null) { visit(node.getInternalExcepttype()); stackProduce(); } + if (node.getInternalType() != null) { visit(node.getInternalType()); stackProduce(); } if (node.getInternalInst() != null) { visit(node.getInternalInst()); stackProduce(); } if (node.getInternalTback() != null) { visit(node.getInternalTback()); stackProduce(); } - if (node.getInternalExcepttype() == null) { + if (node.getInternalType() == null) { code.invokestatic("org/python/core/Py", "makeException", "()" + $pyExc); } else if (node.getInternalInst() == null) { stackConsume(); @@ -1117,10 +1117,10 @@ //setline(name); Label end_of_self = new Label(); - if (handler.getInternalExcepttype() != null) { + if (handler.getInternalType() != null) { code.aload(exc); //get specific exception - visit(handler.getInternalExcepttype()); + visit(handler.getInternalType()); code.invokestatic("org/python/core/Py", "matchException", "(" + $pyExc + $pyObj + ")Z"); code.ifeq(end_of_self); } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 00:34:45
|
Revision: 5874 http://jython.svn.sourceforge.net/jython/?rev=5874&view=rev Author: fwierzbicki Date: 2009-01-08 00:34:35 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Added a sham io.py as a start. Added Paths: ----------- branches/jy3k/Lib/io.py Added: branches/jy3k/Lib/io.py =================================================================== --- branches/jy3k/Lib/io.py (rev 0) +++ branches/jy3k/Lib/io.py 2009-01-08 00:34:35 UTC (rev 5874) @@ -0,0 +1 @@ +import cStringIO as StringIO This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-01-08 00:32:26
|
Revision: 5873 http://jython.svn.sourceforge.net/jython/?rev=5873&view=rev Author: fwierzbicki Date: 2009-01-08 00:32:17 +0000 (Thu, 08 Jan 2009) Log Message: ----------- Merged revisions 5842-5847,5854,5857-5859,5863-5865,5869 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r5842 | cgroves | 2009-01-04 17:15:09 -0500 (Sun, 04 Jan 2009) | 5 lines Split java subclassing tests out of test_java_integration into test_java_subclasses, move unduplicated bits of test_jsubclass into test_java_subclasses. ........ r5843 | cgroves | 2009-01-04 18:06:27 -0500 (Sun, 04 Jan 2009) | 1 line Add tests that have been failing or skipping for the past few months to the expected lists ........ r5844 | cgroves | 2009-01-04 18:20:34 -0500 (Sun, 04 Jan 2009) | 1 line One more longstanding skip ........ r5845 | cgroves | 2009-01-04 22:56:25 -0500 (Sun, 04 Jan 2009) | 17 lines test292 - Moved to test_java_integration test293 - Importing no longer auto-imports submodules; deleted test294 - Moved to test_java_subclasses test295 - Moved to test_traceback test296 - Moved to test_import_jy test297,301,310,313,314,315,317 - Testing jythonc; deleted test298 - Moved to test_import_jy test299,300 - Tested by test_file test303 - Moved to test_java_visibility test307,308 - Moved to test_zipimport_jy test309 - Tested by test_scope test311 - Already disabled; deleted test312 - Moved to test_sax_jy test316 - Moved to test_java_integration test318 - Tested by test_syntax test319 - Moved to test_java_visibility ........ r5846 | cgroves | 2009-01-05 02:08:51 -0500 (Mon, 05 Jan 2009) | 1 line From http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_doctest.py@59127 ........ r5847 | cgroves | 2009-01-05 02:12:43 -0500 (Mon, 05 Jan 2009) | 10 lines test302 - Move to test_pep263_jy This adds a check for the encoding declared by the source file actually matching up with what we were getting out of it, and switches the default encoding to ascii to follow CPython. CPython assumes utf-8 in some single compilation contexts, and this uses the same parser algorithm everywhere, so I made a small change to test_doctest since Jython is throwing a SyntaxError on utf-8 strings to a single compilation. ........ r5854 | amak | 2009-01-05 14:47:25 -0500 (Mon, 05 Jan 2009) | 2 lines Fixed a bug where connect timeouts were not being honoured when set through socket.setdefaulttimeout() http://bugs.jython.org/issue1218 ........ r5857 | fwierzbicki | 2009-01-05 21:11:04 -0500 (Mon, 05 Jan 2009) | 2 lines Remove some unused methods. ........ r5858 | fwierzbicki | 2009-01-06 15:57:41 -0500 (Tue, 06 Jan 2009) | 4 lines Making the package names point to the raw original package names in source and making the jarjar step process everything in one step so the package mangling happens on our source as well as the included jars for jython-complete.jar. ........ r5859 | otmarhumbel | 2009-01-06 16:58:40 -0500 (Tue, 06 Jan 2009) | 2 lines - using ${dist.dir} for both jython.jar and jython-complete.jar - no unjar of jarjar.jar (since it does not exist any more) ........ r5863 | otmarhumbel | 2009-01-07 02:35:05 -0500 (Wed, 07 Jan 2009) | 2 lines - added asm and constantine .jar files to the eclipse build path - jarjar directory is not needed any more ........ r5864 | otmarhumbel | 2009-01-07 03:08:00 -0500 (Wed, 07 Jan 2009) | 5 lines 1) exlude jython.jar from the installation this makes the installer autotests pass again 2) do not include the /Lib files into jython-complete.jar once issue #1214 is fixed, 'java -jar jython-complete.jar' will run for all installation types (for now, set the -Dpython.home variable if not in standalone mode) ........ r5865 | otmarhumbel | 2009-01-07 03:28:57 -0500 (Wed, 07 Jan 2009) | 1 line preparation for an easy rename of the jython .jar files ........ r5869 | cgroves | 2009-01-07 13:12:46 -0500 (Wed, 07 Jan 2009) | 1 line Use the path to the imported item as __file__, not the package path ........ Modified Paths: -------------- branches/jy3k/.classpath branches/jy3k/Lib/os.py branches/jy3k/Lib/socket.py branches/jy3k/Lib/test/regrtest.py branches/jy3k/Lib/test/test_classpathimporter.py branches/jy3k/Lib/test/test_import_jy.py branches/jy3k/Lib/test/test_java_integration.py branches/jy3k/Lib/test/test_java_visibility.py branches/jy3k/Lib/test/test_socket.py branches/jy3k/Lib/test/test_traceback.py branches/jy3k/Lib/test/test_traceback_jy.py branches/jy3k/build.xml branches/jy3k/src/org/python/antlr/GrammarActions.java branches/jy3k/src/org/python/compiler/AdapterMaker.java branches/jy3k/src/org/python/compiler/ClassFile.java branches/jy3k/src/org/python/compiler/Code.java branches/jy3k/src/org/python/compiler/CodeCompiler.java branches/jy3k/src/org/python/compiler/Constant.java branches/jy3k/src/org/python/compiler/Module.java branches/jy3k/src/org/python/compiler/ProxyMaker.java branches/jy3k/src/org/python/core/APIReader.java branches/jy3k/src/org/python/core/BytecodeLoader.java branches/jy3k/src/org/python/core/ClasspathPyImporter.java branches/jy3k/src/org/python/core/ParserFacade.java branches/jy3k/src/org/python/core/Py.java branches/jy3k/src/org/python/core/PyReflectedConstructor.java branches/jy3k/src/org/python/core/imp.java branches/jy3k/src/org/python/core/io/FileIO.java branches/jy3k/src/org/python/core/io/IOBase.java branches/jy3k/src/org/python/core/io/ServerSocketIO.java branches/jy3k/src/org/python/core/util/importer.java branches/jy3k/src/org/python/expose/generate/ClassMethodExposer.java branches/jy3k/src/org/python/expose/generate/DescriptorExposer.java branches/jy3k/src/org/python/expose/generate/ExposeTask.java branches/jy3k/src/org/python/expose/generate/ExposedFieldFinder.java branches/jy3k/src/org/python/expose/generate/ExposedMethodFinder.java branches/jy3k/src/org/python/expose/generate/ExposedTypeProcessor.java branches/jy3k/src/org/python/expose/generate/ExposedTypeVisitor.java branches/jy3k/src/org/python/expose/generate/Exposer.java branches/jy3k/src/org/python/expose/generate/InstanceMethodExposer.java branches/jy3k/src/org/python/expose/generate/MethodExposer.java branches/jy3k/src/org/python/expose/generate/NewExposer.java branches/jy3k/src/org/python/expose/generate/OverridableNewExposer.java branches/jy3k/src/org/python/expose/generate/PyTypes.java branches/jy3k/src/org/python/expose/generate/RestrictiveAnnotationVisitor.java branches/jy3k/src/org/python/expose/generate/TypeExposer.java branches/jy3k/src/org/python/modules/_py_compile.java branches/jy3k/src/org/python/modules/errno.java branches/jy3k/src/org/python/modules/zipimport/zipimporter.java branches/jy3k/tests/java/org/python/expose/generate/DescriptorExposerTest.java branches/jy3k/tests/java/org/python/expose/generate/ExposeMethodFinderTest.java branches/jy3k/tests/java/org/python/expose/generate/ExposedTypeVisitorTest.java branches/jy3k/tests/java/org/python/expose/generate/MethodExposerTest.java branches/jy3k/tests/java/org/python/expose/generate/NewExposerTest.java branches/jy3k/tests/java/org/python/expose/generate/OverridableNewExposerTest.java branches/jy3k/tests/java/org/python/expose/generate/TypeExposerTest.java branches/jy3k/tests/java/org/python/tests/BeanInterface.java branches/jy3k/tests/java/org/python/tests/Coercions.java Added Paths: ----------- branches/jy3k/Lib/test/anygui.py branches/jy3k/Lib/test/import_nonexistent.py branches/jy3k/Lib/test/invalid_utf_8_declared_encoding.py branches/jy3k/Lib/test/latin1_no_encoding.py branches/jy3k/Lib/test/python_home.policy branches/jy3k/Lib/test/syspath_import.jar branches/jy3k/Lib/test/test_doctest.py branches/jy3k/Lib/test/test_java_subclasses.py branches/jy3k/Lib/test/test_pep263_jy.py branches/jy3k/Lib/test/test_sax_jy.py branches/jy3k/Lib/test/test_zipimport_jy.py branches/jy3k/tests/java/org/python/tests/Matryoshka.java Removed Paths: ------------- branches/jy3k/Lib/test/test_jsubclass.py branches/jy3k/bugtests/classes/test288i.java branches/jy3k/bugtests/classes/test288j.java branches/jy3k/bugtests/test290.py branches/jy3k/bugtests/test291.py branches/jy3k/bugtests/test292.policy branches/jy3k/bugtests/test292.py branches/jy3k/bugtests/test293.py branches/jy3k/bugtests/test293p/ branches/jy3k/bugtests/test294.py branches/jy3k/bugtests/test294j.java branches/jy3k/bugtests/test295.py branches/jy3k/bugtests/test296.py branches/jy3k/bugtests/test296p/ branches/jy3k/bugtests/test297.py branches/jy3k/bugtests/test297c.py branches/jy3k/bugtests/test298.py branches/jy3k/bugtests/test298m1.py branches/jy3k/bugtests/test299.py branches/jy3k/bugtests/test300.py branches/jy3k/bugtests/test301.py branches/jy3k/bugtests/test301c.py branches/jy3k/bugtests/test302.py branches/jy3k/bugtests/test303.py branches/jy3k/bugtests/test303j.java branches/jy3k/bugtests/test307.py branches/jy3k/bugtests/test307foobar.template branches/jy3k/bugtests/test307m.template branches/jy3k/bugtests/test307p.template branches/jy3k/bugtests/test308.py branches/jy3k/bugtests/test308d/ branches/jy3k/bugtests/test309.py branches/jy3k/bugtests/test310.py branches/jy3k/bugtests/test310c.py branches/jy3k/bugtests/test311.py branches/jy3k/bugtests/test312.py branches/jy3k/bugtests/test313.py branches/jy3k/bugtests/test313c.py branches/jy3k/bugtests/test314.py branches/jy3k/bugtests/test314c.py branches/jy3k/bugtests/test315.py branches/jy3k/bugtests/test315c.py branches/jy3k/bugtests/test316.py branches/jy3k/bugtests/test317.py branches/jy3k/bugtests/test317c.py branches/jy3k/bugtests/test318.py branches/jy3k/bugtests/test319.py branches/jy3k/bugtests/test319j.java branches/jy3k/tests/java/javatests/MethodInvokationTest.java Property Changed: ---------------- branches/jy3k/ Property changes on: branches/jy3k ___________________________________________________________________ Modified: svnmerge-integrated - /trunk/jython:1-5840 + /trunk/jython:1-5872 Modified: branches/jy3k/.classpath =================================================================== --- branches/jy3k/.classpath 2009-01-07 23:59:24 UTC (rev 5872) +++ branches/jy3k/.classpath 2009-01-08 00:32:17 UTC (rev 5873) @@ -12,8 +12,10 @@ <classpathentry kind="lib" path="extlibs/mysql-connector-java-5.1.6.jar"/> <classpathentry kind="lib" path="extlibs/postgresql-8.3-603.jdbc4.jar"/> <classpathentry kind="lib" path="extlibs/servlet-api-2.5.jar"/> - <classpathentry kind="lib" path="build/jarjar"/> <classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/> <classpathentry kind="lib" path="extlibs/antlr-3.1.1-runtime.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"/> <classpathentry kind="output" path="bugtests/classes"/> </classpath> Modified: branches/jy3k/Lib/os.py =================================================================== --- branches/jy3k/Lib/os.py 2009-01-07 23:59:24 UTC (rev 5872) +++ branches/jy3k/Lib/os.py 2009-01-08 00:32:17 UTC (rev 5873) @@ -47,10 +47,14 @@ import stat as _stat import sys from java.io import File -from org.python.constantine.platform import Errno from org.python.core.io import FileDescriptors, FileIO, IOBase from org.python.core.Py import newString as asPyString +try: + from org.python.constantine.platform import Errno +except ImportError: + from com.kenai.constantine.platform import Errno + # Mapping of: os._name: [name list, shell command list] _os_map = dict(nt=[ ['Windows 95', 'Windows 98', 'Windows ME', 'Windows NT', @@ -96,7 +100,10 @@ # should *NOT* use it _name = get_os_type() -from org.python.posix import JavaPOSIX, POSIXHandler, POSIXFactory +try: + from org.python.posix import JavaPOSIX, POSIXHandler, POSIXFactory +except ImportError: + from org.jruby.ext.posix import JavaPOSIX, POSIXHandler, POSIXFactory class PythonPOSIXHandler(POSIXHandler): def error(self, error, msg): @@ -420,7 +427,10 @@ if constant.name() == constant.description(): # XXX: have constantine handle this fallback # Fake constant or just lacks a description, fallback to Linux's - from org.python.constantine.platform.linux import Errno as LinuxErrno + try: + from org.python.constantine.platform.linux import Errno as LinuxErrno + except ImportError: + from com.kenai.constantine.platform.linux import Errno as LinuxErrno constant = getattr(LinuxErrno, constant.name(), None) if not constant: return 'Unknown error: %d' % code @@ -558,7 +568,10 @@ global _time_t if _time_t is None: from java.lang import Integer, Long - from org.python.posix.util import Platform + try: + from org.python.posix import Platform + except ImportError: + from org.jruby.ext.posix.util import Platform _time_t = Integer if Platform.IS_32_BIT else Long try: Modified: branches/jy3k/Lib/socket.py =================================================================== --- branches/jy3k/Lib/socket.py 2009-01-07 23:59:24 UTC (rev 5872) +++ branches/jy3k/Lib/socket.py 2009-01-08 00:32:17 UTC (rev 5873) @@ -632,12 +632,14 @@ class _nonblocking_api_mixin: - timeout = _defaulttimeout mode = MODE_BLOCKING reference_count = 0 close_lock = threading.Lock() def __init__(self): + self.timeout = _defaulttimeout + if self.timeout is not None: + self.mode = MODE_TIMEOUT self.pending_options = { SO_REUSEADDR: 0, } @@ -791,7 +793,7 @@ self.sock_impl.bind(bind_host, bind_port, self.pending_options[SO_REUSEADDR]) self._config() # Configure timeouts, etc, now that the socket exists self.sock_impl.connect(host, port) - except java.lang.Exception, jlx: + except java.lang.Exception, jlx: raise _map_exception(jlx) def connect(self, addr): Copied: branches/jy3k/Lib/test/anygui.py (from rev 5869, trunk/jython/Lib/test/anygui.py) =================================================================== --- branches/jy3k/Lib/test/anygui.py (rev 0) +++ branches/jy3k/Lib/test/anygui.py 2009-01-08 00:32:17 UTC (rev 5873) @@ -0,0 +1,40 @@ +'''Used by test_import_jy/test_getattr_module''' +import sys + +class anygui: + __all__ = ['Window'] # Etc... + + def __init__(self): + self.__backend = None + self.__backends = ['msw', 'x', 'mac', 'wx', 'tk', 'java'] + + def __try_to_get(self, modulename): + import imp + try: + module = imp.find_module(modulename) + except (IOError, ImportError, AttributeError, AssertionError): + return None + else: + return module + + def __import_backend(self, wishlist): + candidates = self.__backends[:] + for wish in wishlist: + if wish in candidates: + candidates.remove(wish) + else: + wishlist.remove(wish) + candidates = wishlist + candidates + + for name in candidates: + backend = self.__try_to_get('%sgui' % name) + if not backend: + raise Exception, 'not able to import any GUI backends' + self.__backend = backend + + def __getattr__(self, name): + if not self.__backend: + self.__import_backend(self.__dict__.get('wishlist', [])) + return self.__backend.__dict__[name] + +sys.modules[__name__] = anygui() Copied: branches/jy3k/Lib/test/import_nonexistent.py (from rev 5869, trunk/jython/Lib/test/import_nonexistent.py) =================================================================== --- branches/jy3k/Lib/test/import_nonexistent.py (rev 0) +++ branches/jy3k/Lib/test/import_nonexistent.py 2009-01-08 00:32:17 UTC (rev 5873) @@ -0,0 +1,7 @@ +try: + import nonexistent_module +except ImportError: + pass # This should cause an import error, but as there's a security manager in place it hasn't + # always done so +else: + raise Error("Should've caused an import error!") Copied: branches/jy3k/Lib/test/invalid_utf_8_declared_encoding.py (from rev 5869, trunk/jython/Lib/test/invalid_utf_8_declared_encoding.py) =================================================================== (Binary files differ) Copied: branches/jy3k/Lib/test/latin1_no_encoding.py (from rev 5869, trunk/jython/Lib/test/latin1_no_encoding.py) =================================================================== (Binary files differ) Copied: branches/jy3k/Lib/test/python_home.policy (from rev 5869, trunk/jython/Lib/test/python_home.policy) =================================================================== --- branches/jy3k/Lib/test/python_home.policy (rev 0) +++ branches/jy3k/Lib/test/python_home.policy 2009-01-08 00:32:17 UTC (rev 5873) @@ -0,0 +1,5 @@ +grant codeBase "file:${python.home}/-" { + permission java.util.PropertyPermission "*", "read,write"; + permission java.io.FilePermission "<<ALL FILES>>", "read,write"; +}; + Modified: branches/jy3k/Lib/test/regrtest.py =================================================================== --- branches/jy3k/Lib/test/regrtest.py 2009-01-07 23:59:24 UTC (rev 5872) +++ branches/jy3k/Lib/test/regrtest.py 2009-01-08 00:32:17 UTC (rev 5873) @@ -1380,6 +1380,7 @@ 'java': """ test__locale + test__rawffi test_aepack test_al test_applesingle @@ -1449,6 +1450,7 @@ test_winreg test_winsound test_xml_etree_c + test_zipfile64 """ } _expectations['freebsd5'] = _expectations['freebsd4'] @@ -1475,11 +1477,16 @@ test_gc test_iterlen test_marshal + test_multibytecodec + test_multibytecodec_support test_peepholer test_profile test_pyclbr + test_stringprep test_transformer test_ucn + test_unicode + test_unicodedata test_xml_etree test_zipimport """, Copied: branches/jy3k/Lib/test/syspath_import.jar (from rev 5869, trunk/jython/Lib/test/syspath_import.jar) =================================================================== (Binary files differ) Modified: branches/jy3k/Lib/test/test_classpathimporter.py =================================================================== --- branches/jy3k/Lib/test/test_classpathimporter.py 2009-01-07 23:59:24 UTC (rev 5872) +++ branches/jy3k/Lib/test/test_classpathimporter.py 2009-01-08 00:32:17 UTC (rev 5873) @@ -18,22 +18,24 @@ except KeyError: pass - def setClassLoaderAndCheck(self, jar): + def setClassLoaderAndCheck(self, jar, prefix): Thread.currentThread().contextClassLoader = test_support.make_jar_classloader(jar) import flat_in_jar self.assertEquals(flat_in_jar.value, 7) import jar_pkg + self.assertEquals(prefix + '/jar_pkg/__init__$py.class', jar_pkg.__file__) from jar_pkg import prefer_compiled + self.assertEquals(prefix + '/jar_pkg/prefer_compiled$py.class', prefer_compiled.__file__) self.assert_(prefer_compiled.compiled) self.assertRaises(NameError, __import__, 'flat_bad') self.assertRaises(NameError, __import__, 'jar_pkg.bad') def test_default_pyclasspath(self): - self.setClassLoaderAndCheck("classimport.jar") + self.setClassLoaderAndCheck("classimport.jar", "__pyclasspath__") def test_path_in_pyclasspath(self): sys.path = ['__pyclasspath__/Lib'] - self.setClassLoaderAndCheck("classimport_Lib.jar") + self.setClassLoaderAndCheck("classimport_Lib.jar", "__pyclasspath__/Lib") def test_main(): test_support.run_unittest(ClasspathImporterTestCase) Copied: branches/jy3k/Lib/test/test_doctest.py (from rev 5869, trunk/jython/Lib/test/test_doctest.py) =================================================================== --- branches/jy3k/Lib/test/test_doctest.py (rev 0) +++ branches/jy3k/Lib/test/test_doctest.py 2009-01-08 00:32:17 UTC (rev 5873) @@ -0,0 +1,2438 @@ +""" +Test script for doctest. +""" + +from test import test_support +import doctest +import warnings + +###################################################################### +## Sample Objects (used by test cases) +###################################################################### + +def sample_func(v): + """ + Blah blah + + >>> print sample_func(22) + 44 + + Yee ha! + """ + return v+v + +class SampleClass: + """ + >>> print 1 + 1 + + >>> # comments get ignored. so are empty PS1 and PS2 prompts: + >>> + ... + + Multiline example: + >>> sc = SampleClass(3) + >>> for i in range(10): + ... sc = sc.double() + ... print sc.get(), + 6 12 24 48 96 192 384 768 1536 3072 + """ + def __init__(self, val): + """ + >>> print SampleClass(12).get() + 12 + """ + self.val = val + + def double(self): + """ + >>> print SampleClass(12).double().get() + 24 + """ + return SampleClass(self.val + self.val) + + def get(self): + """ + >>> print SampleClass(-5).get() + -5 + """ + return self.val + + def a_staticmethod(v): + """ + >>> print SampleClass.a_staticmethod(10) + 11 + """ + return v+1 + a_staticmethod = staticmethod(a_staticmethod) + + def a_classmethod(cls, v): + """ + >>> print SampleClass.a_classmethod(10) + 12 + >>> print SampleClass(0).a_classmethod(10) + 12 + """ + return v+2 + a_classmethod = classmethod(a_classmethod) + + a_property = property(get, doc=""" + >>> print SampleClass(22).a_property + 22 + """) + + class NestedClass: + """ + >>> x = SampleClass.NestedClass(5) + >>> y = x.square() + >>> print y.get() + 25 + """ + def __init__(self, val=0): + """ + >>> print SampleClass.NestedClass().get() + 0 + """ + self.val = val + def square(self): + return SampleClass.NestedClass(self.val*self.val) + def get(self): + return self.val + +class SampleNewStyleClass(object): + r""" + >>> print '1\n2\n3' + 1 + 2 + 3 + """ + def __init__(self, val): + """ + >>> print SampleNewStyleClass(12).get() + 12 + """ + self.val = val + + def double(self): + """ + >>> print SampleNewStyleClass(12).double().get() + 24 + """ + return SampleNewStyleClass(self.val + self.val) + + def get(self): + """ + >>> print SampleNewStyleClass(-5).get() + -5 + """ + return self.val + +###################################################################### +## Fake stdin (for testing interactive debugging) +###################################################################### + +class _FakeInput: + """ + A fake input stream for pdb's interactive debugger. Whenever a + line is read, print it (to simulate the user typing it), and then + return it. The set of lines to return is specified in the + constructor; they should not have trailing newlines. + """ + def __init__(self, lines): + self.lines = lines + + def readline(self): + line = self.lines.pop(0) + print line + return line+'\n' + +###################################################################### +## Test Cases +###################################################################### + +def test_Example(): r""" +Unit tests for the `Example` class. + +Example is a simple container class that holds: + - `source`: A source string. + - `want`: An expected output string. + - `exc_msg`: An expected exception message string (or None if no + exception is expected). + - `lineno`: A line number (within the docstring). + - `indent`: The example's indentation in the input string. + - `options`: An option dictionary, mapping option flags to True or + False. + +These attributes are set by the constructor. `source` and `want` are +required; the other attributes all have default values: + + >>> example = doctest.Example('print 1', '1\n') + >>> (example.source, example.want, example.exc_msg, + ... example.lineno, example.indent, example.options) + ('print 1\n', '1\n', None, 0, 0, {}) + +The first three attributes (`source`, `want`, and `exc_msg`) may be +specified positionally; the remaining arguments should be specified as +keyword arguments: + + >>> exc_msg = 'IndexError: pop from an empty list' + >>> example = doctest.Example('[].pop()', '', exc_msg, + ... lineno=5, indent=4, + ... options={doctest.ELLIPSIS: True}) + >>> (example.source, example.want, example.exc_msg, + ... example.lineno, example.indent, example.options) + ('[].pop()\n', '', 'IndexError: pop from an empty list\n', 5, 4, {8: True}) + +The constructor normalizes the `source` string to end in a newline: + + Source spans a single line: no terminating newline. + >>> e = doctest.Example('print 1', '1\n') + >>> e.source, e.want + ('print 1\n', '1\n') + + >>> e = doctest.Example('print 1\n', '1\n') + >>> e.source, e.want + ('print 1\n', '1\n') + + Source spans multiple lines: require terminating newline. + >>> e = doctest.Example('print 1;\nprint 2\n', '1\n2\n') + >>> e.source, e.want + ('print 1;\nprint 2\n', '1\n2\n') + + >>> e = doctest.Example('print 1;\nprint 2', '1\n2\n') + >>> e.source, e.want + ('print 1;\nprint 2\n', '1\n2\n') + + Empty source string (which should never appear in real examples) + >>> e = doctest.Example('', '') + >>> e.source, e.want + ('\n', '') + +The constructor normalizes the `want` string to end in a newline, +unless it's the empty string: + + >>> e = doctest.Example('print 1', '1\n') + >>> e.source, e.want + ('print 1\n', '1\n') + + >>> e = doctest.Example('print 1', '1') + >>> e.source, e.want + ('print 1\n', '1\n') + + >>> e = doctest.Example('print', '') + >>> e.source, e.want + ('print\n', '') + +The constructor normalizes the `exc_msg` string to end in a newline, +unless it's `None`: + + Message spans one line + >>> exc_msg = 'IndexError: pop from an empty list' + >>> e = doctest.Example('[].pop()', '', exc_msg) + >>> e.exc_msg + 'IndexError: pop from an empty list\n' + + >>> exc_msg = 'IndexError: pop from an empty list\n' + >>> e = doctest.Example('[].pop()', '', exc_msg) + >>> e.exc_msg + 'IndexError: pop from an empty list\n' + + Message spans multiple lines + >>> exc_msg = 'ValueError: 1\n 2' + >>> e = doctest.Example('raise ValueError("1\n 2")', '', exc_msg) + >>> e.exc_msg + 'ValueError: 1\n 2\n' + + >>> exc_msg = 'ValueError: 1\n 2\n' + >>> e = doctest.Example('raise ValueError("1\n 2")', '', exc_msg) + >>> e.exc_msg + 'ValueError: 1\n 2\n' + + Empty (but non-None) exception message (which should never appear + in real examples) + >>> exc_msg = '' + >>> e = doctest.Example('raise X()', '', exc_msg) + >>> e.exc_msg + '\n' +""" + +def test_DocTest(): r""" +Unit tests for the `DocTest` class. + +DocTest is a collection of examples, extracted from a docstring, along +with information about where the docstring comes from (a name, +filename, and line number). The docstring is parsed by the `DocTest` +constructor: + + >>> docstring = ''' + ... >>> print 12 + ... 12 + ... + ... Non-example text. + ... + ... >>> print 'another\example' + ... another + ... example + ... ''' + >>> globs = {} # globals to run the test in. + >>> parser = doctest.DocTestParser() + >>> test = parser.get_doctest(docstring, globs, 'some_test', + ... 'some_file', 20) + >>> print test + <DocTest some_test from some_file:20 (2 examples)> + >>> len(test.examples) + 2 + >>> e1, e2 = test.examples + >>> (e1.source, e1.want, e1.lineno) + ('print 12\n', '12\n', 1) + >>> (e2.source, e2.want, e2.lineno) + ("print 'another\\example'\n", 'another\nexample\n', 6) + +Source information (name, filename, and line number) is available as +attributes on the doctest object: + + >>> (test.name, test.filename, test.lineno) + ('some_test', 'some_file', 20) + +The line number of an example within its containing file is found by +adding the line number of the example and the line number of its +containing test: + + >>> test.lineno + e1.lineno + 21 + >>> test.lineno + e2.lineno + 26 + +If the docstring contains inconsistant leading whitespace in the +expected output of an example, then `DocTest` will raise a ValueError: + + >>> docstring = r''' + ... >>> print 'bad\nindentation' + ... bad + ... indentation + ... ''' + >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0) + Traceback (most recent call last): + ValueError: line 4 of the docstring for some_test has inconsistent leading whitespace: 'indentation' + +If the docstring contains inconsistent leading whitespace on +continuation lines, then `DocTest` will raise a ValueError: + + >>> docstring = r''' + ... >>> print ('bad indentation', + ... ... 2) + ... ('bad', 'indentation') + ... ''' + >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0) + Traceback (most recent call last): + ValueError: line 2 of the docstring for some_test has inconsistent leading whitespace: '... 2)' + +If there's no blank space after a PS1 prompt ('>>>'), then `DocTest` +will raise a ValueError: + + >>> docstring = '>>>print 1\n1' + >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0) + Traceback (most recent call last): + ValueError: line 1 of the docstring for some_test lacks blank after >>>: '>>>print 1' + +If there's no blank space after a PS2 prompt ('...'), then `DocTest` +will raise a ValueError: + + >>> docstring = '>>> if 1:\n...print 1\n1' + >>> parser.get_doctest(docstring, globs, 'some_test', 'filename', 0) + Traceback (most recent call last): + ValueError: line 2 of the docstring for some_test lacks blank after ...: '...print 1' + +""" + +def test_DocTestFinder(): r""" +Unit tests for the `DocTestFinder` class. + +DocTestFinder is used to extract DocTests from an object's docstring +and the docstrings of its contained objects. It can be used with +modules, functions, classes, methods, staticmethods, classmethods, and +properties. + +Finding Tests in Functions +~~~~~~~~~~~~~~~~~~~~~~~~~~ +For a function whose docstring contains examples, DocTestFinder.find() +will return a single test (for that function's docstring): + + >>> finder = doctest.DocTestFinder() + +We'll simulate a __file__ attr that ends in pyc: + + >>> import test.test_doctest + >>> old = test.test_doctest.__file__ + >>> test.test_doctest.__file__ = 'test_doctest.pyc' + + >>> tests = finder.find(sample_func) + + >>> print tests # doctest: +ELLIPSIS + [<DocTest sample_func from ...:13 (1 example)>] + +The exact name depends on how test_doctest was invoked, so allow for +leading path components. + + >>> tests[0].filename # doctest: +ELLIPSIS + '...test_doctest.py' + + >>> test.test_doctest.__file__ = old + + + >>> e = tests[0].examples[0] + >>> (e.source, e.want, e.lineno) + ('print sample_func(22)\n', '44\n', 3) + +By default, tests are created for objects with no docstring: + + >>> def no_docstring(v): + ... pass + >>> finder.find(no_docstring) + [] + +However, the optional argument `exclude_empty` to the DocTestFinder +constructor can be used to exclude tests for objects with empty +docstrings: + + >>> def no_docstring(v): + ... pass + >>> excl_empty_finder = doctest.DocTestFinder(exclude_empty=True) + >>> excl_empty_finder.find(no_docstring) + [] + +If the function has a docstring with no examples, then a test with no +examples is returned. (This lets `DocTestRunner` collect statistics +about which functions have no tests -- but is that useful? And should +an empty test also be created when there's no docstring?) + + >>> def no_examples(v): + ... ''' no doctest examples ''' + >>> finder.find(no_examples) # doctest: +ELLIPSIS + [<DocTest no_examples from ...:1 (no examples)>] + +Finding Tests in Classes +~~~~~~~~~~~~~~~~~~~~~~~~ +For a class, DocTestFinder will create a test for the class's +docstring, and will recursively explore its contents, including +methods, classmethods, staticmethods, properties, and nested classes. + + >>> finder = doctest.DocTestFinder() + >>> tests = finder.find(SampleClass) + >>> for t in tests: + ... print '%2s %s' % (len(t.examples), t.name) + 3 SampleClass + 3 SampleClass.NestedClass + 1 SampleClass.NestedClass.__init__ + 1 SampleClass.__init__ + 2 SampleClass.a_classmethod + 1 SampleClass.a_property + 1 SampleClass.a_staticmethod + 1 SampleClass.double + 1 SampleClass.get + +New-style classes are also supported: + + >>> tests = finder.find(SampleNewStyleClass) + >>> for t in tests: + ... print '%2s %s' % (len(t.examples), t.name) + 1 SampleNewStyleClass + 1 SampleNewStyleClass.__init__ + 1 SampleNewStyleClass.double + 1 SampleNewStyleClass.get + +Finding Tests in Modules +~~~~~~~~~~~~~~~~~~~~~~~~ +For a module, DocTestFinder will create a test for the class's +docstring, and will recursively explore its contents, including +functions, classes, and the `__test__` dictionary, if it exists: + + >>> # A module + >>> import new + >>> m = new.module('some_module') + >>> def triple(val): + ... ''' + ... >>> print triple(11) + ... 33 + ... ''' + ... return val*3 + >>> m.__dict__.update({ + ... 'sample_func': sample_func, + ... 'SampleClass': SampleClass, + ... '__doc__': ''' + ... Module docstring. + ... >>> print 'module' + ... module + ... ''', + ... '__test__': { + ... 'd': '>>> print 6\n6\n>>> print 7\n7\n', + ... 'c': triple}}) + + >>> finder = doctest.DocTestFinder() + >>> # Use module=test.test_doctest, to prevent doctest from + >>> # ignoring the objects since they weren't defined in m. + >>> import test.test_doctest + >>> tests = finder.find(m, module=test.test_doctest) + >>> for t in tests: + ... print '%2s %s' % (len(t.examples), t.name) + 1 some_module + 3 some_module.SampleClass + 3 some_module.SampleClass.NestedClass + 1 some_module.SampleClass.NestedClass.__init__ + 1 some_module.SampleClass.__init__ + 2 some_module.SampleClass.a_classmethod + 1 some_module.SampleClass.a_property + 1 some_module.SampleClass.a_staticmethod + 1 some_module.SampleClass.double + 1 some_module.SampleClass.get + 1 some_module.__test__.c + 2 some_module.__test__.d + 1 some_module.sample_func + +Duplicate Removal +~~~~~~~~~~~~~~~~~ +If a single object is listed twice (under different names), then tests +will only be generated for it once: + + >>> from test import doctest_aliases + >>> tests = excl_empty_finder.find(doctest_aliases) + >>> print len(tests) + 2 + >>> print tests[0].name + test.doctest_aliases.TwoNames + + TwoNames.f and TwoNames.g are bound to the same object. + We can't guess which will be found in doctest's traversal of + TwoNames.__dict__ first, so we have to allow for either. + + >>> tests[1].name.split('.')[-1] in ['f', 'g'] + True + +Empty Tests +~~~~~~~~~~~ +By default, an object with no doctests doesn't create any tests: + + >>> tests = doctest.DocTestFinder().find(SampleClass) + >>> for t in tests: + ... print '%2s %s' % (len(t.examples), t.name) + 3 SampleClass + 3 SampleClass.NestedClass + 1 SampleClass.NestedClass.__init__ + 1 SampleClass.__init__ + 2 SampleClass.a_classmethod + 1 SampleClass.a_property + 1 SampleClass.a_staticmethod + 1 SampleClass.double + 1 SampleClass.get + +By default, that excluded objects with no doctests. exclude_empty=False +tells it to include (empty) tests for objects with no doctests. This feature +is really to support backward compatibility in what doctest.master.summarize() +displays. + + >>> tests = doctest.DocTestFinder(exclude_empty=False).find(SampleClass) + >>> for t in tests: + ... print '%2s %s' % (len(t.examples), t.name) + 3 SampleClass + 3 SampleClass.NestedClass + 1 SampleClass.NestedClass.__init__ + 0 SampleClass.NestedClass.get + 0 SampleClass.NestedClass.square + 1 SampleClass.__init__ + 2 SampleClass.a_classmethod + 1 SampleClass.a_property + 1 SampleClass.a_staticmethod + 1 SampleClass.double + 1 SampleClass.get + +Turning off Recursion +~~~~~~~~~~~~~~~~~~~~~ +DocTestFinder can be told not to look for tests in contained objects +using the `recurse` flag: + + >>> tests = doctest.DocTestFinder(recurse=False).find(SampleClass) + >>> for t in tests: + ... print '%2s %s' % (len(t.examples), t.name) + 3 SampleClass + +Line numbers +~~~~~~~~~~~~ +DocTestFinder finds the line number of each example: + + >>> def f(x): + ... ''' + ... >>> x = 12 + ... + ... some text + ... + ... >>> # examples are not created for comments & bare prompts. + ... >>> + ... ... + ... + ... >>> for x in range(10): + ... ... print x, + ... 0 1 2 3 4 5 6 7 8 9 + ... >>> x//2 + ... 6 + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> [e.lineno for e in test.examples] + [1, 9, 12] +""" + +def test_DocTestParser(): r""" +Unit tests for the `DocTestParser` class. + +DocTestParser is used to parse docstrings containing doctest examples. + +The `parse` method divides a docstring into examples and intervening +text: + + >>> s = ''' + ... >>> x, y = 2, 3 # no output expected + ... >>> if 1: + ... ... print x + ... ... print y + ... 2 + ... 3 + ... + ... Some text. + ... >>> x+y + ... 5 + ... ''' + >>> parser = doctest.DocTestParser() + >>> for piece in parser.parse(s): + ... if isinstance(piece, doctest.Example): + ... print 'Example:', (piece.source, piece.want, piece.lineno) + ... else: + ... print ' Text:', `piece` + Text: '\n' + Example: ('x, y = 2, 3 # no output expected\n', '', 1) + Text: '' + Example: ('if 1:\n print x\n print y\n', '2\n3\n', 2) + Text: '\nSome text.\n' + Example: ('x+y\n', '5\n', 9) + Text: '' + +The `get_examples` method returns just the examples: + + >>> for piece in parser.get_examples(s): + ... print (piece.source, piece.want, piece.lineno) + ('x, y = 2, 3 # no output expected\n', '', 1) + ('if 1:\n print x\n print y\n', '2\n3\n', 2) + ('x+y\n', '5\n', 9) + +The `get_doctest` method creates a Test from the examples, along with the +given arguments: + + >>> test = parser.get_doctest(s, {}, 'name', 'filename', lineno=5) + >>> (test.name, test.filename, test.lineno) + ('name', 'filename', 5) + >>> for piece in test.examples: + ... print (piece.source, piece.want, piece.lineno) + ('x, y = 2, 3 # no output expected\n', '', 1) + ('if 1:\n print x\n print y\n', '2\n3\n', 2) + ('x+y\n', '5\n', 9) +""" + +class test_DocTestRunner: + def basics(): r""" +Unit tests for the `DocTestRunner` class. + +DocTestRunner is used to run DocTest test cases, and to accumulate +statistics. Here's a simple DocTest case we can use: + + >>> def f(x): + ... ''' + ... >>> x = 12 + ... >>> print x + ... 12 + ... >>> x//2 + ... 6 + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + +The main DocTestRunner interface is the `run` method, which runs a +given DocTest case in a given namespace (globs). It returns a tuple +`(f,t)`, where `f` is the number of failed tests and `t` is the number +of tried tests. + + >>> doctest.DocTestRunner(verbose=False).run(test) + (0, 3) + +If any example produces incorrect output, then the test runner reports +the failure and proceeds to the next example: + + >>> def f(x): + ... ''' + ... >>> x = 12 + ... >>> print x + ... 14 + ... >>> x//2 + ... 6 + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=True).run(test) + ... # doctest: +ELLIPSIS + Trying: + x = 12 + Expecting nothing + ok + Trying: + print x + Expecting: + 14 + ********************************************************************** + File ..., line 4, in f + Failed example: + print x + Expected: + 14 + Got: + 12 + Trying: + x//2 + Expecting: + 6 + ok + (1, 3) +""" + def verbose_flag(): r""" +The `verbose` flag makes the test runner generate more detailed +output: + + >>> def f(x): + ... ''' + ... >>> x = 12 + ... >>> print x + ... 12 + ... >>> x//2 + ... 6 + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + + >>> doctest.DocTestRunner(verbose=True).run(test) + Trying: + x = 12 + Expecting nothing + ok + Trying: + print x + Expecting: + 12 + ok + Trying: + x//2 + Expecting: + 6 + ok + (0, 3) + +If the `verbose` flag is unspecified, then the output will be verbose +iff `-v` appears in sys.argv: + + >>> # Save the real sys.argv list. + >>> old_argv = sys.argv + + >>> # If -v does not appear in sys.argv, then output isn't verbose. + >>> sys.argv = ['test'] + >>> doctest.DocTestRunner().run(test) + (0, 3) + + >>> # If -v does appear in sys.argv, then output is verbose. + >>> sys.argv = ['test', '-v'] + >>> doctest.DocTestRunner().run(test) + Trying: + x = 12 + Expecting nothing + ok + Trying: + print x + Expecting: + 12 + ok + Trying: + x//2 + Expecting: + 6 + ok + (0, 3) + + >>> # Restore sys.argv + >>> sys.argv = old_argv + +In the remaining examples, the test runner's verbosity will be +explicitly set, to ensure that the test behavior is consistent. + """ + def exceptions(): r""" +Tests of `DocTestRunner`'s exception handling. + +An expected exception is specified with a traceback message. The +lines between the first line and the type/value may be omitted or +replaced with any other string: + + >>> def f(x): + ... ''' + ... >>> x = 12 + ... >>> print x//0 + ... Traceback (most recent call last): + ... ZeroDivisionError: integer division or modulo by zero + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + (0, 2) + +An example may not generate output before it raises an exception; if +it does, then the traceback message will not be recognized as +signaling an expected exception, so the example will be reported as an +unexpected exception: + + >>> def f(x): + ... ''' + ... >>> x = 12 + ... >>> print 'pre-exception output', x//0 + ... pre-exception output + ... Traceback (most recent call last): + ... ZeroDivisionError: integer division or modulo by zero + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 4, in f + Failed example: + print 'pre-exception output', x//0 + Exception raised: + ... + ZeroDivisionError: integer division or modulo by zero + (1, 2) + +Exception messages may contain newlines: + + >>> def f(x): + ... r''' + ... >>> raise ValueError, 'multi\nline\nmessage' + ... Traceback (most recent call last): + ... ValueError: multi + ... line + ... message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + (0, 1) + +If an exception is expected, but an exception with the wrong type or +message is raised, then it is reported as a failure: + + >>> def f(x): + ... r''' + ... >>> raise ValueError, 'message' + ... Traceback (most recent call last): + ... ValueError: wrong message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 3, in f + Failed example: + raise ValueError, 'message' + Expected: + Traceback (most recent call last): + ValueError: wrong message + Got: + Traceback (most recent call last): + ... + ValueError: message + (1, 1) + +However, IGNORE_EXCEPTION_DETAIL can be used to allow a mismatch in the +detail: + + >>> def f(x): + ... r''' + ... >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... ValueError: wrong message + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + (0, 1) + +But IGNORE_EXCEPTION_DETAIL does not allow a mismatch in the exception type: + + >>> def f(x): + ... r''' + ... >>> raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL + ... Traceback (most recent call last): + ... TypeError: wrong type + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 3, in f + Failed example: + raise ValueError, 'message' #doctest: +IGNORE_EXCEPTION_DETAIL + Expected: + Traceback (most recent call last): + TypeError: wrong type + Got: + Traceback (most recent call last): + ... + ValueError: message + (1, 1) + +If an exception is raised but not expected, then it is reported as an +unexpected exception: + + >>> def f(x): + ... r''' + ... >>> 1//0 + ... 0 + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 3, in f + Failed example: + 1//0 + Exception raised: + Traceback (most recent call last): + ... + ZeroDivisionError: integer division or modulo by zero + (1, 1) +""" + def optionflags(): r""" +Tests of `DocTestRunner`'s option flag handling. + +Several option flags can be used to customize the behavior of the test +runner. These are defined as module constants in doctest, and passed +to the DocTestRunner constructor (multiple constants should be or-ed +together). + +The DONT_ACCEPT_TRUE_FOR_1 flag disables matches between True/False +and 1/0: + + >>> def f(x): + ... '>>> True\n1\n' + + >>> # Without the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + (0, 1) + + >>> # With the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.DONT_ACCEPT_TRUE_FOR_1 + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 2, in f + Failed example: + True + Expected: + 1 + Got: + True + (1, 1) + +The DONT_ACCEPT_BLANKLINE flag disables the match between blank lines +and the '<BLANKLINE>' marker: + + >>> def f(x): + ... '>>> print "a\\n\\nb"\na\n<BLANKLINE>\nb\n' + + >>> # Without the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + (0, 1) + + >>> # With the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.DONT_ACCEPT_BLANKLINE + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 2, in f + Failed example: + print "a\n\nb" + Expected: + a + <BLANKLINE> + b + Got: + a + <BLANKLINE> + b + (1, 1) + +The NORMALIZE_WHITESPACE flag causes all sequences of whitespace to be +treated as equal: + + >>> def f(x): + ... '>>> print 1, 2, 3\n 1 2\n 3' + + >>> # Without the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 2, in f + Failed example: + print 1, 2, 3 + Expected: + 1 2 + 3 + Got: + 1 2 3 + (1, 1) + + >>> # With the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.NORMALIZE_WHITESPACE + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + (0, 1) + + An example from the docs: + >>> print range(20) #doctest: +NORMALIZE_WHITESPACE + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] + +The ELLIPSIS flag causes ellipsis marker ("...") in the expected +output to match any substring in the actual output: + + >>> def f(x): + ... '>>> print range(15)\n[0, 1, 2, ..., 14]\n' + + >>> # Without the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 2, in f + Failed example: + print range(15) + Expected: + [0, 1, 2, ..., 14] + Got: + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] + (1, 1) + + >>> # With the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.ELLIPSIS + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + (0, 1) + + ... also matches nothing: + + >>> for i in range(100): + ... print i**2, #doctest: +ELLIPSIS + 0 1...4...9 16 ... 36 49 64 ... 9801 + + ... can be surprising; e.g., this test passes: + + >>> for i in range(21): #doctest: +ELLIPSIS + ... print i, + 0 1 2 ...1...2...0 + + Examples from the docs: + + >>> print range(20) # doctest:+ELLIPSIS + [0, 1, ..., 18, 19] + + >>> print range(20) # doctest: +ELLIPSIS + ... # doctest: +NORMALIZE_WHITESPACE + [0, 1, ..., 18, 19] + +The SKIP flag causes an example to be skipped entirely. I.e., the +example is not run. It can be useful in contexts where doctest +examples serve as both documentation and test cases, and an example +should be included for documentation purposes, but should not be +checked (e.g., because its output is random, or depends on resources +which would be unavailable.) The SKIP flag can also be used for +'commenting out' broken examples. + + >>> import unavailable_resource # doctest: +SKIP + >>> unavailable_resource.do_something() # doctest: +SKIP + >>> unavailable_resource.blow_up() # doctest: +SKIP + Traceback (most recent call last): + ... + UncheckedBlowUpError: Nobody checks me. + + >>> import random + >>> print random.random() # doctest: +SKIP + 0.721216923889 + +The REPORT_UDIFF flag causes failures that involve multi-line expected +and actual outputs to be displayed using a unified diff: + + >>> def f(x): + ... r''' + ... >>> print '\n'.join('abcdefg') + ... a + ... B + ... c + ... d + ... f + ... g + ... h + ... ''' + + >>> # Without the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 3, in f + Failed example: + print '\n'.join('abcdefg') + Expected: + a + B + c + d + f + g + h + Got: + a + b + c + d + e + f + g + (1, 1) + + >>> # With the flag: + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.REPORT_UDIFF + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 3, in f + Failed example: + print '\n'.join('abcdefg') + Differences (unified diff with -expected +actual): + @@ -1,7 +1,7 @@ + a + -B + +b + c + d + +e + f + g + -h + (1, 1) + +The REPORT_CDIFF flag causes failures that involve multi-line expected +and actual outputs to be displayed using a context diff: + + >>> # Reuse f() from the REPORT_UDIFF example, above. + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.REPORT_CDIFF + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 3, in f + Failed example: + print '\n'.join('abcdefg') + Differences (context diff with expected followed by actual): + *************** + *** 1,7 **** + a + ! B + c + d + f + g + - h + --- 1,7 ---- + a + ! b + c + d + + e + f + g + (1, 1) + + +The REPORT_NDIFF flag causes failures to use the difflib.Differ algorithm +used by the popular ndiff.py utility. This does intraline difference +marking, as well as interline differences. + + >>> def f(x): + ... r''' + ... >>> print "a b c d e f g h i j k l m" + ... a b c d e f g h i j k 1 m + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.REPORT_NDIFF + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 3, in f + Failed example: + print "a b c d e f g h i j k l m" + Differences (ndiff with -expected +actual): + - a b c d e f g h i j k 1 m + ? ^ + + a b c d e f g h i j k l m + ? + ++ ^ + (1, 1) + +The REPORT_ONLY_FIRST_FAILURE supresses result output after the first +failing example: + + >>> def f(x): + ... r''' + ... >>> print 1 # first success + ... 1 + ... >>> print 2 # first failure + ... 200 + ... >>> print 3 # second failure + ... 300 + ... >>> print 4 # second success + ... 4 + ... >>> print 5 # third failure + ... 500 + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.REPORT_ONLY_FIRST_FAILURE + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 5, in f + Failed example: + print 2 # first failure + Expected: + 200 + Got: + 2 + (3, 5) + +However, output from `report_start` is not supressed: + + >>> doctest.DocTestRunner(verbose=True, optionflags=flags).run(test) + ... # doctest: +ELLIPSIS + Trying: + print 1 # first success + Expecting: + 1 + ok + Trying: + print 2 # first failure + Expecting: + 200 + ********************************************************************** + File ..., line 5, in f + Failed example: + print 2 # first failure + Expected: + 200 + Got: + 2 + (3, 5) + +For the purposes of REPORT_ONLY_FIRST_FAILURE, unexpected exceptions +count as failures: + + >>> def f(x): + ... r''' + ... >>> print 1 # first success + ... 1 + ... >>> raise ValueError(2) # first failure + ... 200 + ... >>> print 3 # second failure + ... 300 + ... >>> print 4 # second success + ... 4 + ... >>> print 5 # third failure + ... 500 + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> flags = doctest.REPORT_ONLY_FIRST_FAILURE + >>> doctest.DocTestRunner(verbose=False, optionflags=flags).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 5, in f + Failed example: + raise ValueError(2) # first failure + Exception raised: + ... + ValueError: 2 + (3, 5) + +New option flags can also be registered, via register_optionflag(). Here +we reach into doctest's internals a bit. + + >>> unlikely = "UNLIKELY_OPTION_NAME" + >>> unlikely in doctest.OPTIONFLAGS_BY_NAME + False + >>> new_flag_value = doctest.register_optionflag(unlikely) + >>> unlikely in doctest.OPTIONFLAGS_BY_NAME + True + +Before 2.4.4/2.5, registering a name more than once erroneously created +more than one flag value. Here we verify that's fixed: + + >>> redundant_flag_value = doctest.register_optionflag(unlikely) + >>> redundant_flag_value == new_flag_value + True + +Clean up. + >>> del doctest.OPTIONFLAGS_BY_NAME[unlikely] + + """ + + def option_directives(): r""" +Tests of `DocTestRunner`'s option directive mechanism. + +Option directives can be used to turn option flags on or off for a +single example. To turn an option on for an example, follow that +example with a comment of the form ``# doctest: +OPTION``: + + >>> def f(x): r''' + ... >>> print range(10) # should fail: no ellipsis + ... [0, 1, ..., 9] + ... + ... >>> print range(10) # doctest: +ELLIPSIS + ... [0, 1, ..., 9] + ... ''' + >>> test = doctest.DocTestFinder().find(f)[0] + >>> doctest.DocTestRunner(verbose=False).run(test) + ... # doctest: +ELLIPSIS + ********************************************************************** + File ..., line 2, in f + Failed example: + print range(10) # should fail: no ellipsis + Expected: + [0, 1, ..., 9] + Got: + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + (1, 2) + +To turn an option off for an example, follow that example with a +comment of the form ``# doctest: -OPTION``: + + >>> def f(x): r''' + ... >>> print range(10) + ... [0, 1, ..., 9] + ... + ... >>> # should fail: ... [truncated message content] |
From: <fwi...@us...> - 2009-01-07 23:59:35
|
Revision: 5872 http://jython.svn.sourceforge.net/jython/?rev=5872&view=rev Author: fwierzbicki Date: 2009-01-07 23:59:24 +0000 (Wed, 07 Jan 2009) Log Message: ----------- Initialized merge tracking via "svnmerge" with revisions "1-5840" from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython Property Changed: ---------------- branches/jy3k/ Property changes on: branches/jy3k ___________________________________________________________________ Added: svnmerge-integrated + /trunk/jython:1-5840 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |