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: <cg...@us...> - 2009-06-22 08:43:10
|
Revision: 6493 http://jython.svn.sourceforge.net/jython/?rev=6493&view=rev Author: cgroves Date: 2009-06-22 08:43:07 +0000 (Mon, 22 Jun 2009) Log Message: ----------- Windows line endings to unix, tabs to spaces, unused import removal, and general coding standard conformity. Modified Paths: -------------- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java trunk/jython/tests/modjy/build.xml trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestContentHeaders.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestEnviron.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestHeaders.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestReturnIterable.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestWSGIStreams.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestWebInf.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestWriteCallable.java Modified: trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java =================================================================== --- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,193 +1,201 @@ -/*### -# -# Copyright Alan Kennedy. -# -# You may contact the copyright holder at this uri: -# -# http://www.xhaus.com/contact/modjy -# -# The licence under which this code is released is the Apache License v2.0. -# -# The terms and conditions of this license are listed in a file contained -# in the distribution that also contained this file, under the name -# LICENSE.txt. -# -# You may also read a copy of the license at the following web address. -# -# http://modjy.xhaus.com/LICENSE.txt -# -###*/ - -package com.xhaus.modjy; - -import java.io.*; -import java.util.*; -import javax.servlet.*; -import javax.servlet.http.*; -import org.python.core.*; -import org.python.util.*; - -public class ModjyJServlet extends HttpServlet -{ - - protected final static String MODJY_PYTHON_CLASSNAME = "modjy_servlet"; - protected final static String LIB_PYTHON = "/WEB-INF/lib-python"; - protected final static String PTH_FILE_EXTENSION = ".pth"; - - protected PythonInterpreter interp; - protected HttpServlet modjyServlet; - - /** - * Read configuration - * 1. Both context and servlet parameters are included in the set, - * so that the definition of some parameters (e.g python.*) can be shared - * between multiple WSGI servlets. - * 2. servlet params take precedence over context parameters - */ - - protected Properties readConfiguration ( ) - { - Properties props = new Properties(); - // Context parameters - ServletContext context = getServletContext(); - Enumeration e = context.getInitParameterNames(); - while (e.hasMoreElements()) - { - String name = (String) e.nextElement(); - props.put(name, context.getInitParameter(name)); - } - // Servlet parameters override context parameters - e = getInitParameterNames(); - while (e.hasMoreElements()) - { - String name = (String) e.nextElement(); - props.put(name, getInitParameter(name)); - } - return props; - } - - /** - * Initialise the modjy servlet. - * 1. Read the configuration - * 2. Initialise the jython runtime - * 3. Setup, in relation to the J2EE servlet environment - * 4. Create the jython-implemented servlet - * 5. Initialise the jython-implemented servlet - */ - - public void init ( ) - throws ServletException - { - try - { - Properties props = readConfiguration(); - PythonInterpreter.initialize(System.getProperties(), props, new String[0]); - PySystemState systemState = new PySystemState(); - interp = new PythonInterpreter(null, systemState); - setupEnvironment(interp, props, systemState); - try - { interp.exec("from modjy.modjy import "+MODJY_PYTHON_CLASSNAME); } - catch (PyException ix) - { throw new ServletException("Unable to import '"+MODJY_PYTHON_CLASSNAME+ - "': maybe you need to set the 'python.home' parameter?", ix);} - PyObject pyServlet = ((PyType)interp.get(MODJY_PYTHON_CLASSNAME)).__call__(); - Object temp = pyServlet.__tojava__(HttpServlet.class); - if (temp == Py.NoConversion) - throw new ServletException("Corrupted modjy file: cannot find definition of '"+MODJY_PYTHON_CLASSNAME+"' class"); - modjyServlet = (HttpServlet) temp; - modjyServlet.init(this); - } - catch (PyException pyx) - { - throw new ServletException("Exception creating modjy servlet: " + pyx.toString(), pyx); - } - } - - /** - * Actually service the incoming request. - * Simply delegate to the jython servlet. - * - * @param request - The incoming HttpServletRequest - * @param response - The outgoing HttpServletResponse - */ - - public void service ( HttpServletRequest req, HttpServletResponse resp ) - throws ServletException, IOException - { - modjyServlet.service(req, resp); - } - - /** - * Setup the modjy environment, i.e. - * 1. Find the location of the modjy.jar file and add it to sys.path - * 2. Process the WEB-INF/lib-python directory, if it exists - * - * @param interp - The PythinInterpreter used to service requests - * @param props - The properties from which config options are found - * @param systemState - The PySystemState corresponding to the interpreter servicing requests - * @returns A String giving the path to the modjy.jar file (which is used only for error reporting) - */ - - protected void setupEnvironment(PythonInterpreter interp, Properties props, PySystemState systemState) - { - processPythonLib(interp, systemState); - } - - /** - * Do all processing in relation to the lib-python subdirectory of WEB-INF - * - * @param interp - The PythinInterpreter used to service requests - * @param systemState - The PySystemState whose path should be updated - */ - - protected void processPythonLib(PythonInterpreter interp, PySystemState systemState) - { - // Add the lib-python directory to sys.path - String pythonLibPath = getServletContext().getRealPath(LIB_PYTHON); - if (pythonLibPath == null) - return; - File pythonLib = new File(pythonLibPath); - if (!pythonLib.exists()) - return; - systemState.path.append(new PyString(pythonLibPath)); - // Now check for .pth files in lib-python and process each one - String[] libPythonContents = pythonLib.list(); - for (int ix = 0 ; ix < libPythonContents.length ; ix++) - if (libPythonContents[ix].endsWith(PTH_FILE_EXTENSION)) - processPthFile(interp, systemState, pythonLibPath, libPythonContents[ix]); - } - - /** - * Process an individual file .pth file in the lib-python directory - * - * @param systemState - The PySystemState whose path should be updated - * @param pythonLibPath - The actual path to the lib-python directory - * @param pthFilename - The PySystemState whose path should be updated - */ - - protected void processPthFile(PythonInterpreter interp, PySystemState systemState, String pythonLibPath, String pthFilename) - { - try - { - LineNumberReader lineReader = new LineNumberReader(new FileReader(new File(pythonLibPath, pthFilename))); - String line; - while ((line = lineReader.readLine()) != null) - { - line = line.trim(); - if (line.length() == 0) - continue; - if (line.startsWith("#")) - continue; - if (line.startsWith("import")) - interp.exec(line); - File archiveFile = new File(pythonLibPath, line); - String archiveRealpath = archiveFile.getAbsolutePath(); - systemState.path.append(new PyString(archiveRealpath)); - } - } - catch (IOException iox) - { - System.err.println("IOException: " + iox.toString()); - } - } -} +/*### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +###*/ + +package com.xhaus.modjy; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.LineNumberReader; +import java.util.Enumeration; +import java.util.Properties; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.python.core.Py; +import org.python.core.PyException; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PySystemState; +import org.python.core.PyType; +import org.python.util.PythonInterpreter; + +public class ModjyJServlet extends HttpServlet { + + protected final static String MODJY_PYTHON_CLASSNAME = "modjy_servlet"; + + protected final static String LIB_PYTHON = "/WEB-INF/lib-python"; + + protected final static String PTH_FILE_EXTENSION = ".pth"; + + protected PythonInterpreter interp; + + protected HttpServlet modjyServlet; + + /** + * Read configuration 1. Both context and servlet parameters are included in the set, so that + * the definition of some parameters (e.g python.*) can be shared between multiple WSGI + * servlets. 2. servlet params take precedence over context parameters + */ + protected Properties readConfiguration() { + Properties props = new Properties(); + // Context parameters + ServletContext context = getServletContext(); + Enumeration<?> e = context.getInitParameterNames(); + while (e.hasMoreElements()) { + String name = (String)e.nextElement(); + props.put(name, context.getInitParameter(name)); + } + // Servlet parameters override context parameters + e = getInitParameterNames(); + while (e.hasMoreElements()) { + String name = (String)e.nextElement(); + props.put(name, getInitParameter(name)); + } + return props; + } + + /** + * Initialise the modjy servlet. 1. Read the configuration 2. Initialise the jython runtime 3. + * Setup, in relation to the J2EE servlet environment 4. Create the jython-implemented servlet + * 5. Initialise the jython-implemented servlet + */ + @Override + public void init() throws ServletException { + try { + Properties props = readConfiguration(); + PythonInterpreter.initialize(System.getProperties(), props, new String[0]); + PySystemState systemState = new PySystemState(); + interp = new PythonInterpreter(null, systemState); + setupEnvironment(interp, props, systemState); + try { + interp.exec("from modjy.modjy import " + MODJY_PYTHON_CLASSNAME); + } catch (PyException ix) { + throw new ServletException("Unable to import '" + MODJY_PYTHON_CLASSNAME + + "': maybe you need to set the 'python.home' parameter?", ix); + } + PyObject pyServlet = ((PyType)interp.get(MODJY_PYTHON_CLASSNAME)).__call__(); + Object temp = pyServlet.__tojava__(HttpServlet.class); + if (temp == Py.NoConversion) + throw new ServletException("Corrupted modjy file: cannot find definition of '" + + MODJY_PYTHON_CLASSNAME + "' class"); + modjyServlet = (HttpServlet)temp; + modjyServlet.init(this); + } catch (PyException pyx) { + throw new ServletException("Exception creating modjy servlet: " + pyx.toString(), pyx); + } + } + + /** + * Actually service the incoming request. Simply delegate to the jython servlet. + * + * @param request + * - The incoming HttpServletRequest + * @param response + * - The outgoing HttpServletResponse + */ + @Override + public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, + IOException { + modjyServlet.service(req, resp); + } + + /** + * Setup the modjy environment, i.e. 1. Find the location of the modjy.jar file and add it to + * sys.path 2. Process the WEB-INF/lib-python directory, if it exists + * + * @param interp + * - The PythinInterpreter used to service requests + * @param props + * - The properties from which config options are found + * @param systemState + * - The PySystemState corresponding to the interpreter servicing requests + * @returns A String giving the path to the modjy.jar file (which is used only for error + * reporting) + */ + protected void setupEnvironment(PythonInterpreter interp, + Properties props, + PySystemState systemState) { + processPythonLib(interp, systemState); + } + + /** + * Do all processing in relation to the lib-python subdirectory of WEB-INF + * + * @param interp + * - The PythinInterpreter used to service requests + * @param systemState + * - The PySystemState whose path should be updated + */ + protected void processPythonLib(PythonInterpreter interp, PySystemState systemState) { + // Add the lib-python directory to sys.path + String pythonLibPath = getServletContext().getRealPath(LIB_PYTHON); + if (pythonLibPath == null) + return; + File pythonLib = new File(pythonLibPath); + if (!pythonLib.exists()) + return; + systemState.path.append(new PyString(pythonLibPath)); + // Now check for .pth files in lib-python and process each one + String[] libPythonContents = pythonLib.list(); + for (String libPythonContent : libPythonContents) + if (libPythonContent.endsWith(PTH_FILE_EXTENSION)) + processPthFile(interp, systemState, pythonLibPath, libPythonContent); + } + + /** + * Process an individual file .pth file in the lib-python directory + * + * @param systemState + * - The PySystemState whose path should be updated + * @param pythonLibPath + * - The actual path to the lib-python directory + * @param pthFilename + * - The PySystemState whose path should be updated + */ + protected void processPthFile(PythonInterpreter interp, + PySystemState systemState, + String pythonLibPath, + String pthFilename) { + try { + LineNumberReader lineReader = new LineNumberReader(new FileReader(new File(pythonLibPath, + pthFilename))); + String line; + while ((line = lineReader.readLine()) != null) { + line = line.trim(); + if (line.length() == 0) + continue; + if (line.startsWith("#")) + continue; + if (line.startsWith("import")) + interp.exec(line); + File archiveFile = new File(pythonLibPath, line); + String archiveRealpath = archiveFile.getAbsolutePath(); + systemState.path.append(new PyString(archiveRealpath)); + } + } catch (IOException iox) { + System.err.println("IOException: " + iox.toString()); + } + } +} Modified: trunk/jython/tests/modjy/build.xml =================================================================== --- trunk/jython/tests/modjy/build.xml 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/build.xml 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,103 +1,97 @@ -<project name="modjy" default="test"> - - <description>Modjy test build.xml</description> - - <!-- set global properties for this build --> - - <property name="test_src" location="java"/> - <property name="build" location="build"/> - - <!-- Import the environment --> - <property environment="env"/> - - <!-- Jython properties --> - - <property name="jython_home" location="${env.JYTHON_HOME}"/> - <property name="jython_jar" value="jython-dev.jar"/> - <property name="jython_jar_path" location="${jython_home}/${jython_jar}"/> - <property name="jython_cachedir" location="${jython_home}/cachedir"/> - <property name="mockrunner_home" location="${env.MOCKRUNNER_HOME}"/> - - <target name="init"> - <available property="jython_home.exists" file="${jython_home}" /> - <fail unless="jython_home.exists" message="jython_home, ${jython_home}, doesn't exist" /> - <available property="mockrunner_home.exists" file="${mockrunner_home}" /> - <fail unless="mockrunner_home.exists" message="mockrunner_home, ${mockrunner_home}, doesn't exist" /> - <!-- Create the build directory structure used by compile --> - <mkdir dir="${build}"/> - </target> - - <target name="clean" description="clean up" > - <!-- Delete the ${build} and ${dist} directory trees --> - <delete dir="${build}"/> - </target> - - <!-- Now testing related targets --> - - <target name="do_test" depends="init" description="Run unit tests against a single jdk/servlet combo"> - <echo message="Running tests against JDK ${jdk_version}, Servlet ${servlet_version}"/> - - <property name="mockrunner_home" value="${env.MOCKRUNNER_HOME}"/> - <property name="mockrunner_jar" location="${mockrunner_home}/jar"/> - <property name="mockrunner_lib" location="${mockrunner_home}/lib/jdk${jdk_version}/${servlet_version}"/> - - <path id="test.classpath"> - <pathelement path="${build}"/> - <pathelement path="${jython_jar_path}"/> - <fileset dir="${jython_home}/javalib" includes="**/*.jar"/> - <fileset dir="${mockrunner_jar}" includes="**/*.jar"/> - <fileset dir="${mockrunner_lib}" includes="**/*.jar"/> - </path> - - <javac - srcdir="${test_src}" - destdir="${build}" - classpathref="test.classpath" - debug="on" - /> - <java classname="com.xhaus.modjy.ModjyTestBase" dir="." fork="yes" - classpathref="test.classpath"> - <sysproperty key="JYTHON_HOME" value="${jython_home}"/> - <sysproperty key="python.cachedir.skip" value="true"/> - </java> - </target> - - <target name="test"> - <antcall target="do_test"> - <param name="jdk_version" value="1.5"/> - <param name="servlet_version" value="j2ee1.3"/> - </antcall> - </target> - - <target name="test_java_15" depends="clean"> - <antcall target="do_test"> - <param name="jdk_version" value="1.5"/> - <param name="servlet_version" value="j2ee1.3"/> - </antcall> - <antcall target="do_test"> - <param name="jdk_version" value="1.5"/> - <param name="servlet_version" value="j2ee1.4"/> - </antcall> - <antcall target="do_test"> - <param name="jdk_version" value="1.5"/> - <param name="servlet_version" value="jee5"/> - </antcall> - </target> - - <target name="test_java_16" depends="clean"> - <antcall target="do_test"> - <param name="jdk_version" value="1.6"/> - <param name="servlet_version" value="j2ee1.3"/> - </antcall> - <antcall target="do_test"> - <param name="jdk_version" value="1.6"/> - <param name="servlet_version" value="j2ee1.4"/> - </antcall> - <antcall target="do_test"> - <param name="jdk_version" value="1.6"/> - <param name="servlet_version" value="jee5"/> - </antcall> - </target> - -</project> - +<project name="modjy" default="test"> + + <description>Modjy test build.xml</description> + + <!-- set global properties for this build --> + + <property name="test_src" location="java" /> + <property name="build" location="build" /> + + <!-- Import the environment --> + <property environment="env" /> + + <!-- Jython properties --> + + <property name="jython_home" location="${env.JYTHON_HOME}" /> + <property name="jython_jar" value="jython-dev.jar" /> + <property name="jython_jar_path" location="${jython_home}/${jython_jar}" /> + <property name="jython_cachedir" location="${jython_home}/cachedir" /> + <property name="mockrunner_home" location="${env.MOCKRUNNER_HOME}" /> + + <target name="init"> + <available property="jython_home.exists" file="${jython_home}" /> + <fail unless="jython_home.exists" message="jython_home, ${jython_home}, doesn't exist" /> + <available property="mockrunner_home.exists" file="${mockrunner_home}" /> + <fail unless="mockrunner_home.exists" message="mockrunner_home, ${mockrunner_home}, doesn't exist" /> + <!-- Create the build directory structure used by compile --> + <mkdir dir="${build}" /> + </target> + + <target name="clean" description="clean up"> + <!-- Delete the ${build} and ${dist} directory trees --> + <delete dir="${build}" /> + </target> + + <!-- Now testing related targets --> + + <target name="do_test" depends="init" description="Run unit tests against a single jdk/servlet combo"> + <echo message="Running tests against JDK ${jdk_version}, Servlet ${servlet_version}" /> + + <property name="mockrunner_home" value="${env.MOCKRUNNER_HOME}" /> + <property name="mockrunner_jar" location="${mockrunner_home}/jar" /> + <property name="mockrunner_lib" location="${mockrunner_home}/lib/jdk${jdk_version}/${servlet_version}" /> + + <path id="test.classpath"> + <pathelement path="${build}" /> + <pathelement path="${jython_jar_path}" /> + <fileset dir="${jython_home}/javalib" includes="**/*.jar" /> + <fileset dir="${mockrunner_jar}" includes="**/*.jar" /> + <fileset dir="${mockrunner_lib}" includes="**/*.jar" /> + </path> + + <javac srcdir="${test_src}" destdir="${build}" classpathref="test.classpath" debug="on" /> + <java classname="com.xhaus.modjy.ModjyTestBase" dir="." fork="yes" classpathref="test.classpath"> + <sysproperty key="JYTHON_HOME" value="${jython_home}" /> + <sysproperty key="python.cachedir.skip" value="true" /> + </java> + </target> + + <target name="test"> + <antcall target="do_test"> + <param name="jdk_version" value="1.5" /> + <param name="servlet_version" value="j2ee1.3" /> + </antcall> + </target> + + <target name="test_java_15" depends="clean"> + <antcall target="do_test"> + <param name="jdk_version" value="1.5" /> + <param name="servlet_version" value="j2ee1.3" /> + </antcall> + <antcall target="do_test"> + <param name="jdk_version" value="1.5" /> + <param name="servlet_version" value="j2ee1.4" /> + </antcall> + <antcall target="do_test"> + <param name="jdk_version" value="1.5" /> + <param name="servlet_version" value="jee5" /> + </antcall> + </target> + + <target name="test_java_16" depends="clean"> + <antcall target="do_test"> + <param name="jdk_version" value="1.6" /> + <param name="servlet_version" value="j2ee1.3" /> + </antcall> + <antcall target="do_test"> + <param name="jdk_version" value="1.6" /> + <param name="servlet_version" value="j2ee1.4" /> + </antcall> + <antcall target="do_test"> + <param name="jdk_version" value="1.6" /> + <param name="servlet_version" value="jee5" /> + </antcall> + </target> + +</project> + Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,224 +1,186 @@ -/*### -# -# Copyright Alan Kennedy. -# -# You may contact the copyright holder at this uri: -# -# http://www.xhaus.com/contact/modjy -# -# The licence under which this code is released is the Apache License v2.0. -# -# The terms and conditions of this license are listed in a file contained -# in the distribution that also contained this file, under the name -# LICENSE.txt. -# -# You may also read a copy of the license at the following web address. -# -# http://modjy.xhaus.com/LICENSE.txt -# -###*/ - -package com.xhaus.modjy; - -import java.io.File; - -import org.python.core.PyDictionary; -import org.python.core.PyInteger; -import org.python.core.PyObject; -import org.python.core.PyString; -import org.python.core.PyTuple; - -public class ModjyTestAppInvocation extends ModjyTestBase -{ - - protected void appInvocationTestSetUp() - throws Exception - { - baseSetUp(); - setAppDir(""); - setAppFile(""); - setAppName(""); - setAppImportable(""); - } - - String[] importablepathElements = new String[] { - "mock_framework", - "web", - "handlers", - "wsgi_handlers", - }; - - public void testRelativeDirectory ( ) - throws Exception - { - baseSetUp(); - setRealPath("/test_apps_dir", "test_apps_dir"); - setAppDir("$/test_apps_dir"); - setAppFile("simple_app.py"); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("Hello World!", result); - } - - public String setupAppImport ( String appCallableName ) - throws Exception - { - StringBuffer filePathBuffer = new StringBuffer(); - StringBuffer importPath = new StringBuffer(); - for (int ix = 0 ; ix < importablepathElements.length ; ix++) - { - String resourcePath; - String filePath; - filePathBuffer.append(importablepathElements[ix]); - resourcePath = "/WEB-INF/"+LIB_PYTHON_DIR+"/"+filePathBuffer.toString(); - filePath = LIB_PYTHON_TEST_PATH+"/"+filePathBuffer.toString(); - setRealPath(resourcePath, filePath); - filePathBuffer.append("/"); - resourcePath = "/WEB-INF/"+LIB_PYTHON_DIR+"/"+filePathBuffer.toString()+"__init__.py"; - filePath = LIB_PYTHON_TEST_PATH+"/"+filePathBuffer.toString()+"__init__.py"; - setRealPath(resourcePath, filePath); - importPath.append(importablepathElements[ix]); - importPath.append("."); - } - importPath.append(appCallableName); - return importPath.toString(); - } - - public void testAppImportCallable ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerFunction"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("WSGIHandlerFunction called.", result); - } - - public void testAppImportBadInstantiable ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerClass"); - setAppImportable(importableName); - createServlet(); - doGet(); - assertEquals("Status code != 500: ServerError, =='"+getStatus()+"'", 500, getStatus()); - } - - public void testAppImportInstantiable ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerClass()"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("__call__ counter = 0", result); - } - - public void testAppImportInstantiableCached ( ) - throws Exception - { - appInvocationTestSetUp(); - setInitParameter("cache_callables", "1"); - String importableName = setupAppImport("WSGIHandlerClass()"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("__call__ counter = 0", result); - clearOutput(); - doGet(); - result = getOutput(); - assertEquals("__call__ counter = 1", result); - } - - public void testAppImportInstantiableNotCached ( ) - throws Exception - { - appInvocationTestSetUp(); - setInitParameter("cache_callables", "0"); - String importableName = setupAppImport("WSGIHandlerClass()"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("__call__ counter = 0", result); - clearOutput(); - doGet(); - result = getOutput(); - assertEquals("__call__ counter = 0", result); - } - - public void testAppImportInstantiableMethod ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("handler_fn counter = 0", result); - } - - public void testAppImportInstantiableBadMethod ( ) - throws Exception - { - appInvocationTestSetUp(); - String importableName = setupAppImport("WSGIHandlerClass().handler_fn.fn_attr"); - setAppImportable(importableName); - createServlet(); - doGet(); - assertEquals("Status code != 500: ServerError, =='"+getStatus()+"'", 500, getStatus()); - } - - public void testAppImportInstantiableMethodCached ( ) - throws Exception - { - appInvocationTestSetUp(); - setInitParameter("cache_callables", "1"); - String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("handler_fn counter = 0", result); - clearOutput(); - doGet(); - result = getOutput(); - assertEquals("handler_fn counter = 1", result); - } - - public void testAppImportInstantiableMethodNotCached ( ) - throws Exception - { - appInvocationTestSetUp(); - setInitParameter("cache_callables", "0"); - String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); - setAppImportable(importableName); - createServlet(); - doGet(); - String result = getOutput(); - assertEquals("handler_fn counter = 0", result); - clearOutput(); - doGet(); - result = getOutput(); - assertEquals("handler_fn counter = 0", result); - } - - public void testBadAppImport() - throws Exception - { - appInvocationTestSetUp(); - setAppImportable("never.existed"); - createServlet(); - doGet(); - assertEquals("Status code != 500: ServerError, =='"+getStatus()+"'", 500, getStatus()); - } - -} +/*### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +###*/ + +package com.xhaus.modjy; + +public class ModjyTestAppInvocation extends ModjyTestBase { + + protected void appInvocationTestSetUp() throws Exception { + baseSetUp(); + setAppDir(""); + setAppFile(""); + setAppName(""); + setAppImportable(""); + } + + String[] importablepathElements = new String[] {"mock_framework", + "web", + "handlers", + "wsgi_handlers",}; + + public void testRelativeDirectory() throws Exception { + baseSetUp(); + setRealPath("/test_apps_dir", "test_apps_dir"); + setAppDir("$/test_apps_dir"); + setAppFile("simple_app.py"); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("Hello World!", result); + } + + public String setupAppImport(String appCallableName) throws Exception { + StringBuffer filePathBuffer = new StringBuffer(); + StringBuffer importPath = new StringBuffer(); + for (String importablepathElement : importablepathElements) { + String resourcePath; + String filePath; + filePathBuffer.append(importablepathElement); + resourcePath = "/WEB-INF/" + LIB_PYTHON_DIR + "/" + filePathBuffer.toString(); + filePath = LIB_PYTHON_TEST_PATH + "/" + filePathBuffer.toString(); + setRealPath(resourcePath, filePath); + filePathBuffer.append("/"); + resourcePath = "/WEB-INF/" + LIB_PYTHON_DIR + "/" + filePathBuffer.toString() + + "__init__.py"; + filePath = LIB_PYTHON_TEST_PATH + "/" + filePathBuffer.toString() + "__init__.py"; + setRealPath(resourcePath, filePath); + importPath.append(importablepathElement); + importPath.append("."); + } + importPath.append(appCallableName); + return importPath.toString(); + } + + public void testAppImportCallable() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerFunction"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("WSGIHandlerFunction called.", result); + } + + public void testAppImportBadInstantiable() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerClass"); + setAppImportable(importableName); + createServlet(); + doGet(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } + + public void testAppImportInstantiable() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerClass()"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("__call__ counter = 0", result); + } + + public void testAppImportInstantiableCached() throws Exception { + appInvocationTestSetUp(); + setInitParameter("cache_callables", "1"); + String importableName = setupAppImport("WSGIHandlerClass()"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("__call__ counter = 0", result); + clearOutput(); + doGet(); + result = getOutput(); + assertEquals("__call__ counter = 1", result); + } + + public void testAppImportInstantiableNotCached() throws Exception { + appInvocationTestSetUp(); + setInitParameter("cache_callables", "0"); + String importableName = setupAppImport("WSGIHandlerClass()"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("__call__ counter = 0", result); + clearOutput(); + doGet(); + result = getOutput(); + assertEquals("__call__ counter = 0", result); + } + + public void testAppImportInstantiableMethod() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("handler_fn counter = 0", result); + } + + public void testAppImportInstantiableBadMethod() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerClass().handler_fn.fn_attr"); + setAppImportable(importableName); + createServlet(); + doGet(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } + + public void testAppImportInstantiableMethodCached() throws Exception { + appInvocationTestSetUp(); + setInitParameter("cache_callables", "1"); + String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("handler_fn counter = 0", result); + clearOutput(); + doGet(); + result = getOutput(); + assertEquals("handler_fn counter = 1", result); + } + + public void testAppImportInstantiableMethodNotCached() throws Exception { + appInvocationTestSetUp(); + setInitParameter("cache_callables", "0"); + String importableName = setupAppImport("WSGIHandlerClass().handler_fn"); + setAppImportable(importableName); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("handler_fn counter = 0", result); + clearOutput(); + doGet(); + result = getOutput(); + assertEquals("handler_fn counter = 0", result); + } + + public void testBadAppImport() throws Exception { + appInvocationTestSetUp(); + setAppImportable("never.existed"); + createServlet(); + doGet(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } +} Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,279 +1,247 @@ -/*### -# -# Copyright Alan Kennedy. -# -# You may contact the copyright holder at this uri: -# -# http://www.xhaus.com/contact/modjy -# -# The licence under which this code is released is the Apache License v2.0. -# -# The terms and conditions of this license are listed in a file contained -# in the distribution that also contained this file, under the name -# LICENSE.txt. -# -# You may also read a copy of the license at the following web address. -# -# http://modjy.xhaus.com/LICENSE.txt -# -###*/ - -package com.xhaus.modjy; - -import junit.framework.TestSuite; - -import org.jdom.output.XMLOutputter; -import org.python.core.PyObject; -import org.python.util.PyFilterTest; -import org.python.util.PyServletTest; -import org.python.util.PythonInterpreter; - -import com.mockrunner.mock.web.MockHttpServletRequest; -import com.mockrunner.mock.web.MockHttpServletResponse; -import com.mockrunner.mock.web.MockServletConfig; -import com.mockrunner.mock.web.MockServletContext; -import com.mockrunner.mock.web.WebMockObjectFactory; -import com.mockrunner.servlet.BasicServletTestCaseAdapter; - -/** - * - */ - -public class ModjyTestBase extends BasicServletTestCaseAdapter -{ - - final static String DEFAULT_APP_DIR = "test_apps_dir"; - final static String LIB_PYTHON_DIR = "lib-python"; - final static String LIB_PYTHON_TEST_PATH = "lib_python_folder"; - final static String DEFAULT_APP_FILE = "simple_app.py"; - final static String DEFAULT_APP_NAME = "simple_app"; - - public WebMockObjectFactory factory; - public MockServletConfig servletConfig; - public MockServletContext servletContext; - - public WebMockObjectFactory getFactory () - { - if (factory == null) - factory = getWebMockObjectFactory(); - return factory; - } - - public MockServletConfig getConfig () - { - if (servletConfig == null) - servletConfig = getFactory().getMockServletConfig(); - return servletConfig; - } - - public MockServletContext getContext () - { - if (servletContext == null) - servletContext = getFactory().getMockServletContext(); - return servletContext; - } - -// public void dumpContextRealPaths ( ) -// { -// Map pathMap = ((LoggingMockServletContext)getContext()).actualPaths; -// Iterator it = pathMap.keySet().iterator(); -// while (it.hasNext()) -// { -// String pathName = (String) it.next(); -// System.out.println("Path '"+pathName+"'-->'"+pathMap.get(pathName)+"'"); -// } -// } - - public void setInitParameter ( String name, String value ) - { - getConfig().setInitParameter(name, value); - } - - public void setRealPath ( String source, String target ) - { - getContext().setRealPath(source, target); - } - - public void addHeader(String headerName, String headerValue) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.addHeader(headerName, headerValue); - getFactory().addRequestWrapper(request); - } - - public void setBodyContent(String content) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setBodyContent(content); - getFactory().addRequestWrapper(request); - } - - public void setServletContextPath(String path) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setContextPath(path); - getFactory().addRequestWrapper(request); - } - - public void setServletPath(String path) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setServletPath(path); - getFactory().addRequestWrapper(request); - } - - public void setRequestURI(String uri) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setRequestURI(uri); - getFactory().addRequestWrapper(request); - } - - public void setScheme(String scheme) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setScheme(scheme); - getFactory().addRequestWrapper(request); - } - - public void setPathInfo(String pathInfo) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setPathInfo(pathInfo); - getFactory().addRequestWrapper(request); - } - - public void setQueryString(String qString) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setQueryString(qString); - getFactory().addRequestWrapper(request); - } - - public void setProtocol(String protocol) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setProtocol(protocol); - getFactory().addRequestWrapper(request); - } - - public void setServerName(String name) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - // Using setLocalName() here: See here for more: http://docs.sun.com/source/819-0077/J2EE.html - request.setLocalName(name); - getFactory().addRequestWrapper(request); - } - - public void setServerPort(int port) - { - MockHttpServletRequest request = (MockHttpServletRequest) getFactory().getWrappedRequest(); - request.setLocalPort(port); - getFactory().addRequestWrapper(request); - } - - public void setPythonHome(String app_dir) - { - setInitParameter("python.home", app_dir); - } - - public void setAppDir(String app_dir) - { - setInitParameter("app_directory", app_dir); - } - - public void setAppFile(String app_file) - { - setInitParameter("app_filename", app_file); - } - - public void setAppName(String app_name) - { - setInitParameter("app_callable_name", app_name); - } - - public void setAppImportable(String app_path) - { - setAppDir(""); - setAppFile(""); - setAppName(""); - setInitParameter("app_import_name", app_path); - } - - public MockHttpServletResponse getResponse() - { - MockHttpServletResponse response = (MockHttpServletResponse) getFactory().getWrappedResponse(); - return response; - } - - public int getStatus() - { - MockHttpServletResponse response = (MockHttpServletResponse) getFactory().getWrappedResponse(); - return response.getStatusCode(); - } - - protected void baseSetUp() - throws Exception - { - super.setUp(); - String jythonHome = System.getProperty("JYTHON_HOME"); - setRealPath(jythonHome, jythonHome); - setRealPath("/WEB-INF/"+LIB_PYTHON_DIR, LIB_PYTHON_TEST_PATH); - setRealPath("/WEB-INF/lib/modjy.jar", "../modjy.jar"); - setPythonHome(jythonHome); - setAppDir(DEFAULT_APP_DIR); - setAppFile(DEFAULT_APP_FILE); - setAppName(DEFAULT_APP_NAME); - setInitParameter("exc_handler", "testing"); -// dumpContextRealPaths(); - } - - protected PyObject evalPythonString(String pyString) - { - // Efficiency be damned: it's a testing phase - PythonInterpreter interp = new PythonInterpreter(); - try - { - return interp.eval(pyString); - } - catch (Exception x) - { - System.err.println("Exception evaling '"+pyString+"': " + x); - return null; - } - } - - protected void createServlet() - { - createServlet(ModjyJServlet.class); - // Set zero content: this can be overridden later - setBodyContent(""); - clearOutput(); - } - - // Leave this here as a simple template for a test - public void testHelloWorld() throws Exception - { - baseSetUp(); - createServlet(); - doGet(); - new XMLOutputter().outputString(getOutputAsJDOMDocument()); - } - - public static void main(String args[]) - { - TestSuite suite = new TestSuite(); - suite.addTestSuite(ModjyTestBase.class); - suite.addTestSuite(ModjyTestAppInvocation.class); - suite.addTestSuite(ModjyTestEnviron.class); - suite.addTestSuite(ModjyTestHeaders.class); - suite.addTestSuite(ModjyTestContentHeaders.class); - suite.addTestSuite(ModjyTestReturnIterable.class); - suite.addTestSuite(ModjyTestWebInf.class); - suite.addTestSuite(ModjyTestWSGIStreams.class); - suite.addTestSuite(PyServletTest.class); - suite.addTestSuite(PyFilterTest.class); - junit.textui.TestRunner.run(suite); - } - -} +/*### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +###*/ + +package com.xhaus.modjy; + +import junit.framework.TestSuite; + +import org.jdom.output.XMLOutputter; +import org.python.core.PyObject; +import org.python.util.PyFilterTest; +import org.python.util.PyServletTest; +import org.python.util.PythonInterpreter; + +import com.mockrunner.mock.web.MockHttpServletRequest; +import com.mockrunner.mock.web.MockHttpServletResponse; +import com.mockrunner.mock.web.MockServletConfig; +import com.mockrunner.mock.web.MockServletContext; +import com.mockrunner.mock.web.WebMockObjectFactory; +import com.mockrunner.servlet.BasicServletTestCaseAdapter; + +public class ModjyTestBase extends BasicServletTestCaseAdapter { + + final static String DEFAULT_APP_DIR = "test_apps_dir"; + + final static String LIB_PYTHON_DIR = "lib-python"; + + final static String LIB_PYTHON_TEST_PATH = "lib_python_folder"; + + final static String DEFAULT_APP_FILE = "simple_app.py"; + + final static String DEFAULT_APP_NAME = "simple_app"; + + public WebMockObjectFactory factory; + + public MockServletConfig servletConfig; + + public MockServletContext servletContext; + + public WebMockObjectFactory getFactory() { + if (factory == null) + factory = getWebMockObjectFactory(); + return factory; + } + + public MockServletConfig getConfig() { + if (servletConfig == null) + servletConfig = getFactory().getMockServletConfig(); + return servletConfig; + } + + public MockServletContext getContext() { + if (servletContext == null) + servletContext = getFactory().getMockServletContext(); + return servletContext; + } + +// public void dumpContextRealPaths ( ) +// { +// Map pathMap = ((LoggingMockServletContext)getContext()).actualPaths; +// Iterator it = pathMap.keySet().iterator(); +// while (it.hasNext()) +// { +// String pathName = (String) it.next(); +// System.out.println("Path '"+pathName+"'-->'"+pathMap.get(pathName)+"'"); +// } +// } + public void setInitParameter(String name, String value) { + getConfig().setInitParameter(name, value); + } + + public void setRealPath(String source, String target) { + getContext().setRealPath(source, target); + } + + public void addHeader(String headerName, String headerValue) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.addHeader(headerName, headerValue); + getFactory().addRequestWrapper(request); + } + + public void setBodyContent(String content) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setBodyContent(content); + getFactory().addRequestWrapper(request); + } + + public void setServletContextPath(String path) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setContextPath(path); + getFactory().addRequestWrapper(request); + } + + public void setServletPath(String path) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setServletPath(path); + getFactory().addRequestWrapper(request); + } + + public void setRequestURI(String uri) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setRequestURI(uri); + getFactory().addRequestWrapper(request); + } + + public void setScheme(String scheme) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setScheme(scheme); + getFactory().addRequestWrapper(request); + } + + public void setPathInfo(String pathInfo) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setPathInfo(pathInfo); + getFactory().addRequestWrapper(request); + } + + public void setQueryString(String qString) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setQueryString(qString); + getFactory().addRequestWrapper(request); + } + + public void setProtocol(String protocol) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setProtocol(protocol); + getFactory().addRequestWrapper(request); + } + + public void setServerName(String name) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + // Using setLocalName() here: See here for more: + // http://docs.sun.com/source/819-0077/J2EE.html + request.setLocalName(name); + getFactory().addRequestWrapper(request); + } + + public void setServerPort(int port) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setLocalPort(port); + getFactory().addRequestWrapper(request); + } + + public void setPythonHome(String app_dir) { + setInitParameter("python.home", app_dir); + } + + public void setAppDir(String app_dir) { + setInitParameter("app_directory", app_dir); + } + + public void setAppFile(String app_file) { + setInitParameter("app_filename", app_file); + } + + public void setAppName(String app_name) { + setInitParameter("app_callable_name", app_name); + } + + public void setAppImportable(String app_path) { + setAppDir(""); + setAppFile(""); + setAppName(""); + setInitParameter("app_import_name", app_path); + } + + public MockHttpServletResponse getResponse() { + MockHttpServletResponse response = (MockHttpServletResponse)getFactory().getWrappedResponse(); + return response; + } + + public int getStatus() { + MockHttpServletResponse response = (MockHttpServletResponse)getFactory().getWrappedResponse(); + return response.getStatusCode(); + } + + protected void baseSetUp() throws Exception { + super.setUp(); + String jythonHome = System.getProperty("JYTHON_HOME"); + setRealPath(jythonHome, jythonHome); + setRealPath("/WEB-INF/" + LIB_PYTHON_DIR, LIB_PYTHON_TEST_PATH); + setRealPath("/WEB-INF/lib/modjy.jar", "../modjy.jar"); + setPythonHome(jythonHome); + setAppDir(DEFAULT_APP_DIR); + setAppFile(DEFAULT_APP_FILE); + setAppName(DEFAULT_APP_NAME); + setInitParameter("exc_handler", "testing"); +// dumpContextRealPaths(); + } + + protected PyObject evalPythonString(String pyString) { + // Efficiency be damned: it's a testing phase + PythonInterpreter interp = new PythonInterpreter(); + try { + return interp.eval(pyString); + } catch (Exception x) { + System.err.println("Exception evaling '" + pyString + "': " + x); + return null; + } + } + + protected void createServlet() { + createServlet(ModjyJServlet.class); + // Set zero content: this can be overridden later + setBodyContent(""); + clearOutput(); + } + + // Leave this here as a simple template for a test + public void testHelloWorld() throws Exception { + baseSetUp(); + createServlet(); + doGet(); + new XMLOutputter().outputString(getOutputAsJDOMDocument()); + } + + public static void main(String args[]) { + TestSuite suite = new TestSuite(); + suite.addTestSuite(ModjyTestBase.class); + suite.addTestSuite(ModjyTestAppInvocation.class); + suite.addTestSuite(ModjyTestEnviron.class); + suite.addTestSuite(ModjyTestHeaders.class); + suite.addTestSuite(ModjyTestContentHeaders.class); + suite.addTestSuite(ModjyTestReturnIterable.class); + suite.addTestSuite(ModjyTestWebInf.class); + suite.addTestSuite(ModjyTestWSGIStreams.class); + suite.addTestSuite(PyServletTest.class); + suite.addTestSuite(PyFilterTest.class); + junit.textui.TestRunner.run(suite); + } +} Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestContentHeaders.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestContentHeaders.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestContentHeaders.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,81 +1,65 @@ /*### # -# Copyright Alan Kennedy. -# +# Copyright Alan Kennedy. +# # You may contact the copyright holder at this uri: -# +# # http://www.xhaus.com/contact/modjy -# +# # The licence under which this code is released is the Apache License v2.0. -# +# # The terms and conditions of this license are listed in a file contained # in the distribution that also contained this file, under the name # LICENSE.txt. -# +# # You may also read a copy of the license at the following web address. -# +# # http://modjy.xhaus.com/LICENSE.txt # ###*/ package com.xhaus.modjy; -import com.mockrunner.base.NestedApplicationException; -import org.python.core.PyException; +public class ModjyTestContentHeaders extends ModjyTestBase { -public class ModjyTestContentHeaders extends ModjyTestBase -{ + // From: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 + protected void contentHeaderTestSetUp() throws Exception { + baseSetUp(); + setAppFile("content_header_tests.py"); + } - // From: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 + public void doHeaderTest(String appName, String queryString) throws Exception { + contentHeaderTestSetUp(); + setAppName(appName); + createServlet(); + if (queryString != null) + setQueryString(queryString); + doGet(); + } - protected void contentHeaderTestSetUp() - throws Exception - { - baseSetUp(); - setAppFile("content_header_tests.py"); - } + public void doHeaderTest(String appName) throws Exception { + doHeaderTest(appName, null); + } - public void doHeaderTest(String appName, String queryString) - throws Exception - { - contentHeaderTestSetUp(); - setAppName(appName); - createServlet(); - if (queryString != null) - setQueryString(queryString); - doGet(); - } + public void testSetContentLengthHeader() throws Exception { + doHeaderTest("test_set_content_length"); + assertEquals("Status code != 200: ServerError, =='" + getStatus() + "'", 200, getStatus()); + } - public void doHeaderTest(String appName) - throws Exception - { - doHeaderTest(appName, null); - } + public void testSetBadContentLengthHeader() throws Exception { + doHeaderTest("test_set_bad_content_length"); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + assertTrue("Could not find exception 'BadArgument' in output", + getOutput().indexOf("BadArgument") != -1); + } - public void testSetContentLengthHeader ( ) - throws Exception - { - doHeaderTest("test_set_content_length"); - assertEquals("Status code != 200: ServerError, =='"+getStatus()+"'", 200, getStatus()); - } - - public void testSetBadContentLengthHeader ( ) - throws Exception - { - doHeaderTest("test_set_bad_content_length"); - assertEquals("Status code != 500: ServerError, =='"+getStatus()+"'", 500, getStatus()); - assertTrue("Could not find exception 'BadArgument' in output", - getOutput().indexOf("BadArgument")!=-1); - } - - public void testInferredContentLength ( ) - throws Exception - { - String appReturn = "Hello World!"; - doHeaderTest("test_inferred_content_length", appReturn); - assertEquals("Status code != 200: ServerError, =='"+getStatus()+"'", 200, getStatus()); - assertEquals("Content-length != '"+appReturn.length()+"', == '"+getResponse().getHeader("content-length")+"' ", - Integer.toString(appReturn.length()), getResponse().getHeader("content-length")); - } - + public void testInferredContentLength() throws Exception { + String appReturn = "Hello World!"; + doHeaderTest("test_inferred_content_length", appReturn); + assertEquals("Status code != 200: ServerError, =='" + getStatus() + "'", 200, getStatus()); + assertEquals("Content-length != '" + appReturn.length() + "', == '" + + getResponse().getHeader("content-length") + "' ", + Integer.toString(appReturn.length()), + getResponse().getHeader("content-length")); + } } Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestEnviron.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestEnviron.java 2009-06-22 08:27:10 UTC (rev 6492) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestEnviron.java 2009-06-22 08:43:07 UTC (rev 6493) @@ -1,328 +1,293 @@ -/*### -# -# Copyright Alan Kennedy. -# -# You may contact the copyright holder at this uri: -# -# http://www.xhaus.com/contact/modjy -# -# The licence under which this code is released is the Apache License v2.0. -# -# The terms and conditions of this license are listed in a file contained -# in the distribution that also contained this file, under the name -# LICENSE.txt. -# -# You may also read a copy of the license at the following web address. -# -# http://modjy.xhaus.com/LICENSE.txt -# -###*/ - -package com.xhaus.modjy; - -import org.python.core.PyDictionary; -import org.python.core.PyInteger; -import org.python.core.PyObject; -import org.python.core.PyString; -import org.python.core.PyTuple; - -public class ModjyTestEnviron extends ModjyTestBase -{ - - protected void environTestS... [truncated message content] |
From: <cg...@us...> - 2009-06-22 08:27:12
|
Revision: 6492 http://jython.svn.sourceforge.net/jython/?rev=6492&view=rev Author: cgroves Date: 2009-06-22 08:27:10 +0000 (Mon, 22 Jun 2009) Log Message: ----------- Add jfeinberg's PyFilter from #1859477. Still need to test this in an actual ServletContainer Modified Paths: -------------- trunk/jython/src/org/python/util/PyServlet.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java Added Paths: ----------- trunk/jython/Lib/test/pyservlet/filter.py trunk/jython/src/org/python/util/PyFilter.java trunk/jython/tests/modjy/java/org/python/util/PyFilterTest.java Added: trunk/jython/Lib/test/pyservlet/filter.py =================================================================== --- trunk/jython/Lib/test/pyservlet/filter.py (rev 0) +++ trunk/jython/Lib/test/pyservlet/filter.py 2009-06-22 08:27:10 UTC (rev 6492) @@ -0,0 +1,9 @@ +from javax.servlet import Filter + +class filter(Filter): + def init(self, config): + self.header = config.getInitParameter('header') + + def doFilter(self, req, resp, chain): + resp.setHeader(self.header, "Yup") + chain.doFilter(req, resp) Added: trunk/jython/src/org/python/util/PyFilter.java =================================================================== --- trunk/jython/src/org/python/util/PyFilter.java (rev 0) +++ trunk/jython/src/org/python/util/PyFilter.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -0,0 +1,158 @@ +package org.python.util; + +import java.io.File; +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import org.python.core.PyException; +import org.python.core.PySystemState; +import org.python.util.PythonInterpreter; + +/** + * Enables you to write Jython modules that inherit from <code>javax.servlet.Filter</code>, and to + * insert them in your servlet container's filter chain, like any Java <code>Filter</code>. + * + * <p> + * Example: + * + * <p> + * <b>/WEB-INF/filters/HeaderFilter.py:</b> + * + * <pre> + * from javax.servlet import Filter + * + * # Module must contain a class with the same name as the module + * # which in turn must implement javax.servlet.Filter + * class HeaderFilter (Filter): + * def init(self, config): + * self.header = config.getInitParameter('header') + * + * def doFilter(self, request, response, chain): + * response.setHeader(self.header, "Yup") + * chain.doFilter(request, response) + * </pre> + * + * <p> + * <b>web.xml:</b> + * </p> + * + * <pre> + * <!-- PyFilter depends on PyServlet --> + * <servlet> + * <servlet-name>PyServlet</servlet-name> + * <servlet-class>org.python.util.PyServlet</servlet-class> + * <load-on-startup>1</load-on-startup> + * </servlet> + * + * <!-- Declare a uniquely-named PyFilter --> + * <filter> + * <filter-name>HeaderFilter</filter-name> + * <filter-class>org.jython.util.PyFilter</filter-class> + * + * <!-- The special param __filter__ gives the context-relative path to the Jython source file --> + * <init-param> + * <param-name>__filter__</param-name> + * <param-value>/WEB-INF/pyfilter/HeaderFilter.py</param-value> + * </init-param> + * + * <!-- Other params are passed on the the Jython filter --> + * <init-param> + * <param-name>header</param-name> + * <param-value>X-LookMaNoJava</param-value> + * </init-param> + * </filter> + * <filter-mapping> + * <filter-name>HeaderFilter</filter-name> + * <url-pattern>/*</url-pattern> + * </filter-mapping> + * </pre> + * + * <p> + * PyFilter depends on initialization code from PyServlet being run. If PyServlet is used to serve + * pages, this code will be executed and PyFilter will work properly. However, if you aren't using + * PyServlet, the initialization code can be invoked as a ServletContextListener instead of as an + * HttpServlet. Use the following in web.xml instead of a servlet tag: + * + * <pre> + * <listener> + * <listener-class>org.python.util.PyServlet</listener-class> + * <load-on-startup>1</load-on-startup> + * </listener> + * </pre> + * + */ +public class PyFilter implements Filter { + public static final String FILTER_PATH_PARAM = "__filter__"; + + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + request.setAttribute("pyfilter", this); + getFilter().doFilter(request, response, chain); + } + + public void init(FilterConfig config) throws ServletException { + if (config.getServletContext().getAttribute(PyServlet.INIT_ATTR) == null) { + throw new ServletException("PyServlet has not been initialized, either as a servlet " + + "or as context listener. This must happen before PyFilter is initialized."); + } + this.config = config; + String filterPath = config.getInitParameter(FILTER_PATH_PARAM); + if (filterPath == null) { + throw new ServletException("Missing required param '" + FILTER_PATH_PARAM + "'"); + } + source = new File(getRealPath(config.getServletContext(), filterPath)); + if (!source.exists()) { + throw new ServletException(source.getAbsolutePath() + " does not exist."); + } + interp = new PythonInterpreter(null, new PySystemState()); + } + + private String getRealPath(ServletContext context, String appPath) { + String realPath = context.getRealPath(appPath); + // This madness seems to be necessary on Windows + return realPath.replaceAll("\\\\", "/"); + } + + private Filter getFilter() throws ServletException, IOException { + if (cached == null || source.lastModified() > loadedMtime) { + return loadFilter(); + } + return cached; + } + + private Filter loadFilter() throws ServletException, IOException { + loadedMtime = source.lastModified(); + cached = PyServlet.createInstance(interp, source, Filter.class); + try { + cached.init(config); + } catch (PyException e) { + throw new ServletException(e); + } + return cached; + } + + public void destroy() { + if (cached != null) { + cached.destroy(); + } + if (interp != null) { + interp.cleanup(); + } + } + + private PythonInterpreter interp; + + private FilterConfig config; + + private File source; + + private Filter cached; + + private long loadedMtime; +} Modified: trunk/jython/src/org/python/util/PyServlet.java =================================================================== --- trunk/jython/src/org/python/util/PyServlet.java 2009-06-22 06:48:53 UTC (rev 6491) +++ trunk/jython/src/org/python/util/PyServlet.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -5,8 +5,12 @@ import java.util.Enumeration; import java.util.Map; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -37,7 +41,6 @@ * print >>out, "</body>" * print >>out, "</html>" * out.close() - * return * </pre> * * in web.xml for the PyServlet context: @@ -59,47 +62,76 @@ * * </pre> */ -public class PyServlet extends HttpServlet { +public class PyServlet extends HttpServlet implements ServletContextListener { + + public static final String SKIP_INIT_NAME = "skip_jython_initialization"; + + protected static final String INIT_ATTR = "__jython_initialized__"; + + public void contextInitialized(ServletContextEvent event) { + init(new Properties(), event.getServletContext(), "a ServletContextListener", true); + } + + public void contextDestroyed(ServletContextEvent event) {} + @Override public void init() { - rootPath = getServletContext().getRealPath("/"); - if (!rootPath.endsWith(File.separator)) { - rootPath += File.separator; - } Properties props = new Properties(); - Properties baseProps = PySystemState.getBaseProperties(); - // Context parameters - ServletContext context = getServletContext(); - Enumeration<?> e = context.getInitParameterNames(); - while (e.hasMoreElements()) { - String name = (String)e.nextElement(); - props.put(name, context.getInitParameter(name)); - } - // Config parameters - e = getInitParameterNames(); + Enumeration<?> e = getInitParameterNames(); while (e.hasMoreElements()) { String name = (String)e.nextElement(); props.put(name, getInitParameter(name)); } - if (props.getProperty("python.home") == null - && baseProps.getProperty("python.home") == null) { - props.put("python.home", rootPath + "WEB-INF" + File.separator + "lib"); + init(props, getServletContext(), "the servlet " + getServletConfig().getServletName(), + getServletConfig().getInitParameter(SKIP_INIT_NAME) != null); + } + + /** + * PyServlet's initialization can be performed as a ServletContextListener or as a regular + * servlet, and this is the shared init code. If both initializations are used in a single + * context, the system state initialization code only runs once. + */ + private void init(Properties props, ServletContext context, String initializerName, + boolean initialize) { + rootPath = context.getRealPath("/"); + if (!rootPath.endsWith(File.separator)) { + rootPath += File.separator; } - - PySystemState.initialize(baseProps, props, new String[0]); + if (context.getAttribute(INIT_ATTR) != null) { + if (initialize) { + System.err.println("Jython has already been initialized by " + + context.getAttribute(INIT_ATTR) + + " in this context, not initializing for " + initializerName + ". Add " + + SKIP_INIT_NAME + + " to as an init param to this servlet's configuration to indicate this " + + "is expected."); + } + } else if (initialize) { + context.setAttribute(INIT_ATTR, initializerName); + Properties baseProps = PySystemState.getBaseProperties(); + // Context parameters + Enumeration<?> e = context.getInitParameterNames(); + while (e.hasMoreElements()) { + String name = (String)e.nextElement(); + props.put(name, context.getInitParameter(name)); + } + if (props.getProperty("python.home") == null + && baseProps.getProperty("python.home") == null) { + props.put("python.home", rootPath + "WEB-INF" + File.separator + "lib"); + } + PySystemState.initialize(baseProps, props, new String[0]); + PySystemState.add_package("javax.servlet"); + PySystemState.add_package("javax.servlet.http"); + PySystemState.add_package("javax.servlet.jsp"); + PySystemState.add_package("javax.servlet.jsp.tagext"); + PySystemState.add_classdir(rootPath + "WEB-INF" + File.separator + "classes"); + PySystemState.add_extdir(rootPath + "WEB-INF" + File.separator + "lib", true); + } reset(); + } - PySystemState.add_package("javax.servlet"); - PySystemState.add_package("javax.servlet.http"); - PySystemState.add_package("javax.servlet.jsp"); - PySystemState.add_package("javax.servlet.jsp.tagext"); - PySystemState.add_classdir(rootPath + "WEB-INF" + File.separator + "classes"); - - PySystemState.add_extdir(rootPath + "WEB-INF" + File.separator + "lib", true); - } - @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException @@ -154,40 +186,44 @@ { File file = new File(path); - // Extract servlet name from path (strip ".../" and ".py") - int start = path.lastIndexOf(File.separator); - if (start < 0) { - start = 0; - } else { - start++; + HttpServlet servlet = createInstance(interp, file, HttpServlet.class); + try { + servlet.init(getServletConfig()); + } catch (PyException e) { + throw new ServletException(e); } - int end = path.lastIndexOf('.'); - if (end < 0 || end <= start) { - end = path.length(); + cache.put(path, new CacheEntry(servlet, file.lastModified())); + return servlet; + } + + protected static <T> T createInstance(PythonInterpreter interp, File file, Class<T> type) + throws ServletException { + Matcher m = FIND_NAME.matcher(file.getName()); + if (!m.find()) { + throw new ServletException("I can't guess the name of the class from " + + file.getAbsolutePath()); } - String name = path.substring(start, end); - - HttpServlet servlet; + String name = m.group(1); try { - interp.set("__file__", path); - interp.execfile(path); + interp.set("__file__", file.getAbsolutePath()); + interp.execfile(file.getAbsolutePath()); PyObject cls = interp.get(name); if (cls == null) { throw new ServletException("No callable (class or function) named " + name + " in " - + path); + + file.getAbsolutePath()); } PyObject pyServlet = cls.__call__(); - Object o = pyServlet.__tojava__(HttpServlet.class); + Object o = pyServlet.__tojava__(type); if (o == Py.NoConversion) { - throw new ServletException("The value from " + name + " must extend HttpServlet"); + throw new ServletException("The value from " + name + " must extend " + + type.getSimpleName()); } - servlet = (HttpServlet)o; - servlet.init(getServletConfig()); + @SuppressWarnings("unchecked") + T asT = (T)o; + return asT; } catch (PyException e) { throw new ServletException(e); } - cache.put(path, new CacheEntry(servlet, file.lastModified())); - return servlet; } private void destroyCache() { @@ -207,6 +243,8 @@ } } + private static final Pattern FIND_NAME = Pattern.compile("([^/]+)\\.py$"); + private PythonInterpreter interp; private String rootPath; private Map<String, CacheEntry> cache = Generic.map(); Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 06:48:53 UTC (rev 6491) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -20,22 +20,20 @@ package com.xhaus.modjy; -import junit.framework.*; +import junit.framework.TestSuite; -import com.mockrunner.servlet.BasicServletTestCaseAdapter; -import com.mockrunner.mock.web.WebMockObjectFactory; -import com.mockrunner.mock.web.MockServletConfig; -import com.mockrunner.mock.web.MockServletContext; -import com.mockrunner.mock.web.MockHttpServletRequest; -import com.mockrunner.mock.web.MockHttpServletResponse; - import org.jdom.output.XMLOutputter; - import org.python.core.PyObject; +import org.python.util.PyFilterTest; import org.python.util.PyServletTest; import org.python.util.PythonInterpreter; -import com.xhaus.modjy.ModjyJServlet; +import com.mockrunner.mock.web.MockHttpServletRequest; +import com.mockrunner.mock.web.MockHttpServletResponse; +import com.mockrunner.mock.web.MockServletConfig; +import com.mockrunner.mock.web.MockServletContext; +import com.mockrunner.mock.web.WebMockObjectFactory; +import com.mockrunner.servlet.BasicServletTestCaseAdapter; /** * @@ -274,6 +272,7 @@ suite.addTestSuite(ModjyTestWebInf.class); suite.addTestSuite(ModjyTestWSGIStreams.class); suite.addTestSuite(PyServletTest.class); + suite.addTestSuite(PyFilterTest.class); junit.textui.TestRunner.run(suite); } Added: trunk/jython/tests/modjy/java/org/python/util/PyFilterTest.java =================================================================== --- trunk/jython/tests/modjy/java/org/python/util/PyFilterTest.java (rev 0) +++ trunk/jython/tests/modjy/java/org/python/util/PyFilterTest.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -0,0 +1,30 @@ +package org.python.util; + +import javax.servlet.http.HttpServletResponse; + +import com.mockrunner.mock.web.MockFilterConfig; + +public class PyFilterTest extends PyServletTest { + @Override + protected void setUp() throws Exception { + super.setUp(); + setDoChain(true); + } + + public void testFilter() { + getWebMockObjectFactory().getMockRequest().setServletPath(getTestPath("basic")); + doGet(); + assertFalse(((HttpServletResponse)getFilteredResponse()).containsHeader("X-LookMaNoJava")); + clearOutput(); + MockFilterConfig cfg = getWebMockObjectFactory().getMockFilterConfig(); + cfg.setInitParameter(PyFilter.FILTER_PATH_PARAM, getTestPath("filter")); + cfg.setInitParameter("header", "X-LookMaNoJava"); + // Set that PyServlet initialization has run as mockrunner's context doesn't indicate that + // it happened. + getWebMockObjectFactory().getMockServletContext().setAttribute(PyServlet.INIT_ATTR, "true"); + createFilter(PyFilter.class); + doGet(); + HttpServletResponse resp = (HttpServletResponse)getFilteredResponse(); + assertTrue(resp.containsHeader("X-LookMaNoJava")); + } +} Modified: trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java =================================================================== --- trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java 2009-06-22 06:48:53 UTC (rev 6491) +++ trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java 2009-06-22 08:27:10 UTC (rev 6492) @@ -47,7 +47,7 @@ createServlet(PyServlet.class); } - private String doGetAndRead(String testName) { + protected String doGetAndRead(String testName) { getWebMockObjectFactory().getMockRequest().setServletPath(getTestPath(testName)); doGet(); String result = getOutput(); @@ -55,7 +55,7 @@ return result; } - private String getTestPath(String testName) { + protected String getTestPath(String testName) { return "/test/pyservlet/" + testName + ".py"; } @@ -84,5 +84,5 @@ }; } - private String basePath = System.getProperty("JYTHON_HOME") + "/Lib"; + protected String basePath = System.getProperty("JYTHON_HOME") + "/Lib"; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-06-22 06:48:55
|
Revision: 6491 http://jython.svn.sourceforge.net/jython/?rev=6491&view=rev Author: cgroves Date: 2009-06-22 06:48:53 +0000 (Mon, 22 Jun 2009) Log Message: ----------- Coding conventions and modernization Modified Paths: -------------- trunk/jython/ACKNOWLEDGMENTS trunk/jython/src/org/python/util/PyServlet.java Modified: trunk/jython/ACKNOWLEDGMENTS =================================================================== --- trunk/jython/ACKNOWLEDGMENTS 2009-06-22 06:32:34 UTC (rev 6490) +++ trunk/jython/ACKNOWLEDGMENTS 2009-06-22 06:48:53 UTC (rev 6491) @@ -33,6 +33,8 @@ Alan Kennedy contributed modjy, which bridges WSGI to the Servlet API + Chris Gokey, David Syer and Finn Bock added PyServlet. + A huge thanks goes to all the members of the jpython/jython mailing lists. Other folks who have contributed to JPython and Jython in ways large and small, in no particular order: Modified: trunk/jython/src/org/python/util/PyServlet.java =================================================================== --- trunk/jython/src/org/python/util/PyServlet.java 2009-06-22 06:32:34 UTC (rev 6490) +++ trunk/jython/src/org/python/util/PyServlet.java 2009-06-22 06:48:53 UTC (rev 6491) @@ -1,27 +1,28 @@ - package org.python.util; -import java.io.*; -import java.util.*; -import javax.servlet.*; -import javax.servlet.http.*; -import org.python.core.*; +import java.io.File; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Map; +import java.util.Properties; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import org.python.core.Py; +import org.python.core.PyException; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PySystemState; + /** - * This servlet is used to re-serve Jython servlets. It stores - * bytecode for Jython servlets and re-uses it if the underlying .py - * file has not changed. + * This servlet is used to re-serve Jython servlets. It stores bytecode for Jython servlets and + * re-uses it if the underlying .py file has not changed. * <p> - * Many people have been involved with this class: - * <ul> - * <li>Chris Gokey - * <li>David Syer - * <li>Finn Bock - * </ul> - * If somebody is missing from this list, let us know. - * <p> - * * e.g. http://localhost:8080/test/hello.py * <pre> * @@ -58,40 +59,32 @@ * * </pre> */ - public class PyServlet extends HttpServlet { - private PythonInterpreter interp; - private Hashtable cache = new Hashtable(); - private String rootPath; - - + @Override public void init() { rootPath = getServletContext().getRealPath("/"); - if (!rootPath.endsWith(File.separator)) + if (!rootPath.endsWith(File.separator)) { rootPath += File.separator; - + } Properties props = new Properties(); Properties baseProps = PySystemState.getBaseProperties(); - // Context parameters ServletContext context = getServletContext(); - Enumeration e = context.getInitParameterNames(); + Enumeration<?> e = context.getInitParameterNames(); while (e.hasMoreElements()) { - String name = (String) e.nextElement(); + String name = (String)e.nextElement(); props.put(name, context.getInitParameter(name)); } // Config parameters e = getInitParameterNames(); while (e.hasMoreElements()) { - String name = (String) e.nextElement(); + String name = (String)e.nextElement(); props.put(name, getInitParameter(name)); } - - if(props.getProperty("python.home") == null + if (props.getProperty("python.home") == null && baseProps.getProperty("python.home") == null) { - props.put("python.home", rootPath + "WEB-INF" + - File.separator + "lib"); + props.put("python.home", rootPath + "WEB-INF" + File.separator + "lib"); } PySystemState.initialize(baseProps, props, new String[0]); @@ -107,13 +100,7 @@ PySystemState.add_extdir(rootPath + "WEB-INF" + File.separator + "lib", true); } - /** - * Implementation of the HttpServlet main method. - * @param req the request parameter. - * @param res the response parameter. - * @exception ServletException - * @exception IOException - */ + @Override public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { @@ -121,29 +108,30 @@ String spath = (String) req.getAttribute("javax.servlet.include.servlet_path"); if (spath == null) { - spath = ((HttpServletRequest) req).getServletPath(); + spath = ((HttpServletRequest)req).getServletPath(); if (spath == null || spath.length() == 0) { - // Servlet 2.1 puts the path of an extension-matched - // servlet in PathInfo. - spath = ((HttpServletRequest) req).getPathInfo(); + // Servlet 2.1 puts the path of an extension-matched servlet in PathInfo. + spath = ((HttpServletRequest)req).getPathInfo(); } } String rpath = getServletContext().getRealPath(spath); + getServlet(rpath).service(req, res); + } - interp.set("__file__", rpath); - - HttpServlet servlet = getServlet(rpath); - if (servlet != null) - servlet.service(req, res); - else - throw new ServletException("No python servlet found at:" + spath); + @Override + public void destroy() { + super.destroy(); + destroyCache(); } + /** + * Clears the cache of loaded servlets and makes a new PythonInterpreter to service further + * requests. + */ public void reset() { destroyCache(); interp = new PythonInterpreter(null, new PySystemState()); - cache.clear(); - + PySystemState sys = Py.getSystemState(); sys.path.append(new PyString(rootPath)); @@ -154,33 +142,34 @@ private synchronized HttpServlet getServlet(String path) throws ServletException, IOException { - CacheEntry entry = (CacheEntry) cache.get(path); - if (entry == null) + CacheEntry entry = cache.get(path); + if (entry == null || new File(path).lastModified() > entry.date) { return loadServlet(path); - File file = new File(path); - if (file.lastModified() > entry.date) - return loadServlet(path); + } return entry.servlet; } private HttpServlet loadServlet(String path) throws ServletException, IOException { - HttpServlet servlet = null; File file = new File(path); // Extract servlet name from path (strip ".../" and ".py") int start = path.lastIndexOf(File.separator); - if (start < 0) + if (start < 0) { start = 0; - else + } else { start++; + } int end = path.lastIndexOf('.'); - if ((end < 0) || (end <= start)) + if (end < 0 || end <= start) { end = path.length(); + } String name = path.substring(start, end); + HttpServlet servlet; try { + interp.set("__file__", path); interp.execfile(path); PyObject cls = interp.get(name); if (cls == null) { @@ -194,34 +183,31 @@ } servlet = (HttpServlet)o; servlet.init(getServletConfig()); - } catch (PyException e) { throw new ServletException(e); } - CacheEntry entry = new CacheEntry(servlet, file.lastModified()); - cache.put(path, entry); + cache.put(path, new CacheEntry(servlet, file.lastModified())); return servlet; } - public void destroy() { - destroyCache(); - } - private void destroyCache() { - for (Enumeration e = cache.elements(); e.hasMoreElements(); ) { - CacheEntry entry = (CacheEntry) e.nextElement(); + for (CacheEntry entry : cache.values()) { entry.servlet.destroy(); } + cache.clear(); } -} + private static class CacheEntry { + public long date; + public HttpServlet servlet; -class CacheEntry { - public long date; - public HttpServlet servlet; - - CacheEntry(HttpServlet servlet, long date) { - this.servlet= servlet; - this.date = date; + CacheEntry(HttpServlet servlet, long date) { + this.servlet= servlet; + this.date = date; + } } -} + + private PythonInterpreter interp; + private String rootPath; + private Map<String, CacheEntry> cache = Generic.map(); +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <cg...@us...> - 2009-06-22 06:32:37
|
Revision: 6490 http://jython.svn.sourceforge.net/jython/?rev=6490&view=rev Author: cgroves Date: 2009-06-22 06:32:34 +0000 (Mon, 22 Jun 2009) Log Message: ----------- Add enough of mockrunner to run servlet tests and use that to run the modjy tests and some new PyServlet tests from our regular build. Modified Paths: -------------- trunk/jython/.classpath trunk/jython/build.xml trunk/jython/src/org/python/core/PySystemState.java trunk/jython/tests/modjy/build.xml trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java Added Paths: ----------- trunk/jython/Lib/test/pyservlet/ trunk/jython/Lib/test/pyservlet/__init__.py trunk/jython/Lib/test/pyservlet/basic.py trunk/jython/Lib/test/pyservlet/empty.py trunk/jython/Lib/test/pyservlet/increment.py trunk/jython/Lib/test/pyservlet/updated_basic.py trunk/jython/extlibs/mockrunner-0.4.1/ trunk/jython/extlibs/mockrunner-0.4.1/jar/ trunk/jython/extlibs/mockrunner-0.4.1/jar/commons-logging-1.0.4.jar trunk/jython/extlibs/mockrunner-0.4.1/jar/j2ee1.3/ trunk/jython/extlibs/mockrunner-0.4.1/jar/j2ee1.3/servlet.jar trunk/jython/extlibs/mockrunner-0.4.1/jar/jakarta-oro-2.0.8.jar trunk/jython/extlibs/mockrunner-0.4.1/jar/jdom.jar trunk/jython/extlibs/mockrunner-0.4.1/jar/nekohtml.jar trunk/jython/extlibs/mockrunner-0.4.1/lib/ trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/ trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/ trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/dependencies.txt trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar trunk/jython/extlibs/mockrunner-0.4.1/readme.txt trunk/jython/tests/modjy/java/org/ trunk/jython/tests/modjy/java/org/python/ trunk/jython/tests/modjy/java/org/python/util/ trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java Property Changed: ---------------- trunk/jython/tests/modjy/ Modified: trunk/jython/.classpath =================================================================== --- trunk/jython/.classpath 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/.classpath 2009-06-22 06:32:34 UTC (rev 6490) @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry excluding="com/ziclix/python/sql/handler/InformixDataHandler.java|com/ziclix/python/sql/handler/OracleDataHandler.java" kind="src" output="build/classes" path="src"/> + <classpathentry kind="src" path="tests/modjy/java"/> <classpathentry kind="src" output="build/classes" path="build/gensrc"/> <classpathentry kind="src" output="build/classes" path="tests/java"/> <classpathentry kind="src" path="bugtests/classes"/> @@ -18,5 +19,7 @@ <classpathentry kind="lib" path="extlibs/asm-commons-3.1.jar"/> <classpathentry kind="lib" path="extlibs/constantine-0.4.jar"/> <classpathentry kind="lib" path="extlibs/jna-posix.jar"/> + <classpathentry kind="lib" path="extlibs/mockrunner-0.4.1/jar/jdom.jar"/> + <classpathentry kind="lib" path="extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar"/> <classpathentry kind="output" path="bugtests/classes"/> </classpath> Added: trunk/jython/Lib/test/pyservlet/basic.py =================================================================== --- trunk/jython/Lib/test/pyservlet/basic.py (rev 0) +++ trunk/jython/Lib/test/pyservlet/basic.py 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,5 @@ +from javax.servlet.http import HttpServlet + +class basic(HttpServlet): + def doGet(self, req, resp): + resp.getOutputStream().write("Basic text response") Added: trunk/jython/Lib/test/pyservlet/increment.py =================================================================== --- trunk/jython/Lib/test/pyservlet/increment.py (rev 0) +++ trunk/jython/Lib/test/pyservlet/increment.py 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,8 @@ +from javax.servlet.http import HttpServlet + +class increment(HttpServlet): + def __init__(self): + self.counter = 0 + def doGet(self, req, resp): + self.counter += 1 + resp.outputStream.write(str(self.counter)) Added: trunk/jython/Lib/test/pyservlet/updated_basic.py =================================================================== --- trunk/jython/Lib/test/pyservlet/updated_basic.py (rev 0) +++ trunk/jython/Lib/test/pyservlet/updated_basic.py 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,5 @@ +from javax.servlet.http import HttpServlet + +class basic(HttpServlet): + def doGet(self, req, resp): + resp.outputStream.write("Updated text response") Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/build.xml 2009-06-22 06:32:34 UTC (rev 6490) @@ -813,7 +813,7 @@ </jar> </target> - <target name="test" depends="prepare-test,javatest,launchertest,regrtest"/> + <target name="test" depends="prepare-test,javatest,launchertest,regrtest,modjytest"/> <target name="singlejavatest" depends="compile,expose"> <junit haltonfailure="true" fork="true"> <formatter type="brief" usefile="false"/> @@ -842,6 +842,12 @@ </batchtest> </junit> </target> + <target name="modjytest" depends="developer-build"> + <ant dir="tests/modjy"> + <property name="jython_home" value="${dist.dir}"/> + <property name="mockrunner_home" value="${extlibs.dir}/mockrunner-0.4.1"/> + </ant> + </target> <target name="launchertest" depends="developer-build" if="os.family.unix"> <exec executable="${test.shell.dir}/test-jython.sh"> <arg value="${dist.dir}"/> Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/commons-logging-1.0.4.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/commons-logging-1.0.4.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/j2ee1.3/servlet.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/j2ee1.3/servlet.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/jakarta-oro-2.0.8.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/jakarta-oro-2.0.8.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/jdom.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/jdom.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/jar/nekohtml.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/jar/nekohtml.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/dependencies.txt =================================================================== --- trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/dependencies.txt (rev 0) +++ trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/dependencies.txt 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,135 @@ +This file lists all the jar files provided by Mockrunner and +the required third party libraries for each jar. Please note +that this file is created automatically by analyzing the +compile time dependencies of all classes in the jar. This +is done recursively, i.e. the dependencies of the third-party +jars are recognized as well. If you add all dependend jars +for a specified mockrunner-xyz.jar to your classpath, you +are on the safe side. However, not all listed dependencies +are necessary at runtime in all cases. Especially with the +"all-in-one"-file mockrunner.jar you don't have to add everything +to the classpath. E.g. if you're only using EJB and JMS, you don't have +to add the web related jar files, because the necessary factories and modules +are created when they are used and lazy initialized respectively. +Please note that the Struts test framework only needs CGLib, if custom action +mappings are used. The jasper related jar files are only necessary if +the JasperJspFactory is used. If you only need one technology it's recommended +to use the corresponding jar file instead of the "all-in-one" mockrunner.jar. +E.g. if you only want to use the JDBC test framework, you can use +mockrunner-jdbc.jar. Please note that each mockrunner-xyz.jar file contains a +jarversion.txt which lists the Mockrunner version and the supported JDK and +J2EE version. + +Created: 06/26/2008 05:59 PM + +Jar file name: mockrunner-tag.jar + +Depends on: + +commons-beanutils-1.7.0.jar +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jdom.jar +junit.jar +nekohtml.jar +servlet.jar +xercesImpl.jar +xml-apis.jar + + +Jar file name: mockrunner-jms.jar + +Depends on: + +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jboss-j2ee.jar +junit.jar + + +Jar file name: mockrunner-servlet.jar + +Depends on: + +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jdom.jar +junit.jar +nekohtml.jar +servlet.jar +xercesImpl.jar +xml-apis.jar + + +Jar file name: mockrunner.jar + +Depends on: + +cglib-nodep-2.2.jar +commons-beanutils-1.7.0.jar +commons-digester-1.8.jar +commons-logging-1.0.4.jar +commons-validator-1.3.1.jar +jakarta-oro-2.0.8.jar +jboss-j2ee.jar +jdom.jar +junit.jar +mockejb.jar +nekohtml.jar +servlet.jar +struts.jar +xercesImpl.jar +xml-apis.jar + + +Jar file name: mockrunner-jca.jar + +Depends on: + +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jboss-j2ee.jar +junit.jar + + +Jar file name: mockrunner-jdbc.jar + +Depends on: + +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jdom.jar +junit.jar +xml-apis.jar + + +Jar file name: mockrunner-ejb.jar + +Depends on: + +cglib-nodep-2.2.jar +commons-beanutils-1.7.0.jar +commons-logging-1.0.4.jar +jakarta-oro-2.0.8.jar +jboss-j2ee.jar +junit.jar +mockejb.jar + + +Jar file name: mockrunner-struts.jar + +Depends on: + +cglib-nodep-2.2.jar +commons-beanutils-1.7.0.jar +commons-digester-1.8.jar +commons-logging-1.0.4.jar +commons-validator-1.3.1.jar +jakarta-oro-2.0.8.jar +jdom.jar +junit.jar +nekohtml.jar +servlet.jar +struts.jar +xercesImpl.jar +xml-apis.jar Added: trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/mockrunner-0.4.1/readme.txt =================================================================== --- trunk/jython/extlibs/mockrunner-0.4.1/readme.txt (rev 0) +++ trunk/jython/extlibs/mockrunner-0.4.1/readme.txt 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,2 @@ +This contains the minimal set of jars from mockrunner-0.4.1 to run the modjy tests against j2ee1.3 +with jdk1.5. Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-06-22 06:32:34 UTC (rev 6490) @@ -698,10 +698,10 @@ } } - public static Properties getBaseProperties(){ - try{ + public static Properties getBaseProperties() { + try { return System.getProperties(); - }catch(AccessControlException ace){ + } catch (AccessControlException ace) { return new Properties(); } } Property changes on: trunk/jython/tests/modjy ___________________________________________________________________ Added: svn:ignore + build Modified: trunk/jython/tests/modjy/build.xml =================================================================== --- trunk/jython/tests/modjy/build.xml 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/tests/modjy/build.xml 2009-06-22 06:32:34 UTC (rev 6490) @@ -12,16 +12,17 @@ <!-- Jython properties --> - <property name="jython_home" location="${env.JYTHON_HOME}"/> + <property name="jython_home" location="${env.JYTHON_HOME}"/> <property name="jython_jar" value="jython-dev.jar"/> <property name="jython_jar_path" location="${jython_home}/${jython_jar}"/> <property name="jython_cachedir" location="${jython_home}/cachedir"/> + <property name="mockrunner_home" location="${env.MOCKRUNNER_HOME}"/> <target name="init"> - <available property="jython.home.set" file="${env.JYTHON_HOME}" /> - <fail unless="jython.home.set" message="JYTHON_HOME not set" /> - <available property="mockrunner.home.set" file="${env.MOCKRUNNER_HOME}" /> - <fail unless="mockrunner.home.set" message="MOCKRUNNER_HOME not set" /> + <available property="jython_home.exists" file="${jython_home}" /> + <fail unless="jython_home.exists" message="jython_home, ${jython_home}, doesn't exist" /> + <available property="mockrunner_home.exists" file="${mockrunner_home}" /> + <fail unless="mockrunner_home.exists" message="mockrunner_home, ${mockrunner_home}, doesn't exist" /> <!-- Create the build directory structure used by compile --> <mkdir dir="${build}"/> </target> @@ -35,12 +36,7 @@ <target name="do_test" depends="init" description="Run unit tests against a single jdk/servlet combo"> <echo message="Running tests against JDK ${jdk_version}, Servlet ${servlet_version}"/> - <echo message="Clearing jython package cache located at ${jython_home}/cachedir"/> - <delete quiet="true"> - <fileset dir="${jython_cachedir}"/> - </delete> - <property name="mockrunner_home" value="${env.MOCKRUNNER_HOME}"/> <property name="mockrunner_jar" location="${mockrunner_home}/jar"/> <property name="mockrunner_lib" location="${mockrunner_home}/lib/jdk${jdk_version}/${servlet_version}"/> @@ -57,15 +53,13 @@ srcdir="${test_src}" destdir="${build}" classpathref="test.classpath" - debug="on" - /> - - <java - classname="com.xhaus.modjy.ModjyTestBase" - dir="." - fork="yes" - classpathref="test.classpath" - /> + debug="on" + /> + <java classname="com.xhaus.modjy.ModjyTestBase" dir="." fork="yes" + classpathref="test.classpath"> + <sysproperty key="JYTHON_HOME" value="${jython_home}"/> + <sysproperty key="python.cachedir.skip" value="true"/> + </java> </target> <target name="test"> Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-21 22:19:53 UTC (rev 6489) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-06-22 06:32:34 UTC (rev 6490) @@ -1,35 +1,27 @@ /*### # -# Copyright Alan Kennedy. -# +# Copyright Alan Kennedy. +# # You may contact the copyright holder at this uri: -# +# # http://www.xhaus.com/contact/modjy -# +# # The licence under which this code is released is the Apache License v2.0. -# +# # The terms and conditions of this license are listed in a file contained # in the distribution that also contained this file, under the name # LICENSE.txt. -# +# # You may also read a copy of the license at the following web address. -# +# # http://modjy.xhaus.com/LICENSE.txt # ###*/ package com.xhaus.modjy; -import java.io.File; - -import java.util.Map; -import java.util.Iterator; - import junit.framework.*; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServlet; - import com.mockrunner.servlet.BasicServletTestCaseAdapter; import com.mockrunner.mock.web.WebMockObjectFactory; import com.mockrunner.mock.web.MockServletConfig; @@ -37,16 +29,16 @@ import com.mockrunner.mock.web.MockHttpServletRequest; import com.mockrunner.mock.web.MockHttpServletResponse; -import org.jdom.Element; import org.jdom.output.XMLOutputter; import org.python.core.PyObject; +import org.python.util.PyServletTest; import org.python.util.PythonInterpreter; import com.xhaus.modjy.ModjyJServlet; /** - * + * */ public class ModjyTestBase extends BasicServletTestCaseAdapter @@ -226,7 +218,7 @@ throws Exception { super.setUp(); - String jythonHome = System.getenv("JYTHON_HOME"); + String jythonHome = System.getProperty("JYTHON_HOME"); setRealPath(jythonHome, jythonHome); setRealPath("/WEB-INF/"+LIB_PYTHON_DIR, LIB_PYTHON_TEST_PATH); setRealPath("/WEB-INF/lib/modjy.jar", "../modjy.jar"); @@ -267,7 +259,7 @@ baseSetUp(); createServlet(); doGet(); - String result = new XMLOutputter().outputString(getOutputAsJDOMDocument()); + new XMLOutputter().outputString(getOutputAsJDOMDocument()); } public static void main(String args[]) @@ -281,6 +273,7 @@ suite.addTestSuite(ModjyTestReturnIterable.class); suite.addTestSuite(ModjyTestWebInf.class); suite.addTestSuite(ModjyTestWSGIStreams.class); + suite.addTestSuite(PyServletTest.class); junit.textui.TestRunner.run(suite); } Added: trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java =================================================================== --- trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java (rev 0) +++ trunk/jython/tests/modjy/java/org/python/util/PyServletTest.java 2009-06-22 06:32:34 UTC (rev 6490) @@ -0,0 +1,88 @@ +package org.python.util; + +import javax.servlet.ServletException; + +import org.python.core.PyFile; +import com.mockrunner.base.NestedApplicationException; +import com.mockrunner.mock.web.MockServletConfig; +import com.mockrunner.mock.web.MockServletContext; +import com.mockrunner.mock.web.WebMockObjectFactory; +import com.mockrunner.servlet.BasicServletTestCaseAdapter; + +public class PyServletTest extends BasicServletTestCaseAdapter { + public void testGet() { + assertEquals("Basic text response", doGetAndRead("basic")); + } + + public void testNoCallable() { + try { + doGetAndRead("empty"); + fail("Using an empty file for PyServlet should raise a ServletException"); + } catch (NestedApplicationException e) { + assertTrue(e.getRootCause() instanceof ServletException); + } + } + + public void testReload() { + String originalBasic = readTestFile("basic"); + try { + testGet(); + writeToTestFile("basic", readTestFile("updated_basic")); + assertEquals("Updated text response", doGetAndRead("basic")); + } finally { + writeToTestFile("basic", originalBasic); + } + } + + public void testInstanceCaching() { + assertEquals("1", doGetAndRead("increment")); + assertEquals("2", doGetAndRead("increment")); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + MockServletConfig cfg = getWebMockObjectFactory().getMockServletConfig(); + cfg.setInitParameter("python.home", System.getProperty("JYTHON_HOME")); + createServlet(PyServlet.class); + } + + private String doGetAndRead(String testName) { + getWebMockObjectFactory().getMockRequest().setServletPath(getTestPath(testName)); + doGet(); + String result = getOutput(); + clearOutput(); + return result; + } + + private String getTestPath(String testName) { + return "/test/pyservlet/" + testName + ".py"; + } + + private String readTestFile(String testName) { + PyFile in = new PyFile(basePath + getTestPath(testName), "r", 4192); + String result = in.read().toString(); + return result; + } + + private void writeToTestFile(String testName, String newContents) { + PyFile out = new PyFile(basePath + getTestPath(testName), "w", 4192); + out.write(newContents); + out.close(); + } + + @Override + protected WebMockObjectFactory createWebMockObjectFactory() { + return new WebMockObjectFactory() { + @Override public MockServletContext createMockServletContext() { + return new MockServletContext() { + @Override public synchronized String getRealPath(String path) { + return basePath + path; + } + }; + } + }; + } + + private String basePath = System.getProperty("JYTHON_HOME") + "/Lib"; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-06-21 22:20:15
|
Revision: 6489 http://jython.svn.sourceforge.net/jython/?rev=6489&view=rev Author: amak Date: 2009-06-21 22:19:53 +0000 (Sun, 21 Jun 2009) Log Message: ----------- Checking in a partial fix for issue 1378. This fix stops the AttributeError. But further work is needed to determine what cpython errno constants the java SSL exceptions should map to. Modified Paths: -------------- trunk/jython/Lib/socket.py Modified: trunk/jython/Lib/socket.py =================================================================== --- trunk/jython/Lib/socket.py 2009-06-21 03:17:50 UTC (rev 6488) +++ trunk/jython/Lib/socket.py 2009-06-21 22:19:53 UTC (rev 6489) @@ -74,7 +74,14 @@ import java.nio.channels.UnresolvedAddressException import java.nio.channels.UnsupportedAddressTypeException +# Javax.net.ssl classes import javax.net.ssl.SSLSocketFactory +# Javax.net.ssl exceptions +javax.net.ssl.SSLException +javax.net.ssl.SSLHandshakeException +javax.net.ssl.SSLKeyException +javax.net.ssl.SSLPeerUnverifiedException +javax.net.ssl.SSLProtocolException import org.python.core.io.DatagramSocketIO import org.python.core.io.ServerSocketIO @@ -85,6 +92,7 @@ class herror(error): pass class gaierror(error): pass class timeout(error): pass +class sslerror(error): pass ALL = None @@ -120,6 +128,15 @@ (java.nio.channels.NotYetConnectedException, ALL) : None, (java.nio.channels.UnresolvedAddressException, ALL) : lambda: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'), (java.nio.channels.UnsupportedAddressTypeException, ALL) : None, + +# These error codes are currently wrong: getting them correct is going to require +# some investigation. Cpython 2.6 introduced extensive SSL support. + +(javax.net.ssl.SSLException, ALL) : lambda: sslerror(-1, 'SSL exception'), +(javax.net.ssl.SSLHandshakeException, ALL) : lambda: sslerror(-1, 'SSL handshake exception'), +(javax.net.ssl.SSLKeyException, ALL) : lambda: sslerror(-1, 'SSL key exception'), +(javax.net.ssl.SSLPeerUnverifiedException, ALL) : lambda: sslerror(-1, 'SSL peer unverified exception'), +(javax.net.ssl.SSLProtocolException, ALL) : lambda: sslerror(-1, 'SSL protocol exception'), } @@ -1392,12 +1409,15 @@ class ssl: - def __init__(self, plain_sock, keyfile=None, certfile=None): - self.ssl_sock = self.make_ssl_socket(plain_sock) - self._in_buf = java.io.BufferedInputStream(self.ssl_sock.getInputStream()) - self._out_buf = java.io.BufferedOutputStream(self.ssl_sock.getOutputStream()) + def __init__(self, plain_sock, keyfile=None, certfile=None): + try: + self.ssl_sock = self._make_ssl_socket(plain_sock) + self._in_buf = java.io.BufferedInputStream(self.ssl_sock.getInputStream()) + self._out_buf = java.io.BufferedOutputStream(self.ssl_sock.getOutputStream()) + except java.lang.Exception, jlx: + raise _map_exception(jlx) - def make_ssl_socket(self, plain_socket, auto_close=0): + def _make_ssl_socket(self, plain_socket, auto_close=0): java_net_socket = plain_socket._get_jsocket() assert isinstance(java_net_socket, java.net.Socket) host = java_net_socket.getInetAddress().getHostAddress() @@ -1409,21 +1429,30 @@ return ssl_socket def read(self, n=4096): - data = jarray.zeros(n, 'b') - m = self._in_buf.read(data, 0, n) - if m <= 0: - return "" - if m < n: - data = data[:m] - return data.tostring() + try: + data = jarray.zeros(n, 'b') + m = self._in_buf.read(data, 0, n) + if m <= 0: + return "" + if m < n: + data = data[:m] + return data.tostring() + except java.lang.Exception, jlx: + raise _map_exception(jlx) def write(self, s): - self._out_buf.write(s) - self._out_buf.flush() - return len(s) + try: + self._out_buf.write(s) + self._out_buf.flush() + return len(s) + except java.lang.Exception, jlx: + raise _map_exception(jlx) def _get_server_cert(self): - return self.ssl_sock.getSession().getPeerCertificates()[0] + try: + return self.ssl_sock.getSession().getPeerCertificates()[0] + except java.lang.Exception, jlx: + raise _map_exception(jlx) def server(self): cert = self._get_server_cert() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-06-21 03:17:53
|
Revision: 6488 http://jython.svn.sourceforge.net/jython/?rev=6488&view=rev Author: zyasoft Date: 2009-06-21 03:17:50 +0000 (Sun, 21 Jun 2009) Log Message: ----------- Added PyNew* versions of PyString and PyUnicode to enable incremental refactoring. Modified Paths: -------------- branches/newstr/src/templates/mappings Added Paths: ----------- branches/newstr/src/org/python/core/PyNewString.java branches/newstr/src/org/python/core/PyNewStringDerived.java branches/newstr/src/org/python/core/PyNewUnicode.java branches/newstr/src/org/python/core/PyNewUnicodeDerived.java branches/newstr/src/templates/newstr.derived branches/newstr/src/templates/newunicode.derived Added: branches/newstr/src/org/python/core/PyNewString.java =================================================================== --- branches/newstr/src/org/python/core/PyNewString.java (rev 0) +++ branches/newstr/src/org/python/core/PyNewString.java 2009-06-21 03:17:50 UTC (rev 6488) @@ -0,0 +1,3104 @@ +/// Copyright (c) Corporation for National Research Initiatives +package org.python.core; + +import java.math.BigInteger; + +import org.python.core.util.ExtraMath; +import org.python.core.util.StringUtil; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedType; +import org.python.expose.MethodType; + + +/** + * A builtin python string. + */ +@ExposedType(name = "newstr") +public class PyNewString extends PyBaseString +{ + public static final PyType TYPE = PyType.fromClass(PyNewString.class); + protected String string; + protected transient boolean interned=false; + + // for PyJavaClass.init() + public PyNewString() { + this(TYPE, ""); + } + + public PyNewString(PyType subType, String string) { + super(subType); + if (string == null) { + throw new IllegalArgumentException( + "Cannot create PyString from null!"); + } + this.string = string; + } + + public PyNewString(String string) { + this(TYPE, string); + } + + public PyNewString(char c) { + this(TYPE,String.valueOf(c)); + } + + PyNewString(StringBuilder buffer) { + this(TYPE, new String(buffer)); + } + + /** + * Creates a PyString from an already interned String. Just means it won't + * be reinterned if used in a place that requires interned Strings. + */ + public static PyNewString fromInterned(String interned) { + PyNewString str = new PyNewString(TYPE, interned); + str.interned = true; + return str; + } + + @ExposedNew + final static PyObject str_new(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { + ArgParser ap = new ArgParser("str", args, keywords, new String[] { "object" }, 0); + PyObject S = ap.getPyObject(0, null); + if(new_.for_type == subtype) { + if(S == null) { + return new PyNewString(""); + } + return new PyNewString(S.__str__().toString()); + } else { + if (S == null) { + return new PyNewStringDerived(subtype, ""); + } + return new PyNewStringDerived(subtype, S.__str__().toString()); + } + } + + public int[] toCodePoints() { + int n = string.length(); + int[] codePoints = new int[n]; + for (int i = 0; i < n; i++) { + codePoints[i] = string.charAt(i); + } + return codePoints; + } + + public String substring(int start, int end) { + return string.substring(start, end); + } + + public PyString __str__() { + return str___str__(); + } + + @ExposedMethod(doc = BuiltinDocs.str___str___doc) + final PyString str___str__() { + return new PyString(string); + } + + public PyUnicode __unicode__() { + return new PyUnicode(string); + } + + public int __len__() { + return str___len__(); + } + + @ExposedMethod(doc = BuiltinDocs.str___len___doc) + final int str___len__() { + return string.length(); + } + + public String toString() { + return string; + } + + public String internedString() { + if (interned) + return string; + else { + string = string.intern(); + interned = true; + return string; + } + } + + public PyString __repr__() { + return str___repr__(); + } + + @ExposedMethod(doc = BuiltinDocs.str___repr___doc) + final PyString str___repr__() { + return new PyString(encode_UnicodeEscape(string, true)); + } + + private static char[] hexdigit = "0123456789abcdef".toCharArray(); + + public static String encode_UnicodeEscape(String str, + boolean use_quotes) + { + int size = str.length(); + StringBuilder v = new StringBuilder(str.length()); + + char quote = 0; + + if (use_quotes) { + quote = str.indexOf('\'') >= 0 && + str.indexOf('"') == -1 ? '"' : '\''; + v.append(quote); + } + + for (int i = 0; size-- > 0; ) { + int ch = str.charAt(i++); + /* Escape quotes */ + if (use_quotes && (ch == quote || ch == '\\')) { + v.append('\\'); + v.append((char) ch); + continue; + } + /* Map UTF-16 surrogate pairs to Unicode \UXXXXXXXX escapes */ + else if (ch >= 0xD800 && ch < 0xDC00) { + char ch2 = str.charAt(i++); + size--; + if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { + int ucs = (((ch & 0x03FF) << 10) | (ch2 & 0x03FF)) + 0x00010000; + v.append('\\'); + v.append('U'); + v.append(hexdigit[(ucs >> 28) & 0xf]); + v.append(hexdigit[(ucs >> 24) & 0xf]); + v.append(hexdigit[(ucs >> 20) & 0xf]); + v.append(hexdigit[(ucs >> 16) & 0xf]); + v.append(hexdigit[(ucs >> 12) & 0xf]); + v.append(hexdigit[(ucs >> 8) & 0xf]); + v.append(hexdigit[(ucs >> 4) & 0xf]); + v.append(hexdigit[ucs & 0xf]); + continue; + } + /* Fall through: isolated surrogates are copied as-is */ + i--; + size++; + } + /* Map 16-bit characters to '\\uxxxx' */ + if (ch >= 256) { + v.append('\\'); + v.append('u'); + v.append(hexdigit[(ch >> 12) & 0xf]); + v.append(hexdigit[(ch >> 8) & 0xf]); + v.append(hexdigit[(ch >> 4) & 0xf]); + v.append(hexdigit[ch & 15]); + } + /* Map special whitespace to '\t', \n', '\r' */ + else if (ch == '\t') v.append("\\t"); + else if (ch == '\n') v.append("\\n"); + else if (ch == '\r') v.append("\\r"); + /* Map non-printable US ASCII to '\ooo' */ + else if (ch < ' ' || ch >= 127) { + v.append('\\'); + v.append('x'); + v.append(hexdigit[(ch >> 4) & 0xf]); + v.append(hexdigit[ch & 0xf]); + } + /* Copy everything else as-is */ + else + v.append((char) ch); + } + if (use_quotes) + v.append(quote); + return v.toString(); + } + + private static ucnhashAPI pucnHash = null; + + + public static String decode_UnicodeEscape(String str, + int start, + int end, + String errors, + boolean unicode) { + StringBuilder v = new StringBuilder(end - start); + for(int s = start; s < end;) { + char ch = str.charAt(s); + /* Non-escape characters are interpreted as Unicode ordinals */ + if(ch != '\\') { + v.append(ch); + s++; + continue; + } + int loopStart = s; + /* \ - Escapes */ + s++; + if(s == end) { + s = codecs.insertReplacementAndGetResume(v, + errors, + "unicodeescape", + str, + loopStart, + s + 1, + "\\ at end of string"); + continue; + } + ch = str.charAt(s++); + switch(ch){ + /* \x escapes */ + case '\n': + break; + case '\\': + v.append('\\'); + break; + case '\'': + v.append('\''); + break; + case '\"': + v.append('\"'); + break; + case 'b': + v.append('\b'); + break; + case 'f': + v.append('\014'); + break; /* FF */ + case 't': + v.append('\t'); + break; + case 'n': + v.append('\n'); + break; + case 'r': + v.append('\r'); + break; + case 'v': + v.append('\013'); + break; /* VT */ + case 'a': + v.append('\007'); + break; /* BEL, not classic C */ + /* \OOO (octal) escapes */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + int x = Character.digit(ch, 8); + for(int j = 0; j < 2 && s < end; j++, s++) { + ch = str.charAt(s); + if(ch < '0' || ch > '7') + break; + x = (x << 3) + Character.digit(ch, 8); + } + v.append((char)x); + break; + case 'x': + s = hexescape(v, errors, 2, s, str, end, "truncated \\xXX"); + break; + case 'u': + if(!unicode) { + v.append('\\'); + v.append('u'); + break; + } + s = hexescape(v, + errors, + 4, + s, + str, + end, + "truncated \\uXXXX"); + break; + case 'U': + if(!unicode) { + v.append('\\'); + v.append('U'); + break; + } + s = hexescape(v, + errors, + 8, + s, + str, + end, + "truncated \\UXXXXXXXX"); + break; + case 'N': + if(!unicode) { + v.append('\\'); + v.append('N'); + break; + } + /* + * Ok, we need to deal with Unicode Character Names now, + * make sure we've imported the hash table data... + */ + if(pucnHash == null) { + PyObject mod = imp.importName("ucnhash", true); + mod = mod.__call__(); + pucnHash = (ucnhashAPI)mod.__tojava__(Object.class); + if(pucnHash.getCchMax() < 0) + throw Py.UnicodeError("Unicode names not loaded"); + } + if(str.charAt(s) == '{') { + int startName = s + 1; + int endBrace = startName; + /* + * look for either the closing brace, or we exceed the + * maximum length of the unicode character names + */ + int maxLen = pucnHash.getCchMax(); + while(endBrace < end && str.charAt(endBrace) != '}' + && (endBrace - startName) <= maxLen) { + endBrace++; + } + if(endBrace != end && str.charAt(endBrace) == '}') { + int value = pucnHash.getValue(str, + startName, + endBrace); + if(storeUnicodeCharacter(value, v)) { + s = endBrace + 1; + } else { + s = codecs.insertReplacementAndGetResume(v, + errors, + "unicodeescape", + str, + loopStart, + endBrace + 1, + "illegal Unicode character"); + } + } else { + s = codecs.insertReplacementAndGetResume(v, + errors, + "unicodeescape", + str, + loopStart, + endBrace, + "malformed \\N character escape"); + } + break; + } else { + s = codecs.insertReplacementAndGetResume(v, + errors, + "unicodeescape", + str, + loopStart, + s + 1, + "malformed \\N character escape"); + } + break; + default: + v.append('\\'); + v.append(str.charAt(s - 1)); + break; + } + } + return v.toString(); + } + + private static int hexescape(StringBuilder partialDecode, + String errors, + int digits, + int hexDigitStart, + String str, + int size, + String errorMessage) { + if(hexDigitStart + digits > size) { + return codecs.insertReplacementAndGetResume(partialDecode, + errors, + "unicodeescape", + str, + hexDigitStart - 2, + size, + errorMessage); + } + int i = 0; + int x = 0; + for(; i < digits; ++i) { + char c = str.charAt(hexDigitStart + i); + int d = Character.digit(c, 16); + if(d == -1) { + return codecs.insertReplacementAndGetResume(partialDecode, + errors, + "unicodeescape", + str, + hexDigitStart - 2, + hexDigitStart + i + 1, + errorMessage); + } + x = (x << 4) & ~0xF; + if(c >= '0' && c <= '9') + x += c - '0'; + else if(c >= 'a' && c <= 'f') + x += 10 + c - 'a'; + else + x += 10 + c - 'A'; + } + if(storeUnicodeCharacter(x, partialDecode)) { + return hexDigitStart + i; + } else { + return codecs.insertReplacementAndGetResume(partialDecode, + errors, + "unicodeescape", + str, + hexDigitStart - 2, + hexDigitStart + i + 1, + "illegal Unicode character"); + } + } + + /*pass in an int since this can be a UCS-4 character */ + private static boolean storeUnicodeCharacter(int value, + StringBuilder partialDecode) { + if (value < 0 || (value >= 0xD800 && value <= 0xDFFF)) { + return false; + } else if (value <= PySystemState.maxunicode) { + partialDecode.appendCodePoint(value); + return true; + } + return false; + } + + @ExposedMethod(doc = BuiltinDocs.str___getitem___doc) + final PyObject str___getitem__(PyObject index) { + PyObject ret = seq___finditem__(index); + if (ret == null) { + throw Py.IndexError("string index out of range"); + } + return ret; + } + + //XXX: need doc + @ExposedMethod(defaults = "null") + final PyObject str___getslice__(PyObject start, PyObject stop, PyObject step) { + return seq___getslice__(start, stop, step); + } + + public int __cmp__(PyObject other) { + return str___cmp__(other); + } + + @ExposedMethod(type = MethodType.CMP) + final int str___cmp__(PyObject other) { + if (!(other instanceof PyNewString)) + return -2; + + int c = string.compareTo(((PyNewString)other).string); + return c < 0 ? -1 : c > 0 ? 1 : 0; + } + + public PyObject __eq__(PyObject other) { + return str___eq__(other); + } + + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.str___eq___doc) + final PyObject str___eq__(PyObject other) { + String s = coerce(other); + if (s == null) + return null; + return string.equals(s) ? Py.True : Py.False; + } + + public PyObject __ne__(PyObject other) { + return str___ne__(other); + } + + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.str___ne___doc) + final PyObject str___ne__(PyObject other) { + String s = coerce(other); + if (s == null) + return null; + return string.equals(s) ? Py.False : Py.True; + } + + public PyObject __lt__(PyObject other) { + return str___lt__(other); + } + + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.str___lt___doc) + final PyObject str___lt__(PyObject other){ + String s = coerce(other); + if (s == null) + return null; + return string.compareTo(s) < 0 ? Py.True : Py.False; + } + + public PyObject __le__(PyObject other) { + return str___le__(other); + } + + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.str___le___doc) + final PyObject str___le__(PyObject other){ + String s = coerce(other); + if (s == null) + return null; + return string.compareTo(s) <= 0 ? Py.True : Py.False; + } + + public PyObject __gt__(PyObject other) { + return str___gt__(other); + } + + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.str___gt___doc) + final PyObject str___gt__(PyObject other){ + String s = coerce(other); + if (s == null) + return null; + return string.compareTo(s) > 0 ? Py.True : Py.False; + } + + public PyObject __ge__(PyObject other) { + return str___ge__(other); + } + + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.str___ge___doc) + final PyObject str___ge__(PyObject other){ + String s = coerce(other); + if (s == null) + return null; + return string.compareTo(s) >= 0 ? Py.True : Py.False; + } + + private static String coerce(PyObject o) { + if (o instanceof PyNewString) + return o.toString(); + return null; + } + + public int hashCode() { + return str___hash__(); + } + + @ExposedMethod(doc = BuiltinDocs.str___hash___doc) + final int str___hash__() { + return string.hashCode(); + } + + /** + * @return a byte array with one byte for each char in this object's + * underlying String. Each byte contains the low-order bits of its + * corresponding char. + */ + public byte[] toBytes() { + return StringUtil.toBytes(string); + } + + public Object __tojava__(Class<?> c) { + if (c.isAssignableFrom(String.class)) { + return string; + } + + if (c == Character.TYPE || c == Character.class) + if (string.length() == 1) + return new Character(string.charAt(0)); + + if (c.isArray()) { + if (c.getComponentType() == Byte.TYPE) + return toBytes(); + if (c.getComponentType() == Character.TYPE) + return string.toCharArray(); + } + + if (c.isInstance(this)) + return this; + + return Py.NoConversion; + } + + protected PyObject pyget(int i) { + return Py.newString(string.charAt(i)); + } + + protected PyObject getslice(int start, int stop, int step) { + if (step > 0 && stop < start) + stop = start; + if (step == 1) + return fromSubstring(start, stop); + else { + int n = sliceLength(start, stop, step); + char new_chars[] = new char[n]; + int j = 0; + for (int i=start; j<n; i+=step) + new_chars[j++] = string.charAt(i); + + return createInstance(new String(new_chars), true); + } + } + + public PyNewString createInstance(String str) { + return new PyNewString(str); + } + + protected PyNewString createInstance(String str, boolean isBasic) { + // ignore isBasic, doesn't apply to PyString, just PyNewUnicode + return new PyNewString(str); + } + + public boolean __contains__(PyObject o) { + return str___contains__(o); + } + + @ExposedMethod(doc = BuiltinDocs.str___contains___doc) + final boolean str___contains__(PyObject o) { + if (!(o instanceof PyNewString)) + throw Py.TypeError("'in <string>' requires string as left operand"); + PyNewString other = (PyNewString) o; + return string.indexOf(other.string) >= 0; + } + + protected PyObject repeat(int count) { + if(count < 0) { + count = 0; + } + int s = string.length(); + if((long)s * count > Integer.MAX_VALUE) { + // Since Strings store their data in an array, we can't make one + // longer than Integer.MAX_VALUE. Without this check we get + // NegativeArraySize exceptions when we create the array on the + // line with a wrapped int. + throw Py.OverflowError("max str len is " + Integer.MAX_VALUE); + } + char new_chars[] = new char[s * count]; + for(int i = 0; i < count; i++) { + string.getChars(0, s, new_chars, i * s); + } + return createInstance(new String(new_chars)); + } + + @Override + public PyObject __mul__(PyObject o) { + return str___mul__(o); + } + + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.str___mul___doc) + final PyObject str___mul__(PyObject o) { + if (!o.isIndex()) { + return null; + } + return repeat(o.asIndex(Py.OverflowError)); + } + + @Override + public PyObject __rmul__(PyObject o) { + return str___rmul__(o); + } + + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.str___rmul___doc) + final PyObject str___rmul__(PyObject o) { + if (!o.isIndex()) { + return null; + } + return repeat(o.asIndex(Py.OverflowError)); + } + + public PyObject __add__(PyObject other) { + return str___add__(other); + } + + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.str___add___doc) + final PyObject str___add__(PyObject other) { + if (other instanceof PyNewUnicode) { + return decode().__add__(other); + } + if (other instanceof PyNewString) { + PyNewString otherStr = (PyNewString)other; + return new PyNewString(string.concat(otherStr.string)); + } + return null; + } + + @ExposedMethod(doc = BuiltinDocs.str___getnewargs___doc) + final PyTuple str___getnewargs__() { + return new PyTuple(new PyNewString(this.string)); + } + + public PyTuple __getnewargs__() { + return str___getnewargs__(); + } + + public PyObject __mod__(PyObject other) { + return str___mod__(other); + } + + @ExposedMethod(doc = BuiltinDocs.str___mod___doc) + public PyObject str___mod__(PyObject other){ + StringFormatter fmt = new StringFormatter(string, false); + return fmt.format(other); + } + + public PyObject __int__() { + try + { + return Py.newInteger(atoi(10)); + } catch (PyException e) { + if (e.match(Py.OverflowError)) { + return atol(10); + } + throw e; + } + } + + public PyObject __long__() { + return atol(10); + } + + public PyFloat __float__() { + return new PyFloat(atof()); + } + + public PyObject __pos__() { + throw Py.TypeError("bad operand type for unary +"); + } + + public PyObject __neg__() { + throw Py.TypeError("bad operand type for unary -"); + } + + public PyObject __invert__() { + throw Py.TypeError("bad operand type for unary ~"); + } + + @SuppressWarnings("fallthrough") + public PyComplex __complex__() { + boolean got_re = false; + boolean got_im = false; + boolean done = false; + boolean sw_error = false; + + int s = 0; + int n = string.length(); + while (s < n && Character.isSpaceChar(string.charAt(s))) + s++; + + if (s == n) { + throw Py.ValueError("empty string for complex()"); + } + + double z = -1.0; + double x = 0.0; + double y = 0.0; + + int sign = 1; + do { + char c = string.charAt(s); + switch (c) { + case '-': + sign = -1; + /* Fallthrough */ + case '+': + if (done || s+1 == n) { + sw_error = true; + break; + } + // a character is guaranteed, but it better be a digit + // or J or j + c = string.charAt(++s); // eat the sign character + // and check the next + if (!Character.isDigit(c) && c!='J' && c!='j') + sw_error = true; + break; + + case 'J': + case 'j': + if (got_im || done) { + sw_error = true; + break; + } + if (z < 0.0) { + y = sign; + } else { + y = sign * z; + } + got_im = true; + done = got_re; + sign = 1; + s++; // eat the J or j + break; + + case ' ': + while (s < n && Character.isSpaceChar(string.charAt(s))) + s++; + if (s != n) + sw_error = true; + break; + + default: + boolean digit_or_dot = (c == '.' || Character.isDigit(c)); + if (!digit_or_dot) { + sw_error = true; + break; + } + int end = endDouble(string, s); + z = Double.valueOf(string.substring(s, end)).doubleValue(); + if (z == Double.POSITIVE_INFINITY) { + throw Py.ValueError(String.format("float() out of range: %.150s", string)); + } + + s=end; + if (s < n) { + c = string.charAt(s); + if (c == 'J' || c == 'j') { + break; + } + } + if (got_re) { + sw_error = true; + break; + } + + /* accept a real part */ + x = sign * z; + got_re = true; + done = got_im; + z = -1.0; + sign = 1; + break; + + } /* end of switch */ + + } while (s < n && !sw_error); + + if (sw_error) { + throw Py.ValueError("malformed string for complex() " + + string.substring(s)); + } + + return new PyComplex(x,y); + } + + private int endDouble(String string, int s) { + int n = string.length(); + while (s < n) { + char c = string.charAt(s++); + if (Character.isDigit(c)) + continue; + if (c == '.') + continue; + if (c == 'e' || c == 'E') { + if (s < n) { + c = string.charAt(s); + if (c == '+' || c == '-') + s++; + continue; + } + } + return s-1; + } + return s; + } + + // Add in methods from string module + public String lower() { + return str_lower(); + } + + @ExposedMethod(doc = BuiltinDocs.str_lower_doc) + final String str_lower() { + return string.toLowerCase(); + } + + public String upper() { + return str_upper(); + } + + @ExposedMethod(doc = BuiltinDocs.str_upper_doc) + final String str_upper() { + return string.toUpperCase(); + } + + public String title() { + return str_title(); + } + + @ExposedMethod(doc = BuiltinDocs.str_title_doc) + final String str_title() { + char[] chars = string.toCharArray(); + int n = chars.length; + + boolean previous_is_cased = false; + for (int i = 0; i < n; i++) { + char ch = chars[i]; + if (previous_is_cased) + chars[i] = Character.toLowerCase(ch); + else + chars[i] = Character.toTitleCase(ch); + + if (Character.isLowerCase(ch) || + Character.isUpperCase(ch) || + Character.isTitleCase(ch)) + previous_is_cased = true; + else + previous_is_cased = false; + } + return new String(chars); + } + + public String swapcase() { + return str_swapcase(); + } + + @ExposedMethod(doc = BuiltinDocs.str_swapcase_doc) + final String str_swapcase() { + char[] chars = string.toCharArray(); + int n=chars.length; + for (int i=0; i<n; i++) { + char c = chars[i]; + if (Character.isUpperCase(c)) { + chars[i] = Character.toLowerCase(c); + } + else if (Character.isLowerCase(c)) { + chars[i] = Character.toUpperCase(c); + } + } + return new String(chars); + } + + public String strip() { + return str_strip(null); + } + + public String strip(String sep) { + return str_strip(sep); + } + + @ExposedMethod(defaults = "null", doc = BuiltinDocs.str_strip_doc) + final String str_strip(String sep) { + char[] chars = string.toCharArray(); + int n=chars.length; + int start=0; + if (sep == null) + while (start < n && Character.isWhitespace(chars[start])) + start++; + else + while (start < n && sep.indexOf(chars[start]) >= 0) + start++; + + int end=n-1; + if (sep == null) + while (end >= 0 && Character.isWhitespace(chars[end])) + end--; + else + while (end >= 0 && sep.indexOf(chars[end]) >= 0) + end--; + + if (end >= start) { + return (end < n-1 || start > 0) + ? string.substring(start, end+1) : string; + } else { + return ""; + } + } + + public String lstrip() { + return str_lstrip(null); + } + + public String lstrip(String sep) { + return str_lstrip(sep); + } + + @ExposedMethod(defaults = "null", doc = BuiltinDocs.str_lstrip_doc) + final String str_lstrip(String sep) { + char[] chars = string.toCharArray(); + int n=chars.length; + int start=0; + if (sep == null) + while (start < n && Character.isWhitespace(chars[start])) + start++; + else + while (start < n && sep.indexOf(chars[start]) >= 0) + start++; + + return (start > 0) ? string.substring(start, n) : string; + } + + public String rstrip(String sep) { + return str_rstrip(sep); + } + + @ExposedMethod(defaults = "null", doc = BuiltinDocs.str_rstrip_doc) + final String str_rstrip(String sep) { + char[] chars = string.toCharArray(); + int n=chars.length; + int end=n-1; + if (sep == null) + while (end >= 0 && Character.isWhitespace(chars[end])) + end--; + else + while (end >= 0 && sep.indexOf(chars[end]) >= 0) + end--; + + return (end < n-1) ? string.substring(0, end+1) : string; + } + + + public PyList split() { + return str_split(null, -1); + } + + public PyList split(String sep) { + return str_split(sep, -1); + } + + public PyList split(String sep, int maxsplit) { + return str_split(sep, maxsplit); + } + + @ExposedMethod(defaults = {"null", "-1"}, doc = BuiltinDocs.str_split_doc) + final PyList str_split(String sep, int maxsplit) { + if (sep != null) { + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + return splitfields(sep, maxsplit); + } + + PyList list = new PyList(); + + char[] chars = string.toCharArray(); + int n=chars.length; + + if (maxsplit < 0) + maxsplit = n; + + int splits=0; + int index=0; + while (index < n && splits < maxsplit) { + while (index < n && Character.isWhitespace(chars[index])) + index++; + if (index == n) + break; + int start = index; + + while (index < n && !Character.isWhitespace(chars[index])) + index++; + list.append(fromSubstring(start, index)); + splits++; + } + while (index < n && Character.isWhitespace(chars[index])) + index++; + if (index < n) { + list.append(fromSubstring(index, n)); + } + return list; + } + + public PyList rsplit() { + return str_rsplit(null, -1); + } + + public PyList rsplit(String sep) { + return str_rsplit(sep, -1); + } + + public PyList rsplit(String sep, int maxsplit) { + return str_rsplit(sep, maxsplit); + } + + @ExposedMethod(defaults = {"null", "-1"}, doc = BuiltinDocs.str_rsplit_doc) + final PyList str_rsplit(String sep, int maxsplit) { + if (sep != null) { + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + PyList list = rsplitfields(sep, maxsplit); + list.reverse(); + return list; + } + + PyList list = new PyList(); + char[] chars = string.toCharArray(); + + if (maxsplit < 0) { + maxsplit = chars.length; + } + + int splits = 0; + int i = chars.length - 1; + + while (i > -1 && Character.isWhitespace(chars[i])) { + i--; + } + if (i == -1) { + return list; + } + + while (splits < maxsplit) { + while (i > -1 && Character.isWhitespace(chars[i])) { + i--; + } + if (i == -1) { + break; + } + + int nextWsChar = i; + while (nextWsChar > -1 && !Character.isWhitespace(chars[nextWsChar])) { + nextWsChar--; + } + if (nextWsChar == -1) { + break; + } + + splits++; + list.add(fromSubstring(nextWsChar + 1, i + 1)); + i = nextWsChar; + } + while (i > -1 && Character.isWhitespace(chars[i])) { + i--; + } + if (i > -1) { + list.add(fromSubstring(0,i+1)); + } + list.reverse(); + return list; + } + + public PyTuple partition(PyObject sepObj) { + return str_partition(sepObj); + } + + @ExposedMethod(doc = BuiltinDocs.str_partition_doc) + final PyTuple str_partition(PyObject sepObj) { + String sep; + + if (sepObj instanceof PyNewUnicode) { + return unicodePartition(sepObj); + } else if (sepObj instanceof PyNewString) { + sep = ((PyNewString)sepObj).string; + } else { + throw Py.TypeError("expected a character buffer object"); + } + + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + + int index = string.indexOf(sep); + if (index != -1) { + return new PyTuple(fromSubstring(0, index), sepObj, + fromSubstring(index + sep.length(), string.length())); + } else { + return new PyTuple(this, Py.EmptyString, Py.EmptyString); + } + } + + final PyTuple unicodePartition(PyObject sepObj) { + PyUnicode strObj = __unicode__(); + String str = strObj.string; + + // Will throw a TypeError if not a basestring + String sep = sepObj.asString(); + sepObj = sepObj.__unicode__(); + + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + + int index = str.indexOf(sep); + if (index != -1) { + return new PyTuple(strObj.fromSubstring(0, index), sepObj, + strObj.fromSubstring(index + sep.length(), str.length())); + } else { + PyUnicode emptyUnicode = Py.newUnicode(""); + return new PyTuple(this, emptyUnicode, emptyUnicode); + } + } + + public PyTuple rpartition(PyObject sepObj) { + return str_rpartition(sepObj); + } + + @ExposedMethod(doc = BuiltinDocs.str_rpartition_doc) + final PyTuple str_rpartition(PyObject sepObj) { + String sep; + + if (sepObj instanceof PyNewUnicode) { + return unicodePartition(sepObj); + } else if (sepObj instanceof PyNewString) { + sep = ((PyNewString)sepObj).string; + } else { + throw Py.TypeError("expected a character buffer object"); + } + + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + + int index = string.lastIndexOf(sep); + if (index != -1) { + return new PyTuple(fromSubstring(0, index), sepObj, + fromSubstring(index + sep.length(), string.length())); + } else { + return new PyTuple(Py.EmptyString, Py.EmptyString, this); + } + } + + final PyTuple unicodeRpartition(PyObject sepObj) { + PyUnicode strObj = __unicode__(); + String str = strObj.string; + + // Will throw a TypeError if not a basestring + String sep = sepObj.asString(); + sepObj = sepObj.__unicode__(); + + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + + int index = str.lastIndexOf(sep); + if (index != -1) { + return new PyTuple(strObj.fromSubstring(0, index), sepObj, + strObj.fromSubstring(index + sep.length(), str.length())); + } else { + PyUnicode emptyUnicode = Py.newUnicode(""); + return new PyTuple(emptyUnicode, emptyUnicode, this); + } + } + + private PyList splitfields(String sep, int maxsplit) { + PyList list = new PyList(); + + int length = string.length(); + if (maxsplit < 0) + maxsplit = length + 1; + + int lastbreak = 0; + int splits = 0; + int sepLength = sep.length(); + int index; + if((sep.length() == 0) && (maxsplit != 0)) { + index = string.indexOf(sep, lastbreak); + list.append(fromSubstring(lastbreak, index)); + splits++; + } + while (splits < maxsplit) { + index = string.indexOf(sep, lastbreak); + if (index == -1) + break; + if(sep.length() == 0) + index++; + splits += 1; + list.append(fromSubstring(lastbreak, index)); + lastbreak = index + sepLength; + } + if (lastbreak <= length) { + list.append(fromSubstring(lastbreak, length)); + } + return list; + } + + private PyList rsplitfields(String sep, int maxsplit) { + PyList list = new PyList(); + + int length = string.length(); + if (maxsplit < 0) { + maxsplit = length + 1; + } + + int lastbreak = length; + int splits = 0; + int index = length; + int sepLength = sep.length(); + + while (index > 0 && splits < maxsplit) { + int i = string.lastIndexOf(sep, index - sepLength); + if (i == index) { + i -= sepLength; + } + if (i < 0) { + break; + } + splits++; + list.append(fromSubstring(i + sepLength, lastbreak)); + lastbreak = i; + index = i; + + } + list.append(fromSubstring(0, lastbreak)); + return list; + } + + public PyList splitlines() { + return str_splitlines(false); + } + + public PyList splitlines(boolean keepends) { + return str_splitlines(keepends); + } + + @ExposedMethod(defaults = "false", doc = BuiltinDocs.str_splitlines_doc) + final PyList str_splitlines(boolean keepends) { + PyList list = new PyList(); + + char[] chars = string.toCharArray(); + int n=chars.length; + + int j = 0; + for (int i = 0; i < n; ) { + /* Find a line and append it */ + while (i < n && chars[i] != '\n' && chars[i] != '\r' && + Character.getType(chars[i]) != Character.LINE_SEPARATOR) + i++; + + /* Skip the line break reading CRLF as one line break */ + int eol = i; + if (i < n) { + if (chars[i] == '\r' && i + 1 < n && chars[i+1] == '\n') + i += 2; + else + i++; + if (keepends) + eol = i; + } + list.append(fromSubstring(j, eol)); + j = i; + } + if (j < n) { + list.append(fromSubstring(j, n)); + } + return list; + } + + protected PyNewString fromSubstring(int begin, int end) { + return createInstance(string.substring(begin, end), true); + } + + public int index(String sub) { + return str_index(sub, 0, null); + } + + public int index(String sub, int start) { + return str_index(sub, start, null); + } + + public int index(String sub, int start, int end) { + return str_index(sub, start, Py.newInteger(end)); + } + + @ExposedMethod(defaults = {"0", "null"}, doc = BuiltinDocs.str_index_doc) + final int str_index(String sub, int start, PyObject end) { + int index = str_find(sub, start, end); + if (index == -1) + throw Py.ValueError("substring not found in string.index"); + return index; + } + + public int rindex(String sub) { + return str_rindex(sub, 0, null); + } + + public int rindex(String sub, int start) { + return str_rindex(sub, start, null); + } + + public int rindex(String sub, int start, int end) { + return str_rindex(sub, start, Py.newInteger(end)); + } + + @ExposedMethod(defaults = {"0", "null"}, doc = BuiltinDocs.str_rindex_doc) + final int str_rindex(String sub, int start, PyObject end) { + int index = str_rfind(sub, start, end); + if(index == -1) + throw Py.ValueError("substring not found in string.rindex"); + return index; + } + + public int count(String sub) { + return str_count(sub, 0, null); + } + + public int count(String sub, int start) { + return str_count(sub, start, null); + } + + public int count(String sub, int start, int end) { + return str_count(sub, start, Py.newInteger(end)); + } + + @ExposedMethod(defaults = {"0", "null"}, doc = BuiltinDocs.str_count_doc) + final int str_count(String sub, int start, PyObject end) { + int[] indices = translateIndices(start, end); + int n = sub.length(); + if(n == 0) { + if (start > string.length()) { + return 0; + } + return indices[1] - indices[0] + 1; + } + int count = 0; + while(true){ + int index = string.indexOf(sub, indices[0]); + indices[0] = index + n; + if(indices[0] > indices[1] || index == -1) { + break; + } + count++; + } + return count; + } + + public int find(String sub) { + return str_find(sub, 0, null); + } + + public int find(String sub, int start) { + return str_find(sub, start, null); + } + + public int find(String sub, int start, int end) { + return str_find(sub, start, Py.newInteger(end)); + } + + @ExposedMethod(defaults = {"0", "null"}, doc = BuiltinDocs.str_find_doc) + final int str_find(String sub, int start, PyObject end) { + int[] indices = translateIndices(start, end); + int index = string.indexOf(sub, indices[0]); + if (index < start || index > indices[1]) { + return -1; + } + return index; + } + + public int rfind(String sub) { + return str_rfind(sub, 0, null); + } + + public int rfind(String sub, int start) { + return str_rfind(sub, start, null); + } + + public int rfind(String sub, int start, int end) { + return str_rfind(sub, start, Py.newInteger(end)); + } + + @ExposedMethod(defaults = {"0", "null"}, doc = BuiltinDocs.str_rfind_doc) + final int str_rfind(String sub, int start, PyObject end) { + int[] indices = translateIndices(start, end); + int index = string.lastIndexOf(sub, indices[1] - sub.length()); + if (index < start) { + return -1; + } + return index; + } + + public double atof() { + StringBuilder s = null; + int n = string.length(); + for (int i = 0; i < n; i++) { + char ch = string.charAt(i); + if (ch == '\u0000') { + throw Py.ValueError("null byte in argument for float()"); + } + if (Character.isDigit(ch)) { + if (s == null) + s = new StringBuilder(string); + int val = Character.digit(ch, 10); + s.setCharAt(i, Character.forDigit(val, 10)); + } + } + String sval = string; + if (s != null) + sval = s.toString(); + try { + // Double.valueOf allows format specifier ("d" or "f") at the end + String lowSval = sval.toLowerCase(); + if (lowSval.equals("nan")) return Double.NaN; + else if (lowSval.equals("inf")) return Double.POSITIVE_INFINITY; + else if (lowSval.equals("-inf")) return Double.NEGATIVE_INFINITY; + + if (lowSval.endsWith("d") || lowSval.endsWith("f")) { + throw new NumberFormatException("format specifiers not allowed"); + } + return Double.valueOf(sval).doubleValue(); + } + catch (NumberFormatException exc) { + throw Py.ValueError("invalid literal for __float__: "+string); + } + } + + public int atoi() { + return atoi(10); + } + + public int atoi(int base) { + if ((base != 0 && base < 2) || (base > 36)) { + throw Py.ValueError("invalid base for atoi()"); + } + + int b = 0; + int e = string.length(); + + while (b < e && Character.isWhitespace(string.charAt(b))) + b++; + + while (e > b && Character.isWhitespace(string.charAt(e-1))) + e--; + + char sign = 0; + if (b < e) { + sign = string.charAt(b); + if (sign == '-' || sign == '+') { + b++; + while (b < e && Character.isWhitespace(string.charAt(b))) b++; + } + + if (base == 0 || base == 16) { + if (string.charAt(b) == '0') { + if (b < e-1 && + Character.toUpperCase(string.charAt(b+1)) == 'X') { + base = 16; + b += 2; + } else { + if (base == 0) + base = 8; + } + } + } + } + + if (base == 0) + base = 10; + + String s = string; + if (b > 0 || e < string.length()) + s = string.substring(b, e); + + try { + BigInteger bi; + if (sign == '-') { + bi = new BigInteger("-" + s, base); + } else + bi = new BigInteger(s, base); + if (bi.compareTo(PyInteger.maxInt) > 0 || bi.compareTo(PyInteger.minInt) < 0) { + throw Py.OverflowError("long int too large to convert to int"); + } + return bi.intValue(); + } catch (NumberFormatException exc) { + throw Py.ValueError("invalid literal for int() with base " + base + ": " + string); + } catch (StringIndexOutOfBoundsException exc) { + throw Py.ValueError("invalid literal for int() with base " + base + ": " + string); + } + } + + public PyLong atol() { + return atol(10); + } + + public PyLong atol(int base) { + String str = string; + int b = 0; + int e = str.length(); + + while (b < e && Character.isWhitespace(str.charAt(b))) + b++; + + while (e > b && Character.isWhitespace(str.charAt(e-1))) + e--; + + + char sign = 0; + if (b < e) { + sign = string.charAt(b); + if (sign == '-' || sign == '+') { + b++; + while (b < e && Character.isWhitespace(str.charAt(b))) b++; + } + + + if (base == 0 || base == 16) { + if (string.charAt(b) == '0') { + if (b < e-1 && + Character.toUpperCase(string.charAt(b+1)) == 'X') { + base = 16; + b += 2; + } else { + if (base == 0) + base = 8; + } + } + } + } + if (base == 0) + base = 10; + + if (base < 2 || base > 36) + throw Py.ValueError("invalid base for long literal:" + base); + + // if the base >= 22, then an 'l' or 'L' is a digit! + if (base < 22 && e > b && (str.charAt(e-1) == 'L' || str.charAt(e-1) == 'l')) + e--; + + if (b > 0 || e < str.length()) + str = str.substring(b, e); + + try { + java.math.BigInteger bi = null; + if (sign == '-') + bi = new java.math.BigInteger("-" + str, base); + else + bi = new java.math.BigInteger(str, base); + return new PyLong(bi); + } catch (NumberFormatException exc) { + if (this instanceof PyNewUnicode) { + // TODO: here's a basic issue: do we use the BigInteger constructor + // above, or add an equivalent to CPython's PyNewUnicode_EncodeDecimal; + // we should note that the current error string does not quite match + // CPython regardless of the codec, that's going to require some more work + throw Py.UnicodeEncodeError("decimal", "codec can't encode character", + 0,0, "invalid decimal Unicode string"); + } + else { + throw Py.ValueError("invalid literal for long() with base " + base + ": " + string); + } + } catch (StringIndexOutOfBoundsException exc) { + throw Py.ValueError("invalid literal for long() with base " + base + ": " + string); + } + } + + private static String padding(int n, char pad) { + char[] chars = new char[n]; + for (int i=0; i<n; i++) + chars[i] = pad; + return new String(chars); + } + + private static char parse_fillchar(String function, String fillchar) { + if (fillchar == null) { return ' '; } + if (fillchar.length() != 1) { + throw Py.TypeError(function + "() argument 2 must be char, not str"); + } + return fillchar.charAt(0); + } + + public String ljust(int width) { + return str_ljust(width, null); + } + + public String ljust(int width, String padding) { + return str_ljust(width, padding); + } + + @ExposedMethod(defaults="null", doc = BuiltinDocs.str_ljust_doc) + final String str_ljust(int width, String fillchar) { + char pad = parse_fillchar("ljust", fillchar); + int n = width-string.length(); + if (n <= 0) + return string; + return string+padding(n, pad); + } + + public String rjust(int width) { + return str_rjust(width, null); + } + + @ExposedMethod(defaults="null", doc = BuiltinDocs.str_rjust_doc) + final String str_rjust(int width, String fillchar) { + char pad = parse_fillchar("rjust", fillchar); + int n = width-string.length(); + if (n <= 0) + return string; + return padding(n, pad)+string; + } + + public String center(int width) { + return str_center(width, null); + } + + @ExposedMethod(defaults="null", doc = BuiltinDocs.str_center_doc) + final String str_center(int width, String fillchar) { + char pad = parse_fillchar("center", fillchar); + int n = width-string.length(); + if (n <= 0) + return string; + int half = n/2; + if (n%2 > 0 && width%2 > 0) + half += 1; + + return padding(half, pad)+string+padding(n-half, pad); + } + + public String zfill(int width) { + return str_zfill(width); + } + + @ExposedMethod(doc = BuiltinDocs.str_zfill_doc) + final String str_zfill(int width) { + String s = string; + int n = s.length(); + if (n >= width) + return s; + char[] chars = new char[width]; + int nzeros = width-n; + int i=0; + int sStart=0; + if (n > 0) { + char start = s.charAt(0); + if (start == '+' || start == '-') { + chars[0] = start; + i += 1; + nzeros++; + sStart=1; + } + } + for(;i<nzeros; i++) { + chars[i] = '0'; + } + s.getChars(sStart, s.length(), chars, i); + return new String(chars); + } + + public String expandtabs() { + return str_expandtabs(8); + } + + public String expandtabs(int tabsize) { + return str_expandtabs(tabsize); + } + + @ExposedMethod(defaults = "8", doc = BuiltinDocs.str_expandtabs_doc) + final String str_expandtabs(int tabsize) { + String s = string; + StringBuilder buf = new StringBuilder((int)(s.length()*1.5)); + char[] chars = s.toCharArray(); + int n = chars.length; + int position = 0; + + for(int i=0; i<n; i++) { + char c = chars[i]; + if (c == '\t') { + int spaces = tabsize-position%tabsize; + position += spaces; + while (spaces-- > 0) { + buf.append(' '); + } + continue; + } + if (c == '\n' || c == '\r') { + position = -1; + } + buf.append(c); + position++; + } + return buf.toString(); + } + + public String capitalize() { + return str_capitalize(); + } + + @ExposedMethod(doc = BuiltinDocs.str_capitalize_doc) + final String str_capitalize() { + if (string.length() == 0) + return string; + String first = string.substring(0,1).toUpperCase(); + return first.concat(string.substring(1).toLowerCase()); + } + + @ExposedMethod(defaults = "null", doc = BuiltinDocs.str_replace_doc) + final PyNewString str_replace(PyObject oldPiece, PyObject newPiece, PyObject maxsplit) { + if(!(oldPiece instanceof PyNewString) || !(newPiece instanceof PyNewString)) { + throw Py.TypeError("str or unicode required for replace"); + } + + return replace((PyNewString)oldPiece, (PyNewString)newPiece, maxsplit == null ? -1 : maxsplit.asInt()); + } + + protected PyNewString replace(PyNewString oldPiece, PyNewString newPiece, int maxsplit) { + int len = string.length(); + int old_len = oldPiece.string.length(); + if (len == 0) { + if (max... [truncated message content] |
From: <zy...@us...> - 2009-06-20 16:41:20
|
Revision: 6487 http://jython.svn.sourceforge.net/jython/?rev=6487&view=rev Author: zyasoft Date: 2009-06-20 16:41:18 +0000 (Sat, 20 Jun 2009) Log Message: ----------- Created branch to rewrite PyString to use byte[] instead of String Added Paths: ----------- branches/newstr/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-06-20 16:40:31
|
Revision: 6486 http://jython.svn.sourceforge.net/jython/?rev=6486&view=rev Author: zyasoft Date: 2009-06-20 16:40:29 +0000 (Sat, 20 Jun 2009) Log Message: ----------- Created branch for unicodedata implemented in Java Added Paths: ----------- branches/unicodedata/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-19 01:22:15
|
Revision: 6485 http://jython.svn.sourceforge.net/jython/?rev=6485&view=rev Author: fwierzbicki Date: 2009-06-19 01:22:13 +0000 (Fri, 19 Jun 2009) Log Message: ----------- Include some abc code from CPython, fix literal support in GrammarActions. Modified Paths: -------------- branches/jy26/CPythonLib.includes branches/jy26/src/org/python/antlr/GrammarActions.java branches/jy26/src/org/python/core/PySystemState.java Added Paths: ----------- branches/jy26/Lib/_abcoll.py Modified: branches/jy26/CPythonLib.includes =================================================================== --- branches/jy26/CPythonLib.includes 2009-06-19 01:02:53 UTC (rev 6484) +++ branches/jy26/CPythonLib.includes 2009-06-19 01:22:13 UTC (rev 6485) @@ -16,6 +16,7 @@ _MozillaCookieJar.py _strptime.py _threading_local.py +abc.py aifc.py anydbm.py atexit.py Added: branches/jy26/Lib/_abcoll.py =================================================================== --- branches/jy26/Lib/_abcoll.py (rev 0) +++ branches/jy26/Lib/_abcoll.py 2009-06-19 01:22:13 UTC (rev 6485) @@ -0,0 +1,563 @@ +# Copyright 2007 Google, Inc. All Rights Reserved. +# Licensed to PSF under a Contributor Agreement. + +"""Abstract Base Classes (ABCs) for collections, according to PEP 3119. + +DON'T USE THIS MODULE DIRECTLY! The classes here should be imported +via collections; they are defined here only to alleviate certain +bootstrapping issues. Unit tests are in test_collections. +""" + +from abc import ABCMeta, abstractmethod +import sys + +__all__ = ["Hashable", "Iterable", "Iterator", + "Sized", "Container", "Callable", + "Set", "MutableSet", + "Mapping", "MutableMapping", + "MappingView", "KeysView", "ItemsView", "ValuesView", + "Sequence", "MutableSequence", + ] + +### ONE-TRICK PONIES ### + +class Hashable: + __metaclass__ = ABCMeta + + @abstractmethod + def __hash__(self): + return 0 + + @classmethod + def __subclasshook__(cls, C): + if cls is Hashable: + for B in C.__mro__: + if "__hash__" in B.__dict__: + if B.__dict__["__hash__"]: + return True + break + return NotImplemented + + +class Iterable: + __metaclass__ = ABCMeta + + @abstractmethod + def __iter__(self): + while False: + yield None + + @classmethod + def __subclasshook__(cls, C): + if cls is Iterable: + if any("__iter__" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + +Iterable.register(str) + + +class Iterator(Iterable): + + @abstractmethod + def next(self): + raise StopIteration + + def __iter__(self): + return self + + @classmethod + def __subclasshook__(cls, C): + if cls is Iterator: + if any("next" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + + +class Sized: + __metaclass__ = ABCMeta + + @abstractmethod + def __len__(self): + return 0 + + @classmethod + def __subclasshook__(cls, C): + if cls is Sized: + if any("__len__" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + + +class Container: + __metaclass__ = ABCMeta + + @abstractmethod + def __contains__(self, x): + return False + + @classmethod + def __subclasshook__(cls, C): + if cls is Container: + if any("__contains__" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + + +class Callable: + __metaclass__ = ABCMeta + + @abstractmethod + def __call__(self, *args, **kwds): + return False + + @classmethod + def __subclasshook__(cls, C): + if cls is Callable: + if any("__call__" in B.__dict__ for B in C.__mro__): + return True + return NotImplemented + + +### SETS ### + + +class Set(Sized, Iterable, Container): + """A set is a finite, iterable container. + + This class provides concrete generic implementations of all + methods except for __contains__, __iter__ and __len__. + + To override the comparisons (presumably for speed, as the + semantics are fixed), all you have to do is redefine __le__ and + then the other operations will automatically follow suit. + """ + + def __le__(self, other): + if not isinstance(other, Set): + return NotImplemented + if len(self) > len(other): + return False + for elem in self: + if elem not in other: + return False + return True + + def __lt__(self, other): + if not isinstance(other, Set): + return NotImplemented + return len(self) < len(other) and self.__le__(other) + + def __gt__(self, other): + if not isinstance(other, Set): + return NotImplemented + return other < self + + def __ge__(self, other): + if not isinstance(other, Set): + return NotImplemented + return other <= self + + def __eq__(self, other): + if not isinstance(other, Set): + return NotImplemented + return len(self) == len(other) and self.__le__(other) + + def __ne__(self, other): + return not (self == other) + + @classmethod + def _from_iterable(cls, it): + '''Construct an instance of the class from any iterable input. + + Must override this method if the class constructor signature + does not accept an iterable for an input. + ''' + return cls(it) + + def __and__(self, other): + if not isinstance(other, Iterable): + return NotImplemented + return self._from_iterable(value for value in other if value in self) + + def isdisjoint(self, other): + for value in other: + if value in self: + return False + return True + + def __or__(self, other): + if not isinstance(other, Iterable): + return NotImplemented + chain = (e for s in (self, other) for e in s) + return self._from_iterable(chain) + + def __sub__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return self._from_iterable(value for value in self + if value not in other) + + def __xor__(self, other): + if not isinstance(other, Set): + if not isinstance(other, Iterable): + return NotImplemented + other = self._from_iterable(other) + return (self - other) | (other - self) + + # Sets are not hashable by default, but subclasses can change this + __hash__ = None + + def _hash(self): + """Compute the hash value of a set. + + Note that we don't define __hash__: not all sets are hashable. + But if you define a hashable set type, its __hash__ should + call this function. + + This must be compatible __eq__. + + All sets ought to compare equal if they contain the same + elements, regardless of how they are implemented, and + regardless of the order of the elements; so there's not much + freedom for __eq__ or __hash__. We match the algorithm used + by the built-in frozenset type. + """ + MAX = sys.maxint + MASK = 2 * MAX + 1 + n = len(self) + h = 1927868237 * (n + 1) + h &= MASK + for x in self: + hx = hash(x) + h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167 + h &= MASK + h = h * 69069 + 907133923 + h &= MASK + if h > MAX: + h -= MASK + 1 + if h == -1: + h = 590923713 + return h + +Set.register(frozenset) + + +class MutableSet(Set): + + @abstractmethod + def add(self, value): + """Add an element.""" + raise NotImplementedError + + @abstractmethod + def discard(self, value): + """Remove an element. Do not raise an exception if absent.""" + raise NotImplementedError + + def remove(self, value): + """Remove an element. If not a member, raise a KeyError.""" + if value not in self: + raise KeyError(value) + self.discard(value) + + def pop(self): + """Return the popped value. Raise KeyError if empty.""" + it = iter(self) + try: + value = next(it) + except StopIteration: + raise KeyError + self.discard(value) + return value + + def clear(self): + """This is slow (creates N new iterators!) but effective.""" + try: + while True: + self.pop() + except KeyError: + pass + + def __ior__(self, it): + for value in it: + self.add(value) + return self + + def __iand__(self, it): + for value in (self - it): + self.discard(value) + return self + + def __ixor__(self, it): + if not isinstance(it, Set): + it = self._from_iterable(it) + for value in it: + if value in self: + self.discard(value) + else: + self.add(value) + return self + + def __isub__(self, it): + for value in it: + self.discard(value) + return self + +MutableSet.register(set) + + +### MAPPINGS ### + + +class Mapping(Sized, Iterable, Container): + + @abstractmethod + def __getitem__(self, key): + raise KeyError + + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + def __contains__(self, key): + try: + self[key] + except KeyError: + return False + else: + return True + + def iterkeys(self): + return iter(self) + + def itervalues(self): + for key in self: + yield self[key] + + def iteritems(self): + for key in self: + yield (key, self[key]) + + def keys(self): + return list(self) + + def items(self): + return [(key, self[key]) for key in self] + + def values(self): + return [self[key] for key in self] + + # Mappings are not hashable by default, but subclasses can change this + __hash__ = None + + def __eq__(self, other): + return isinstance(other, Mapping) and \ + dict(self.items()) == dict(other.items()) + + def __ne__(self, other): + return not (self == other) + +class MappingView(Sized): + + def __init__(self, mapping): + self._mapping = mapping + + def __len__(self): + return len(self._mapping) + + +class KeysView(MappingView, Set): + + def __contains__(self, key): + return key in self._mapping + + def __iter__(self): + for key in self._mapping: + yield key + + +class ItemsView(MappingView, Set): + + def __contains__(self, item): + key, value = item + try: + v = self._mapping[key] + except KeyError: + return False + else: + return v == value + + def __iter__(self): + for key in self._mapping: + yield (key, self._mapping[key]) + + +class ValuesView(MappingView): + + def __contains__(self, value): + for key in self._mapping: + if value == self._mapping[key]: + return True + return False + + def __iter__(self): + for key in self._mapping: + yield self._mapping[key] + + +class MutableMapping(Mapping): + + @abstractmethod + def __setitem__(self, key, value): + raise KeyError + + @abstractmethod + def __delitem__(self, key): + raise KeyError + + __marker = object() + + def pop(self, key, default=__marker): + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def popitem(self): + try: + key = next(iter(self)) + except StopIteration: + raise KeyError + value = self[key] + del self[key] + return key, value + + def clear(self): + try: + while True: + self.popitem() + except KeyError: + pass + + def update(self, other=(), **kwds): + if isinstance(other, Mapping): + for key in other: + self[key] = other[key] + elif hasattr(other, "keys"): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + def setdefault(self, key, default=None): + try: + return self[key] + except KeyError: + self[key] = default + return default + +MutableMapping.register(dict) + + +### SEQUENCES ### + + +class Sequence(Sized, Iterable, Container): + """All the operations on a read-only sequence. + + Concrete subclasses must override __new__ or __init__, + __getitem__, and __len__. + """ + + @abstractmethod + def __getitem__(self, index): + raise IndexError + + def __iter__(self): + i = 0 + try: + while True: + v = self[i] + yield v + i += 1 + except IndexError: + return + + def __contains__(self, value): + for v in self: + if v == value: + return True + return False + + def __reversed__(self): + for i in reversed(range(len(self))): + yield self[i] + + def index(self, value): + for i, v in enumerate(self): + if v == value: + return i + raise ValueError + + def count(self, value): + return sum(1 for v in self if v == value) + +Sequence.register(tuple) +Sequence.register(basestring) +if not sys.platform.startswith('java'): + Sequence.register(buffer) +Sequence.register(xrange) + + +class MutableSequence(Sequence): + + @abstractmethod + def __setitem__(self, index, value): + raise IndexError + + @abstractmethod + def __delitem__(self, index): + raise IndexError + + @abstractmethod + def insert(self, index, value): + raise IndexError + + def append(self, value): + self.insert(len(self), value) + + def reverse(self): + n = len(self) + for i in range(n//2): + self[i], self[n-i-1] = self[n-i-1], self[i] + + def extend(self, values): + for v in values: + self.append(v) + + def pop(self, index=-1): + v = self[index] + del self[index] + return v + + def remove(self, value): + del self[self.index(value)] + + def __iadd__(self, values): + self.extend(values) + return self + +MutableSequence.register(list) Modified: branches/jy26/src/org/python/antlr/GrammarActions.java =================================================================== --- branches/jy26/src/org/python/antlr/GrammarActions.java 2009-06-19 01:02:53 UTC (rev 6484) +++ branches/jy26/src/org/python/antlr/GrammarActions.java 2009-06-19 01:22:13 UTC (rev 6485) @@ -345,6 +345,12 @@ if (s.startsWith("0x") || s.startsWith("0X")) { radix = 16; s = s.substring(2, s.length()); + } 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()); } else if (s.startsWith("0")) { radix = 8; } @@ -410,6 +416,10 @@ int end; boolean ustring = false; + if (quoteChar == 'b' || quoteChar == 'B') { + start++; + } + if (quoteChar == 'u' || quoteChar == 'U') { ustring = true; start++; Modified: branches/jy26/src/org/python/core/PySystemState.java =================================================================== --- branches/jy26/src/org/python/core/PySystemState.java 2009-06-19 01:02:53 UTC (rev 6484) +++ branches/jy26/src/org/python/core/PySystemState.java 2009-06-19 01:22:13 UTC (rev 6485) @@ -103,6 +103,9 @@ private static boolean initialized = false; + //XXX: placeholder. + public static final boolean py3kwarning = false; + /** The arguments passed to this program on the command line. */ public PyList argv = new PyList(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-19 01:13:40
|
Revision: 6484 http://jython.svn.sourceforge.net/jython/?rev=6484&view=rev Author: fwierzbicki Date: 2009-06-19 01:02:53 +0000 (Fri, 19 Jun 2009) Log Message: ----------- Point at 2.6 CPythonLib, fix with statement default. Modified Paths: -------------- branches/jy26/src/org/python/compiler/CodeCompiler.java branches/jy26/src/org/python/compiler/Future.java Property Changed: ---------------- branches/jy26/ Property changes on: branches/jy26 ___________________________________________________________________ Modified: svn:externals - CPythonLib -r70085 http://svn.python.org/projects/python/branches/release25-maint/Lib/ + CPythonLib -r73469 http://svn.python.org/projects/python/branches/release26-maint/Lib/ Modified: branches/jy26/src/org/python/compiler/CodeCompiler.java =================================================================== --- branches/jy26/src/org/python/compiler/CodeCompiler.java 2009-06-18 15:53:09 UTC (rev 6483) +++ branches/jy26/src/org/python/compiler/CodeCompiler.java 2009-06-19 01:02:53 UTC (rev 6484) @@ -2267,10 +2267,6 @@ @Override public Object visitWith(With node) throws Exception { - if (!module.getFutures().withStatementSupported()) { - throw new ParseException("'with' will become a reserved keyword in Python 2.6", node); - } - final Label label_body_start = new Label(); final Label label_body_end = new Label(); final Label label_catch = new Label(); Modified: branches/jy26/src/org/python/compiler/Future.java =================================================================== --- branches/jy26/src/org/python/compiler/Future.java 2009-06-18 15:53:09 UTC (rev 6483) +++ branches/jy26/src/org/python/compiler/Future.java 2009-06-19 01:02:53 UTC (rev 6484) @@ -56,8 +56,6 @@ if (cflags != null) { if (cflags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) FutureFeature.division.addTo(features); - if (cflags.isFlagSet(CodeFlag.CO_FUTURE_WITH_STATEMENT)) - FutureFeature.with_statement.addTo(features); if (cflags.isFlagSet(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT)) FutureFeature.absolute_import.addTo(features); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-18 15:53:11
|
Revision: 6483 http://jython.svn.sourceforge.net/jython/?rev=6483&view=rev Author: fwierzbicki Date: 2009-06-18 15:53:09 +0000 (Thu, 18 Jun 2009) Log Message: ----------- Initialized merge tracking via "svnmerge" with revisions "1-6052" from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython Property Changed: ---------------- trunk/sandbox/wierzbicki/test27/ Property changes on: trunk/sandbox/wierzbicki/test27 ___________________________________________________________________ Modified: svnmerge-integrated - /branches/pbcvm:1-6045 + /branches/pbcvm:1-6045 /trunk/jython:1-6052 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-18 15:44:35
|
Revision: 6482 http://jython.svn.sourceforge.net/jython/?rev=6482&view=rev Author: fwierzbicki Date: 2009-06-18 15:44:30 +0000 (Thu, 18 Jun 2009) Log Message: ----------- small fix to jysite. Modified Paths: -------------- trunk/sandbox/wierzbicki/jysite/writer/jysite.py Modified: trunk/sandbox/wierzbicki/jysite/writer/jysite.py =================================================================== --- trunk/sandbox/wierzbicki/jysite/writer/jysite.py 2009-06-18 15:43:49 UTC (rev 6481) +++ trunk/sandbox/wierzbicki/jysite/writer/jysite.py 2009-06-18 15:44:30 UTC (rev 6482) @@ -107,7 +107,7 @@ buffer.append('</div>') buffer.append('<div id="content">') else: - raise "%s does not exisi." % navleft + raise Exception("%s does not exisi." % navleft) return "\n".join(buffer) def get_body_suffix(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-18 15:43:51
|
Revision: 6481 http://jython.svn.sourceforge.net/jython/?rev=6481&view=rev Author: fwierzbicki Date: 2009-06-18 15:43:49 +0000 (Thu, 18 Jun 2009) Log Message: ----------- kill another branch in sandbox (again, branches should not live in sandbox - my bad) Removed Paths: ------------- trunk/sandbox/wierzbicki/jlr_experiment/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-18 14:28:39
|
Revision: 6480 http://jython.svn.sourceforge.net/jython/?rev=6480&view=rev Author: fwierzbicki Date: 2009-06-18 14:28:22 +0000 (Thu, 18 Jun 2009) Log Message: ----------- killing this branch. Branches shouldn't live in sandbox anyway... Removed Paths: ------------- trunk/sandbox/wierzbicki/grammar26/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-18 14:26:07
|
Revision: 6479 http://jython.svn.sourceforge.net/jython/?rev=6479&view=rev Author: fwierzbicki Date: 2009-06-18 14:25:46 +0000 (Thu, 18 Jun 2009) Log Message: ----------- Grammar changes from 2.5 to 2.6: * binary literals * 'as' in except * extended arglist Modified Paths: -------------- branches/jy26/grammar/Python.g Modified: branches/jy26/grammar/Python.g =================================================================== --- branches/jy26/grammar/Python.g 2009-06-17 21:09:27 UTC (rev 6478) +++ branches/jy26/grammar/Python.g 2009-06-18 14:25:46 UTC (rev 6479) @@ -938,9 +938,9 @@ } ; -//except_clause: 'except' [test [',' test]] +//except_clause: 'except' [test [('as' | ',') test]] except_clause - : EXCEPT (t1=test[expr_contextType.Load] (COMMA t2=test[expr_contextType.Store])?)? COLON suite[!$suite.isEmpty() && $suite::continueIllegal] + : EXCEPT (t1=test[expr_contextType.Load] ((COMMA | AS) t2=test[expr_contextType.Store])?)? COLON suite[!$suite.isEmpty() && $suite::continueIllegal] -> ^(EXCEPT<ExceptHandler>[$EXCEPT, actions.castExpr($t1.tree), actions.castExpr($t2.tree), actions.castStmts($suite.stypes)]) ; @@ -1474,7 +1474,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(); @@ -1483,7 +1485,7 @@ } : argument[arguments, kws, gens, true] (COMMA argument[arguments, kws, gens, false])* (COMMA - ( STAR s=test[expr_contextType.Load] (COMMA DOUBLESTAR k=test[expr_contextType.Load])? + ( STAR s=test[expr_contextType.Load] (COMMA argument[arguments, kws, gens, false])* (COMMA DOUBLESTAR k=test[expr_contextType.Load])? | DOUBLESTAR k=test[expr_contextType.Load] )? )? @@ -1737,8 +1739,12 @@ INT : // Hex '0' ('x' | 'X') ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' )+ | // Octal - '0' ( '0' .. '7' )* - | '1'..'9' DIGITS* + '0' ('o' | 'O') ( '0' .. '7' )* + | '0' ( '0' .. '7' )* + | // Binary + '0' ('b' | 'B') ( '0' .. '1' )* + | // Decimal + '1'..'9' DIGITS* ; COMPLEX @@ -1757,7 +1763,7 @@ * should make us exit loop not continue. */ STRING - : ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? + : ('r'|'u'|'b'|'ur'|'R'|'U'|'B'|'UR'|'uR'|'Ur')? ( '\'\'\'' (options {greedy=false;}:TRIAPOS)* '\'\'\'' | '"""' (options {greedy=false;}:TRIQUOTE)* '"""' | '"' (ESC|~('\\'|'\n'|'"'))* '"' @@ -1771,7 +1777,7 @@ ; STRINGPART - : {partial}?=> ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? + : {partial}?=> ('r'|'u'|'b'|'ur'|'R'|'U'|'B'|'UR'|'uR'|'Ur')? ( '\'\'\'' ~('\'\'\'')* | '"""' ~('"""')* ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-17 21:09:28
|
Revision: 6478 http://jython.svn.sourceforge.net/jython/?rev=6478&view=rev Author: fwierzbicki Date: 2009-06-17 21:09:27 +0000 (Wed, 17 Jun 2009) Log Message: ----------- Temporary home for 2.6 grammar + features while we concentrate on 2.5.1 in trunk. Added Paths: ----------- branches/jy26/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Frank W. <fwi...@gm...> - 2009-06-16 19:46:38
|
Thanks Philip and Ches -- I uploaded the changes to the website. -Frank |
From: <pj...@us...> - 2009-06-16 19:29:41
|
Revision: 6477 http://jython.svn.sourceforge.net/jython/?rev=6477&view=rev Author: pjenvey Date: 2009-06-16 19:29:28 +0000 (Tue, 16 Jun 2009) Log Message: ----------- fix the install instructions link thanks Ches Martin Modified Paths: -------------- trunk/website/left.nav Modified: trunk/website/left.nav =================================================================== --- trunk/website/left.nav 2009-06-16 17:21:54 UTC (rev 6476) +++ trunk/website/left.nav 2009-06-16 19:29:28 UTC (rev 6477) @@ -6,7 +6,7 @@ menupageitem | Mailing Lists | http://sourceforge.net/mail/?group_id=12867 section | Wiki links menupageitem | Front page/News | http://wiki.python.org/jython/ -menupageitem | Installation | http://wiki.python.org/jython/InsallationInstructions +menupageitem | Installation | http://wiki.python.org/jython/InstallationInstructions menupageitem | FAQ | http://wiki.python.org/jython/JythonFaq menupageitem | Download | http://wiki.python.org/jython/DownloadInstructions menupageitem | User Guide | http://wiki.python.org/jython/UserGuide This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-16 17:22:00
|
Revision: 6476 http://jython.svn.sourceforge.net/jython/?rev=6476&view=rev Author: fwierzbicki Date: 2009-06-16 17:21:54 +0000 (Tue, 16 Jun 2009) Log Message: ----------- Release 2.5.0 tag Added Paths: ----------- tags/Release_2_5_0/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-16 17:18:50
|
Revision: 6475 http://jython.svn.sourceforge.net/jython/?rev=6475&view=rev Author: fwierzbicki Date: 2009-06-16 17:18:28 +0000 (Tue, 16 Jun 2009) Log Message: ----------- Release labels for 2.5.0 final. Modified Paths: -------------- trunk/jython/NEWS trunk/jython/README.txt trunk/jython/build.xml Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-06-11 11:56:08 UTC (rev 6474) +++ trunk/jython/NEWS 2009-06-16 17:18:28 UTC (rev 6475) @@ -1,5 +1,8 @@ Jython NEWS +Jython 2.5.0 + The same as rc4. + Jython 2.5.0 rc4 Bugs fixed - [ 1354 ] core language failures in interactive interpreter Modified: trunk/jython/README.txt =================================================================== --- trunk/jython/README.txt 2009-06-11 11:56:08 UTC (rev 6474) +++ trunk/jython/README.txt 2009-06-16 17:18:28 UTC (rev 6475) @@ -1,9 +1,11 @@ -Welcome to Jython 2.5rc4 -======================== +Welcome to Jython 2.5.0 +======================= -This is the fourth release candidate of the 2.5 version of Jython. Many bugs -are fixed in this release, and the regression tests now pass on Windows. See -the NEWS file for details. +This is the final release of the 2.5.0 version of Jython and brings us up to +language level compatibility with the 2.5 version of CPython. This release has +had a strong focus on CPython compatibility, and so this release of Jython can +run more pure Python apps then any previous release. Please see the NEWS file +for detailed release notes. The release was compiled on Mac OS X with JDK 5 and requires JDK 5 to run. Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-06-11 11:56:08 UTC (rev 6474) +++ trunk/jython/build.xml 2009-06-16 17:18:28 UTC (rev 6475) @@ -187,13 +187,13 @@ <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> <!-- The current version info --> - <property name="jython.version" value="2.5rc4+"/> - <property name="jython.version.noplus" value="2.5rc4"/> + <property name="jython.version" value="2.5.0+"/> + <property name="jython.version.noplus" value="2.5.0"/> <property name="jython.major_version" value="2"/> <property name="jython.minor_version" value="5"/> <property name="jython.micro_version" value="0"/> - <property name="jython.release_level" value="${PY_RELEASE_LEVEL_GAMMA}"/> - <property name="jython.release_serial" value="4"/> + <property name="jython.release_level" value="${PY_RELEASE_LEVEL_FINAL}"/> + <property name="jython.release_serial" value="0"/> <condition property="do.snapshot.build"> <isset property="snapshot.revision" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-06-11 11:56:09
|
Revision: 6474 http://jython.svn.sourceforge.net/jython/?rev=6474&view=rev Author: otmarhumbel Date: 2009-06-11 11:56:08 +0000 (Thu, 11 Jun 2009) Log Message: ----------- removal of unnecessary casts Modified Paths: -------------- trunk/jython/src/org/python/antlr/PythonTree.java trunk/jython/src/org/python/antlr/PythonTreeAdaptor.java Modified: trunk/jython/src/org/python/antlr/PythonTree.java =================================================================== --- trunk/jython/src/org/python/antlr/PythonTree.java 2009-06-11 11:55:18 UTC (rev 6473) +++ trunk/jython/src/org/python/antlr/PythonTree.java 2009-06-11 11:56:08 UTC (rev 6474) @@ -296,7 +296,7 @@ if ( t==null ) { return; // do nothing upon addChild(null) } - PythonTree childTree = (PythonTree)t; + PythonTree childTree = t; if ( childTree.isNil() ) { // t is an empty node possibly with children if ( this.children!=null && this.children == childTree.children ) { throw new RuntimeException("attempt to add child list to itself"); @@ -444,7 +444,7 @@ public void freshenParentAndChildIndexes(int offset) { int n = getChildCount(); for (int c = offset; c < n; c++) { - PythonTree child = (PythonTree)getChild(c); + PythonTree child = getChild(c); child.setChildIndex(c); child.setParent(this); } Modified: trunk/jython/src/org/python/antlr/PythonTreeAdaptor.java =================================================================== --- trunk/jython/src/org/python/antlr/PythonTreeAdaptor.java 2009-06-11 11:55:18 UTC (rev 6473) +++ trunk/jython/src/org/python/antlr/PythonTreeAdaptor.java 2009-06-11 11:56:08 UTC (rev 6474) @@ -72,7 +72,7 @@ // handle ^(nil real-node) if ( newRootTree.isNil() ) { int nc = newRootTree.getChildCount(); - if ( nc==1 ) newRootTree = (PythonTree)newRootTree.getChild(0); + if ( nc==1 ) newRootTree = newRootTree.getChild(0); else if ( nc >1 ) { // TODO: make tree run time exceptions hierarchy throw new RuntimeException("more than one node as root (TODO: make exception hierarchy)"); @@ -93,7 +93,7 @@ r = null; } else if ( r.getChildCount()==1 ) { - r = (PythonTree)r.getChild(0); + r = r.getChild(0); // whoever invokes rule will set parent and child index r.setParent(null); r.setChildIndex(-1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-06-11 11:55:22
|
Revision: 6473 http://jython.svn.sourceforge.net/jython/?rev=6473&view=rev Author: otmarhumbel Date: 2009-06-11 11:55:18 +0000 (Thu, 11 Jun 2009) Log Message: ----------- removal of unnecessary imports Modified Paths: -------------- trunk/jython/src/com/ziclix/python/sql/DataHandler.java trunk/jython/src/com/ziclix/python/sql/JDBC20DataHandler.java trunk/jython/src/com/ziclix/python/sql/Jython22DataHandler.java trunk/jython/src/com/ziclix/python/sql/handler/MySQLDataHandler.java trunk/jython/src/org/python/core/ParserFacade.java Modified: trunk/jython/src/com/ziclix/python/sql/DataHandler.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/DataHandler.java 2009-06-09 01:12:21 UTC (rev 6472) +++ trunk/jython/src/com/ziclix/python/sql/DataHandler.java 2009-06-11 11:55:18 UTC (rev 6473) @@ -12,7 +12,6 @@ import org.python.core.PyFile; import org.python.core.PyObject; import org.python.core.PyList; -import org.python.core.PyString; import org.python.core.util.StringUtil; import java.io.BufferedInputStream; Modified: trunk/jython/src/com/ziclix/python/sql/JDBC20DataHandler.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/JDBC20DataHandler.java 2009-06-09 01:12:21 UTC (rev 6472) +++ trunk/jython/src/com/ziclix/python/sql/JDBC20DataHandler.java 2009-06-11 11:55:18 UTC (rev 6473) @@ -8,12 +8,6 @@ */ package com.ziclix.python.sql; -import org.python.core.Py; -import org.python.core.PyFile; -import org.python.core.PyObject; -import org.python.core.PyString; -import org.python.core.util.StringUtil; - import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; @@ -27,6 +21,11 @@ import java.sql.SQLException; import java.sql.Types; +import org.python.core.Py; +import org.python.core.PyFile; +import org.python.core.PyObject; +import org.python.core.util.StringUtil; + /** * Support for JDBC 2.x type mappings, including Arrays, CLOBs and BLOBs. * Modified: trunk/jython/src/com/ziclix/python/sql/Jython22DataHandler.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/Jython22DataHandler.java 2009-06-09 01:12:21 UTC (rev 6472) +++ trunk/jython/src/com/ziclix/python/sql/Jython22DataHandler.java 2009-06-11 11:55:18 UTC (rev 6473) @@ -8,14 +8,6 @@ */ package com.ziclix.python.sql; -import org.python.core.Py; -import org.python.core.PyFile; -import org.python.core.PyLong; -import org.python.core.PyObject; -import org.python.core.PyList; -import org.python.core.PyString; -import org.python.core.util.StringUtil; - import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.InputStream; @@ -32,6 +24,13 @@ import java.sql.Timestamp; import java.sql.Types; +import org.python.core.Py; +import org.python.core.PyFile; +import org.python.core.PyList; +import org.python.core.PyLong; +import org.python.core.PyObject; +import org.python.core.util.StringUtil; + /** * A copy of the DataHandler class as it was before Jython 2.5. By that version, * some backward-incompatible changes was made, as returning datetime.* Modified: trunk/jython/src/com/ziclix/python/sql/handler/MySQLDataHandler.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/handler/MySQLDataHandler.java 2009-06-09 01:12:21 UTC (rev 6472) +++ trunk/jython/src/com/ziclix/python/sql/handler/MySQLDataHandler.java 2009-06-11 11:55:18 UTC (rev 6473) @@ -8,11 +8,6 @@ */ package com.ziclix.python.sql.handler; -import com.ziclix.python.sql.DataHandler; -import org.python.core.PyFile; -import org.python.core.PyObject; -import org.python.core.util.StringUtil; - import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -20,6 +15,12 @@ import java.sql.SQLException; import java.sql.Types; +import org.python.core.PyFile; +import org.python.core.PyObject; +import org.python.core.util.StringUtil; + +import com.ziclix.python.sql.DataHandler; + /** * MySQL specific data handling. * Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2009-06-09 01:12:21 UTC (rev 6472) +++ trunk/jython/src/org/python/core/ParserFacade.java 2009-06-11 11:55:18 UTC (rev 6473) @@ -21,14 +21,13 @@ import org.antlr.runtime.CharStream; import org.antlr.runtime.CommonTokenStream; - import org.python.antlr.BaseParser; -import org.python.antlr.ParseException; import org.python.antlr.NoCloseReaderStream; -import org.python.antlr.PythonTree; +import org.python.antlr.ParseException; import org.python.antlr.PythonLexer; import org.python.antlr.PythonPartial; import org.python.antlr.PythonTokenSource; +import org.python.antlr.PythonTree; import org.python.antlr.base.mod; import org.python.core.io.StreamIO; import org.python.core.io.TextIOInputStream; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-09 01:13:00
|
Revision: 6472 http://jython.svn.sourceforge.net/jython/?rev=6472&view=rev Author: fwierzbicki Date: 2009-06-09 01:12:21 +0000 (Tue, 09 Jun 2009) Log Message: ----------- Website tweaks to avoid 404s + new favicon. Modified Paths: -------------- trunk/website/archive/css/screen.css trunk/website/build.xml trunk/website/css/screen.css trunk/website/index.txt trunk/website/left.nav trunk/website/redirects/Project/books_articles.txt trunk/website/redirects/Project/bugs.txt trunk/website/redirects/Project/devfaq.txt trunk/website/redirects/Project/download.txt trunk/website/redirects/Project/history.txt trunk/website/redirects/Project/index.txt trunk/website/redirects/Project/installation.txt trunk/website/redirects/Project/jythonc.txt trunk/website/redirects/Project/license.txt trunk/website/redirects/Project/news.txt trunk/website/redirects/Project/roadmap.txt trunk/website/redirects/Project/todo.txt trunk/website/redirects/Project/userfaq.txt trunk/website/redirects/Project/userguide.txt trunk/website/redirects/css/screen.css Added Paths: ----------- trunk/website/favicon.ico trunk/website/robots.txt Modified: trunk/website/archive/css/screen.css =================================================================== --- trunk/website/archive/css/screen.css 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/archive/css/screen.css 2009-06-09 01:12:21 UTC (rev 6472) @@ -70,7 +70,6 @@ #top .header { float: left; width: 100%; - background: url("images/header_white_line.gif") repeat-x bottom; } #top .grouplogo { @@ -101,7 +100,6 @@ color: white; background-color: #000000; z-index:0; - background-image: url(images/rc-t-l-5-1header-2searchbox-3searchbox.png); background-repeat: no-repeat; background-position: top left; bottom: -1px; /* compensate for IE rendering issue */ @@ -125,10 +123,8 @@ margin: 0; list-style: none; } -/* background: #CFDCED url("images/tab-right.gif") no-repeat right top;*/ #tabs li { float: left; - background-image: url(images/rc-t-r-5-1header-2tab-unselected-3tab-unselected.png); background-repeat: no-repeat; background-position: top right; background-color: #000000; @@ -136,7 +132,6 @@ padding: 0; } -/*background: url("images/tab-left.gif") no-repeat left top;*/ #tabs li a { float: left; display: block; @@ -144,7 +139,6 @@ text-decoration: none; color: black; white-space: nowrap; - background-image: url(images/rc-t-l-5-1header-2tab-unselected-3tab-unselected.png); background-repeat: no-repeat; background-position: top left; padding: 5px 15px 4px; @@ -159,7 +153,6 @@ #top .header .current { background-color: #4C6C8F; - background-image: url(images/rc-t-r-5-1header-2tab-selected-3tab-selected.png); background-repeat: no-repeat; background-position: top right; } @@ -167,7 +160,6 @@ font-weight: bold; padding-bottom: 5px; color: white; - background-image: url(images/rc-t-l-5-1header-2tab-selected-3tab-selected.png); background-repeat: no-repeat; background-position: top left; } @@ -212,13 +204,11 @@ * Round corner */ #roundtop { - background-image: url(images/rc-t-r-15-1body-2menu-3menu.png); background-repeat: no-repeat; background-position: top right; } #roundbottom { - background-image: url(images/rc-b-r-15-1body-2menu-3menu.png); background-repeat: no-repeat; background-position: top right; } @@ -231,13 +221,11 @@ } .roundtopsmall { - background-image: url(images/rc-t-r-5-1header-2searchbox-3searchbox.png); background-repeat: no-repeat; background-position: top right; } #roundbottomsmall { - background-image: url(images/rc-b-r-5-1header-2tab-selected-3tab-selected.png); background-repeat: no-repeat; background-position: top right; } @@ -273,7 +261,6 @@ cursor:pointer; padding: 3px 12px; margin-left: 10px; - background-image: url('images/chapter.gif'); background-repeat: no-repeat; background-position: center left; font-weight : bold; @@ -291,7 +278,6 @@ #menu .menuitem { padding: 0px 0px 2px 12px; - background-image: url('images/page.gif'); background-repeat: no-repeat; background-position: center left; font-weight : normal; @@ -301,7 +287,6 @@ #menu .menupage { margin: 5px 0px 5px 10px; padding: 0px 3px 0px 12px; - background-image: url('images/current.gif'); background-repeat: no-repeat; background-position: top left; font-style : normal; @@ -413,7 +398,6 @@ padding-top: 5px; } .minitoc { - list-style-image: url('images/current.gif'); font-weight: normal; } li p { @@ -509,4 +493,4 @@ display: block; height: 16px; width: 16px; -} \ No newline at end of file +} Modified: trunk/website/build.xml =================================================================== --- trunk/website/build.xml 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/build.xml 2009-06-09 01:12:21 UTC (rev 6472) @@ -35,6 +35,7 @@ <copy todir="dist"> <fileset dir="."> <include name="*.txt"/> + <include name="favicon.ico"/> </fileset> <fileset dir="."> <include name="left.nav"/> @@ -74,6 +75,11 @@ <include name="left.nav"/> </fileset> </copy> + <copy todir="dist/Project"> + <fileset dir="."> + <include name="left.nav"/> + </fileset> + </copy> <apply verbose="true" executable="${rst2jysite.command}" dest="dist"> <arg line="--link-stylesheet" /> <arg line="--stylesheet=../css/html4css1.css" /> Modified: trunk/website/css/screen.css =================================================================== --- trunk/website/css/screen.css 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/css/screen.css 2009-06-09 01:12:21 UTC (rev 6472) @@ -70,7 +70,6 @@ #top .header { float: left; width: 100%; - background: url("images/header_white_line.gif") repeat-x bottom; } #top .grouplogo { @@ -101,7 +100,6 @@ color: white; background-color: #000000; z-index:0; - background-image: url(images/rc-t-l-5-1header-2searchbox-3searchbox.png); background-repeat: no-repeat; background-position: top left; bottom: -1px; /* compensate for IE rendering issue */ @@ -125,10 +123,8 @@ margin: 0; list-style: none; } -/* background: #CFDCED url("images/tab-right.gif") no-repeat right top;*/ #tabs li { float: left; - background-image: url(images/rc-t-r-5-1header-2tab-unselected-3tab-unselected.png); background-repeat: no-repeat; background-position: top right; background-color: #000000; @@ -136,7 +132,6 @@ padding: 0; } -/*background: url("images/tab-left.gif") no-repeat left top;*/ #tabs li a { float: left; display: block; @@ -144,7 +139,6 @@ text-decoration: none; color: black; white-space: nowrap; - background-image: url(images/rc-t-l-5-1header-2tab-unselected-3tab-unselected.png); background-repeat: no-repeat; background-position: top left; padding: 5px 15px 4px; @@ -159,7 +153,6 @@ #top .header .current { background-color: #4C6C8F; - background-image: url(images/rc-t-r-5-1header-2tab-selected-3tab-selected.png); background-repeat: no-repeat; background-position: top right; } @@ -167,7 +160,6 @@ font-weight: bold; padding-bottom: 5px; color: white; - background-image: url(images/rc-t-l-5-1header-2tab-selected-3tab-selected.png); background-repeat: no-repeat; background-position: top left; } @@ -212,13 +204,11 @@ * Round corner */ #roundtop { - background-image: url(images/rc-t-r-15-1body-2menu-3menu.png); background-repeat: no-repeat; background-position: top right; } #roundbottom { - background-image: url(images/rc-b-r-15-1body-2menu-3menu.png); background-repeat: no-repeat; background-position: top right; } @@ -231,13 +221,11 @@ } .roundtopsmall { - background-image: url(images/rc-t-r-5-1header-2searchbox-3searchbox.png); background-repeat: no-repeat; background-position: top right; } #roundbottomsmall { - background-image: url(images/rc-b-r-5-1header-2tab-selected-3tab-selected.png); background-repeat: no-repeat; background-position: top right; } @@ -273,7 +261,6 @@ cursor:pointer; padding: 3px 12px; margin-left: 10px; - background-image: url('images/chapter.gif'); background-repeat: no-repeat; background-position: center left; font-weight : bold; @@ -291,7 +278,6 @@ #menu .menuitem { padding: 0px 0px 2px 12px; - background-image: url('images/page.gif'); background-repeat: no-repeat; background-position: center left; font-weight : normal; @@ -301,7 +287,6 @@ #menu .menupage { margin: 5px 0px 5px 10px; padding: 0px 3px 0px 12px; - background-image: url('images/current.gif'); background-repeat: no-repeat; background-position: top left; font-style : normal; @@ -413,7 +398,6 @@ padding-top: 5px; } .minitoc { - list-style-image: url('images/current.gif'); font-weight: normal; } li p { @@ -509,4 +493,4 @@ display: block; height: 16px; width: 16px; -} \ No newline at end of file +} Added: trunk/website/favicon.ico =================================================================== (Binary files differ) Property changes on: trunk/website/favicon.ico ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/website/index.txt =================================================================== --- trunk/website/index.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/index.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -3,8 +3,14 @@ ================== .. admonition:: Latest News - The Jython development team is proud to announce the release of `Jython 2.5rc3 <http://downloads.sourceforge.net/jython/jython_installer-2.5rc3.jar>`__! + The Jython development team is proud to announce the release of `Jython 2.5rc4 <http://downloads.sourceforge.net/jython/jython_installer-2.5rc4.jar>`__! + For production use please continue to use Jython 2.2.1 + + * `Download location`_ + * `Installation instructions`_ + + Jython 2.5 Documentation ======================== @@ -19,3 +25,5 @@ .. _wiki: http://wiki.python.org/jython .. _Jython 2.1: ./archive/21/index.html .. _Jython 2.2: ./archive/22/index.html +.. _Installation instructions: http://wiki.python.org/jython/InstallationInstructions +.. _Download location: http://downloads.sourceforge.net/jython/jython_installer-2.2.1.jar Modified: trunk/website/left.nav =================================================================== --- trunk/website/left.nav 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/left.nav 2009-06-09 01:12:21 UTC (rev 6472) @@ -12,6 +12,6 @@ menupageitem | User Guide | http://wiki.python.org/jython/UserGuide menupageitem | Books and Articles | http://wiki.python.org/jython/JythonBibliography #menupageitem | CPython comparison | http://wiki.python.org/jython/FIXME -#menupageitem | Developer FAQ | http://wiki.python.org/jython/JythonDeveloperGuide +menupageitem | Developer FAQ | http://wiki.python.org/jython/DeveloperFAQ menupageitem | Developer Guide | http://wiki.python.org/jython/JythonDeveloperGuide -#menupageitem | Reporting Bugs | http://wiki.python.org/jython/JythonDeveloperGuide +menupageitem | Reporting Bugs | http://wiki.python.org/jython/ReportingBugs Modified: trunk/website/redirects/Project/books_articles.txt =================================================================== --- trunk/website/redirects/Project/books_articles.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/books_articles.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -1,9 +1,9 @@ -This page has been retired for versions of Jython older than 2.2. Please see the books_articles_ wiki page for the current 2.5 version. +This page has been retired for versions of Jython older than 2.2. Please see the JythonBibliography_ wiki page for the current 2.5 version. If you want the archived web page: `2.2 books_articles`_ -.. _books_articles: http://wiki.python.org/jython/BooksAndArticles +.. _JythonBibliography: http://wiki.python.org/jython/JythonBibliography -.. _2.2 books_articles: ./archive/22/books_articles.html +.. _2.2 books_articles: ../archive/22/books_articles.html Modified: trunk/website/redirects/Project/bugs.txt =================================================================== --- trunk/website/redirects/Project/bugs.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/bugs.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -6,4 +6,4 @@ .. _bugs: http://wiki.python.org/jython/ReportingBugs -.. _2.2 bugs: ./archive/22/bugs.html +.. _2.2 bugs: ../archive/22/bugs.html Modified: trunk/website/redirects/Project/devfaq.txt =================================================================== --- trunk/website/redirects/Project/devfaq.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/devfaq.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -6,4 +6,4 @@ .. _devfaq: http://wiki.python.org/jython/DeveloperFAQ -.. _2.2 devfaq: ./archive/22/devfaq.html +.. _2.2 devfaq: ../archive/22/devfaq.html Modified: trunk/website/redirects/Project/download.txt =================================================================== --- trunk/website/redirects/Project/download.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/download.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -4,6 +4,6 @@ `2.2 download`_ -.. _download: http://wiki.python.org/jython/DownloadingJython +.. _download: http://wiki.python.org/jython/DownloadInstructions -.. _2.2 download: ./archive/22/download.html +.. _2.2 download: ../archive/22/download.html Modified: trunk/website/redirects/Project/history.txt =================================================================== --- trunk/website/redirects/Project/history.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/history.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -1,9 +1,7 @@ -This page has been retired for versions of Jython older than 2.2. Please see the history_ wiki page for the current 2.5 version. +This page has been retired for versions of Jython older than 2.2. If you want the archived web page: `2.2 history`_ -.. _history: http://wiki.python.org/jython/JythonHistory - -.. _2.2 history: ./archive/22/history.html +.. _2.2 history: ../archive/22/history.html Modified: trunk/website/redirects/Project/index.txt =================================================================== --- trunk/website/redirects/Project/index.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/index.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -1,9 +1,9 @@ -This page has been retired for versions of Jython older than 2.2. Please see the index_ wiki page for the current 2.5 version. +This page has been retired for versions of Jython older than 2.2. Please see the main_ wiki page for the current 2.5 version. If you want the archived web page: `2.2 index`_ -.. _index: http://wiki.python.org/jython/ +.. _main: http://wiki.python.org/jython/ -.. _2.2 index: ./archive/22/index.html +.. _2.2 index: ../archive/22/index.html Modified: trunk/website/redirects/Project/installation.txt =================================================================== --- trunk/website/redirects/Project/installation.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/installation.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -6,4 +6,4 @@ .. _installation: http://wiki.python.org/jython/InstallingJython -.. _2.2 installation: ./archive/22/installation.html +.. _2.2 installation: ../archive/22/installation.html Modified: trunk/website/redirects/Project/jythonc.txt =================================================================== --- trunk/website/redirects/Project/jythonc.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/jythonc.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -1,9 +1,9 @@ -This page has been retired for versions of Jython older than 2.2. Please see the jythonc_ wiki page for the current 2.5 version. +This page has been retired for versions of Jython older than 2.2. Please see the ReplaceJythonc_ wiki page for the current 2.5 version. If you want the archived web page: `2.2 jythonc`_ -.. _jythonc: http://wiki.python.org/jython/JythoncCompiler +.. _ReplaceJythonc: http://wiki.python.org/jython/ReplaceJythonc -.. _2.2 jythonc: ./archive/22/jythonc.html +.. _2.2 jythonc: ../archive/22/jythonc.html Modified: trunk/website/redirects/Project/license.txt =================================================================== --- trunk/website/redirects/Project/license.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/license.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -1,9 +1,9 @@ -This page has been retired for versions of Jython older than 2.2. Please see the license_ wiki page for the current 2.5 version. +This page has been retired for versions of Jython older than 2.2. Please see the license_ page for the current 2.5 version. If you want the archived web page: `2.2 license`_ -.. _license: http://wiki.python.org/jython/License +.. _license: ../license.html -.. _2.2 license: ./archive/22/license.html +.. _2.2 license: ../archive/22/license.html Modified: trunk/website/redirects/Project/news.txt =================================================================== --- trunk/website/redirects/Project/news.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/news.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -1,9 +1,9 @@ -This page has been retired for versions of Jython older than 2.2. Please see the news_ wiki page for the current 2.5 version. +This page has been retired for versions of Jython older than 2.2. Please see the main_ wiki page for the current 2.5 version. If you want the archived web page: `2.2 news`_ -.. _news: http://wiki.python.org/jython/ +.. _main: http://wiki.python.org/jython/ -.. _2.2 news: ./archive/22/news.html +.. _2.2 news: ../archive/22/news.html Modified: trunk/website/redirects/Project/roadmap.txt =================================================================== --- trunk/website/redirects/Project/roadmap.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/roadmap.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -6,4 +6,4 @@ .. _roadmap: http://wiki.python.org/jython/Roadmap -.. _2.2 roadmap: ./archive/22/roadmap.html +.. _2.2 roadmap: ../archive/22/roadmap.html Modified: trunk/website/redirects/Project/todo.txt =================================================================== --- trunk/website/redirects/Project/todo.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/todo.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -6,4 +6,4 @@ .. _todo: http://wiki.python.org/jython/Todo -.. _2.2 todo: ./archive/22/todo.html +.. _2.2 todo: ../archive/22/todo.html Modified: trunk/website/redirects/Project/userfaq.txt =================================================================== --- trunk/website/redirects/Project/userfaq.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/userfaq.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -6,4 +6,4 @@ .. _userfaq: http://wiki.python.org/jython/UserFAQ -.. _2.2 userfaq: ./archive/22/userfaq.html +.. _2.2 userfaq: ../archive/22/userfaq.html Modified: trunk/website/redirects/Project/userguide.txt =================================================================== --- trunk/website/redirects/Project/userguide.txt 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/Project/userguide.txt 2009-06-09 01:12:21 UTC (rev 6472) @@ -6,4 +6,4 @@ .. _userguide: http://wiki.python.org/jython/UserGuide -.. _2.2 userguide: ./archive/22/userguide.html +.. _2.2 userguide: ../archive/22/userguide.html Modified: trunk/website/redirects/css/screen.css =================================================================== --- trunk/website/redirects/css/screen.css 2009-06-08 17:20:04 UTC (rev 6471) +++ trunk/website/redirects/css/screen.css 2009-06-09 01:12:21 UTC (rev 6472) @@ -70,7 +70,6 @@ #top .header { float: left; width: 100%; - background: url("images/header_white_line.gif") repeat-x bottom; } #top .grouplogo { @@ -101,7 +100,6 @@ color: white; background-color: #000000; z-index:0; - background-image: url(images/rc-t-l-5-1header-2searchbox-3searchbox.png); background-repeat: no-repeat; background-position: top left; bottom: -1px; /* compensate for IE rendering issue */ @@ -125,10 +123,8 @@ margin: 0; list-style: none; } -/* background: #CFDCED url("images/tab-right.gif") no-repeat right top;*/ #tabs li { float: left; - background-image: url(images/rc-t-r-5-1header-2tab-unselected-3tab-unselected.png); background-repeat: no-repeat; background-position: top right; background-color: #000000; @@ -136,7 +132,6 @@ padding: 0; } -/*background: url("images/tab-left.gif") no-repeat left top;*/ #tabs li a { float: left; display: block; @@ -144,7 +139,6 @@ text-decoration: none; color: black; white-space: nowrap; - background-image: url(images/rc-t-l-5-1header-2tab-unselected-3tab-unselected.png); background-repeat: no-repeat; background-position: top left; padding: 5px 15px 4px; @@ -159,7 +153,6 @@ #top .header .current { background-color: #4C6C8F; - background-image: url(images/rc-t-r-5-1header-2tab-selected-3tab-selected.png); background-repeat: no-repeat; background-position: top right; } @@ -167,7 +160,6 @@ font-weight: bold; padding-bottom: 5px; color: white; - background-image: url(images/rc-t-l-5-1header-2tab-selected-3tab-selected.png); background-repeat: no-repeat; background-position: top left; } @@ -212,13 +204,11 @@ * Round corner */ #roundtop { - background-image: url(images/rc-t-r-15-1body-2menu-3menu.png); background-repeat: no-repeat; background-position: top right; } #roundbottom { - background-image: url(images/rc-b-r-15-1body-2menu-3menu.png); background-repeat: no-repeat; background-position: top right; } @@ -231,13 +221,11 @@ } .roundtopsmall { - background-image: url(images/rc-t-r-5-1header-2searchbox-3searchbox.png); background-repeat: no-repeat; background-position: top right; } #roundbottomsmall { - background-image: url(images/rc-b-r-5-1header-2tab-selected-3tab-selected.png); background-repeat: no-repeat; background-position: top right; } @@ -273,7 +261,6 @@ cursor:pointer; padding: 3px 12px; margin-left: 10px; - background-image: url('images/chapter.gif'); background-repeat: no-repeat; background-position: center left; font-weight : bold; @@ -291,7 +278,6 @@ #menu .menuitem { padding: 0px 0px 2px 12px; - background-image: url('images/page.gif'); background-repeat: no-repeat; background-position: center left; font-weight : normal; @@ -301,7 +287,6 @@ #menu .menupage { margin: 5px 0px 5px 10px; padding: 0px 3px 0px 12px; - background-image: url('images/current.gif'); background-repeat: no-repeat; background-position: top left; font-style : normal; @@ -413,7 +398,6 @@ padding-top: 5px; } .minitoc { - list-style-image: url('images/current.gif'); font-weight: normal; } li p { @@ -509,4 +493,4 @@ display: block; height: 16px; width: 16px; -} \ No newline at end of file +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-08 17:21:30
|
Revision: 6471 http://jython.svn.sourceforge.net/jython/?rev=6471&view=rev Author: fwierzbicki Date: 2009-06-08 17:20:04 +0000 (Mon, 08 Jun 2009) Log Message: ----------- copy rc4 to tag Added Paths: ----------- tags/Release_2_5rc4/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-06-08 17:19:06
|
Revision: 6470 http://jython.svn.sourceforge.net/jython/?rev=6470&view=rev Author: fwierzbicki Date: 2009-06-08 17:18:04 +0000 (Mon, 08 Jun 2009) Log Message: ----------- Increment to rc4, also increment API_VERSION since some compiler changes have occured without an update. Modified Paths: -------------- trunk/jython/NEWS trunk/jython/README.txt trunk/jython/build.xml trunk/jython/src/org/python/core/imp.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-06-08 07:06:07 UTC (rev 6469) +++ trunk/jython/NEWS 2009-06-08 17:18:04 UTC (rev 6470) @@ -20,6 +20,8 @@ recompiling due to stale bytecode - Fixed minor short term memory leaks in functions on some lists allocated inline + - Updated imp.APIVersion to 23 as some compiler changes occured since the + last update. Jython 2.5.0 rc3 Bugs fixed Modified: trunk/jython/README.txt =================================================================== --- trunk/jython/README.txt 2009-06-08 07:06:07 UTC (rev 6469) +++ trunk/jython/README.txt 2009-06-08 17:18:04 UTC (rev 6470) @@ -1,8 +1,9 @@ -Welcome to Jython 2.5rc3 +Welcome to Jython 2.5rc4 ======================== -This is the third release candidate of the 2.5 version of Jython. It partially -fixes JLine on Cygwin and some threading issues. +This is the fourth release candidate of the 2.5 version of Jython. Many bugs +are fixed in this release, and the regression tests now pass on Windows. See +the NEWS file for details. The release was compiled on Mac OS X with JDK 5 and requires JDK 5 to run. Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-06-08 07:06:07 UTC (rev 6469) +++ trunk/jython/build.xml 2009-06-08 17:18:04 UTC (rev 6470) @@ -187,13 +187,13 @@ <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> <!-- The current version info --> - <property name="jython.version" value="2.5rc3+"/> - <property name="jython.version.noplus" value="2.5rc3"/> + <property name="jython.version" value="2.5rc4+"/> + <property name="jython.version.noplus" value="2.5rc4"/> <property name="jython.major_version" value="2"/> <property name="jython.minor_version" value="5"/> <property name="jython.micro_version" value="0"/> <property name="jython.release_level" value="${PY_RELEASE_LEVEL_GAMMA}"/> - <property name="jython.release_serial" value="3"/> + <property name="jython.release_serial" value="4"/> <condition property="do.snapshot.build"> <isset property="snapshot.revision" /> Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2009-06-08 07:06:07 UTC (rev 6469) +++ trunk/jython/src/org/python/core/imp.java 2009-06-08 17:18:04 UTC (rev 6470) @@ -20,7 +20,7 @@ private static final String UNKNOWN_SOURCEFILE = "<unknown>"; - private static final int APIVersion = 22; + private static final int APIVersion = 23; public static final int NO_MTIME = -1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |