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: <am...@us...> - 2009-03-05 15:54:48
|
Revision: 6069 http://jython.svn.sourceforge.net/jython/?rev=6069&view=rev Author: amak Date: 2009-03-05 15:54:43 +0000 (Thu, 05 Mar 2009) Log Message: ----------- Adding the original modjy demo application to the Demo subdirectory. This application gives the users a complete running application that they can use as a template for aplication development. In the future, we might develop a more sophisticated application. Added Paths: ----------- branches/modjy/Demo/modjy_webapp/ branches/modjy/Demo/modjy_webapp/WEB-INF/ branches/modjy/Demo/modjy_webapp/WEB-INF/lib/ branches/modjy/Demo/modjy_webapp/WEB-INF/lib-python/ branches/modjy/Demo/modjy_webapp/WEB-INF/lib-python/readme.txt branches/modjy/Demo/modjy_webapp/WEB-INF/web.xml branches/modjy/Demo/modjy_webapp/demo_app.py branches/modjy/Demo/modjy_webapp/readme.txt Added: branches/modjy/Demo/modjy_webapp/WEB-INF/lib-python/readme.txt =================================================================== --- branches/modjy/Demo/modjy_webapp/WEB-INF/lib-python/readme.txt (rev 0) +++ branches/modjy/Demo/modjy_webapp/WEB-INF/lib-python/readme.txt 2009-03-05 15:54:43 UTC (rev 6069) @@ -0,0 +1,11 @@ +The WEB-INF/lib-python directory, if it exists, is automatically added +to sys.path. Adding jython modules into this directory will make them +available for import into your application. + +If you add your modules in a subdirectory, then be sure that that +subdirectory contains an __init__.py file, so that the subdirectory +is considered to be a package. + +See here for more details. +http://www.rexx.com/~dkuhlman/python_101/python_101.html#SECTION004540000000000000000 +http://www.python.org/doc/essays/packages.html Added: branches/modjy/Demo/modjy_webapp/WEB-INF/web.xml =================================================================== --- branches/modjy/Demo/modjy_webapp/WEB-INF/web.xml (rev 0) +++ branches/modjy/Demo/modjy_webapp/WEB-INF/web.xml 2009-03-05 15:54:43 UTC (rev 6069) @@ -0,0 +1,85 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE web-app + PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" + "http://java.sun.com/dtd/web-app_2_3.dtd"> +<web-app> + + <display-name>modjy demo application</display-name> + <description> + modjy WSGI demo application + </description> + + <servlet> + <servlet-name>modjy</servlet-name> + <servlet-class>com.xhaus.modjy.ModjyJServlet</servlet-class> + <init-param> + <param-name>python.home</param-name> + <param-value>C:/jython2.5</param-value> + </init-param> +<!-- + There are two different ways you can specify an application to modjy + 1. Using the app_import_name mechanism + 2. Using a combination of app_directory/app_filename/app_callable_name + Examples of both are given below + See the documenation for more details. + http://modjy.xhaus.com/locating.html#locating_callables +--> +<!-- + This is the app_import_name mechanism. If you specify a value + for this variable, then it will take precedence over the other mechanism + <init-param> + <param-name>app_import_name</param-name> + <param-value>my_wsgi_module.my_handler_class().handler_method</param-value> + </init-param> +--> +<!-- + And this is the app_directory/app_filename/app_callable_name combo + The defaults for these three variables are ""/application.py/handler + So if you specify no values at all for any of app_* variables, then modjy + will by default look for "handler" in "application.py" in the servlet + context root. + <init-param> + <param-name>app_directory</param-name> + <param-value>some_sub_directory</param-value> + </init-param> +--> + <init-param> + <param-name>app_filename</param-name> + <param-value>demo_app.py</param-value> + </init-param> +<!-- + Supply a value for this parameter if you want your application + callable to have a different name than the default. + <init-param> + <param-name>app_callable_name</param-name> + <param-value>my_handler_func</param-value> + </init-param> +--> + <!-- Do you want application callables to be cached? --> + <init-param> + <param-name>cache_callables</param-name> + <param-value>1</param-value> + </init-param> + <!-- Should the application be reloaded if it's .py file changes? --> + <!-- Does not work with the app_import_name mechanism --> + <init-param> + <param-name>reload_on_mod</param-name> + <param-value>1</param-value> + </init-param> + <init-param> + <param-name>log_level</param-name> + <param-value>debug</param-value> +<!-- <param-value>info</param-value> --> +<!-- <param-value>warn</param-value> --> +<!-- <param-value>error</param-value> --> +<!-- <param-value>fatal</param-value> --> + </init-param> + <load-on-startup>1</load-on-startup> + </servlet> + + <servlet-mapping> + <servlet-name>modjy</servlet-name> + <url-pattern>/*</url-pattern> + </servlet-mapping> + +</web-app> Added: branches/modjy/Demo/modjy_webapp/demo_app.py =================================================================== --- branches/modjy/Demo/modjy_webapp/demo_app.py (rev 0) +++ branches/modjy/Demo/modjy_webapp/demo_app.py 2009-03-05 15:54:43 UTC (rev 6069) @@ -0,0 +1,37 @@ +import sys + +def escape_html(s): return s.replace('&', '&').replace('<', '<').replace('>', '>') + +def cutoff(s, n=100): + if len(s) > n: return s[:n]+ '.. cut ..' + return s + +def handler(environ, start_response): + writer = start_response("200 OK", [ ('content-type', 'text/html') ]) + response_parts = [] + response_parts.append("<html>") + response_parts.append("<head>") + response_parts.append("<title>Modjy demo application</title>") + response_parts.append("</head>") + response_parts.append("<body>") + response_parts.append("<p>Modjy servlet running correctly: jython %s on %s:</p>" % (sys.version, sys.platform)) + response_parts.append("<h3>Hello WSGI World!</h3>") + response_parts.append("<h4>Here are the contents of the WSGI environment</h4>") + environ_str = "<table border='1'>" + keys = environ.keys() + keys.sort() + for ix, name in enumerate(keys): + if ix % 2: + background='#ffffff' + else: + background='#eeeeee' + style = " style='background-color:%s;'" % background + value = escape_html(cutoff(str(environ[name]))) or ' ' + environ_str = "%s\n<tr><td%s>%s</td><td%s>%s</td></tr>" % \ + (environ_str, style, name, style, value) + environ_str = "%s\n</table>" % environ_str + response_parts.append(environ_str) + response_parts.append("</body>") + response_parts.append("</html>") + response_text = "\n".join(response_parts) + return [response_text] Added: branches/modjy/Demo/modjy_webapp/readme.txt =================================================================== --- branches/modjy/Demo/modjy_webapp/readme.txt (rev 0) +++ branches/modjy/Demo/modjy_webapp/readme.txt 2009-03-05 15:54:43 UTC (rev 6069) @@ -0,0 +1,15 @@ +To deploy this application + +1. Copy the jython.jar file into the WEB-INF/lib subdirectory +2. Set the value of python.home property in WEB-INF/web.xml so + that it points to your jython installation. +3. Copy this directory to the applications directory of your servlet + container. On Apache Tomcat, this is the "webapps" subdirectory + of the tomcat install directory. +4. Enter the URL http://localhost:8080/modjy_webapp into your + browser. +5. You should see a table containing the WSGI environment. + +Please see the installation documentation for more details. + +http://modjy.xhaus.com/install.html This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-03-05 15:43:07
|
Revision: 6068 http://jython.svn.sourceforge.net/jython/?rev=6068&view=rev Author: amak Date: 2009-03-05 15:43:01 +0000 (Thu, 05 Mar 2009) Log Message: ----------- Modification to the ModjyJServlet to reflect that it is now part of the jython distribution, rather than a standalone product. Modified Paths: -------------- branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java Modified: branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java =================================================================== --- branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java 2009-03-05 13:18:55 UTC (rev 6067) +++ branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java 2009-03-05 15:43:01 UTC (rev 6068) @@ -84,12 +84,12 @@ PythonInterpreter.initialize(System.getProperties(), props, new String[0]); PySystemState systemState = new PySystemState(); interp = new PythonInterpreter(null, systemState); - String modjyJarLocation = setupEnvironment(interp, props, systemState); + setupEnvironment(interp, props, systemState); try - { interp.exec("from modjy import "+MODJY_PYTHON_CLASSNAME); } + { interp.exec("from modjy.modjy import "+MODJY_PYTHON_CLASSNAME); } catch (PyException ix) - { throw new ServletException("Unable to import '"+MODJY_PYTHON_CLASSNAME+"' from "+modjyJarLocation+ - ": do you maybe need to set the 'modjy_jar.location' parameter?", 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) @@ -128,43 +128,12 @@ * @returns A String giving the path to the modjy.jar file (which is used only for error reporting) */ - protected String setupEnvironment(PythonInterpreter interp, Properties props, PySystemState systemState) + protected void setupEnvironment(PythonInterpreter interp, Properties props, PySystemState systemState) { - String modjyJarLocation = locateModjyJar(props); - systemState.path.append(new PyString(modjyJarLocation)); processPythonLib(interp, systemState); - return modjyJarLocation; } /** - * Find out the location of "modjy.jar", so that it can - * be added to the sys.path and thus imported - * - * @param The properties from which config options are found - * @returns A String giving the path to the modjy.jar file - */ - - protected String locateModjyJar ( Properties props ) - { - // Give priority to modjy_jar.location - if (props.get("modjy_jar.location") != null) - return (String)props.get("modjy_jar.location"); - // Then try to find it in WEB-INF/lib - String location = getServletContext().getRealPath("/WEB-INF/lib/modjy.jar"); - if (location != null) - { - File f = new File(location); - if (f.exists()) - return location; - } - // Try finding the archive that this class was loaded from - try - { return this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(); } - catch (Exception x) - { return null;} - } - - /** * Do all processing in relation to the lib-python subdirectory of WEB-INF * * @param interp - The PythinInterpreter used to service requests This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-03-05 13:18:58
|
Revision: 6067 http://jython.svn.sourceforge.net/jython/?rev=6067&view=rev Author: amak Date: 2009-03-05 13:18:55 +0000 (Thu, 05 Mar 2009) Log Message: ----------- Copying over latest version of modjy, version 0.25.3. Added Paths: ----------- branches/modjy/Lib/modjy/ branches/modjy/Lib/modjy/__init__.py branches/modjy/Lib/modjy/modjy.py branches/modjy/Lib/modjy/modjy_exceptions.py branches/modjy/Lib/modjy/modjy_impl.py branches/modjy/Lib/modjy/modjy_log.py branches/modjy/Lib/modjy/modjy_params.py branches/modjy/Lib/modjy/modjy_publish.py branches/modjy/Lib/modjy/modjy_response.py branches/modjy/Lib/modjy/modjy_write.py branches/modjy/Lib/modjy/modjy_wsgi.py branches/modjy/src/com/xhaus/ branches/modjy/src/com/xhaus/modjy/ branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java Added: branches/modjy/Lib/modjy/__init__.py =================================================================== --- branches/modjy/Lib/modjy/__init__.py (rev 0) +++ branches/modjy/Lib/modjy/__init__.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,22 @@ +### +# +# 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 +# +### + +__all__ = ['modjy', 'modjy_exceptions', 'modjy_impl', 'modjy_log', 'modjy_params', 'modjy_publish', 'modjy_response', 'modjy_write', 'modjy_wsgi',] + Added: branches/modjy/Lib/modjy/modjy.py =================================================================== --- branches/modjy/Lib/modjy/modjy.py (rev 0) +++ branches/modjy/Lib/modjy/modjy.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,121 @@ +### +# +# 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 +# +### + +import jarray +import synchronize +import sys +import types + +sys.add_package("javax.servlet") +sys.add_package("javax.servlet.http") +sys.add_package("org.python.core") + +from modjy_exceptions import * +from modjy_log import * +from modjy_params import modjy_param_mgr, modjy_servlet_params +from modjy_wsgi import modjy_wsgi +from modjy_response import start_response_object +from modjy_impl import modjy_impl +from modjy_publish import modjy_publisher + +from javax.servlet.http import HttpServlet + +class modjy_servlet(HttpServlet, modjy_publisher, modjy_wsgi, modjy_impl): + + def __init__(self): + HttpServlet.__init__(self) + + def do_param(self, name, value): + if name[:3] == 'log': + getattr(self.log, "set_%s" % name)(value) + else: + self.params[name] = value + + def process_param_container(self, param_container): + param_enum = param_container.getInitParameterNames() + while param_enum.hasMoreElements(): + param_name = param_enum.nextElement() + self.do_param(param_name, param_container.getInitParameter(param_name)) + + def get_params(self): + self.process_param_container(self.servlet_context) + self.process_param_container(self.servlet) + + def init(self, delegator): + self.servlet = delegator + self.servlet_context = self.servlet.getServletContext() + self.servlet_config = self.servlet.getServletConfig() + self.log = modjy_logger(self.servlet_context) + self.params = modjy_param_mgr(modjy_servlet_params) + self.get_params() + self.init_impl() + self.init_publisher() + import modjy_exceptions + self.exc_handler = getattr(modjy_exceptions, '%s_handler' % self.params['exc_handler'])() + + def service (self, req, resp): + wsgi_environ = {} + try: + self.dispatch_to_application(req, resp, wsgi_environ) + except ModjyException, mx: + self.log.error("Exception servicing request: %s" % str(mx)) + typ, value, tb = sys.exc_info()[:] + self.exc_handler.handle(req, resp, wsgi_environ, mx, (typ, value, tb) ) + + def get_j2ee_ns(self, req, resp): + return { + 'servlet': self.servlet, + 'servlet_context': self.servlet_context, + 'servlet_config': self.servlet_config, + 'request': req, + 'response': resp, + } + + def dispatch_to_application(self, req, resp, environ): + app_callable = self.get_app_object(req, environ) + self.set_wsgi_environment(req, resp, environ, self.params, self.get_j2ee_ns(req, resp)) + response_callable = start_response_object(req, resp) + try: + app_return = self.call_application(app_callable, environ, response_callable) + if app_return is None: + raise ReturnNotIterable("Application returned None: must return an iterable") + self.deal_with_app_return(environ, response_callable, app_return) + except ModjyException, mx: + self.raise_exc(mx.__class__, str(mx)) + except Exception, x: + self.raise_exc(ApplicationException, str(x)) + + def call_application(self, app_callable, environ, response_callable): + if self.params['multithread']: + return app_callable.__call__(environ, response_callable) + else: + return synchronize.apply_synchronized( \ + app_callable, \ + app_callable, \ + (environ, response_callable)) + + def expand_relative_path(self, path): + if path.startswith("$"): + return self.servlet.getServletContext().getRealPath(path[1:]) + return path + + def raise_exc(self, exc_class, message): + self.log.error(message) + raise exc_class(message) Added: branches/modjy/Lib/modjy/modjy_exceptions.py =================================================================== --- branches/modjy/Lib/modjy/modjy_exceptions.py (rev 0) +++ branches/modjy/Lib/modjy/modjy_exceptions.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,91 @@ +### +# +# 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 +# +### + +import sys +import StringIO +import traceback + +from java.lang import IllegalStateException +from java.io import IOException +from javax.servlet import ServletException + +class ModjyException(Exception): pass + +class ModjyIOException(ModjyException): pass + +class ConfigException(ModjyException): pass +class BadParameter(ConfigException): pass +class ApplicationNotFound(ConfigException): pass +class NoCallable(ConfigException): pass + +class RequestException(ModjyException): pass + +class ApplicationException(ModjyException): pass +class StartResponseNotCalled(ApplicationException): pass +class StartResponseCalledTwice(ApplicationException): pass +class ResponseCommitted(ApplicationException): pass +class HopByHopHeaderSet(ApplicationException): pass +class WrongLength(ApplicationException): pass +class BadArgument(ApplicationException): pass +class ReturnNotIterable(ApplicationException): pass +class NonStringOutput(ApplicationException): pass + +class exception_handler: + + def handle(self, req, resp, environ, exc, exc_info): + pass + + def get_status_and_message(self, req, resp, exc): + return resp.SC_INTERNAL_SERVER_ERROR, "Server configuration error" + +# +# Special exception handler for testing +# + +class testing_handler(exception_handler): + + def handle(self, req, resp, environ, exc, exc_info): + typ, value, tb = exc_info + err_msg = StringIO.StringIO() + err_msg.write("%s: %s\n" % (typ, value,) ) + err_msg.write(">Environment\n") + for k in environ.keys(): + err_msg.write("%s=%s\n" % (k, repr(environ[k])) ) + err_msg.write("<Environment\n") + err_msg.write(">TraceBack\n") + for line in traceback.format_exception(typ, value, tb): + err_msg.write(line) + err_msg.write("<TraceBack\n") + try: + status, message = self.get_status_and_message(req, resp, exc) + resp.setStatus(status) + resp.setContentLength(len(err_msg.getvalue())) + resp.getOutputStream().write(err_msg.getvalue()) + except IllegalStateException, ise: + raise exc # Let the container deal with it + +# +# Standard exception handler +# + +class standard_handler(exception_handler): + + def handle(self, req, resp, environ, exc, exc_info): + raise exc_info[0], exc_info[1], exc_info[2] Added: branches/modjy/Lib/modjy/modjy_impl.py =================================================================== --- branches/modjy/Lib/modjy/modjy_impl.py (rev 0) +++ branches/modjy/Lib/modjy/modjy_impl.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,101 @@ +### +# +# 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 +# +### + +import types +import sys + +from modjy_exceptions import * + +class modjy_impl: + + def deal_with_app_return(self, environ, start_response_callable, app_return): + self.log.debug("Processing app return type: %s" % str(type(app_return))) + if isinstance(app_return, types.StringTypes): + raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return))) + if type(app_return) is types.FileType: + pass # TBD: What to do here? can't call fileno() + if hasattr(app_return, '__len__') and callable(app_return.__len__): + expected_pieces = app_return.__len__() + else: + expected_pieces = -1 + try: + try: + ix = 0 + for next_piece in app_return: + if not isinstance(next_piece, types.StringTypes): + raise NonStringOutput("Application returned iterable containing non-strings: %s" % str(type(next_piece))) + if ix == 0: + # The application may have called start_response in the first iteration + if not start_response_callable.called: + raise StartResponseNotCalled("Start_response callable was never called.") + if not start_response_callable.content_length \ + and expected_pieces == 1 \ + and start_response_callable.write_callable.num_writes == 0: + # Take the length of the first piece + start_response_callable.set_content_length(len(next_piece)) + start_response_callable.write_callable(next_piece) + ix += 1 + if ix == expected_pieces: + break + if expected_pieces != -1 and ix != expected_pieces: + raise WrongLength("Iterator len() was wrong. Expected %d pieces: got %d" % (expected_pieces, ix) ) + except AttributeError, ax: + if str(ax) == "__getitem__": + raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return))) + else: + raise ax + except TypeError, tx: + raise ReturnNotIterable("Application returned object that was not an iterable: %s" % str(type(app_return))) + except ModjyException, mx: + raise mx + except Exception, x: + raise ApplicationException(x) + finally: + if hasattr(app_return, 'close') and callable(app_return.close): + app_return.close() + + def init_impl(self): + self.do_j_env_params() + + def add_packages(self, package_list): + packages = [p.strip() for p in package_list.split(';')] + for p in packages: + self.log.info("Adding java package %s to jython" % p) + sys.add_package(p) + + def add_classdirs(self, classdir_list): + classdirs = [cd.strip() for cd in classdir_list.split(';')] + for cd in classdirs: + self.log.info("Adding directory %s to jython class file search path" % cd) + sys.add_classdir(cd) + + def add_extdirs(self, extdir_list): + extdirs = [ed.strip() for ed in extdir_list.split(';')] + for ed in extdirs: + self.log.info("Adding directory %s for .jars and .zips search path" % ed) + sys.add_extdir(self.expand_relative_path(ed)) + + def do_j_env_params(self): + if self.params['packages']: + self.add_packages(self.params['packages']) + if self.params['classdirs']: + self.add_classdirs(self.params['classdirs']) + if self.params['extdirs']: + self.add_extdirs(self.params['extdirs']) Added: branches/modjy/Lib/modjy/modjy_log.py =================================================================== --- branches/modjy/Lib/modjy/modjy_log.py (rev 0) +++ branches/modjy/Lib/modjy/modjy_log.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,80 @@ +### +# +# 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 +# +### + +import java + +import sys + +DEBUG = 'debug' +INFO = 'info' +WARN = 'warn' +ERROR = 'error' +FATAL = 'fatal' + +levels_dict = {} +ix = 0 +for level in [DEBUG, INFO, WARN, ERROR, FATAL, ]: + levels_dict[level]=ix + ix += 1 + +class modjy_logger: + + def __init__(self, context): + self.log_ctx = context + self.format_str = "%(lvl)s:\t%(msg)s" + self.log_level = levels_dict[DEBUG] + + def _log(self, level, level_str, msg, exc): + if level >= self.log_level: + msg = self.format_str % {'lvl': level_str, 'msg': msg, } + if exc: +# java.lang.System.err.println(msg, exc) + self.log_ctx.log(msg, exc) + else: +# java.lang.System.err.println(msg) + self.log_ctx.log(msg) + + def debug(self, msg, exc=None): + self._log(0, DEBUG, msg, exc) + + def info(self, msg, exc=None): + self._log(1, INFO, msg, exc) + + def warn(self, msg, exc=None): + self._log(2, WARN, msg, exc) + + def error(self, msg, exc=None): + self._log(3, ERROR, msg, exc) + + def fatal(self, msg, exc=None): + self._log(4, FATAL, msg, exc) + + def set_log_level(self, level_string): + try: + self.log_level = levels_dict[level_string] + except KeyError: + raise BadParameter("Invalid log level: '%s'" % level_string) + + def set_log_format(self, format_string): + # BUG! Format string never actually used in this function. + try: + self._log(debug, "This is a log formatting test", None) + except KeyError: + raise BadParameter("Bad format string: '%s'" % format_string) Added: branches/modjy/Lib/modjy/modjy_params.py =================================================================== --- branches/modjy/Lib/modjy/modjy_params.py (rev 0) +++ branches/modjy/Lib/modjy/modjy_params.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,84 @@ +### +# +# 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 +# +### + +from UserDict import UserDict + +BOOLEAN = ('boolean', int) +INTEGER = ('integer', int) +FLOAT = ('float', float) +STRING = ('string', None) + +modjy_servlet_params = { + + 'multithread': (BOOLEAN, 1), + 'cache_callables': (BOOLEAN, 1), + 'reload_on_mod': (BOOLEAN, 0), + + 'app_import_name': (STRING, None), + + 'app_directory': (STRING, None), + 'app_filename': (STRING, 'application.py'), + 'app_callable_name': (STRING, 'handler'), + 'callable_query_name': (STRING, None), + + 'exc_handler': (STRING, 'standard'), + + 'log_level': (STRING, 'info'), + + 'packages': (STRING, None), + 'classdirs': (STRING, None), + 'extdirs': (STRING, None), + + 'initial_env': (STRING, None), +} + +class modjy_param_mgr(UserDict): + + def __init__(self, param_types): + UserDict.__init__(self) + self.param_types = param_types + for pname in self.param_types.keys(): + typ, default = self.param_types[pname] + self.__setitem__(pname, default) + + def __getitem__(self, name): + return self._get_defaulted_value(name) + + def __setitem__(self, name, value): + self.data[name] = self._convert_value(name, value) + + def _convert_value(self, name, value): + if self.param_types.has_key(name): + typ, default = self.param_types[name] + typ_str, typ_func = typ + if typ_func: + try: + return typ_func(value) + except ValueError: + raise BadParameter("Illegal value for %s parameter '%s': %s" % (typ_str, name, value) ) + return value + + def _get_defaulted_value(self, name): + if self.data.has_key(name): + return self.data[name] + if self.param_types.has_key(name): + typ, default = self.param_types[name] + return default + raise KeyError(name) Added: branches/modjy/Lib/modjy/modjy_publish.py =================================================================== --- branches/modjy/Lib/modjy/modjy_publish.py (rev 0) +++ branches/modjy/Lib/modjy/modjy_publish.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,138 @@ +### +# +# 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 +# +### + +import sys +import synchronize + +from java.io import File + +from modjy_exceptions import * + +class modjy_publisher: + + def init_publisher(self): + self.cache = None + if self.params['app_directory']: + self.app_directory = self.expand_relative_path(self.params['app_directory']) + else: + self.app_directory = self.servlet_context.getRealPath('/') + self.params['app_directory'] = self.app_directory + if not self.app_directory in sys.path: + sys.path.append(self.app_directory) + + def map_uri(self, req, environ): + source_uri = '%s%s%s' % (self.app_directory, File.separator, self.params['app_filename']) + callable_name = self.params['app_callable_name'] + if self.params['callable_query_name']: + query_string = req.getQueryString() + if query_string and '=' in query_string: + for name_val in query_string.split('&'): + name, value = name_val.split('=') + if name == self.params['callable_query_name']: + callable_name = value + return source_uri, callable_name + + def get_app_object(self, req, environ): + environ["SCRIPT_NAME"] = "%s%s" % (req.getContextPath(), req.getServletPath()) + path_info = req.getPathInfo() or "" + environ["PATH_INFO"] = path_info + environ["PATH_TRANSLATED"] = File(self.app_directory, path_info).getPath() + + if self.params['app_import_name'] is not None: + return self.get_app_object_importable(self.params['app_import_name']) + else: + if self.cache is None: + self.cache = {} + return self.get_app_object_old_style(req, environ) + + get_app_object = synchronize.make_synchronized(get_app_object) + + def get_app_object_importable(self, importable_name): + self.log.debug("Attempting to import application callable '%s'\n" % (importable_name, )) + # Under the importable mechanism, the cache contains a single object + if self.cache is None: + application, instantiable, method_name = self.load_importable(importable_name.strip()) + if instantiable and self.params['cache_callables']: + application = application() + self.cache = application, instantiable, method_name + application, instantiable, method_name = self.cache + self.log.debug("Application is " + str(application)) + if instantiable and not self.params['cache_callables']: + application = application() + self.log.debug("Instantiated application is " + str(application)) + if method_name is not None: + if not hasattr(application, method_name): + self.log.fatal("Attribute error application callable '%s' as no method '%s'" % (application, method_name)) + self.raise_exc(ApplicationNotFound, "Attribute error application callable '%s' as no method '%s'" % (application, method_name)) + application = getattr(application, method_name) + self.log.debug("Application method is " + str(application)) + return application + + def load_importable(self, name): + try: + instantiable = False ; method_name = None + importable_name = name + if name.find('()') != -1: + instantiable = True + importable_name, method_name = name.split('()') + if method_name.startswith('.'): + method_name = method_name[1:] + if not method_name: + method_name = None + module_path, from_name = importable_name.rsplit('.', 1) + imported = __import__(module_path, globals(), locals(), [from_name]) + imported = getattr(imported, from_name) + return imported, instantiable, method_name + except (ImportError, AttributeError), aix: + self.log.fatal("Import error import application callable '%s': %s\n" % (name, str(aix))) + self.raise_exc(ApplicationNotFound, "Failed to import app callable '%s': %s" % (name, str(aix))) + + def get_app_object_old_style(self, req, environ): + source_uri, callable_name = self.map_uri(req, environ) + source_filename = source_uri + if not self.params['cache_callables']: + self.log.debug("Caching of callables disabled") + return self.load_object(source_filename, callable_name) + if not self.cache.has_key( (source_filename, callable_name) ): + self.log.debug("Callable object not in cache: %s#%s" % (source_filename, callable_name) ) + return self.load_object(source_filename, callable_name) + app_callable, last_mod = self.cache.get( (source_filename, callable_name) ) + self.log.debug("Callable object was in cache: %s#%s" % (source_filename, callable_name) ) + if self.params['reload_on_mod']: + f = File(source_filename) + if f.lastModified() > last_mod: + self.log.info("Source file '%s' has been modified: reloading" % source_filename) + return self.load_object(source_filename, callable_name) + return app_callable + + def load_object(self, path, callable_name): + try: + app_ns = {} ; execfile(path, app_ns) + app_callable = app_ns[callable_name] + f = File(path) + self.cache[ (path, callable_name) ] = (app_callable, f.lastModified()) + return app_callable + except IOError, ioe: + self.raise_exc(ApplicationNotFound, "Application filename not found: %s" % path) + except KeyError, k: + self.raise_exc(NoCallable, "No callable named '%s' in %s" % (callable_name, path)) + except Exception, x: + self.raise_exc(NoCallable, "Error loading jython callable '%s': %s" % (callable_name, str(x)) ) + Added: branches/modjy/Lib/modjy/modjy_response.py =================================================================== --- branches/modjy/Lib/modjy/modjy_response.py (rev 0) +++ branches/modjy/Lib/modjy/modjy_response.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,113 @@ +### +# +# 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 +# +### + +import types + +from java.lang import System + +from modjy_exceptions import * +from modjy_write import write_object + +# From: http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 + +hop_by_hop_headers = { + 'connection': None, + 'keep-alive': None, + 'proxy-authenticate': None, + 'proxy-authorization': None, + 'te': None, + 'trailers': None, + 'transfer-encoding': None, + 'upgrade': None, +} + +class start_response_object: + + def __init__(self, req, resp): + self.http_req = req + self.http_resp = resp + self.write_callable = None + self.called = 0 + self.content_length = None + + # I'm doing the parameters this way to facilitate porting back to java + def __call__(self, *args, **keywords): + if len(args) < 2 or len(args) > 3: + raise BadArgument("Start response callback requires either two or three arguments: got %s" % str(args)) + if len(args) == 3: + exc_info = args[2] + try: + try: + self.http_resp.reset() + except IllegalStateException, isx: + raise exc_info[0], exc_info[1], exc_info[2] + finally: + exc_info = None + else: + if self.called > 0: + raise StartResponseCalledTwice("Start response callback may only be called once, without exception information.") + status_str = args[0] + headers_list = args[1] + if not isinstance(status_str, types.StringType): + raise BadArgument("Start response callback requires string as first argument") + if not isinstance(headers_list, types.ListType): + raise BadArgument("Start response callback requires list as second argument") + try: + status_code, status_message_str = status_str.split(" ", 1) + self.http_resp.setStatus(int(status_code)) + except ValueError: + raise BadArgument("Status string must be of the form '<int> <string>'") + self.make_write_object() + try: + for header_name, header_value in headers_list: + header_name_lower = header_name.lower() + if hop_by_hop_headers.has_key(header_name_lower): + raise HopByHopHeaderSet("Under WSGI, it is illegal to set hop-by-hop headers, i.e. '%s'" % header_name) + if header_name_lower == "content-length": + try: + self.set_content_length(int(header_value)) + except ValueError, v: + raise BadArgument("Content-Length header value must be a string containing an integer, not '%s'" % header_value) + else: + final_value = header_value.encode('latin-1') + # Here would be the place to check for control characters, whitespace, etc + self.http_resp.addHeader(header_name, final_value) + except (AttributeError, TypeError), t: + raise BadArgument("Start response callback headers must contain a list of (<string>,<string>) tuples") + except UnicodeError, u: + raise BadArgument("Encoding error: header values may only contain latin-1 characters, not '%s'" % repr(header_value)) + except ValueError, v: + raise BadArgument("Headers list must contain 2-tuples") + self.called += 1 + return self.write_callable + + def set_content_length(self, length): + if self.write_callable.num_writes == 0: + self.content_length = length + self.http_resp.setContentLength(length) + else: + raise ResponseCommitted("Cannot set content-length: response is already commited.") + + def make_write_object(self): + try: + self.write_callable = write_object(self.http_resp.getOutputStream()) + except IOException, iox: + raise IOError(iox) + return self.write_callable Added: branches/modjy/Lib/modjy/modjy_write.py =================================================================== --- branches/modjy/Lib/modjy/modjy_write.py (rev 0) +++ branches/modjy/Lib/modjy/modjy_write.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,43 @@ +### +# +# 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 +# +### + +import types + +from modjy_exceptions import * + +class write_object: + + def __init__(self, ostream): + self.ostream = ostream + self.num_writes = 0 + + def __call__(self, *args, **keywords): + if len(args) != 1 or not isinstance(args[0], types.StringTypes): + raise NonStringOutput("Invocation of write callable requires exactly one string argument") + try: + self.ostream.write(args[0]) # Jython implicitly converts the (binary) string to a byte array + # WSGI requires that all output be flushed before returning to the application + # According to the java docs: " The flush method of OutputStream does nothing." + # Still, leave it in place for now: it's in the right place should this + # code ever be ported to another platform. + self.ostream.flush() + self.num_writes += 1 + except Exception, x: + raise ModjyIOException(x) Added: branches/modjy/Lib/modjy/modjy_wsgi.py =================================================================== --- branches/modjy/Lib/modjy/modjy_wsgi.py (rev 0) +++ branches/modjy/Lib/modjy/modjy_wsgi.py 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,156 @@ +### +# +# 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 +# +### + +from java.lang import System + +try: + from org.python.core.util import FileUtil + create_py_file = FileUtil.wrap +except ImportError: + from org.python.core import PyFile + create_py_file = PyFile + +from modjy_exceptions import * + +server_name = "modjy" +server_param_prefix = "%s.param" % server_name +j2ee_ns_prefix = "j2ee" + +cgi_var_char_encoding = "iso-8859-1" + +class modjy_wsgi: + + # + # WSGI constants + # + + empty_pystring = u"" + wsgi_version = (1,0) + + # + # Container-specific constants + # + + modjy_version = (0, 25, 3) + + def set_string_envvar(self, dict, name, value): + if value is None: + value = self.empty_pystring + value = value.encode(cgi_var_char_encoding) + dict[name] = value + + def set_string_envvar_optional(self, dict, name, value, default_value): + if value != default_value: + self.set_string_envvar(dict, name, value) + + def set_int_envvar(self, dict, name, value, default_value): + if value == default_value: + value = self.empty_pystring + else: + value = unicode(value) + self.set_string_envvar(dict, name, value) + + def set_container_specific_wsgi_vars(self, req, resp, dict, params): + dict["%s.version" % server_name] = self.modjy_version + for pname in params.keys(): + dict["%s.%s" % (server_param_prefix, pname)] = params[pname] + + def set_j2ee_specific_wsgi_vars(self, dict, j2ee_ns): + for p in j2ee_ns.keys(): + dict["%s.%s" % (j2ee_ns_prefix, p)] = j2ee_ns[p] + + def set_required_cgi_environ (self, req, resp, dict): + self.set_string_envvar(dict, "REQUEST_METHOD", req.getMethod()) + self.set_string_envvar(dict, "QUERY_STRING", req.getQueryString()) + self.set_string_envvar(dict, "CONTENT_TYPE", req.getContentType()) + self.set_int_envvar(dict, "CONTENT_LENGTH", req.getContentLength(), -1) + self.set_string_envvar(dict, "SERVER_NAME", req.getLocalName()) + self.set_int_envvar(dict, "SERVER_PORT", req.getLocalPort(), 0) + + def set_other_cgi_environ (self, req, resp, dict): + if req.isSecure(): + self.set_string_envvar(dict, "HTTPS", 'on') + else: + self.set_string_envvar(dict, "HTTPS", 'off') + self.set_string_envvar(dict, "SERVER_PROTOCOL", req.getProtocol()) + self.set_string_envvar(dict, "REMOTE_HOST", req.getRemoteHost()) + self.set_string_envvar(dict, "REMOTE_ADDR", req.getRemoteAddr()) + self.set_int_envvar(dict, "REMOTE_PORT", req.getRemotePort(), -1) + self.set_string_envvar_optional(dict, "AUTH_TYPE", req.getAuthType(), None) + self.set_string_envvar_optional(dict, "REMOTE_USER", req.getRemoteUser(), None) + + def set_http_header_environ(self, req, resp, dict): + header_name_enum = req.getHeaderNames() + while header_name_enum.hasMoreElements(): + curr_header_name = header_name_enum.nextElement() + values = None + values_enum = req.getHeaders(curr_header_name) + while values_enum.hasMoreElements(): + next_value = values_enum.nextElement().encode(cgi_var_char_encoding) + if values is None: + values = next_value + else: + if isinstance(values, list): + values.append(next_value) + else: + values = [values] + dict["HTTP_%s" % str(curr_header_name).replace('-', '_').upper()] = values + + def set_required_wsgi_vars(self, req, resp, dict): + dict["wsgi.version"] = self.wsgi_version + dict["wsgi.url_scheme"] = req.getScheme() + dict["wsgi.multithread"] = \ + int(dict["%s.cache_callables" % server_param_prefix]) \ + and \ + int(dict["%s.multithread" % server_param_prefix]) + dict["wsgi.multiprocess"] = self.wsgi_multiprocess = 0 + dict["wsgi.run_once"] = not(dict["%s.cache_callables" % server_param_prefix]) + + def set_wsgi_streams(self, req, resp, dict): + try: + dict["wsgi.input"] = create_py_file(req.getInputStream()) + dict["wsgi.errors"] = create_py_file(System.err) + except IOException, iox: + raise ModjyIOException(iox) + + def set_wsgi_classes(self, req, resp, dict): + # dict["wsgi.file_wrapper"] = modjy_file_wrapper + pass + + def set_user_specified_environment(self, req, resp, wsgi_environ, params): + if not params.has_key('initial_env') or not params['initial_env']: + return + user_env_string = params['initial_env'] + for l in user_env_string.split('\n'): + l = l.strip() + if l: + name, value = l.split(':', 1) + wsgi_environ[name.strip()] = value.strip() + + def set_wsgi_environment(self, req, resp, wsgi_environ, params, j2ee_ns): + self.set_container_specific_wsgi_vars(req, resp, wsgi_environ, params) + self.set_j2ee_specific_wsgi_vars(wsgi_environ, j2ee_ns) + self.set_required_cgi_environ(req, resp, wsgi_environ) + self.set_other_cgi_environ(req, resp, wsgi_environ) + self.set_http_header_environ(req, resp, wsgi_environ) + self.set_required_wsgi_vars(req, resp, wsgi_environ) + self.set_wsgi_streams(req, resp, wsgi_environ) + self.set_wsgi_classes(req, resp, wsgi_environ) + self.set_user_specified_environment(req, resp, wsgi_environ, params) Added: branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java =================================================================== --- branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java (rev 0) +++ branches/modjy/src/com/xhaus/modjy/ModjyJServlet.java 2009-03-05 13:18:55 UTC (rev 6067) @@ -0,0 +1,224 @@ +/*### +# +# 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); + String modjyJarLocation = setupEnvironment(interp, props, systemState); + try + { interp.exec("from modjy import "+MODJY_PYTHON_CLASSNAME); } + catch (PyException ix) + { throw new ServletException("Unable to import '"+MODJY_PYTHON_CLASSNAME+"' from "+modjyJarLocation+ + ": do you maybe need to set the 'modjy_jar.location' 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 String setupEnvironment(PythonInterpreter interp, Properties props, PySystemState systemState) + { + String modjyJarLocation = locateModjyJar(props); + systemState.path.append(new PyString(modjyJarLocation)); + processPythonLib(interp, systemState); + return modjyJarLocation; + } + + /** + * Find out the location of "modjy.jar", so that it can + * be added to the sys.path and thus imported + * + * @param The properties from which config options are found + * @returns A String giving the path to the modjy.jar file + */ + + protected String locateModjyJar ( Properties props ) + { + // Give priority to modjy_jar.location + if (props.get("modjy_jar.location") != null) + return (String)props.get("modjy_jar.location"); + // Then try to find it in WEB-INF/lib + String location = getServletContext().getRealPath("/WEB-INF/lib/modjy.jar"); + if (location != null) + { + File f = new File(location); + if (f.exists()) + return location; + } + // Try finding the archive that this class was loaded from + try + { return this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(); } + catch (Exception x) + { return null;} + } + + /** + * 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()); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-03-05 13:15:54
|
Revision: 6066 http://jython.svn.sourceforge.net/jython/?rev=6066&view=rev Author: amak Date: 2009-03-05 13:15:50 +0000 (Thu, 05 Mar 2009) Log Message: ----------- Removing old version of modjy, to get a fresh start on copying in the latest version. Removed Paths: ------------- branches/modjy/Lib/modjy/ branches/modjy/src/com/xhaus/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-03-03 22:54:14
|
Revision: 6065 http://jython.svn.sourceforge.net/jython/?rev=6065&view=rev Author: otmarhumbel Date: 2009-03-03 22:54:05 +0000 (Tue, 03 Mar 2009) Log Message: ----------- use the correct name of the new antlr 3.1.2 runtime .jar in /extlibs Modified Paths: -------------- trunk/jython/build.xml Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-03-03 15:54:04 UTC (rev 6064) +++ trunk/jython/build.xml 2009-03-03 22:54:05 UTC (rev 6065) @@ -539,7 +539,7 @@ <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="extlibs/jarjar-0.7.jar"/> <jarjar destfile="${dist.dir}/${jython.deploy.jar}"> <zipfileset src="${dist.dir}/${jython.dev.jar}"/> - <zipfileset src="extlibs/antlr-3.1.2-runtime.jar"/> + <zipfileset src="extlibs/antlr-runtime-3.1.2.jar"/> <rule pattern="org.antlr.runtime.**" result="org.python.antlr.runtime.@1"/> <zipfileset src="extlibs/asm-3.1.jar"/> <zipfileset src="extlibs/asm-commons-3.1.jar"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-03 15:54:10
|
Revision: 6064 http://jython.svn.sourceforge.net/jython/?rev=6064&view=rev Author: fwierzbicki Date: 2009-03-03 15:54:04 +0000 (Tue, 03 Mar 2009) Log Message: ----------- Test and fix for http://bugs.jython.org/issue1222877. Duplicate keyword args where erroneously permitted in Jython. Thanks to Khalid Zuberi for taking a crack at a patch, I modified the patch to avoid an extra loop. Modified Paths: -------------- trunk/jython/Lib/test/test_func_syntax_jy.py trunk/jython/src/org/python/core/ArgParser.java Modified: trunk/jython/Lib/test/test_func_syntax_jy.py =================================================================== --- trunk/jython/Lib/test/test_func_syntax_jy.py 2009-03-03 07:09:37 UTC (rev 6063) +++ trunk/jython/Lib/test/test_func_syntax_jy.py 2009-03-03 15:54:04 UTC (rev 6064) @@ -9,6 +9,10 @@ self.assertRaises(SyntaxError, eval, "parrot(voltage=.5, \'dead\')") + def test_dup_keywords(self): + self.assertRaises(TypeError, eval, + "complex(imag=4, imag=2)") + def test_main(): test.test_support.run_unittest(FuncSyntaxTest) Modified: trunk/jython/src/org/python/core/ArgParser.java =================================================================== --- trunk/jython/src/org/python/core/ArgParser.java 2009-03-03 07:09:37 UTC (rev 6063) +++ trunk/jython/src/org/python/core/ArgParser.java 2009-03-03 15:54:04 UTC (rev 6064) @@ -1,5 +1,8 @@ package org.python.core; +import java.util.HashSet; +import java.util.Set; + /** * A utility class for handling mixed positional and keyword arguments. * @@ -239,19 +242,26 @@ } private void check() { - int nargs = this.args.length - this.kws.length; - l1: for (int i = 0; i < this.kws.length; i++) { - for (int j = 0; j < this.params.length; j++) { - if (this.kws[i].equals(this.params[j])) { + Set<Integer> usedKws = new HashSet<Integer>(); + int nargs = args.length - kws.length; + l1: for (int i = 0; i < kws.length; i++) { + for (int j = 0; j < params.length; j++) { + if (kws[i].equals(params[j])) { if (j < nargs) { throw Py.TypeError("keyword parameter '" - + this.params[j] + + params[j] + "' was given by position and by name"); } + if (usedKws.contains(j)) { + throw Py.TypeError(String.format( + "%s got multiple values for keyword argument '%s'", + funcname, params[j])); + } + usedKws.add(j); continue l1; } } - throw Py.TypeError("'" + this.kws[i] + "' is an invalid keyword " + throw Py.TypeError("'" + kws[i] + "' is an invalid keyword " + "argument for this function"); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Frank W. <fwi...@gm...> - 2009-03-03 13:11:52
|
On Tue, Mar 3, 2009 at 6:59 AM, Alan Kennedy <jyt...@xh...> wrote: > [Frank] >> +#XXX: just copying from CPython -- someone with better knowledge of socket.py >> +# should check if this makes sense. >> +_GLOBAL_DEFAULT_TIMEOUT = object() >> + > > Hi Frank, > > That change relates to a greater change in 2.6, namely the > introduction of the create_connection method, which enables the use of > timeouts across all modules that layer on socket, i.e. urllib, > httplib, etc. I only added that to get regrtest working in a proof of concept in the sandbox, when we are doing it for real I'm sure it will be quite different. I don't plan to mess with this sandbox code much more before PyCon. > So, this change is really part of a bigger change for 2.6. > > Which raises the question: when are we targetting 2.6? Given that updating to 2.6 and getting it stable will take a while, and that 2.7 (as I understand) is planned as a fairly modest CPython release, I was thinking of going right for 2.7. If all goes really well, I hope to release Jython 2.7 at or shortly after CPython releases theirs. My plan is to have release candidates of 2.5 going by PyCon in a Release_2_5maint branch, and change trunk to point to 2.7 (thus CPython trunk) at that time so that anyone interested in hacking on 2.7 features can do so easily during the PyCon sprints. -Frank |
From: Alan K. <jyt...@xh...> - 2009-03-03 11:59:33
|
[Frank] > +#XXX: just copying from CPython -- someone with better knowledge of socket.py > +# should check if this makes sense. > +_GLOBAL_DEFAULT_TIMEOUT = object() > + Hi Frank, That change relates to a greater change in 2.6, namely the introduction of the create_connection method, which enables the use of timeouts across all modules that layer on socket, i.e. urllib, httplib, etc. No way to disable socket timeouts in httplib, etc. http://bugs.python.org/issue2451 http://svn.python.org/view?view=rev&revision=63788 So, this change is really part of a bigger change for 2.6. Which raises the question: when are we targetting 2.6? Regards, Alan. |
From: <otm...@us...> - 2009-03-03 07:09:40
|
Revision: 6063 http://jython.svn.sourceforge.net/jython/?rev=6063&view=rev Author: otmarhumbel Date: 2009-03-03 07:09:37 +0000 (Tue, 03 Mar 2009) Log Message: ----------- only antlr runtime jar is needed Modified Paths: -------------- trunk/jython/.classpath Modified: trunk/jython/.classpath =================================================================== --- trunk/jython/.classpath 2009-03-03 07:03:09 UTC (rev 6062) +++ trunk/jython/.classpath 2009-03-03 07:09:37 UTC (rev 6063) @@ -13,7 +13,7 @@ <classpathentry kind="lib" path="extlibs/postgresql-8.3-603.jdbc4.jar"/> <classpathentry kind="lib" path="extlibs/servlet-api-2.5.jar"/> <classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/> - <classpathentry kind="lib" path="extlibs/antlr-3.1.2.jar"/> + <classpathentry kind="lib" path="extlibs/antlr-runtime-3.1.2.jar"/> <classpathentry kind="lib" path="extlibs/asm-3.1.jar"/> <classpathentry kind="lib" path="extlibs/asm-commons-3.1.jar"/> <classpathentry kind="lib" path="extlibs/constantine-0.4.jar"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-03-03 07:03:10
|
Revision: 6062 http://jython.svn.sourceforge.net/jython/?rev=6062&view=rev Author: otmarhumbel Date: 2009-03-03 07:03:09 +0000 (Tue, 03 Mar 2009) Log Message: ----------- Update to antlr 3.1.2. for eclipse Modified Paths: -------------- trunk/jython/.classpath Modified: trunk/jython/.classpath =================================================================== --- trunk/jython/.classpath 2009-03-03 01:24:04 UTC (rev 6061) +++ trunk/jython/.classpath 2009-03-03 07:03:09 UTC (rev 6062) @@ -13,7 +13,7 @@ <classpathentry kind="lib" path="extlibs/postgresql-8.3-603.jdbc4.jar"/> <classpathentry kind="lib" path="extlibs/servlet-api-2.5.jar"/> <classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/> - <classpathentry kind="lib" path="extlibs/antlr-3.1.1-runtime.jar"/> + <classpathentry kind="lib" path="extlibs/antlr-3.1.2.jar"/> <classpathentry kind="lib" path="extlibs/asm-3.1.jar"/> <classpathentry kind="lib" path="extlibs/asm-commons-3.1.jar"/> <classpathentry kind="lib" path="extlibs/constantine-0.4.jar"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-03 01:24:07
|
Revision: 6061 http://jython.svn.sourceforge.net/jython/?rev=6061&view=rev Author: fwierzbicki Date: 2009-03-03 01:24:04 +0000 (Tue, 03 Mar 2009) Log Message: ----------- Merged in tests of mapping in exec and eval written by Mehendran in Issue1815116. Thanks Mehendran! Modified Paths: -------------- trunk/jython/Lib/test/test_builtin_jy.py Modified: trunk/jython/Lib/test/test_builtin_jy.py =================================================================== --- trunk/jython/Lib/test/test_builtin_jy.py 2009-03-02 19:26:12 UTC (rev 6060) +++ trunk/jython/Lib/test/test_builtin_jy.py 2009-03-03 01:24:04 UTC (rev 6061) @@ -1,7 +1,9 @@ -1# -*- coding: utf-8 -*- -import sys -import unittest -import test.test_support +# -*- coding: utf-8 -*- +import test.test_support, unittest +from test.test_support import TESTFN, unlink + +import sys, UserDict + from codecs import BOM_UTF8 class BuiltinTest(unittest.TestCase): @@ -46,8 +48,8 @@ def test_getslice(self): class F: - def __getitem__(self,*args): return '__getitem__ '+`args` - def __getslice__(self,*args): return '__getslice__ '+`args` + def __getitem__(self,*args): return '__getitem__ '+repr(args) + def __getslice__(self,*args): return '__getslice__ '+repr(args) self.failUnless("__getslice__ (1, 1)" in F()[1:1]) class ChrTest(unittest.TestCase): @@ -157,6 +159,112 @@ exec code in ns self.assertEqual(foo, ns['a']) + def test_general_eval(self): + # Tests that general mappings can be used for the locals argument + + class M: + "Test mapping interface versus possible calls from eval()." + def __getitem__(self, key): + if key == 'a': + return 12 + raise KeyError + def keys(self): + return list('xyz') + + m = M() + g = globals() + self.assertEqual(eval('a', g, m), 12) + self.assertRaises(NameError, eval, 'b', g, m) + self.assertEqual(eval('dir()', g, m), list('xyz')) + self.assertEqual(eval('globals()', g, m), g) + self.assertEqual(eval('locals()', g, m), m) + #XXX: the following assert holds in CPython because globals must be a + # real dict. Should Jython be as strict? + #self.assertRaises(TypeError, eval, 'a', m) + class A: + "Non-mapping" + pass + m = A() + self.assertRaises(TypeError, eval, 'a', g, m) + + # Verify that dict subclasses work as well + class D(dict): + def __getitem__(self, key): + if key == 'a': + return 12 + return dict.__getitem__(self, key) + def keys(self): + return list('xyz') + + d = D() + self.assertEqual(eval('a', g, d), 12) + self.assertRaises(NameError, eval, 'b', g, d) + self.assertEqual(eval('dir()', g, d), list('xyz')) + self.assertEqual(eval('globals()', g, d), g) + self.assertEqual(eval('locals()', g, d), d) + + # Verify locals stores (used by list comps) + eval('[locals() for i in (2,3)]', g, d) + eval('[locals() for i in (2,3)]', g, UserDict.UserDict()) + + class SpreadSheet: + "Sample application showing nested, calculated lookups." + _cells = {} + def __setitem__(self, key, formula): + self._cells[key] = formula + def __getitem__(self, key): + return eval(self._cells[key], globals(), self) + + ss = SpreadSheet() + ss['a1'] = '5' + ss['a2'] = 'a1*6' + ss['a3'] = 'a2*7' + self.assertEqual(ss['a3'], 210) + + # Verify that dir() catches a non-list returned by eval + # SF bug #1004669 + class C: + def __getitem__(self, item): + raise KeyError(item) + def keys(self): + return 'a' + self.assertRaises(TypeError, eval, 'dir()', globals(), C()) + + # Done outside of the method test_z to get the correct scope + z = 0 + f = open(TESTFN, 'w') + f.write('z = z+1\n') + f.write('z = z*2\n') + f.close() + execfile(TESTFN) + + def test_execfile(self): + globals = {'a': 1, 'b': 2} + locals = {'b': 200, 'c': 300} + + class M: + "Test mapping interface versus possible calls from execfile()." + def __init__(self): + self.z = 10 + def __getitem__(self, key): + if key == 'z': + return self.z + raise KeyError + def __setitem__(self, key, value): + if key == 'z': + self.z = value + return + raise KeyError + + locals = M() + locals['z'] = 0 + execfile(TESTFN, globals, locals) + self.assertEqual(locals['z'], 2) + + self.assertRaises(TypeError, execfile) + self.assertRaises(TypeError, execfile, TESTFN, {}, ()) + unlink(TESTFN) + class ModuleNameTest(unittest.TestCase): """Tests that the module when imported has the same __name__""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-02 19:26:29
|
Revision: 6060 http://jython.svn.sourceforge.net/jython/?rev=6060&view=rev Author: fwierzbicki Date: 2009-03-02 19:26:12 +0000 (Mon, 02 Mar 2009) Log Message: ----------- Added BytesWarning, plus a couple of quick bandaids to get regrtest sort of running. Modified Paths: -------------- trunk/sandbox/wierzbicki/test27/Lib/socket.py trunk/sandbox/wierzbicki/test27/Lib/test/regrtest.py trunk/sandbox/wierzbicki/test27/Lib/warnings.py trunk/sandbox/wierzbicki/test27/src/org/python/core/Py.java trunk/sandbox/wierzbicki/test27/src/org/python/core/PySystemState.java trunk/sandbox/wierzbicki/test27/src/org/python/core/exceptions.java Modified: trunk/sandbox/wierzbicki/test27/Lib/socket.py =================================================================== --- trunk/sandbox/wierzbicki/test27/Lib/socket.py 2009-03-02 18:59:56 UTC (rev 6059) +++ trunk/sandbox/wierzbicki/test27/Lib/socket.py 2009-03-02 19:26:12 UTC (rev 6060) @@ -136,6 +136,10 @@ exception.java_exception = exc return exception +#XXX: just copying from CPython -- someone with better knowledge of socket.py +# should check if this makes sense. +_GLOBAL_DEFAULT_TIMEOUT = object() + MODE_BLOCKING = 'block' MODE_NONBLOCKING = 'nonblock' MODE_TIMEOUT = 'timeout' Modified: trunk/sandbox/wierzbicki/test27/Lib/test/regrtest.py =================================================================== --- trunk/sandbox/wierzbicki/test27/Lib/test/regrtest.py 2009-03-02 18:59:56 UTC (rev 6059) +++ trunk/sandbox/wierzbicki/test27/Lib/test/regrtest.py 2009-03-02 19:26:12 UTC (rev 6060) @@ -553,6 +553,8 @@ else: cfp = cStringIO.StringIO() + #XXX: seems to need setting outside of the try block. + indirect_test = None try: save_stdout = sys.stdout if junit_xml_dir: @@ -605,6 +607,7 @@ print test, "skipped --", msg sys.stdout.flush() if junit_xml_dir: + from test.junit_xml import Tee, write_direct_test write_direct_test(junit_xml_dir, abstest, time.time() - start, 'skipped', sys.exc_info(), stdout=stdout.getvalue(), @@ -629,6 +632,7 @@ traceback.print_exc(file=sys.stdout) sys.stdout.flush() if junit_xml_dir and indirect_test is None: + from test.junit_xml import Tee, write_direct_test write_direct_test(junit_xml_dir, abstest, time.time() - start, 'error', sys.exc_info(), stdout=stdout.getvalue(), Modified: trunk/sandbox/wierzbicki/test27/Lib/warnings.py =================================================================== --- trunk/sandbox/wierzbicki/test27/Lib/warnings.py 2009-03-02 18:59:56 UTC (rev 6059) +++ trunk/sandbox/wierzbicki/test27/Lib/warnings.py 2009-03-02 19:26:12 UTC (rev 6060) @@ -187,6 +187,8 @@ fnl = filename.lower() if fnl.endswith((".pyc", ".pyo")): filename = filename[:-1] + elif fnl.endswith("$py.class"): + filename = filename[:-9] + '.py' else: if module == "__main__": try: @@ -391,12 +393,16 @@ if not _warnings_defaults: simplefilter("ignore", category=PendingDeprecationWarning, append=1) simplefilter("ignore", category=ImportWarning, append=1) - bytes_warning = sys.flags.bytes_warning - if bytes_warning > 1: - bytes_action = "error" - elif bytes_warning: - bytes_action = "default" - else: - bytes_action = "ignore" + + #FIXME: setting to "ignore" just to get moving + bytes_action = "ignore" + #bytes_warning = sys.flags.bytes_warning + #if bytes_warning > 1: + # bytes_action = "error" + #elif bytes_warning: + # bytes_action = "default" + #else: + # bytes_action = "ignore" + simplefilter(bytes_action, category=BytesWarning, append=1) del _warnings_defaults Modified: trunk/sandbox/wierzbicki/test27/src/org/python/core/Py.java =================================================================== --- trunk/sandbox/wierzbicki/test27/src/org/python/core/Py.java 2009-03-02 18:59:56 UTC (rev 6059) +++ trunk/sandbox/wierzbicki/test27/src/org/python/core/Py.java 2009-03-02 19:26:12 UTC (rev 6060) @@ -375,6 +375,12 @@ warning(UnicodeWarning, message); } + public static PyObject BytesWarning; + public static void BytesWarning(String message) { + warning(BytesWarning, message); + } + + private static PyObject warnings_mod; private static PyObject importWarnings() { @@ -731,6 +737,7 @@ RuntimeWarning = initExc("RuntimeWarning", exc, dict); FutureWarning = initExc("FutureWarning", exc, dict); ImportWarning = initExc("ImportWarning", exc, dict); + BytesWarning = initExc("BytesWarning", exc, dict); UnicodeWarning = initExc("UnicodeWarning", exc, dict); // Pre-initialize the PyJavaClass for OutOfMemoryError so when we need Modified: trunk/sandbox/wierzbicki/test27/src/org/python/core/PySystemState.java =================================================================== --- trunk/sandbox/wierzbicki/test27/src/org/python/core/PySystemState.java 2009-03-02 18:59:56 UTC (rev 6059) +++ trunk/sandbox/wierzbicki/test27/src/org/python/core/PySystemState.java 2009-03-02 19:26:12 UTC (rev 6060) @@ -101,6 +101,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(); Modified: trunk/sandbox/wierzbicki/test27/src/org/python/core/exceptions.java =================================================================== --- trunk/sandbox/wierzbicki/test27/src/org/python/core/exceptions.java 2009-03-02 18:59:56 UTC (rev 6059) +++ trunk/sandbox/wierzbicki/test27/src/org/python/core/exceptions.java 2009-03-02 19:26:12 UTC (rev 6060) @@ -166,6 +166,10 @@ buildClass(dict, "ImportWarning", "Warning", "Base class for warnings about probable mistakes in module imports"); + buildClass(dict, "BytesWarning", "Warning", + "Base class for warnings about bytes and buffer related problems, mostly\n" + + "related to conversion from str or comparing to str."); + buildClass(dict, "UnicodeWarning", "Warning", "Base class for warnings about Unicode related problems, mostly\n" + "related to conversion problems."); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-02 19:00:03
|
Revision: 6059 http://jython.svn.sourceforge.net/jython/?rev=6059&view=rev Author: fwierzbicki Date: 2009-03-02 18:59:56 +0000 (Mon, 02 Mar 2009) Log Message: ----------- from: http://svn.python.org/projects/python/trunk/Lib/warnings.py@66386 Modified Paths: -------------- trunk/sandbox/wierzbicki/test27/Lib/warnings.py Modified: trunk/sandbox/wierzbicki/test27/Lib/warnings.py =================================================================== --- trunk/sandbox/wierzbicki/test27/Lib/warnings.py 2009-03-02 18:45:47 UTC (rev 6058) +++ trunk/sandbox/wierzbicki/test27/Lib/warnings.py 2009-03-02 18:59:56 UTC (rev 6059) @@ -3,145 +3,43 @@ # Note: function level imports should *not* be used # in this module as it may cause import lock deadlock. # See bug 683658. -import sys, types import linecache +import sys +import types __all__ = ["warn", "showwarning", "formatwarning", "filterwarnings", - "resetwarnings"] + "resetwarnings", "catch_warnings"] -# filters contains a sequence of filter 5-tuples -# The components of the 5-tuple are: -# - an action: error, ignore, always, default, module, or once -# - a compiled regex that must match the warning message -# - a class representing the warning category -# - a compiled regex that must match the module that is being warned -# - a line number for the line being warning, or 0 to mean any line -# If either if the compiled regexs are None, match anything. -filters = [] -defaultaction = "default" -onceregistry = {} -def warn(message, category=None, stacklevel=1): - """Issue a warning, or maybe ignore it or raise an exception.""" - # Check if message is already a Warning object - if isinstance(message, Warning): - category = message.__class__ - # Check category argument - if category is None: - category = UserWarning - assert issubclass(category, Warning) - # Get context information - try: - caller = sys._getframe(stacklevel) - except ValueError: - globals = sys.__dict__ - lineno = 1 - else: - globals = caller.f_globals - lineno = caller.f_lineno - if '__name__' in globals: - module = globals['__name__'] - else: - module = "<string>" - filename = globals.get('__file__') - if filename: - fnl = filename.lower() - if fnl.endswith((".pyc", ".pyo")): - filename = filename[:-1] - elif fnl.endswith("$py.class"): - filename = filename[:-9] + '.py' - else: - if module == "__main__": - try: - filename = sys.argv[0] - except AttributeError: - # embedded interpreters don't have sys.argv, see bug #839151 - filename = '__main__' - if not filename: - filename = module - registry = globals.setdefault("__warningregistry__", {}) - warn_explicit(message, category, filename, lineno, module, registry, - globals) +def warnpy3k(message, category=None, stacklevel=1): + """Issue a deprecation warning for Python 3.x related changes. -def warn_explicit(message, category, filename, lineno, - module=None, registry=None, module_globals=None): - if module is None: - module = filename or "<unknown>" - if module[-3:].lower() == ".py": - module = module[:-3] # XXX What about leading pathname? - if registry is None: - registry = {} - if isinstance(message, Warning): - text = str(message) - category = message.__class__ - else: - text = message - message = category(message) - key = (text, category, lineno) - # Quick test for common case - if registry.get(key): - return - # Search the filters - for item in filters: - action, msg, cat, mod, ln = item - if ((msg is None or msg.match(text)) and - issubclass(category, cat) and - (mod is None or mod.match(module)) and - (ln == 0 or lineno == ln)): - break - else: - action = defaultaction - # Early exit actions - if action == "ignore": - registry[key] = 1 - return + Warnings are omitted unless Python is started with the -3 option. + """ + if sys.py3kwarning: + if category is None: + category = DeprecationWarning + warn(message, category, stacklevel+1) - # Prime the linecache for formatting, in case the - # "file" is actually in a zipfile or something. - linecache.getlines(filename, module_globals) - - if action == "error": - raise message - # Other actions - if action == "once": - registry[key] = 1 - oncekey = (text, category) - if onceregistry.get(oncekey): - return - onceregistry[oncekey] = 1 - elif action == "always": - pass - elif action == "module": - registry[key] = 1 - altkey = (text, category, 0) - if registry.get(altkey): - return - registry[altkey] = 1 - elif action == "default": - registry[key] = 1 - else: - # Unrecognized actions are errors - raise RuntimeError( - "Unrecognized action (%r) in warnings.filters:\n %s" % - (action, item)) - # Print message and context - showwarning(message, category, filename, lineno) - -def showwarning(message, category, filename, lineno, file=None): +def _show_warning(message, category, filename, lineno, file=None, line=None): """Hook to write a warning to a file; replace if you like.""" if file is None: file = sys.stderr try: - file.write(formatwarning(message, category, filename, lineno)) + file.write(formatwarning(message, category, filename, lineno, line)) except IOError: pass # the file (probably stderr) is invalid - this warning gets lost. +# Keep a worrking version around in case the deprecation of the old API is +# triggered. +showwarning = _show_warning -def formatwarning(message, category, filename, lineno): +def formatwarning(message, category, filename, lineno, line=None): """Function to format a warning the standard way.""" s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message) - line = linecache.getline(filename, lineno).strip() + line = linecache.getline(filename, lineno) if line is None else line if line: - s = s + " " + line + "\n" + line = line.strip() + s += " %s\n" % line return s def filterwarnings(action, message="", category=Warning, module="", lineno=0, @@ -260,7 +158,245 @@ raise _OptionError("invalid warning category: %r" % (category,)) return cat + +# Code typically replaced by _warnings +def warn(message, category=None, stacklevel=1): + """Issue a warning, or maybe ignore it or raise an exception.""" + # Check if message is already a Warning object + if isinstance(message, Warning): + category = message.__class__ + # Check category argument + if category is None: + category = UserWarning + assert issubclass(category, Warning) + # Get context information + try: + caller = sys._getframe(stacklevel) + except ValueError: + globals = sys.__dict__ + lineno = 1 + else: + globals = caller.f_globals + lineno = caller.f_lineno + if '__name__' in globals: + module = globals['__name__'] + else: + module = "<string>" + filename = globals.get('__file__') + if filename: + fnl = filename.lower() + if fnl.endswith((".pyc", ".pyo")): + filename = filename[:-1] + else: + if module == "__main__": + try: + filename = sys.argv[0] + except AttributeError: + # embedded interpreters don't have sys.argv, see bug #839151 + filename = '__main__' + if not filename: + filename = module + registry = globals.setdefault("__warningregistry__", {}) + warn_explicit(message, category, filename, lineno, module, registry, + globals) + +def warn_explicit(message, category, filename, lineno, + module=None, registry=None, module_globals=None): + lineno = int(lineno) + if module is None: + module = filename or "<unknown>" + if module[-3:].lower() == ".py": + module = module[:-3] # XXX What about leading pathname? + if registry is None: + registry = {} + if isinstance(message, Warning): + text = str(message) + category = message.__class__ + else: + text = message + message = category(message) + key = (text, category, lineno) + # Quick test for common case + if registry.get(key): + return + # Search the filters + for item in filters: + action, msg, cat, mod, ln = item + if ((msg is None or msg.match(text)) and + issubclass(category, cat) and + (mod is None or mod.match(module)) and + (ln == 0 or lineno == ln)): + break + else: + action = defaultaction + # Early exit actions + if action == "ignore": + registry[key] = 1 + return + + # Prime the linecache for formatting, in case the + # "file" is actually in a zipfile or something. + linecache.getlines(filename, module_globals) + + if action == "error": + raise message + # Other actions + if action == "once": + registry[key] = 1 + oncekey = (text, category) + if onceregistry.get(oncekey): + return + onceregistry[oncekey] = 1 + elif action == "always": + pass + elif action == "module": + registry[key] = 1 + altkey = (text, category, 0) + if registry.get(altkey): + return + registry[altkey] = 1 + elif action == "default": + registry[key] = 1 + else: + # Unrecognized actions are errors + raise RuntimeError( + "Unrecognized action (%r) in warnings.filters:\n %s" % + (action, item)) + # Warn if showwarning() does not support the 'line' argument. + # Don't use 'inspect' as it relies on an extension module, which break the + # build thanks to 'warnings' being imported by setup.py. + fxn_code = None + if hasattr(showwarning, 'func_code'): + fxn_code = showwarning.func_code + elif hasattr(showwarning, '__func__'): + fxn_code = showwarning.__func__.func_code + if fxn_code: + args = fxn_code.co_varnames[:fxn_code.co_argcount] + CO_VARARGS = 0x4 + if 'line' not in args and not fxn_code.co_flags & CO_VARARGS: + showwarning_msg = ("functions overriding warnings.showwarning() " + "must support the 'line' argument") + if message == showwarning_msg: + _show_warning(message, category, filename, lineno) + else: + warn(showwarning_msg, DeprecationWarning) + # Print message and context + showwarning(message, category, filename, lineno) + + +class WarningMessage(object): + + """Holds the result of a single showwarning() call.""" + + _WARNING_DETAILS = ("message", "category", "filename", "lineno", "file", + "line") + + def __init__(self, message, category, filename, lineno, file=None, + line=None): + local_values = locals() + for attr in self._WARNING_DETAILS: + setattr(self, attr, local_values[attr]) + self._category_name = category.__name__ if category else None + + def __str__(self): + return ("{message : %r, category : %r, filename : %r, lineno : %s, " + "line : %r}" % (self.message, self._category_name, + self.filename, self.lineno, self.line)) + + +class catch_warnings(object): + + """A context manager that copies and restores the warnings filter upon + exiting the context. + + The 'record' argument specifies whether warnings should be captured by a + custom implementation of warnings.showwarning() and be appended to a list + returned by the context manager. Otherwise None is returned by the context + manager. The objects appended to the list are arguments whose attributes + mirror the arguments to showwarning(). + + The 'module' argument is to specify an alternative module to the module + named 'warnings' and imported under that name. This argument is only useful + when testing the warnings module itself. + + """ + + def __init__(self, record=False, module=None): + """Specify whether to record warnings and if an alternative module + should be used other than sys.modules['warnings']. + + For compatibility with Python 3.0, please consider all arguments to be + keyword-only. + + """ + self._record = record + self._module = sys.modules['warnings'] if module is None else module + self._entered = False + + def __repr__(self): + args = [] + if self._record: + args.append("record=True") + if self._module is not sys.modules['warnings']: + args.append("module=%r" % self._module) + name = type(self).__name__ + return "%s(%s)" % (name, ", ".join(args)) + + def __enter__(self): + if self._entered: + raise RuntimeError("Cannot enter %r twice" % self) + self._entered = True + self._filters = self._module.filters + self._module.filters = self._filters[:] + self._showwarning = self._module.showwarning + if self._record: + log = [] + def showwarning(*args, **kwargs): + log.append(WarningMessage(*args, **kwargs)) + self._module.showwarning = showwarning + return log + else: + return None + + def __exit__(self, *exc_info): + if not self._entered: + raise RuntimeError("Cannot exit %r without entering first" % self) + self._module.filters = self._filters + self._module.showwarning = self._showwarning + + +# filters contains a sequence of filter 5-tuples +# The components of the 5-tuple are: +# - an action: error, ignore, always, default, module, or once +# - a compiled regex that must match the warning message +# - a class representing the warning category +# - a compiled regex that must match the module that is being warned +# - a line number for the line being warning, or 0 to mean any line +# If either if the compiled regexs are None, match anything. +_warnings_defaults = False +try: + from _warnings import (filters, default_action, once_registry, + warn, warn_explicit) + defaultaction = default_action + onceregistry = once_registry + _warnings_defaults = True +except ImportError: + filters = [] + defaultaction = "default" + onceregistry = {} + + # Module initialization _processoptions(sys.warnoptions) -simplefilter("ignore", category=PendingDeprecationWarning, append=1) -simplefilter("ignore", category=ImportWarning, append=1) +if not _warnings_defaults: + simplefilter("ignore", category=PendingDeprecationWarning, append=1) + simplefilter("ignore", category=ImportWarning, append=1) + bytes_warning = sys.flags.bytes_warning + if bytes_warning > 1: + bytes_action = "error" + elif bytes_warning: + bytes_action = "default" + else: + bytes_action = "ignore" + simplefilter(bytes_action, category=BytesWarning, append=1) +del _warnings_defaults This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-02 18:45:56
|
Revision: 6058 http://jython.svn.sourceforge.net/jython/?rev=6058&view=rev Author: fwierzbicki Date: 2009-03-02 18:45:47 +0000 (Mon, 02 Mar 2009) Log Message: ----------- Don't register buffer in _abcoll, and remove custom platform since it looks Jython friendly now. Modified Paths: -------------- trunk/sandbox/wierzbicki/test27/Lib/_abcoll.py Removed Paths: ------------- trunk/sandbox/wierzbicki/test27/Lib/platform.py Modified: trunk/sandbox/wierzbicki/test27/Lib/_abcoll.py =================================================================== --- trunk/sandbox/wierzbicki/test27/Lib/_abcoll.py 2009-03-02 18:14:30 UTC (rev 6057) +++ trunk/sandbox/wierzbicki/test27/Lib/_abcoll.py 2009-03-02 18:45:47 UTC (rev 6058) @@ -521,7 +521,8 @@ Sequence.register(tuple) Sequence.register(basestring) -Sequence.register(buffer) +if not sys.platform.startswith('java'): + Sequence.register(buffer) Sequence.register(xrange) Deleted: trunk/sandbox/wierzbicki/test27/Lib/platform.py =================================================================== --- trunk/sandbox/wierzbicki/test27/Lib/platform.py 2009-03-02 18:14:30 UTC (rev 6057) +++ trunk/sandbox/wierzbicki/test27/Lib/platform.py 2009-03-02 18:45:47 UTC (rev 6058) @@ -1,1271 +0,0 @@ -#!/usr/bin/env python - -""" This module tries to retrieve as much platform-identifying data as - possible. It makes this information available via function APIs. - - If called from the command line, it prints the platform - information concatenated as single string to stdout. The output - format is useable as part of a filename. - -""" -# This module is maintained by Marc-Andre Lemburg <ma...@eg...>. -# If you find problems, please submit bug reports/patches via the -# Python SourceForge Project Page and assign them to "lemburg". -# -# Note: Please keep this module compatible to Python 1.5.2. -# -# Still needed: -# * more support for WinCE -# * support for MS-DOS (PythonDX ?) -# * support for Amiga and other still unsupported platforms running Python -# * support for additional Linux distributions -# -# Many thanks to all those who helped adding platform-specific -# checks (in no particular order): -# -# Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell, -# Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef -# Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg -# Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark -# Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support), -# Colin Kong, Trent Mick, Guido van Rossum -# -# History: -# -# <see CVS and SVN checkin messages for history> -# -# 1.0.3 - added normalization of Windows system name -# 1.0.2 - added more Windows support -# 1.0.1 - reformatted to make doc.py happy -# 1.0.0 - reformatted a bit and checked into Python CVS -# 0.8.0 - added sys.version parser and various new access -# APIs (python_version(), python_compiler(), etc.) -# 0.7.2 - fixed architecture() to use sizeof(pointer) where available -# 0.7.1 - added support for Caldera OpenLinux -# 0.7.0 - some fixes for WinCE; untabified the source file -# 0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and -# vms_lib.getsyi() configured -# 0.6.1 - added code to prevent 'uname -p' on platforms which are -# known not to support it -# 0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k; -# did some cleanup of the interfaces - some APIs have changed -# 0.5.5 - fixed another type in the MacOS code... should have -# used more coffee today ;-) -# 0.5.4 - fixed a few typos in the MacOS code -# 0.5.3 - added experimental MacOS support; added better popen() -# workarounds in _syscmd_ver() -- still not 100% elegant -# though -# 0.5.2 - fixed uname() to return '' instead of 'unknown' in all -# return values (the system uname command tends to return -# 'unknown' instead of just leaving the field emtpy) -# 0.5.1 - included code for slackware dist; added exception handlers -# to cover up situations where platforms don't have os.popen -# (e.g. Mac) or fail on socket.gethostname(); fixed libc -# detection RE -# 0.5.0 - changed the API names referring to system commands to *syscmd*; -# added java_ver(); made syscmd_ver() a private -# API (was system_ver() in previous versions) -- use uname() -# instead; extended the win32_ver() to also return processor -# type information -# 0.4.0 - added win32_ver() and modified the platform() output for WinXX -# 0.3.4 - fixed a bug in _follow_symlinks() -# 0.3.3 - fixed popen() and "file" command invokation bugs -# 0.3.2 - added architecture() API and support for it in platform() -# 0.3.1 - fixed syscmd_ver() RE to support Windows NT -# 0.3.0 - added system alias support -# 0.2.3 - removed 'wince' again... oh well. -# 0.2.2 - added 'wince' to syscmd_ver() supported platforms -# 0.2.1 - added cache logic and changed the platform string format -# 0.2.0 - changed the API to use functions instead of module globals -# since some action take too long to be run on module import -# 0.1.0 - first release -# -# You can always get the latest version of this module at: -# -# http://www.egenix.com/files/python/platform.py -# -# If that URL should fail, try contacting the author. - -__copyright__ = """ - Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:ma...@le... - Copyright (c) 2000-2003, eGenix.com Software GmbH; mailto:in...@eg... - - Permission to use, copy, modify, and distribute this software and its - documentation for any purpose and without fee or royalty is hereby granted, - provided that the above copyright notice appear in all copies and that - both that copyright notice and this permission notice appear in - supporting documentation or portions thereof, including modifications, - that you make. - - EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO - THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, - INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING - FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, - NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION - WITH THE USE OR PERFORMANCE OF THIS SOFTWARE ! - -""" - -__version__ = '1.0.4' - -import sys,string,os,re - -### Platform specific APIs - -_libc_search = re.compile(r'(__libc_init)' - '|' - '(GLIBC_([0-9.]+))' - '|' - '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)') - -def libc_ver(executable=sys.executable,lib='',version='', - - chunksize=2048): - - """ Tries to determine the libc version that the file executable - (which defaults to the Python interpreter) is linked against. - - Returns a tuple of strings (lib,version) which default to the - given parameters in case the lookup fails. - - Note that the function has intimate knowledge of how different - libc versions add symbols to the executable and thus is probably - only useable for executables compiled using gcc. - - The file is read and scanned in chunks of chunksize bytes. - - """ - f = open(executable,'rb') - binary = f.read(chunksize) - pos = 0 - while 1: - m = _libc_search.search(binary,pos) - if not m: - binary = f.read(chunksize) - if not binary: - break - pos = 0 - continue - libcinit,glibc,glibcversion,so,threads,soversion = m.groups() - if libcinit and not lib: - lib = 'libc' - elif glibc: - if lib != 'glibc': - lib = 'glibc' - version = glibcversion - elif glibcversion > version: - version = glibcversion - elif so: - if lib != 'glibc': - lib = 'libc' - if soversion > version: - version = soversion - if threads and version[-len(threads):] != threads: - version = version + threads - pos = m.end() - f.close() - return lib,version - -def _dist_try_harder(distname,version,id): - - """ Tries some special tricks to get the distribution - information in case the default method fails. - - Currently supports older SuSE Linux, Caldera OpenLinux and - Slackware Linux distributions. - - """ - if os.path.exists('/var/adm/inst-log/info'): - # SuSE Linux stores distribution information in that file - info = open('/var/adm/inst-log/info').readlines() - distname = 'SuSE' - for line in info: - tv = string.split(line) - if len(tv) == 2: - tag,value = tv - else: - continue - if tag == 'MIN_DIST_VERSION': - version = string.strip(value) - elif tag == 'DIST_IDENT': - values = string.split(value,'-') - id = values[2] - return distname,version,id - - if os.path.exists('/etc/.installed'): - # Caldera OpenLinux has some infos in that file (thanks to Colin Kong) - info = open('/etc/.installed').readlines() - for line in info: - pkg = string.split(line,'-') - if len(pkg) >= 2 and pkg[0] == 'OpenLinux': - # XXX does Caldera support non Intel platforms ? If yes, - # where can we find the needed id ? - return 'OpenLinux',pkg[1],id - - if os.path.isdir('/usr/lib/setup'): - # Check for slackware verson tag file (thanks to Greg Andruk) - verfiles = os.listdir('/usr/lib/setup') - for n in range(len(verfiles)-1, -1, -1): - if verfiles[n][:14] != 'slack-version-': - del verfiles[n] - if verfiles: - verfiles.sort() - distname = 'slackware' - version = verfiles[-1][14:] - return distname,version,id - - return distname,version,id - -_release_filename = re.compile(r'(\w+)[-_](release|version)') -_release_version = re.compile(r'([\d.]+)[^(]*(?:\((.+)\))?') - -# Note:In supported_dists below we need 'fedora' before 'redhat' as in -# Fedora redhat-release is a link to fedora-release. - -def dist(distname='',version='',id='', - - supported_dists=('SuSE', 'debian', 'fedora', 'redhat', 'mandrake')): - - """ Tries to determine the name of the Linux OS distribution name. - - The function first looks for a distribution release file in - /etc and then reverts to _dist_try_harder() in case no - suitable files are found. - - Returns a tuple (distname,version,id) which default to the - args given as parameters. - - """ - try: - etc = os.listdir('/etc') - except os.error: - # Probably not a Unix system - return distname,version,id - for file in etc: - m = _release_filename.match(file) - if m: - _distname,dummy = m.groups() - if _distname in supported_dists: - distname = _distname - break - else: - return _dist_try_harder(distname,version,id) - f = open('/etc/'+file,'r') - firstline = f.readline() - f.close() - m = _release_version.search(firstline) - if m: - _version,_id = m.groups() - if _version: - version = _version - if _id: - id = _id - else: - # Unkown format... take the first two words - l = string.split(string.strip(firstline)) - if l: - version = l[0] - if len(l) > 1: - id = l[1] - return distname,version,id - -class _popen: - - """ Fairly portable (alternative) popen implementation. - - This is mostly needed in case os.popen() is not available, or - doesn't work as advertised, e.g. in Win9X GUI programs like - PythonWin or IDLE. - - Writing to the pipe is currently not supported. - - """ - tmpfile = '' - pipe = None - bufsize = None - mode = 'r' - - def __init__(self,cmd,mode='r',bufsize=None): - - if mode != 'r': - raise ValueError,'popen()-emulation only supports read mode' - import tempfile - self.tmpfile = tmpfile = tempfile.mktemp() - os.system(cmd + ' > %s' % tmpfile) - self.pipe = open(tmpfile,'rb') - self.bufsize = bufsize - self.mode = mode - - def read(self): - - return self.pipe.read() - - def readlines(self): - - if self.bufsize is not None: - return self.pipe.readlines() - - def close(self, - - remove=os.unlink,error=os.error): - - if self.pipe: - rc = self.pipe.close() - else: - rc = 255 - if self.tmpfile: - try: - remove(self.tmpfile) - except error: - pass - return rc - - # Alias - __del__ = close - -def popen(cmd, mode='r', bufsize=None): - - """ Portable popen() interface. - """ - # Find a working popen implementation preferring win32pipe.popen - # over os.popen over _popen - popen = None - if os.environ.get('OS','') == 'Windows_NT': - # On NT win32pipe should work; on Win9x it hangs due to bugs - # in the MS C lib (see MS KnowledgeBase article Q150956) - try: - import win32pipe - except ImportError: - pass - else: - popen = win32pipe.popen - if popen is None: - if hasattr(os,'popen'): - popen = os.popen - # Check whether it works... it doesn't in GUI programs - # on Windows platforms - if sys.platform == 'win32': # XXX Others too ? - try: - popen('') - except os.error: - popen = _popen - else: - popen = _popen - if bufsize is None: - return popen(cmd,mode) - else: - return popen(cmd,mode,bufsize) - -def _norm_version(version,build=''): - - """ Normalize the version and build strings and return a single - version string using the format major.minor.build (or patchlevel). - """ - l = string.split(version,'.') - if build: - l.append(build) - try: - ints = map(int,l) - except ValueError: - strings = l - else: - strings = map(str,ints) - version = string.join(strings[:3],'.') - return version - -_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' - '.*' - 'Version ([\d.]+))') - -def _syscmd_ver(system='',release='',version='', - - supported_platforms=('win32','win16','dos','os2')): - - """ Tries to figure out the OS version used and returns - a tuple (system,release,version). - - It uses the "ver" shell command for this which is known - to exists on Windows, DOS and OS/2. XXX Others too ? - - In case this fails, the given parameters are used as - defaults. - - """ - if sys.platform not in supported_platforms: - return system,release,version - - # Try some common cmd strings - for cmd in ('ver','command /c ver','cmd /c ver'): - try: - pipe = popen(cmd) - info = pipe.read() - if pipe.close(): - raise os.error,'command failed' - # XXX How can I supress shell errors from being written - # to stderr ? - except os.error,why: - #print 'Command %s failed: %s' % (cmd,why) - continue - except IOError,why: - #print 'Command %s failed: %s' % (cmd,why) - continue - else: - break - else: - return system,release,version - - # Parse the output - info = string.strip(info) - m = _ver_output.match(info) - if m: - system,release,version = m.groups() - # Strip trailing dots from version and release - if release[-1] == '.': - release = release[:-1] - if version[-1] == '.': - version = version[:-1] - # Normalize the version and build strings (eliminating additional - # zeros) - version = _norm_version(version) - return system,release,version - -def _win32_getvalue(key,name,default=''): - - """ Read a value for name from the registry key. - - In case this fails, default is returned. - - """ - from win32api import RegQueryValueEx - try: - return RegQueryValueEx(key,name) - except: - return default - -def win32_ver(release='',version='',csd='',ptype=''): - - """ Get additional version information from the Windows Registry - and return a tuple (version,csd,ptype) referring to version - number, CSD level and OS type (multi/single - processor). - - As a hint: ptype returns 'Uniprocessor Free' on single - processor NT machines and 'Multiprocessor Free' on multi - processor machines. The 'Free' refers to the OS version being - free of debugging code. It could also state 'Checked' which - means the OS version uses debugging code, i.e. code that - checks arguments, ranges, etc. (Thomas Heller). - - Note: this function only works if Mark Hammond's win32 - package is installed and obviously only runs on Win32 - compatible platforms. - - """ - # XXX Is there any way to find out the processor type on WinXX ? - # XXX Is win32 available on Windows CE ? - # - # Adapted from code posted by Karl Putland to comp.lang.python. - # - # The mappings between reg. values and release names can be found - # here: http://msdn.microsoft.com/library/en-us/sysinfo/base/osversioninfo_str.asp - - # Import the needed APIs - try: - import win32api - except ImportError: - return release,version,csd,ptype - from win32api import RegQueryValueEx,RegOpenKeyEx,RegCloseKey,GetVersionEx - from win32con import HKEY_LOCAL_MACHINE,VER_PLATFORM_WIN32_NT,\ - VER_PLATFORM_WIN32_WINDOWS - - # Find out the registry key and some general version infos - maj,min,buildno,plat,csd = GetVersionEx() - version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF) - if csd[:13] == 'Service Pack ': - csd = 'SP' + csd[13:] - if plat == VER_PLATFORM_WIN32_WINDOWS: - regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion' - # Try to guess the release name - if maj == 4: - if min == 0: - release = '95' - elif min == 10: - release = '98' - elif min == 90: - release = 'Me' - else: - release = 'postMe' - elif maj == 5: - release = '2000' - elif plat == VER_PLATFORM_WIN32_NT: - regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion' - if maj <= 4: - release = 'NT' - elif maj == 5: - if min == 0: - release = '2000' - elif min == 1: - release = 'XP' - elif min == 2: - release = '2003Server' - else: - release = 'post2003' - else: - if not release: - # E.g. Win3.1 with win32s - release = '%i.%i' % (maj,min) - return release,version,csd,ptype - - # Open the registry key - try: - keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE,regkey) - # Get a value to make sure the key exists... - RegQueryValueEx(keyCurVer,'SystemRoot') - except: - return release,version,csd,ptype - - # Parse values - #subversion = _win32_getvalue(keyCurVer, - # 'SubVersionNumber', - # ('',1))[0] - #if subversion: - # release = release + subversion # 95a, 95b, etc. - build = _win32_getvalue(keyCurVer, - 'CurrentBuildNumber', - ('',1))[0] - ptype = _win32_getvalue(keyCurVer, - 'CurrentType', - (ptype,1))[0] - - # Normalize version - version = _norm_version(version,build) - - # Close key - RegCloseKey(keyCurVer) - return release,version,csd,ptype - -def _mac_ver_lookup(selectors,default=None): - - from gestalt import gestalt - import MacOS - l = [] - append = l.append - for selector in selectors: - try: - append(gestalt(selector)) - except (RuntimeError, MacOS.Error): - append(default) - return l - -def _bcd2str(bcd): - - return hex(bcd)[2:] - -def mac_ver(release='',versioninfo=('','',''),machine=''): - - """ Get MacOS version information and return it as tuple (release, - versioninfo, machine) with versioninfo being a tuple (version, - dev_stage, non_release_version). - - Entries which cannot be determined are set to the paramter values - which default to ''. All tuple entries are strings. - - Thanks to Mark R. Levinson for mailing documentation links and - code examples for this function. Documentation for the - gestalt() API is available online at: - - http://www.rgaros.nl/gestalt/ - - """ - # Check whether the version info module is available - try: - import gestalt - import MacOS - except ImportError: - return release,versioninfo,machine - # Get the infos - sysv,sysu,sysa = _mac_ver_lookup(('sysv','sysu','sysa')) - # Decode the infos - if sysv: - major = (sysv & 0xFF00) >> 8 - minor = (sysv & 0x00F0) >> 4 - patch = (sysv & 0x000F) - - if (major, minor) >= (10, 4): - # the 'sysv' gestald cannot return patchlevels - # higher than 9. Apple introduced 3 new - # gestalt codes in 10.4 to deal with this - # issue (needed because patch levels can - # run higher than 9, such as 10.4.11) - major,minor,patch = _mac_ver_lookup(('sys1','sys2','sys3')) - release = '%i.%i.%i' %(major, minor, patch) - else: - release = '%s.%i.%i' % (_bcd2str(major),minor,patch) - if sysu: - major = int((sysu & 0xFF000000L) >> 24) - minor = (sysu & 0x00F00000) >> 20 - bugfix = (sysu & 0x000F0000) >> 16 - stage = (sysu & 0x0000FF00) >> 8 - nonrel = (sysu & 0x000000FF) - version = '%s.%i.%i' % (_bcd2str(major),minor,bugfix) - nonrel = _bcd2str(nonrel) - stage = {0x20:'development', - 0x40:'alpha', - 0x60:'beta', - 0x80:'final'}.get(stage,'') - versioninfo = (version,stage,nonrel) - if sysa: - machine = {0x1: '68k', - 0x2: 'PowerPC', - 0xa: 'i386'}.get(sysa,'') - return release,versioninfo,machine - -def _java_getprop(name,default): - - from java.lang import System - from org.python.core.Py import newString - try: - return newString(System.getProperty(name)) - except: - return default - -def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): - - """ Version interface for Jython. - - Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being - a tuple (vm_name,vm_release,vm_vendor) and osinfo being a - tuple (os_name,os_version,os_arch). - - Values which cannot be determined are set to the defaults - given as parameters (which all default to ''). - - """ - # Import the needed APIs - try: - import java.lang - except ImportError: - return release,vendor,vminfo,osinfo - - vendor = _java_getprop('java.vendor',vendor) - release = _java_getprop('java.version',release) - vm_name,vm_release,vm_vendor = vminfo - vm_name = _java_getprop('java.vm.name',vm_name) - vm_vendor = _java_getprop('java.vm.vendor',vm_vendor) - vm_release = _java_getprop('java.vm.version',vm_release) - vminfo = vm_name,vm_release,vm_vendor - os_name,os_version,os_arch = osinfo - os_arch = _java_getprop('os.arch',os_arch) - os_name = _java_getprop('os.name',os_name) - os_version = _java_getprop('os.version',os_version) - osinfo = os_name,os_version,os_arch - - return release,vendor,vminfo,osinfo - -### System name aliasing - -def system_alias(system,release,version): - - """ Returns (system,release,version) aliased to common - marketing names used for some systems. - - It also does some reordering of the information in some cases - where it would otherwise cause confusion. - - """ - if system == 'Rhapsody': - # Apple's BSD derivative - # XXX How can we determine the marketing release number ? - return 'MacOS X Server',system+release,version - - elif system == 'SunOS': - # Sun's OS - if release < '5': - # These releases use the old name SunOS - return system,release,version - # Modify release (marketing release = SunOS release - 3) - l = string.split(release,'.') - if l: - try: - major = int(l[0]) - except ValueError: - pass - else: - major = major - 3 - l[0] = str(major) - release = string.join(l,'.') - if release < '6': - system = 'Solaris' - else: - # XXX Whatever the new SunOS marketing name is... - system = 'Solaris' - - elif system == 'IRIX64': - # IRIX reports IRIX64 on platforms with 64-bit support; yet it - # is really a version and not a different platform, since 32-bit - # apps are also supported.. - system = 'IRIX' - if version: - version = version + ' (64bit)' - else: - version = '64bit' - - elif system in ('win32','win16'): - # In case one of the other tricks - system = 'Windows' - - return system,release,version - -### Various internal helpers - -def _platform(*args): - - """ Helper to format the platform string in a filename - compatible format e.g. "system-version-machine". - """ - # Format the platform string - platform = string.join( - map(string.strip, - filter(len,args)), - '-') - - # Cleanup some possible filename obstacles... - replace = string.replace - platform = replace(platform,' ','_') - platform = replace(platform,'/','-') - platform = replace(platform,'\\','-') - platform = replace(platform,':','-') - platform = replace(platform,';','-') - platform = replace(platform,'"','-') - platform = replace(platform,'(','-') - platform = replace(platform,')','-') - - # No need to report 'unknown' information... - platform = replace(platform,'unknown','') - - # Fold '--'s and remove trailing '-' - while 1: - cleaned = replace(platform,'--','-') - if cleaned == platform: - break - platform = cleaned - while platform[-1] == '-': - platform = platform[:-1] - - return platform - -def _node(default=''): - - """ Helper to determine the node name of this machine. - """ - try: - import socket - except ImportError: - # No sockets... - return default - try: - return socket.gethostname() - except socket.error: - # Still not working... - return default - -# os.path.abspath is new in Python 1.5.2: -if not hasattr(os.path,'abspath'): - - def _abspath(path, - - isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd, - normpath=os.path.normpath): - - if not isabs(path): - path = join(getcwd(), path) - return normpath(path) - -else: - - _abspath = os.path.abspath - -def _follow_symlinks(filepath): - - """ In case filepath is a symlink, follow it until a - real file is reached. - """ - filepath = _abspath(filepath) - while os.path.islink(filepath): - filepath = os.path.normpath( - os.path.join(os.path.dirname(filepath),os.readlink(filepath))) - return filepath - -def _syscmd_uname(option,default=''): - - """ Interface to the system's uname command. - """ - if sys.platform in ('dos','win32','win16','os2'): - # XXX Others too ? - return default - try: - f = os.popen('uname %s 2> /dev/null' % option) - except (AttributeError,os.error): - return default - output = string.strip(f.read()) - rc = f.close() - if not output or rc: - return default - else: - return output - -def _syscmd_file(target,default=''): - - """ Interface to the system's file command. - - The function uses the -b option of the file command to have it - ommit the filename in its output and if possible the -L option - to have the command follow symlinks. It returns default in - case the command should fail. - - """ - target = _follow_symlinks(target) - try: - f = os.popen('file %s 2> /dev/null' % target) - except (AttributeError,os.error): - return default - output = string.strip(f.read()) - rc = f.close() - if not output or rc: - return default - else: - return output - -### Information about the used architecture - -# Default values for architecture; non-empty strings override the -# defaults given as parameters -_default_architecture = { - 'win32': ('','WindowsPE'), - 'win16': ('','Windows'), - 'dos': ('','MSDOS'), -} - -_architecture_split = re.compile(r'[\s,]').split - -def architecture(executable=sys.executable,bits='',linkage=''): - - """ Queries the given executable (defaults to the Python interpreter - binary) for various architecture information. - - Returns a tuple (bits,linkage) which contains information about - the bit architecture and the linkage format used for the - executable. Both values are returned as strings. - - Values that cannot be determined are returned as given by the - parameter presets. If bits is given as '', the sizeof(pointer) - (or sizeof(long) on Python version < 1.5.2) is used as - indicator for the supported pointer size. - - The function relies on the system's "file" command to do the - actual work. This is available on most if not all Unix - platforms. On some non-Unix platforms where the "file" command - does not exist and the executable is set to the Python interpreter - binary defaults from _default_architecture are used. - - """ - # Use the sizeof(pointer) as default number of bits if nothing - # else is given as default. - if not bits: - import struct - try: - size = struct.calcsize('P') - except struct.error: - # Older installations can only query longs - size = struct.calcsize('l') - bits = str(size*8) + 'bit' - - # Get data from the 'file' system command - output = _syscmd_file(executable,'') - - if not output and \ - executable == sys.executable: - # "file" command did not return anything; we'll try to provide - # some sensible defaults then... - if _default_architecture.has_key(sys.platform): - b,l = _default_architecture[sys.platform] - if b: - bits = b - if l: - linkage = l - return bits,linkage - - # Split the output into a list of strings omitting the filename - fileout = _architecture_split(output)[1:] - - if 'executable' not in fileout: - # Format not supported - return bits,linkage - - # Bits - if '32-bit' in fileout: - bits = '32bit' - elif 'N32' in fileout: - # On Irix only - bits = 'n32bit' - elif '64-bit' in fileout: - bits = '64bit' - - # Linkage - if 'ELF' in fileout: - linkage = 'ELF' - elif 'PE' in fileout: - # E.g. Windows uses this format - if 'Windows' in fileout: - linkage = 'WindowsPE' - else: - linkage = 'PE' - elif 'COFF' in fileout: - linkage = 'COFF' - elif 'MS-DOS' in fileout: - linkage = 'MSDOS' - else: - # XXX the A.OUT format also falls under this class... - pass - - return bits,linkage - -### Portable uname() interface - -_uname_cache = None - -def uname(): - - """ Fairly portable uname interface. Returns a tuple - of strings (system,node,release,version,machine,processor) - identifying the underlying platform. - - Note that unlike the os.uname function this also returns - possible processor information as an additional tuple entry. - - Entries which cannot be determined are set to ''. - - """ - global _uname_cache - - if _uname_cache is not None: - return _uname_cache - - # Get some infos from the builtin os.uname API... - try: - system,node,release,version,machine = os.uname() - - except AttributeError: - # Hmm, no uname... we'll have to poke around the system then. - system = sys.platform - release = '' - version = '' - node = _node() - machine = '' - processor = '' - use_syscmd_ver = 1 - - # Try win32_ver() on win32 platforms - if system == 'win32': - release,version,csd,ptype = win32_ver() - if release and version: - use_syscmd_ver = 0 - - # Try the 'ver' system command available on some - # platforms - if use_syscmd_ver: - system,release,version = _syscmd_ver(system) - # Normalize system to what win32_ver() normally returns - # (_syscmd_ver() tends to return the vendor name as well) - if system == 'Microsoft Windows': - system = 'Windows' - - # In case we still don't know anything useful, we'll try to - # help ourselves - if system in ('win32','win16'): - if not version: - if system == 'win32': - version = '32bit' - else: - version = '16bit' - system = 'Windows' - - elif system[:4] == 'java': - release,vendor,vminfo,osinfo = java_ver() - system = 'Java' - version = string.join(vminfo,', ') - if not version: - version = vendor - - elif os.name == 'mac': - release,(version,stage,nonrel),machine = mac_ver() - system = 'MacOS' - - else: - # System specific extensions - if system == 'OpenVMS': - # OpenVMS seems to have release and version mixed up - if not release or release == '0': - release = version - version = '' - # Get processor information - try: - import vms_lib - except ImportError: - pass - else: - csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0) - if (cpu_number >= 128): - processor = 'Alpha' - else: - processor = 'VAX' - else: - # Get processor information from the uname system command - processor = _syscmd_uname('-p','') - - # 'unknown' is not really any useful as information; we'll convert - # it to '' which is more portable - if system == 'unknown': - system = '' - if node == 'unknown': - node = '' - if release == 'unknown': - release = '' - if version == 'unknown': - version = '' - if machine == 'unknown': - machine = '' - if processor == 'unknown': - processor = '' - - # normalize name - if system == 'Microsoft' and release == 'Windows': - system = 'Windows' - release = 'Vista' - - _uname_cache = system,node,release,version,machine,processor - return _uname_cache - -### Direct interfaces to some of the uname() return values - -def system(): - - """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'. - - An empty string is returned if the value cannot be determined. - - """ - return uname()[0] - -def node(): - - """ Returns the computer's network name (which may not be fully - qualified) - - An empty string is returned if the value cannot be determined. - - """ - return uname()[1] - -def release(): - - """ Returns the system's release, e.g. '2.2.0' or 'NT' - - An empty string is returned if the value cannot be determined. - - """ - return uname()[2] - -def version(): - - """ Returns the system's release version, e.g. '#3 on degas' - - An empty string is returned if the value cannot be determined. - - """ - return uname()[3] - -def machine(): - - """ Returns the machine type, e.g. 'i386' - - An empty string is returned if the value cannot be determined. - - """ - return uname()[4] - -def processor(): - - """ Returns the (true) processor name, e.g. 'amdk6' - - An empty string is returned if the value cannot be - determined. Note that many platforms do not provide this - information or simply return the same value as for machine(), - e.g. NetBSD does this. - - """ - return uname()[5] - -### Various APIs for extracting information from sys.version - -_sys_version_parser = re.compile(r'([\w.+]+)\s*' - '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' - '\[([^\]]+)\]?') -_sys_version_cache = None - -def _sys_version(): - - """ Returns a parsed version of Python's sys.version as tuple - (version, buildno, builddate, compiler) referring to the Python - version, build number, build date/time as string and the compiler - identification string. - - Note that unlike the Python sys.version, the returned value - for the Python version will always include the patchlevel (it - defaults to '.0'). - - """ - global _sys_version_cache - - if _sys_version_cache is not None: - return _sys_version_cache - version, buildno, builddate, buildtime, compiler = \ - _sys_version_parser.match(sys.version).groups() - builddate = builddate + ' ' + buildtime - l = string.split(version, '.') - if len(l) == 2: - l.append('0') - version = string.join(l, '.') - _sys_version_cache = (version, buildno, builddate, compiler) - return _sys_version_cache - -def python_version(): - - """ Returns the Python version as string 'major.minor.patchlevel' - - Note that unlike the Python sys.version, the returned value - will always include the patchlevel (it defaults to 0). - - """ - return _sys_version()[0] - -def python_version_tuple(): - - """ Returns the Python version as tuple (major, minor, patchlevel) - of strings. - - Note that unlike the Python sys.version, the returned value - will always include the patchlevel (it defaults to 0). - - """ - return string.split(_sys_version()[0], '.') - -def python_build(): - - """ Returns a tuple (buildno, builddate) stating the Python - build number and date as strings. - - """ - return _sys_version()[1:3] - -def python_compiler(): - - """ Returns a string identifying the compiler used for compiling - Python. - - """ - return _sys_version()[3] - -### The Opus Magnum of platform strings :-) - -_platform_cache = {} - -def platform(aliased=0, terse=0): - - """ Returns a single string identifying the underlying platform - with as much useful information as possible (but no more :). - - The output is intended to be human readable rather than - machine parseable. It may look different on different - platforms and this is intended. - - If "aliased" is true, the function will use aliases for - various platforms that report system names which differ from - their common names, e.g. SunOS will be reported as - Solaris. The system_alias() function is used to implement - this. - - Setting terse to true causes the function to return only the - absolute minimum information needed to identify the platform. - - """ - result = _platform_cache.get((aliased, terse), None) - if result is not None: - return result - - # Get uname information and then apply platform specific cosmetics - # to it... - system,node,release,version,machine,processor = uname() - if machine == processor: - processor = '' - if aliased: - system,release,version = system_alias(system,release,version) - - if system == 'Windows': - # MS platforms - rel,vers,csd,ptype = win32_ver(version) - if terse: - platform = _platform(system,release) - else: - platform = _platform(system,release,version,csd) - - elif system in ('Linux',): - # Linux based systems - distname,distversion,distid = dist('') - if distname and not terse: - platform = _platform(system,release,machine,processor, - 'with', - distname,distversion,distid) - else: - # If the distribution name is unknown check for libc vs. glibc - libcname,libcversion = libc_ver(sys.executable) - platform = _platform(system,release,machine,processor, - 'with', - libcname+libcversion) - elif system == 'Java': - # Java platforms - r,v,vminfo,(os_name,os_version,os_arch) = java_ver() - if terse: - platform = _platform(system,release,version) - else: - platform = _platform(system,release,version, - 'on', - os_name,os_version,os_arch) - - elif system == 'MacOS': - # MacOS platforms - if terse: - platform = _platform(system,release) - else: - platform = _platform(system,release,machine) - - else: - # Generic handler - if terse: - platform = _platform(system,release) - else: - bits,linkage = architecture(sys.executable) - platform = _platform(system,release,machine,processor,bits,linkage) - - _platform_cache[(aliased, terse)] = platform - return platform - -### Command line interface - -if __name__ == '__main__': - # Default is to print the aliased verbose platform string - terse = ('terse' in sys.argv or '--terse' in sys.argv) - aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv) - print platform(aliased,terse) - sys.exit(0) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-02 18:14:34
|
Revision: 6057 http://jython.svn.sourceforge.net/jython/?rev=6057&view=rev Author: fwierzbicki Date: 2009-03-02 18:14:30 +0000 (Mon, 02 Mar 2009) Log Message: ----------- from: http://svn.python.org/projects/python/trunk/Lib/_abcoll.py@70016 Added Paths: ----------- trunk/sandbox/wierzbicki/test27/Lib/_abcoll.py Added: trunk/sandbox/wierzbicki/test27/Lib/_abcoll.py =================================================================== --- trunk/sandbox/wierzbicki/test27/Lib/_abcoll.py (rev 0) +++ trunk/sandbox/wierzbicki/test27/Lib/_abcoll.py 2009-03-02 18:14:30 UTC (rev 6057) @@ -0,0 +1,565 @@ +# 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, c): + for value in self: + if value not in c: + 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) + + def __repr__(self): + return '{0.__class__.__name__}({0._mapping!r})'.format(self) + + +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) +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) + +MutableSequence.register(list) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-02 18:12:27
|
Revision: 6056 http://jython.svn.sourceforge.net/jython/?rev=6056&view=rev Author: fwierzbicki Date: 2009-03-02 18:12:22 +0000 (Mon, 02 Mar 2009) Log Message: ----------- Intital 2.7 tweaks: parser updates, with statement always on, add abc.py. Modified Paths: -------------- trunk/sandbox/wierzbicki/test27/CPythonLib.includes trunk/sandbox/wierzbicki/test27/grammar/Python.g trunk/sandbox/wierzbicki/test27/src/org/python/antlr/GrammarActions.java trunk/sandbox/wierzbicki/test27/src/org/python/compiler/CodeCompiler.java Property Changed: ---------------- trunk/sandbox/wierzbicki/test27/ Property changes on: trunk/sandbox/wierzbicki/test27 ___________________________________________________________________ Modified: svn:externals - CPythonLib -r70085 http://svn.python.org/projects/python/branches/release25-maint/Lib/ + CPythonLib -r70098 http://svn.python.org/projects/python/trunk/Lib/ Modified: trunk/sandbox/wierzbicki/test27/CPythonLib.includes =================================================================== --- trunk/sandbox/wierzbicki/test27/CPythonLib.includes 2009-03-02 15:59:20 UTC (rev 6055) +++ trunk/sandbox/wierzbicki/test27/CPythonLib.includes 2009-03-02 18:12:22 UTC (rev 6056) @@ -16,6 +16,7 @@ _MozillaCookieJar.py _strptime.py _threading_local.py +abc.py aifc.py anydbm.py atexit.py Modified: trunk/sandbox/wierzbicki/test27/grammar/Python.g =================================================================== --- trunk/sandbox/wierzbicki/test27/grammar/Python.g 2009-03-02 15:59:20 UTC (rev 6055) +++ trunk/sandbox/wierzbicki/test27/grammar/Python.g 2009-03-02 18:12:22 UTC (rev 6056) @@ -936,9 +936,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)]) ; @@ -1481,7 +1481,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] )? )? @@ -1735,8 +1735,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 @@ -1755,7 +1759,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'|'"'))* '"' @@ -1769,7 +1773,7 @@ ; STRINGPART - : {partial}?=> ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? + : {partial}?=> ('r'|'u'|'b'|'ur'|'R'|'U'|'B'|'UR'|'uR'|'Ur')? ( '\'\'\'' ~('\'\'\'')* | '"""' ~('"""')* ) Modified: trunk/sandbox/wierzbicki/test27/src/org/python/antlr/GrammarActions.java =================================================================== --- trunk/sandbox/wierzbicki/test27/src/org/python/antlr/GrammarActions.java 2009-03-02 15:59:20 UTC (rev 6055) +++ trunk/sandbox/wierzbicki/test27/src/org/python/antlr/GrammarActions.java 2009-03-02 18:12:22 UTC (rev 6056) @@ -350,6 +350,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; } @@ -415,6 +421,10 @@ int end; boolean ustring = false; + if (quoteChar == 'b' || quoteChar == 'B') { + start++; + } + if (quoteChar == 'u' || quoteChar == 'U') { ustring = true; start++; Modified: trunk/sandbox/wierzbicki/test27/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/sandbox/wierzbicki/test27/src/org/python/compiler/CodeCompiler.java 2009-03-02 15:59:20 UTC (rev 6055) +++ trunk/sandbox/wierzbicki/test27/src/org/python/compiler/CodeCompiler.java 2009-03-02 18:12:22 UTC (rev 6056) @@ -2229,10 +2229,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(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-03-02 15:59:24
|
Revision: 6055 http://jython.svn.sourceforge.net/jython/?rev=6055&view=rev Author: thobes Date: 2009-03-02 15:59:20 +0000 (Mon, 02 Mar 2009) Log Message: ----------- Moving the advanced branch. All useful things imported. At this point there are two patches to jython for integrating the advanced compiler: * One patch to make the flags that are passed around in compilation type safe. * One patch to decouple the compiler implementation and provide an extension point where a new compiler can be inserted. Modified Paths: -------------- trunk/sandbox/tobias/.hg/patches/series trunk/sandbox/tobias/.hgignore trunk/sandbox/tobias/README.txt trunk/sandbox/tobias/compiler/src/org/python/compiler/AdvancedCompiler.java trunk/sandbox/tobias/compiler/src/org/python/compiler/AdvancedPreferences.java trunk/sandbox/tobias/compiler/src/org/python/compiler/CodeGenerator.java trunk/sandbox/tobias/compiler/src/org/python/compiler/CompilerDirector.java trunk/sandbox/tobias/compiler/src/org/python/compiler/ConstantChecker.java trunk/sandbox/tobias/compiler/src/org/python/compiler/DirectCodeBundle.java trunk/sandbox/tobias/compiler/src/org/python/compiler/DirectGenerator.java trunk/sandbox/tobias/compiler/src/org/python/compiler/FlowGraphBundle.java trunk/sandbox/tobias/compiler/src/org/python/compiler/FlowGraphGenerator.java trunk/sandbox/tobias/compiler/src/org/python/compiler/GeneratedCodeState.java trunk/sandbox/tobias/compiler/src/org/python/compiler/IntermediateCodeGenerator.java trunk/sandbox/tobias/compiler/src/org/python/compiler/IntermediateCodeGeneratorFactory.java trunk/sandbox/tobias/compiler/src/org/python/compiler/PragmaParser.java trunk/sandbox/tobias/compiler/src/org/python/compiler/ScopeInformation.java trunk/sandbox/tobias/compiler/src/org/python/compiler/ScopesBuilder.java trunk/sandbox/tobias/compiler/src/org/python/compiler/advanced/EnvironmentHolder.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/Block.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/CodeGraph.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/Constant.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/ValueOperation.java Added Paths: ----------- trunk/sandbox/tobias/.classpath trunk/sandbox/tobias/.externalToolBuilders/ trunk/sandbox/tobias/.externalToolBuilders/Build preparation.launch trunk/sandbox/tobias/.hg/hgrc trunk/sandbox/tobias/.hg/patches/decouple.patch trunk/sandbox/tobias/.hg/patches/types.patch trunk/sandbox/tobias/.project trunk/sandbox/tobias/.settings/ trunk/sandbox/tobias/.settings/org.eclipse.jdt.core.prefs trunk/sandbox/tobias/agent/ trunk/sandbox/tobias/agent/build.xml trunk/sandbox/tobias/agent/src/ trunk/sandbox/tobias/agent/src/org/python/javaagent/InstrumentationProxy.java trunk/sandbox/tobias/build.xml trunk/sandbox/tobias/bytecode/ trunk/sandbox/tobias/bytecode/build.xml trunk/sandbox/tobias/bytecode/src/ trunk/sandbox/tobias/bytecode/src/org/ trunk/sandbox/tobias/bytecode/src/org/python/ trunk/sandbox/tobias/bytecode/src/org/python/bytecode/ trunk/sandbox/tobias/compiler/build.xml trunk/sandbox/tobias/compiler/src/ trunk/sandbox/tobias/compiler/src/org/ trunk/sandbox/tobias/compiler/src/org/python/ trunk/sandbox/tobias/compiler/src/org/python/compiler/ trunk/sandbox/tobias/compiler/src/org/python/compiler/BytecodeBundle.java trunk/sandbox/tobias/compiler/src/org/python/compiler/BytecodeCodeBundle.java trunk/sandbox/tobias/compiler/src/org/python/compiler/CodeGeneratorGraphVisitor.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/BlockBuilder.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/BlockBuilderImpl.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/BlockState.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/BlockTermination.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/CodeGraphFactory.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/CodeGraphVisitor.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/CodeReference.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/ConsumerCallback.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/GraphInfo.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/Instruction.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/ProducerCallback.java trunk/sandbox/tobias/compiler/src/org/python/compiler/flowgraph/SimpleCallback.java trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/ trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/Construct.java trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/Define.java trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/Exception.java trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/Import.java trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/Invocation.java trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/MemoryOperation.java trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/Operator.java trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/SystemCalls.java trunk/sandbox/tobias/compiler/src/org/python/compiler/instructions/TypeOperation.java trunk/sandbox/tobias/compiler/src/org/thobe/ trunk/sandbox/tobias/compiler/src/org/thobe/compiler/ trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/ trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/Graph.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/GraphVisitor.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/HandlerBlock.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/IfNode.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/Node.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/OpNode.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/PhiNode.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/SwitchNode.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/Value.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/ValueNode.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/ValueOperation.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/ValueType.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/VariableLocation.java trunk/sandbox/tobias/compiler/src/org/thobe/compiler/sea/VoidOperation.java trunk/sandbox/tobias/util/ trunk/sandbox/tobias/util/build.xml trunk/sandbox/tobias/util/src/ trunk/sandbox/tobias/util/src/org/ trunk/sandbox/tobias/util/src/org/python/ trunk/sandbox/tobias/util/src/org/python/code/ trunk/sandbox/tobias/util/src/org/python/hash/ Property Changed: ---------------- trunk/sandbox/tobias/ trunk/sandbox/tobias/.hg/patches/ trunk/sandbox/tobias/compiler/ Property changes on: trunk/sandbox/tobias ___________________________________________________________________ Modified: svn:externals - jython https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython + jython https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython frame https://projects.thobe.org/svn/public/javaframe Added: svn:ignore + target Added: trunk/sandbox/tobias/.classpath =================================================================== --- trunk/sandbox/tobias/.classpath (rev 0) +++ trunk/sandbox/tobias/.classpath 2009-03-02 15:59:20 UTC (rev 6055) @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry excluding="com/ziclix/python/sql/|com/ziclix/python/sql/connect/|com/ziclix/python/sql/handler/|com/ziclix/python/sql/pipe/|com/ziclix/python/sql/pipe/csv/|com/ziclix/python/sql/pipe/db/|com/ziclix/python/sql/procedure/|com/ziclix/python/sql/resource/|com/ziclix/python/sql/util/" kind="src" path="jython/src"/> + <classpathentry excluding="org/python/compiler/advanced/ast/" kind="src" path="compiler/src"/> + <classpathentry kind="src" path="util/src"/> + <classpathentry kind="src" path="bytecode/src"/> + <classpathentry kind="src" path="agent/src"/> + <classpathentry kind="src" path="frame/src"/> + <classpathentry kind="src" path="frame/test"/> + <classpathentry kind="src" path="jython/build/gensrc"/> + <classpathentry kind="src" path="jython/tests/java"/> + <classpathentry kind="lib" path="jython/Demo/jreload/example.jar"/> + <classpathentry kind="lib" path="jython/extlibs/antlr-2.7.7.jar"/> + <classpathentry kind="lib" path="jython/extlibs/asm-3.1.jar"/> + <classpathentry kind="lib" path="jython/extlibs/asm-commons-3.1.jar"/> + <classpathentry kind="lib" path="jython/extlibs/asm-util-3.1.jar"/> + <classpathentry kind="lib" path="jython/extlibs/constantine-0.4.jar"/> + <classpathentry kind="lib" path="jython/extlibs/cpptasks/cpptasks.jar"/> + <classpathentry kind="lib" path="jython/extlibs/jarjar-0.7.jar"/> + <classpathentry kind="lib" path="jython/extlibs/jline-0.9.94.jar"/> + <classpathentry kind="lib" path="jython/extlibs/jna-posix.jar"/> + <classpathentry kind="lib" path="jython/extlibs/jna.jar"/> + <classpathentry kind="lib" path="jython/extlibs/junit-3.8.2.jar"/> + <classpathentry kind="lib" path="jython/extlibs/libreadline-java-0.8.jar"/> + <classpathentry kind="lib" path="jython/extlibs/mysql-connector-java-5.1.6.jar"/> + <classpathentry kind="lib" path="jython/extlibs/postgresql-8.3-603.jdbc4.jar"/> + <classpathentry kind="lib" path="jython/extlibs/profile.jar"/> + <classpathentry kind="lib" path="jython/extlibs/servlet-api-2.5.jar"/> + <classpathentry kind="lib" path="jython/extlibs/stringtemplate-3.2.jar"/> + <classpathentry kind="lib" path="jython/extlibs/svnant-jars/svnant.jar"/> + <classpathentry kind="lib" path="jython/extlibs/svnant-jars/svnClientAdapter.jar"/> + <classpathentry kind="lib" path="jython/extlibs/svnant-jars/svnjavahl.jar"/> + <classpathentry kind="lib" path="jython/extlibs/xercesImpl-2.9.1.jar"/> + <classpathentry kind="lib" path="jython/Lib/test/blob.jar"/> + <classpathentry kind="lib" path="jython/Lib/test/bug1239.jar"/> + <classpathentry kind="lib" path="jython/Lib/test/classimport_Lib.jar"/> + <classpathentry kind="lib" path="jython/Lib/test/classimport.jar"/> + <classpathentry kind="lib" path="jython/Lib/test/syspath_import.jar"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/JVM 1.5.0 (Mac OS X default)"/> + <classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/> + <classpathentry kind="lib" path="jython/extlibs/antlr-3.1.2.jar"/> + <classpathentry kind="lib" path="jython/extlibs/antlr-runtime-3.1.2.jar"/> + <classpathentry kind="output" path="target/build"/> +</classpath> Added: trunk/sandbox/tobias/.externalToolBuilders/Build preparation.launch =================================================================== --- trunk/sandbox/tobias/.externalToolBuilders/Build preparation.launch (rev 0) +++ trunk/sandbox/tobias/.externalToolBuilders/Build preparation.launch 2009-03-02 15:59:20 UTC (rev 6055) @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?><launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AFTER_CLEAN_TARGETS" value="antlr_gen,"/> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_MANUAL_TARGETS" value="antlr_gen,"/> +<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/> +<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> +<listEntry value="/advanced-compiler/jython/build.xml"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> +<listEntry value="1"/> +</listAttribute> +<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> +<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> +<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="advanced-compiler"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/advanced-compiler/jython/build.xml}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,"/> +<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> +</launchConfiguration> Added: trunk/sandbox/tobias/.hg/hgrc =================================================================== --- trunk/sandbox/tobias/.hg/hgrc (rev 0) +++ trunk/sandbox/tobias/.hg/hgrc 2009-03-02 15:59:20 UTC (rev 6055) @@ -0,0 +1,3 @@ +[diff] +nodates=1 +git=1 Property changes on: trunk/sandbox/tobias/.hg/patches ___________________________________________________________________ Modified: svn:ignore - status + status guards Added: trunk/sandbox/tobias/.hg/patches/decouple.patch =================================================================== --- trunk/sandbox/tobias/.hg/patches/decouple.patch (rev 0) +++ trunk/sandbox/tobias/.hg/patches/decouple.patch 2009-03-02 15:59:20 UTC (rev 6055) @@ -0,0 +1,375 @@ +diff --git a/jython/src/org/python/compiler/LegacyCompiler.java b/jython/src/org/python/compiler/LegacyCompiler.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/compiler/LegacyCompiler.java +@@ -0,0 +1,72 @@ ++package org.python.compiler; ++ ++import java.io.ByteArrayOutputStream; ++import java.io.OutputStream; ++ ++import org.python.antlr.base.mod; ++import org.python.core.BytecodeLoader; ++import org.python.core.CompilerFlags; ++import org.python.core.Py; ++import org.python.core.PyCode; ++import org.python.core.PythonCodeBundle; ++import org.python.core.PythonCompiler; ++ ++public class LegacyCompiler implements PythonCompiler { ++ ++ public PythonCodeBundle compile(mod node, String name, String filename, ++ boolean linenumbers, boolean printResults, CompilerFlags cflags) { ++ return new LazyLegacyBundle(node, name, filename, linenumbers, ++ printResults, cflags); ++ } ++ ++ private static class LazyLegacyBundle implements PythonCodeBundle { ++ ++ private final mod node; ++ private final String name; ++ private final String filename; ++ private final boolean linenumbers; ++ private final boolean printResults; ++ private final CompilerFlags cflags; ++ private ByteArrayOutputStream ostream = null; ++ ++ public LazyLegacyBundle(mod node, String name, String filename, ++ boolean linenumbers, boolean printResults, CompilerFlags cflags) { ++ this.node = node; ++ this.name = name; ++ this.filename = filename; ++ this.linenumbers = linenumbers; ++ this.printResults = printResults; ++ this.cflags = cflags; ++ } ++ ++ public PyCode loadCode() throws Exception { ++ return BytecodeLoader.makeCode(name, ostream().toByteArray(), ++ filename); ++ } ++ ++ public void writeTo(OutputStream stream) throws Exception { ++ if (this.ostream != null) { ++ stream.write(ostream.toByteArray()); ++ } else { ++ Module.compile(node, stream, name, filename, linenumbers, ++ printResults, cflags); ++ } ++ } ++ ++ public void saveCode(String directory) throws Exception { ++ // FIXME: this is slightly broken, it should use the directory ++ Py.saveClassFile(name, ostream()); ++ } ++ ++ private ByteArrayOutputStream ostream() throws Exception { ++ if (ostream == null) { ++ ostream = new ByteArrayOutputStream(); ++ Module.compile(node, ostream, name, filename, linenumbers, ++ printResults, cflags); ++ } ++ return ostream; ++ } ++ ++ } ++ ++} +diff --git a/jython/src/org/python/compiler/Module.java b/jython/src/org/python/compiler/Module.java +--- a/jython/src/org/python/compiler/Module.java ++++ b/jython/src/org/python/compiler/Module.java +@@ -12,10 +12,14 @@ + + import org.objectweb.asm.Label; + import org.objectweb.asm.Opcodes; ++import org.python.core.CodeBootstrap; + import org.python.core.CodeFlag; ++import org.python.core.CodeLoader; + import org.python.core.CompilerFlags; + import org.python.core.Py; + import org.python.core.PyException; ++import org.python.core.PyRunnableBootstrap; ++import org.objectweb.asm.Type; + import org.python.antlr.ParseException; + import org.python.antlr.PythonTree; + import org.python.antlr.ast.Suite; +@@ -541,10 +545,26 @@ + c.dup(); + c.ldc(classfile.name); + c.invokespecial(classfile.name, "<init>", "(" + $str + ")V"); ++ c.invokevirtual(classfile.name, "getMain", "()" + $pyCode); ++ String bootstrap = Type.getDescriptor(CodeBootstrap.class); ++ c.invokestatic(Type.getInternalName(CodeLoader.class), ++ CodeLoader.SIMPLE_FACTORY_METHOD_NAME, ++ "(" + $pyCode + ")" + bootstrap); + c.aload(0); +- c.invokestatic("org/python/core/Py", "runMain", "(" + $pyRunnable + $strArr + ")V"); ++ c.invokestatic("org/python/core/Py", "runMain", "(" + bootstrap + $strArr + ")V"); + c.return_(); + } ++ ++ public void addBootstrap() throws IOException { ++ Code c = classfile.addMethod(CodeLoader.GET_BOOTSTRAP_METHOD_NAME, ++ "()" + Type.getDescriptor(CodeBootstrap.class), ++ ACC_PUBLIC | ACC_STATIC); ++ c.ldc(Type.getType("L" + classfile.name + ";")); ++ c.invokestatic(Type.getInternalName(PyRunnableBootstrap.class), ++ PyRunnableBootstrap.REFLECTION_METHOD_NAME, ++ "(" + $clss + ")" + Type.getDescriptor(CodeBootstrap.class)); ++ c.areturn(); ++ } + + public void addConstants(Code c) throws IOException { + classfile.addField("self", "L"+classfile.name+";", +@@ -599,6 +619,7 @@ + addInit(); + addRunnable(); + addMain(); ++ addBootstrap(); + + addFunctions(); + +diff --git a/jython/src/org/python/core/CodeBootstrap.java b/jython/src/org/python/core/CodeBootstrap.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/core/CodeBootstrap.java +@@ -0,0 +1,7 @@ ++package org.python.core; ++ ++public interface CodeBootstrap { ++ ++ PyCode loadCode(CodeLoader loader); ++ ++} +diff --git a/jython/src/org/python/core/CodeLoader.java b/jython/src/org/python/core/CodeLoader.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/core/CodeLoader.java +@@ -0,0 +1,60 @@ ++package org.python.core; ++ ++import java.lang.reflect.InvocationTargetException; ++import java.lang.reflect.Method; ++import java.lang.reflect.Modifier; ++ ++public final class CodeLoader { ++ ++ public static final String GET_BOOTSTRAP_METHOD_NAME = "getCodeBootstrap"; ++ public final String name; ++ public final String filename; ++ ++ private CodeLoader(String name, String filename) { ++ this.name = name; ++ this.filename = filename; ++ } ++ ++ public static boolean canLoad(Class<?> cls) { ++ try { ++ Method getBootstrap = cls.getMethod(GET_BOOTSTRAP_METHOD_NAME); ++ return Modifier.isStatic(getBootstrap.getModifiers()); ++ } catch (Exception e) { ++ return false; ++ } ++ } ++ ++ public static PyCode loadCode(Class<?> cls, String name, String filename) ++ throws SecurityException, NoSuchMethodException, ++ IllegalArgumentException, IllegalAccessException, ++ InvocationTargetException { ++ Method getBootstrap = cls.getMethod(GET_BOOTSTRAP_METHOD_NAME); ++ CodeBootstrap bootstrap = (CodeBootstrap) getBootstrap.invoke(null); ++ return loadCode(bootstrap, name, filename); ++ } ++ ++ public static PyCode loadCode(Class<?> cls) throws SecurityException, ++ IllegalArgumentException, NoSuchMethodException, ++ IllegalAccessException, InvocationTargetException { ++ return loadCode(cls, null, null); ++ } ++ ++ public static PyCode loadCode(CodeBootstrap bootstrap, String name, ++ String filename) { ++ return bootstrap.loadCode(new CodeLoader(name, filename)); ++ } ++ ++ public static PyCode loadCode(CodeBootstrap bootstrap) { ++ return loadCode(bootstrap, null, null); ++ } ++ ++ public static final String SIMPLE_FACTORY_METHOD_NAME = "createSimpleBootstrap"; ++ ++ public static CodeBootstrap createSimpleBootstrap(final PyCode code) { ++ return new CodeBootstrap() { ++ public PyCode loadCode(CodeLoader loader) { ++ return code; ++ } ++ }; ++ } ++} +diff --git a/jython/src/org/python/core/CompilerFacade.java b/jython/src/org/python/core/CompilerFacade.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/core/CompilerFacade.java +@@ -0,0 +1,39 @@ ++package org.python.core; ++ ++import org.python.antlr.base.mod; ++import org.python.compiler.LegacyCompiler; ++ ++/** ++ * Facade for different compiler implementations. ++ * ++ * The static methods of this class act as a Facade for the compiler subsystem. ++ * This is so that the rest of Jython (even generated code) can statically link ++ * to the static interface of this class, while allowing for different ++ * implementations of the various components of the compiler subsystem. ++ * ++ * @author Tobias Ivarsson ++ */ ++public class CompilerFacade { ++ ++ private static volatile PythonCompiler compiler = loadDefaultCompiler(); ++ ++ public static void setCompiler(PythonCompiler compiler) { ++ CompilerFacade.compiler = compiler; ++ } ++ ++ private static PythonCompiler loadDefaultCompiler() { ++ return new LegacyCompiler(); ++ } ++ ++ public static PyCode compile(mod node, String name, String filename, ++ boolean linenumbers, boolean printResults, CompilerFlags cflags) { ++ try { ++ PythonCodeBundle bundle = compiler.compile(node, name, filename, ++ linenumbers, printResults, cflags); ++ bundle.saveCode(Options.proxyDebugDirectory); ++ return bundle.loadCode(); ++ } catch (Throwable t) { ++ throw ParserFacade.fixParseError(null, t, filename); ++ } ++ } ++} +diff --git a/jython/src/org/python/core/Py.java b/jython/src/org/python/core/Py.java +--- a/jython/src/org/python/core/Py.java ++++ b/jython/src/org/python/core/Py.java +@@ -862,9 +862,19 @@ + * Called by the code generated in {@link Module#addMain()} + */ + public static void runMain(PyRunnable main, String[] args) throws Exception { ++ runMain(new PyRunnableBootstrap(main), args); ++ } ++ ++ /** ++ * Initializes a default PythonInterpreter and runs the code loaded from the ++ * {@link CodeBootstrap} as __main__ Called by the code generated in ++ * {@link Module#addMain()} ++ */ ++ public static void runMain(CodeBootstrap main, String[] args) ++ throws Exception { + PySystemState.initialize(null, null, args, main.getClass().getClassLoader()); + try { +- imp.createFromCode("__main__", main.getMain()); ++ imp.createFromCode("__main__", CodeLoader.loadCode(main)); + } catch (PyException e) { + Py.getSystemState().callExitFunc(); + if (Py.matchException(e, Py.SystemExit)) { +@@ -1632,6 +1642,8 @@ + public static PyCode compile_flags(mod node, String name, String filename, + boolean linenumbers, boolean printResults, + CompilerFlags cflags) { ++ return CompilerFacade.compile(node, name, filename, linenumbers, printResults, cflags); ++ /* + try { + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + Module.compile(node, ostream, name, filename, linenumbers, printResults, cflags); +@@ -1642,6 +1654,7 @@ + } catch (Throwable t) { + throw ParserFacade.fixParseError(null, t, filename); + } ++ */ + } + + public static PyCode compile_flags(mod node, String filename, +diff --git a/jython/src/org/python/core/PyRunnableBootstrap.java b/jython/src/org/python/core/PyRunnableBootstrap.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/core/PyRunnableBootstrap.java +@@ -0,0 +1,43 @@ ++package org.python.core; ++ ++import java.lang.reflect.Constructor; ++ ++public class PyRunnableBootstrap implements CodeBootstrap { ++ ++ public static final String REFLECTION_METHOD_NAME = "getFilenameConstructorReflectionBootstrap"; ++ private final PyRunnable runnable; ++ ++ PyRunnableBootstrap(PyRunnable runnable) { ++ this.runnable = runnable; ++ } ++ ++ public PyCode loadCode(CodeLoader loader) { ++ return runnable.getMain(); ++ } ++ ++ public static CodeBootstrap getFilenameConstructorReflectionBootstrap( ++ Class<? extends PyRunnable> cls) { ++ final Constructor<? extends PyRunnable> constructor; ++ try { ++ constructor = cls.getConstructor(String.class); ++ } catch (Exception e) { ++ throw new IllegalArgumentException( ++ "PyRunnable class does not specify apropriate constructor.", ++ e); ++ } ++ return new CodeBootstrap() { ++ ++ public PyCode loadCode(CodeLoader loader) { ++ try { ++ return constructor.newInstance(loader.filename).getMain(); ++ } catch (Exception e) { ++ throw new IllegalArgumentException( ++ "PyRunnable class constructor does not support instantiation protocol.", ++ e); ++ } ++ } ++ ++ }; ++ } ++ ++} +diff --git a/jython/src/org/python/core/PythonCodeBundle.java b/jython/src/org/python/core/PythonCodeBundle.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/core/PythonCodeBundle.java +@@ -0,0 +1,13 @@ ++package org.python.core; ++ ++import java.io.OutputStream; ++ ++public interface PythonCodeBundle { ++ ++ PyCode loadCode() throws Exception; ++ ++ void writeTo(OutputStream stream) throws Exception; ++ ++ void saveCode(String directory) throws Exception; ++ ++} +diff --git a/jython/src/org/python/core/PythonCompiler.java b/jython/src/org/python/core/PythonCompiler.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/core/PythonCompiler.java +@@ -0,0 +1,11 @@ ++package org.python.core; ++ ++import org.python.antlr.base.mod; ++ ++public interface PythonCompiler { ++ ++ PythonCodeBundle compile(mod node, String name, String filename, ++ boolean linenumbers, boolean printResults, CompilerFlags cflags) ++ throws Exception; ++ ++} Modified: trunk/sandbox/tobias/.hg/patches/series =================================================================== --- trunk/sandbox/tobias/.hg/patches/series 2009-03-02 03:29:30 UTC (rev 6054) +++ trunk/sandbox/tobias/.hg/patches/series 2009-03-02 15:59:20 UTC (rev 6055) @@ -0,0 +1,2 @@ +types.patch #+trunk #-advanced +decouple.patch #+trunk #-advanced Added: trunk/sandbox/tobias/.hg/patches/types.patch =================================================================== --- trunk/sandbox/tobias/.hg/patches/types.patch (rev 0) +++ trunk/sandbox/tobias/.hg/patches/types.patch 2009-03-02 15:59:20 UTC (rev 6055) @@ -0,0 +1,1546 @@ +diff --git a/jython/Lib/codeop.py b/jython/Lib/codeop.py +--- a/jython/Lib/codeop.py ++++ b/jython/Lib/codeop.py +@@ -57,8 +57,8 @@ + """ + + # import internals, not guaranteed interface +-from org.python.core import Py,CompilerFlags +-from org.python.core.PyTableCode import PyCF_DONT_IMPLY_DEDENT ++from org.python.core import Py,CompilerFlags,CompileMode ++from org.python.core.CompilerFlags import PyCF_DONT_IMPLY_DEDENT + + # public interface + +@@ -84,6 +84,7 @@ + """ + if symbol not in ['single','eval']: + raise ValueError,"symbol arg must be either single or eval" ++ symbol = CompileMode.getMode(symbol) + return Py.compile_command_flags(source,filename,symbol,Py.getCompilerFlags(),0) + + class Compile: +@@ -95,6 +96,7 @@ + self._cflags = CompilerFlags() + + def __call__(self, source, filename, symbol): ++ symbol = CompileMode.getMode(symbol) + return Py.compile_flags(source, filename, symbol, self._cflags) + + class CommandCompiler: +@@ -128,5 +130,6 @@ + """ + if symbol not in ['single','eval']: + raise ValueError,"symbol arg must be either single or eval" ++ symbol = CompileMode.getMode(symbol) + return Py.compile_command_flags(source,filename,symbol,self._cflags,0) + +diff --git a/jython/src/org/python/Version.java b/jython/src/org/python/Version.java +--- a/jython/src/org/python/Version.java ++++ b/jython/src/org/python/Version.java +@@ -3,7 +3,13 @@ + + import java.io.InputStream; + import java.io.IOException; ++import java.util.Arrays; ++import java.util.Collection; ++import java.util.EnumSet; + import java.util.Properties; ++import java.util.Set; ++ ++import org.python.core.CodeFlag; + + /** + * Jython version information. +@@ -36,6 +42,10 @@ + /** Short version of branch, e.g. asm. */ + public static String SHORT_BRANCH; + ++ /** The flags that are set by default in a code object. */ ++ private static final Collection<CodeFlag> defaultCodeFlags = Arrays.asList( ++ CodeFlag.CO_NESTED, CodeFlag.CO_GENERATOR_ALLOWED); ++ + private static final String headURL = + "$HeadURL: https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython/src/org/python/Version.java $"; + +@@ -144,4 +154,8 @@ + public static String getVersion() { + return String.format("%.80s (%.80s) %.80s", PY_VERSION, getBuildInfo(), getVM()); + } ++ ++ public static Set<CodeFlag> getDefaultCodeFlags() { ++ return EnumSet.copyOf(defaultCodeFlags); ++ } + } +diff --git a/jython/src/org/python/antlr/BaseParser.java b/jython/src/org/python/antlr/BaseParser.java +--- a/jython/src/org/python/antlr/BaseParser.java ++++ b/jython/src/org/python/antlr/BaseParser.java +@@ -1,15 +1,31 @@ + package org.python.antlr; + + import org.antlr.runtime.CharStream; ++import org.antlr.runtime.CommonTokenStream; ++import org.antlr.runtime.RecognitionException; + import org.antlr.runtime.Token; ++import org.python.antlr.base.mod; + + public class BaseParser { + +- protected CharStream charStream; +- protected boolean partial; +- protected String filename; +- protected String encoding; ++ protected final CharStream charStream; ++ @Deprecated ++ protected final boolean partial; ++ protected final String filename; ++ protected final String encoding; + protected ErrorHandler errorHandler = new FailFastHandler(); ++ ++ public BaseParser(CharStream stream, String filename, String encoding) { ++ this(stream, filename, encoding, false); ++ } ++ ++ @Deprecated ++ public BaseParser(CharStream stream, String filename, String encoding, boolean partial) { ++ this.charStream = stream; ++ this.filename = filename; ++ this.encoding = encoding; ++ this.partial = partial; ++ } + + public void setAntlrErrorHandler(ErrorHandler eh) { + this.errorHandler = eh; +@@ -25,4 +41,60 @@ + return super.nextToken(); + } + } ++ ++ private CharStream charStream(boolean single) { ++ return charStream; ++ } ++ ++ private PythonParser setupParser(boolean single) { ++ PythonLexer lexer = new PyLexer(this.charStream(single)); ++ lexer.setErrorHandler(errorHandler); ++ CommonTokenStream tokens = new CommonTokenStream(lexer); ++ PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename, single); ++ tokens = new CommonTokenStream(indentedSource); ++ PythonParser parser = new PythonParser(tokens, encoding); ++ parser.setErrorHandler(errorHandler); ++ parser.setTreeAdaptor(new PythonTreeAdaptor()); ++ return parser; ++ } ++ ++ public mod parseExpression() { ++ mod tree = null; ++ PythonParser parser = setupParser(false); ++ try { ++ PythonParser.eval_input_return r = parser.eval_input(); ++ tree = (mod)r.tree; ++ } catch (RecognitionException e) { ++ //XXX: this can't happen. Need to strip the throws from antlr ++ // generated code. ++ } ++ return tree; ++ } ++ ++ public mod parseInteractive() { ++ mod tree = null; ++ PythonParser parser = setupParser(true); ++ try { ++ PythonParser.single_input_return r = parser.single_input(); ++ tree = (mod)r.tree; ++ } catch (RecognitionException e) { ++ //I am only throwing ParseExceptions, but "throws RecognitionException" still gets ++ //into the generated code. ++ System.err.println("FIXME: pretty sure this can't happen -- but needs to be checked"); ++ } ++ return tree; ++ } ++ ++ public mod parseModule() { ++ mod tree = null; ++ PythonParser parser = setupParser(false); ++ try { ++ PythonParser.file_input_return r = parser.file_input(); ++ tree = (mod)r.tree; ++ } catch (RecognitionException e) { ++ //XXX: this can't happen. Need to strip the throws from antlr ++ // generated code. ++ } ++ return tree; ++ } + } +diff --git a/jython/src/org/python/antlr/ExpressionParser.java b/jython/src/org/python/antlr/ExpressionParser.java +deleted file mode 100644 +--- a/jython/src/org/python/antlr/ExpressionParser.java ++++ /dev/null +@@ -1,36 +0,0 @@ +-package org.python.antlr; +- +-import org.antlr.runtime.CharStream; +-import org.antlr.runtime.CommonTokenStream; +-import org.antlr.runtime.RecognitionException; +-import org.python.antlr.base.mod; +- +-public class ExpressionParser extends BaseParser { +- +- public ExpressionParser(CharStream cs, String filename, String encoding) { +- this.charStream = cs; +- this.filename = filename; +- this.encoding = encoding; +- } +- +- public mod parse() { +- mod tree = null; +- PythonLexer lexer = new PyLexer(this.charStream); +- lexer.setErrorHandler(errorHandler); +- CommonTokenStream tokens = new CommonTokenStream(lexer); +- PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename); +- tokens = new CommonTokenStream(indentedSource); +- PythonParser parser = new PythonParser(tokens, encoding); +- parser.setErrorHandler(errorHandler); +- parser.setTreeAdaptor(new PythonTreeAdaptor()); +- +- try { +- PythonParser.eval_input_return r = parser.eval_input(); +- tree = (mod)r.tree; +- } catch (RecognitionException e) { +- //XXX: this can't happen. Need to strip the throws from antlr +- // generated code. +- } +- return tree; +- } +-} +diff --git a/jython/src/org/python/antlr/InteractiveParser.java b/jython/src/org/python/antlr/InteractiveParser.java +deleted file mode 100644 +--- a/jython/src/org/python/antlr/InteractiveParser.java ++++ /dev/null +@@ -1,41 +0,0 @@ +-package org.python.antlr; +- +-import java.io.BufferedReader; +-import java.io.IOException; +- +-import org.antlr.runtime.CommonTokenStream; +-import org.antlr.runtime.RecognitionException; +-import org.python.antlr.base.mod; +- +-public class InteractiveParser extends BaseParser { +- +- private BufferedReader bufreader; +- +- public InteractiveParser(BufferedReader br, String filename, String encoding) { +- this.bufreader = br; +- this.filename = filename; +- this.encoding = encoding; +- } +- +- public mod parse() throws IOException { +- mod tree = null; +- PythonLexer lexer = new PyLexer(new NoCloseReaderStream(bufreader)); +- lexer.setErrorHandler(errorHandler); +- CommonTokenStream tokens = new CommonTokenStream(lexer); +- PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename, true); +- tokens = new CommonTokenStream(indentedSource); +- PythonParser parser = new PythonParser(tokens, encoding); +- parser.setErrorHandler(errorHandler); +- parser.setTreeAdaptor(new PythonTreeAdaptor()); +- +- try { +- PythonParser.single_input_return r = parser.single_input(); +- tree = (mod)r.tree; +- } catch (RecognitionException e) { +- //I am only throwing ParseExceptions, but "throws RecognitionException" still gets +- //into the generated code. +- System.err.println("FIXME: pretty sure this can't happen -- but needs to be checked"); +- } +- return tree; +- } +-} +diff --git a/jython/src/org/python/antlr/ModuleParser.java b/jython/src/org/python/antlr/ModuleParser.java +deleted file mode 100644 +--- a/jython/src/org/python/antlr/ModuleParser.java ++++ /dev/null +@@ -1,39 +0,0 @@ +-package org.python.antlr; +- +-import org.antlr.runtime.CharStream; +-import org.antlr.runtime.CommonTokenStream; +-import org.antlr.runtime.RecognitionException; +-import org.python.antlr.base.mod; +- +-public class ModuleParser extends BaseParser { +- public ModuleParser(CharStream cs, String filename, String encoding) { +- this(cs, filename, encoding, false); +- } +- +- public ModuleParser(CharStream cs, String filename, String encoding, boolean partial) { +- this.charStream = cs; +- this.filename = filename; +- this.encoding = encoding; +- this.partial = partial; +- } +- +- public mod file_input() { +- mod tree = null; +- PythonLexer lexer = new PyLexer(this.charStream); +- lexer.setErrorHandler(errorHandler); +- CommonTokenStream tokens = new CommonTokenStream(lexer); +- PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename); +- tokens = new CommonTokenStream(indentedSource); +- PythonParser parser = new PythonParser(tokens, encoding); +- parser.setErrorHandler(errorHandler); +- parser.setTreeAdaptor(new PythonTreeAdaptor()); +- try { +- PythonParser.file_input_return r = parser.file_input(); +- tree = (mod)r.tree; +- } catch (RecognitionException e) { +- //XXX: this can't happen. Need to strip the throws from antlr +- // generated code. +- } +- return tree; +- } +-} +diff --git a/jython/src/org/python/antlr/ast/AstModule.java b/jython/src/org/python/antlr/ast/AstModule.java +--- a/jython/src/org/python/antlr/ast/AstModule.java ++++ b/jython/src/org/python/antlr/ast/AstModule.java +@@ -8,12 +8,12 @@ + import org.python.antlr.op.*; + import org.python.core.AstList; + import org.python.core.ClassDictInit; ++import org.python.core.CompilerFlags; + import org.python.core.imp; + import org.python.core.Py; + import org.python.core.PyInteger; + import org.python.core.PyObject; + import org.python.core.PyString; +-import org.python.core.PyTableCode; + import org.python.core.PyType; + + import org.python.antlr.AST; +@@ -27,7 +27,7 @@ + dict.__setitem__("__doc__", Py.None); + dict.__setitem__("__name__", new PyString("_ast")); + dict.__setitem__("__version__", new PyString("62047")); +- dict.__setitem__("PyCF_ONLY_AST", new PyInteger(PyTableCode.PyCF_ONLY_AST)); ++ dict.__setitem__("PyCF_ONLY_AST", new PyInteger(CompilerFlags.PyCF_ONLY_AST)); + + dict.__setitem__("astlist", AstList.TYPE); + +diff --git a/jython/src/org/python/compiler/Future.java b/jython/src/org/python/compiler/Future.java +--- a/jython/src/org/python/compiler/Future.java ++++ b/jython/src/org/python/compiler/Future.java +@@ -8,73 +8,65 @@ + import org.python.antlr.ast.Interactive; + import org.python.antlr.ast.Module; + import org.python.antlr.ast.Str; ++import org.python.antlr.ast.alias; + import org.python.antlr.base.mod; + import org.python.antlr.base.stmt; ++import org.python.core.CodeFlag; ++import org.python.core.FutureFeature; ++import org.python.core.Pragma; ++import org.python.core.PragmaReceiver; + ++import java.util.EnumSet; + import java.util.List; ++import java.util.Set; + + public class Future { ++ Set<FutureFeature> featureSet = EnumSet.noneOf(FutureFeature.class); ++ private final PragmaReceiver features = new PragmaReceiver() { + +- private boolean division = false; +- private boolean with_statement = false; +- private boolean absolute_import = false; ++ public void add(Pragma pragma) { ++ if (pragma instanceof FutureFeature) { ++ FutureFeature feature = (FutureFeature) pragma; ++ featureSet.add(feature); ++ } ++ } + +- private static final String FUTURE = "__future__"; ++ }; + + private boolean check(ImportFrom cand) throws Exception { +- if (!cand.getInternalModule().equals(FUTURE)) ++ if (!cand.getInternalModule().equals(FutureFeature.MODULE_NAME)) + return false; +- int n = cand.getInternalNames().size(); +- if (n == 0) { +- throw new ParseException("future statement does not support import *", cand); ++ if (cand.getInternalNames().isEmpty()) { ++ throw new ParseException( ++ "future statement does not support import *", cand); + } +- for (int i = 0; i < n; i++) { +- String feature = cand.getInternalNames().get(i).getInternalName(); +- // *known* features +- if (feature.equals("nested_scopes")) { +- continue; ++ try { ++ for (alias feature : cand.getInternalNames()) { ++ // *known* features ++ FutureFeature.addFeature(feature.getInternalName(), features); + } +- if (feature.equals("division")) { +- division = true; +- continue; +- } +- if (feature.equals("generators")) { +- continue; +- } +- if (feature.equals("with_statement")) { +- with_statement = true; +- continue; +- } +- if (feature.equals("absolute_import")) { +- absolute_import = true; +- continue; +- } +- if (feature.equals("braces")) { +- throw new ParseException("not a chance", cand); +- } +- if (feature.equals("GIL") || feature.equals("global_interpreter_lock")) { +- throw new ParseException("Never going to happen!", cand); +- } +- throw new ParseException("future feature " + feature + " is not defined", cand); ++ } catch (ParseException pe) { ++ throw new ParseException(pe.getMessage(), cand); + } + return true; + } + +- public void preprocessFutures(mod node, +- org.python.core.CompilerFlags cflags) +- throws Exception +- { ++ public void preprocessFutures(mod node, org.python.core.CompilerFlags cflags) ++ throws Exception { + if (cflags != null) { +- division = cflags.division; +- with_statement = cflags.with_statement; +- absolute_import = cflags.absolute_import; ++ if (cflags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) ++ FutureFeature.division.addTo(features); ++ if (cflags.isFlagSet(CodeFlag.CO_FUTURE_WITH_STATEMENT)) ++ FutureFeature.with_statement.addTo(features); ++ if (cflags.isFlagSet(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT)) ++ FutureFeature.absolute_import.addTo(features); + } + int beg = 0; + List<stmt> suite = null; + if (node instanceof Module) { + suite = ((Module) node).getInternalBody(); +- if (suite.size() > 0 && suite.get(0) instanceof Expr && +- ((Expr) suite.get(0)).getInternalValue() instanceof Str) { ++ if (suite.size() > 0 && suite.get(0) instanceof Expr ++ && ((Expr) suite.get(0)).getInternalValue() instanceof Str) { + beg++; + } + } else if (node instanceof Interactive) { +@@ -85,45 +77,36 @@ + + for (int i = beg; i < suite.size(); i++) { + stmt s = suite.get(i); +- if (!(s instanceof ImportFrom)) +- break; ++ if (!(s instanceof ImportFrom)) break; + s.from_future_checked = true; +- if (!check((ImportFrom)s)) +- break; ++ if (!check((ImportFrom) s)) break; + } + + if (cflags != null) { +- cflags.division = cflags.division || division; +- } +- if (cflags != null) { +- cflags.with_statement = cflags.with_statement || with_statement; +- } +- if (cflags != null) { +- cflags.absolute_import = cflags.absolute_import || absolute_import; ++ for (FutureFeature feature : featureSet) { ++ feature.setFlag(cflags); ++ } + } + } + +- + public static void checkFromFuture(ImportFrom node) throws Exception { +- if (node.from_future_checked) +- return; +- if (node.getInternalModule().equals(FUTURE)) { +- throw new ParseException("from __future__ imports must occur " + +- "at the beginning of the file",node); ++ if (node.from_future_checked) return; ++ if (node.getInternalModule().equals(FutureFeature.MODULE_NAME)) { ++ throw new ParseException("from __future__ imports must occur " ++ + "at the beginning of the file", node); + } + node.from_future_checked = true; + } + + public boolean areDivisionOn() { +- return division; ++ return featureSet.contains(FutureFeature.division); + } + + public boolean withStatementSupported() { +- return with_statement; ++ return featureSet.contains(FutureFeature.with_statement); + } + + public boolean isAbsoluteImportOn() { +- return absolute_import; ++ return featureSet.contains(FutureFeature.absolute_import); + } +- + } +diff --git a/jython/src/org/python/compiler/Module.java b/jython/src/org/python/compiler/Module.java +--- a/jython/src/org/python/compiler/Module.java ++++ b/jython/src/org/python/compiler/Module.java +@@ -12,6 +12,7 @@ + + import org.objectweb.asm.Label; + import org.objectweb.asm.Opcodes; ++import org.python.core.CodeFlag; + import org.python.core.CompilerFlags; + import org.python.core.Py; + import org.python.core.PyException; +@@ -500,17 +501,17 @@ + code.jy_npurecell = scope.jy_npurecell; + + if (compiler.optimizeGlobals) { +- code.moreflags |= org.python.core.PyTableCode.CO_OPTIMIZED; ++ code.moreflags |= org.python.core.CodeFlag.CO_OPTIMIZED.flag; + } + if (compiler.my_scope.generator) { +- code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR; ++ code.moreflags |= org.python.core.CodeFlag.CO_GENERATOR.flag; + } + if (cflags != null) { +- if (cflags.generator_allowed) { +- code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR_ALLOWED; ++ if (cflags.isFlagSet(CodeFlag.CO_GENERATOR_ALLOWED)) { ++ code.moreflags |= org.python.core.CodeFlag.CO_GENERATOR_ALLOWED.flag; + } +- if (cflags.division) { +- code.moreflags |= org.python.core.PyTableCode.CO_FUTUREDIVISION; ++ if (cflags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) { ++ code.moreflags |= org.python.core.CodeFlag.CO_FUTURE_DIVISION.flag; + } + } + +diff --git a/jython/src/org/python/compiler/pbc/Bytecode.java b/jython/src/org/python/compiler/pbc/Bytecode.java +--- a/jython/src/org/python/compiler/pbc/Bytecode.java ++++ b/jython/src/org/python/compiler/pbc/Bytecode.java +@@ -14,6 +14,8 @@ + import java.util.List; + import java.util.Map; + import java.util.Set; ++ ++import org.python.core.CodeFlag; + import org.python.core.Py; + import org.python.core.Opcode; + import org.python.core.PyBaseCode; +@@ -25,7 +27,7 @@ + + private int co_argcount = 0; + private int co_stacksize = 0; +- private int co_flags = PyBaseCode.CO_OPTIMIZED | PyBaseCode.CO_NEWLOCALS; // typical usage ++ private int co_flags = CodeFlag.CO_OPTIMIZED.flag | CodeFlag.CO_NEWLOCALS.flag; // typical usage + // co_filename = '<generated code>' + // co_name = '<lambda>' + // co_firstlineno = 0 +@@ -135,7 +137,7 @@ + + public void YIELD_VALUE() { + stackchange(1, 1); +- co_flags |= PyBaseCode.CO_GENERATOR; ++ co_flags |= CodeFlag.CO_GENERATOR.flag; + emit(Opcode.YIELD_VALUE); + } + +diff --git a/jython/src/org/python/core/CodeFlag.java b/jython/src/org/python/core/CodeFlag.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/core/CodeFlag.java +@@ -0,0 +1,106 @@ ++package org.python.core; ++ ++import java.util.Arrays; ++import java.util.Collections; ++import java.util.Iterator; ++ ++/** ++ * Represents flags that can be set on code objects. ++ * ++ * @author Tobias Ivarsson ++ */ ++public enum CodeFlag { ++ /** ++ * Denotes that the code block uses fast locals. ++ */ ++ CO_OPTIMIZED(0x0001), ++ /** ++ * Denotes that a new dictionary should be created for the code block. ++ */ ++ CO_NEWLOCALS(0x0002), ++ /** ++ * The compiled code block has a varargs argument. ++ */ ++ CO_VARARGS(0x0004), ++ /** ++ * The compiled code block has a varkeyword argument. ++ */ ++ CO_VARKEYWORDS(0x0008), ++ /** ++ * The compiled code block is a generator code block. ++ */ ++ CO_GENERATOR(0x0020), ++ /** ++ * Denotes that nested scopes are enabled in the code block. ++ */ ++ CO_NESTED(0x0010), ++ /** ++ * Denotes that generators are enabled in the code block. ++ */ ++ CO_GENERATOR_ALLOWED(0x1000), ++ /** ++ * Standard division of integers returns float, truncating division needs to ++ * be enforced. ++ */ ++ CO_FUTURE_DIVISION(0x2000), ++ /** ++ * Absolute import. ++ */ ++ CO_FUTURE_ABSOLUTE_IMPORT(0x4000), ++ /** ++ * With statement. ++ */ ++ CO_FUTURE_WITH_STATEMENT(0x8000); ++ ++ public final int flag; ++ private static Iterable<CodeFlag> allFlags = Collections.unmodifiableList(Arrays.asList(values())); ++ ++ private CodeFlag(int flag) { ++ this.flag = flag; ++ } ++ ++ public boolean isFlagBitSetIn(int flags) { ++ return (flags & flag) != 0; ++ } ++ ++ static Iterable<CodeFlag> parse(final int flags) { ++ return new Iterable<CodeFlag>() { ++ ++ public Iterator<CodeFlag> iterator() { ++ return new Iterator<CodeFlag>() { ++ Iterator<CodeFlag> all = allFlags.iterator(); ++ CodeFlag next = null; ++ ++ public boolean hasNext() { ++ if (next != null) { ++ return true; ++ } ++ while (all.hasNext()) { ++ CodeFlag flag = all.next(); ++ if (flag.isFlagBitSetIn(flags)) { ++ next = flag; ++ return true; ++ } ++ } ++ return false; ++ } ++ ++ public CodeFlag next() { ++ if (hasNext()) try { ++ return next; ++ } finally { ++ next = null; ++ } ++ throw new IllegalStateException(); ++ } ++ ++ public void remove() { ++ throw new UnsupportedOperationException(); ++ } ++ ++ }; ++ } ++ ++ }; ++ } ++} +diff --git a/jython/src/org/python/core/CompileMode.java b/jython/src/org/python/core/CompileMode.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/core/CompileMode.java +@@ -0,0 +1,33 @@ ++package org.python.core; ++ ++import org.python.antlr.BaseParser; ++import org.python.antlr.base.mod; ++ ++public enum CompileMode { ++ eval { ++ @Override ++ mod dispatch(BaseParser parser) { ++ return parser.parseExpression(); ++ } ++ }, ++ single { ++ @Override ++ mod dispatch(BaseParser parser) { ++ return parser.parseInteractive(); ++ } ++ }, ++ exec { ++ @Override ++ mod dispatch(BaseParser parser) { ++ return parser.parseModule(); ++ } ++ }; ++ abstract mod dispatch(BaseParser parser); ++ ++ public static CompileMode getMode(String mode) { ++ if (!mode.equals("exec") && !mode.equals("eval") && !mode.equals("single")) { ++ throw Py.ValueError("compile() arg 3 must be 'exec' or 'eval' or 'single'"); ++ } ++ return valueOf(mode); ++ } ++} +diff --git a/jython/src/org/python/core/CompilerFlags.java b/jython/src/org/python/core/CompilerFlags.java +--- a/jython/src/org/python/core/CompilerFlags.java ++++ b/jython/src/org/python/core/CompilerFlags.java +@@ -1,46 +1,84 @@ + + package org.python.core; + ++import java.util.Set; ++ ++import org.python.Version; ++ + public class CompilerFlags { +- +- private int co_flags; +- +- public boolean nested_scopes = true; +- public boolean division; +- public boolean generator_allowed = true; +- public boolean with_statement; +- public boolean absolute_import; +- ++ // These flags don't mean anything to the code, only to the compiler ++ public static final int PyCF_SOURCE_IS_UTF8 = 0x0100; ++ public static final int PyCF_DONT_IMPLY_DEDENT = 0x0200; ++ public static final int PyCF_ONLY_AST = 0x0400; + public boolean only_ast; + public boolean dont_imply_dedent; + public boolean source_is_utf8; + + public String encoding; ++ private final Set<CodeFlag> flags = Version.getDefaultCodeFlags(); + + public CompilerFlags() {} + + public CompilerFlags(int co_flags) { +- this.co_flags = co_flags; +- nested_scopes = isEnabled(PyTableCode.CO_NESTED); +- division = isEnabled(PyTableCode.CO_FUTUREDIVISION); +- generator_allowed = isEnabled(PyTableCode.CO_GENERATOR_ALLOWED); +- absolute_import = isEnabled(PyTableCode.CO_FUTURE_ABSOLUTE_IMPORT); +- with_statement = isEnabled(PyTableCode.CO_WITH_STATEMENT); +- only_ast = isEnabled(PyTableCode.PyCF_ONLY_AST); +- dont_imply_dedent = isEnabled(PyTableCode.PyCF_DONT_IMPLY_DEDENT); +- source_is_utf8 = isEnabled(PyTableCode.PyCF_SOURCE_IS_UTF8); ++ for (CodeFlag flag : CodeFlag.parse(co_flags)) { ++ setFlag(flag); ++ } ++ only_ast = isEnabled(co_flags, PyCF_ONLY_AST); ++ dont_imply_dedent = isEnabled(co_flags, PyCF_DONT_IMPLY_DEDENT); ++ source_is_utf8 = isEnabled(co_flags, PyCF_SOURCE_IS_UTF8); + } + +- private boolean isEnabled(int codeConstant) { ++ private boolean isEnabled(int co_flags, int codeConstant) { + return (co_flags & codeConstant) != 0; + } + +- public String toString() { +- return String.format("CompilerFlags[division=%s nested_scopes=%s generators=%s " +- + "with_statement=%s absolute_import=%s only_ast=%s " +- + "dont_imply_dedent=%s source_is_utf8=%s]", division, nested_scopes, +- generator_allowed, with_statement, absolute_import, only_ast, +- dont_imply_dedent, source_is_utf8); ++ public void setFlag(CodeFlag flag) { ++ flags.add(flag); + } + ++ public boolean isFlagSet(CodeFlag flag) { ++ return flags.contains(flag); ++ } ++ ++ public String toString() { ++ return String.format( ++ "CompilerFlags[division=%s nested_scopes=%s generators=%s " ++ + "with_statement=%s absolute_import=%s only_ast=%s " ++ + "dont_imply_dedent=%s source_is_utf8=%s]", ++ isFlagSet(CodeFlag.CO_FUTURE_DIVISION), ++ isFlagSet(CodeFlag.CO_NESTED), ++ isFlagSet(CodeFlag.CO_GENERATOR_ALLOWED), ++ isFlagSet(CodeFlag.CO_FUTURE_WITH_STATEMENT), ++ isFlagSet(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT), ++ only_ast, dont_imply_dedent, source_is_utf8); ++ } ++ ++ public static CompilerFlags getCompilerFlags() { ++ return getCompilerFlags(0, false); ++ } ++ ++ private static final int CO_ALL_FEATURES = CompilerFlags.PyCF_DONT_IMPLY_DEDENT ++ | CompilerFlags.PyCF_ONLY_AST ++ | CompilerFlags.PyCF_SOURCE_IS_UTF8 ++ | CodeFlag.CO_NESTED.flag ++ | CodeFlag.CO_GENERATOR_ALLOWED.flag ++ | CodeFlag.CO_FUTURE_DIVISION.flag ++ | CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT.flag ++ | CodeFlag.CO_FUTURE_WITH_STATEMENT.flag; ++ ++ public static CompilerFlags getCompilerFlags(int flags, boolean dont_inherit) { ++ if ((flags & ~CO_ALL_FEATURES) != 0) { ++ throw Py.ValueError("compile(): unrecognised flags"); ++ } ++ CompilerFlags cflags = null; ++ if (dont_inherit) { ++ cflags = new CompilerFlags(flags); ++ } else { ++ PyFrame frame = Py.getFrame(); ++ if (frame != null && frame.f_code != null) { ++ cflags = new CompilerFlags(frame.f_code.co_flags | flags); ++ } ++ } ++ return cflags; ++ } + } +diff --git a/jython/src/org/python/core/FutureFeature.java b/jython/src/org/python/core/FutureFeature.java +new file mode 100644 +--- /dev/null ++++ b/jython/src/org/python/core/FutureFeature.java +@@ -0,0 +1,101 @@ ++package org.python.core; ++ ++import org.python.antlr.ParseException; ++ ++public enum FutureFeature implements Pragma { ++ /** ++ * Enables nested scopes. ++ */ ++ nested_scopes(CodeFlag.CO_NESTED), ++ /** ++ * Makes integer / integer division return float. ++ */ ++ division(CodeFlag.CO_FUTURE_DIVISION), ++ /** ++ * Enables generators. ++ */ ++ generators(CodeFlag.CO_GENERATOR_ALLOWED), ++ /** ++ * Enables absolute imports. ++ */ ++ absolute_import(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT), ++ /** ++ * Enables the with statement. ++ */ ++ with_statement(CodeFlag.CO_FUTURE_WITH_STATEMENT), ++ /** ++ * Use braces for block delimiters instead of indentation. ++ */ ++ braces { ++ @Override ++ public void addTo(PragmaReceiver features) { ++ throw new ParseException("not a chance"); ++ } ++ }, ++ /** ++ * Enable the Global Interpreter Lock in Jython. ++ */ ++ GIL { ++ @Override ++ public void addTo(PragmaReceiver features) { ++ throw new ParseException("Never going to happen!"); ++ } ++ }, ++ /** ++ * Enable the Global Interpreter Loc... [truncated message content] |
From: <fwi...@us...> - 2009-03-02 03:29:34
|
Revision: 6054 http://jython.svn.sourceforge.net/jython/?rev=6054&view=rev Author: fwierzbicki Date: 2009-03-02 03:29:30 +0000 (Mon, 02 Mar 2009) Log Message: ----------- Merged revisions 5934-5947,5950-5951,5953-5957,5959,5961,5965-5966,5971-5976,5978-5979,5981-5983,5992,6001,6003,6006-6014,6023,6031-6037,6039-6040,6045-6047,6049-6052 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ................ r5934 | fwierzbicki | 2009-01-14 22:36:09 -0500 (Wed, 14 Jan 2009) | 3 lines Change negate so that -0 and -0.0 behave as CPython behaves (no USub node, just negate zero). ................ r5935 | cgroves | 2009-01-16 03:11:48 -0500 (Fri, 16 Jan 2009) | 6 lines underlying_class is the class of instances of this type, so PyJavaType shouldn't store the class it's wrapping in it. Instead, it should use the general javaProxy field on PyObject and leave underlying_class up to its bases. Without this, Python classes can't subclass a Java interface and a Python class subclassing a Java class or interface. ................ r5936 | cgroves | 2009-01-16 04:17:19 -0500 (Fri, 16 Jan 2009) | 4 lines Check for parent beans of the same name to fill in missing getters or setters when adding beans for a type. Fixes bug #1132. Thanks to garyh for tracking it down and supplying a test case. ................ r5937 | zyasoft | 2009-01-17 13:12:57 -0500 (Sat, 17 Jan 2009) | 6 lines Fixes #1227 where for cStringIO.StringIO, orderings of method calls like write-seek-write did not properly work. This also addresses a problem for PyAMF support. Thanks go to Nick Joyce for the patch! ................ r5938 | zyasoft | 2009-01-17 13:31:06 -0500 (Sat, 17 Jan 2009) | 6 lines Fixes #1217 where we report the underlying Java error (java.util.zip.DataFormatException) instead of the standard Python one (zlib.error). This also helps support PyAMF on Jython. Thanks Nick Joyce for the patch. ................ r5939 | cgroves | 2009-01-17 13:42:14 -0500 (Sat, 17 Jan 2009) | 1 line Shoulda gone out with r5607. ................ r5940 | cgroves | 2009-01-17 15:35:09 -0500 (Sat, 17 Jan 2009) | 3 lines Add some tests for overriding attribute lookup and adding mapping methods to wrapped Java types. ................ r5941 | cgroves | 2009-01-17 15:56:28 -0500 (Sat, 17 Jan 2009) | 5 lines Implement Iterable in PyIterator. This means generators are usable in foreach loops. The implementation could be moved up to PyObject, but I feel like implementing the interface says that the object will be iterable, and not all PyObjects provide an __iter__. ................ r5942 | cgroves | 2009-01-17 17:36:27 -0500 (Sat, 17 Jan 2009) | 3 lines Resurrect some PyJavaClass code to fix bug #1235. ................ r5943 | cgroves | 2009-01-17 18:57:54 -0500 (Sat, 17 Jan 2009) | 1 line Match the statuses from CPython ................ r5944 | cgroves | 2009-01-17 19:53:10 -0500 (Sat, 17 Jan 2009) | 1 line ecj likes this, but javac disputes that it's compilable, so go back to the old way ................ r5945 | cgroves | 2009-01-18 05:04:29 -0500 (Sun, 18 Jan 2009) | 7 lines Add an Ant task to compile .py files to $py.class. It runs on Lib as part of developer-build to exercise it a little bit. Also, only rename the xerces parts of org.apache. Otherwise our ant imports get renamed when jarjaring. ................ r5946 | otmarhumbel | 2009-01-18 08:46:12 -0500 (Sun, 18 Jan 2009) | 9 lines enable running jython from a directory with an exclamation mark in it's name due to jdk limitations this is only possible for + jdk 1.6 and higher + directory names not ending with an exclamation mark due to the special treatment of exclamation marks in enabledelayedexpansion, this is currently not possible for jython.bat on windows installer autotests now use an exclamation mark if possible ................ r5947 | otmarhumbel | 2009-01-19 16:43:36 -0500 (Mon, 19 Jan 2009) | 2 lines add xercesImpl as zipfileset to jarjar again: without this, there are no org.python.apache.* packages in jython.jar ................ r5950 | zyasoft | 2009-01-20 13:28:03 -0500 (Tue, 20 Jan 2009) | 4 lines Added os.getcwdu. This fixes #1219 (necessary for Django 1.0.2 support), but not the larger question of better Unicode handling in the os module, specifically around os.path. ................ r5951 | leosoto | 2009-01-20 14:29:17 -0500 (Tue, 20 Jan 2009) | 1 line Use the new getcwdu on POSIXHandler, to avoid unnecesary conversions from unicode to bytestring. Also added getcwdu to os.__all__ ................ r5953 | cgroves | 2009-01-21 15:47:19 -0500 (Wed, 21 Jan 2009) | 1 line Break out the compile method for use in subclasses ................ r5954 | cgroves | 2009-01-21 16:26:50 -0500 (Wed, 21 Jan 2009) | 1 line Turn includeJavaStackInExceptions on by default as it was always done in previous versions. ................ r5955 | cgroves | 2009-01-21 18:32:55 -0500 (Wed, 21 Jan 2009) | 8 lines Add a jython initializer service. If META-INF/services/org.python.core.JythonInitializer is on the classpath, the class named in that file will be instantiated and used in Jython's initialization. This is useful when Jython is initialized by a library outside of your control, but some customization still needs to be done to Jython's environment. I promise not to add a JythonFactory or a JythonFactoryFactory. ................ r5956 | fwierzbicki | 2009-01-21 21:21:08 -0500 (Wed, 21 Jan 2009) | 4 lines Fix for http://bugs.jython.org/issue1239. When jars where added to sys.path, they did not always trigger package caching, leading to unexpected import failures. This is Charlie Grove's fix, which was much better than mine. ................ r5957 | fwierzbicki | 2009-01-21 23:16:47 -0500 (Wed, 21 Jan 2009) | 7 lines Thanks to Marc Downie for this patch that fixes http://bugs.jython.org/issue1230 importing with '*' from java packages does not work with 2.5b1. Also added a test to test_java_integration.py. ................ r5959 | cgroves | 2009-01-22 14:50:18 -0500 (Thu, 22 Jan 2009) | 1 line Expose rich comparision methods on Java classes implementing Comparable ................ r5961 | fwierzbicki | 2009-01-22 20:03:39 -0500 (Thu, 22 Jan 2009) | 3 lines Over-ride pyset in PyTuple so our tuples go back to being immutable. Fixes http://bugs.jython.org/issue1242. ................ r5965 | pjenvey | 2009-01-23 18:40:46 -0500 (Fri, 23 Jan 2009) | 2 lines more java.lang.Strings to regular str instead of unicode ................ r5966 | pjenvey | 2009-01-23 19:17:40 -0500 (Fri, 23 Jan 2009) | 3 lines merge from: http://svn.python.org/projects/python/branches/release25-maint/Lib/platform.py -c 66214 ................ r5971 | cgroves | 2009-01-24 15:10:59 -0500 (Sat, 24 Jan 2009) | 1 line Run the java import * test from a sub-interpreter to allow regrtest to be run with python.cachedir.skip=true ................ r5972 | cgroves | 2009-01-24 15:11:54 -0500 (Sat, 24 Jan 2009) | 1 line Try the current classloader for places where the context classloader isn't set ................ r5973 | cgroves | 2009-01-24 15:17:39 -0500 (Sat, 24 Jan 2009) | 1 line Exclude the xerces service declaration as our jarjar'd version doesn't match the names in the declaration ................ r5974 | cgroves | 2009-01-25 07:15:25 -0500 (Sun, 25 Jan 2009) | 1 line Bring up to the current state of affairs ................ r5975 | cgroves | 2009-01-25 07:19:27 -0500 (Sun, 25 Jan 2009) | 3 lines Use Python's mro to determine an mro for Java classes and interfaces. If the Java class has an mro conflict, resolve it by arbitrarily choosing an interface or class. If an interface or class involved in an mro conflict has had its dict modified, or has its dict modified, raise a TypeError. ................ r5976 | cgroves | 2009-01-25 07:19:58 -0500 (Sun, 25 Jan 2009) | 1 line Test support classes for the last commit ................ r5978 | nriley | 2009-01-25 16:06:04 -0500 (Sun, 25 Jan 2009) | 1 line Typo fix. ................ r5979 | cgroves | 2009-01-25 19:33:21 -0500 (Sun, 25 Jan 2009) | 4 lines Include Python Java subclasses as bases as well as the Java proxy type, as it may have additional methods in its Python. Return the proxyClass directly from getProxyType as we're setting that on Python subclasses now. ................ r5981 | cgroves | 2009-01-25 21:21:05 -0500 (Sun, 25 Jan 2009) | 1 line Defer resolving inner classes till the containing class is fully resolved. Fixes issue #1234. ................ r5982 | cgroves | 2009-01-25 22:10:36 -0500 (Sun, 25 Jan 2009) | 1 line Try to assign to a static field for a given name in __setattr__ on a Java type before filling something in on the dict. Fixes bug #1241 ................ r5983 | cgroves | 2009-01-25 22:36:25 -0500 (Sun, 25 Jan 2009) | 1 line Fix javatests ................ r5992 | amak | 2009-01-28 11:05:59 -0500 (Wed, 28 Jan 2009) | 3 lines Fix and unit test for bug 1244. Problem letting system choose the port for binding UDP socket http://bugs.jython.org/issue1244 ................ r6001 | amak | 2009-01-29 12:59:04 -0500 (Thu, 29 Jan 2009) | 2 lines Re-arranging the socket shutdown methods. TCP client sockets can shutdown their input streams, but this is not appropriate for either TCP server sockets or UDP sockets, which don't have input and output streams. For these latter two types, the shutdown method should have the same effect as the close method, and thus the shutdown method is a no-op for these types. I have documented this difference between cpython and jython on the wiki. This should finally resolve bug 1121: listening socket shutdown expects the wrong kind of socket http://bugs.jython.org/issue1121 ................ r6003 | pjenvey | 2009-01-30 21:20:48 -0500 (Fri, 30 Jan 2009) | 1 line make --version resemble CPython ................ r6006 | amak | 2009-02-02 10:50:25 -0500 (Mon, 02 Feb 2009) | 4 lines Fix for bug 1258. select() semantics differ from CPython, causing pydoc HTTPd to fail http://bugs.jython.org/issue1258 Thanks to Ryan Blair for reporting the bug and providing a patch. ................ r6007 | amak | 2009-02-03 07:01:46 -0500 (Tue, 03 Feb 2009) | 2 lines Committing the latest version of modjy. See the release notes for details. ................ r6008 | pjenvey | 2009-02-03 15:19:57 -0500 (Tue, 03 Feb 2009) | 1 line fix test_version per r6003 ................ r6009 | pjenvey | 2009-02-03 16:25:23 -0500 (Tue, 03 Feb 2009) | 2 lines include PATH for platforms lacking bash in /bin ................ r6010 | leosoto | 2009-02-03 19:51:47 -0500 (Tue, 03 Feb 2009) | 1 line PyObject#reduce_2: Use invoke("iteritems") instead of this.iteritems() to avoid problems with dict subclasses which override iteritems on python code. Fixes #1257 ................ r6011 | amak | 2009-02-04 10:20:56 -0500 (Wed, 04 Feb 2009) | 4 lines Our asyncore is completely broken; see bug 1237. Asnycore does not seem to work in Jython 2.5 (b0 or b1) http://bugs.jython.org/issue1237 Starting again from scratch; Step 1: remove existing module. ................ r6012 | amak | 2009-02-04 10:22:21 -0500 (Wed, 04 Feb 2009) | 1 line Fresh start with asyncore; step 2: copy over asyncore from cpython 2.5.2. ................ r6013 | amak | 2009-02-04 10:27:59 -0500 (Wed, 04 Feb 2009) | 3 lines Fresh start with asycnore; step 3: make necessary changes to cpython 2.5 module to work on jython 2.5. The code in this bug report now works identically to cpython. http://bugs.jython.org/issue1237 ................ r6014 | otmarhumbel | 2009-02-05 13:08:10 -0500 (Thu, 05 Feb 2009) | 1 line added dummy_thread.py and dummy_threading.py ................ r6023 | fwierzbicki | 2009-02-08 20:40:53 -0500 (Sun, 08 Feb 2009) | 2 lines Fix for http://bugs.jython.org/issue1243. Thanks RJ Ryan for suggesting the fix. ................ r6031 | fwierzbicki | 2009-02-15 09:23:28 -0500 (Sun, 15 Feb 2009) | 3 lines Fix potential infinite loop (and wrong slice behavior) -- found with FindBugs ................ r6032 | fwierzbicki | 2009-02-15 13:22:18 -0500 (Sun, 15 Feb 2009) | 2 lines Fixed two infinite recursions found with FindBugs. ................ r6033 | fwierzbicki | 2009-02-15 13:31:27 -0500 (Sun, 15 Feb 2009) | 2 lines Fixed NPE found with FindBugs. ................ r6034 | amak | 2009-02-15 13:35:41 -0500 (Sun, 15 Feb 2009) | 2 lines A new version of modjy, containing some bug fixes kindly contributed by Philip Jenvey; see contained release notes for more information. http://github.com/pjenvey/modjy-pjenvey ................ r6035 | pjenvey | 2009-02-15 18:27:44 -0500 (Sun, 15 Feb 2009) | 3 lines double antlr's conversiontimeout for slower environments, in particular the hudson buildot ................ r6036 | fwierzbicki | 2009-02-16 10:41:50 -0500 (Mon, 16 Feb 2009) | 2 lines Useless double assignment. ................ r6037 | fwierzbicki | 2009-02-16 21:38:09 -0500 (Mon, 16 Feb 2009) | 2 lines Make the public adapters in AstAdapters final. ................ r6039 | amak | 2009-02-18 08:21:13 -0500 (Wed, 18 Feb 2009) | 1 line Updating the zip file for modjy 0.25.3; previously checked in version had the wrong version of modjy.jar in WEB-INF/lib. ................ r6040 | fwierzbicki | 2009-02-19 15:16:18 -0500 (Thu, 19 Feb 2009) | 4 lines Our handling of writes after a seek beyond the end of cStringIO was not consistent with CPython (or even our own use of StringIO). Found while trying to get Mercurial to respond to "hg log". ................ r6045 | zyasoft | 2009-02-24 00:04:05 -0500 (Tue, 24 Feb 2009) | 3 lines Initialized merge tracking via "svnmerge" with revisions "1-5948" from https://jython.svn.sourceforge.net/svnroot/jython/branches/pbcvm ................ r6046 | zyasoft | 2009-02-24 00:45:38 -0500 (Tue, 24 Feb 2009) | 206 lines Merged revisions 5949,5952,5962,5964,5967-5970,5980,5984,5987-5989,5998-5999,6004-6005,6015-6022,6024-6030,6038,6041-6042 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/branches/pbcvm ........ r5949 | zyasoft | 2009-01-20 06:56:46 -0700 (Tue, 20 Jan 2009) | 2 lines Initial commit. ........ r5952 | zyasoft | 2009-01-20 22:02:29 -0700 (Tue, 20 Jan 2009) | 3 lines Fixed binary and inplace bytecodes to use the proper methods. Added block support to support iteration. ........ r5962 | zyasoft | 2009-01-22 21:40:26 -0700 (Thu, 22 Jan 2009) | 3 lines Added support for try/except and try/finally blocks (and their combination). ........ r5964 | zyasoft | 2009-01-23 08:30:09 -0700 (Fri, 23 Jan 2009) | 2 lines Basic generators are almost supported. ........ r5967 | zyasoft | 2009-01-23 19:49:52 -0700 (Fri, 23 Jan 2009) | 2 lines Now supports generators, via the standard PyGenerator protocol. ........ r5968 | zyasoft | 2009-01-23 21:36:06 -0700 (Fri, 23 Jan 2009) | 2 lines Added support for keyword args, *arg, and **kwarg calling conventions. ........ r5969 | zyasoft | 2009-01-24 09:47:59 -0700 (Sat, 24 Jan 2009) | 3 lines Added support for basic coroutines (no support for throw) and generator expressions. ........ r5970 | zyasoft | 2009-01-24 11:02:37 -0700 (Sat, 24 Jan 2009) | 2 lines Supports throwing exceptions into generators. ........ r5980 | zyasoft | 2009-01-25 18:19:12 -0700 (Sun, 25 Jan 2009) | 4 lines Properly handles *args, **kwargs for the receiver function. func_code can now be set to a PyBytecode (or other extender of PyBaseCode). Turned off debugging by default for PyBytecode objects. ........ r5984 | zyasoft | 2009-01-25 22:02:21 -0700 (Sun, 25 Jan 2009) | 2 lines Added extract tool (to be run by CPython) for creating test modules. ........ r5987 | zyasoft | 2009-01-26 18:45:48 -0700 (Mon, 26 Jan 2009) | 2 lines Fixed raising of exceptions and PyStack.rot ........ r5988 | zyasoft | 2009-01-26 19:16:49 -0700 (Mon, 26 Jan 2009) | 2 lines Fixed opcode support for LOAD/STORE/DELETE_NAME and BUILD_CLASS. ........ r5989 | zyasoft | 2009-01-26 19:26:20 -0700 (Mon, 26 Jan 2009) | 2 lines Fixed RAISE_VARARGS opcode to raise exceptions properly. ........ r5998 | zyasoft | 2009-01-28 20:44:58 -0700 (Wed, 28 Jan 2009) | 3 lines extract.py now creates modules where codeobjects respect their dependency relationships (via a tsort). ........ r5999 | zyasoft | 2009-01-29 07:24:33 -0700 (Thu, 29 Jan 2009) | 6 lines Extract script now processes most/all of the test.test_* modules with a test_main and importable by CPython. May want to consider generalizing support for instance methods and closure setup with respect to new.function (= PyFunction), but this seems purely a testing nicety for top-level defs. ........ r6004 | zyasoft | 2009-02-01 01:12:13 -0700 (Sun, 01 Feb 2009) | 3 lines From http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_marshal@27825 ........ r6005 | zyasoft | 2009-02-01 01:24:06 -0700 (Sun, 01 Feb 2009) | 13 lines Added _marshal, a Java implementation of the Python module, and made current. test_marshal now passes (with minor modifications around GC and floating point accuracy on to/from string representation), except for support of code objects. That's next. Pulled IOFile (now PyIOFile) from cPickle to share its duck typing with _marshal A historical note: from what I can discern in the log, the original marshal.py was written by Guido van Rossum specifically for "JPython" in 1997, one of the few bits he apparently did. Now it survives only as a shell, to import in _marshal. ........ r6015 | zyasoft | 2009-02-05 20:50:10 -0700 (Thu, 05 Feb 2009) | 5 lines Changed read/write binary_float so that it doesn't go through struct but instead j.l.Double's support for converting to/from bits. This also resolves endian ordering issues so that it follows the native endian ordering. ........ r6016 | zyasoft | 2009-02-06 00:07:45 -0700 (Fri, 06 Feb 2009) | 7 lines Fixed some cellvar/freevar nested scope issues, with work to continue. Added a slightly modified version of pycimport.py from Tobias' pyasm implementation in the sandbox. This, in conjunction with compileall (run from CPython; compileall.compile_dir against the unit tests) is allowing a significant fraction of the regrtest to run against PBC-VM. ........ r6017 | zyasoft | 2009-02-06 00:42:15 -0700 (Fri, 06 Feb 2009) | 2 lines Fixed slice, exec support. ........ r6018 | zyasoft | 2009-02-06 21:04:54 -0700 (Fri, 06 Feb 2009) | 2 lines Fixed stack ops (DUP_TOPX, ROT_THREE, ROT_FOUR), INPLACE_POWER. ........ r6019 | zyasoft | 2009-02-06 23:29:37 -0700 (Fri, 06 Feb 2009) | 5 lines Fixed IMPORT_STAR for nested modules. sys.exc_info now returns Py.None for the traceback (this fixes an issue in PBC where null is being used as both a sentinel value by __getitem__ AND an actual value for exception handling). ........ r6020 | zyasoft | 2009-02-07 10:47:19 -0700 (Sat, 07 Feb 2009) | 2 lines Fixes nested scope treatment of free variables. ........ r6021 | zyasoft | 2009-02-07 11:14:33 -0700 (Sat, 07 Feb 2009) | 2 lines Further refinement of nested scopes. ........ r6022 | zyasoft | 2009-02-07 14:26:31 -0700 (Sat, 07 Feb 2009) | 3 lines Fixed control flow by pushing the wrapped Why onto the stack (instead of its string representation from the earliest version of this code). ........ r6024 | zyasoft | 2009-02-10 20:11:10 -0700 (Tue, 10 Feb 2009) | 7 lines Support tostring/fromstring of unsigned types so that they can be stored in the same size as their signed representation. This fixes an issues with peak.util.assembler where it expects that unsigned bytes (typecode 'B') take one byte to store and therefore are directly interoperable with co_code. ........ r6025 | zyasoft | 2009-02-11 21:38:04 -0700 (Wed, 11 Feb 2009) | 2 lines Beginning of PBC compilation support. Pretty much a shell for now. ........ r6026 | zyasoft | 2009-02-14 02:23:58 -0700 (Sat, 14 Feb 2009) | 7 lines Now interns names in co_names, etc., when unmarshalling, which fixes equality tests on special case like __class__, __dict__, etc. Fix instanceof test in eval and exec so that it looks at PyBaseCode, not PyTableCode. Also, exec cannot be called with Py.None instead of null. Fixes test_scope. ........ r6027 | zyasoft | 2009-02-14 03:44:17 -0700 (Sat, 14 Feb 2009) | 3 lines Set the traceback when intercepting an exception. Set __doc__ strings for functions from the constant pool (if available). ........ r6028 | zyasoft | 2009-02-14 04:17:17 -0700 (Sat, 14 Feb 2009) | 3 lines LOAD_DEREF needs to do the same lookup as LOAD_CLOSURE. Populate doc strings for MAKE_CLOSURE. ........ r6029 | zyasoft | 2009-02-14 04:58:48 -0700 (Sat, 14 Feb 2009) | 3 lines Fixed WITH_CLEANUP so that it properly calls __exit__ with the exception components off the stack. ........ r6030 | zyasoft | 2009-02-14 12:17:04 -0700 (Sat, 14 Feb 2009) | 3 lines Fixed UNPACK_SEQUENCE so that ValueError is raised if too few/too many values to unpack. ........ r6038 | zyasoft | 2009-02-17 17:06:55 -0700 (Tue, 17 Feb 2009) | 8 lines Added support for code.getlineno (using co_lnotab), co_code, co_consts, co_lnotab. co_code and co_lnotab now use byte[] for a more compact representation and then manage accessing as if it were an unsigned representation. This enables a good chunk of the peak.util.assembler unit tests to pass; the remainder seem to have a dictionary traversal dependency. ........ r6041 | zyasoft | 2009-02-22 07:40:49 -0700 (Sun, 22 Feb 2009) | 4 lines Inlined PyTableCode#interpret into #call(PyFrame,PyClosure) (which restores this method to what it was before the PBC-VM work). This change restores the performance as tested by test/pystone.py. ........ r6042 | zyasoft | 2009-02-23 21:25:13 -0700 (Mon, 23 Feb 2009) | 8 lines LineCache implementation to support efficient setline edge detection, as necessary for tracing. No longer looks up the ThreadState twice, in the caller of PyBytecode#interpret and interpret itself, so this should provide for some optimization. ........ ................ r6047 | fwierzbicki | 2009-02-24 15:42:25 -0500 (Tue, 24 Feb 2009) | 6 lines Added a target and infrastructure for compiling the ctypes_test.c needed for test__rawffi.py. So far only tested on OS X. Used cpptasks from http://ant-contrib.sourceforge.net/cpptasks/index.html ................ r6049 | fwierzbicki | 2009-03-01 15:42:46 -0500 (Sun, 01 Mar 2009) | 3 lines Update to antlr 3.1.2. This required deleting mismatch() override in Python.g and PythonPartial.g. ................ r6050 | fwierzbicki | 2009-03-01 19:59:05 -0500 (Sun, 01 Mar 2009) | 2 lines Bump CPython version to 70085. ................ r6051 | fwierzbicki | 2009-03-01 20:00:34 -0500 (Sun, 01 Mar 2009) | 3 lines from http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_new@52060 ................ r6052 | fwierzbicki | 2009-03-01 20:04:20 -0500 (Sun, 01 Mar 2009) | 2 lines maybe 'never' was too strong for new.code in Jython. Disable test for now. ................ Modified Paths: -------------- trunk/sandbox/wierzbicki/grammar26/CPythonLib.includes trunk/sandbox/wierzbicki/grammar26/Lib/marshal.py trunk/sandbox/wierzbicki/grammar26/Lib/new.py trunk/sandbox/wierzbicki/grammar26/Lib/os.py trunk/sandbox/wierzbicki/grammar26/Lib/platform.py trunk/sandbox/wierzbicki/grammar26/Lib/pydoc.py trunk/sandbox/wierzbicki/grammar26/Lib/socket.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_StringIO_jy.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_array.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_builtin_jy.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_classpathimporter.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_cmd_line.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_import_jy.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_java_integration.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_java_subclasses.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_java_visibility.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_socket.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_tuple.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_zlib.py trunk/sandbox/wierzbicki/grammar26/Lib/threading.py trunk/sandbox/wierzbicki/grammar26/Lib/zlib.py trunk/sandbox/wierzbicki/grammar26/build.xml trunk/sandbox/wierzbicki/grammar26/grammar/Python.g trunk/sandbox/wierzbicki/grammar26/grammar/PythonPartial.g trunk/sandbox/wierzbicki/grammar26/registry trunk/sandbox/wierzbicki/grammar26/src/org/python/antlr/GrammarActions.java trunk/sandbox/wierzbicki/grammar26/src/org/python/antlr/adapter/AstAdapters.java trunk/sandbox/wierzbicki/grammar26/src/org/python/compiler/Future.java trunk/sandbox/wierzbicki/grammar26/src/org/python/compiler/JavaMaker.java trunk/sandbox/wierzbicki/grammar26/src/org/python/compiler/Module.java trunk/sandbox/wierzbicki/grammar26/src/org/python/compiler/ScopesCompiler.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/AstList.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/BytecodeLoader.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/ClasspathPyImporter.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/Options.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/Py.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyArray.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyBuiltinMethodNarrow.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyFrame.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyFunction.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyIterator.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyJavaType.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyList.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyNewWrapper.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyObject.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PySequence.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PySystemState.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyTableCode.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyTuple.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyType.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/SyspathJavaLoader.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/ThreadStateMapping.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/__builtin__.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/codecs.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/imp.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/packagecache/PackageManager.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/packagecache/PathPackageManager.java trunk/sandbox/wierzbicki/grammar26/src/org/python/expose/generate/ExposeTask.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/Setup.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/_csv/PyWriter.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/_py_compile.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/cPickle.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/cStringIO.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/struct.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/thread/PyLocal.java trunk/sandbox/wierzbicki/grammar26/src/org/python/util/Generic.java trunk/sandbox/wierzbicki/grammar26/src/org/python/util/jython.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/expose/generate/TypeExposerTest.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/Coercions.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/Visible.java Added Paths: ----------- trunk/sandbox/wierzbicki/grammar26/Lib/asyncore.py trunk/sandbox/wierzbicki/grammar26/Lib/pycimport.py trunk/sandbox/wierzbicki/grammar26/Lib/test/bug1239.jar trunk/sandbox/wierzbicki/grammar26/Lib/test/check_for_initializer_in_syspath.py trunk/sandbox/wierzbicki/grammar26/Lib/test/import_star_from_java.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_jython_initializer.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_marshal.py trunk/sandbox/wierzbicki/grammar26/Lib/test/test_new.py trunk/sandbox/wierzbicki/grammar26/Tools/pbcvm/ trunk/sandbox/wierzbicki/grammar26/Tools/pbcvm/extract.py trunk/sandbox/wierzbicki/grammar26/extlibs/antlr-3.1.2.jar trunk/sandbox/wierzbicki/grammar26/extlibs/antlr-runtime-3.1.2.jar trunk/sandbox/wierzbicki/grammar26/extlibs/cpptasks/ trunk/sandbox/wierzbicki/grammar26/extlibs/cpptasks/cpptasks.jar trunk/sandbox/wierzbicki/grammar26/extlibs/modjy_0_25_3.zip trunk/sandbox/wierzbicki/grammar26/src/org/python/compiler/pbc/ trunk/sandbox/wierzbicki/grammar26/src/org/python/compiler/pbc/Bytecode.java trunk/sandbox/wierzbicki/grammar26/src/org/python/compiler/pbc/BytecodeCompiler.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/JythonInitializer.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/Opcode.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyBaseCode.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/PyBytecode.java trunk/sandbox/wierzbicki/grammar26/src/org/python/core/WrappedIterIterator.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/PyIOFile.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/PyIOFileFactory.java trunk/sandbox/wierzbicki/grammar26/src/org/python/modules/_marshal.java trunk/sandbox/wierzbicki/grammar26/src/org/python/util/GlobMatchingTask.java trunk/sandbox/wierzbicki/grammar26/src/org/python/util/JycompileAntTask.java trunk/sandbox/wierzbicki/grammar26/tests/data/ trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/ trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/META-INF/ trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/META-INF/services/ trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/SyspathAppendingInitializer.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/Child.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/CustomizableMapHolder.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/Parent.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/inbred/ trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/inbred/Metis.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/inbred/Zeus.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/ trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/ConfusedOnGetitemAdd.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/ConfusedOnImport.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/FirstAndPost.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/FirstAndSecond.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/FirstPredefinedGetitem.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/GetitemAdder.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/PostAndFirst.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/PostdefinedGetitem.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/SecondAndFirst.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/SecondPredefinedGetitem.java Removed Paths: ------------- trunk/sandbox/wierzbicki/grammar26/Lib/asyncore.py trunk/sandbox/wierzbicki/grammar26/Tools/pbcvm/extract.py trunk/sandbox/wierzbicki/grammar26/extlibs/antlr-3.1.1-runtime.jar trunk/sandbox/wierzbicki/grammar26/extlibs/antlr-3.1.1.jar trunk/sandbox/wierzbicki/grammar26/extlibs/cpptasks/cpptasks.jar trunk/sandbox/wierzbicki/grammar26/extlibs/modjy_0_25_1.zip trunk/sandbox/wierzbicki/grammar26/src/org/python/compiler/pbc/Bytecode.java trunk/sandbox/wierzbicki/grammar26/src/org/python/compiler/pbc/BytecodeCompiler.java trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/ trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/META-INF/ trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/META-INF/services/ trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/META-INF/services/org.python.core.JythonInitializer trunk/sandbox/wierzbicki/grammar26/tests/data/initializer/SyspathAppendingInitializer.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/inbred/Metis.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/inbred/Zeus.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/ConfusedOnGetitemAdd.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/ConfusedOnImport.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/FirstAndPost.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/FirstAndSecond.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/FirstPredefinedGetitem.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/GetitemAdder.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/PostAndFirst.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/PostdefinedGetitem.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/SecondAndFirst.java trunk/sandbox/wierzbicki/grammar26/tests/java/org/python/tests/mro/SecondPredefinedGetitem.java Property Changed: ---------------- trunk/sandbox/wierzbicki/grammar26/ Property changes on: trunk/sandbox/wierzbicki/grammar26 ___________________________________________________________________ Modified: svn:externals - CPythonLib -r68460 http://svn.python.org/projects/python/branches/release25-maint/Lib/ + CPythonLib -r70085 http://svn.python.org/projects/python/branches/release25-maint/Lib/ Modified: svnmerge-integrated - /trunk/jython:1-5932 + /trunk/jython:1-6053 Modified: trunk/sandbox/wierzbicki/grammar26/CPythonLib.includes =================================================================== --- trunk/sandbox/wierzbicki/grammar26/CPythonLib.includes 2009-03-02 02:26:09 UTC (rev 6053) +++ trunk/sandbox/wierzbicki/grammar26/CPythonLib.includes 2009-03-02 03:29:30 UTC (rev 6054) @@ -52,6 +52,8 @@ DocXMLRPCServer.py dospath.py dumbdbm.py +dummy_thread.py +dummy_threading.py exceptions.py fileinput.py fnmatch.py Deleted: trunk/sandbox/wierzbicki/grammar26/Lib/asyncore.py =================================================================== --- trunk/sandbox/wierzbicki/grammar26/Lib/asyncore.py 2009-03-02 02:26:09 UTC (rev 6053) +++ trunk/sandbox/wierzbicki/grammar26/Lib/asyncore.py 2009-03-02 03:29:30 UTC (rev 6054) @@ -1,561 +0,0 @@ -# -*- Mode: Python -*- -# Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp -# Author: Sam Rushing <ru...@ni...> - -# ====================================================================== -# Copyright 1996 by Sam Rushing -# -# All Rights Reserved -# -# Permission to use, copy, modify, and distribute this software and -# its documentation for any purpose and without fee is hereby -# granted, provided that the above copyright notice appear in all -# copies and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of Sam -# Rushing not be used in advertising or publicity pertaining to -# distribution of the software without specific, written prior -# permission. -# -# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN -# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR -# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, -# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN -# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# ====================================================================== - -"""Basic infrastructure for asynchronous socket service clients and servers. - -There are only two ways to have a program on a single processor do "more -than one thing at a time". Multi-threaded programming is the simplest and -most popular way to do it, but there is another very different technique, -that lets you have nearly all the advantages of multi-threading, without -actually using multiple threads. it's really only practical if your program -is largely I/O bound. If your program is CPU bound, then pre-emptive -scheduled threads are probably what you really need. Network servers are -rarely CPU-bound, however. - -If your operating system supports the select() system call in its I/O -library (and nearly all do), then you can use it to juggle multiple -communication channels at once; doing other work while your I/O is taking -place in the "background." Although this strategy can seem strange and -complex, especially at first, it is in many ways easier to understand and -control than multi-threaded programming. The module documented here solves -many of the difficult problems for you, making the task of building -sophisticated high-performance network servers and clients a snap. -""" - -import exceptions -import select -import socket -import sys -import time - -import os -from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \ - ENOTCONN, ESHUTDOWN, EINTR, EISCONN - -try: - socket_map -except NameError: - socket_map = {} - -class ExitNow(exceptions.Exception): - pass - -def read(obj): - try: - obj.handle_read_event() - except ExitNow: - raise - except: - obj.handle_error() - -def write(obj): - try: - obj.handle_write_event() - except ExitNow: - raise - except: - obj.handle_error() - -def readwrite(obj, flags): - try: - if flags & select.POLLIN: - obj.handle_read_event() - if flags & select.POLLOUT: - obj.handle_write_event() - except ExitNow: - raise - except: - obj.handle_error() - -def poll(timeout=0.0, map=None): - if map is None: - map = socket_map - if map: - r = []; w = []; e = [] - for fd, obj in map.items(): - if obj.readable(): - r.append(fd) - if obj.writable(): - w.append(fd) - if [] == r == w == e: - time.sleep(timeout) - else: - try: - r, w, e = select.select(r, w, e, timeout) - except select.error, err: - if err[0] != EINTR: - raise - else: - return - - for fd in r: - obj = map.get(fd) - if obj is None: - continue - read(obj) - - for fd in w: - obj = map.get(fd) - if obj is None: - continue - write(obj) - -def poll2(timeout=0.0, map=None): - import poll - if map is None: - map = socket_map - if timeout is not None: - # timeout is in milliseconds - timeout = int(timeout*1000) - if map: - l = [] - for fd, obj in map.items(): - flags = 0 - if obj.readable(): - flags = poll.POLLIN - if obj.writable(): - flags = flags | poll.POLLOUT - if flags: - l.append((fd, flags)) - r = poll.poll(l, timeout) - for fd, flags in r: - obj = map.get(fd) - if obj is None: - continue - readwrite(obj, flags) - -def poll3(timeout=0.0, map=None): - # Use the poll() support added to the select module in Python 2.0 - if map is None: - map = socket_map - if timeout is not None: - # timeout is in milliseconds - timeout = int(timeout*1000) - pollster = select.poll() - if map: - for fd, obj in map.items(): - flags = 0 - if obj.readable(): - flags = select.POLLIN - if obj.writable(): - flags = flags | select.POLLOUT - if flags: - pollster.register(fd, flags) - try: - r = pollster.poll(timeout) - except select.error, err: - if err[0] != EINTR: - raise - r = [] - for fd, flags in r: - obj = map.get(fd) - if obj is None: - continue - readwrite(obj, flags) - -def loop(timeout=30.0, use_poll=0, map=None): - if map is None: - map = socket_map - - if use_poll: - if hasattr(select, 'poll'): - poll_fun = poll3 - else: - poll_fun = poll2 - else: - poll_fun = poll - - while map: - poll_fun(timeout, map) - -class dispatcher: - - debug = 0 - connected = 0 - accepting = 0 - closing = 0 - addr = None - - def __init__(self, sock=None, map=None): - if sock: - self.set_socket(sock, map) - # I think it should inherit this anyway - self.socket.setblocking(0) - self.connected = 1 - # XXX Does the constructor require that the socket passed - # be connected? - try: - self.addr = sock.getpeername() - except socket.error: - # The addr isn't crucial - pass - else: - self.socket = None - - def __repr__(self): - status = [self.__class__.__module__+"."+self.__class__.__name__] - if self.accepting and self.addr: - status.append('listening') - elif self.connected: - status.append('connected') - if self.addr is not None: - try: - status.append('%s:%d' % self.addr) - except TypeError: - status.append(repr(self.addr)) - # On some systems (RH10) id() can be a negative number. - # work around this. - MAX = 2L*sys.maxint+1 - return '<%s at %#x>' % (' '.join(status), id(self)&MAX) - - def add_channel(self, map=None): - #self.log_info('adding channel %s' % self) - if map is None: - if hasattr(self, '_map'): - map = self._map - del self._map - else: - map = socket_map - if not hasattr(self, '_fileno'): - self._fileno = self.socket.fileno() - map[self._fileno] = self - - def del_channel(self, map=None): - fd = self._fileno - if map is None: - map = socket_map - if map.has_key(fd): - #self.log_info('closing channel %d:%s' % (fd, self)) - del map[fd] - - def create_socket(self, family, type): - self.family_and_type = family, type - self.socket = socket.socket(family, type) - self.socket.setblocking(0) - - def set_socket(self, sock, map=None): - self.socket = sock -## self.__dict__['socket'] = sock - if sock.fileno(): - self.add_channel(map) - else: - self._map = map - - def set_reuse_addr(self): - # try to re-use a server port if possible - try: - self.socket.setsockopt( - socket.SOL_SOCKET, socket.SO_REUSEADDR, - self.socket.getsockopt(socket.SOL_SOCKET, - socket.SO_REUSEADDR) | 1 - ) - except socket.error: - pass - - # ================================================== - # predicates for select() - # these are used as filters for the lists of sockets - # to pass to select(). - # ================================================== - - def readable(self): - return True - - if os.name == 'mac': - # The macintosh will select a listening socket for - # write if you let it. What might this mean? - def writable(self): - return not self.accepting - else: - def writable(self): - return True - - # ================================================== - # socket object methods. - # ================================================== - - def listen(self, num): - self.accepting = 1 - if os.name == 'nt' and num > 5: - num = 1 - ret = self.socket.listen(num) - self.add_channel() - return ret - - def bind(self, addr): - self.addr = addr - return self.socket.bind(addr) - - def connect(self, address): - self.connected = 0 - err = self.socket.connect_ex(address) - # XXX Should interpret Winsock return values - if err in (EINPROGRESS, EALREADY, EWOULDBLOCK): - return - if err in (0, EISCONN): - self.add_channel() - self.addr = address - self.connected = 1 - self.handle_connect() - else: - raise socket.error, err - - def accept(self): - # XXX can return either an address pair or None - try: - conn, addr = self.socket.accept() - self.add_channel() - return conn, addr - except socket.error, why: - if why[0] == EWOULDBLOCK: - pass - else: - raise socket.error, why - - def send(self, data): - try: - result = self.socket.send(data) - return result - except socket.error, why: - if why[0] == EWOULDBLOCK: - return 0 - else: - raise socket.error, why - return 0 - - def recv(self, buffer_size): - try: - data = self.socket.recv(buffer_size) - if not data: - # a closed connection is indicated by signaling - # a read condition, and having recv() return 0. - self.handle_close() - return '' - else: - return data - except socket.error, why: - # winsock sometimes throws ENOTCONN - if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]: - self.handle_close() - return '' - else: - raise socket.error, why - - def close(self): - self.del_channel() - self.socket.close() - - # cheap inheritance, used to pass all other attribute - # references to the underlying socket object. - def __getattr__(self, attr): - return getattr(self.socket, attr) - - # log and log_info may be overridden to provide more sophisticated - # logging and warning methods. In general, log is for 'hit' logging - # and 'log_info' is for informational, warning and error logging. - - def log(self, message): - sys.stderr.write('log: %s\n' % str(message)) - - def log_info(self, message, type='info'): - if __debug__ or type != 'info': - print '%s: %s' % (type, message) - - def handle_read_event(self): - if self.accepting: - # for an accepting socket, getting a read implies - # that we are connected - if not self.connected: - self.connected = 1 - self.handle_accept() - elif not self.connected: - self.handle_connect() - self.connected = 1 - self.handle_read() - else: - self.handle_read() - - def handle_write_event(self): - # getting a write implies that we are connected - if not self.connected: - self.handle_connect() - self.connected = 1 - self.handle_write() - - def handle_expt_event(self): - self.handle_expt() - - def handle_error(self): - nil, t, v, tbinfo = compact_traceback() - - # sometimes a user repr method will crash. - try: - self_repr = repr(self) - except: - self_repr = '<__repr__(self) failed for object at %0x>' % id(self) - - self.log_info( - 'uncaptured python exception, closing channel %s (%s:%s %s)' % ( - self_repr, - t, - v, - tbinfo - ), - 'error' - ) - self.close() - - def handle_expt(self): - self.log_info('unhandled exception', 'warning') - - def handle_read(self): - self.log_info('unhandled read event', 'warning') - - def handle_write(self): - self.log_info('unhandled write event', 'warning') - - def handle_connect(self): - self.log_info('unhandled connect event', 'warning') - - def handle_accept(self): - self.log_info('unhandled accept event', 'warning') - - def handle_close(self): - self.log_info('unhandled close event', 'warning') - self.close() - -# --------------------------------------------------------------------------- -# adds simple buffered output capability, useful for simple clients. -# [for more sophisticated usage use asynchat.async_chat] -# --------------------------------------------------------------------------- - -class dispatcher_with_send(dispatcher): - - def __init__(self, sock=None): - dispatcher.__init__(self, sock) - self.out_buffer = '' - - def initiate_send(self): - num_sent = 0 - num_sent = dispatcher.send(self, self.out_buffer[:512]) - self.out_buffer = self.out_buffer[num_sent:] - - def handle_write(self): - self.initiate_send() - - def writable(self): - return (not self.connected) or len(self.out_buffer) - - def send(self, data): - if self.debug: - self.log_info('sending %s' % repr(data)) - self.out_buffer = self.out_buffer + data - self.initiate_send() - -# --------------------------------------------------------------------------- -# used for debugging. -# --------------------------------------------------------------------------- - -def compact_traceback(): - t, v, tb = sys.exc_info() - tbinfo = [] - assert tb # Must have a traceback - while tb: - tbinfo.append(( - tb.tb_frame.f_code.co_filename, - tb.tb_frame.f_code.co_name, - str(tb.tb_lineno) - )) - tb = tb.tb_next - - # just to be safe - del tb - - file, function, line = tbinfo[-1] - info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo]) - return (file, function, line), t, v, info - -def close_all(map=None): - if map is None: - map = socket_map - for x in map.values(): - x.socket.close() - map.clear() - -# Asynchronous File I/O: -# -# After a little research (reading man pages on various unixen, and -# digging through the linux kernel), I've determined that select() -# isn't meant for doing asynchronous file i/o. -# Heartening, though - reading linux/mm/filemap.c shows that linux -# supports asynchronous read-ahead. So _MOST_ of the time, the data -# will be sitting in memory for us already when we go to read it. -# -# What other OS's (besides NT) support async file i/o? [VMS?] -# -# Regardless, this is useful for pipes, and stdin/stdout... - -if os.name == 'posix': - import fcntl - - class file_wrapper: - # here we override just enough to make a file - # look like a socket for the purposes of asyncore. - - def __init__(self, fd): - self.fd = fd - - def recv(self, *args): - return os.read(self.fd, *args) - - def send(self, *args): - return os.write(self.fd, *args) - - read = recv - write = send - - def close(self): - return os.close(self.fd) - - def fileno(self): - return self.fd - - class file_dispatcher(dispatcher): - - def __init__(self, fd): - dispatcher.__init__(self) - self.connected = 1 - # set it to non-blocking mode - flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) - flags = flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) - self.set_file(fd) - - def set_file(self, fd): - self._fileno = fd - self.socket = file_wrapper(fd) - self.add_channel() Copied: trunk/sandbox/wierzbicki/grammar26/Lib/asyncore.py (from rev 6052, trunk/jython/Lib/asyncore.py) =================================================================== --- trunk/sandbox/wierzbicki/grammar26/Lib/asyncore.py (rev 0) +++ trunk/sandbox/wierzbicki/grammar26/Lib/asyncore.py 2009-03-02 03:29:30 UTC (rev 6054) @@ -0,0 +1,551 @@ +# -*- Mode: Python -*- +# Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp +# Author: Sam Rushing <ru...@ni...> + +# ====================================================================== +# Copyright 1996 by Sam Rushing +# +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and +# its documentation for any purpose and without fee is hereby +# granted, provided that the above copyright notice appear in all +# copies and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of Sam +# Rushing not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. +# +# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# ====================================================================== + +"""Basic infrastructure for asynchronous socket service clients and servers. + +There are only two ways to have a program on a single processor do "more +than one thing at a time". Multi-threaded programming is the simplest and +most popular way to do it, but there is another very different technique, +that lets you have nearly all the advantages of multi-threading, without +actually using multiple threads. it's really only practical if your program +is largely I/O bound. If your program is CPU bound, then pre-emptive +scheduled threads are probably what you really need. Network servers are +rarely CPU-bound, however. + +If your operating system supports the select() system call in its I/O +library (and nearly all do), then you can use it to juggle multiple +communication channels at once; doing other work while your I/O is taking +place in the "background." Although this strategy can seem strange and +complex, especially at first, it is in many ways easier to understand and +control than multi-threaded programming. The module documented here solves +many of the difficult problems for you, making the task of building +sophisticated high-performance network servers and clients a snap. +""" + +import select +import socket +import sys +import time + +import os +from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \ + ENOTCONN, ESHUTDOWN, EINTR, EISCONN, errorcode + +try: + socket_map +except NameError: + socket_map = {} + +class ExitNow(Exception): + pass + +def read(obj): + try: + obj.handle_read_event() + except ExitNow: + raise + except: + obj.handle_error() + +def write(obj): + try: + obj.handle_write_event() + except ExitNow: + raise + except: + obj.handle_error() + +def _exception (obj): + try: + obj.handle_expt_event() + except ExitNow: + raise + except: + obj.handle_error() + +def readwrite(obj, flags): + try: + if flags & (select.POLLIN | select.POLLPRI): + obj.handle_read_event() + if flags & select.POLLOUT: + obj.handle_write_event() + if flags & (select.POLLERR | select.POLLHUP | select.POLLNVAL): + obj.handle_expt_event() + except ExitNow: + raise + except: + obj.handle_error() + +def poll(timeout=0.0, map=None): + if map is None: + map = socket_map + if map: + r = []; w = []; e = [] + for fd, obj in map.items(): + is_r = obj.readable() + is_w = obj.writable() + if is_r: + r.append(fd) + if is_w: + w.append(fd) + if is_r or is_w: + e.append(fd) + if [] == r == w == e: + time.sleep(timeout) + else: + try: + r, w, e = select.select(r, w, e, timeout) + except select.error, err: + if err[0] != EINTR: + raise + else: + return + + for fd in r: + obj = map.get(fd) + if obj is None: + continue + read(obj) + + for fd in w: + obj = map.get(fd) + if obj is None: + continue + write(obj) + + for fd in e: + obj = map.get(fd) + if obj is None: + continue + _exception(obj) + +def poll2(timeout=0.0, map=None): + # Use the poll() support added to the select module in Python 2.0 + if map is None: + map = socket_map + if timeout is not None: + # timeout is in milliseconds + timeout = int(timeout*1000) + pollster = select.poll() + if map: + for fd, obj in map.items(): + flags = 0 + if obj.readable(): + flags |= select.POLLIN | select.POLLPRI + if obj.writable(): + flags |= select.POLLOUT + if flags: + # Only check for exceptions if object was either readable + # or writable. + flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL + pollster.register(fd, flags) + try: + r = pollster.poll(timeout) + except select.error, err: + if err[0] != EINTR: + raise + r = [] + for fd, flags in r: + obj = map.get(fd) + if obj is None: + continue + readwrite(obj, flags) + +poll3 = poll2 # Alias for backward compatibility + +def loop(timeout=30.0, use_poll=True, map=None, count=None): + if map is None: + map = socket_map + + if use_poll and hasattr(select, 'poll'): + poll_fun = poll2 + else: + poll_fun = poll + + if count is None: + while map: + ... [truncated message content] |
From: <fwi...@us...> - 2009-03-02 02:26:10
|
Revision: 6053 http://jython.svn.sourceforge.net/jython/?rev=6053&view=rev Author: fwierzbicki Date: 2009-03-02 02:26:09 +0000 (Mon, 02 Mar 2009) Log Message: ----------- copy trunk to test against CPython trunk's Lib Added Paths: ----------- trunk/sandbox/wierzbicki/test27/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-02 01:04:21
|
Revision: 6052 http://jython.svn.sourceforge.net/jython/?rev=6052&view=rev Author: fwierzbicki Date: 2009-03-02 01:04:20 +0000 (Mon, 02 Mar 2009) Log Message: ----------- maybe 'never' was too strong for new.code in Jython. Disable test for now. Modified Paths: -------------- trunk/jython/Lib/test/test_new.py Modified: trunk/jython/Lib/test/test_new.py =================================================================== --- trunk/jython/Lib/test/test_new.py 2009-03-02 01:00:34 UTC (rev 6051) +++ trunk/jython/Lib/test/test_new.py 2009-03-02 01:04:20 UTC (rev 6052) @@ -115,8 +115,7 @@ print 'new.code()' # bogus test of new.code() -# Note: Jython will never have new.code() -if hasattr(new, 'code'): +if hasattr(new, 'code') and not sys.platform.startswith('java'): def f(a): pass c = f.func_code This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-02 01:00:35
|
Revision: 6051 http://jython.svn.sourceforge.net/jython/?rev=6051&view=rev Author: fwierzbicki Date: 2009-03-02 01:00:34 +0000 (Mon, 02 Mar 2009) Log Message: ----------- from http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_new@52060 Added Paths: ----------- trunk/jython/Lib/test/test_new.py Added: trunk/jython/Lib/test/test_new.py =================================================================== --- trunk/jython/Lib/test/test_new.py (rev 0) +++ trunk/jython/Lib/test/test_new.py 2009-03-02 01:00:34 UTC (rev 6051) @@ -0,0 +1,183 @@ +from test.test_support import verbose, verify, TestFailed +import sys +import new + +class Eggs: + def get_yolks(self): + return self.yolks + +print 'new.module()' +m = new.module('Spam') +if verbose: + print m +m.Eggs = Eggs +sys.modules['Spam'] = m +import Spam + +def get_more_yolks(self): + return self.yolks + 3 + +print 'new.classobj()' +C = new.classobj('Spam', (Spam.Eggs,), {'get_more_yolks': get_more_yolks}) +if verbose: + print C +print 'new.instance()' +c = new.instance(C, {'yolks': 3}) +if verbose: + print c +o = new.instance(C) +verify(o.__dict__ == {}, + "new __dict__ should be empty") +del o +o = new.instance(C, None) +verify(o.__dict__ == {}, + "new __dict__ should be empty") +del o + +def break_yolks(self): + self.yolks = self.yolks - 2 +print 'new.instancemethod()' +im = new.instancemethod(break_yolks, c, C) +if verbose: + print im + +verify(c.get_yolks() == 3 and c.get_more_yolks() == 6, + 'Broken call of hand-crafted class instance') +im() +verify(c.get_yolks() == 1 and c.get_more_yolks() == 4, + 'Broken call of hand-crafted instance method') + +im = new.instancemethod(break_yolks, c) +im() +verify(c.get_yolks() == -1) +try: + new.instancemethod(break_yolks, None) +except TypeError: + pass +else: + raise TestFailed, "dangerous instance method creation allowed" + +# Verify that instancemethod() doesn't allow keyword args +try: + new.instancemethod(break_yolks, c, kw=1) +except TypeError: + pass +else: + raise TestFailed, "instancemethod shouldn't accept keyword args" + +# It's unclear what the semantics should be for a code object compiled at +# module scope, but bound and run in a function. In CPython, `c' is global +# (by accident?) while in Jython, `c' is local. The intent of the test +# clearly is to make `c' global, so let's be explicit about it. +codestr = ''' +global c +a = 1 +b = 2 +c = a + b +''' + +ccode = compile(codestr, '<string>', 'exec') +# Jython doesn't have a __builtins__, so use a portable alternative +import __builtin__ +g = {'c': 0, '__builtins__': __builtin__} +# this test could be more robust +print 'new.function()' +func = new.function(ccode, g) +if verbose: + print func +func() +verify(g['c'] == 3, + 'Could not create a proper function object') + +# test the various extended flavors of function.new +def f(x): + def g(y): + return x + y + return g +g = f(4) +new.function(f.func_code, {}, "blah") +g2 = new.function(g.func_code, {}, "blah", (2,), g.func_closure) +verify(g2() == 6) +g3 = new.function(g.func_code, {}, "blah", None, g.func_closure) +verify(g3(5) == 9) +def test_closure(func, closure, exc): + try: + new.function(func.func_code, {}, "", None, closure) + except exc: + pass + else: + print "corrupt closure accepted" + +test_closure(g, None, TypeError) # invalid closure +test_closure(g, (1,), TypeError) # non-cell in closure +test_closure(g, (1, 1), ValueError) # closure is wrong size +test_closure(f, g.func_closure, ValueError) # no closure needed + +print 'new.code()' +# bogus test of new.code() +# Note: Jython will never have new.code() +if hasattr(new, 'code'): + def f(a): pass + + c = f.func_code + argcount = c.co_argcount + nlocals = c.co_nlocals + stacksize = c.co_stacksize + flags = c.co_flags + codestring = c.co_code + constants = c.co_consts + names = c.co_names + varnames = c.co_varnames + filename = c.co_filename + name = c.co_name + firstlineno = c.co_firstlineno + lnotab = c.co_lnotab + freevars = c.co_freevars + cellvars = c.co_cellvars + + d = new.code(argcount, nlocals, stacksize, flags, codestring, + constants, names, varnames, filename, name, + firstlineno, lnotab, freevars, cellvars) + + # test backwards-compatibility version with no freevars or cellvars + d = new.code(argcount, nlocals, stacksize, flags, codestring, + constants, names, varnames, filename, name, + firstlineno, lnotab) + + try: # this used to trigger a SystemError + d = new.code(-argcount, nlocals, stacksize, flags, codestring, + constants, names, varnames, filename, name, + firstlineno, lnotab) + except ValueError: + pass + else: + raise TestFailed, "negative co_argcount didn't trigger an exception" + + try: # this used to trigger a SystemError + d = new.code(argcount, -nlocals, stacksize, flags, codestring, + constants, names, varnames, filename, name, + firstlineno, lnotab) + except ValueError: + pass + else: + raise TestFailed, "negative co_nlocals didn't trigger an exception" + + try: # this used to trigger a Py_FatalError! + d = new.code(argcount, nlocals, stacksize, flags, codestring, + constants, (5,), varnames, filename, name, + firstlineno, lnotab) + except TypeError: + pass + else: + raise TestFailed, "non-string co_name didn't trigger an exception" + + # new.code used to be a way to mutate a tuple... + class S(str): pass + t = (S("ab"),) + d = new.code(argcount, nlocals, stacksize, flags, codestring, + constants, t, varnames, filename, name, + firstlineno, lnotab) + verify(type(t[0]) is S, "eek, tuple changed under us!") + + if verbose: + print d This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-02 00:59:07
|
Revision: 6050 http://jython.svn.sourceforge.net/jython/?rev=6050&view=rev Author: fwierzbicki Date: 2009-03-02 00:59:05 +0000 (Mon, 02 Mar 2009) Log Message: ----------- Bump CPython version to 70085. Property Changed: ---------------- trunk/jython/ Property changes on: trunk/jython ___________________________________________________________________ Modified: svn:externals - CPythonLib -r68460 http://svn.python.org/projects/python/branches/release25-maint/Lib/ + CPythonLib -r70085 http://svn.python.org/projects/python/branches/release25-maint/Lib/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-01 20:42:55
|
Revision: 6049 http://jython.svn.sourceforge.net/jython/?rev=6049&view=rev Author: fwierzbicki Date: 2009-03-01 20:42:46 +0000 (Sun, 01 Mar 2009) Log Message: ----------- Update to antlr 3.1.2. This required deleting mismatch() override in Python.g and PythonPartial.g. Modified Paths: -------------- trunk/jython/build.xml trunk/jython/grammar/Python.g trunk/jython/grammar/PythonPartial.g Added Paths: ----------- trunk/jython/extlibs/antlr-3.1.2.jar trunk/jython/extlibs/antlr-runtime-3.1.2.jar Removed Paths: ------------- trunk/jython/extlibs/antlr-3.1.1-runtime.jar trunk/jython/extlibs/antlr-3.1.1.jar Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-02-24 22:39:22 UTC (rev 6048) +++ trunk/jython/build.xml 2009-03-01 20:42:46 UTC (rev 6049) @@ -151,7 +151,7 @@ <pathelement path="${extlibs.dir}/mysql-connector-java-5.1.6.jar" /> <pathelement path="${extlibs.dir}/postgresql-8.3-603.jdbc4.jar" /> <pathelement path="${extlibs.dir}/antlr-2.7.7.jar" /> - <pathelement path="${extlibs.dir}/antlr-3.1.1.jar" /> + <pathelement path="${extlibs.dir}/antlr-3.1.2.jar" /> <pathelement path="${extlibs.dir}/stringtemplate-3.2.jar" /> <pathelement path="${extlibs.dir}/asm-3.1.jar" /> @@ -539,7 +539,7 @@ <taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="extlibs/jarjar-0.7.jar"/> <jarjar destfile="${dist.dir}/${jython.deploy.jar}"> <zipfileset src="${dist.dir}/${jython.dev.jar}"/> - <zipfileset src="extlibs/antlr-3.1.1-runtime.jar"/> + <zipfileset src="extlibs/antlr-3.1.2-runtime.jar"/> <rule pattern="org.antlr.runtime.**" result="org.python.antlr.runtime.@1"/> <zipfileset src="extlibs/asm-3.1.jar"/> <zipfileset src="extlibs/asm-commons-3.1.jar"/> Deleted: trunk/jython/extlibs/antlr-3.1.1-runtime.jar =================================================================== (Binary files differ) Deleted: trunk/jython/extlibs/antlr-3.1.1.jar =================================================================== (Binary files differ) Added: trunk/jython/extlibs/antlr-3.1.2.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/antlr-3.1.2.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/antlr-runtime-3.1.2.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/antlr-runtime-3.1.2.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/jython/grammar/Python.g =================================================================== --- trunk/jython/grammar/Python.g 2009-02-24 22:39:22 UTC (rev 6048) +++ trunk/jython/grammar/Python.g 2009-03-01 20:42:46 UTC (rev 6049) @@ -170,12 +170,6 @@ actions.setErrorHandler(eh); } - protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException { - if (errorHandler.mismatch(this, input, ttype, follow)) { - super.mismatch(input, ttype, follow); - } - } - protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException { Modified: trunk/jython/grammar/PythonPartial.g =================================================================== --- trunk/jython/grammar/PythonPartial.g 2009-02-24 22:39:22 UTC (rev 6048) +++ trunk/jython/grammar/PythonPartial.g 2009-03-01 20:42:46 UTC (rev 6049) @@ -75,12 +75,6 @@ @members { private ErrorHandler errorHandler = new FailFastHandler(); - protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException { - if (errorHandler.mismatch(this, input, ttype, follow)) { - super.mismatch(input, ttype, follow); - } - } - protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-02-24 23:08:34
|
Revision: 6048 http://jython.svn.sourceforge.net/jython/?rev=6048&view=rev Author: thobes Date: 2009-02-24 22:39:22 +0000 (Tue, 24 Feb 2009) Log Message: ----------- Setting up a sandbox for easier maintanance of the "advanced" compiler. See README.txt for more information. Added Paths: ----------- trunk/sandbox/tobias/ trunk/sandbox/tobias/.hg/ trunk/sandbox/tobias/.hg/patches/ trunk/sandbox/tobias/.hg/patches/series trunk/sandbox/tobias/.hg/requires trunk/sandbox/tobias/.hg/store/ trunk/sandbox/tobias/.hgignore trunk/sandbox/tobias/README.txt trunk/sandbox/tobias/compiler/ Property changes on: trunk/sandbox/tobias ___________________________________________________________________ Added: svn:externals + jython https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython Property changes on: trunk/sandbox/tobias/.hg ___________________________________________________________________ Added: svn:ignore + * Property changes on: trunk/sandbox/tobias/.hg/patches ___________________________________________________________________ Added: svn:ignore + status Added: trunk/sandbox/tobias/.hg/requires =================================================================== --- trunk/sandbox/tobias/.hg/requires (rev 0) +++ trunk/sandbox/tobias/.hg/requires 2009-02-24 22:39:22 UTC (rev 6048) @@ -0,0 +1,3 @@ +revlogv1 +store +fncache Property changes on: trunk/sandbox/tobias/.hg/store ___________________________________________________________________ Added: svn:ignore + * Added: trunk/sandbox/tobias/.hgignore =================================================================== --- trunk/sandbox/tobias/.hgignore (rev 0) +++ trunk/sandbox/tobias/.hgignore 2009-02-24 22:39:22 UTC (rev 6048) @@ -0,0 +1,4 @@ +\.svn/ +\.hgignore$ +README.txt$ +compiler Added: trunk/sandbox/tobias/README.txt =================================================================== --- trunk/sandbox/tobias/README.txt (rev 0) +++ trunk/sandbox/tobias/README.txt 2009-02-24 22:39:22 UTC (rev 6048) @@ -0,0 +1,21 @@ +This sandbox contains Tobias projects. Most notably the "advanced" compiler. + +Here double version control systems are used. Subversion is used at the base. +All sub projects are managed in subversion. The main Jython code is linked +using svn:externals. +Mercurial is used for managing patches on the main Jython code. +For this to work a few things needs to be maintained: + * The .hgignore file should contain all subprojects. Only linked code should + be visible to mercurial. + * Subversion is set to ignore everything in the .hg directory except for the + patches directory where Mercurial Patch Queues on the main Jython code goes. + * When starting a new working copy all the files needs to be added to hg, + this is because the entire hg repository is NOT stored in subversion, + only the patches. + +Hopefully this setup will decrease the overhead of branch management. This by +eliminating the need for merges from trunk, since there is no branch. And +making merge back a simple commit (with patches applied). + +Further information about each sub project can be found in the README files +in the directory for each sub project respectively. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-02-24 20:42:30
|
Revision: 6047 http://jython.svn.sourceforge.net/jython/?rev=6047&view=rev Author: fwierzbicki Date: 2009-02-24 20:42:25 +0000 (Tue, 24 Feb 2009) Log Message: ----------- Added a target and infrastructure for compiling the ctypes_test.c needed for test__rawffi.py. So far only tested on OS X. Used cpptasks from http://ant-contrib.sourceforge.net/cpptasks/index.html Modified Paths: -------------- trunk/jython/build.xml Added Paths: ----------- trunk/jython/extlibs/cpptasks/ trunk/jython/extlibs/cpptasks/cpptasks.jar Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-02-24 05:45:38 UTC (rev 6046) +++ trunk/jython/build.xml 2009-02-24 20:42:25 UTC (rev 6047) @@ -168,6 +168,7 @@ <pathelement path="${extlibs.dir}/junit-3.8.2.jar" /> <pathelement path="${exposed.dir}" /> <pathelement path="${compile.dir}" /> + <pathelement path="${cpptasks.jar.dir}" /> </path> <!-- 64 bit Java 6 needs roughly 96m for regrtest on most platforms, but Apple's needs more --> @@ -215,6 +216,7 @@ <property file="${basedir}/ant.properties" /> <property name="svnant.jar.dir" value="${basedir}/extlibs/svnant-jars" /> + <property name="cpptasks.jar.dir" value="${basedir}/extlibs/cpptasks/cpptasks.jar" /> <!-- use this property to distinguish a full-build from a developer-build --> <property name="full-build" value="true" /> @@ -493,8 +495,6 @@ nowarn="${nowarn}"> <classpath refid="test.classpath" /> </javac> - - <copy file="${source.dir}/org/python/modules/ucnhash.dat" todir="${compile.dir}/org/python/modules" preservelastmodified="true" /> @@ -506,6 +506,23 @@ </copy> </target> + <!-- + If you run this before running regrtest, test__rawffi.py should pass. + So far I have been unable to enable cpptasks without passing an arg to ant. + To run this task like I am do: + + ant -lib extlibs/cpptasks/cpptasks.jar compile_cpp + + XXX: get cpptasks running without an arg to ant. + --> + <target name="compile_cpp" depends="compile"> + <taskdef resource="cpptasks.tasks"/> + <cc outtype="shared" subsystem="console" outfile="ctypes_test" objdir="${compile.dir}"> + <fileset dir="tests/c" includes="*.c"/> + </cc> + </target> + + <target name="expose" depends="init"> <taskdef name="expose" classname="org.python.expose.generate.ExposeTask"> <classpath> Added: trunk/jython/extlibs/cpptasks/cpptasks.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/cpptasks/cpptasks.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |