From: <am...@us...> - 2009-10-06 12:27:59
|
Revision: 6840 http://jython.svn.sourceforge.net/jython/?rev=6840&view=rev Author: amak Date: 2009-10-06 12:27:51 +0000 (Tue, 06 Oct 2009) Log Message: ----------- Adding proper interpreter shutdown on servlet.destroy() for modjy. Fixes: http://bugs.jython.org/issue1474 Thanks to Colin Evans for reporting the issue. Modified Paths: -------------- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java Added Paths: ----------- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java trunk/jython/tests/modjy/test_apps_dir/lifecycle_tests.py Modified: trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java =================================================================== --- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-10-04 23:25:51 UTC (rev 6839) +++ trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-10-06 12:27:51 UTC (rev 6840) @@ -127,6 +127,15 @@ } /** + * Close down the modjy servlet. + * + */ + @Override + public void destroy( ) { + interp.cleanup(); + } + + /** * 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 * Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-10-04 23:25:51 UTC (rev 6839) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-10-06 12:27:51 UTC (rev 6840) @@ -194,7 +194,7 @@ super.setUp(); String jythonHome = System.getProperty("JYTHON_HOME"); setRealPath(jythonHome, jythonHome); - setRealPath("/WEB-INF/" + LIB_PYTHON_DIR, LIB_PYTHON_TEST_PATH); + setRealPath("/WEB-INF/" + LIB_PYTHON_DIR, LIB_PYTHON_TEST_PATH); setRealPath("/WEB-INF/lib/modjy.jar", "../modjy.jar"); setPythonHome(jythonHome); setAppDir(DEFAULT_APP_DIR); @@ -238,6 +238,7 @@ suite.addTestSuite(ModjyTestHeaders.class); suite.addTestSuite(ModjyTestContentHeaders.class); suite.addTestSuite(ModjyTestReturnIterable.class); + suite.addTestSuite(ModjyTestServletLifecycle.class); suite.addTestSuite(ModjyTestWebInf.class); suite.addTestSuite(ModjyTestWSGIStreams.class); suite.addTestSuite(PyServletTest.class); Added: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java (rev 0) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java 2009-10-06 12:27:51 UTC (rev 6840) @@ -0,0 +1,42 @@ +/*### +# +# 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 javax.servlet.http.HttpServlet; + +public class ModjyTestServletLifecycle extends ModjyTestBase { + + protected void lifecycleTestSetUp() throws Exception { + baseSetUp(); + setAppFile("lifecycle_tests.py"); + } + + public void testAtExitHandlersCalled() throws Exception { + System.setProperty("modjy", "here"); + lifecycleTestSetUp(); + createServlet(); + doGet(); + HttpServlet modjyServlet = getServlet(); + modjyServlet.destroy(); + assertEquals("gone", System.getProperty("modjy")); + } + +} Added: trunk/jython/tests/modjy/test_apps_dir/lifecycle_tests.py =================================================================== --- trunk/jython/tests/modjy/test_apps_dir/lifecycle_tests.py (rev 0) +++ trunk/jython/tests/modjy/test_apps_dir/lifecycle_tests.py 2009-10-06 12:27:51 UTC (rev 6840) @@ -0,0 +1,34 @@ +# -*- coding: windows-1252 -*- + +### +# +# 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 atexit + +def exit_func(): + import java + java.lang.System.setProperty("modjy", "gone") + +atexit.register(exit_func) + +def lifecycle_test(environ, start_response): + writer = start_response("200 OK", []) + writer("Hello World!") + return [] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-10-06 13:11:16
|
Revision: 6842 http://jython.svn.sourceforge.net/jython/?rev=6842&view=rev Author: amak Date: 2009-10-06 13:11:06 +0000 (Tue, 06 Oct 2009) Log Message: ----------- Tabs to spaces, DOS line-endings to unix. Modified Paths: -------------- trunk/jython/Lib/modjy/__init__.py trunk/jython/Lib/modjy/modjy.py trunk/jython/Lib/modjy/modjy_exceptions.py trunk/jython/Lib/modjy/modjy_impl.py trunk/jython/Lib/modjy/modjy_log.py trunk/jython/Lib/modjy/modjy_params.py trunk/jython/Lib/modjy/modjy_publish.py trunk/jython/Lib/modjy/modjy_response.py trunk/jython/Lib/modjy/modjy_write.py trunk/jython/Lib/modjy/modjy_wsgi.py trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestContentHeaders.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java trunk/jython/tests/modjy/test_apps_dir/content_header_tests.py trunk/jython/tests/modjy/test_apps_dir/environ_tests.py trunk/jython/tests/modjy/test_apps_dir/header_tests.py trunk/jython/tests/modjy/test_apps_dir/lifecycle_tests.py trunk/jython/tests/modjy/test_apps_dir/return_tests.py trunk/jython/tests/modjy/test_apps_dir/simple_app.py trunk/jython/tests/modjy/test_apps_dir/stream_tests.py trunk/jython/tests/modjy/test_apps_dir/web_inf_tests.py Modified: trunk/jython/Lib/modjy/__init__.py =================================================================== --- trunk/jython/Lib/modjy/__init__.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/__init__.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,22 +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',] - +### +# +# 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',] + Modified: trunk/jython/Lib/modjy/modjy.py =================================================================== --- trunk/jython/Lib/modjy/modjy.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/modjy.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,121 +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) +### +# +# 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) Modified: trunk/jython/Lib/modjy/modjy_exceptions.py =================================================================== --- trunk/jython/Lib/modjy/modjy_exceptions.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/modjy_exceptions.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,91 +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] +### +# +# 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] Modified: trunk/jython/Lib/modjy/modjy_impl.py =================================================================== --- trunk/jython/Lib/modjy/modjy_impl.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/modjy_impl.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,101 +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']) +### +# +# 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']) Modified: trunk/jython/Lib/modjy/modjy_log.py =================================================================== --- trunk/jython/Lib/modjy/modjy_log.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/modjy_log.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,80 +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) +### +# +# 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) Modified: trunk/jython/Lib/modjy/modjy_params.py =================================================================== --- trunk/jython/Lib/modjy/modjy_params.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/modjy_params.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,84 +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) +### +# +# 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) Modified: trunk/jython/Lib/modjy/modjy_publish.py =================================================================== --- trunk/jython/Lib/modjy/modjy_publish.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/modjy_publish.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,138 +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)) ) - +### +# +# 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)) ) + Modified: trunk/jython/Lib/modjy/modjy_response.py =================================================================== --- trunk/jython/Lib/modjy/modjy_response.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/modjy_response.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,113 +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 +### +# +# 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 Modified: trunk/jython/Lib/modjy/modjy_write.py =================================================================== --- trunk/jython/Lib/modjy/modjy_write.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/modjy_write.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,43 +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) +### +# +# 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) Modified: trunk/jython/Lib/modjy/modjy_wsgi.py =================================================================== --- trunk/jython/Lib/modjy/modjy_wsgi.py 2009-10-06 12:38:52 UTC (rev 6841) +++ trunk/jython/Lib/modjy/modjy_wsgi.py 2009-10-06 13:11:06 UTC (rev 6842) @@ -1,156 +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/LICENS... [truncated message content] |
From: <pj...@us...> - 2009-10-10 05:44:34
|
Revision: 6851 http://jython.svn.sourceforge.net/jython/?rev=6851&view=rev Author: pjenvey Date: 2009-10-10 05:44:16 +0000 (Sat, 10 Oct 2009) Log Message: ----------- after a SystemRestart don't reset PySystemState until after the exitfuncs are called, otherwise some strange problems can occur Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/util/jython.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-10-09 18:32:33 UTC (rev 6850) +++ trunk/jython/NEWS 2009-10-10 05:44:16 UTC (rev 6851) @@ -3,6 +3,8 @@ Jython 2.5.2a1 Bugs Fixed - [ 1478 ] defaultdict & weakref.WeakKeyDictionary [TypeError: first argument must be callable] + - Fix runtime issues during exitfuncs triggered via SystemRestart (such as + during Django or Pylons development mode reloading) Jython 2.5.1rc3 Bugs Fixed Modified: trunk/jython/src/org/python/util/jython.java =================================================================== --- trunk/jython/src/org/python/util/jython.java 2009-10-09 18:32:33 UTC (rev 6850) +++ trunk/jython/src/org/python/util/jython.java 2009-10-10 05:44:16 UTC (rev 6851) @@ -254,9 +254,11 @@ // Shutdown this instance... shouldRestart = true; shutdownInterpreter(); + interp.cleanup(); // ..reset the state... Py.setSystemState(new PySystemState()); // ...and start again + return; } else { Py.printException(t); if (!opts.interactive) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-14 03:19:45
|
Revision: 6855 http://jython.svn.sourceforge.net/jython/?rev=6855&view=rev Author: pjenvey Date: 2009-10-14 03:19:24 +0000 (Wed, 14 Oct 2009) Log Message: ----------- add support for specifying docstrings in ExposedType/ExposedGet annotations. exposed type.__doc__, which for the most part removes the need for PyObject.getDoc Modified Paths: -------------- trunk/jython/src/org/python/core/PyBuiltinCallable.java trunk/jython/src/org/python/core/PyDataDescr.java trunk/jython/src/org/python/core/PyFunction.java trunk/jython/src/org/python/core/PyMethod.java trunk/jython/src/org/python/core/PyMethodDescr.java trunk/jython/src/org/python/core/PyModule.java trunk/jython/src/org/python/core/PyObject.java trunk/jython/src/org/python/core/PyReflectedFunction.java trunk/jython/src/org/python/core/PyType.java trunk/jython/src/org/python/expose/BaseTypeBuilder.java trunk/jython/src/org/python/expose/ExposedGet.java trunk/jython/src/org/python/expose/ExposedType.java trunk/jython/src/org/python/expose/TypeBuilder.java trunk/jython/src/org/python/expose/generate/DescriptorExposer.java trunk/jython/src/org/python/expose/generate/DescriptorVisitor.java trunk/jython/src/org/python/expose/generate/ExposedFieldFinder.java trunk/jython/src/org/python/expose/generate/ExposedMethodFinder.java trunk/jython/src/org/python/expose/generate/ExposedTypeProcessor.java trunk/jython/src/org/python/expose/generate/ExposedTypeVisitor.java trunk/jython/src/org/python/expose/generate/TypeExposer.java trunk/jython/tests/java/org/python/expose/generate/ExposeMethodFinderTest.java trunk/jython/tests/java/org/python/expose/generate/ExposedTypeProcessorTest.java trunk/jython/tests/java/org/python/expose/generate/ExposedTypeVisitorTest.java trunk/jython/tests/java/org/python/expose/generate/SimpleExposed.java trunk/jython/tests/java/org/python/expose/generate/TypeExposerTest.java Modified: trunk/jython/src/org/python/core/PyBuiltinCallable.java =================================================================== --- trunk/jython/src/org/python/core/PyBuiltinCallable.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/core/PyBuiltinCallable.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -30,7 +30,7 @@ } @ExposedGet(name = "__doc__") - public String fastGetDoc() { + public String getDoc() { return doc; } Modified: trunk/jython/src/org/python/core/PyDataDescr.java =================================================================== --- trunk/jython/src/org/python/core/PyDataDescr.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/core/PyDataDescr.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -17,6 +17,8 @@ protected Class ofType; + private String doc; + /** * @param onType - * the type the descriptor belongs to @@ -25,8 +27,8 @@ * @param ofType - * the type returned by the descriptor */ - public PyDataDescr(PyType onType, String name, Class ofType) { - this(name, ofType); + public PyDataDescr(PyType onType, String name, Class ofType, String doc) { + this(name, ofType, doc); setType(onType); } @@ -39,9 +41,10 @@ * @param ofType - * the type returned by the descriptor */ - public PyDataDescr(String name, Class ofType) { + public PyDataDescr(String name, Class ofType, String doc) { this.name = name; this.ofType = ofType; + this.doc = doc; } /** @@ -116,6 +119,11 @@ return String.format("<attribute '%s' of '%s' objects>", name, dtype.fastGetName()); } + @ExposedGet(name = "__doc__") + public String getDoc() { + return doc; + } + /** * Return the name this descriptor is exposed as. * Modified: trunk/jython/src/org/python/core/PyFunction.java =================================================================== --- trunk/jython/src/org/python/core/PyFunction.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/core/PyFunction.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -284,11 +284,6 @@ } @Override - public PyObject getDoc() { - return __doc__; - } - - @Override public PyObject __get__(PyObject obj, PyObject type) { return function___get__(obj, type); } Modified: trunk/jython/src/org/python/core/PyMethod.java =================================================================== --- trunk/jython/src/org/python/core/PyMethod.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/core/PyMethod.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -285,9 +285,9 @@ return hashCode ^ im_func.hashCode(); } - @Override + @ExposedGet(name = "__doc__") public PyObject getDoc() { - return im_func.getDoc(); + return im_func.__getattr__("__doc__"); } @Override Modified: trunk/jython/src/org/python/core/PyMethodDescr.java =================================================================== --- trunk/jython/src/org/python/core/PyMethodDescr.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/core/PyMethodDescr.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -21,8 +21,8 @@ } @ExposedGet(name = "__doc__") - public String fastGetDoc() { - return meth.fastGetDoc(); + public String getDoc() { + return meth.getDoc(); } public int getMaxargs() { Modified: trunk/jython/src/org/python/core/PyModule.java =================================================================== --- trunk/jython/src/org/python/core/PyModule.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/core/PyModule.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -80,18 +80,6 @@ throw Py.TypeError("readonly attribute"); } - @ExposedGet(name = "__doc__") - public PyObject getDoc() { - PyObject dict = fastGetDict(); - if (dict != null) { - PyObject doc = dict.__finditem__("__doc__"); - if (doc != null) { - return doc; - } - } - return moduleDoc; - } - protected PyObject impAttr(String name) { PyObject path = __dict__.__finditem__("__path__"); PyObject pyName = __dict__.__finditem__("__name__"); Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/core/PyObject.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -111,19 +111,6 @@ return objtype; } - //XXX: needs doc - @ExposedGet(name = "__doc__") - public PyObject getDoc() { - PyObject d = fastGetDict(); - if (d != null) { - PyObject doc = d.__finditem__("__doc__"); - if(doc != null) { - return doc; - } - } - return Py.None; - } - /** * Dispatch __init__ behavior */ Modified: trunk/jython/src/org/python/core/PyReflectedFunction.java =================================================================== --- trunk/jython/src/org/python/core/PyReflectedFunction.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/core/PyReflectedFunction.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -53,11 +53,6 @@ container, wherefound); } - @Override - public PyObject getDoc() { - return __doc__; - } - private ReflectedArgs makeArgs(Method m) { return new ReflectedArgs(m, m.getParameterTypes(), Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/core/PyType.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -292,7 +292,8 @@ * Create the __dict__ descriptor. */ private void createDictSlot() { - dict.__setitem__("__dict__", new PyDataDescr(this, "__dict__", PyObject.class) { + String doc = "dictionary for instance variables (if defined)"; + dict.__setitem__("__dict__", new PyDataDescr(this, "__dict__", PyObject.class, doc) { @Override public Object invokeGet(PyObject obj) { return obj.getDict(); @@ -325,7 +326,8 @@ * Create the __weakref__ descriptor. */ private void createWeakrefSlot() { - dict.__setitem__("__weakref__", new PyDataDescr(this, "__weakref__", PyObject.class) { + String doc = "list of weak references to the object (if defined)"; + dict.__setitem__("__weakref__", new PyDataDescr(this, "__weakref__", PyObject.class, doc) { private static final String writeMsg = "attribute '%s' of '%s' objects is not writable"; @@ -484,6 +486,21 @@ TypeBuilder builder = classToBuilder.get(underlying_class); name = builder.getName(); dict = builder.getDict(this); + String doc = builder.getDoc(); + // XXX: Can't create a __doc__ str until the PyBaseString/PyString types are + // created + if (dict.__finditem__("__doc__") == null && forClass != PyBaseString.class + && forClass != PyString.class) { + PyObject docObj; + if (doc != null) { + docObj = new PyString(doc); + } else { + // XXX: Hack: Py.None may be null during bootstrapping. Most types + // encountered then should have docstrings anyway + docObj = Py.None == null ? new PyString() : Py.None; + } + dict.__setitem__("__doc__", docObj); + } setIsBaseType(builder.getIsBaseType()); instantiable = dict.__finditem__("__new__") != null; fillHasSetAndDelete(); @@ -1543,14 +1560,15 @@ } /** - * Equivalent of CPython's typeobject type_get_doc; handles __doc__ descriptors. + * Equivalent of CPython's typeobject.c::type_get_doc; handles __doc__ descriptors. */ + @ExposedGet(name = "__doc__") public PyObject getDoc() { - PyObject doc = super.getDoc(); - if (!builtin && doc != null && doc.getType().lookup("__get__") != null) { - return doc.__get__(null, this); + PyObject doc = dict.__finditem__("__doc__"); + if (doc == null) { + return Py.None; } - return doc; + return doc.__get__(null, this); } boolean getUsesObjectGetattribute() { Modified: trunk/jython/src/org/python/expose/BaseTypeBuilder.java =================================================================== --- trunk/jython/src/org/python/expose/BaseTypeBuilder.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/BaseTypeBuilder.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -24,16 +24,20 @@ private boolean isBaseType; + private String doc; + public BaseTypeBuilder(String name, Class<?> typeClass, Class<?> baseClass, boolean isBaseType, + String doc, PyBuiltinMethod[] meths, PyDataDescr[] descrs, PyNewWrapper newWrapper) { this.typeClass = typeClass; this.baseClass = baseClass; this.isBaseType = isBaseType; + this.doc = doc; this.name = name; this.descrs = descrs; this.meths = meths; @@ -72,4 +76,8 @@ public boolean getIsBaseType() { return isBaseType; } + + public String getDoc() { + return doc; + } } Modified: trunk/jython/src/org/python/expose/ExposedGet.java =================================================================== --- trunk/jython/src/org/python/expose/ExposedGet.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/ExposedGet.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -10,4 +10,9 @@ public @interface ExposedGet { String name() default ""; + + /** + * Returns the __doc__ String for this descriptor. + */ + String doc() default ""; } Modified: trunk/jython/src/org/python/expose/ExposedType.java =================================================================== --- trunk/jython/src/org/python/expose/ExposedType.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/ExposedType.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -31,4 +31,9 @@ * @return Whether this type allows subclassing. */ boolean isBaseType() default true; + + /** + * Returns the __doc__ String for this type. + */ + String doc() default ""; } Modified: trunk/jython/src/org/python/expose/TypeBuilder.java =================================================================== --- trunk/jython/src/org/python/expose/TypeBuilder.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/TypeBuilder.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -17,4 +17,6 @@ public Class getBase(); public boolean getIsBaseType(); + + public String getDoc(); } Modified: trunk/jython/src/org/python/expose/generate/DescriptorExposer.java =================================================================== --- trunk/jython/src/org/python/expose/generate/DescriptorExposer.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/generate/DescriptorExposer.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -15,6 +15,8 @@ private String name; + private String doc; + private String getterMethodName, getterFieldName, setterMethodName, setterFieldName, deleterMethodName; @@ -36,6 +38,10 @@ } public void addMethodGetter(String methodName, String desc) { + addMethodGetter(methodName, desc, null); + } + + public void addMethodGetter(String methodName, String desc, String doc) { if(hasGetter()) { error("Descriptor can only have one getter"); } @@ -44,14 +50,20 @@ } setOfType(Type.getReturnType(desc)); getterMethodName = methodName; + this.doc = doc; } public void addFieldGetter(String fieldName, Type fieldType) { + addFieldGetter(fieldName, fieldType, null); + } + + public void addFieldGetter(String fieldName, Type fieldType, String doc) { if(hasGetter()) { error("Can only have one getter for a descriptor"); } setOfType(fieldType); getterFieldName = fieldName; + this.doc = doc; } public boolean hasGetter() { @@ -130,7 +142,12 @@ } else { mv.visitLdcInsn(ofType); } - superConstructor(STRING, CLASS); + if (doc == null) { + mv.visitInsn(ACONST_NULL); + } else { + mv.visitLdcInsn(doc); + } + superConstructor(STRING, CLASS, STRING); endConstructor(); } Modified: trunk/jython/src/org/python/expose/generate/DescriptorVisitor.java =================================================================== --- trunk/jython/src/org/python/expose/generate/DescriptorVisitor.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/generate/DescriptorVisitor.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -4,14 +4,18 @@ private String val; + private String doc; + DescriptorVisitor(String defaultName) { val = defaultName; } @Override public void visit(String name, Object value) { - if(name.equals("name")) { + if (name.equals("name")) { val = (String)value; + } else if (name.equals("doc")) { + doc = (String)value; } else { super.visit(name, value); } @@ -19,8 +23,8 @@ @Override public void visitEnd() { - handleResult(val); + handleResult(val, doc); } - public abstract void handleResult(String name); -} \ No newline at end of file + public abstract void handleResult(String name, String doc); +} Modified: trunk/jython/src/org/python/expose/generate/ExposedFieldFinder.java =================================================================== --- trunk/jython/src/org/python/expose/generate/ExposedFieldFinder.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/generate/ExposedFieldFinder.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -10,6 +10,8 @@ private FieldVisitor delegate; + private String doc; + public ExposedFieldFinder(String name, FieldVisitor delegate) { fieldName = name; this.delegate = delegate; @@ -20,15 +22,15 @@ return new DescriptorVisitor(fieldName) { @Override - public void handleResult(String name) { - exposeAsGet(name); + public void handleResult(String name, String doc) { + exposeAsGet(name, doc); } }; } else if(EXPOSED_SET.getDescriptor().equals(desc)) { return new DescriptorVisitor(fieldName) { @Override - public void handleResult(String name) { + public void handleResult(String name, String doc) { exposeAsSet(name); } }; @@ -37,7 +39,7 @@ } } - public abstract void exposeAsGet(String name); + public abstract void exposeAsGet(String name, String doc); public abstract void exposeAsSet(String name); Modified: trunk/jython/src/org/python/expose/generate/ExposedMethodFinder.java =================================================================== --- trunk/jython/src/org/python/expose/generate/ExposedMethodFinder.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/generate/ExposedMethodFinder.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -63,7 +63,7 @@ */ public abstract void handleNewExposer(Exposer exposer); - public abstract void exposeAsGetDescriptor(String descName); + public abstract void exposeAsGetDescriptor(String descName, String doc); public abstract void exposeAsSetDescriptor(String descName); @@ -93,15 +93,15 @@ return new DescriptorVisitor(methodName) { @Override - public void handleResult(String name) { - exposeAsGetDescriptor(name); + public void handleResult(String name, String doc) { + exposeAsGetDescriptor(name, doc); } }; } else if(desc.equals(EXPOSED_SET.getDescriptor())) { return new DescriptorVisitor(methodName) { @Override - public void handleResult(String name) { + public void handleResult(String name, String doc) { exposeAsSetDescriptor(name); } }; @@ -109,7 +109,7 @@ return new DescriptorVisitor(methodName) { @Override - public void handleResult(String name) { + public void handleResult(String name, String doc) { exposeAsDeleteDescriptor(name); } }; Modified: trunk/jython/src/org/python/expose/generate/ExposedTypeProcessor.java =================================================================== --- trunk/jython/src/org/python/expose/generate/ExposedTypeProcessor.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/generate/ExposedTypeProcessor.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -111,6 +111,8 @@ private boolean isBaseType = true; + private String doc; + private boolean generatedStaticBlock; private TypeProcessor(ClassVisitor cv) { @@ -135,18 +137,13 @@ return new ExposedTypeVisitor(onType, visitor) { @Override - public void handleResult(String name) { - typeName = name; + public void handleResult(String typeName, Type baseType, boolean isBaseType, + String doc) { + ExposedTypeProcessor.this.typeName = typeName; + TypeProcessor.this.baseType = baseType; + TypeProcessor.this.isBaseType = isBaseType; + TypeProcessor.this.doc = doc; } - - @Override - public void handleResult(Type base) { - baseType = base; - } - - public void handleResult(boolean boolIsBaseType) { - isBaseType = boolIsBaseType; - } }; } return visitor; @@ -166,6 +163,7 @@ typeExposer = new TypeExposer(onType, baseType, isBaseType, + doc, getName(), methodExposers, descExposers.values(), @@ -266,8 +264,8 @@ } @Override - public void exposeAsGetDescriptor(String descName) { - getDescriptorExposer(descName).addMethodGetter(name, desc); + public void exposeAsGetDescriptor(String descName, String doc) { + getDescriptorExposer(descName).addMethodGetter(name, desc, doc); } @Override @@ -303,8 +301,8 @@ return new ExposedFieldFinder(fieldName, passthroughVisitor) { @Override - public void exposeAsGet(String name) { - getDescriptorExposer(name).addFieldGetter(fieldName, Type.getType(desc)); + public void exposeAsGet(String name, String doc) { + getDescriptorExposer(name).addFieldGetter(fieldName, Type.getType(desc), doc); } @Override Modified: trunk/jython/src/org/python/expose/generate/ExposedTypeVisitor.java =================================================================== --- trunk/jython/src/org/python/expose/generate/ExposedTypeVisitor.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/generate/ExposedTypeVisitor.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -16,6 +16,8 @@ private boolean isBaseType = true; + private String doc; + private final AnnotationVisitor passthrough; public ExposedTypeVisitor(Type onType, AnnotationVisitor passthrough) { @@ -25,12 +27,14 @@ @Override public void visit(String name, Object value) { - if(name.equals("name")) { + if (name.equals("name")) { typeName = (String)value; - } else if(name.equals("base")) { + } else if (name.equals("base")) { base = (Type)value; - } else if(name.equals("isBaseType")) { + } else if (name.equals("isBaseType")) { isBaseType = (Boolean)value; + } else if (name.equals("doc")) { + doc = (String)value; } else { super.visit(name, value); } @@ -41,25 +45,21 @@ @Override public void visitEnd() { - if(typeName == null) { + if (typeName == null) { String name = onType.getClassName(); typeName = name.substring(name.lastIndexOf(".") + 1); } - handleResult(typeName); - handleResult(base); - handleResult(isBaseType); + handleResult(typeName, base, isBaseType, doc); if (passthrough != null) { passthrough.visitEnd(); } } - public abstract void handleResult(Type base); - - public abstract void handleResult(boolean isBaseType); - /** - * @param name - - * the name the type should be exposed as from the annotation. + * @param name the name the type should be exposed as from the annotation + * @param name the specified base type + * @param name the value of the isBaseType flag + * @param name the type's docstring */ - public abstract void handleResult(String name); + public abstract void handleResult(String name, Type base, boolean isBaseType, String doc); } Modified: trunk/jython/src/org/python/expose/generate/TypeExposer.java =================================================================== --- trunk/jython/src/org/python/expose/generate/TypeExposer.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/src/org/python/expose/generate/TypeExposer.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -20,6 +20,8 @@ private boolean isBaseType; + private String doc; + private Type onType; private String name; @@ -35,6 +37,7 @@ public TypeExposer(Type onType, Type baseType, boolean isBaseType, + String doc, String name, Collection<MethodExposer> methods, Collection<DescriptorExposer> descriptors, @@ -42,6 +45,7 @@ super(BaseTypeBuilder.class, makeGeneratedName(onType)); this.baseType = baseType; this.isBaseType = isBaseType; + this.doc = doc; this.onType = onType; this.name = name; this.methods = methods; @@ -106,6 +110,11 @@ mv.visitLdcInsn(onType); mv.visitLdcInsn(baseType); mv.visitLdcInsn(isBaseType); + if (doc == null) { + mv.visitInsn(ACONST_NULL); + } else { + mv.visitLdcInsn(doc); + } mv.visitLdcInsn(numNames); mv.visitTypeInsn(ANEWARRAY, BUILTIN_METHOD.getInternalName()); mv.visitVarInsn(ASTORE, 1); @@ -140,7 +149,7 @@ } else { mv.visitInsn(ACONST_NULL); } - superConstructor(STRING, CLASS, CLASS, BOOLEAN, ABUILTIN_METHOD, ADATA_DESCR, + superConstructor(STRING, CLASS, CLASS, BOOLEAN, STRING, ABUILTIN_METHOD, ADATA_DESCR, PYNEWWRAPPER); endConstructor(); } Modified: trunk/jython/tests/java/org/python/expose/generate/ExposeMethodFinderTest.java =================================================================== --- trunk/jython/tests/java/org/python/expose/generate/ExposeMethodFinderTest.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/tests/java/org/python/expose/generate/ExposeMethodFinderTest.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -36,7 +36,7 @@ } @Override - public void exposeAsGetDescriptor(String descName) { + public void exposeAsGetDescriptor(String descName, String doc) { getName = descName; } Modified: trunk/jython/tests/java/org/python/expose/generate/ExposedTypeProcessorTest.java =================================================================== --- trunk/jython/tests/java/org/python/expose/generate/ExposedTypeProcessorTest.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/tests/java/org/python/expose/generate/ExposedTypeProcessorTest.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -7,6 +7,7 @@ import org.python.core.PyBuiltinCallable; import org.python.core.PyDataDescr; import org.python.core.PyObject; +import org.python.core.PyString; import org.python.core.PyType; public class ExposedTypeProcessorTest extends InterpTestCase { @@ -42,6 +43,7 @@ desc.setType(simp.getType()); assertEquals(doctoredSimple.getField("toStringVal").get(simp), desc.__get__(simp, PyType.fromClass(doctoredSimple)).toString()); + assertEquals(desc.__getattr__("__doc__"), new PyString("tostring docs")); } public void testNoAnnotationType() throws IOException { Modified: trunk/jython/tests/java/org/python/expose/generate/ExposedTypeVisitorTest.java =================================================================== --- trunk/jython/tests/java/org/python/expose/generate/ExposedTypeVisitorTest.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/tests/java/org/python/expose/generate/ExposedTypeVisitorTest.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -12,18 +12,11 @@ etv = new ExposedTypeVisitor(Type.getType("Lsimpletype;"), null) { @Override - public void handleResult(String name) { + public void handleResult(String name, Type base, boolean isBaseType, String doc) { result = name; - } - - @Override - public void handleResult(Type base) { baseResult = base; - } - - @Override - public void handleResult(boolean isBaseType) { isBaseTypeResult = isBaseType; + docResult = doc; } }; } @@ -38,10 +31,12 @@ etv.visit("name", "different"); etv.visit("base", Type.getType(PyObject.class)); etv.visit("isBaseType", false); + etv.visit("doc", "Different docstring"); etv.visitEnd(); assertEquals("different", result); assertEquals(Type.getType(PyObject.class), baseResult); assertEquals(false, isBaseTypeResult); + assertEquals("Different docstring", docResult); } ExposedTypeVisitor etv; @@ -51,4 +46,6 @@ private Type baseResult; private boolean isBaseTypeResult; + + private String docResult; } Modified: trunk/jython/tests/java/org/python/expose/generate/SimpleExposed.java =================================================================== --- trunk/jython/tests/java/org/python/expose/generate/SimpleExposed.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/tests/java/org/python/expose/generate/SimpleExposed.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -4,7 +4,6 @@ import org.python.core.PyInteger; import org.python.core.PyNewWrapper; import org.python.core.PyObject; -import org.python.core.PyString; import org.python.core.PyType; import org.python.core.ThreadState; import org.python.expose.ExposedClassMethod; @@ -16,7 +15,7 @@ import org.python.expose.ExposedType; import org.python.expose.MethodType; -@ExposedType(name = "simpleexposed", isBaseType = false) +@ExposedType(name = "simpleexposed", isBaseType = false, doc = "Docstring") public class SimpleExposed extends PyObject { public void method() {} @@ -147,7 +146,7 @@ } } - @ExposedGet(name = "tostring") + @ExposedGet(name = "tostring", doc = "tostring docs") public String toStringVal = TO_STRING_RETURN; public static final String TO_STRING_RETURN = "A simple test class"; Modified: trunk/jython/tests/java/org/python/expose/generate/TypeExposerTest.java =================================================================== --- trunk/jython/tests/java/org/python/expose/generate/TypeExposerTest.java 2009-10-13 02:31:45 UTC (rev 6854) +++ trunk/jython/tests/java/org/python/expose/generate/TypeExposerTest.java 2009-10-14 03:19:24 UTC (rev 6855) @@ -22,6 +22,7 @@ assertEquals(false, t.getIsBaseType()); PyType type = PyType.fromClass(SimpleExposed.class); PyObject dict = t.getDict(type); + assertEquals(dict.__finditem__("__doc__"), Py.newString("Docstring")); assertNotNull(dict.__finditem__("simple_method")); assertNotNull(dict.__finditem__("prefixed")); assertNotNull(dict.__finditem__("__str__")); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-14 06:02:21
|
Revision: 6856 http://jython.svn.sourceforge.net/jython/?rev=6856&view=rev Author: pjenvey Date: 2009-10-14 06:02:01 +0000 (Wed, 14 Oct 2009) Log Message: ----------- docs galore, enable test_descr.descrdoc Modified Paths: -------------- trunk/jython/Lib/test/test_descr.py trunk/jython/Misc/make_pydocs.py trunk/jython/src/org/python/core/BuiltinDocs.java trunk/jython/src/org/python/core/PyBaseString.java trunk/jython/src/org/python/core/PyBoolean.java trunk/jython/src/org/python/core/PyClassMethod.java trunk/jython/src/org/python/core/PyComplex.java trunk/jython/src/org/python/core/PyDictionary.java trunk/jython/src/org/python/core/PyEnumerate.java trunk/jython/src/org/python/core/PyFile.java trunk/jython/src/org/python/core/PyFloat.java trunk/jython/src/org/python/core/PyFunction.java trunk/jython/src/org/python/core/PyInteger.java trunk/jython/src/org/python/core/PyList.java trunk/jython/src/org/python/core/PyLong.java trunk/jython/src/org/python/core/PyMethod.java trunk/jython/src/org/python/core/PyObject.java trunk/jython/src/org/python/core/PyProperty.java trunk/jython/src/org/python/core/PySlice.java trunk/jython/src/org/python/core/PyStaticMethod.java trunk/jython/src/org/python/core/PyString.java trunk/jython/src/org/python/core/PySuper.java trunk/jython/src/org/python/core/PyTuple.java trunk/jython/src/org/python/core/PyType.java trunk/jython/src/org/python/core/PyUnicode.java trunk/jython/src/org/python/core/PyXRange.java Modified: trunk/jython/Lib/test/test_descr.py =================================================================== --- trunk/jython/Lib/test/test_descr.py 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/Lib/test/test_descr.py 2009-10-14 06:02:01 UTC (rev 6856) @@ -4396,9 +4396,6 @@ # takes 1 arg) specials, - # Jython file lacks doc strings - descrdoc, - # New style classes don't support __del__: # http://bugs.jython.org/issue1057 delhook, Modified: trunk/jython/Misc/make_pydocs.py =================================================================== --- trunk/jython/Misc/make_pydocs.py 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/Misc/make_pydocs.py 2009-10-14 06:02:01 UTC (rev 6856) @@ -2,15 +2,21 @@ import __builtin__ def print_doc(out, obj, meth): - doc = (getattr(obj, meth)).__doc__ - if doc == None: + if meth == '__doc__': + doc = getattr(obj, meth) + bdname = '%s_doc' % obj.__name__ + else: + doc = getattr(obj, meth).__doc__ + bdname = '%s_%s_doc' % (obj.__name__, meth) + + if doc is None: doc = "" lines = doc.split("\n") - outstring = '\\n" + \n "'.join(lines) - print >> out, (' public final static String %s_%s_doc = ' - % (obj.__name__, meth)) + outstring = '\\n" + \n "'.join(format(line) for line in lines) + print >> out, (' public final static String %s = ' % bdname) print >> outfile, ' "%s";\n' % outstring +format = lambda line: line.replace('\\', '\\\\').replace('"', r'\"') opt = lambda n: getattr(__builtin__, n, None) def f(): pass @@ -58,13 +64,13 @@ ] outfile = open("BuiltinDocs.java", "w") -print >> outfile, '//generated by make_pydocs.py\n' +print >> outfile, '// generated by make_pydocs.py\n' print >> outfile, 'package org.python.core;\n' print >> outfile, 'public class BuiltinDocs {\n' for obj in types_list: - print >> outfile, ' //Docs for %s' % obj + print >> outfile, ' // Docs for %s' % obj for meth in dir(obj): print_doc(outfile, obj, meth) Modified: trunk/jython/src/org/python/core/BuiltinDocs.java =================================================================== --- trunk/jython/src/org/python/core/BuiltinDocs.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/BuiltinDocs.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -1,10 +1,10 @@ -//generated by make_pydocs.py +// generated by make_pydocs.py package org.python.core; public class BuiltinDocs { - //Docs for <type 'object'> + // Docs for <type 'object'> public final static String object___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -12,11 +12,8 @@ public final static String object___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String object___doc___doc = - "str(object) -> string\n" + - "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + public final static String object_doc = + "The most base type"; public final static String object___getattribute___doc = "x.__getattribute__('name') <==> x.name"; @@ -45,7 +42,7 @@ public final static String object___str___doc = "x.__str__() <==> str(x)"; - //Docs for <type 'type'> + // Docs for <type 'type'> public final static String type___base___doc = "The most base type"; @@ -91,11 +88,9 @@ "non-string. If the argument is outside the integer range a long object\n" + "will be returned instead."; - public final static String type___doc___doc = - "str(object) -> string\n" + - "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + public final static String type_doc = + "type(object) -> the object's type\n" + + "type(name, bases, dict) -> a new type"; public final static String type___flags___doc = "int(x[, base]) -> integer\n" + @@ -179,7 +174,7 @@ "mro() -> list\n" + "return a type's method resolution order"; - //Docs for <type 'unicode'> + // Docs for <type 'unicode'> public final static String unicode___add___doc = "x.__add__(y) <==> x+y"; @@ -193,11 +188,12 @@ public final static String unicode___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String unicode___doc___doc = - "str(object) -> string\n" + + public final static String unicode_doc = + "unicode(string [, encoding[, errors]]) -> object\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Create a new Unicode object from the given encoded string.\n" + + "encoding defaults to the current default string encoding.\n" + + "errors can be 'strict', 'replace' or 'ignore' and defaults to 'strict'."; public final static String unicode___eq___doc = "x.__eq__(y) <==> x==y"; @@ -327,7 +323,7 @@ "S.find(sub [,start [,end]]) -> int\n" + "\n" + "Return the lowest index in S where substring sub is found,\n" + - "such that sub is contained within s[start:end]. Optional\n" + + "such that sub is contained within s[start,end]. Optional\n" + "arguments start and end are interpreted as in slice notation.\n" + "\n" + "Return -1 on failure."; @@ -435,7 +431,7 @@ "S.rfind(sub [,start [,end]]) -> int\n" + "\n" + "Return the highest index in S where substring sub is found,\n" + - "such that sub is contained within s[start:end]. Optional\n" + + "such that sub is contained within s[start,end]. Optional\n" + "arguments start and end are interpreted as in slice notation.\n" + "\n" + "Return -1 on failure."; @@ -537,7 +533,7 @@ "Pad a numeric string x with zeros on the left, to fill a field\n" + "of the specified width. The string x is never truncated."; - //Docs for <type 'dict'> + // Docs for <type 'dict'> public final static String dict___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -554,11 +550,16 @@ public final static String dict___delitem___doc = "x.__delitem__(y) <==> del x[y]"; - public final static String dict___doc___doc = - "str(object) -> string\n" + - "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + public final static String dict_doc = + "dict() -> new empty dictionary.\n" + + "dict(mapping) -> new dictionary initialized from a mapping object's\n" + + " (key, value) pairs.\n" + + "dict(seq) -> new dictionary initialized as if via:\n" + + " d = {}\n" + + " for k, v in seq:\n" + + " d[k] = v\n" + + "dict(**kwargs) -> new dictionary initialized with the name=value pairs\n" + + " in the keyword argument list. For example: dict(one=1, two=2)"; public final static String dict___eq___doc = "x.__eq__(y) <==> x==y"; @@ -666,7 +667,7 @@ public final static String dict_values_doc = "D.values() -> list of D's values"; - //Docs for <type 'list'> + // Docs for <type 'list'> public final static String list___add___doc = "x.__add__(y) <==> x+y"; @@ -688,11 +689,9 @@ " \n" + " Use of negative indices is not supported."; - public final static String list___doc___doc = - "str(object) -> string\n" + - "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + public final static String list_doc = + "list() -> new list\n" + + "list(sequence) -> new list initialized from sequence's items"; public final static String list___eq___doc = "x.__eq__(y) <==> x==y"; @@ -804,7 +803,7 @@ "L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;\n" + "cmp(x, y) -> -1, 0, 1"; - //Docs for <type 'slice'> + // Docs for <type 'slice'> public final static String slice___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -815,11 +814,10 @@ public final static String slice___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String slice___doc___doc = - "str(object) -> string\n" + + public final static String slice_doc = + "slice([start,] stop[, step])\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Create a slice object. This is used for extended slicing (e.g. a[0:10:2])."; public final static String slice___getattribute___doc = "x.__getattribute__('name') <==> x.name"; @@ -865,7 +863,7 @@ public final static String slice_stop_doc = ""; - //Docs for <type 'super'> + // Docs for <type 'super'> public final static String super___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -873,11 +871,14 @@ public final static String super___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String super___doc___doc = - "str(object) -> string\n" + - "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + public final static String super_doc = + "super(type) -> unbound super object\n" + + "super(type, obj) -> bound super object; requires isinstance(obj, type)\n" + + "super(type, type2) -> bound super object; requires issubclass(type2, type)\n" + + "Typical use to call a cooperative superclass method:\n" + + "class C(B):\n" + + " def meth(self, arg):\n" + + " super(C, self).meth(arg)"; public final static String super___get___doc = "descr.__get__(obj[, type]) -> value"; @@ -918,7 +919,7 @@ public final static String super___thisclass___doc = "the class invoking super()"; - //Docs for <type 'staticmethod'> + // Docs for <type 'staticmethod'> public final static String staticmethod___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -926,11 +927,23 @@ public final static String staticmethod___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String staticmethod___doc___doc = - "str(object) -> string\n" + + public final static String staticmethod_doc = + "staticmethod(function) -> method\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Convert a function to be a static method.\n" + + "\n" + + "A static method does not receive an implicit first argument.\n" + + "To declare a static method, use this idiom:\n" + + "\n" + + " class C:\n" + + " def f(arg1, arg2, ...): ...\n" + + " f = staticmethod(f)\n" + + "\n" + + "It can be called either on the class (e.g. C.f()) or on an instance\n" + + "(e.g. C().f()). The instance is ignored except for its class.\n" + + "\n" + + "Static methods in Python are similar to those found in Java or C++.\n" + + "For a more advanced concept, see the classmethod builtin."; public final static String staticmethod___get___doc = "descr.__get__(obj[, type]) -> value"; @@ -962,7 +975,7 @@ public final static String staticmethod___str___doc = "x.__str__() <==> str(x)"; - //Docs for <type 'float'> + // Docs for <type 'float'> public final static String float___abs___doc = "x.__abs__() <==> abs(x)"; @@ -985,11 +998,10 @@ public final static String float___divmod___doc = "x.__divmod__(y) <==> divmod(x, y)"; - public final static String float___doc___doc = - "str(object) -> string\n" + + public final static String float_doc = + "float(x) -> floating point number\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Convert a string or number to a floating point number, if possible."; public final static String float___eq___doc = "x.__eq__(y) <==> x==y"; @@ -1125,7 +1137,7 @@ public final static String float___truediv___doc = "x.__truediv__(y) <==> x/y"; - //Docs for <type 'enumerate'> + // Docs for <type 'enumerate'> public final static String enumerate___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -1133,11 +1145,13 @@ public final static String enumerate___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String enumerate___doc___doc = - "str(object) -> string\n" + + public final static String enumerate_doc = + "enumerate(iterable) -> iterator for index, value of iterable\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Return an enumerate object. iterable must be an other object that supports\n" + + "iteration. The enumerate object yields pairs containing a count (from\n" + + "zero) and a value yielded by the iterable argument. enumerate is useful\n" + + "for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2]), ..."; public final static String enumerate___getattribute___doc = "x.__getattribute__('name') <==> x.name"; @@ -1172,7 +1186,7 @@ public final static String enumerate_next_doc = "x.next() -> the next value, or raise StopIteration"; - //Docs for <type 'basestring'> + // Docs for <type 'basestring'> public final static String basestring___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -1180,11 +1194,8 @@ public final static String basestring___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String basestring___doc___doc = - "str(object) -> string\n" + - "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + public final static String basestring_doc = + "Type basestring cannot be instantiated; it is the base for str and unicode."; public final static String basestring___getattribute___doc = "x.__getattribute__('name') <==> x.name"; @@ -1213,7 +1224,7 @@ public final static String basestring___str___doc = "x.__str__() <==> str(x)"; - //Docs for <type 'long'> + // Docs for <type 'long'> public final static String long___abs___doc = "x.__abs__() <==> abs(x)"; @@ -1242,11 +1253,14 @@ public final static String long___divmod___doc = "x.__divmod__(y) <==> divmod(x, y)"; - public final static String long___doc___doc = - "str(object) -> string\n" + + public final static String long_doc = + "long(x[, base]) -> integer\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Convert a string or number to a long integer, if possible. A floating\n" + + "point argument will be truncated towards zero (this does not include a\n" + + "string representation of a floating point number!) When converting a\n" + + "string, use the optional base. It is an error to supply a base when\n" + + "converting a non-string."; public final static String long___float___doc = "x.__float__() <==> float(x)"; @@ -1380,7 +1394,7 @@ public final static String long___xor___doc = "x.__xor__(y) <==> x^y"; - //Docs for <type 'tuple'> + // Docs for <type 'tuple'> public final static String tuple___add___doc = "x.__add__(y) <==> x+y"; @@ -1394,11 +1408,11 @@ public final static String tuple___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String tuple___doc___doc = - "str(object) -> string\n" + + public final static String tuple_doc = + "tuple() -> an empty tuple\n" + + "tuple(sequence) -> tuple initialized from sequence's items\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "If the argument is a tuple, the return value is the same object."; public final static String tuple___eq___doc = "x.__eq__(y) <==> x==y"; @@ -1468,7 +1482,7 @@ public final static String tuple___str___doc = "x.__str__() <==> str(x)"; - //Docs for <type 'str'> + // Docs for <type 'str'> public final static String str___add___doc = "x.__add__(y) <==> x+y"; @@ -1482,7 +1496,7 @@ public final static String str___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String str___doc___doc = + public final static String str_doc = "str(object) -> string\n" + "\n" + "Return a nice string representation of the object.\n" + @@ -1616,7 +1630,7 @@ "S.find(sub [,start [,end]]) -> int\n" + "\n" + "Return the lowest index in S where substring sub is found,\n" + - "such that sub is contained within s[start:end]. Optional\n" + + "such that sub is contained within s[start,end]. Optional\n" + "arguments start and end are interpreted as in slice notation.\n" + "\n" + "Return -1 on failure."; @@ -1712,7 +1726,7 @@ "S.rfind(sub [,start [,end]]) -> int\n" + "\n" + "Return the highest index in S where substring sub is found,\n" + - "such that sub is contained within s[start:end]. Optional\n" + + "such that sub is contained within s[start,end]. Optional\n" + "arguments start and end are interpreted as in slice notation.\n" + "\n" + "Return -1 on failure."; @@ -1813,7 +1827,7 @@ "Pad a numeric string S with zeros on the left, to fill a field\n" + "of the specified width. The string S is never truncated."; - //Docs for <type 'property'> + // Docs for <type 'property'> public final static String property___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -1824,11 +1838,17 @@ public final static String property___delete___doc = "descr.__delete__(obj)"; - public final static String property___doc___doc = - "str(object) -> string\n" + + public final static String property_doc = + "property(fget=None, fset=None, fdel=None, doc=None) -> property attribute\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "fget is a function to be used for getting an attribute value, and likewise\n" + + "fset is a function for setting, and fdel a function for del'ing, an\n" + + "attribute. Typical use is to define a managed attribute x:\n" + + "class C(object):\n" + + " def getx(self): return self.__x\n" + + " def setx(self, value): self.__x = value\n" + + " def delx(self): del self.__x\n" + + " x = property(getx, setx, delx, \"I'm the 'x' property.\")"; public final static String property___get___doc = "descr.__get__(obj[, type]) -> value"; @@ -1872,7 +1892,7 @@ public final static String property_fset_doc = ""; - //Docs for <type 'int'> + // Docs for <type 'int'> public final static String int___abs___doc = "x.__abs__() <==> abs(x)"; @@ -1901,11 +1921,15 @@ public final static String int___divmod___doc = "x.__divmod__(y) <==> divmod(x, y)"; - public final static String int___doc___doc = - "str(object) -> string\n" + + public final static String int_doc = + "int(x[, base]) -> integer\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Convert a string or number to an integer, if possible. A floating point\n" + + "argument will be truncated towards zero (this does not include a string\n" + + "representation of a floating point number!) When converting a string, use\n" + + "the optional base. It is an error to supply a base when converting a\n" + + "non-string. If the argument is outside the integer range a long object\n" + + "will be returned instead."; public final static String int___float___doc = "x.__float__() <==> float(x)"; @@ -2039,7 +2063,7 @@ public final static String int___xor___doc = "x.__xor__(y) <==> x^y"; - //Docs for <type 'xrange'> + // Docs for <type 'xrange'> public final static String xrange___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -2047,11 +2071,12 @@ public final static String xrange___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String xrange___doc___doc = - "str(object) -> string\n" + + public final static String xrange_doc = + "xrange([start,] stop[, step]) -> xrange object\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Like range(), but instead of returning a list, returns an object that\n" + + "generates the numbers in the range on demand. For looping, this is \n" + + "slightly faster than range() and more memory efficient."; public final static String xrange___getattribute___doc = "x.__getattribute__('name') <==> x.name"; @@ -2092,7 +2117,7 @@ public final static String xrange___str___doc = "x.__str__() <==> str(x)"; - //Docs for <type 'file'> + // Docs for <type 'file'> public final static String file___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -2100,11 +2125,24 @@ public final static String file___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String file___doc___doc = - "str(object) -> string\n" + + public final static String file_doc = + "file(name[, mode[, buffering]]) -> file object\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Open a file. The mode can be 'r', 'w' or 'a' for reading (default),\n" + + "writing or appending. The file will be created if it doesn't exist\n" + + "when opened for writing or appending; it will be truncated when\n" + + "opened for writing. Add a 'b' to the mode for binary files.\n" + + "Add a '+' to the mode to allow simultaneous reading and writing.\n" + + "If the buffering argument is given, 0 means unbuffered, 1 means line\n" + + "buffered, and larger numbers specify the buffer size.\n" + + "Add a 'U' to mode to open the file for input with universal newline\n" + + "support. Any line ending in the input file will be seen as a '\\n'\n" + + "in Python. Also, a file so opened gains the attribute 'newlines';\n" + + "the value for this attribute is one of None (no newline read yet),\n" + + "'\\r', '\\n', '\\r\\n' or a tuple containing all the newline types seen.\n" + + "\n" + + "'U' cannot be combined with 'w' or '+' mode.\n" + + ""; public final static String file___enter___doc = "__enter__() -> self."; @@ -2244,7 +2282,7 @@ "For backward compatibility. File objects now include the performance\n" + "optimizations previously implemented in the xreadlines module."; - //Docs for <type 'complex'> + // Docs for <type 'complex'> public final static String complex___abs___doc = "x.__abs__() <==> abs(x)"; @@ -2267,11 +2305,11 @@ public final static String complex___divmod___doc = "x.__divmod__(y) <==> divmod(x, y)"; - public final static String complex___doc___doc = - "str(object) -> string\n" + + public final static String complex_doc = + "complex(real[, imag]) -> complex number\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Create a complex number from a real part and an optional imaginary part.\n" + + "This is equivalent to (real + imag*1j) where imag defaults to 0."; public final static String complex___eq___doc = "x.__eq__(y) <==> x==y"; @@ -2393,7 +2431,7 @@ public final static String complex_real_doc = "the real part of a complex number"; - //Docs for <type 'bool'> + // Docs for <type 'bool'> public final static String bool___abs___doc = "x.__abs__() <==> abs(x)"; @@ -2422,11 +2460,12 @@ public final static String bool___divmod___doc = "x.__divmod__(y) <==> divmod(x, y)"; - public final static String bool___doc___doc = - "str(object) -> string\n" + + public final static String bool_doc = + "bool(x) -> bool\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Returns True when the argument x is true, False otherwise.\n" + + "The builtins True and False are the only two instances of the class bool.\n" + + "The class bool is a subclass of the class int, and cannot be subclassed."; public final static String bool___float___doc = "x.__float__() <==> float(x)"; @@ -2560,7 +2599,7 @@ public final static String bool___xor___doc = "x.__xor__(y) <==> x^y"; - //Docs for <type 'classmethod'> + // Docs for <type 'classmethod'> public final static String classmethod___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -2568,11 +2607,26 @@ public final static String classmethod___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String classmethod___doc___doc = - "str(object) -> string\n" + + public final static String classmethod_doc = + "classmethod(function) -> method\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Convert a function to be a class method.\n" + + "\n" + + "A class method receives the class as implicit first argument,\n" + + "just like an instance method receives the instance.\n" + + "To declare a class method, use this idiom:\n" + + "\n" + + " class C:\n" + + " def f(cls, arg1, arg2, ...): ...\n" + + " f = classmethod(f)\n" + + "\n" + + "It can be called either on the class (e.g. C.f()) or on an instance\n" + + "(e.g. C().f()). The instance is ignored except for its class.\n" + + "If a class method is called for a derived class, the derived class\n" + + "object is passed as the implied first argument.\n" + + "\n" + + "Class methods are different than C++ or Java static methods.\n" + + "If you want those, see the staticmethod builtin."; public final static String classmethod___get___doc = "descr.__get__(obj[, type]) -> value"; @@ -2604,7 +2658,7 @@ public final static String classmethod___str___doc = "x.__str__() <==> str(x)"; - //Docs for <type 'function'> + // Docs for <type 'function'> public final static String function___call___doc = "x.__call__(...) <==> x(...)"; @@ -2618,11 +2672,13 @@ public final static String function___dict___doc = ""; - public final static String function___doc___doc = - "str(object) -> string\n" + + public final static String function_doc = + "function(code, globals[, name[, argdefs[, closure]]])\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Create a function object from a code object and a dictionary.\n" + + "The optional name string overrides the name from the code object.\n" + + "The optional argdefs tuple specifies the default argument values.\n" + + "The optional closure tuple supplies the bindings for free variables."; public final static String function___get___doc = "descr.__get__(obj[, type]) -> value"; @@ -2687,7 +2743,7 @@ public final static String function_func_name_doc = ""; - //Docs for <type 'instancemethod'> + // Docs for <type 'instancemethod'> public final static String instancemethod___call___doc = "x.__call__(...) <==> x(...)"; @@ -2701,11 +2757,10 @@ public final static String instancemethod___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String instancemethod___doc___doc = - "str(object) -> string\n" + + public final static String instancemethod_doc = + "instancemethod(function, instance, class)\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Create an instance method object."; public final static String instancemethod___get___doc = "descr.__get__(obj[, type]) -> value"; @@ -2746,7 +2801,7 @@ public final static String instancemethod_im_self_doc = "the instance to which a method is bound; None for unbound methods"; - //Docs for <type 'code'> + // Docs for <type 'code'> public final static String code___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -2757,11 +2812,11 @@ public final static String code___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String code___doc___doc = - "str(object) -> string\n" + + public final static String code_doc = + "code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n" + + " varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n" + "\n" + - "Return a nice string representation of the object.\n" + - "If the argument is a string, the return value is the same object."; + "Create a code object. Not for the faint of heart."; public final static String code___getattribute___doc = "x.__getattribute__('name') <==> x.name"; @@ -2832,7 +2887,7 @@ public final static String code_co_varnames_doc = ""; - //Docs for <type 'frame'> + // Docs for <type 'frame'> public final static String frame___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -2840,7 +2895,7 @@ public final static String frame___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String frame___doc___doc = + public final static String frame_doc = ""; public final static String frame___getattribute___doc = @@ -2906,7 +2961,7 @@ public final static String frame_f_trace_doc = ""; - //Docs for <type 'traceback'> + // Docs for <type 'traceback'> public final static String traceback___class___doc = "type(object) -> the object's type\n" + "type(name, bases, dict) -> a new type"; @@ -2914,7 +2969,7 @@ public final static String traceback___delattr___doc = "x.__delattr__('name') <==> del x.name"; - public final static String traceback___doc___doc = + public final static String traceback_doc = ""; public final static String traceback___getattribute___doc = Modified: trunk/jython/src/org/python/core/PyBaseString.java =================================================================== --- trunk/jython/src/org/python/core/PyBaseString.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyBaseString.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -5,7 +5,7 @@ /** * base class for jython strings. */ -@ExposedType(name = "basestring", base = PyObject.class) +@ExposedType(name = "basestring", base = PyObject.class, doc = BuiltinDocs.basestring_doc) public abstract class PyBaseString extends PySequence { public static final PyType TYPE = PyType.fromClass(PyBaseString.class); Modified: trunk/jython/src/org/python/core/PyBoolean.java =================================================================== --- trunk/jython/src/org/python/core/PyBoolean.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyBoolean.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -8,7 +8,7 @@ /** * A builtin python bool. */ -@ExposedType(name = "bool", isBaseType = false) +@ExposedType(name = "bool", isBaseType = false, doc = BuiltinDocs.bool_doc) public class PyBoolean extends PyInteger { public static final PyType TYPE = PyType.fromClass(PyBoolean.class); Modified: trunk/jython/src/org/python/core/PyClassMethod.java =================================================================== --- trunk/jython/src/org/python/core/PyClassMethod.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyClassMethod.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -7,7 +7,7 @@ /** * The classmethod descriptor. */ -@ExposedType(name = "classmethod") +@ExposedType(name = "classmethod", doc = BuiltinDocs.classmethod_doc) public class PyClassMethod extends PyObject { public static final PyType TYPE = PyType.fromClass(PyClassMethod.class); Modified: trunk/jython/src/org/python/core/PyComplex.java =================================================================== --- trunk/jython/src/org/python/core/PyComplex.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyComplex.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -10,14 +10,17 @@ /** * A builtin python complex number */ -@ExposedType(name = "complex") +@ExposedType(name = "complex", doc = BuiltinDocs.complex_doc) public class PyComplex extends PyObject { public static final PyType TYPE = PyType.fromClass(PyComplex.class); - @ExposedGet - public double real, imag; + @ExposedGet(doc = BuiltinDocs.complex_real_doc) + public double real; + @ExposedGet(doc = BuiltinDocs.complex_imag_doc) + public double imag; + static PyComplex J = new PyComplex(0, 1.); @ExposedNew Modified: trunk/jython/src/org/python/core/PyDictionary.java =================================================================== --- trunk/jython/src/org/python/core/PyDictionary.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyDictionary.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -22,7 +22,7 @@ /** * A builtin python dictionary. */ -@ExposedType(name = "dict") +@ExposedType(name = "dict", doc = BuiltinDocs.dict_doc) public class PyDictionary extends PyObject implements ConcurrentMap { public static final PyType TYPE = PyType.fromClass(PyDictionary.class); Modified: trunk/jython/src/org/python/core/PyEnumerate.java =================================================================== --- trunk/jython/src/org/python/core/PyEnumerate.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyEnumerate.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -8,7 +8,7 @@ /** * The Python builtin enumerate type. */ -@ExposedType(name = "enumerate", base = PyObject.class) +@ExposedType(name = "enumerate", base = PyObject.class, doc = BuiltinDocs.enumerate_doc) public class PyEnumerate extends PyIterator { public static final PyType TYPE = PyType.fromClass(PyEnumerate.class); Modified: trunk/jython/src/org/python/core/PyFile.java =================================================================== --- trunk/jython/src/org/python/core/PyFile.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyFile.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -32,20 +32,20 @@ /** * The Python file type. Wraps an {@link TextIOBase} object. */ -@ExposedType(name = "file") +@ExposedType(name = "file", doc = BuiltinDocs.file_doc) public class PyFile extends PyObject { public static final PyType TYPE = PyType.fromClass(PyFile.class); /** The filename */ - @ExposedGet + @ExposedGet(doc = BuiltinDocs.file_name_doc) public PyObject name; /** The mode string */ - @ExposedGet + @ExposedGet(doc = BuiltinDocs.file_mode_doc) public String mode; - @ExposedGet + @ExposedGet(doc = BuiltinDocs.file_encoding_doc) public String encoding; /** Indicator dictating whether a space should be written to this @@ -525,17 +525,17 @@ file.checkClosed(); } - @ExposedGet(name = "closed") + @ExposedGet(name = "closed", doc = BuiltinDocs.file_closed_doc) public boolean getClosed() { return file.closed(); } - @ExposedGet(name = "newlines") + @ExposedGet(name = "newlines", doc = BuiltinDocs.file_newlines_doc) public PyObject getNewlines() { return file.getNewlines(); } - @ExposedGet(name = "softspace") + @ExposedGet(name = "softspace", doc = BuiltinDocs.file_softspace_doc) public PyObject getSoftspace() { // NOTE: not actual bools because CPython is this way return softspace ? Py.One : Py.Zero; Modified: trunk/jython/src/org/python/core/PyFloat.java =================================================================== --- trunk/jython/src/org/python/core/PyFloat.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyFloat.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -13,7 +13,7 @@ /** * A builtin python float. */ -@ExposedType(name = "float") +@ExposedType(name = "float", doc = BuiltinDocs.float_doc) public class PyFloat extends PyObject { /** Precisions used by repr() and str(), respectively. */ Modified: trunk/jython/src/org/python/core/PyFunction.java =================================================================== --- trunk/jython/src/org/python/core/PyFunction.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyFunction.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -11,7 +11,7 @@ /** * A Python function. */ -@ExposedType(name = "function", isBaseType = false) +@ExposedType(name = "function", isBaseType = false, doc = BuiltinDocs.function_doc) public class PyFunction extends PyObject { public static final PyType TYPE = PyType.fromClass(PyFunction.class); Modified: trunk/jython/src/org/python/core/PyInteger.java =================================================================== --- trunk/jython/src/org/python/core/PyInteger.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyInteger.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -12,7 +12,7 @@ /** * A builtin python int. */ -@ExposedType(name = "int") +@ExposedType(name = "int", doc = BuiltinDocs.int_doc) public class PyInteger extends PyObject { public static final PyType TYPE = PyType.fromClass(PyInteger.class); Modified: trunk/jython/src/org/python/core/PyList.java =================================================================== --- trunk/jython/src/org/python/core/PyList.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyList.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -19,7 +19,7 @@ import java.lang.reflect.Array; -@ExposedType(name = "list", base = PyObject.class) +@ExposedType(name = "list", base = PyObject.class, doc = BuiltinDocs.list_doc) public class PyList extends PySequenceList implements List { public static final PyType TYPE = PyType.fromClass(PyList.class); Modified: trunk/jython/src/org/python/core/PyLong.java =================================================================== --- trunk/jython/src/org/python/core/PyLong.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyLong.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -14,7 +14,7 @@ * A builtin python long. This is implemented as a * java.math.BigInteger. */ -@ExposedType(name = "long") +@ExposedType(name = "long", doc = BuiltinDocs.long_doc) public class PyLong extends PyObject { public static final PyType TYPE = PyType.fromClass(PyLong.class); Modified: trunk/jython/src/org/python/core/PyMethod.java =================================================================== --- trunk/jython/src/org/python/core/PyMethod.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyMethod.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -10,21 +10,21 @@ /** * A Python method. */ -@ExposedType(name = "instancemethod", isBaseType = false) +@ExposedType(name = "instancemethod", isBaseType = false, doc = BuiltinDocs.instancemethod_doc) public class PyMethod extends PyObject { public static final PyType TYPE = PyType.fromClass(PyMethod.class); /** The class associated with a method. */ - @ExposedGet + @ExposedGet(doc = BuiltinDocs.instancemethod_im_class_doc) public PyObject im_class; /** The function (or other callable) implementing a method. */ - @ExposedGet + @ExposedGet(doc = BuiltinDocs.instancemethod_im_func_doc) public PyObject im_func; /** The instance to which a method is bound; None for unbound methods. */ - @ExposedGet + @ExposedGet(doc = BuiltinDocs.instancemethod_im_self_doc) public PyObject im_self; public PyMethod(PyObject function, PyObject self, PyObject type) { Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyObject.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -20,7 +20,7 @@ * All objects known to the Jython runtime system are represented by an instance * of the class <code>PyObject</code> or one of its subclasses. */ -@ExposedType(name = "object") +@ExposedType(name = "object", doc = BuiltinDocs.object_doc) public class PyObject implements Serializable { public static final PyType TYPE = PyType.fromClass(PyObject.class); Modified: trunk/jython/src/org/python/core/PyProperty.java =================================================================== --- trunk/jython/src/org/python/core/PyProperty.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyProperty.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -3,21 +3,20 @@ import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; -import org.python.expose.ExposedSet; import org.python.expose.ExposedType; -@ExposedType(name = "property") +@ExposedType(name = "property", doc = BuiltinDocs.property_doc) public class PyProperty extends PyObject { public static final PyType TYPE = PyType.fromClass(PyProperty.class); - @ExposedGet + @ExposedGet(doc = BuiltinDocs.property_fget_doc) protected PyObject fget; - @ExposedGet + @ExposedGet(doc = BuiltinDocs.property_fset_doc) protected PyObject fset; - @ExposedGet + @ExposedGet(doc = BuiltinDocs.property_fdel_doc) protected PyObject fdel; @ExposedGet(name = "__doc__") Modified: trunk/jython/src/org/python/core/PySlice.java =================================================================== --- trunk/jython/src/org/python/core/PySlice.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PySlice.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -9,18 +9,18 @@ /** * The Python slice object. */ -@ExposedType(name = "slice", isBaseType = false) +@ExposedType(name = "slice", isBaseType = false, doc = BuiltinDocs.slice_doc) public class PySlice extends PyObject { public static final PyType TYPE = PyType.fromClass(PySlice.class); - @ExposedGet + @ExposedGet(doc = BuiltinDocs.slice_start_doc) public PyObject start = Py.None; - @ExposedGet + @ExposedGet(doc = BuiltinDocs.slice_stop_doc) public PyObject stop = Py.None; - @ExposedGet + @ExposedGet(doc = BuiltinDocs.slice_step_doc) public PyObject step = Py.None; public PySlice() { Modified: trunk/jython/src/org/python/core/PyStaticMethod.java =================================================================== --- trunk/jython/src/org/python/core/PyStaticMethod.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyStaticMethod.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -7,7 +7,7 @@ /** * The staticmethod descriptor. */ -@ExposedType(name = "staticmethod") +@ExposedType(name = "staticmethod", doc = BuiltinDocs.staticmethod_doc) public class PyStaticMethod extends PyObject { public static final PyType TYPE = PyType.fromClass(PyStaticMethod.class); Modified: trunk/jython/src/org/python/core/PyString.java =================================================================== --- trunk/jython/src/org/python/core/PyString.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyString.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -13,7 +13,7 @@ /** * A builtin python string. */ -@ExposedType(name = "str") +@ExposedType(name = "str", doc = BuiltinDocs.str_doc) public class PyString extends PyBaseString { public static final PyType TYPE = PyType.fromClass(PyString.class); Modified: trunk/jython/src/org/python/core/PySuper.java =================================================================== --- trunk/jython/src/org/python/core/PySuper.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PySuper.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -9,18 +9,18 @@ /** * The Python super type. */ -@ExposedType(name = "super") +@ExposedType(name = "super", doc = BuiltinDocs.super_doc) public class PySuper extends PyObject { public static final PyType TYPE = PyType.fromClass(PySuper.class); - @ExposedGet(name = "__thisclass__") + @ExposedGet(name = "__thisclass__", doc = BuiltinDocs.super___thisclass___doc) protected PyType superType; - @ExposedGet(name = "__self__") + @ExposedGet(name = "__self__", doc = BuiltinDocs.super___self___doc) protected PyObject obj; - @ExposedGet(name = "__self_class__") + @ExposedGet(name = "__self_class__", doc = BuiltinDocs.super___self_class___doc) protected PyType objType; public PySuper() { Modified: trunk/jython/src/org/python/core/PyTuple.java =================================================================== --- trunk/jython/src/org/python/core/PyTuple.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyTuple.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -17,7 +17,7 @@ /** * A builtin python tuple. */ -@ExposedType(name = "tuple", base = PyObject.class) +@ExposedType(name = "tuple", base = PyObject.class, doc = BuiltinDocs.tuple_doc) public class PyTuple extends PySequenceList implements List { public static final PyType TYPE = PyType.fromClass(PyTuple.class); Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyType.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -25,7 +25,7 @@ /** * The Python Type object implementation. */ -@ExposedType(name = "type") +@ExposedType(name = "type", doc = BuiltinDocs.type_doc) public class PyType extends PyObject implements Serializable { public static PyType TYPE = fromClass(PyType.class); @@ -640,7 +640,6 @@ bases = cleanedBases.toArray(new PyObject[cleanedBases.size()]); } - //XXX: needs __doc__ @ExposedGet(name = "__base__") public PyObject getBase() { if (base == null) @@ -648,7 +647,6 @@ return base; } - //XXX: needs __doc__ @ExposedGet(name = "__bases__") public PyObject getBases() { return new PyTuple(bases); Modified: trunk/jython/src/org/python/core/PyUnicode.java =================================================================== --- trunk/jython/src/org/python/core/PyUnicode.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyUnicode.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -17,7 +17,7 @@ /** * a builtin python unicode string. */ -@ExposedType(name = "unicode", base = PyBaseString.class) +@ExposedType(name = "unicode", base = PyBaseString.class, doc = BuiltinDocs.unicode_doc) public class PyUnicode extends PyString implements Iterable { private enum Plane { Modified: trunk/jython/src/org/python/core/PyXRange.java =================================================================== --- trunk/jython/src/org/python/core/PyXRange.java 2009-10-14 03:19:24 UTC (rev 6855) +++ trunk/jython/src/org/python/core/PyXRange.java 2009-10-14 06:02:01 UTC (rev 6856) @@ -8,7 +8,8 @@ /** * The builtin xrange type. */ -@ExposedType(name = "xrange", base = PyObject.class, isBaseType = false) +@ExposedType(name = "xrange", base = PyObject.class, isBaseType = false, + doc = BuiltinDocs.xrange_doc) public class PyXRange extends PySequence { public static final PyType TYPE = PyType.fromClass(PyXRange.class); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-10-15 17:40:30
|
Revision: 6859 http://jython.svn.sourceforge.net/jython/?rev=6859&view=rev Author: amak Date: 2009-10-15 17:40:22 +0000 (Thu, 15 Oct 2009) Log Message: ----------- Checking in support for loading site-packages, through the use of imp.load("site"). Controlled with a "load_site_packages" option, which defaults to true. Modified Paths: -------------- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java trunk/jython/tests/modjy/test_apps_dir/lifecycle_tests.py Added Paths: ----------- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestInterpreterLifecycle.java Removed Paths: ------------- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java Modified: trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java =================================================================== --- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-10-14 06:54:56 UTC (rev 6858) +++ trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-10-15 17:40:22 UTC (rev 6859) @@ -33,6 +33,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.python.core.imp; import org.python.core.Py; import org.python.core.PyException; import org.python.core.PyObject; @@ -49,6 +50,8 @@ protected final static String PTH_FILE_EXTENSION = ".pth"; + protected final static String LOAD_SITE_PACKAGES_PARAM = "load_site_packages"; + protected PythonInterpreter interp; protected HttpServlet modjyServlet; @@ -140,7 +143,7 @@ * sys.path 2. Process the WEB-INF/lib-python directory, if it exists * * @param interp - * - The PythinInterpreter used to service requests + * - The PythonInterpreter used to service requests * @param props * - The properties from which config options are found * @param systemState @@ -148,11 +151,27 @@ */ protected void setupEnvironment(PythonInterpreter interp, Properties props, - PySystemState systemState) { + PySystemState systemState) throws PyException { + checkSitePackages(props); processPythonLib(interp, systemState); } /** + * Check if the user has requested to initialise the jython installation "site-packages". + * + * @param props + * - The properties from which config options are found + */ + protected void checkSitePackages(Properties props) throws PyException { + String loadSitePackagesParam = props.getProperty(LOAD_SITE_PACKAGES_PARAM); + boolean loadSitePackages = true; + if (loadSitePackagesParam != null && loadSitePackagesParam.trim().compareTo("0") == 0) + loadSitePackages = false; + if (loadSitePackages) + imp.load("site"); + } + + /** * Do all processing in relation to the lib-python subdirectory of WEB-INF * * @param interp Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-10-14 06:54:56 UTC (rev 6858) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-10-15 17:40:22 UTC (rev 6859) @@ -238,7 +238,7 @@ suite.addTestSuite(ModjyTestHeaders.class); suite.addTestSuite(ModjyTestContentHeaders.class); suite.addTestSuite(ModjyTestReturnIterable.class); - suite.addTestSuite(ModjyTestServletLifecycle.class); + suite.addTestSuite(ModjyTestInterpreterLifecycle.class); suite.addTestSuite(ModjyTestWebInf.class); suite.addTestSuite(ModjyTestWSGIStreams.class); suite.addTestSuite(PyServletTest.class); Copied: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestInterpreterLifecycle.java (from rev 6842, trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java) =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestInterpreterLifecycle.java (rev 0) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestInterpreterLifecycle.java 2009-10-15 17:40:22 UTC (rev 6859) @@ -0,0 +1,62 @@ +/*### +# +# 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 javax.servlet.http.HttpServlet; + +public class ModjyTestInterpreterLifecycle extends ModjyTestBase { + + protected void lifecycleTestSetUp() throws Exception { + baseSetUp(); + setAppFile("lifecycle_tests.py"); + } + + public void testAtExitHandlersCalled() throws Exception { + System.setProperty("modjy", "here"); + lifecycleTestSetUp(); + createServlet(); + doGet(); + HttpServlet modjyServlet = getServlet(); + modjyServlet.destroy(); + assertEquals("gone", System.getProperty("modjy")); + } + + public void testSitePackagesLoaded() throws Exception { + for (int loadSitePackages = -1 ; loadSitePackages < 2 ; loadSitePackages++) { + lifecycleTestSetUp(); + setAppName("load_site_packages_test"); + String parameter, expectedResult; + if (loadSitePackages != -1) { + parameter = Integer.toString(loadSitePackages); + setInitParameter("load_site_packages", parameter); + expectedResult = parameter; + } else { + // Do not set the parameter, so we get default behaviour + expectedResult = "1"; + } + createServlet(); + doGet(); + String result = getOutput(); + assertEquals(expectedResult, result); + } + } + +} Property changes on: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestInterpreterLifecycle.java ___________________________________________________________________ Added: svn:mergeinfo + /branches/jsr223/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java:6285-6565 /branches/newstyle-java-types/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java:5564-5663,5666-5729 Deleted: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java 2009-10-14 06:54:56 UTC (rev 6858) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestServletLifecycle.java 2009-10-15 17:40:22 UTC (rev 6859) @@ -1,42 +0,0 @@ -/*### -# -# 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 javax.servlet.http.HttpServlet; - -public class ModjyTestServletLifecycle extends ModjyTestBase { - - protected void lifecycleTestSetUp() throws Exception { - baseSetUp(); - setAppFile("lifecycle_tests.py"); - } - - public void testAtExitHandlersCalled() throws Exception { - System.setProperty("modjy", "here"); - lifecycleTestSetUp(); - createServlet(); - doGet(); - HttpServlet modjyServlet = getServlet(); - modjyServlet.destroy(); - assertEquals("gone", System.getProperty("modjy")); - } - -} Modified: trunk/jython/tests/modjy/test_apps_dir/lifecycle_tests.py =================================================================== --- trunk/jython/tests/modjy/test_apps_dir/lifecycle_tests.py 2009-10-14 06:54:56 UTC (rev 6858) +++ trunk/jython/tests/modjy/test_apps_dir/lifecycle_tests.py 2009-10-15 17:40:22 UTC (rev 6859) @@ -29,6 +29,11 @@ atexit.register(exit_func) def lifecycle_test(environ, start_response): - writer = start_response("200 OK", []) - writer("Hello World!") - return [] + start_response("200 OK", []) + return ["Hello World!"] + +def load_site_packages_test(environ, start_response): + import sys + start_response("200 OK", []) + response = {True: '1', False: '0'}[sys.modules.has_key('site')] + return [response] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2009-10-15 19:34:42
|
Revision: 6860 http://jython.svn.sourceforge.net/jython/?rev=6860&view=rev Author: otmarhumbel Date: 2009-10-15 19:34:31 +0000 (Thu, 15 Oct 2009) Log Message: ----------- fixed javadoc warnings Modified Paths: -------------- trunk/jython/build.xml trunk/jython/src/org/python/modules/cPickle.java trunk/jython/src/org/python/modules/cStringIO.java trunk/jython/src/org/python/modules/itertools.java Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-10-15 17:40:22 UTC (rev 6859) +++ trunk/jython/build.xml 2009-10-15 19:34:31 UTC (rev 6860) @@ -640,6 +640,7 @@ <target name="javadoc" depends="compile"> <path id="javadoc.classpath"> <pathelement path="${java.class.path}" /> + <pathelement path="${compile.dir}" /> <path refid="main.classpath" /> </path> <javadoc sourcepath="${source.dir}" Modified: trunk/jython/src/org/python/modules/cPickle.java =================================================================== --- trunk/jython/src/org/python/modules/cPickle.java 2009-10-15 17:40:22 UTC (rev 6859) +++ trunk/jython/src/org/python/modules/cPickle.java 2009-10-15 19:34:31 UTC (rev 6860) @@ -548,7 +548,7 @@ * @param file a file-like object, can be a cStringIO.StringIO, * a PyFile or any python object which implements a * <i>write</i> method. The data will be written as text. - * @returns a new Pickler instance. + * @return a new Pickler instance. */ public static Pickler Pickler(PyObject file) { return new Pickler(file, 0); @@ -560,7 +560,7 @@ * a PyFile or any python object which implements a * <i>write</i> method. * @param protocol pickle protocol version (0 - text, 1 - pre-2.3 binary, 2 - 2.3) - * @returns a new Pickler instance. + * @return a new Pickler instance. */ public static Pickler Pickler(PyObject file, int protocol) { return new Pickler(file, protocol); @@ -572,7 +572,7 @@ * @param file a file-like object, can be a cStringIO.StringIO, * a PyFile or any python object which implements a * <i>read</i> and <i>readline</i> method. - * @returns a new Unpickler instance. + * @return a new Unpickler instance. */ public static Unpickler Unpickler(PyObject file) { return new Unpickler(file); @@ -586,7 +586,6 @@ * a PyFile or any python object which implements a * <i>write</i> method. The data will be written as * text. - * @returns a new Unpickler instance. */ public static void dump(PyObject object, PyObject file) { dump(object, file, 0); @@ -599,7 +598,6 @@ * a PyFile or any python object which implements a * <i>write</i> method. * @param protocol pickle protocol version (0 - text, 1 - pre-2.3 binary, 2 - 2.3) - * @returns a new Unpickler instance. */ public static void dump(PyObject object, PyObject file, int protocol) { new Pickler(file, protocol).dump(object); @@ -609,7 +607,7 @@ /** * Shorthand function which pickles and returns the string representation. * @param object a data object which should be pickled. - * @returns a string representing the pickled object. + * @return a string representing the pickled object. */ public static PyString dumps(PyObject object) { return dumps(object, 0); @@ -620,7 +618,7 @@ * Shorthand function which pickles and returns the string representation. * @param object a data object which should be pickled. * @param protocol pickle protocol version (0 - text, 1 - pre-2.3 binary, 2 - 2.3) - * @returns a string representing the pickled object. + * @return a string representing the pickled object. */ public static PyString dumps(PyObject object, int protocol) { cStringIO.StringIO file = cStringIO.StringIO(); @@ -635,7 +633,7 @@ * @param file a file-like object, can be a cStringIO.StringIO, * a PyFile or any python object which implements a * <i>read</i> and <i>readline</i> method. - * @returns a new object. + * @return a new object. */ public static Object load(PyObject file) { return new Unpickler(file).load(); @@ -647,7 +645,7 @@ * returns the new object. * @param str a strings which must contain a pickled object * representation. - * @returns a new object. + * @return a new object. */ public static Object loads(PyObject str) { cStringIO.StringIO file = cStringIO.StringIO(str.toString()); Modified: trunk/jython/src/org/python/modules/cStringIO.java =================================================================== --- trunk/jython/src/org/python/modules/cStringIO.java 2009-10-15 17:40:22 UTC (rev 6859) +++ trunk/jython/src/org/python/modules/cStringIO.java 2009-10-15 19:34:31 UTC (rev 6860) @@ -26,10 +26,6 @@ * @version cStringIO.java,v 1.10 1999/05/20 18:03:20 fb Exp */ public class cStringIO { - /** - * Create an empty StringIO object - * @return a new StringIO object. - */ // would be nicer if we directly imported from os, but crazy to do so // since in python code itself @@ -48,7 +44,7 @@ /** * Create a StringIO object, initialized by the value. - * @param buf The initial value. + * @param buffer The initial value. * @return a new StringIO object. */ public static StringIO StringIO(String buffer) { @@ -134,8 +130,11 @@ /** * Position the file pointer to the position in the . - * @param pos the position in the file. - * @param mode; 0=from the start, 1=relative, 2=from the end. + * + * @param pos + * the position in the file. + * @param mode + * 0=from the start, 1=relative, 2=from the end. */ public synchronized void seek(long pos, int mode) { _complain_ifclosed(); @@ -162,7 +161,7 @@ /** * Return the file position. - * @returns the position in the file. + * @return the position in the file. */ public synchronized int tell() { _complain_ifclosed(); @@ -174,7 +173,7 @@ /** * Read all data until EOF is reached. * An empty string is returned when EOF is encountered immediately. - * @returns A string containing the data. + * @return A string containing the data. */ public PyString read() { return read(-1); @@ -187,7 +186,7 @@ * reached. An empty string is returned when EOF is encountered * immediately. * @param size the number of characters to read. - * @returns A string containing the data read. + * @return A string containing the data read. */ public synchronized PyString read(long size) { @@ -212,7 +211,7 @@ * is kept in the string (but may be absent when a file ends with * an incomplete line). * An empty string is returned when EOF is hit immediately. - * @returns data from the file up to and including the newline. + * @return data from the file up to and including the newline. */ public PyString readline() { return readline(-1); @@ -226,7 +225,7 @@ * If the size argument is non-negative, it is a maximum byte count * (including the trailing newline) and an incomplete line may be * returned. - * @returns data from the file up to and including the newline. + * @return data from the file up to and including the newline. */ public synchronized PyString readline(long size) { _complain_ifclosed(); @@ -317,7 +316,7 @@ /** * Write a string to the file. - * @param s The data to write. + * @param obj The data to write. */ public void write(PyObject obj) { write(obj.toString()); Modified: trunk/jython/src/org/python/modules/itertools.java =================================================================== --- trunk/jython/src/org/python/modules/itertools.java 2009-10-15 17:40:22 UTC (rev 6859) +++ trunk/jython/src/org/python/modules/itertools.java 2009-10-15 19:34:31 UTC (rev 6860) @@ -354,16 +354,14 @@ } /** - * @see islice(PyObject PyObject iterable, PyObject startObj, PyObject - * stopObj, PyObject stepObj) startObj defaults to 0 and stepObj to 1 + * @see #islice(PyObject, PyObject, PyObject, PyObject) startObj defaults to 0 and stepObj to 1 */ public static PyIterator islice(PyObject iterable, PyObject stopObj) { return islice(iterable, new PyInteger(0), stopObj, new PyInteger(1)); } /** - * @see islice(PyObject PyObject iterable, PyObject startObj, PyObject stopObj, PyObject - * stepObj) stepObj defaults to 1 + * @see #islice(PyObject, PyObject, PyObject, PyObject) stepObj defaults to 1 */ public static PyIterator islice(PyObject iterable, PyObject start, PyObject stopObj) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-16 02:39:29
|
Revision: 6861 http://jython.svn.sourceforge.net/jython/?rev=6861&view=rev Author: pjenvey Date: 2009-10-16 02:39:10 +0000 (Fri, 16 Oct 2009) Log Message: ----------- doc sets and BaseException Modified Paths: -------------- trunk/jython/Misc/make_pydocs.py trunk/jython/src/org/python/core/BuiltinDocs.java trunk/jython/src/org/python/core/PyBaseException.java trunk/jython/src/org/python/core/PyFrozenSet.java trunk/jython/src/org/python/core/PySet.java trunk/jython/src/org/python/core/exceptions.java Modified: trunk/jython/Misc/make_pydocs.py =================================================================== --- trunk/jython/Misc/make_pydocs.py 2009-10-15 19:34:31 UTC (rev 6860) +++ trunk/jython/Misc/make_pydocs.py 2009-10-16 02:39:10 UTC (rev 6861) @@ -53,6 +53,9 @@ complex, opt('bool'), classmethod, +set, +frozenset, +BaseException, #buffer, # + type(f), @@ -60,7 +63,6 @@ type(f.func_code), type(sys._getframe()), type(tb), -#type(slice), ] outfile = open("BuiltinDocs.java", "w") @@ -75,5 +77,3 @@ print_doc(outfile, obj, meth) print >> outfile, '}' - - Modified: trunk/jython/src/org/python/core/BuiltinDocs.java =================================================================== --- trunk/jython/src/org/python/core/BuiltinDocs.java 2009-10-15 19:34:31 UTC (rev 6860) +++ trunk/jython/src/org/python/core/BuiltinDocs.java 2009-10-16 02:39:10 UTC (rev 6861) @@ -2658,6 +2658,355 @@ public final static String classmethod___str___doc = "x.__str__() <==> str(x)"; + // Docs for <type 'set'> + public final static String set___and___doc = + "x.__and__(y) <==> x&y"; + + public final static String set___class___doc = + "type(object) -> the object's type\n" + + "type(name, bases, dict) -> a new type"; + + public final static String set___cmp___doc = + "x.__cmp__(y) <==> cmp(x,y)"; + + public final static String set___contains___doc = + "x.__contains__(y) <==> y in x."; + + public final static String set___delattr___doc = + "x.__delattr__('name') <==> del x.name"; + + public final static String set_doc = + "set(iterable) --> set object\n" + + "\n" + + "Build an unordered collection of unique elements."; + + public final static String set___eq___doc = + "x.__eq__(y) <==> x==y"; + + public final static String set___ge___doc = + "x.__ge__(y) <==> x>=y"; + + public final static String set___getattribute___doc = + "x.__getattribute__('name') <==> x.name"; + + public final static String set___gt___doc = + "x.__gt__(y) <==> x>y"; + + public final static String set___hash___doc = + "x.__hash__() <==> hash(x)"; + + public final static String set___iand___doc = + "x.__iand__(y) <==> x&y"; + + public final static String set___init___doc = + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature"; + + public final static String set___ior___doc = + "x.__ior__(y) <==> x|y"; + + public final static String set___isub___doc = + "x.__isub__(y) <==> x-y"; + + public final static String set___iter___doc = + "x.__iter__() <==> iter(x)"; + + public final static String set___ixor___doc = + "x.__ixor__(y) <==> x^y"; + + public final static String set___le___doc = + "x.__le__(y) <==> x<=y"; + + public final static String set___len___doc = + "x.__len__() <==> len(x)"; + + public final static String set___lt___doc = + "x.__lt__(y) <==> x<y"; + + public final static String set___ne___doc = + "x.__ne__(y) <==> x!=y"; + + public final static String set___new___doc = + "T.__new__(S, ...) -> a new object with type S, a subtype of T"; + + public final static String set___or___doc = + "x.__or__(y) <==> x|y"; + + public final static String set___rand___doc = + "x.__rand__(y) <==> y&x"; + + public final static String set___reduce___doc = + "Return state information for pickling."; + + public final static String set___reduce_ex___doc = + "helper for pickle"; + + public final static String set___repr___doc = + "x.__repr__() <==> repr(x)"; + + public final static String set___ror___doc = + "x.__ror__(y) <==> y|x"; + + public final static String set___rsub___doc = + "x.__rsub__(y) <==> y-x"; + + public final static String set___rxor___doc = + "x.__rxor__(y) <==> y^x"; + + public final static String set___setattr___doc = + "x.__setattr__('name', value) <==> x.name = value"; + + public final static String set___str___doc = + "x.__str__() <==> str(x)"; + + public final static String set___sub___doc = + "x.__sub__(y) <==> x-y"; + + public final static String set___xor___doc = + "x.__xor__(y) <==> x^y"; + + public final static String set_add_doc = + "Add an element to a set.\n" + + "\n" + + "This has no effect if the element is already present."; + + public final static String set_clear_doc = + "Remove all elements from this set."; + + public final static String set_copy_doc = + "Return a shallow copy of a set."; + + public final static String set_difference_doc = + "Return the difference of two sets as a new set.\n" + + "\n" + + "(i.e. all elements that are in this set but not the other.)"; + + public final static String set_difference_update_doc = + "Remove all elements of another set from this set."; + + public final static String set_discard_doc = + "Remove an element from a set if it is a member.\n" + + "\n" + + "If the element is not a member, do nothing."; + + public final static String set_intersection_doc = + "Return the intersection of two sets as a new set.\n" + + "\n" + + "(i.e. all elements that are in both sets.)"; + + public final static String set_intersection_update_doc = + "Update a set with the intersection of itself and another."; + + public final static String set_issubset_doc = + "Report whether another set contains this set."; + + public final static String set_issuperset_doc = + "Report whether this set contains another set."; + + public final static String set_pop_doc = + "Remove and return an arbitrary set element."; + + public final static String set_remove_doc = + "Remove an element from a set; it must be a member.\n" + + "\n" + + "If the element is not a member, raise a KeyError."; + + public final static String set_symmetric_difference_doc = + "Return the symmetric difference of two sets as a new set.\n" + + "\n" + + "(i.e. all elements that are in exactly one of the sets.)"; + + public final static String set_symmetric_difference_update_doc = + "Update a set with the symmetric difference of itself and another."; + + public final static String set_union_doc = + "Return the union of two sets as a new set.\n" + + "\n" + + "(i.e. all elements that are in either set.)"; + + public final static String set_update_doc = + "Update a set with the union of itself and another."; + + // Docs for <type 'frozenset'> + public final static String frozenset___and___doc = + "x.__and__(y) <==> x&y"; + + public final static String frozenset___class___doc = + "type(object) -> the object's type\n" + + "type(name, bases, dict) -> a new type"; + + public final static String frozenset___cmp___doc = + "x.__cmp__(y) <==> cmp(x,y)"; + + public final static String frozenset___contains___doc = + "x.__contains__(y) <==> y in x."; + + public final static String frozenset___delattr___doc = + "x.__delattr__('name') <==> del x.name"; + + public final static String frozenset_doc = + "frozenset(iterable) --> frozenset object\n" + + "\n" + + "Build an immutable unordered collection of unique elements."; + + public final static String frozenset___eq___doc = + "x.__eq__(y) <==> x==y"; + + public final static String frozenset___ge___doc = + "x.__ge__(y) <==> x>=y"; + + public final static String frozenset___getattribute___doc = + "x.__getattribute__('name') <==> x.name"; + + public final static String frozenset___gt___doc = + "x.__gt__(y) <==> x>y"; + + public final static String frozenset___hash___doc = + "x.__hash__() <==> hash(x)"; + + public final static String frozenset___init___doc = + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature"; + + public final static String frozenset___iter___doc = + "x.__iter__() <==> iter(x)"; + + public final static String frozenset___le___doc = + "x.__le__(y) <==> x<=y"; + + public final static String frozenset___len___doc = + "x.__len__() <==> len(x)"; + + public final static String frozenset___lt___doc = + "x.__lt__(y) <==> x<y"; + + public final static String frozenset___ne___doc = + "x.__ne__(y) <==> x!=y"; + + public final static String frozenset___new___doc = + "T.__new__(S, ...) -> a new object with type S, a subtype of T"; + + public final static String frozenset___or___doc = + "x.__or__(y) <==> x|y"; + + public final static String frozenset___rand___doc = + "x.__rand__(y) <==> y&x"; + + public final static String frozenset___reduce___doc = + "Return state information for pickling."; + + public final static String frozenset___reduce_ex___doc = + "helper for pickle"; + + public final static String frozenset___repr___doc = + "x.__repr__() <==> repr(x)"; + + public final static String frozenset___ror___doc = + "x.__ror__(y) <==> y|x"; + + public final static String frozenset___rsub___doc = + "x.__rsub__(y) <==> y-x"; + + public final static String frozenset___rxor___doc = + "x.__rxor__(y) <==> y^x"; + + public final static String frozenset___setattr___doc = + "x.__setattr__('name', value) <==> x.name = value"; + + public final static String frozenset___str___doc = + "x.__str__() <==> str(x)"; + + public final static String frozenset___sub___doc = + "x.__sub__(y) <==> x-y"; + + public final static String frozenset___xor___doc = + "x.__xor__(y) <==> x^y"; + + public final static String frozenset_copy_doc = + "Return a shallow copy of a set."; + + public final static String frozenset_difference_doc = + "Return the difference of two sets as a new set.\n" + + "\n" + + "(i.e. all elements that are in this set but not the other.)"; + + public final static String frozenset_intersection_doc = + "Return the intersection of two sets as a new set.\n" + + "\n" + + "(i.e. all elements that are in both sets.)"; + + public final static String frozenset_issubset_doc = + "Report whether another set contains this set."; + + public final static String frozenset_issuperset_doc = + "Report whether this set contains another set."; + + public final static String frozenset_symmetric_difference_doc = + "Return the symmetric difference of two sets as a new set.\n" + + "\n" + + "(i.e. all elements that are in exactly one of the sets.)"; + + public final static String frozenset_union_doc = + "Return the union of two sets as a new set.\n" + + "\n" + + "(i.e. all elements that are in either set.)"; + + // Docs for <type 'exceptions.BaseException'> + public final static String BaseException___class___doc = + "type(object) -> the object's type\n" + + "type(name, bases, dict) -> a new type"; + + public final static String BaseException___delattr___doc = + "x.__delattr__('name') <==> del x.name"; + + public final static String BaseException___dict___doc = + ""; + + public final static String BaseException_doc = + "Common base class for all exceptions"; + + public final static String BaseException___getattribute___doc = + "x.__getattribute__('name') <==> x.name"; + + public final static String BaseException___getitem___doc = + "x.__getitem__(y) <==> x[y]"; + + public final static String BaseException___getslice___doc = + "x.__getslice__(i, j) <==> x[i:j]\n" + + " \n" + + " Use of negative indices is not supported."; + + public final static String BaseException___hash___doc = + "x.__hash__() <==> hash(x)"; + + public final static String BaseException___init___doc = + "x.__init__(...) initializes x; see x.__class__.__doc__ for signature"; + + public final static String BaseException___new___doc = + "T.__new__(S, ...) -> a new object with type S, a subtype of T"; + + public final static String BaseException___reduce___doc = + ""; + + public final static String BaseException___reduce_ex___doc = + "helper for pickle"; + + public final static String BaseException___repr___doc = + "x.__repr__() <==> repr(x)"; + + public final static String BaseException___setattr___doc = + "x.__setattr__('name', value) <==> x.name = value"; + + public final static String BaseException___setstate___doc = + ""; + + public final static String BaseException___str___doc = + "x.__str__() <==> str(x)"; + + public final static String BaseException_args_doc = + ""; + + public final static String BaseException_message_doc = + "exception message"; + // Docs for <type 'function'> public final static String function___call___doc = "x.__call__(...) <==> x(...)"; Modified: trunk/jython/src/org/python/core/PyBaseException.java =================================================================== --- trunk/jython/src/org/python/core/PyBaseException.java 2009-10-15 19:34:31 UTC (rev 6860) +++ trunk/jython/src/org/python/core/PyBaseException.java 2009-10-16 02:39:10 UTC (rev 6861) @@ -12,18 +12,18 @@ * The base class for all standard Python exceptions. * */ -@ExposedType(name = "exceptions.BaseException") +@ExposedType(name = "exceptions.BaseException", doc = BuiltinDocs.BaseException_doc) public class PyBaseException extends PyObject { public static final PyType TYPE = PyType.fromClass(PyBaseException.class); /** Exception message. */ - @ExposedGet + @ExposedGet(doc = BuiltinDocs.BaseException_message_doc) @ExposedSet public PyObject message = Py.EmptyString; /** Exception's arguments. */ - @ExposedGet + @ExposedGet(doc = BuiltinDocs.BaseException_args_doc) public PyObject args = Py.EmptyTuple; /** Exception's underlying dictionary, lazily created. */ @@ -42,7 +42,7 @@ } @ExposedNew - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.BaseException___init___doc) final void BaseException___init__(PyObject[] args, String[] keywords) { ArgParser ap = new ArgParser(getType().getName(), args, keywords, "args"); ap.noKeywords(); @@ -56,7 +56,7 @@ return BaseException___getitem__(index); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.BaseException___getitem___doc) final PyObject BaseException___getitem__(PyObject index) { return args.__getitem__(index); } @@ -65,7 +65,7 @@ return BaseException___getslice__(start, stop); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.BaseException___getslice___doc) final PyObject BaseException___getslice__(PyObject start, PyObject stop) { return args.__getslice__(start, stop); } @@ -75,7 +75,7 @@ return BaseException___reduce__(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.BaseException___reduce___doc) final PyObject BaseException___reduce__() { if (__dict__ != null) { return new PyTuple(getType(), args, __dict__); @@ -88,7 +88,7 @@ return BaseException___setstate__(state); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.BaseException___setstate___doc) final PyObject BaseException___setstate__(PyObject state) { if (state != Py.None) { if (!(state instanceof PyStringMap) && !(state instanceof PyDictionary)) { @@ -120,7 +120,7 @@ BaseException___setattr__(name, value); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.BaseException___setattr___doc) final void BaseException___setattr__(String name, PyObject value) { ensureDict(); super.__setattr__(name, value); @@ -130,7 +130,7 @@ return __dict__; } - @ExposedGet(name = "__dict__") + @ExposedGet(name = "__dict__", doc = BuiltinDocs.BaseException___dict___doc) public PyObject getDict() { ensureDict(); return __dict__; @@ -154,7 +154,7 @@ return BaseException___str__(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.BaseException___str___doc) final PyString BaseException___str__() { switch (args.__len__()) { case 0: @@ -171,7 +171,7 @@ return BaseException_toString(); } - @ExposedMethod(names = ("__repr__")) + @ExposedMethod(names = "__repr__", doc = BuiltinDocs.BaseException___repr___doc) final String BaseException_toString() { PyObject reprSuffix = args.__repr__(); String name = getType().fastGetName(); Modified: trunk/jython/src/org/python/core/PyFrozenSet.java =================================================================== --- trunk/jython/src/org/python/core/PyFrozenSet.java 2009-10-15 19:34:31 UTC (rev 6860) +++ trunk/jython/src/org/python/core/PyFrozenSet.java 2009-10-16 02:39:10 UTC (rev 6861) @@ -9,7 +9,7 @@ import org.python.expose.ExposedType; import org.python.expose.MethodType; -@ExposedType(name = "frozenset", base = PyObject.class) +@ExposedType(name = "frozenset", base = PyObject.class, doc = BuiltinDocs.frozenset_doc) public class PyFrozenSet extends BaseSet { public static final PyType TYPE = PyType.fromClass(PyFrozenSet.class); @@ -51,72 +51,72 @@ return fset; } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___cmp___doc) final PyObject frozenset___cmp__(PyObject o) { return new PyInteger(baseset___cmp__(o)); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___ne___doc) final PyObject frozenset___ne__(PyObject o) { return baseset___ne__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___eq___doc) final PyObject frozenset___eq__(PyObject o) { return baseset___eq__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___or___doc) final PyObject frozenset___or__(PyObject o) { return baseset___or__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___xor___doc) final PyObject frozenset___xor__(PyObject o) { return baseset___xor__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___sub___doc) final PyObject frozenset___sub__(PyObject o) { return baseset___sub__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___and___doc) final PyObject frozenset___and__(PyObject o) { return baseset___and__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___lt___doc) final PyObject frozenset___lt__(PyObject o) { return baseset___lt__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___gt___doc) final PyObject frozenset___gt__(PyObject o) { return baseset___gt__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___ge___doc) final PyObject frozenset___ge__(PyObject o) { return baseset___ge__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.frozenset___le___doc) final PyObject frozenset___le__(PyObject o) { return baseset___le__(o); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset___iter___doc) final PyObject frozenset___iter__() { return baseset___iter__(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset___contains___doc) final boolean frozenset___contains__(PyObject item) { return baseset___contains__(item); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset_copy_doc) final PyObject frozenset_copy() { if (getClass() == PyFrozenSet.class) { return this; @@ -125,52 +125,52 @@ return baseset_copy(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset_union_doc) final PyObject frozenset_union(PyObject set) { return baseset_union(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset_difference_doc) final PyObject frozenset_difference(PyObject set) { return baseset_difference(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset_symmetric_difference_doc) final PyObject frozenset_symmetric_difference(PyObject set) { return baseset_symmetric_difference(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset_intersection_doc) final PyObject frozenset_intersection(PyObject set) { return baseset_intersection(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset_issubset_doc) final PyObject frozenset_issubset(PyObject set) { return baseset_issubset(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset_issuperset_doc) final PyObject frozenset_issuperset(PyObject set) { return baseset_issuperset(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset___len___doc) final int frozenset___len__() { return baseset___len__(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset___reduce___doc) final PyObject frozenset___reduce__() { return baseset___reduce__(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.frozenset___hash___doc) final int frozenset___hash__() { return _set.hashCode(); } - @ExposedMethod(names = "__repr__") + @ExposedMethod(names = "__repr__", doc = BuiltinDocs.frozenset___repr___doc) final String frozenset_toString() { return baseset_toString(); } Modified: trunk/jython/src/org/python/core/PySet.java =================================================================== --- trunk/jython/src/org/python/core/PySet.java 2009-10-15 19:34:31 UTC (rev 6860) +++ trunk/jython/src/org/python/core/PySet.java 2009-10-16 02:39:10 UTC (rev 6861) @@ -10,7 +10,7 @@ import org.python.expose.MethodType; import org.python.util.Generic; -@ExposedType(name = "set", base = PyObject.class) +@ExposedType(name = "set", base = PyObject.class, doc = BuiltinDocs.set_doc) public class PySet extends BaseSet { public static final PyType TYPE = PyType.fromClass(PySet.class); @@ -33,7 +33,7 @@ } @ExposedNew - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set___init___doc) final void set___init__(PyObject[] args, String[] kwds) { int nargs = args.length - kwds.length; if (nargs > 1) { @@ -47,112 +47,112 @@ _update(args[0]); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___cmp___doc) final PyObject set___cmp__(PyObject o) { return new PyInteger(baseset___cmp__(o)); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___ne___doc) final PyObject set___ne__(PyObject o) { return baseset___ne__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___eq___doc) final PyObject set___eq__(PyObject o) { return baseset___eq__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___or___doc) final PyObject set___or__(PyObject o) { return baseset___or__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___xor___doc) final PyObject set___xor__(PyObject o) { return baseset___xor__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___sub___doc) final PyObject set___sub__(PyObject o) { return baseset___sub__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___and___doc) final PyObject set___and__(PyObject o) { return baseset___and__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___lt___doc) final PyObject set___lt__(PyObject o) { return baseset___lt__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___gt___doc) final PyObject set___gt__(PyObject o) { return baseset___gt__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___ge___doc) final PyObject set___ge__(PyObject o) { return baseset___ge__(o); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___le___doc) final PyObject set___le__(PyObject o) { return baseset___le__(o); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set___iter___doc) final PyObject set___iter__() { return baseset___iter__(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set___contains___doc) final boolean set___contains__(PyObject item) { return baseset___contains__(item); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_copy_doc) final PyObject set_copy() { return baseset_copy(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_union_doc) final PyObject set_union(PyObject set) { return baseset_union(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_difference_doc) final PyObject set_difference(PyObject set) { return baseset_difference(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_symmetric_difference_doc) final PyObject set_symmetric_difference(PyObject set) { return baseset_symmetric_difference(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_intersection_doc) final PyObject set_intersection(PyObject set) { return baseset_intersection(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_issubset_doc) final PyObject set_issubset(PyObject set) { return baseset_issubset(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_issuperset_doc) final PyObject set_issuperset(PyObject set) { return baseset_issuperset(set); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set___len___doc) final int set___len__() { return baseset___len__(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set___reduce___doc) final PyObject set___reduce__() { return baseset___reduce__(); } @@ -161,7 +161,7 @@ return set___ior__(other); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___ior___doc) final PyObject set___ior__(PyObject other) { if (!(other instanceof BaseSet)) { return null; @@ -174,7 +174,7 @@ return set___ixor__(other); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___ixor___doc) final PyObject set___ixor__(PyObject other) { if (!(other instanceof BaseSet)) { return null; @@ -187,7 +187,7 @@ return set___iand__(other); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___iand___doc) final PyObject set___iand__(PyObject other) { if (!(other instanceof BaseSet)) { return null; @@ -200,7 +200,7 @@ return set___isub__(other); } - @ExposedMethod(type = MethodType.BINARY) + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.set___isub___doc) final PyObject set___isub__(PyObject other) { if (!(other instanceof BaseSet)) { return null; @@ -213,17 +213,17 @@ return set___hash__(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set___hash___doc) final int set___hash__() { throw Py.TypeError("set objects are unhashable"); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_add_doc) final void set_add(PyObject o) { _set.add(o); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_remove_doc) final void set_remove(PyObject o) { boolean b = false; try { @@ -237,7 +237,7 @@ } } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_discard_doc) final void set_discard(PyObject o) { try { _set.remove(o); @@ -247,7 +247,7 @@ } } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_pop_doc) final PyObject set_pop() { Iterator iterator = _set.iterator(); try { @@ -259,17 +259,17 @@ } } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_clear_doc) final void set_clear() { _set.clear(); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_update_doc) final void set_update(PyObject data) { _update(data); } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_intersection_update_doc) final void set_intersection_update(PyObject other) { if (other instanceof BaseSet) { __iand__(other); @@ -279,7 +279,7 @@ } } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_symmetric_difference_update_doc) final void set_symmetric_difference_update(PyObject other) { if (this == other) { set_clear(); @@ -296,7 +296,7 @@ } } - @ExposedMethod + @ExposedMethod(doc = BuiltinDocs.set_difference_update_doc) final void set_difference_update(PyObject other) { if (other instanceof BaseSet) { __isub__(other); @@ -309,7 +309,7 @@ } } - @ExposedMethod(names = "__repr__") + @ExposedMethod(names = "__repr__", doc = BuiltinDocs.set___repr___doc) final String set_toString() { return baseset_toString(); } Modified: trunk/jython/src/org/python/core/exceptions.java =================================================================== --- trunk/jython/src/org/python/core/exceptions.java 2009-10-15 19:34:31 UTC (rev 6860) +++ trunk/jython/src/org/python/core/exceptions.java 2009-10-16 02:39:10 UTC (rev 6861) @@ -41,9 +41,6 @@ } ts.frame = frame; - // XXX: - PyObject baseExcDict = PyBaseException.TYPE.fastGetDict(); - baseExcDict.__setitem__("__doc__", Py.newString("Common base class for all exceptions")); dict.__setitem__("BaseException", PyBaseException.TYPE); buildClass(dict, "KeyboardInterrupt", "BaseException", "Program interrupted by user."); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-10-17 16:03:59
|
Revision: 6866 http://jython.svn.sourceforge.net/jython/?rev=6866&view=rev Author: amak Date: 2009-10-17 16:03:45 +0000 (Sat, 17 Oct 2009) Log Message: ----------- Fixing a previously unnoticed bug where a relative value for "python.home" was not being treated relative to the context root and should have been. Modified Paths: -------------- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java Modified: trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java =================================================================== --- trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-10-17 02:11:46 UTC (rev 6865) +++ trunk/jython/src/com/xhaus/modjy/ModjyJServlet.java 2009-10-17 16:03:45 UTC (rev 6866) @@ -52,6 +52,8 @@ protected final static String LOAD_SITE_PACKAGES_PARAM = "load_site_packages"; + protected final static String PYTHON_HOME_PARAM = "python.home"; + protected PythonInterpreter interp; protected HttpServlet modjyServlet; @@ -78,6 +80,14 @@ String name = (String)e.nextElement(); props.put(name, getInitParameter(name)); } + // Check if python home is relative, in which case find it in the servlet context + String pythonHomeString = props.getProperty(PYTHON_HOME_PARAM); + if (pythonHomeString != null) { + File pythonHome = new File(pythonHomeString); + if (!pythonHome.isAbsolute()) + pythonHomeString = context.getRealPath(pythonHomeString); + props.setProperty(PYTHON_HOME_PARAM, pythonHomeString); + } return props; } @@ -101,7 +111,7 @@ interp.exec("from modjy.modjy import " + MODJY_PYTHON_CLASSNAME); } catch (PyException ix) { throw new ServletException("Unable to import '" + MODJY_PYTHON_CLASSNAME - + "': maybe you need to set the 'python.home' parameter?", ix); + + "': maybe you need to set the '" + PYTHON_HOME_PARAM + "' parameter?", ix); } PyObject pyServlet = ((PyType)interp.get(MODJY_PYTHON_CLASSNAME)).__call__(); Object temp = pyServlet.__tojava__(HttpServlet.class); Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-10-17 02:11:46 UTC (rev 6865) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-10-17 16:03:45 UTC (rev 6866) @@ -195,13 +195,12 @@ String jythonHome = System.getProperty("JYTHON_HOME"); setRealPath(jythonHome, jythonHome); setRealPath("/WEB-INF/" + LIB_PYTHON_DIR, LIB_PYTHON_TEST_PATH); - setRealPath("/WEB-INF/lib/modjy.jar", "../modjy.jar"); setPythonHome(jythonHome); setAppDir(DEFAULT_APP_DIR); setAppFile(DEFAULT_APP_FILE); setAppName(DEFAULT_APP_NAME); setInitParameter("exc_handler", "testing"); -// dumpContextRealPaths(); +// dumpContextRealPaths(); } protected PyObject evalPythonString(String pyString) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-17 17:07:59
|
Revision: 6869 http://jython.svn.sourceforge.net/jython/?rev=6869&view=rev Author: pjenvey Date: 2009-10-17 17:07:38 +0000 (Sat, 17 Oct 2009) Log Message: ----------- expose PyFastSequenceIter and avoid PyType.fromClass during its construction Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/src/org/python/core/PyFastSequenceIter.java Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2009-10-17 16:57:13 UTC (rev 6868) +++ trunk/jython/CoreExposed.includes 2009-10-17 17:07:38 UTC (rev 6869) @@ -15,6 +15,7 @@ org/python/core/PyDictProxy.class org/python/core/PyEnumerate.class org/python/core/PyEllipsis.class +org/python/core/PyFastSequenceIter.class org/python/core/PyFile.class org/python/core/PyFloat.class org/python/core/PyFrame.class Modified: trunk/jython/src/org/python/core/PyFastSequenceIter.java =================================================================== --- trunk/jython/src/org/python/core/PyFastSequenceIter.java 2009-10-17 16:57:13 UTC (rev 6868) +++ trunk/jython/src/org/python/core/PyFastSequenceIter.java 2009-10-17 17:07:38 UTC (rev 6869) @@ -1,19 +1,32 @@ /* Copyright (c) Jython Developers */ package org.python.core; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedType; + /** * Sequence iterator specialized for accessing the underlying sequence directly. */ +@ExposedType(name = "fastsequenceiterator", base = PyObject.class, isBaseType = false) public class PyFastSequenceIter extends PyIterator { + public static final PyType TYPE = PyType.fromClass(PyFastSequenceIter.class); + private PySequence seq; - private int index = 0; + private int index; public PyFastSequenceIter(PySequence seq) { + super(TYPE); this.seq = seq; } + @ExposedMethod(doc = "x.next() -> the next value, or raise StopIteration") + final PyObject fastsequenceiterator_next() { + return super.next(); + } + + @Override public PyObject __iternext__() { if (seq == null) { return null; @@ -22,13 +35,14 @@ PyObject result; try { result = seq.seq___finditem__(index++); - } catch (PyException exc) { - if (exc.match(Py.StopIteration)) { + } catch (PyException pye) { + if (pye.match(Py.StopIteration)) { seq = null; return null; } - throw exc; + throw pye; } + if (result == null) { seq = null; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-19 21:26:28
|
Revision: 6872 http://jython.svn.sourceforge.net/jython/?rev=6872&view=rev Author: pjenvey Date: 2009-10-19 21:26:09 +0000 (Mon, 19 Oct 2009) Log Message: ----------- bring in constantine 0.6 release, for OpenFlags Modified Paths: -------------- trunk/jython/build.xml Added Paths: ----------- trunk/jython/extlibs/constantine.jar Removed Paths: ------------- trunk/jython/extlibs/constantine-0.4.jar Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-10-19 04:56:15 UTC (rev 6871) +++ trunk/jython/build.xml 2009-10-19 21:26:09 UTC (rev 6872) @@ -189,7 +189,7 @@ <pathelement path="${extlibs.dir}/asm-3.1.jar" /> <pathelement path="${extlibs.dir}/asm-commons-3.1.jar" /> - <pathelement path="${extlibs.dir}/constantine-0.4.jar" /> + <pathelement path="${extlibs.dir}/constantine.jar" /> <pathelement path="${extlibs.dir}/jna.jar"/> <pathelement path="${extlibs.dir}/jna-posix.jar"/> </path> @@ -573,7 +573,7 @@ <zipfileset src="extlibs/jna-posix.jar"/> <!-- <rule pattern="com.sun.jna.**" result="org.python.jna.@1"/> --> <rule pattern="org.jruby.ext.posix.**" result="org.python.posix.@1"/> - <zipfileset src="extlibs/constantine-0.4.jar"/> + <zipfileset src="extlibs/constantine.jar"/> <rule pattern="com.kenai.constantine.**" result="org.python.constantine.@1"/> <zipfileset src="extlibs/xercesImpl-2.9.1.jar" excludes="META-INF/services/*"/> <rule pattern="org.apache.xml.**" result="org.python.apache.xml.@1"/> Deleted: trunk/jython/extlibs/constantine-0.4.jar =================================================================== (Binary files differ) Added: trunk/jython/extlibs/constantine.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/constantine.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-19 22:02:54
|
Revision: 6874 http://jython.svn.sourceforge.net/jython/?rev=6874&view=rev Author: pjenvey Date: 2009-10-19 22:02:41 +0000 (Mon, 19 Oct 2009) Log Message: ----------- o pull posix bits out of os into their own module o further pull some of the slower to initialize bits out of posix into a Java _posix (_nt on Windows) module. this speeds up startup. eventually we should move more if not everything there o adapt 2.6's os.py: - hide exec* - we don't need to use set/get/putenv for the environ dict wrapper - our stat_result can be pickled, remove the copy_reg workaround - re-add some 2.5isms Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/Lib/grp.py trunk/jython/Lib/os.py trunk/jython/Lib/posix.py trunk/jython/Lib/pwd.py trunk/jython/Lib/select.py trunk/jython/Lib/subprocess.py trunk/jython/Lib/test/test_import_jy.py trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/io/FileIO.java trunk/jython/src/org/python/core/io/StreamIO.java trunk/jython/src/org/python/core/util/FileUtil.java trunk/jython/src/org/python/modules/Setup.java trunk/jython/src/org/python/util/jython.java Added Paths: ----------- trunk/jython/Lib/nt.py trunk/jython/src/org/python/modules/posix/ trunk/jython/src/org/python/modules/posix/OS.java trunk/jython/src/org/python/modules/posix/PosixModule.java trunk/jython/src/org/python/modules/posix/PyStatResult.java trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/CoreExposed.includes 2009-10-19 22:02:41 UTC (rev 6874) @@ -61,6 +61,7 @@ org/python/modules/_weakref/ReferenceType.class org/python/modules/operator$PyAttrGetter.class org/python/modules/operator$PyItemGetter.class +org/python/modules/posix/PyStatResult.class org/python/modules/random/PyRandom.class org/python/modules/thread/PyLocal.class org/python/modules/time/PyTimeTuple.class Modified: trunk/jython/Lib/grp.py =================================================================== --- trunk/jython/Lib/grp.py 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/Lib/grp.py 2009-10-19 22:02:41 UTC (rev 6874) @@ -17,7 +17,7 @@ __all__ = ['getgrgid', 'getgrnam', 'getgrall'] -from os import _name, _posix +from os import _name, _posix_impl if _name == 'nt': raise ImportError, 'grp module not supported on Windows' @@ -50,7 +50,7 @@ Return the group database entry for the given numeric group ID. If id is not valid, raise KeyError. """ - entry = _posix.getgrgid(uid) + entry = _posix_impl.getgrgid(uid) if not entry: raise KeyError(uid) return struct_group(entry) @@ -62,7 +62,7 @@ Return the group database entry for the given group name. If name is not valid, raise KeyError. """ - entry = _posix.getgrnam(name) + entry = _posix_impl.getgrnam(name) if not entry: raise KeyError(name) return struct_group(entry) @@ -76,7 +76,7 @@ """ groups = [] while True: - group = _posix.getgrent() + group = _posix_impl.getgrent() if not group: break groups.append(struct_group(group)) Added: trunk/jython/Lib/nt.py =================================================================== --- trunk/jython/Lib/nt.py (rev 0) +++ trunk/jython/Lib/nt.py 2009-10-19 22:02:41 UTC (rev 6874) @@ -0,0 +1,2 @@ +from posix import __all__ +from posix import * Modified: trunk/jython/Lib/os.py =================================================================== --- trunk/jython/Lib/os.py 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/Lib/os.py 2009-10-19 22:02:41 UTC (rev 6874) @@ -38,8 +38,9 @@ except AttributeError: return [n for n in dir(module) if n[0] != '_'] -if 'posix' in _names: - name = 'posix' +name = 'java' +if '_posix' in _names: + _name = 'posix' linesep = '\n' from posix import * try: @@ -52,8 +53,8 @@ __all__.extend(_get_exports_list(posix)) del posix -elif 'nt' in _names: - name = 'nt' +elif '_nt' in _names: + _name = 'nt' linesep = '\r\n' from nt import * try: @@ -66,8 +67,8 @@ __all__.extend(_get_exports_list(nt)) del nt -elif 'os2' in _names: - name = 'os2' +elif '_os2' in _names: + _name = 'os2' linesep = '\r\n' from os2 import * try: @@ -84,8 +85,8 @@ __all__.extend(_get_exports_list(os2)) del os2 -elif 'ce' in _names: - name = 'ce' +elif '_ce' in _names: + _name = 'ce' linesep = '\r\n' from ce import * try: @@ -99,8 +100,8 @@ __all__.extend(_get_exports_list(ce)) del ce -elif 'riscos' in _names: - name = 'riscos' +elif '_riscos' in _names: + _name = 'riscos' linesep = '\n' from riscos import * try: @@ -304,90 +305,97 @@ except NameError: environ = {} -def execl(file, *args): - """execl(file, *args) +def _exists(name): + # CPython eval's the name, whereas looking in __all__ works for + # Jython and is much faster + return name in __all__ - Execute the executable file with argument list args, replacing the - current process. """ - execv(file, args) +if _exists('execv'): -def execle(file, *args): - """execle(file, *args, env) + def execl(file, *args): + """execl(file, *args) - Execute the executable file with argument list args and - environment env, replacing the current process. """ - env = args[-1] - execve(file, args[:-1], env) + Execute the executable file with argument list args, replacing the + current process. """ + execv(file, args) -def execlp(file, *args): - """execlp(file, *args) + def execle(file, *args): + """execle(file, *args, env) - Execute the executable file (which is searched for along $PATH) - with argument list args, replacing the current process. """ - execvp(file, args) + Execute the executable file with argument list args and + environment env, replacing the current process. """ + env = args[-1] + execve(file, args[:-1], env) -def execlpe(file, *args): - """execlpe(file, *args, env) + def execlp(file, *args): + """execlp(file, *args) - Execute the executable file (which is searched for along $PATH) - with argument list args and environment env, replacing the current - process. """ - env = args[-1] - execvpe(file, args[:-1], env) + Execute the executable file (which is searched for along $PATH) + with argument list args, replacing the current process. """ + execvp(file, args) -def execvp(file, args): - """execp(file, args) + def execlpe(file, *args): + """execlpe(file, *args, env) - Execute the executable file (which is searched for along $PATH) - with argument list args, replacing the current process. - args may be a list or tuple of strings. """ - _execvpe(file, args) + Execute the executable file (which is searched for along $PATH) + with argument list args and environment env, replacing the current + process. """ + env = args[-1] + execvpe(file, args[:-1], env) -def execvpe(file, args, env): - """execvpe(file, args, env) + def execvp(file, args): + """execp(file, args) - Execute the executable file (which is searched for along $PATH) - with argument list args and environment env , replacing the - current process. - args may be a list or tuple of strings. """ - _execvpe(file, args, env) + Execute the executable file (which is searched for along $PATH) + with argument list args, replacing the current process. + args may be a list or tuple of strings. """ + _execvpe(file, args) -__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"]) + def execvpe(file, args, env): + """execvpe(file, args, env) -def _execvpe(file, args, env=None): - if env is not None: - func = execve - argrest = (args, env) - else: - func = execv - argrest = (args,) - env = environ + Execute the executable file (which is searched for along $PATH) + with argument list args and environment env , replacing the + current process. + args may be a list or tuple of strings. """ + _execvpe(file, args, env) - head, tail = path.split(file) - if head: - func(file, *argrest) - return - if 'PATH' in env: - envpath = env['PATH'] - else: - envpath = defpath - PATH = envpath.split(pathsep) - saved_exc = None - saved_tb = None - for dir in PATH: - fullname = path.join(dir, file) - try: - func(fullname, *argrest) - except error, e: - tb = sys.exc_info()[2] - if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR - and saved_exc is None): - saved_exc = e - saved_tb = tb - if saved_exc: - raise error, saved_exc, saved_tb - raise error, e, tb + __all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"]) + def _execvpe(file, args, env=None): + if env is not None: + func = execve + argrest = (args, env) + else: + func = execv + argrest = (args,) + env = environ + + head, tail = path.split(file) + if head: + func(file, *argrest) + return + if 'PATH' in env: + envpath = env['PATH'] + else: + envpath = defpath + PATH = envpath.split(pathsep) + saved_exc = None + saved_tb = None + for dir in PATH: + fullname = path.join(dir, file) + try: + func(fullname, *argrest) + except error, e: + tb = sys.exc_info()[2] + if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR + and saved_exc is None): + saved_exc = e + saved_tb = tb + if saved_exc: + raise error, saved_exc, saved_tb + raise error, e, tb + # Change environ to automatically call putenv() if it exists try: # This will fail if there's no putenv @@ -405,10 +413,10 @@ def unsetenv(key): putenv(key, "") - if name == "riscos": + if _name == "riscos": # On RISC OS, all env access goes through getenv and putenv from riscosenviron import _Environ - elif name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE + elif _name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE # But we store them as upper case class _Environ(UserDict.IterableUserDict): def __init__(self, environ): @@ -417,26 +425,11 @@ for k, v in environ.items(): data[k.upper()] = v def __setitem__(self, key, item): - putenv(key, item) self.data[key.upper()] = item def __getitem__(self, key): return self.data[key.upper()] - try: - unsetenv - except NameError: - def __delitem__(self, key): - del self.data[key.upper()] - else: - def __delitem__(self, key): - unsetenv(key) - del self.data[key.upper()] - def clear(self): - for key in self.data.keys(): - unsetenv(key) - del self.data[key] - def pop(self, key, *args): - unsetenv(key) - return self.data.pop(key.upper(), *args) + def __delitem__(self, key): + del self.data[key.upper()] def has_key(self, key): return key.upper() in self.data def __contains__(self, key): @@ -462,64 +455,14 @@ def copy(self): return dict(self) - else: # Where Env Var Names Can Be Mixed Case - class _Environ(UserDict.IterableUserDict): - def __init__(self, environ): - UserDict.UserDict.__init__(self) - self.data = environ - def __setitem__(self, key, item): - putenv(key, item) - self.data[key] = item - def update(self, dict=None, **kwargs): - if dict: - try: - keys = dict.keys() - except AttributeError: - # List of (key, value) - for k, v in dict: - self[k] = v - else: - # got keys - # cannot use items(), since mappings - # may not have them. - for k in keys: - self[k] = dict[k] - if kwargs: - self.update(kwargs) - try: - unsetenv - except NameError: - pass - else: - def __delitem__(self, key): - unsetenv(key) - del self.data[key] - def clear(self): - for key in self.data.keys(): - unsetenv(key) - del self.data[key] - def pop(self, key, *args): - unsetenv(key) - return self.data.pop(key, *args) - def copy(self): - return dict(self) + environ = _Environ(environ) - - environ = _Environ(environ) - def getenv(key, default=None): """Get an environment variable, return None if it doesn't exist. The optional second argument can specify an alternate default.""" return environ.get(key, default) __all__.append("getenv") -def _exists(name): - try: - eval(name) - return True - except NameError: - return False - # Supply spawn*() (probably only for Unix) if _exists("fork") and not _exists("spawnv") and _exists("execv"): @@ -655,7 +598,7 @@ # Supply popen2 etc. (for Unix) -if _exists("fork"): +if sys.platform.startswith('java') or _exists("fork"): if not _exists("popen2"): def popen2(cmd, mode="t", bufsize=-1): """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' @@ -664,10 +607,6 @@ is a string it will be passed to the shell (as with os.system()). If 'bufsize' is specified, it sets the buffer size for the I/O pipes. The file objects (child_stdin, child_stdout) are returned.""" - import warnings - msg = "os.popen2 is deprecated. Use the subprocess module." - warnings.warn(msg, DeprecationWarning, stacklevel=2) - import subprocess PIPE = subprocess.PIPE p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring), @@ -684,10 +623,6 @@ is a string it will be passed to the shell (as with os.system()). If 'bufsize' is specified, it sets the buffer size for the I/O pipes. The file objects (child_stdin, child_stdout, child_stderr) are returned.""" - import warnings - msg = "os.popen3 is deprecated. Use the subprocess module." - warnings.warn(msg, DeprecationWarning, stacklevel=2) - import subprocess PIPE = subprocess.PIPE p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring), @@ -704,10 +639,6 @@ is a string it will be passed to the shell (as with os.system()). If 'bufsize' is specified, it sets the buffer size for the I/O pipes. The file objects (child_stdin, child_stdout_stderr) are returned.""" - import warnings - msg = "os.popen4 is deprecated. Use the subprocess module." - warnings.warn(msg, DeprecationWarning, stacklevel=2) - import subprocess PIPE = subprocess.PIPE p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring), @@ -716,33 +647,6 @@ return p.stdin, p.stdout __all__.append("popen4") -import copy_reg as _copy_reg - -def _make_stat_result(tup, dict): - return stat_result(tup, dict) - -def _pickle_stat_result(sr): - (type, args) = sr.__reduce__() - return (_make_stat_result, args) - -try: - _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result) -except NameError: # stat_result may not exist - pass - -def _make_statvfs_result(tup, dict): - return statvfs_result(tup, dict) - -def _pickle_statvfs_result(sr): - (type, args) = sr.__reduce__() - return (_make_statvfs_result, args) - -try: - _copy_reg.pickle(statvfs_result, _pickle_statvfs_result, - _make_statvfs_result) -except NameError: # statvfs_result may not exist - pass - if not _exists("urandom"): def urandom(n): """urandom(n) -> str @@ -754,10 +658,8 @@ _urandomfd = open("/dev/urandom", O_RDONLY) except (OSError, IOError): raise NotImplementedError("/dev/urandom (or equivalent) not found") - try: - bs = b"" - while n - len(bs) >= 1: - bs += read(_urandomfd, n - len(bs)) - finally: - close(_urandomfd) - return bs + bytes = "" + while len(bytes) < n: + bytes += read(_urandomfd, n - len(bytes)) + close(_urandomfd) + return bytes Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/Lib/posix.py 2009-10-19 22:02:41 UTC (rev 6874) @@ -1,235 +1,47 @@ -r"""OS routines for Java, with some attempts to support NT, and Posix -functionality. - -This exports: - - all functions from posix, nt, dos, os2, mac, or ce, e.g. unlink, stat, etc. - - os.path is one of the modules posixpath, ntpath, macpath, or dospath - - os.name is 'posix', 'nt', 'dos', 'os2', 'mac', 'ce' or 'riscos' - - os.curdir is a string representing the current directory ('.' or ':') - - os.pardir is a string representing the parent directory ('..' or '::') - - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\') - - os.altsep is the alternate pathname separator (None or '/') - - os.pathsep is the component separator used in $PATH etc - - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n') - - os.defpath is the default search path for executables - -Programs that import and use 'os' stand a better chance of being -portable between different platforms. Of course, they must then -only use functions that are defined by all platforms (e.g., unlink -and opendir), and leave all pathname manipulation to os.path -(e.g., split and join). """ - -# CPython os.py __all__ -__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep", - "defpath", "name", "path", - "SEEK_SET", "SEEK_CUR", "SEEK_END"] - -# Would come from the posix/nt/etc. modules on CPython -__all__.extend(['EX_OK', 'F_OK', 'O_APPEND', 'O_CREAT', 'O_EXCL', 'O_RDONLY', - 'O_RDWR', 'O_SYNC', 'O_TRUNC', 'O_WRONLY', 'R_OK', 'SEEK_CUR', - 'SEEK_END', 'SEEK_SET', 'W_OK', 'X_OK', '_exit', 'access', - 'altsep', 'chdir', 'chmod', 'close', 'curdir', 'defpath', - 'environ', 'error', 'fdopen', 'fsync', 'getcwd', 'getcwdu', - 'getenv', 'getpid', 'isatty', 'linesep', 'listdir', 'lseek', - 'lstat', 'makedirs', 'mkdir', 'name', 'open', 'pardir', 'path', - 'pathsep', 'popen', 'popen2', 'popen3', 'popen4', 'putenv', - 'read', 'remove', 'removedirs', 'rename', 'renames', 'rmdir', - 'sep', 'stat', 'stat_result', 'strerror', 'system', 'unlink', - 'unsetenv', 'utime', 'walk', 'write']) - +This module provides access to operating system functionality that is +standardized by the C Standard and the POSIX standard (a thinly +disguised Unix interface). Refer to the library manual and +corresponding Unix manual entries for more information on calls. +""" +try: + import _posix + from _posix import * +except: + import _nt as _posix + from _nt import * import errno import jarray import java.lang.System -import time import stat as _stat import sys from java.io import File from org.python.core.io import FileDescriptors, FileIO, IOBase from org.python.core.Py import newString as asPyString - try: from org.python.constantine.platform import Errno except ImportError: from com.kenai.constantine.platform import Errno -# Mapping of: os._name: [name list, shell command list] -_os_map = dict(nt=[ - ['Windows'], - [['cmd.exe', '/c'], ['command.com', '/c']] - ], - posix=[ - [], # posix is a fallback, instead of matching names - [['/bin/sh', '-c']] - ] - ) +__all__ = _posix.__all__[:] +__all__.extend(['_exit', 'access', 'chdir', 'chmod', 'close', 'environ', + 'fdopen', 'fsync', 'ftruncate', 'getcwd', 'getcwdu', 'getenv', + 'getpid', 'isatty', 'listdir', 'lseek', 'lstat', 'mkdir', + 'open', 'popen', 'putenv', 'read', 'remove', 'rename', 'rmdir', + 'stat', 'strerror', 'system', 'umask', 'unlink', 'unsetenv', + 'urandom', 'utime', 'write']) -def get_os_type(): - """Return the name of the type of the underlying OS. +_name = _posix.__name__[1:] - Returns a value suitable for the os.name variable (though not - necessarily intended to be for os.name Jython). This value may be - overwritten in the Jython registry. - """ - os_name = sys.registry.getProperty('python.os') - if os_name: - return asPyString(os_name) - - os_name = asPyString(java.lang.System.getProperty('os.name')) - os_type = None - for type, (patterns, shell_commands) in _os_map.iteritems(): - for pattern in patterns: - if os_name.startswith(pattern): - # determine the shell_command later, when it's needed: - # it requires os.path (which isn't setup yet) - return type - return 'posix' - -name = 'java' -# WARNING: _name is private: for Jython internal usage only! user code -# should *NOT* use it -_name = get_os_type() - -try: - from org.python.posix import JavaPOSIX, POSIXHandler, POSIXFactory -except ImportError: - from org.jruby.ext.posix import JavaPOSIX, POSIXHandler, POSIXFactory - -class PythonPOSIXHandler(POSIXHandler): - def error(self, error, msg): - err = getattr(errno, error.name(), None) - if err is None: - raise OSError('%s: %s' % (error, asPyString(msg))) - raise OSError(err, strerror(err), asPyString(msg)) - def unimplementedError(self, method_name): - raise NotImplementedError(method_name) - def warn(self, warning_id, msg, rest): - pass # XXX implement - def isVerbose(self): - return False - def getCurrentWorkingDirectory(self): - return File(getcwdu()) - def getEnv(self): - return ['%s=%s' % (key, val) for key, val in environ.iteritems()] - def getInputStream(self): - return getattr(java.lang.System, 'in') # XXX handle resetting - def getOutputStream(self): - return java.lang.System.out # XXX handle resetting - def getPID(self): - return 0 - def getErrorStream(self): - return java.lang.System.err # XXX handle resetting - -_posix = POSIXFactory.getPOSIX(PythonPOSIXHandler(), True) -_native_posix = not isinstance(_posix, JavaPOSIX) - -if _name == 'nt': - import ntpath as path -else: - import posixpath as path - -sys.modules['os.path'] = _path = path -from os.path import curdir, pardir, sep, pathsep, defpath, extsep, altsep, devnull -linesep = java.lang.System.getProperty('line.separator') - -# open for reading only -O_RDONLY = 0x0 -# open for writing only -O_WRONLY = 0x1 -# open for reading and writing -O_RDWR = 0x2 - -# set append mode -O_APPEND = 0x8 -# synchronous writes -O_SYNC = 0x80 - -# create if nonexistant -O_CREAT = 0x200 -# truncate to zero length -O_TRUNC = 0x400 -# error if already exists -O_EXCL = 0x800 - -# seek variables -SEEK_SET = 0 -SEEK_CUR = 1 -SEEK_END = 2 - -# test for existence of file -F_OK = 0 -# test for execute or search permission -X_OK = 1<<0 -# test for write permission -W_OK = 1<<1 -# test for read permission -R_OK = 1<<2 - -# successful termination -EX_OK = 0 - # Java class representing the size of a time_t. internal use, lazily set _time_t = None -class stat_result: +# For urandom +urandom_source = None - _stat_members = ( - ('st_mode', _stat.ST_MODE), - ('st_ino', _stat.ST_INO), - ('st_dev', _stat.ST_DEV), - ('st_nlink', _stat.ST_NLINK), - ('st_uid', _stat.ST_UID), - ('st_gid', _stat.ST_GID), - ('st_size', _stat.ST_SIZE), - ('st_atime', _stat.ST_ATIME), - ('st_mtime', _stat.ST_MTIME), - ('st_ctime', _stat.ST_CTIME), - ) +# Lazily loaded path module +_path = None - def __init__(self, results): - if len(results) != 10: - raise TypeError("stat_result() takes an a 10-sequence") - for (name, index) in stat_result._stat_members: - self.__dict__[name] = results[index] - - @classmethod - def from_jnastat(cls, s): - results = [] - for meth in (s.mode, s.ino, s.dev, s.nlink, s.uid, s.gid, s.st_size, - s.atime, s.mtime, s.ctime): - try: - results.append(meth()) - except NotImplementedError: - results.append(0) - return cls(results) - - def __getitem__(self, i): - if i < 0 or i > 9: - raise IndexError(i) - return getattr(self, stat_result._stat_members[i][0]) - - def __setitem__(self, x, value): - raise TypeError("object doesn't support item assignment") - - def __setattr__(self, name, value): - if name in [x[0] for x in stat_result._stat_members]: - raise TypeError(name) - raise AttributeError("readonly attribute") - - def __len__(self): - return 10 - - def __cmp__(self, other): - if not isinstance(other, stat_result): - return 1 - return cmp(self.__dict__, other.__dict__) - - def __repr__(self): - return repr(tuple(self.__dict__[member[0]] for member - in stat_result._stat_members)) - -error = OSError - def _exit(n=0): """_exit(status) @@ -257,12 +69,13 @@ Change the current working directory to the specified path. """ - realpath = _path.realpath(path) - if not _path.exists(realpath): - raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) - if not _path.isdir(realpath): + global _path + if not _stat.S_ISDIR(stat(path).st_mode): raise OSError(errno.ENOTDIR, strerror(errno.ENOTDIR), path) - sys.setCurrentWorkingDir(realpath) + if _path is None: + import os + _path = os.path + sys.setCurrentWorkingDir(_path.realpath(path)) def listdir(path): """listdir(path) -> list_of_strings @@ -289,7 +102,7 @@ abs_path = sys.getPath(path) if not File(abs_path).exists(): raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) - _posix.chmod(abs_path, mode) + _posix_impl.chmod(abs_path, mode) def mkdir(path, mode='ignored'): """mkdir(path [, mode=0777]) @@ -298,7 +111,7 @@ The optional parameter is currently ignored. """ - # XXX: use _posix.mkdir when we can get the real errno upon failure + # XXX: use _posix_impl.mkdir when we can get the real errno upon failure fp = File(sys.getPath(path)) if not fp.mkdir(): if fp.isDirectory() or fp.isFile(): @@ -308,31 +121,6 @@ msg = strerror(err) if err else "couldn't make directory" raise OSError(err, msg, path) -def makedirs(path, mode='ignored'): - """makedirs(path [, mode=0777]) - - Super-mkdir; create a leaf directory and all intermediate ones. - - Works like mkdir, except that any intermediate path segment (not - just the rightmost) will be created if it does not exist. - The optional parameter is currently ignored. - """ - sys_path = sys.getPath(path) - if File(sys_path).mkdirs(): - return - - # if making a /x/y/z/., java.io.File#mkdirs inexplicably fails. So we need - # to force it - - # need to use _path instead of path, because param is hiding - # os.path module in namespace! - head, tail = _path.split(sys_path) - if tail == curdir: - if File(_path.join(head)).mkdirs(): - return - - raise OSError(0, "couldn't make directories", path) - def remove(path): """remove(path) @@ -351,33 +139,6 @@ if not File(sys.getPath(path)).renameTo(File(sys.getPath(newpath))): raise OSError(0, "couldn't rename file", path) -#XXX: copied from CPython 2.5.1 -def renames(old, new): - """renames(old, new) - - Super-rename; create directories as necessary and delete any left - empty. Works like rename, except creation of any intermediate - directories needed to make the new pathname good is attempted - first. After the rename, directories corresponding to rightmost - path segments of the old name will be pruned way until either the - whole path is consumed or a nonempty directory is found. - - Note: this function can fail with the new directory structure made - if you lack permissions needed to unlink the leaf directory or - file. - - """ - head, tail = path.split(new) - if head and tail and not path.exists(head): - makedirs(head) - rename(old, new) - head, tail = path.split(old) - if head and tail: - try: - removedirs(head) - except error: - pass - def rmdir(path): """rmdir(path) @@ -390,31 +151,6 @@ elif not f.delete(): raise OSError(0, "couldn't delete directory", path) -#XXX: copied from CPython 2.5.1 -def removedirs(name): - """removedirs(path) - - Super-rmdir; remove a leaf directory and empty all intermediate - ones. Works like rmdir except that, if the leaf directory is - successfully removed, directories corresponding to rightmost path - segments will be pruned away until either the whole path is - consumed or an error occurs. Errors during this latter phase are - ignored -- they generally mean that a directory was not empty. - - """ - rmdir(name) - head, tail = path.split(name) - if not tail: - head, tail = path.split(head) - while head and tail: - try: - rmdir(head) - except error: - break - head, tail = path.split(head) - -__all__.extend(['makedirs', 'renames', 'removedirs']) - def strerror(code): """strerror(code) -> string @@ -475,7 +211,7 @@ """ abs_path = sys.getPath(path) try: - return stat_result.from_jnastat(_posix.stat(abs_path)) + return _from_jnastat(_posix_impl.stat(abs_path)) except NotImplementedError: pass f = File(abs_path) @@ -501,7 +237,7 @@ """ abs_path = sys.getPath(path) try: - return stat_result.from_jnastat(_posix.lstat(abs_path)) + return _from_jnastat(_posix_impl.lstat(abs_path)) except NotImplementedError: pass f = File(sys.getPath(path)) @@ -524,7 +260,7 @@ # The parent directory's path is not canonical (one of the parent # directories is a symlink). Build a new path with the parent's # canonical path and compare the files - f = File(_path.join(can_parent.getAbsolutePath(), f.getName())) + f = File(can_parent.getAbsolutePath(), f.getName()) if f.getAbsolutePath() != f.getCanonicalPath(): return stat_result((_stat.S_IFLNK, 0, 0, 0, 0, 0, 0, 0, 0, 0)) @@ -556,7 +292,7 @@ else: raise TypeError('utime() arg 2 must be a tuple (atime, mtime)') - _posix.utimes(path, atimeval, mtimeval) + _posix_impl.utimes(path, atimeval, mtimeval) def _to_timeval(seconds): """Convert seconds (with a fraction) from epoch to a 2 item tuple of @@ -647,8 +383,9 @@ if updating and writing: raise OSError(errno.EINVAL, strerror(errno.EINVAL), filename) - if not creating and not path.exists(filename): - raise OSError(errno.ENOENT, strerror(errno.ENOENT), filename) + if not creating: + # raises ENOENT if it doesn't exist + stat(filename) if not writing: if updating: @@ -678,7 +415,8 @@ try: fchannel = RandomAccessFile(sys.getPath(filename), 'rws').getChannel() except FileNotFoundException, fnfe: - if path.isdir(filename): + #if path.isdir(filename): + if _stat.S_ISDIR(stat(filename).st_mode): raise OSError(errno.EISDIR, strerror(errno.EISDIR)) raise OSError(errno.ENOENT, strerror(errno.ENOENT), filename) return FileIO(fchannel, mode) @@ -757,51 +495,6 @@ def __iter__(self): return iter(self._stream) -# os module versions of the popen# methods have different return value -# order than popen2 functions - -def popen2(cmd, mode="t", bufsize=-1): - """Execute the shell command cmd in a sub-process. - - On UNIX, 'cmd' may be a sequence, in which case arguments will be - passed directly to the program without shell intervention (as with - os.spawnv()). If 'cmd' is a string it will be passed to the shell - (as with os.system()). If 'bufsize' is specified, it sets the - buffer size for the I/O pipes. The file objects (child_stdin, - child_stdout) are returned. - """ - import popen2 - stdout, stdin = popen2.popen2(cmd, bufsize) - return stdin, stdout - -def popen3(cmd, mode="t", bufsize=-1): - """Execute the shell command 'cmd' in a sub-process. - - On UNIX, 'cmd' may be a sequence, in which case arguments will be - passed directly to the program without shell intervention - (as with os.spawnv()). If 'cmd' is a string it will be passed - to the shell (as with os.system()). If 'bufsize' is specified, - it sets the buffer size for the I/O pipes. The file objects - (child_stdin, child_stdout, child_stderr) are returned. - """ - import popen2 - stdout, stdin, stderr = popen2.popen3(cmd, bufsize) - return stdin, stdout, stderr - -def popen4(cmd, mode="t", bufsize=-1): - """Execute the shell command 'cmd' in a sub-process. - - On UNIX, 'cmd' may be a sequence, in which case arguments will be - passed directly to the program without shell intervention - (as with os.spawnv()). If 'cmd' is a string it will be passed - to the shell (as with os.system()). If 'bufsize' is specified, - it sets the buffer size for the I/O pipes. The file objects - (child_stdin, child_stdout_stderr) are returned. - """ - import popen2 - stdout, stdin = popen2.popen4(cmd, bufsize) - return stdin, stdout - def getlogin(): """getlogin() -> string @@ -809,139 +502,8 @@ """ return java.lang.System.getProperty("user.name") -#XXX: copied from CPython's release23-maint branch revision 56502 -def walk(top, topdown=True, onerror=None): - """Directory tree generator. - - For each directory in the directory tree rooted at top (including top - itself, but excluding '.' and '..'), yields a 3-tuple - - dirpath, dirnames, filenames - - dirpath is a string, the path to the directory. dirnames is a list of - the names of the subdirectories in dirpath (excluding '.' and '..'). - filenames is a list of the names of the non-directory files in dirpath. - Note that the names in the lists are just names, with no path components. - To get a full path (which begins with top) to a file or directory in - dirpath, do os.path.join(dirpath, name). - - If optional arg 'topdown' is true or not specified, the triple for a - directory is generated before the triples for any of its subdirectories - (directories are generated top down). If topdown is false, the triple - for a directory is generated after the triples for all of its - subdirectories (directories are generated bottom up). - - When topdown is true, the caller can modify the dirnames list in-place - (e.g., via del or slice assignment), and walk will only recurse into the - subdirectories whose names remain in dirnames; this can be used to prune - the search, or to impose a specific order of visiting. Modifying - dirnames when topdown is false is ineffective, since the directories in - dirnames have already been generated by the time dirnames itself is - generated. - - By default errors from the os.listdir() call are ignored. If - optional arg 'onerror' is specified, it should be a function; it - will be called with one argument, an os.error instance. It can - report the error to continue with the walk, or raise the exception - to abort the walk. Note that the filename is available as the - filename attribute of the exception object. - - Caution: if you pass a relative pathname for top, don't change the - current working directory between resumptions of walk. walk never - changes the current directory, and assumes that the client doesn't - either. - - Example: - - from os.path import join, getsize - for root, dirs, files in walk('python/Lib/email'): - print root, "consumes", - print sum([getsize(join(root, name)) for name in files]), - print "bytes in", len(files), "non-directory files" - if 'CVS' in dirs: - dirs.remove('CVS') # don't visit CVS directories - """ - - from os.path import join, isdir, islink - - # We may not have read permission for top, in which case we can't - # get a list of the files the directory contains. os.path.walk - # always suppressed the exception then, rather than blow up for a - # minor reason when (say) a thousand readable directories are still - # left to visit. That logic is copied here. - try: - # Note that listdir and error are globals in this module due - # to earlier import-*. - names = listdir(top) - except error, err: - if onerror is not None: - onerror(err) - return - - dirs, nondirs = [], [] - for name in names: - if isdir(join(top, name)): - dirs.append(name) - else: - nondirs.append(name) - - if topdown: - yield top, dirs, nondirs - for name in dirs: - path = join(top, name) - if not islink(path): - for x in walk(path, topdown, onerror): - yield x - if not topdown: - yield top, dirs, nondirs - -__all__.append("walk") - environ = sys.getEnviron() -if _name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE - import UserDict - - # But we store them as upper case - class _Environ(UserDict.IterableUserDict): - def __init__(self, environ): - UserDict.UserDict.__init__(self) - data = self.data - for k, v in environ.items(): - data[k.upper()] = v - def __setitem__(self, key, item): - self.data[key.upper()] = item - def __getitem__(self, key): - return self.data[key.upper()] - def __delitem__(self, key): - del self.data[key.upper()] - def has_key(self, key): - return key.upper() in self.data - def __contains__(self, key): - return key.upper() in self.data - def get(self, key, failobj=None): - return self.data.get(key.upper(), failobj) - def update(self, dict=None, **kwargs): - if dict: - try: - keys = dict.keys() - except AttributeError: - # List of (key, value) - for k, v in dict: - self[k] = v - else: - # got keys - # cannot use items(), since mappings - # may not have them. - for k in keys: - self[k] = dict[k] - if kwargs: - self.update(kwargs) - def copy(self): - return dict(self) - - environ = _Environ(environ) - def putenv(key, value): """putenv(key, value) @@ -968,14 +530,14 @@ Create a hard link to a file. """ - _posix.link(sys.getPath(src), sys.getPath(dst)) + _posix_impl.link(sys.getPath(src), sys.getPath(dst)) def symlink(src, dst): """symlink(src, dst) Create a symbolic link pointing to src named dst. """ - _posix.symlink(src, sys.getPath(dst)) + _posix_impl.symlink(src, sys.getPath(dst)) def readlink(path): """readlink(path) -> path @@ -983,61 +545,61 @@ Return a string representing the path to which the symbolic link points. """ - return _posix.readlink(sys.getPath(path)) + return _posix_impl.readlink(sys.getPath(path)) def getegid(): """getegid() -> egid Return the current process's effective group id.""" - return _posix.getegid() + return _posix_impl.getegid() def geteuid(): """geteuid() -> euid Return the current process's effective user id.""" - return _posix.geteuid() + return _posix_impl.geteuid() def getgid(): """getgid() -> gid Return the current process's group id.""" - return _posix.getgid() + return _posix_impl.getgid() def getlogin(): """getlogin() -> string Return the actual login name.""" - return _posix.getlogin() + return _posix_impl.getlogin() def getpgrp(): """getpgrp() -> pgrp Return the current process group id.""" - return _posix.getpgrp() + return _posix_impl.getpgrp() def getppid(): """getppid() -> ppid Return the parent's process id.""" - return _posix.getppid() + return _posix_impl.getppid() def getuid(): """getuid() -> uid Return the current process's user id.""" - return _posix.getuid() + return _posix_impl.getuid() def setpgrp(): """setpgrp() Make this process a session leader.""" - return _posix.setpgrp() + return _posix_impl.setpgrp() def setsid(): """setsid() Call the system call setsid().""" - return _posix.setsid() + return _posix_impl.setsid() # This implementation of fork partially works on # Jython. Diagnosing what works, what doesn't, and fixing it is @@ -1049,13 +611,13 @@ # # Fork a child process. # Return 0 to child process and PID of child to parent process.""" - # return _posix.fork() + # return _posix_impl.fork() def kill(pid, sig): """kill(pid, sig) Kill a process with a signal.""" - return _posix.kill(pid, sig) + return _posix_impl.kill(pid, sig) def wait(): """wait() -> (pid, status) @@ -1063,7 +625,7 @@ Wait for completion of a child process.""" status = jarray.zeros(1, 'i') - res_pid = _posix.wait(status) + res_pid = _posix_impl.wait(status) if res_pid == -1: raise OSError(status[0], strerror(status[0])) return res_pid, status[0] @@ -1073,7 +635,7 @@ Wait for completion of a given child process.""" status = jarray.zeros(1, 'i') - res_pid = _posix.waitpid(pid, status, options) + res_pid = _posix_impl.waitpid(pid, status, options) if res_pid == -1: raise OSError(status[0], strerror(status[0])) return res_pid, status[0] @@ -1117,7 +679,7 @@ """getpid() -> pid Return the current process id.""" - return _posix.getpid() + return _posix_impl.getpid() def isatty(fileno): """isatty(fd) -> bool @@ -1137,10 +699,10 @@ raise NotImplemented('Integer file descriptor compatibility only ' 'available for stdin, stdout and stderr (0-2)') - return _posix.isatty(fd) + return _posix_impl.isatty(fd) if isinstance(fileno, FileDescriptor): - return _posix.isatty(fileno) + return _posix_impl.isatty(fileno) if not isinstance(fileno, IOBase): raise TypeError('a file descriptor is required') @@ -1151,16 +713,23 @@ """umask(new_mask) -> old_mask Set the current numeric umask and return the previous umask.""" - return _posix.umask(int(new_mask)) + return _posix_impl.umask(int(new_mask)) - -from java.security import SecureRandom -urandom_source = None - def urandom(n): global urandom_source if urandom_source is None: + from java.security import SecureRandom urandom_source = SecureRandom() buffer = jarray.zeros(n, 'b') urandom_source.nextBytes(buffer) return buffer.tostring() + +def _from_jnastat(s): + results = [] + for meth in (s.mode, s.ino, s.dev, s.nlink, s.uid, s.gid, s.st_size, + s.atime, s.mtime, s.ctime): + try: + results.append(meth()) + except NotImplementedError: + results.append(0) + return stat_result(results) Modified: trunk/jython/Lib/pwd.py =================================================================== --- trunk/jython/Lib/pwd.py 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/Lib/pwd.py 2009-10-19 22:02:41 UTC (rev 6874) @@ -10,7 +10,7 @@ __all__ = ['getpwuid', 'getpwnam', 'getpwall'] -from os import _name, _posix +from os import _name, _posix_impl if _name == 'nt': raise ImportError, 'pwd module not supported on Windows' @@ -44,7 +44,7 @@ Return the password database entry for the given numeric user ID. See pwd.__doc__ for more on password database entries. """ - entry = _posix.getpwuid(uid) + entry = _posix_impl.getpwuid(uid) if not entry: raise KeyError(uid) return struct_passwd(entry) @@ -57,7 +57,7 @@ Return the password database entry for the given user name. See pwd.__doc__ for more on password database entries. """ - entry = _posix.getpwnam(name) + entry = _posix_impl.getpwnam(name) if not entry: raise KeyError(name) return struct_passwd(entry) @@ -72,7 +72,7 @@ """ entries = [] while True: - entry = _posix.getpwent() + entry = _posix_impl.getpwent() if not entry: break entries.append(struct_passwd(entry)) Modified: trunk/jython/Lib/select.py =================================================================== --- trunk/jython/Lib/select.py 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/Lib/select.py 2009-10-19 22:02:41 UTC (rev 6874) @@ -180,7 +180,7 @@ class poll_object_cache: def __init__(self): - self.is_windows = os.get_os_type() == 'nt' + self.is_windows = os._name == 'nt' if self.is_windows: self.poll_object_queue = Queue.Queue() import atexit Modified: trunk/jython/Lib/subprocess.py =================================================================== --- trunk/jython/Lib/subprocess.py 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/Lib/subprocess.py 2009-10-19 22:02:41 UTC (rev 6874) @@ -620,11 +620,7 @@ _cmdline2listimpl = lambda args: [args] _escape_args = lambda args: args - os_info = os._os_map.get(os._name) - if os_info is None: - os_info = os._os_map.get('posix') - - for shell_command in os_info[1]: + for shell_command in os._get_shell_commands(): executable = shell_command[0] if not os.path.isabs(executable): import distutils.spawn Modified: trunk/jython/Lib/test/test_import_jy.py =================================================================== --- trunk/jython/Lib/test/test_import_jy.py 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/Lib/test/test_import_jy.py 2009-10-19 22:02:41 UTC (rev 6874) @@ -100,8 +100,8 @@ def test_override(self): modname = os.path.__name__ tests = [ - ("import os.path" , "('os.path', None, -1, 'os')" ), - ("import os.path as path2", "('os.path', None, -1, 'os')" ), + ("import os.path" , "('os.path', None, -1, '_posix')" ), + ("import os.path as path2", "('os.path', None, -1, '_posix')" ), ("from os.path import *" , "('os.path', ('*',), -1, '%s')" % modname), ("from os.path import join", Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/src/org/python/core/Py.java 2009-10-19 22:02:41 UTC (rev 6874) @@ -21,6 +21,7 @@ import java.util.Set; import org.python.antlr.base.mod; +import com.kenai.constantine.Constant; import com.kenai.constantine.platform.Errno; import java.util.ArrayList; import java.util.List; @@ -102,6 +103,12 @@ return new PyException(Py.OSError, message); } + public static PyException OSError(Constant errno, String filename) { + PyObject args = new PyTuple(Py.newInteger(errno.value()), Py.newString(errno.toString()), + Py.newString(filename)); + return new PyException(Py.OSError, args); + } + public static PyObject NotImplementedError; public static PyException NotImplementedError(String message) { return new PyException(Py.NotImplementedError, message); @@ -163,15 +170,14 @@ return new PyException(Py.IOError, message); } - public static PyException IOError(Errno errno) { - PyObject args = new PyTuple(Py.newInteger(errno.value()), - Py.newString(errno.description())); + public static PyException IOError(Constant errno) { + PyObject args = new PyTuple(Py.newInteger(errno.value()), Py.newString(errno.toString())); return new PyException(Py.IOError, args); } - public static PyException IOError(Errno errno, String filename) { - PyObject args = new PyTuple(Py.newInteger(errno.value()), - Py.newString(errno.description()), Py.newString(filename)); + public static PyException IOError(Constant errno, String filename) { + PyObject args = new PyTuple(Py.newInteger(errno.value()), Py.newString(errno.toString()), + Py.newString(filename)); return new PyException(Py.IOError, args); } Modified: trunk/jython/src/org/python/core/io/FileIO.java =================================================================== --- trunk/jython/src/org/python/core/io/FileIO.java 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/src/org/python/core/io/FileIO.java 2009-10-19 22:02:41 UTC (rev 6874) @@ -16,8 +16,8 @@ import com.kenai.constantine.platform.Errno; import org.jruby.ext.posix.util.Platform; import org.python.core.Py; -import org.python.core.util.FileUtil; import org.python.core.util.RelativeFile; +import org.python.modules.posix.PosixModule; /** * Raw I/O implementation for OS files. @@ -222,7 +222,8 @@ return false; } try { - return FileUtil.isatty(file != null ? file.getFD() : fileOutputStream.getFD()); + return PosixModule.getPOSIX().isatty(file != null + ? file.getFD() : fileOutputStream.getFD()); } catch (IOException e) { return false; } Modified: trunk/jython/src/org/python/core/io/StreamIO.java =================================================================== --- trunk/jython/src/org/python/core/io/StreamIO.java 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/src/org/python/core/io/StreamIO.java 2009-10-19 22:02:41 UTC (rev 6874) @@ -17,7 +17,7 @@ import java.nio.channels.WritableByteChannel; import org.python.core.Py; -import org.python.core.util.FileUtil; +import org.python.modules.posix.PosixModule; /** * Raw I/O implementation for simple streams. @@ -231,7 +231,7 @@ return false; } - return FileUtil.isatty(fd); + return PosixModule.getPOSIX().isatty(fd); } @Override Modified: trunk/jython/src/org/python/core/util/FileUtil.java =================================================================== --- trunk/jython/src/org/python/core/util/FileUtil.java 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/src/org/python/core/util/FileUtil.java 2009-10-19 22:02:41 UTC (rev 6874) @@ -64,14 +64,4 @@ } return out.toByteArray(); } - - public static boolean isatty(FileDescriptor fd) { - try { - return imp.load("os").__getattr__("isatty").__call__(Py.java2py(fd)).__nonzero__(); - } catch (PyException e) { - // Weak isatty check copied from jna-posix JavaPOSIX class - return fd == FileDescriptor.in || fd == FileDescriptor.out || fd == FileDescriptor.err; - } - } - } Modified: trunk/jython/src/org/python/modules/Setup.java =================================================================== --- trunk/jython/src/org/python/modules/Setup.java 2009-10-19 21:56:07 UTC (rev 6873) +++ trunk/jython/src/org/python/modules/Setup.java 2009-10-19 22:02:41 UTC (rev 6874) @@ -1,6 +1,8 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.modules; +import org.python.modules.posix.PosixModule; + // This is sort of analogous to CPython's Modules/Setup file. Use this to // specify additional builtin modules. @@ -56,6 +58,7 @@ "_systemrestart", "_ast:org.python.antlr.ast.AstModule", "_marshal", - "_threading:org.python.modules._threading._threading" + "_threading:org.python.modules._threading._threading", + "_" + PosixModule.getOSName() + ":org.python.modules.posix.PosixModule" }; } Added: trunk/jython/src/org/python/modules/posix/OS.java =================================================================== --- trunk/jython/src/org/python/modules/posix/OS.java (rev 0) +++ trunk/jython/src/org/python/modules/posix/OS.java 2009-10-19 22:02:41 UTC (rev 6874) @@ -0,0 +1,90 @@ +/* Copyright (c) Jython Developers */ +package org.python.modules.posix; + +import java.lang.reflect.Method; + +import org.python.core.PyObject; +import org.python.core.PySystemState; + +/** + * A Marker tagging what OS we're running on, with some accompanying information about + * that platform. + */ +enum OS { + NT("Windows", new String[] {"cmd.exe", "/c"}, new String[] {"command.com", "/c"}), + POSIX(new String[] {"/bin/sh", "-c"}); + + /** An array of potential shell commands this platform may use. */ + private final String[][] shellCommands; + + /** + * Name to match against os.name System property for identification + * (os.name.startswith(pattern)). Defaults to name(). + */ + private final String pattern; + + OS(String pattern, String[]... shellCommands) { + this.shellCommands = shellCommands; + this.pattern = pattern != null ? pattern : name(); + } + + OS(String[]... shellCommands) { + this(null, shellCommands); + } + + String getModuleName() { + return name().toLowerCase(); + } + + String[][] getShellCommands() { + return shellCommands; + } + + /** + * Hide module level functions defined in the PosixModule dict not applicable to this + * OS, identified by the PosixModule.Hide annotation. + * + * @param dict The PosixModule module dict + */ + void hideFunctions(PyObject dict) { + for (Method method: PosixModule.class.getDeclaredMethods()) { + if (isHidden(method)) { + dict.__setitem__(method.getName(), null); + } + } + } + + /** + * Determine if method should be hidden for this OS. + * + * @param method a PosixModule Method + * @return true if should be hidden + */ + private boolean isHidden(Method method) { + if (method.isAnnotationPresent(PosixModule.Hide.class)) { + for (OS os : method.getAnnotation(PosixModule.Hide.class).value()) { + if (os == this) { + return true; + } + } + } + return false; + } + + /** + * Return the OS we're running on. + */ + static OS getOS() { + String osName = PySystemState.registry.getProperty("python.os"); + if (osName == null) { + osName = System.getProperty("os.name"); + } + + for (OS os : OS.values()) { + if (osName.startsWith(os.pattern)) { + return os; + } + } + return OS.POSIX; + } +} Added: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java (rev 0) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-19 22:02:41 UTC (rev 6874) @@ -0,0 +1,115 @@ +/* Copyright (c) Jython Developers */ +package org.python.modules.posix; + +import com.kenai.constantine.Constant; +import com.kenai.constantine.ConstantSet; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.jruby.ext.posix.JavaPOSIX; +import org.jruby.ext.posix.POSIX; +import org.jruby.ext.posix.POSIXFactory; + +import org.python.core.ClassDictInit; +import org.python.core.Py; +import org.python.core.PyList; +import org.python.core.PyObject; +import org.python.core.PyString; +import org.python.core.PyTuple; + +/** + * The underlying _posix or _nt module, named depending on the platform. + * + * This currently contains only some of the basics of the posix/nt modules (which are + * implemented in Python). In particular things like the PythonPOSIXHandler that are + * slower to instantiate and thus would affect startup time. + * + * Eventually more if not all of the pure Python module should end up here. + */ +public class PosixModule implements ClassDictInit { + + public static final PyString __doc__ = new PyString( + "This module provides access to operating system functionality that is\n" + + "standardized by the C Standard and the POSIX standard (a thinly\n" + + "disguised Unix interface). Refer to the library manual and\n" + + "corresponding Unix manual entries for more information on calls."); + + /** Current OS information. */ + private static OS os = OS.getOS(); + + /** Platform specific POSIX services. */ + private static POSIX posix = POSIXFactory.getPOSIX(new PythonPOSIXHandler(), true); + + private static final String[] openFlags = + {"O_RDONLY", "O_WRONLY", "O_RDWR", "O_APPEND", "O_SYNC", "O_CREAT", "O_TRUNC", "O_EXCL"}; + + public static void classDictInit(PyObject dict) { + dict.__setitem__("__name__", new PyString("_" + os.getModuleName())); + dict.__setitem__("__doc__", __doc__); + + // os.open flags, only expose what we support + ConstantSet openFlagConstants = ConstantSet.getConstantSet("OpenFlags"); + for (String openFlag : openFlags) { + dict.__setitem__(openFlag, Py.newInteger(openFlagConstants.getValue(openFlag))); + } + // os.access constants + dict.__setitem__("F_OK", Py.Zero); + dict.__setitem__("X_OK", Py.newInteger(1 << 0)); + dict.__setitem__("W_OK", Py.newInteger(1 << 1)); + ... [truncated message content] |
From: <pj...@us...> - 2009-10-20 00:21:20
|
Revision: 6878 http://jython.svn.sourceforge.net/jython/?rev=6878&view=rev Author: pjenvey Date: 2009-10-20 00:20:58 +0000 (Tue, 20 Oct 2009) Log Message: ----------- o jna-posix does the pure java stat for us, simplify it + move it to PosixModule o move strerror to PosixModule because it does the work of falling back to Linux errno descriptions on Windows, and we need that from some Java calls Modified Paths: -------------- trunk/jython/Lib/posix.py trunk/jython/Lib/test/test_fileno.py trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/modules/posix/PosixModule.java trunk/jython/src/org/python/modules/posix/PyStatResult.java trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/Lib/posix.py 2009-10-20 00:20:58 UTC (rev 6878) @@ -18,18 +18,14 @@ from java.io import File from org.python.core.io import FileDescriptors, FileIO, IOBase from org.python.core.Py import newString as asPyString -try: - from org.python.constantine.platform import Errno -except ImportError: - from com.kenai.constantine.platform import Errno __all__ = _posix.__all__[:] __all__.extend(['_exit', 'access', 'chdir', 'chmod', 'close', 'environ', 'fdopen', 'fsync', 'ftruncate', 'getcwd', 'getcwdu', 'getenv', - 'getpid', 'isatty', 'listdir', 'lseek', 'lstat', 'mkdir', - 'open', 'popen', 'putenv', 'read', 'remove', 'rename', 'rmdir', - 'stat', 'strerror', 'system', 'umask', 'unlink', 'unsetenv', - 'urandom', 'utime', 'write']) + 'getpid', 'isatty', 'listdir', 'lseek', 'mkdir', 'open', + 'popen', 'putenv', 'read', 'remove', 'rename', 'rmdir', + 'system', 'umask', 'unlink', 'unsetenv', 'urandom', 'utime', + 'write']) _name = _posix.__name__[1:] @@ -151,28 +147,6 @@ elif not f.delete(): raise OSError(0, "couldn't delete directory", path) -def strerror(code): - """strerror(code) -> string - - Translate an error code to a message string. - """ - if not isinstance(code, (int, long)): - raise TypeError('an integer is required') - constant = Errno.valueOf(code) - if constant is Errno.__UNKNOWN_CONSTANT__: - return 'Unknown error: %d' % code - if constant.name() == constant.description(): - # XXX: have constantine handle this fallback - # Fake constant or just lacks a description, fallback to Linux's - try: - from org.python.constantine.platform.linux import Errno as LinuxErrno - except ImportError: - from com.kenai.constantine.platform.linux import Errno as LinuxErrno - constant = getattr(LinuxErrno, constant.name(), None) - if not constant: - return 'Unknown error: %d' % code - return asPyString(constant.toString()) - def access(path, mode): """access(path, mode) -> True if granted, False otherwise @@ -201,75 +175,6 @@ result = False return result -def stat(path): - """stat(path) -> stat result - - Perform a stat system call on the given path. - - The Java stat implementation only returns a small subset of - the standard fields: size, modification time and change time. - """ - abs_path = sys.getPath(path) - try: - return _from_jnastat(_posix_impl.stat(abs_path)) - except NotImplementedError: - pass - f = File(abs_path) - if not f.exists(): - raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) - size = f.length() - mtime = f.lastModified() / 1000.0 - mode = 0 - if f.isDirectory(): - mode = _stat.S_IFDIR - elif f.isFile(): - mode = _stat.S_IFREG - if f.canRead(): - mode = mode | _stat.S_IREAD - if f.canWrite(): - mode = mode | _stat.S_IWRITE - return stat_result((mode, 0, 0, 0, 0, 0, size, mtime, mtime, 0)) - -def lstat(path): - """lstat(path) -> stat result - - Like stat(path), but do not follow symbolic links. - """ - abs_path = sys.getPath(path) - try: - return _from_jnastat(_posix_impl.lstat(abs_path)) - except NotImplementedError: - pass - f = File(sys.getPath(path)) - # XXX: jna-posix implements similar link detection in - # JavaFileStat.calculateSymlink, fallback to that instead when not - # native - abs_parent = f.getAbsoluteFile().getParentFile() - if not abs_parent: - # root isn't a link - return stat(path) - can_parent = abs_parent.getCanonicalFile() - - if can_parent.getAbsolutePath() == abs_parent.getAbsolutePath(): - # The parent directory's absolute path is canonical.. - if f.getAbsolutePath() != f.getCanonicalPath(): - # but the file's absolute and canonical paths differ (a - # link) - return stat_result((_stat.S_IFLNK, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - - # The parent directory's path is not canonical (one of the parent - # directories is a symlink). Build a new path with the parent's - # canonical path and compare the files - f = File(can_parent.getAbsolutePath(), f.getName()) - if f.getAbsolutePath() != f.getCanonicalPath(): - return stat_result((_stat.S_IFLNK, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - - # Not a link, only now can we determine if it exists (because - # File.exists() returns False for dead links) - if not f.exists(): - raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) - return stat(path) - def utime(path, times): """utime(path, (atime, mtime)) utime(path, None) @@ -723,13 +628,3 @@ buffer = jarray.zeros(n, 'b') urandom_source.nextBytes(buffer) return buffer.tostring() - -def _from_jnastat(s): - results = [] - for meth in (s.mode, s.ino, s.dev, s.nlink, s.uid, s.gid, s.st_size, - s.atime, s.mtime, s.ctime): - try: - results.append(meth()) - except NotImplementedError: - results.append(0) - return stat_result(results) Modified: trunk/jython/Lib/test/test_fileno.py =================================================================== --- trunk/jython/Lib/test/test_fileno.py 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/Lib/test/test_fileno.py 2009-10-20 00:20:58 UTC (rev 6878) @@ -327,7 +327,7 @@ except exc, val: if expected and str(val) != msg: raise test_support.TestFailed( - "Message %r, expected %r" % (str(value), msg)) + "Message %r, expected %r" % (str(val), msg)) else: raise test_support.TestFailed("Expected %s" % exc) Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/src/org/python/core/Py.java 2009-10-20 00:20:58 UTC (rev 6878) @@ -27,6 +27,7 @@ import java.util.List; import org.python.core.adapter.ClassicPyObjectAdapter; import org.python.core.adapter.ExtensiblePyObjectAdapter; +import org.python.modules.posix.PosixModule; import org.python.util.Generic; public final class Py { @@ -104,7 +105,10 @@ } public static PyException OSError(Constant errno, String filename) { - PyObject args = new PyTuple(Py.newInteger(errno.value()), Py.newString(errno.toString()), + int value = errno.value(); + // Pass to strerror because constantine currently lacks Errno descriptions on + // Windows, and strerror falls back to Linux's + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), Py.newString(filename)); return new PyException(Py.OSError, args); } @@ -171,12 +175,14 @@ } public static PyException IOError(Constant errno) { - PyObject args = new PyTuple(Py.newInteger(errno.value()), Py.newString(errno.toString())); + int value = errno.value(); + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value)); return new PyException(Py.IOError, args); } public static PyException IOError(Constant errno, String filename) { - PyObject args = new PyTuple(Py.newInteger(errno.value()), Py.newString(errno.toString()), + int value = errno.value(); + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value), Py.newString(filename)); return new PyException(Py.IOError, args); } Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 00:20:58 UTC (rev 6878) @@ -1,7 +1,9 @@ /* Copyright (c) Jython Developers */ package org.python.modules.posix; +import com.kenai.constantine.Constant; import com.kenai.constantine.ConstantSet; +import com.kenai.constantine.platform.Errno; import org.jruby.ext.posix.JavaPOSIX; import org.jruby.ext.posix.POSIX; @@ -70,6 +72,39 @@ dict.__setitem__("__all__", dict.invoke("keys")); } + public static PyString __doc__lstat = new PyString( + "lstat(path) -> stat result\n\n" + + "Like stat(path), but do not follow symbolic links."); + public static PyObject lstat(String path) { + return PyStatResult.fromFileStat(posix.lstat(Py.getSystemState().getPath(path))); + } + + public static PyString __doc__stat = new PyString( + "stat(path) -> stat result\n\n" + + "Perform a stat system call on the given path.\n\n" + + "Note that some platforms may return only a small subset of the\n" + + "standard fields"); + public static PyObject stat(String path) { + return PyStatResult.fromFileStat(posix.stat(Py.getSystemState().getPath(path))); + } + + public static PyString __doc__strerror = new PyString( + "strerror(code) -> string\n\n" + + "Translate an error code to a message string."); + public static PyObject strerror(int code) { + Constant errno = Errno.valueOf(code); + if (errno == Errno.__UNKNOWN_CONSTANT__) { + return new PyString("Unknown error: " + code); + } + if (errno.name() == errno.toString()) { + // Fake constant or just lacks a description, fallback to Linux's + // XXX: have constantine handle this fallback + errno = Enum.valueOf(com.kenai.constantine.platform.linux.Errno.class, + errno.name()); + } + return new PyString(errno.toString()); + } + /** * Helper function for the subprocess module, returns the potential shell commands for * this OS. Modified: trunk/jython/src/org/python/modules/posix/PyStatResult.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PyStatResult.java 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/src/org/python/modules/posix/PyStatResult.java 2009-10-20 00:20:58 UTC (rev 6878) @@ -1,11 +1,7 @@ /* Copyright (c) Jython Developers */ package org.python.modules.posix; -import org.python.expose.ExposedGet; -import org.python.expose.ExposedMethod; -import org.python.expose.ExposedNew; -import org.python.expose.ExposedType; -import org.python.expose.MethodType; +import org.jruby.ext.posix.FileStat; import org.python.core.ArgParser; import org.python.core.Py; @@ -15,6 +11,12 @@ import org.python.core.PyTuple; import org.python.core.PyType; +import org.python.expose.ExposedGet; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedType; +import org.python.expose.MethodType; + @ExposedType(name = "posix.stat_result", isBaseType = false) public class PyStatResult extends PyTuple { @@ -66,6 +68,17 @@ } } + /** + * Return a Python stat result from a posix layer FileStat object. + */ + public static PyStatResult fromFileStat(FileStat stat) { + return new PyStatResult(Py.newInteger(stat.mode()), Py.newLong(stat.ino()), + Py.newLong(stat.dev()), Py.newInteger(stat.nlink()), + Py.newInteger(stat.uid()), Py.newInteger(stat.gid()), + Py.newLong(stat.st_size()), Py.newLong(stat.atime()), + Py.newLong(stat.mtime()), Py.newLong(stat.ctime())); + } + @Override public synchronized PyObject __eq__(PyObject o) { return stat_result___eq__(o); Modified: trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java 2009-10-20 00:06:05 UTC (rev 6877) +++ trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java 2009-10-20 00:20:58 UTC (rev 6878) @@ -31,6 +31,10 @@ } public void unimplementedError(String methodName) { + if (methodName.startsWith("stat.")) { + // Ignore unimplemented FileStat methods + return; + } throw Py.NotImplementedError(methodName); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-20 00:54:09
|
Revision: 6879 http://jython.svn.sourceforge.net/jython/?rev=6879&view=rev Author: pjenvey Date: 2009-10-20 00:54:00 +0000 (Tue, 20 Oct 2009) Log Message: ----------- o constantine lacks sensible Windows OpenFlags constants, roll our own o fix put/unset/getenv on Windows Modified Paths: -------------- trunk/jython/Lib/posix.py trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-20 00:20:58 UTC (rev 6878) +++ trunk/jython/Lib/posix.py 2009-10-20 00:54:00 UTC (rev 6879) @@ -320,7 +320,6 @@ try: fchannel = RandomAccessFile(sys.getPath(filename), 'rws').getChannel() except FileNotFoundException, fnfe: - #if path.isdir(filename): if _stat.S_ISDIR(stat(filename).st_mode): raise OSError(errno.EISDIR, strerror(errno.EISDIR)) raise OSError(errno.ENOENT, strerror(errno.ENOENT), filename) @@ -414,20 +413,26 @@ Change or add an environment variable. """ - environ[key] = value + # XXX: put/unset/getenv should probably be deprecated + import os + os.environ[key] = value def unsetenv(key): """unsetenv(key) Delete an environment variable. """ - if key in environ: - del environ[key] + import os + try: + del os.environ[key] + except KeyError: + pass def getenv(key, default=None): """Get an environment variable, return None if it doesn't exist. The optional second argument can specify an alternate default.""" - return environ.get(key, default) + import os + return os.environ.get(key, default) if _name == 'posix': def link(src, dst): Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 00:20:58 UTC (rev 6878) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 00:54:00 UTC (rev 6879) @@ -2,7 +2,6 @@ package org.python.modules.posix; import com.kenai.constantine.Constant; -import com.kenai.constantine.ConstantSet; import com.kenai.constantine.platform.Errno; import org.jruby.ext.posix.JavaPOSIX; @@ -39,18 +38,20 @@ /** Platform specific POSIX services. */ private static POSIX posix = POSIXFactory.getPOSIX(new PythonPOSIXHandler(), true); - private static final String[] openFlags = - {"O_RDONLY", "O_WRONLY", "O_RDWR", "O_APPEND", "O_SYNC", "O_CREAT", "O_TRUNC", "O_EXCL"}; - public static void classDictInit(PyObject dict) { dict.__setitem__("__name__", new PyString("_" + os.getModuleName())); dict.__setitem__("__doc__", __doc__); // os.open flags, only expose what we support - ConstantSet openFlagConstants = ConstantSet.getConstantSet("OpenFlags"); - for (String openFlag : openFlags) { - dict.__setitem__(openFlag, Py.newInteger(openFlagConstants.getValue(openFlag))); - } + dict.__setitem__("O_RDONLY", Py.newInteger(0x0)); + dict.__setitem__("O_WRONLY", Py.newInteger(0x1)); + dict.__setitem__("O_RDWR", Py.newInteger(0x2)); + dict.__setitem__("O_APPEND", Py.newInteger(0x8)); + dict.__setitem__("O_SYNC", Py.newInteger(0x80)); + dict.__setitem__("O_CREAT", Py.newInteger(0x200)); + dict.__setitem__("O_TRUNC", Py.newInteger(0x400)); + dict.__setitem__("O_EXCL", Py.newInteger(0x800)); + // os.access constants dict.__setitem__("F_OK", Py.Zero); dict.__setitem__("X_OK", Py.newInteger(1 << 0)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-20 01:16:03
|
Revision: 6880 http://jython.svn.sourceforge.net/jython/?rev=6880&view=rev Author: pjenvey Date: 2009-10-20 01:15:51 +0000 (Tue, 20 Oct 2009) Log Message: ----------- move the environ dict into the more appropriate PosixModule Modified Paths: -------------- trunk/jython/Lib/posix.py trunk/jython/src/org/python/core/PySystemState.java trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-20 00:54:00 UTC (rev 6879) +++ trunk/jython/Lib/posix.py 2009-10-20 01:15:51 UTC (rev 6880) @@ -20,11 +20,11 @@ from org.python.core.Py import newString as asPyString __all__ = _posix.__all__[:] -__all__.extend(['_exit', 'access', 'chdir', 'chmod', 'close', 'environ', - 'fdopen', 'fsync', 'ftruncate', 'getcwd', 'getcwdu', 'getenv', - 'getpid', 'isatty', 'listdir', 'lseek', 'mkdir', 'open', - 'popen', 'putenv', 'read', 'remove', 'rename', 'rmdir', - 'system', 'umask', 'unlink', 'unsetenv', 'urandom', 'utime', +__all__.extend(['_exit', 'access', 'chdir', 'chmod', 'close', 'fdopen', + 'fsync', 'ftruncate', 'getcwd', 'getcwdu', 'getenv', 'getpid', + 'isatty', 'listdir', 'lseek', 'mkdir', 'open', 'popen', + 'putenv', 'read', 'remove', 'rename', 'rmdir', 'system', + 'umask', 'unlink', 'unsetenv', 'urandom', 'utime', 'write']) _name = _posix.__name__[1:] @@ -406,8 +406,6 @@ """ return java.lang.System.getProperty("user.name") -environ = sys.getEnviron() - def putenv(key, value): """putenv(key, value) Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-10-20 00:54:00 UTC (rev 6879) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-10-20 01:15:51 UTC (rev 6880) @@ -125,8 +125,6 @@ private String currentWorkingDir; - private PyObject environ; - private ClassLoader classLoader = null; public PyObject stdout, stderr, stdin; @@ -165,7 +163,6 @@ path_importer_cache = new PyDictionary(); currentWorkingDir = new File("").getAbsolutePath(); - initEnviron(); // Set up the initial standard ins and outs String mode = Options.unbuffered ? "b" : ""; @@ -437,27 +434,6 @@ } /** - * Initialize the environ dict from System.getenv. environ may be empty when the - * security policy doesn't grant us access. - */ - public void initEnviron() { - environ = new PyDictionary(); - Map<String, String> env; - try { - env = System.getenv(); - } catch (SecurityException se) { - return; - } - for (Map.Entry<String, String> entry : env.entrySet()) { - environ.__setitem__(Py.newString(entry.getKey()), Py.newString(entry.getValue())); - } - } - - public PyObject getEnviron() { - return environ; - } - - /** * Change the current working directory to the specified path. * * path is assumed to be absolute and canonical (via Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 00:54:00 UTC (rev 6879) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 01:15:51 UTC (rev 6880) @@ -4,12 +4,15 @@ import com.kenai.constantine.Constant; import com.kenai.constantine.platform.Errno; +import java.util.Map; + import org.jruby.ext.posix.JavaPOSIX; import org.jruby.ext.posix.POSIX; import org.jruby.ext.posix.POSIXFactory; import org.python.core.ClassDictInit; import org.python.core.Py; +import org.python.core.PyDictionary; import org.python.core.PyList; import org.python.core.PyObject; import org.python.core.PyString; @@ -60,6 +63,7 @@ // Successful termination dict.__setitem__("EX_OK", Py.Zero); + dict.__setitem__("environ", getEnviron()); dict.__setitem__("error", Py.OSError); dict.__setitem__("stat_result", PyStatResult.TYPE); dict.__setitem__("_posix_impl", Py.java2py(posix)); @@ -126,6 +130,24 @@ return new PyTuple(commandsTup); } + /** + * Initialize the environ dict from System.getenv. environ may be empty when the + * security policy doesn't grant us access. + */ + private static PyObject getEnviron() { + PyObject environ = new PyDictionary(); + Map<String, String> env; + try { + env = System.getenv(); + } catch (SecurityException se) { + return environ; + } + for (Map.Entry<String, String> entry : env.entrySet()) { + environ.__setitem__(Py.newString(entry.getKey()), Py.newString(entry.getValue())); + } + return environ; + } + public static POSIX getPOSIX() { return posix; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-20 04:05:02
|
Revision: 6884 http://jython.svn.sourceforge.net/jython/?rev=6884&view=rev Author: pjenvey Date: 2009-10-20 04:04:53 +0000 (Tue, 20 Oct 2009) Log Message: ----------- move _exit/listdir to PosixModule, get rid of a duplicate getlogin impl Modified Paths: -------------- trunk/jython/Lib/posix.py trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-20 03:43:46 UTC (rev 6883) +++ trunk/jython/Lib/posix.py 2009-10-20 04:04:53 UTC (rev 6884) @@ -12,20 +12,18 @@ from _nt import * import errno import jarray -import java.lang.System import stat as _stat import sys from java.io import File from org.python.core.io import FileDescriptors, FileIO, IOBase from org.python.core.Py import newString as asPyString -__all__ = _posix.__all__[:] -__all__.extend(['_exit', 'access', 'chdir', 'chmod', 'close', 'fdopen', - 'fsync', 'ftruncate', 'getcwd', 'getcwdu', 'getenv', 'getpid', - 'isatty', 'listdir', 'lseek', 'mkdir', 'open', 'popen', - 'putenv', 'read', 'remove', 'rename', 'rmdir', 'system', - 'umask', 'unlink', 'unsetenv', 'urandom', 'utime', - 'write']) +__all__ = [name for name in _posix.__all__ if not name.startswith('__doc__')] +__all__.extend(['access', 'chdir', 'chmod', 'close', 'fdopen', 'fsync', + 'ftruncate', 'getcwd', 'getcwdu', 'getenv', 'getpid', 'isatty', + 'lseek', 'mkdir', 'open', 'popen', 'putenv', 'read', 'remove', + 'rename', 'rmdir', 'system', 'umask', 'unlink', 'unsetenv', + 'urandom', 'utime', 'write']) _name = _posix.__name__[1:] @@ -38,14 +36,6 @@ # Lazily loaded path module _path = None -def _exit(n=0): - """_exit(status) - - Exit to the system with specified status, without normal exit - processing. - """ - java.lang.System.exit(n) - def getcwd(): """getcwd() -> path @@ -73,21 +63,6 @@ _path = os.path sys.setCurrentWorkingDir(_path.realpath(path)) -def listdir(path): - """listdir(path) -> list_of_strings - - Return a list containing the names of the entries in the directory. - - path: path of directory to list - - The list is in arbitrary order. It does not include the special - entries '.' and '..' even if they are present in the directory. - """ - l = File(sys.getPath(path)).list() - if l is None: - raise OSError(0, 'No such directory', path) - return [asPyString(entry) for entry in l] - def chmod(path, mode): """chmod(path, mode) @@ -399,13 +374,6 @@ def __iter__(self): return iter(self._stream) -def getlogin(): - """getlogin() -> string - - Return the actual login name. - """ - return java.lang.System.getProperty("user.name") - def putenv(key, value): """putenv(key, value) Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 03:43:46 UTC (rev 6883) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-20 04:04:53 UTC (rev 6884) @@ -17,13 +17,14 @@ import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyTuple; +import org.python.core.util.RelativeFile; /** * The underlying _posix or _nt module, named depending on the platform. * * This currently contains only some of the basics of the posix/nt modules (which are - * implemented in Python). In particular things like the PythonPOSIXHandler that are - * slower to instantiate and thus would affect startup time. + * implemented in Python), most importantly things like PythonPOSIXHandler that are slower + * to instantiate and thus would affect startup time. * * Eventually more if not all of the pure Python module should end up here. */ @@ -42,9 +43,6 @@ private static POSIX posix = POSIXFactory.getPOSIX(new PythonPOSIXHandler(), true); public static void classDictInit(PyObject dict) { - dict.__setitem__("__name__", new PyString("_" + os.getModuleName())); - dict.__setitem__("__doc__", __doc__); - // os.open flags, only expose what we support dict.__setitem__("O_RDONLY", Py.newInteger(0x0)); dict.__setitem__("O_WRONLY", Py.newInteger(0x1)); @@ -75,13 +73,46 @@ dict.__setitem__("getOSName", null); dict.__setitem__("__all__", dict.invoke("keys")); + + dict.__setitem__("__name__", new PyString("_" + os.getModuleName())); + dict.__setitem__("__doc__", __doc__); } + public static PyString __doc___exit = new PyString( + "_exit(status)\n\n" + + "Exit to the system with specified status, without normal exit processing."); + public static void _exit() { + _exit(0); + } + + public static void _exit(int status) { + System.exit(status); + } + + public static PyString __doc__listdir = new PyString( + "listdir(path) -> list_of_strings\n\n" + + "Return a list containing the names of the entries in the directory.\n\n" + + "path: path of directory to list\n\n" + + "The list is in arbitrary order. It does not include the special\n" + + "entries '.' and '..' even if they are present in the directory."); + public static PyList listdir(String path) { + PyList list = new PyList(); + String[] files = new RelativeFile(path).list(); + + if (files == null) { + throw Py.OSError("No such directory: " + path); + } + for (String file : files) { + list.append(new PyString(file)); + } + return list; + } + public static PyString __doc__lstat = new PyString( "lstat(path) -> stat result\n\n" + "Like stat(path), but do not follow symbolic links."); public static PyObject lstat(String path) { - return PyStatResult.fromFileStat(posix.lstat(Py.getSystemState().getPath(path))); + return PyStatResult.fromFileStat(posix.lstat(new RelativeFile(path).getPath())); } public static PyString __doc__stat = new PyString( @@ -90,11 +121,11 @@ "Note that some platforms may return only a small subset of the\n" + "standard fields"); public static PyObject stat(String path) { - return PyStatResult.fromFileStat(posix.stat(Py.getSystemState().getPath(path))); + return PyStatResult.fromFileStat(posix.stat(new RelativeFile(path).getPath())); } public static PyString __doc__strerror = new PyString( - "strerror(code) -> string\n\n" + + "strerror(code) -> string\n\n" + "Translate an error code to a message string."); public static PyObject strerror(int code) { Constant errno = Errno.valueOf(code); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-20 04:25:23
|
Revision: 6886 http://jython.svn.sourceforge.net/jython/?rev=6886&view=rev Author: pjenvey Date: 2009-10-20 04:25:15 +0000 (Tue, 20 Oct 2009) Log Message: ----------- don't decode bytes when searching for an encoding defined in an InputStream thanks artichoke fixes #1487 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/core/ParserFacade.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-10-20 04:24:54 UTC (rev 6885) +++ trunk/jython/NEWS 2009-10-20 04:25:15 UTC (rev 6886) @@ -3,6 +3,7 @@ Jython 2.5.2a1 Bugs Fixed - [ 1478 ] defaultdict & weakref.WeakKeyDictionary [TypeError: first argument must be callable] + - [ 1487 ] Import of module with latin-1 chars fails on utf-8 file encoding - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2009-10-20 04:24:54 UTC (rev 6885) +++ trunk/jython/src/org/python/core/ParserFacade.java 2009-10-20 04:25:15 UTC (rev 6886) @@ -4,14 +4,11 @@ import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; -import java.io.Writer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; @@ -25,7 +22,6 @@ import org.python.antlr.BaseParser; import org.python.antlr.NoCloseReaderStream; import org.python.antlr.ParseException; -import org.python.antlr.PythonLexer; import org.python.antlr.PythonPartialLexer; import org.python.antlr.PythonPartialParser; import org.python.antlr.PythonTokenSource; @@ -387,7 +383,7 @@ private static String readEncoding(InputStream stream) throws IOException { stream.mark(MARK_LIMIT); String encoding = null; - BufferedReader br = new BufferedReader(new InputStreamReader(stream), 512); + BufferedReader br = new BufferedReader(new InputStreamReader(stream, "ISO-8859-1"), 512); encoding = findEncoding(br); // XXX: reset() can still raise an IOException if a line exceeds our large mark // limit This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-24 01:43:08
|
Revision: 6892 http://jython.svn.sourceforge.net/jython/?rev=6892&view=rev Author: pjenvey Date: 2009-10-24 01:42:48 +0000 (Sat, 24 Oct 2009) Log Message: ----------- move os.open to PosixModule to fix the recent test_threaded_import regression Modified Paths: -------------- trunk/jython/Lib/posix.py trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-23 21:55:28 UTC (rev 6891) +++ trunk/jython/Lib/posix.py 2009-10-24 01:42:48 UTC (rev 6892) @@ -15,7 +15,7 @@ import stat as _stat import sys from java.io import File -from org.python.core.io import FileDescriptors, FileIO, IOBase +from org.python.core.io import FileDescriptors, IOBase from org.python.core.Py import newString as asPyString __all__ = [name for name in _posix.__all__ if not name.startswith('__doc__')] @@ -245,64 +245,6 @@ rawio = FileDescriptors.get(fd) return _handle_oserror(rawio.seek, pos, how) -def open(filename, flag, mode=0777): - """open(filename, flag [, mode=0777]) -> fd - - Open a file (for low level IO). - """ - reading = flag & O_RDONLY - writing = flag & O_WRONLY - updating = flag & O_RDWR - creating = flag & O_CREAT - - truncating = flag & O_TRUNC - exclusive = flag & O_EXCL - sync = flag & O_SYNC - appending = flag & O_APPEND - - if updating and writing: - raise OSError(errno.EINVAL, strerror(errno.EINVAL), filename) - - if not creating: - # raises ENOENT if it doesn't exist - stat(filename) - - if not writing: - if updating: - writing = True - else: - reading = True - - if truncating and not writing: - # Explicitly truncate, writing will truncate anyway - FileIO(filename, 'w').close() - - if exclusive and creating: - from java.io import IOException - try: - if not File(sys.getPath(filename)).createNewFile(): - raise OSError(errno.EEXIST, strerror(errno.EEXIST), - filename) - except IOException, ioe: - raise OSError(ioe) - - mode = '%s%s%s%s' % (reading and 'r' or '', - (not appending and writing) and 'w' or '', - (appending and (writing or updating)) and 'a' or '', - updating and '+' or '') - - if sync and (writing or updating): - from java.io import FileNotFoundException, RandomAccessFile - try: - fchannel = RandomAccessFile(sys.getPath(filename), 'rws').getChannel() - except FileNotFoundException, fnfe: - if _stat.S_ISDIR(stat(filename).st_mode): - raise OSError(errno.EISDIR, strerror(errno.EISDIR)) - raise OSError(errno.ENOENT, strerror(errno.ENOENT), filename) - return FileIO(fchannel, mode) - - return FileIO(filename, mode) - def read(fd, buffersize): """read(fd, buffersize) -> string Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-10-23 21:55:28 UTC (rev 6891) +++ trunk/jython/src/org/python/core/Py.java 2009-10-24 01:42:48 UTC (rev 6892) @@ -104,6 +104,10 @@ return new PyException(Py.OSError, message); } + public static PyException OSError(IOException ioe) { + return fromIOException(ioe, Py.OSError); + } + public static PyException OSError(Constant errno, String filename) { int value = errno.value(); // Pass to strerror because constantine currently lacks Errno descriptions on @@ -158,16 +162,7 @@ public static PyObject IOError; public static PyException IOError(IOException ioe) { - String message = ioe.getMessage(); - if (message == null) { - message = ioe.getClass().getName(); - } - if (ioe instanceof FileNotFoundException) { - PyTuple args = new PyTuple(Py.newInteger(Errno.ENOENT.value()), - Py.newString("File not found - " + message)); - return new PyException(Py.IOError, args); - } - return new PyException(Py.IOError, message); + return fromIOException(ioe, Py.IOError); } public static PyException IOError(String message) { @@ -187,6 +182,19 @@ return new PyException(Py.IOError, args); } + private static PyException fromIOException(IOException ioe, PyObject err) { + String message = ioe.getMessage(); + if (message == null) { + message = ioe.getClass().getName(); + } + if (ioe instanceof FileNotFoundException) { + PyTuple args = new PyTuple(Py.newInteger(Errno.ENOENT.value()), + Py.newString("File not found - " + message)); + return new PyException(err, args); + } + return new PyException(err, message); + } + public static PyObject KeyError; public static PyException KeyError(String message) { Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-23 21:55:28 UTC (rev 6891) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-24 01:42:48 UTC (rev 6892) @@ -4,6 +4,10 @@ import com.kenai.constantine.Constant; import com.kenai.constantine.platform.Errno; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.RandomAccessFile; import java.util.Map; import org.jruby.ext.posix.JavaPOSIX; @@ -17,6 +21,7 @@ import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyTuple; +import org.python.core.io.FileIO; import org.python.core.util.RelativeFile; /** @@ -42,16 +47,26 @@ /** Platform specific POSIX services. */ private static POSIX posix = POSIXFactory.getPOSIX(new PythonPOSIXHandler(), true); + /** os.open flags. */ + private static int O_RDONLY = 0x0; + private static int O_WRONLY = 0x1; + private static int O_RDWR = 0x2; + private static int O_APPEND = 0x8; + private static int O_SYNC = 0x80; + private static int O_CREAT = 0x200; + private static int O_TRUNC = 0x400; + private static int O_EXCL = 0x800; + public static void classDictInit(PyObject dict) { - // os.open flags, only expose what we support - dict.__setitem__("O_RDONLY", Py.newInteger(0x0)); - dict.__setitem__("O_WRONLY", Py.newInteger(0x1)); - dict.__setitem__("O_RDWR", Py.newInteger(0x2)); - dict.__setitem__("O_APPEND", Py.newInteger(0x8)); - dict.__setitem__("O_SYNC", Py.newInteger(0x80)); - dict.__setitem__("O_CREAT", Py.newInteger(0x200)); - dict.__setitem__("O_TRUNC", Py.newInteger(0x400)); - dict.__setitem__("O_EXCL", Py.newInteger(0x800)); + // only expose the open flags we support + dict.__setitem__("O_RDONLY", Py.newInteger(O_RDONLY)); + dict.__setitem__("O_WRONLY", Py.newInteger(O_WRONLY)); + dict.__setitem__("O_RDWR", Py.newInteger(O_RDWR)); + dict.__setitem__("O_APPEND", Py.newInteger(O_APPEND)); + dict.__setitem__("O_SYNC", Py.newInteger(O_SYNC)); + dict.__setitem__("O_CREAT", Py.newInteger(O_CREAT)); + dict.__setitem__("O_TRUNC", Py.newInteger(O_TRUNC)); + dict.__setitem__("O_EXCL", Py.newInteger(O_EXCL)); // os.access constants dict.__setitem__("F_OK", Py.Zero); @@ -115,6 +130,71 @@ return PyStatResult.fromFileStat(posix.lstat(new RelativeFile(path).getPath())); } + public static PyString __doc__open = new PyString( + "open(filename, flag [, mode=0777]) -> fd\n\n" + + "Open a file (for low level IO).\n\n" + + "Note that the mode argument is not currently supported on Jython."); + public static PyObject open(String path, int flag) { + return open(path, flag, 0777); + } + + public static PyObject open(String path, int flag, int mode) { + boolean reading = (flag & O_RDONLY) != 0; + boolean writing = (flag & O_WRONLY) != 0; + boolean updating = (flag & O_RDWR) != 0; + boolean creating = (flag & O_CREAT) != 0; + boolean appending = (flag & O_APPEND) != 0; + boolean truncating = (flag & O_TRUNC) != 0; + boolean exclusive = (flag & O_EXCL) != 0; + boolean sync = (flag & O_SYNC) != 0; + File file = new RelativeFile(path); + + if (updating && writing) { + throw Py.OSError(Errno.EINVAL, path); + } + if (!creating && !file.exists()) { + throw Py.OSError(Errno.ENOENT, path); + } + + if (!writing) { + if (updating) { + writing = true; + } else { + reading = true; + } + } + + if (truncating && !writing) { + // Explicitly truncate, writing will truncate anyway + new FileIO(path, "w").close(); + } + + if (exclusive && creating) { + try { + if (!file.createNewFile()) { + throw Py.OSError(Errno.EEXIST, path); + } + } catch (IOException ioe) { + throw Py.OSError(ioe); + } + } + + String fileIOMode = (reading ? "r" : "") + (!appending && writing ? "w" : "") + + (appending && (writing || updating) ? "a" : "") + (updating ? "+" : ""); + FileIO fileIO; + if (sync && (writing || updating)) { + try { + fileIO = new FileIO(new RandomAccessFile(file, "rws").getChannel(), fileIOMode); + } catch (FileNotFoundException fnfe) { + throw Py.OSError(file.isDirectory() ? Errno.EISDIR : Errno.ENOENT, path); + } + } else { + fileIO = new FileIO(path, fileIOMode); + } + + return Py.java2py(fileIO); + } + public static PyString __doc__stat = new PyString( "stat(path) -> stat result\n\n" + "Perform a stat system call on the given path.\n\n" + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-24 03:11:54
|
Revision: 6894 http://jython.svn.sourceforge.net/jython/?rev=6894&view=rev Author: pjenvey Date: 2009-10-24 03:11:46 +0000 (Sat, 24 Oct 2009) Log Message: ----------- improve isNumber/Mapping/SequenceType Modified Paths: -------------- trunk/jython/src/org/python/core/PyComplex.java trunk/jython/src/org/python/core/PyDictProxy.java trunk/jython/src/org/python/core/PyDictionary.java trunk/jython/src/org/python/core/PyFloat.java trunk/jython/src/org/python/core/PyInstance.java trunk/jython/src/org/python/core/PyInteger.java trunk/jython/src/org/python/core/PyLong.java trunk/jython/src/org/python/core/PyObject.java trunk/jython/src/org/python/core/PySequence.java trunk/jython/src/org/python/core/PyStringMap.java trunk/jython/src/org/python/modules/_collections/PyDeque.java Added Paths: ----------- trunk/jython/Lib/test/test_operator_jy.py Added: trunk/jython/Lib/test/test_operator_jy.py =================================================================== --- trunk/jython/Lib/test/test_operator_jy.py (rev 0) +++ trunk/jython/Lib/test/test_operator_jy.py 2009-10-24 03:11:46 UTC (rev 6894) @@ -0,0 +1,80 @@ +"""Misc operator module tests + +Made for Jython. +""" +import collections +import operator +import sys +import unittest +from test import test_support + +class OperatorTestCase(unittest.TestCase): + + class NewStyle(object): + pass + class OldStyle: + pass + class HasGetitem(object): + def __getitem__(self, name): + return 'foo' + class HasInt(object): + def __int__(self): + return 1 + class HasLong(object): + def __long__(self): + return 1 + class HasFloat(object): + def __float__(self): + return 1.0 + + # obj, isNumberType, isMappingType, isSequenceType + tests = ( + (type, False, False, False), + (type.__dict__, False, True, False), # dictproxy + (globals(), False, True, False), # stringmap + ({}, False, True, False), + ('', False, False, True), + (u'', False, False, True), + ([], False, False, True), + ((), False, False, True), + (xrange(5), False, False, True), + (set(), False, False, False), + (frozenset(), False, False, False), + (1, True, False, False), + (2L, True, False, False), + (3.0, True, False, False), + (4j, True, False, False), + (Exception(), False, False, True), + (collections.deque(), False, False, True), + (collections.defaultdict(), False, True, False), + (collections.namedtuple('test', 't'), False, False, False), + (NewStyle(), False, False, False), + (OldStyle(), not sys.platform.startswith('java'), False, False), + (HasGetitem(), False, True, True), + (HasInt(), True, False, False), + (HasFloat(), True, False, False), + ) + + def test_isNumberType(self): + for obj, isNumberType, _, _ in self.tests: + self.assert_istype(operator.isNumberType, obj, isNumberType) + + def test_isMappingType(self): + for obj, _, isMappingType, _ in self.tests: + self.assert_istype(operator.isMappingType, obj, isMappingType) + + def test_isSequenceType(self): + for obj, _, _, isSequenceType in self.tests: + self.assert_istype(operator.isSequenceType, obj, isSequenceType) + + def assert_istype(self, func, obj, result): + self.assertEqual(func(obj), result, '%s %s should be: %s' % + (type(obj), func.__name__, result)) + + +def test_main(): + test_support.run_unittest(OperatorTestCase) + + +if __name__ == "__main__": + test_main() Modified: trunk/jython/src/org/python/core/PyComplex.java =================================================================== --- trunk/jython/src/org/python/core/PyComplex.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PyComplex.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -712,6 +712,8 @@ return complex___getnewargs__(); } - public boolean isMappingType() { return false; } - public boolean isSequenceType() { return false; } + @Override + public boolean isNumberType() { + return true; + } } Modified: trunk/jython/src/org/python/core/PyDictProxy.java =================================================================== --- trunk/jython/src/org/python/core/PyDictProxy.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PyDictProxy.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -20,14 +20,17 @@ this.dict = dict; } + @Override public PyObject __iter__() { return dict.__iter__(); } + @Override public PyObject __finditem__(PyObject key) { return dict.__finditem__(key); } + @Override public int __len__() { return dict.__len__(); } @@ -87,6 +90,7 @@ return dict.invoke("copy"); } + @Override public int __cmp__(PyObject other) { return dictproxy___cmp__(other); } @@ -126,8 +130,19 @@ return dict.__ge__(other); } + @Override @ExposedMethod public PyString __str__() { return dict.__str__(); } + + @Override + public boolean isMappingType() { + return true; + } + + @Override + public boolean isSequenceType() { + return false; + } } Modified: trunk/jython/src/org/python/core/PyDictionary.java =================================================================== --- trunk/jython/src/org/python/core/PyDictionary.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PyDictionary.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -676,6 +676,12 @@ throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName())); } + @Override + public boolean isMappingType() { + return true; + } + + @Override public boolean isSequenceType() { return false; } Modified: trunk/jython/src/org/python/core/PyFloat.java =================================================================== --- trunk/jython/src/org/python/core/PyFloat.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PyFloat.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -628,6 +628,11 @@ return value; } + @Override + public boolean isNumberType() { + return true; + } + // standard singleton issues apply here to __getformat__/__setformat__, // but this is what Python demands @@ -681,8 +686,4 @@ } } } - - public boolean isMappingType() { return false; } - public boolean isSequenceType() { return false; } - } Modified: trunk/jython/src/org/python/core/PyInstance.java =================================================================== --- trunk/jython/src/org/python/core/PyInstance.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PyInstance.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -174,6 +174,21 @@ } @Override + public boolean isNumberType() { + return __findattr__("__int__") != null || __findattr__("__float__") != null; + } + + @Override + public boolean isMappingType() { + return __findattr__("__getitem__") != null; + } + + @Override + public boolean isSequenceType() { + return __findattr__("__getitem__") != null; + } + + @Override public boolean isIndex() { return __findattr__("__index__") != null; } Modified: trunk/jython/src/org/python/core/PyInteger.java =================================================================== --- trunk/jython/src/org/python/core/PyInteger.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PyInteger.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -825,6 +825,11 @@ } @Override + public boolean isNumberType() { + return true; + } + + @Override public boolean isIndex() { return true; } Modified: trunk/jython/src/org/python/core/PyLong.java =================================================================== --- trunk/jython/src/org/python/core/PyLong.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PyLong.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -864,6 +864,11 @@ } @Override + public boolean isNumberType() { + return true; + } + + @Override public boolean isIndex() { return true; } Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PyObject.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -523,20 +523,23 @@ return __call__(args, keywords); } - /* xxx fix these around */ - public boolean isCallable() { return getType().lookup("__call__") != null; } + public boolean isNumberType() { + PyType type = getType(); + return type.lookup("__int__") != null || type.lookup("__float__") != null; + } + public boolean isMappingType() { - return true; + PyType type = getType(); + return type.lookup("__getitem__") != null + && !(isSequenceType() && type.lookup("__getslice__") != null); } - public boolean isNumberType() { - return true; - } + public boolean isSequenceType() { - return true; + return getType().lookup("__getitem__") != null; } /** Modified: trunk/jython/src/org/python/core/PySequence.java =================================================================== --- trunk/jython/src/org/python/core/PySequence.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PySequence.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -414,6 +414,11 @@ return null; } + @Override + public boolean isSequenceType() { + return true; + } + protected final SequenceIndexDelegate delegator = new SequenceIndexDelegate() { @Override Modified: trunk/jython/src/org/python/core/PyStringMap.java =================================================================== --- trunk/jython/src/org/python/core/PyStringMap.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/core/PyStringMap.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -435,6 +435,16 @@ return new ValuesIter(table.values()); } + @Override + public boolean isMappingType() { + return true; + } + + @Override + public boolean isSequenceType() { + return false; + } + private abstract class StringMapIter<T> extends PyIterator { protected final Iterator<T> iterator; Modified: trunk/jython/src/org/python/modules/_collections/PyDeque.java =================================================================== --- trunk/jython/src/org/python/modules/_collections/PyDeque.java 2009-10-24 01:44:57 UTC (rev 6893) +++ trunk/jython/src/org/python/modules/_collections/PyDeque.java 2009-10-24 03:11:46 UTC (rev 6894) @@ -474,6 +474,16 @@ return pd; } + @Override + public boolean isMappingType() { + return false; + } + + @Override + public boolean isSequenceType() { + return true; + } + private static class Node { private Node left; private Node right; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-24 04:34:17
|
Revision: 6897 http://jython.svn.sourceforge.net/jython/?rev=6897&view=rev Author: pjenvey Date: 2009-10-24 04:34:03 +0000 (Sat, 24 Oct 2009) Log Message: ----------- treat numbers as smaller in _default_cmp's fallback fixes #1449 Modified Paths: -------------- trunk/jython/Lib/test/test_builtin_jy.py trunk/jython/Lib/test/test_cmp_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyObject.java Modified: trunk/jython/Lib/test/test_builtin_jy.py =================================================================== --- trunk/jython/Lib/test/test_builtin_jy.py 2009-10-24 04:21:18 UTC (rev 6896) +++ trunk/jython/Lib/test/test_builtin_jy.py 2009-10-24 04:34:03 UTC (rev 6897) @@ -25,6 +25,11 @@ return name self.assertEqual(dir(Foo()), []) + def test_numeric_cmp(self): + # http://bugs.jython.org/issue1449 + for numeric in 1, 2L, 3.0, 4j: + self.assertTrue(numeric < Ellipsis) + class LoopTest(unittest.TestCase): def test_break(self): Modified: trunk/jython/Lib/test/test_cmp_jy.py =================================================================== --- trunk/jython/Lib/test/test_cmp_jy.py 2009-10-24 04:21:18 UTC (rev 6896) +++ trunk/jython/Lib/test/test_cmp_jy.py 2009-10-24 04:34:03 UTC (rev 6897) @@ -60,15 +60,14 @@ baz.cmp = lambda other : Foo() self.assertEqual(cmp(100, baz), 0) baz.cmp = lambda other : NotImplemented - self.assertEqual(cmp(100, baz), 1) + # CPython is faulty here (returns 1) + self.assertEqual(cmp(100, baz), -1 if test_support.is_jython else 1) baz.cmp = lambda other: Bar() self.assertRaises(ValueError, cmp, 100, baz) baz.cmp = lambda other: 1 / 0 self.assertRaises(ZeroDivisionError, cmp, 100, baz) del Baz.__cmp__ - # CPython handles numbers differently than other types in - # object.c:default_3way_compare, and gets 1 here. we don't care - self.assert_(cmp(100, baz) in (-1, 1)) + self.assertEqual(cmp(100, baz), -1) def test_cmp_stops_short(self): class Foo(object): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-10-24 04:21:18 UTC (rev 6896) +++ trunk/jython/NEWS 2009-10-24 04:34:03 UTC (rev 6897) @@ -4,6 +4,7 @@ Bugs Fixed - [ 1478 ] defaultdict & weakref.WeakKeyDictionary [TypeError: first argument must be callable] - [ 1487 ] Import of module with latin-1 chars fails on utf-8 file encoding + - [ 1449 ] Ellipsis comparison different from Python 2.5 to Jython 2.5 - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-10-24 04:21:18 UTC (rev 6896) +++ trunk/jython/src/org/python/core/PyObject.java 2009-10-24 04:34:03 UTC (rev 6897) @@ -1299,25 +1299,33 @@ private final int _default_cmp(PyObject other) { int result; - if (this._is(other).__nonzero__()) + if (_is(other).__nonzero__()) return 0; /* None is smaller than anything */ - if (this == Py.None) + if (this == Py.None) { return -1; - if (other == Py.None) + } + if (other == Py.None) { return 1; + } // No rational way to compare these, so ask their classes to compare - PyType this_type = this.getType(); - PyType other_type = other.getType(); - if (this_type == other_type) { - return Py.id(this) < Py.id(other)? -1: 1; + PyType type = getType(); + PyType otherType = other.getType(); + if (type == otherType) { + return Py.id(this) < Py.id(other) ? -1 : 1; } - result = this_type.fastGetName().compareTo(other_type.fastGetName()); - if (result == 0) - return Py.id(this_type)<Py.id(other_type)? -1: 1; - return result < 0? -1: 1; + + // different type: compare type names; numbers are smaller + String typeName = isNumberType() ? "" : type.fastGetName(); + String otherTypeName = otherType.isNumberType() ? "" : otherType.fastGetName(); + result = typeName.compareTo(otherTypeName); + if (result == 0) { + // Same type name, or (more likely) incomparable numeric types + return Py.id(type) < Py.id(otherType) ? -1 : 1; + } + return result < 0 ? -1 : 1; } private final int _cmp_unsafe(PyObject other) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-24 07:19:11
|
Revision: 6899 http://jython.svn.sourceforge.net/jython/?rev=6899&view=rev Author: pjenvey Date: 2009-10-24 07:19:01 +0000 (Sat, 24 Oct 2009) Log Message: ----------- migrate more over to PosixModule and more lazy imports in posix.py Modified Paths: -------------- trunk/jython/Lib/posix.py trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/io/FileDescriptors.java trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-24 05:46:34 UTC (rev 6898) +++ trunk/jython/Lib/posix.py 2009-10-24 07:19:01 UTC (rev 6899) @@ -11,19 +11,12 @@ import _nt as _posix from _nt import * import errno -import jarray -import stat as _stat import sys -from java.io import File -from org.python.core.io import FileDescriptors, IOBase -from org.python.core.Py import newString as asPyString __all__ = [name for name in _posix.__all__ if not name.startswith('__doc__')] -__all__.extend(['access', 'chdir', 'chmod', 'close', 'fdopen', 'fsync', - 'ftruncate', 'getcwd', 'getcwdu', 'getenv', 'getpid', 'isatty', - 'lseek', 'mkdir', 'popen', 'putenv', 'read', 'remove', - 'rename', 'rmdir', 'system', 'umask', 'unlink', 'unsetenv', - 'urandom', 'utime', 'write']) +__all__.extend(['chmod', 'fsync', 'getenv', 'getpid', 'isatty', 'mkdir', + 'popen', 'putenv', 'remove', 'rename', 'rmdir', 'system', + 'umask', 'unlink', 'unsetenv', 'urandom', 'utime']) _name = _posix.__name__[1:] @@ -33,36 +26,6 @@ # For urandom urandom_source = None -# Lazily loaded path module -_path = None - -def getcwd(): - """getcwd() -> path - - Return a string representing the current working directory. - """ - return asPyString(sys.getCurrentWorkingDir()) - -def getcwdu(): - """getcwd() -> path - - Return a unicode string representing the current working directory. - """ - return sys.getCurrentWorkingDir() - -def chdir(path): - """chdir(path) - - Change the current working directory to the specified path. - """ - global _path - if not _stat.S_ISDIR(stat(path).st_mode): - raise OSError(errno.ENOTDIR, strerror(errno.ENOTDIR), path) - if _path is None: - import os - _path = os.path - sys.setCurrentWorkingDir(_path.realpath(path)) - def chmod(path, mode): """chmod(path, mode) @@ -70,6 +33,7 @@ """ # XXX no error handling for chmod in jna-posix # catch not found errors explicitly here, for now + from java.io import File abs_path = sys.getPath(path) if not File(abs_path).exists(): raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) @@ -83,6 +47,7 @@ The optional parameter is currently ignored. """ # XXX: use _posix_impl.mkdir when we can get the real errno upon failure + from java.io import File fp = File(sys.getPath(path)) if not fp.mkdir(): if fp.isDirectory() or fp.isFile(): @@ -97,6 +62,7 @@ Remove a file (same as unlink(path)). """ + from java.io import File if not File(sys.getPath(path)).delete(): raise OSError(0, "couldn't delete file", path) @@ -107,6 +73,7 @@ Rename a file or directory. """ + from java.io import File if not File(sys.getPath(path)).renameTo(File(sys.getPath(newpath))): raise OSError(0, "couldn't rename file", path) @@ -114,6 +81,7 @@ """rmdir(path) Remove a directory.""" + from java.io import File f = File(sys.getPath(path)) if not f.exists(): raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) @@ -122,34 +90,6 @@ elif not f.delete(): raise OSError(0, "couldn't delete directory", path) -def access(path, mode): - """access(path, mode) -> True if granted, False otherwise - - Use the real uid/gid to test for access to a path. Note that most - operations will use the effective uid/gid, therefore this routine can - be used in a suid/sgid environment to test if the invoking user has the - specified access to the path. The mode argument can be F_OK to test - existence, or the inclusive-OR of R_OK, W_OK, and X_OK. - """ - if not isinstance(mode, (int, long)): - raise TypeError('an integer is required') - - f = File(sys.getPath(path)) - result = True - if not f.exists(): - result = False - if mode & R_OK and not f.canRead(): - result = False - if mode & W_OK and not f.canWrite(): - result = False - if mode & X_OK: - # NOTE: always False without jna-posix stat - try: - result = (stat(path).st_mode & _stat.S_IEXEC) != 0 - except OSError: - result = False - return result - def utime(path, times): """utime(path, (atime, mtime)) utime(path, None) @@ -201,78 +141,6 @@ usec = 0 return floor, usec -def close(fd): - """close(fd) - - Close a file descriptor (for low level IO). - """ - rawio = FileDescriptors.get(fd) - _handle_oserror(rawio.close) - -def fdopen(fd, mode='r', bufsize=-1): - """fdopen(fd [, mode='r' [, bufsize]]) -> file_object - - Return an open file object connected to a file descriptor. - """ - rawio = FileDescriptors.get(fd) - if (len(mode) and mode[0] or '') not in 'rwa': - raise ValueError("invalid file mode '%s'" % mode) - if rawio.closed(): - raise OSError(errno.EBADF, strerror(errno.EBADF)) - - try: - fp = FileDescriptors.wrap(rawio, mode, bufsize) - except IOError: - raise OSError(errno.EINVAL, strerror(errno.EINVAL)) - return fp - -def ftruncate(fd, length): - """ftruncate(fd, length) - - Truncate a file to a specified length. - """ - rawio = FileDescriptors.get(fd) - try: - rawio.truncate(length) - except Exception, e: - raise IOError(errno.EBADF, strerror(errno.EBADF)) - -def lseek(fd, pos, how): - """lseek(fd, pos, how) -> newpos - - Set the current position of a file descriptor. - """ - rawio = FileDescriptors.get(fd) - return _handle_oserror(rawio.seek, pos, how) - -def read(fd, buffersize): - """read(fd, buffersize) -> string - - Read a file descriptor. - """ - from org.python.core.util import StringUtil - rawio = FileDescriptors.get(fd) - buf = _handle_oserror(rawio.read, buffersize) - return asPyString(StringUtil.fromBytes(buf)) - -def write(fd, string): - """write(fd, string) -> byteswritten - - Write a string to a file descriptor. - """ - from java.nio import ByteBuffer - from org.python.core.util import StringUtil - rawio = FileDescriptors.get(fd) - return _handle_oserror(rawio.write, - ByteBuffer.wrap(StringUtil.toBytes(string))) - -def _handle_oserror(func, *args, **kwargs): - """Translate exceptions into OSErrors""" - try: - return func(*args, **kwargs) - except: - raise OSError(errno.EBADF, strerror(errno.EBADF)) - def system(command): """system(command) -> exit_status @@ -442,7 +310,7 @@ """wait() -> (pid, status) Wait for completion of a child process.""" - + import jarray status = jarray.zeros(1, 'i') res_pid = _posix_impl.wait(status) if res_pid == -1: @@ -453,6 +321,7 @@ """waitpid(pid, options) -> (pid, status) Wait for completion of a given child process.""" + import jarray status = jarray.zeros(1, 'i') res_pid = _posix_impl.waitpid(pid, status, options) if res_pid == -1: @@ -481,6 +350,7 @@ def _fsync(fd, metadata): """Internal fsync impl""" + from org.python.core.io import FileDescriptors rawio = FileDescriptors.get(fd) rawio.checkClosed() @@ -524,6 +394,7 @@ if isinstance(fileno, FileDescriptor): return _posix_impl.isatty(fileno) + from org.python.core.io import IOBase if not isinstance(fileno, IOBase): raise TypeError('a file descriptor is required') @@ -540,6 +411,7 @@ if urandom_source is None: from java.security import SecureRandom urandom_source = SecureRandom() + import jarray buffer = jarray.zeros(n, 'b') urandom_source.nextBytes(buffer) return buffer.tostring() Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-10-24 05:46:34 UTC (rev 6898) +++ trunk/jython/src/org/python/core/Py.java 2009-10-24 07:19:01 UTC (rev 6899) @@ -108,6 +108,12 @@ return fromIOException(ioe, Py.OSError); } + public static PyException OSError(Constant errno) { + int value = errno.value(); + PyObject args = new PyTuple(Py.newInteger(value), PosixModule.strerror(value)); + return new PyException(Py.OSError, args); + } + public static PyException OSError(Constant errno, String filename) { int value = errno.value(); // Pass to strerror because constantine currently lacks Errno descriptions on Modified: trunk/jython/src/org/python/core/io/FileDescriptors.java =================================================================== --- trunk/jython/src/org/python/core/io/FileDescriptors.java 2009-10-24 05:46:34 UTC (rev 6898) +++ trunk/jython/src/org/python/core/io/FileDescriptors.java 2009-10-24 07:19:01 UTC (rev 6899) @@ -2,7 +2,6 @@ package org.python.core.io; import org.python.core.Py; -import org.python.core.PyFile; import org.python.core.PyObject; /** @@ -14,10 +13,6 @@ */ public class FileDescriptors { - public static PyFile wrap(RawIOBase raw, String mode, int bufsize) { - return new PyFile(raw, "<fdopen>", mode, bufsize); - } - /** * Return the RawIOBase associated with the specified file descriptor. * Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-24 05:46:34 UTC (rev 6898) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-24 07:19:01 UTC (rev 6899) @@ -8,6 +8,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; +import java.nio.ByteBuffer; import java.util.Map; import org.jruby.ext.posix.JavaPOSIX; @@ -17,12 +18,18 @@ import org.python.core.ClassDictInit; import org.python.core.Py; import org.python.core.PyDictionary; +import org.python.core.PyException; +import org.python.core.PyFile; import org.python.core.PyList; import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyTuple; +import org.python.core.imp; +import org.python.core.io.FileDescriptors; import org.python.core.io.FileIO; +import org.python.core.io.RawIOBase; import org.python.core.util.RelativeFile; +import org.python.core.util.StringUtil; /** * The underlying _posix or _nt module, named depending on the platform. @@ -57,6 +64,15 @@ private static int O_TRUNC = 0x400; private static int O_EXCL = 0x800; + /** os.access constants. */ + private static int F_OK = 0; + private static int X_OK = 1 << 0; + private static int W_OK = 1 << 1; + private static int R_OK = 1 << 2; + + /** os.path.realpath function for use by chdir. Lazily loaded. */ + private static PyObject realpath; + public static void classDictInit(PyObject dict) { // only expose the open flags we support dict.__setitem__("O_RDONLY", Py.newInteger(O_RDONLY)); @@ -68,11 +84,10 @@ dict.__setitem__("O_TRUNC", Py.newInteger(O_TRUNC)); dict.__setitem__("O_EXCL", Py.newInteger(O_EXCL)); - // os.access constants - dict.__setitem__("F_OK", Py.Zero); - dict.__setitem__("X_OK", Py.newInteger(1 << 0)); - dict.__setitem__("W_OK", Py.newInteger(1 << 1)); - dict.__setitem__("R_OK", Py.newInteger(1 << 2)); + dict.__setitem__("F_OK", Py.newInteger(F_OK)); + dict.__setitem__("X_OK", Py.newInteger(X_OK)); + dict.__setitem__("W_OK", Py.newInteger(W_OK)); + dict.__setitem__("R_OK", Py.newInteger(R_OK)); // Successful termination dict.__setitem__("EX_OK", Py.Zero); @@ -86,6 +101,7 @@ dict.__setitem__("classDictInit", null); dict.__setitem__("getPOSIX", null); dict.__setitem__("getOSName", null); + dict.__setitem__("badFD", null); dict.__setitem__("__all__", dict.invoke("keys")); @@ -104,6 +120,129 @@ System.exit(status); } + public static PyString __doc__access = new PyString( + "access(path, mode) -> True if granted, False otherwise\n\n" + + "Use the real uid/gid to test for access to a path. Note that most\n" + + "operations will use the effective uid/gid, therefore this routine can\n" + + "be used in a suid/sgid environment to test if the invoking user has the\n" + + "specified access to the path. The mode argument can be F_OK to test\n" + + "existence, or the inclusive-OR of R_OK, W_OK, and X_OK."); + public static boolean access(String path, int mode) { + boolean result = true; + File file = new RelativeFile(path); + + if (!file.exists()) { + result = false; + } + if ((mode & R_OK) != 0 && !file.canRead()) { + result = false; + } + if ((mode & W_OK) != 0 && !file.canWrite()) { + result = false; + } + if ((mode & X_OK) != 0) { + // NOTE: always true without native jna-posix stat + try { + result = posix.stat(file.getPath()).isExecutable(); + } catch (PyException pye) { + if (!pye.match(Py.OSError)) { + throw pye; + } + // ENOENT + result = false; + } + } + return result; + } + + public static PyString __doc__chdir = new PyString( + "chdir(path)\n\n" + + "Change the current working directory to the specified path."); + public static void chdir(PyObject pathObj) { + if (!(pathObj instanceof PyString)) { + throw Py.TypeError(String.format("coercing to Unicode: need string, '%s' type found", + pathObj.getType().fastGetName())); + } + + String path = pathObj.toString(); + // stat raises ENOENT for us if path doesn't exist + if (!posix.stat(new RelativeFile(path).getPath()).isDirectory()) { + throw Py.OSError(Errno.ENOTDIR, path); + } + + if (realpath == null) { + realpath = imp.load("os.path").__getattr__("realpath"); + } + Py.getSystemState().setCurrentWorkingDir(realpath.__call__(pathObj).toString()); + } + + public static PyString __doc__close = new PyString( + "close(fd)\n\n" + + "Close a file descriptor (for low level IO)."); + public static void close(PyObject fd) { + try { + FileDescriptors.get(fd).close(); + } catch (PyException pye) { + badFD(); + } + } + + public static PyString __doc__fdopen = new PyString( + "fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n\n" + + "Return an open file object connected to a file descriptor."); + public static PyObject fdopen(PyObject fd) { + return fdopen(fd, "r"); + + } + + public static PyObject fdopen(PyObject fd, String mode) { + return fdopen(fd, mode, -1); + + } + public static PyObject fdopen(PyObject fd, String mode, int bufsize) { + if (mode.length() == 0 || !"rwa".contains("" + mode.charAt(0))) { + throw Py.ValueError(String.format("invalid file mode '%s'", mode)); + } + RawIOBase rawIO = FileDescriptors.get(fd); + if (rawIO.closed()) { + badFD(); + } + + try { + return new PyFile(rawIO, "<fdopen>", mode, bufsize); + } catch (PyException pye) { + if (!pye.match(Py.IOError)) { + throw pye; + } + throw Py.OSError(Errno.EINVAL); + } + } + + public static PyString __doc__ftruncate = new PyString( + "ftruncate(fd, length)\n\n" + + "Truncate a file to a specified length."); + public static void ftruncate(PyObject fd, long length) { + try { + FileDescriptors.get(fd).truncate(length); + } catch (PyException pye) { + throw Py.IOError(Errno.EBADF); + } + } + + public static PyString __doc___getcwd = new PyString( + "getcwd() -> path\n\n" + + "Return a string representing the current working directory."); + public static PyObject getcwd() { + return Py.newString(Py.getSystemState().getCurrentWorkingDir()); + } + + public static PyString __doc___getcwdu = new PyString( + "getcwd() -> path\n\n" + + "Return a unicode string representing the current working directory."); + public static PyObject getcwdu() { + return Py.newUnicode(Py.getSystemState().getCurrentWorkingDir()); + } + public static PyString __doc__listdir = new PyString( "listdir(path) -> list_of_strings\n\n" + "Return a list containing the names of the entries in the directory.\n\n" + @@ -123,6 +262,18 @@ return list; } + public static PyString __doc__lseek = new PyString( + "lseek(fd, pos, how) -> newpos\n\n" + + "Set the current position of a file descriptor."); + public static long lseek(PyObject fd, long pos, int how) { + try { + return FileDescriptors.get(fd).seek(pos, how); + } catch (PyException pye) { + badFD(); + return -1; + } + } + public static PyString __doc__lstat = new PyString( "lstat(path) -> stat result\n\n" + "Like stat(path), but do not follow symbolic links."); @@ -134,11 +285,11 @@ "open(filename, flag [, mode=0777]) -> fd\n\n" + "Open a file (for low level IO).\n\n" + "Note that the mode argument is not currently supported on Jython."); - public static PyObject open(String path, int flag) { + public static FileIO open(String path, int flag) { return open(path, flag, 0777); } - public static PyObject open(String path, int flag, int mode) { + public static FileIO open(String path, int flag, int mode) { boolean reading = (flag & O_RDONLY) != 0; boolean writing = (flag & O_WRONLY) != 0; boolean updating = (flag & O_RDWR) != 0; @@ -181,18 +332,26 @@ String fileIOMode = (reading ? "r" : "") + (!appending && writing ? "w" : "") + (appending && (writing || updating) ? "a" : "") + (updating ? "+" : ""); - FileIO fileIO; if (sync && (writing || updating)) { try { - fileIO = new FileIO(new RandomAccessFile(file, "rws").getChannel(), fileIOMode); + return new FileIO(new RandomAccessFile(file, "rws").getChannel(), fileIOMode); } catch (FileNotFoundException fnfe) { throw Py.OSError(file.isDirectory() ? Errno.EISDIR : Errno.ENOENT, path); } - } else { - fileIO = new FileIO(path, fileIOMode); } + return new FileIO(path, fileIOMode); + } - return Py.java2py(fileIO); + public static PyString __doc__read = new PyString( + "read(fd, buffersize) -> string\n\n" + + "Read a file descriptor."); + public static String read(PyObject fd, int buffersize) { + try { + return StringUtil.fromBytes(FileDescriptors.get(fd).read(buffersize)); + } catch (PyException pye) { + badFD(); + return null; + } } public static PyString __doc__stat = new PyString( @@ -221,6 +380,18 @@ return new PyString(errno.toString()); } + public static PyString __doc__write = new PyString( + "write(fd, string) -> byteswritten\n\n" + + "Write a string to a file descriptor."); + public static int write(PyObject fd, String string) { + try { + return FileDescriptors.get(fd).write(ByteBuffer.wrap(StringUtil.toBytes(string))); + } catch (PyException pye) { + badFD(); + return -1; + } + } + /** * Helper function for the subprocess module, returns the potential shell commands for * this OS. @@ -259,6 +430,10 @@ return environ; } + private static void badFD() { + throw Py.OSError(Errno.EBADF); + } + public static POSIX getPOSIX() { return posix; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-26 04:16:55
|
Revision: 6902 http://jython.svn.sourceforge.net/jython/?rev=6902&view=rev Author: pjenvey Date: 2009-10-26 04:16:36 +0000 (Mon, 26 Oct 2009) Log Message: ----------- fix handling of the corner case where the winning metatype differs from the specified type. we were calling the wrong __new__, and its __init__ twice Modified Paths: -------------- trunk/jython/Lib/test/test_class_jy.py trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/Lib/test/test_class_jy.py =================================================================== --- trunk/jython/Lib/test/test_class_jy.py 2009-10-25 18:31:36 UTC (rev 6901) +++ trunk/jython/Lib/test/test_class_jy.py 2009-10-26 04:16:36 UTC (rev 6902) @@ -190,7 +190,23 @@ raise IndexError, "Fraid not" self.assertRaises(IndexError, A().__getitem__, 'b') + def test_winning_metatype(self): + class Meta(type): + def __new__(cls, name, bases, attrs): + attrs['spam'] = name + attrs['counter'] = 0 + return type.__new__(cls, name, bases, attrs) + def __init__(cls, name, bases, attrs): + cls.counter += 1 + class Base(object): + __metaclass__ = Meta + Foo = type('Foo', (Base,), {}) + # Previously we called the wrong __new__ + self.assertEqual(Foo.spam, 'Foo') + # and called __init__ twice + self.assertEqual(Foo.counter, 1) + class ClassNamelessModuleTestCase(unittest.TestCase): def setUp(self): Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-10-25 18:31:36 UTC (rev 6901) +++ trunk/jython/src/org/python/core/PyType.java 2009-10-26 04:16:36 UTC (rev 6902) @@ -144,11 +144,10 @@ PyType winner = findMostDerivedMetatype(tmpBases, metatype); if (winner != metatype) { - PyObject winner_new_ = winner.lookup("__new__"); - if (winner_new_ != null && winner_new_ != new_) { - return invoke_new_(new_, winner, false, - new PyObject[] {new PyString(name), bases, dict}, - Py.NoKeywords); + PyObject winnerNew = winner.lookup("__new__"); + if (winnerNew != null && winnerNew != new_) { + return invokeNew(winnerNew, winner, false, + new PyObject[] {new PyString(name), bases, dict}, Py.NoKeywords); } metatype = winner; } @@ -438,24 +437,19 @@ } } - private static PyObject invoke_new_(PyObject new_, PyType type, boolean init, PyObject[] args, - String[] keywords) { - PyObject newobj; + private static PyObject invokeNew(PyObject new_, PyType type, boolean init, PyObject[] args, + String[] keywords) { + PyObject obj; if (new_ instanceof PyNewWrapper) { - newobj = ((PyNewWrapper)new_).new_impl(init, type, args, keywords); + obj = ((PyNewWrapper)new_).new_impl(init, type, args, keywords); } else { int n = args.length; - PyObject[] type_prepended = new PyObject[n + 1]; - System.arraycopy(args, 0, type_prepended, 1, n); - type_prepended[0] = type; - newobj = new_.__get__(null, type).__call__(type_prepended, keywords); + PyObject[] typePrepended = new PyObject[n + 1]; + System.arraycopy(args, 0, typePrepended, 1, n); + typePrepended[0] = type; + obj = new_.__get__(null, type).__call__(typePrepended, keywords); } - // special case type(x) - if (type == TYPE && args.length == 1 && keywords.length == 0) { - return newobj; - } - newobj.dispatch__init__(type, args, keywords); - return newobj; + return obj; } /** @@ -1479,9 +1473,16 @@ final PyObject type___call__(PyObject[] args, String[] keywords) { PyObject new_ = lookup("__new__"); if (!instantiable || new_ == null) { - throw Py.TypeError("cannot create '" + name + "' instances"); + throw Py.TypeError(String.format("cannot create '%.100s' instances", name)); } - return invoke_new_(new_, this, true, args, keywords); + + PyObject obj = invokeNew(new_, this, true, args, keywords); + // special case type(x) + if (this == TYPE && args.length == 1 && keywords.length == 0) { + return obj; + } + obj.dispatch__init__(this, args, keywords); + return obj; } protected void __rawdir__(PyDictionary accum) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-27 22:16:29
|
Revision: 6917 http://jython.svn.sourceforge.net/jython/?rev=6917&view=rev Author: pjenvey Date: 2009-10-27 22:16:17 +0000 (Tue, 27 Oct 2009) Log Message: ----------- is{Number,Mapping,Sequence}Type are unnecessary for PyNone now Modified Paths: -------------- trunk/jython/Lib/test/test_operator_jy.py trunk/jython/src/org/python/core/PyNone.java Modified: trunk/jython/Lib/test/test_operator_jy.py =================================================================== --- trunk/jython/Lib/test/test_operator_jy.py 2009-10-27 22:09:16 UTC (rev 6916) +++ trunk/jython/Lib/test/test_operator_jy.py 2009-10-27 22:16:17 UTC (rev 6917) @@ -44,6 +44,8 @@ (2L, True, False, False), (3.0, True, False, False), (4j, True, False, False), + (None, False, False, False), + (Ellipsis, False, False, False), (Exception(), False, False, True), (collections.deque(), False, False, True), (collections.defaultdict(), False, True, False), Modified: trunk/jython/src/org/python/core/PyNone.java =================================================================== --- trunk/jython/src/org/python/core/PyNone.java 2009-10-27 22:09:16 UTC (rev 6916) +++ trunk/jython/src/org/python/core/PyNone.java 2009-10-27 22:16:17 UTC (rev 6917) @@ -1,4 +1,7 @@ -// Copyright (c) Corporation for National Research Initiatives +/* + * Copyright (c) Corporation for National Research Initiatives + * Copyright (c) Jython Developers + */ package org.python.core; import java.io.Serializable; @@ -7,11 +10,10 @@ import org.python.expose.ExposedType; /** - * A class representing the singleton None object, + * The singleton None object. */ @ExposedType(name = "NoneType", isBaseType = false) -public class PyNone extends PyObject implements Serializable -{ +public class PyNone extends PyObject implements Serializable { public static final PyType TYPE = PyType.fromClass(PyNone.class); @@ -19,24 +21,25 @@ super(TYPE); } - private Object writeReplace() { - return new Py.SingletonResolver("None"); - } - + @Override public boolean __nonzero__() { return false; } - public Object __tojava__(Class c) { - //Danger here. java.lang.Object gets null not None - if (c == PyObject.class) + @Override + public Object __tojava__(Class<?> c) { + if (c == PyObject.class) { return this; - if (c.isPrimitive()) + } + if (c.isPrimitive()) { return Py.NoConversion; + } + // Java gets null return null; } - public String toString() throws PyIgnoreMethodTag { + @Override + public String toString() { return NoneType_toString(); } @@ -45,23 +48,17 @@ return "None"; } - public boolean isMappingType() { - return false; - } - - public boolean isSequenceType() { - return false; - } - - public boolean isNumberType() { - return false; - } - + @Override public String asStringOrNull(int index) { return null; } + @Override public String asStringOrNull() { return null; } + + private Object writeReplace() { + return new Py.SingletonResolver("None"); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-27 23:55:02
|
Revision: 6920 http://jython.svn.sourceforge.net/jython/?rev=6920&view=rev Author: pjenvey Date: 2009-10-27 23:54:38 +0000 (Tue, 27 Oct 2009) Log Message: ----------- o move chmod/mkdir to PosixModule and add chown, using the newer jna-posix errno() for accurate error messages fixes #1470, 1493 o attempt to figure out listdir failure errnos fixes #1496 o guard against null paths in PosixModule refs #1369 Modified Paths: -------------- trunk/jython/Lib/posix.py trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-27 23:49:37 UTC (rev 6919) +++ trunk/jython/Lib/posix.py 2009-10-27 23:54:38 UTC (rev 6920) @@ -14,9 +14,9 @@ import sys __all__ = [name for name in _posix.__all__ if not name.startswith('__doc__')] -__all__.extend(['chmod', 'fsync', 'getenv', 'getpid', 'isatty', 'mkdir', - 'popen', 'putenv', 'remove', 'rename', 'rmdir', 'system', - 'umask', 'unlink', 'unsetenv', 'urandom', 'utime']) +__all__.extend(['fsync', 'getenv', 'getpid', 'isatty', 'popen', 'putenv', + 'remove', 'rename', 'rmdir', 'system', 'umask', 'unlink', + 'unsetenv', 'urandom', 'utime']) _name = _posix.__name__[1:] @@ -26,37 +26,6 @@ # For urandom urandom_source = None -def chmod(path, mode): - """chmod(path, mode) - - Change the access permissions of a file. - """ - # XXX no error handling for chmod in jna-posix - # catch not found errors explicitly here, for now - from java.io import File - abs_path = sys.getPath(path) - if not File(abs_path).exists(): - raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) - _posix_impl.chmod(abs_path, mode) - -def mkdir(path, mode='ignored'): - """mkdir(path [, mode=0777]) - - Create a directory. - - The optional parameter is currently ignored. - """ - # XXX: use _posix_impl.mkdir when we can get the real errno upon failure - from java.io import File - fp = File(sys.getPath(path)) - if not fp.mkdir(): - if fp.isDirectory() or fp.isFile(): - err = errno.EEXIST - else: - err = 0 - msg = strerror(err) if err else "couldn't make directory" - raise OSError(err, msg, path) - def remove(path): """remove(path) @@ -369,6 +338,8 @@ """getpid() -> pid Return the current process id.""" + # XXX: getpid and umask should really be hidden from __all__ when + # not _native_posix return _posix_impl.getpid() def isatty(fileno): Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-27 23:49:37 UTC (rev 6919) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-27 23:54:38 UTC (rev 6920) @@ -11,6 +11,7 @@ import java.nio.ByteBuffer; import java.util.Map; +import org.jruby.ext.posix.FileStat; import org.jruby.ext.posix.JavaPOSIX; import org.jruby.ext.posix.POSIX; import org.jruby.ext.posix.POSIXFactory; @@ -128,6 +129,7 @@ "specified access to the path. The mode argument can be F_OK to test\n" + "existence, or the inclusive-OR of R_OK, W_OK, and X_OK."); public static boolean access(String path, int mode) { + ensurePath(path); boolean result = true; File file = new RelativeFile(path); @@ -166,7 +168,7 @@ String path = pathObj.toString(); // stat raises ENOENT for us if path doesn't exist - if (!posix.stat(new RelativeFile(path).getPath()).isDirectory()) { + if (!posix.stat(absolutePath(path)).isDirectory()) { throw Py.OSError(Errno.ENOTDIR, path); } @@ -176,6 +178,24 @@ Py.getSystemState().setCurrentWorkingDir(realpath.__call__(pathObj).toString()); } + public static PyString __doc__chmod = new PyString( + "chmod(path, mode)\n\n" + + "Change the access permissions of a file."); + public static void chmod(String path, int mode) { + if (posix.chmod(absolutePath(path), mode) < 0) { + throw errorFromErrno(path); + } + } + + public static PyString __doc__chown = new PyString( + "chown(path, uid, gid)\n\n" + + "Change the owner and group id of path to the numeric uid and gid."); + public static void chown(String path, int uid, int gid) { + if (posix.chown(absolutePath(path), uid, gid) < 0) { + throw errorFromErrno(path); + } + } + public static PyString __doc__close = new PyString( "close(fd)\n\n" + "Close a file descriptor (for low level IO)."); @@ -183,7 +203,7 @@ try { FileDescriptors.get(fd).close(); } catch (PyException pye) { - badFD(); + throw badFD(); } } @@ -205,7 +225,7 @@ } RawIOBase rawIO = FileDescriptors.get(fd); if (rawIO.closed()) { - badFD(); + throw badFD(); } try { @@ -250,14 +270,27 @@ "The list is in arbitrary order. It does not include the special\n" + "entries '.' and '..' even if they are present in the directory."); public static PyList listdir(String path) { + ensurePath(path); PyList list = new PyList(); - String[] files = new RelativeFile(path).list(); + File file = new RelativeFile(path); + String[] names = file.list(); - if (files == null) { - throw Py.OSError("No such directory: " + path); + if (names == null) { + // Can't read the path for some reason. stat will throw an error if it can't + // read it either + FileStat stat = posix.stat(file.getPath()); + // It exists, maybe not a dir, or we don't have permission? + if (!stat.isDirectory()) { + throw Py.OSError(Errno.ENOTDIR, path); + } + if (!file.canRead()) { + throw Py.OSError(Errno.EACCES, path); + } + // + throw Py.OSError("listdir(): an unknown error occured: " + path); } - for (String file : files) { - list.append(new PyString(file)); + for (String name : names) { + list.append(new PyString(name)); } return list; } @@ -269,8 +302,7 @@ try { return FileDescriptors.get(fd).seek(pos, how); } catch (PyException pye) { - badFD(); - return -1; + throw badFD(); } } @@ -278,9 +310,22 @@ "lstat(path) -> stat result\n\n" + "Like stat(path), but do not follow symbolic links."); public static PyObject lstat(String path) { - return PyStatResult.fromFileStat(posix.lstat(new RelativeFile(path).getPath())); + return PyStatResult.fromFileStat(posix.lstat(absolutePath(path))); } + public static PyString __doc__mkdir = new PyString( + "mkdir(path [, mode=0777])\n\n" + + "Create a directory."); + public static void mkdir(String path) { + mkdir(path, 0777); + } + + public static void mkdir(String path, int mode) { + if (posix.mkdir(absolutePath(path), mode) < 0) { + throw errorFromErrno(path); + } + } + public static PyString __doc__open = new PyString( "open(filename, flag [, mode=0777]) -> fd\n\n" + "Open a file (for low level IO).\n\n" + @@ -290,6 +335,7 @@ } public static FileIO open(String path, int flag, int mode) { + ensurePath(path); boolean reading = (flag & O_RDONLY) != 0; boolean writing = (flag & O_WRONLY) != 0; boolean updating = (flag & O_RDWR) != 0; @@ -349,8 +395,7 @@ try { return StringUtil.fromBytes(FileDescriptors.get(fd).read(buffersize)); } catch (PyException pye) { - badFD(); - return null; + throw badFD(); } } @@ -360,7 +405,7 @@ "Note that some platforms may return only a small subset of the\n" + "standard fields"); public static PyObject stat(String path) { - return PyStatResult.fromFileStat(posix.stat(new RelativeFile(path).getPath())); + return PyStatResult.fromFileStat(posix.stat(absolutePath(path))); } public static PyString __doc__strerror = new PyString( @@ -387,8 +432,7 @@ try { return FileDescriptors.get(fd).write(ByteBuffer.wrap(StringUtil.toBytes(string))); } catch (PyException pye) { - badFD(); - return -1; + throw badFD(); } } @@ -430,10 +474,31 @@ return environ; } - private static void badFD() { - throw Py.OSError(Errno.EBADF); + /** + * Return the absolute form of path. + * + * @param path a path String, raising a TypeError when null + * @return an absolute path String + */ + private static String absolutePath(String path) { + ensurePath(path); + return new RelativeFile(path).getPath(); } + private static void ensurePath(String path) { + if (path == null) { + throw Py.TypeError("coercing to Unicode: need string or buffer, NoneType found"); + } + } + + private static PyException badFD() { + return Py.OSError(Errno.EBADF); + } + + private static PyException errorFromErrno(String path) { + return Py.OSError(Errno.valueOf(posix.errno()), path); + } + public static POSIX getPOSIX() { return posix; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-28 02:28:46
|
Revision: 6921 http://jython.svn.sourceforge.net/jython/?rev=6921&view=rev Author: pjenvey Date: 2009-10-28 02:28:34 +0000 (Wed, 28 Oct 2009) Log Message: ----------- o more over to PosixModule, so we don't need the builtin-in function class var workaround for tempfile refs #1396 o bring back the PosixModule method hider with hiding per OS and whether the posix impl is native Modified Paths: -------------- trunk/jython/CPythonLib.includes trunk/jython/Lib/posix.py trunk/jython/Lib/test/test_tempfile.py trunk/jython/src/org/python/modules/posix/PosixModule.java Added Paths: ----------- trunk/jython/src/org/python/modules/posix/Hider.java Removed Paths: ------------- trunk/jython/Lib/tempfile.py Modified: trunk/jython/CPythonLib.includes =================================================================== --- trunk/jython/CPythonLib.includes 2009-10-27 23:54:38 UTC (rev 6920) +++ trunk/jython/CPythonLib.includes 2009-10-28 02:28:34 UTC (rev 6921) @@ -134,6 +134,7 @@ tabnanny.py this.py textwrap.py +tempfile.py token.py tokenize.py trace.py Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-10-27 23:54:38 UTC (rev 6920) +++ trunk/jython/Lib/posix.py 2009-10-28 02:28:34 UTC (rev 6921) @@ -14,8 +14,8 @@ import sys __all__ = [name for name in _posix.__all__ if not name.startswith('__doc__')] -__all__.extend(['fsync', 'getenv', 'getpid', 'isatty', 'popen', 'putenv', - 'remove', 'rename', 'rmdir', 'system', 'umask', 'unlink', +__all__.extend(['fsync', 'getenv', 'isatty', 'popen', 'putenv', + 'rename', 'rmdir', 'system', 'unsetenv', 'urandom', 'utime']) _name = _posix.__name__[1:] @@ -26,17 +26,6 @@ # For urandom urandom_source = None -def remove(path): - """remove(path) - - Remove a file (same as unlink(path)). - """ - from java.io import File - if not File(sys.getPath(path)).delete(): - raise OSError(0, "couldn't delete file", path) - -unlink = remove - def rename(path, newpath): """rename(old, new) @@ -181,13 +170,6 @@ return os.environ.get(key, default) if _name == 'posix': - def link(src, dst): - """link(src, dst) - - Create a hard link to a file. - """ - _posix_impl.link(sys.getPath(src), sys.getPath(dst)) - def symlink(src, dst): """symlink(src, dst) @@ -305,7 +287,7 @@ """ _fsync(fd, False) - __all__.extend(['link', 'symlink', 'readlink', 'getegid', 'geteuid', + __all__.extend(['symlink', 'readlink', 'getegid', 'geteuid', 'getgid', 'getlogin', 'getpgrp', 'getppid', 'getuid', 'setpgrp', 'setsid', 'kill', 'wait', 'waitpid', 'fdatasync']) @@ -334,14 +316,6 @@ except IOException, ioe: raise OSError(ioe) -def getpid(): - """getpid() -> pid - - Return the current process id.""" - # XXX: getpid and umask should really be hidden from __all__ when - # not _native_posix - return _posix_impl.getpid() - def isatty(fileno): """isatty(fd) -> bool @@ -371,12 +345,6 @@ return fileno.isatty() -def umask(new_mask): - """umask(new_mask) -> old_mask - - Set the current numeric umask and return the previous umask.""" - return _posix_impl.umask(int(new_mask)) - def urandom(n): global urandom_source if urandom_source is None: Deleted: trunk/jython/Lib/tempfile.py =================================================================== --- trunk/jython/Lib/tempfile.py 2009-10-27 23:54:38 UTC (rev 6920) +++ trunk/jython/Lib/tempfile.py 2009-10-28 02:28:34 UTC (rev 6921) @@ -1,494 +0,0 @@ -"""Temporary files. - -This module provides generic, low- and high-level interfaces for -creating temporary files and directories. The interfaces listed -as "safe" just below can be used without fear of race conditions. -Those listed as "unsafe" cannot, and are provided for backward -compatibility only. - -This module also provides some data items to the user: - - TMP_MAX - maximum number of names that will be tried before - giving up. - template - the default prefix for all temporary names. - You may change this to control the default prefix. - tempdir - If this is set to a string before the first use of - any routine from this module, it will be considered as - another candidate location to store temporary files. -""" - -__all__ = [ - "NamedTemporaryFile", "TemporaryFile", # high level safe interfaces - "mkstemp", "mkdtemp", # low level safe interfaces - "mktemp", # deprecated unsafe interface - "TMP_MAX", "gettempprefix", # constants - "tempdir", "gettempdir" - ] - - -# Imports. - -import os as _os -import errno as _errno -from random import Random as _Random - -if _os.name == 'mac': - import Carbon.Folder as _Folder - import Carbon.Folders as _Folders - -try: - import fcntl as _fcntl -except ImportError: - def _set_cloexec(fd): - pass -else: - def _set_cloexec(fd): - try: - flags = _fcntl.fcntl(fd, _fcntl.F_GETFD, 0) - except IOError: - pass - else: - # flags read successfully, modify - flags |= _fcntl.FD_CLOEXEC - _fcntl.fcntl(fd, _fcntl.F_SETFD, flags) - - -try: - import thread as _thread -except ImportError: - import dummy_thread as _thread -_allocate_lock = _thread.allocate_lock - -_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL -if hasattr(_os, 'O_NOINHERIT'): - _text_openflags |= _os.O_NOINHERIT -if hasattr(_os, 'O_NOFOLLOW'): - _text_openflags |= _os.O_NOFOLLOW - -_bin_openflags = _text_openflags -if hasattr(_os, 'O_BINARY'): - _bin_openflags |= _os.O_BINARY - -if hasattr(_os, 'TMP_MAX'): - TMP_MAX = _os.TMP_MAX -else: - TMP_MAX = 10000 - -template = "tmp" - -tempdir = None - -# Internal routines. - -_once_lock = _allocate_lock() - -if hasattr(_os, "lstat"): - _stat = _os.lstat -elif hasattr(_os, "stat"): - _stat = _os.stat -else: - # Fallback. All we need is something that raises os.error if the - # file doesn't exist. - def _stat(fn): - try: - f = open(fn) - except IOError: - raise _os.error - f.close() - -def _exists(fn): - try: - _stat(fn) - except _os.error: - return False - else: - return True - -class _RandomNameSequence: - """An instance of _RandomNameSequence generates an endless - sequence of unpredictable strings which can safely be incorporated - into file names. Each string is six characters long. Multiple - threads can safely use the same instance at the same time. - - _RandomNameSequence is an iterator.""" - - characters = ("abcdefghijklmnopqrstuvwxyz" + - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + - "0123456789-_") - - def __init__(self): - self.mutex = _allocate_lock() - self.rng = _Random() - self.normcase = _os.path.normcase - - def __iter__(self): - return self - - def next(self): - m = self.mutex - c = self.characters - choose = self.rng.choice - - m.acquire() - try: - letters = [choose(c) for dummy in "123456"] - finally: - m.release() - - return self.normcase(''.join(letters)) - -def _candidate_tempdir_list(): - """Generate a list of candidate temporary directories which - _get_default_tempdir will try.""" - - dirlist = [] - - # First, try the environment. - for envname in 'TMPDIR', 'TEMP', 'TMP': - dirname = _os.getenv(envname) - if dirname: dirlist.append(dirname) - - # Failing that, try OS-specific locations. - if _os.name == 'mac': - try: - fsr = _Folder.FSFindFolder(_Folders.kOnSystemDisk, - _Folders.kTemporaryFolderType, 1) - dirname = fsr.as_pathname() - dirlist.append(dirname) - except _Folder.error: - pass - elif _os.name == 'riscos': - dirname = _os.getenv('Wimp$ScrapDir') - if dirname: dirlist.append(dirname) - elif _os.name == 'nt': - dirlist.extend([ r'c:\temp', r'c:\tmp', r'\temp', r'\tmp' ]) - else: - dirlist.extend([ '/tmp', '/var/tmp', '/usr/tmp' ]) - - # As a last resort, the current directory. - try: - dirlist.append(_os.getcwd()) - except (AttributeError, _os.error): - dirlist.append(_os.curdir) - - return dirlist - -def _get_default_tempdir(): - """Calculate the default directory to use for temporary files. - This routine should be called exactly once. - - We determine whether or not a candidate temp dir is usable by - trying to create and write to a file in that directory. If this - is successful, the test file is deleted. To prevent denial of - service, the name of the test file must be randomized.""" - - namer = _RandomNameSequence() - dirlist = _candidate_tempdir_list() - flags = _text_openflags - - for dir in dirlist: - if dir != _os.curdir: - dir = _os.path.normcase(_os.path.abspath(dir)) - # Try only a few names per directory. - for seq in xrange(100): - name = namer.next() - filename = _os.path.join(dir, name) - try: - fd = _os.open(filename, flags, 0600) - fp = _os.fdopen(fd, 'w') - fp.write('blat') - fp.close() - _os.unlink(filename) - del fp, fd - return dir - except (OSError, IOError), e: - if e[0] != _errno.EEXIST: - break # no point trying more names in this directory - pass - raise IOError, (_errno.ENOENT, - ("No usable temporary directory found in %s" % dirlist)) - -_name_sequence = None - -def _get_candidate_names(): - """Common setup sequence for all user-callable interfaces.""" - - global _name_sequence - if _name_sequence is None: - _once_lock.acquire() - try: - if _name_sequence is None: - _name_sequence = _RandomNameSequence() - finally: - _once_lock.release() - return _name_sequence - - -def _mkstemp_inner(dir, pre, suf, flags): - """Code common to mkstemp, TemporaryFile, and NamedTemporaryFile.""" - - names = _get_candidate_names() - - for seq in xrange(TMP_MAX): - name = names.next() - file = _os.path.join(dir, pre + name + suf) - try: - fd = _os.open(file, flags, 0600) - _set_cloexec(fd) - return (fd, _os.path.abspath(file)) - except OSError, e: - if e.errno == _errno.EEXIST: - continue # try again - raise - - raise IOError, (_errno.EEXIST, "No usable temporary file name found") - - -# User visible interfaces. - -def gettempprefix(): - """Accessor for tempdir.template.""" - return template - -tempdir = None - -def gettempdir(): - """Accessor for tempdir.tempdir.""" - global tempdir - if tempdir is None: - _once_lock.acquire() - try: - if tempdir is None: - tempdir = _get_default_tempdir() - finally: - _once_lock.release() - return tempdir - -def mkstemp(suffix="", prefix=template, dir=None, text=False): - """mkstemp([suffix, [prefix, [dir, [text]]]]) - User-callable function to create and return a unique temporary - file. The return value is a pair (fd, name) where fd is the - file descriptor returned by os.open, and name is the filename. - - If 'suffix' is specified, the file name will end with that suffix, - otherwise there will be no suffix. - - If 'prefix' is specified, the file name will begin with that prefix, - otherwise a default prefix is used. - - If 'dir' is specified, the file will be created in that directory, - otherwise a default directory is used. - - If 'text' is specified and true, the file is opened in text - mode. Else (the default) the file is opened in binary mode. On - some operating systems, this makes no difference. - - The file is readable and writable only by the creating user ID. - If the operating system uses permission bits to indicate whether a - file is executable, the file is executable by no one. The file - descriptor is not inherited by children of this process. - - Caller is responsible for deleting the file when done with it. - """ - - if dir is None: - dir = gettempdir() - - if text: - flags = _text_openflags - else: - flags = _bin_openflags - - return _mkstemp_inner(dir, prefix, suffix, flags) - - -def mkdtemp(suffix="", prefix=template, dir=None): - """mkdtemp([suffix, [prefix, [dir]]]) - User-callable function to create and return a unique temporary - directory. The return value is the pathname of the directory. - - Arguments are as for mkstemp, except that the 'text' argument is - not accepted. - - The directory is readable, writable, and searchable only by the - creating user. - - Caller is responsible for deleting the directory when done with it. - """ - - if dir is None: - dir = gettempdir() - - names = _get_candidate_names() - - for seq in xrange(TMP_MAX): - name = names.next() - file = _os.path.join(dir, prefix + name + suffix) - try: - _os.mkdir(file, 0700) - return file - except OSError, e: - if e.errno == _errno.EEXIST: - continue # try again - raise - - raise IOError, (_errno.EEXIST, "No usable temporary directory name found") - -def mktemp(suffix="", prefix=template, dir=None): - """mktemp([suffix, [prefix, [dir]]]) - User-callable function to return a unique temporary file name. The - file is not created. - - Arguments are as for mkstemp, except that the 'text' argument is - not accepted. - - This function is unsafe and should not be used. The file name - refers to a file that did not exist at some point, but by the time - you get around to creating it, someone else may have beaten you to - the punch. - """ - -## from warnings import warn as _warn -## _warn("mktemp is a potential security risk to your program", -## RuntimeWarning, stacklevel=2) - - if dir is None: - dir = gettempdir() - - names = _get_candidate_names() - for seq in xrange(TMP_MAX): - name = names.next() - file = _os.path.join(dir, prefix + name + suffix) - if not _exists(file): - return file - - raise IOError, (_errno.EEXIST, "No usable temporary filename found") - -class _TemporaryFileWrapper: - """Temporary file wrapper - - This class provides a wrapper around files opened for - temporary use. In particular, it seeks to automatically - remove the file when it is no longer needed. - """ - - def __init__(self, file, name): - self.file = file - self.name = name - self.close_called = False - - # XXX: CPython assigns unlink as a class var but this would - # rebind Jython's os.unlink (to be a classmethod) because it's - # not a built-in function (unfortunately built-in functions act - # differently when binding: - # http://mail.python.org/pipermail/python-dev/2003-April/034749.html) - - # Cache the unlinker so we don't get spurious errors at - # shutdown when the module-level "os" is None'd out. Note - # that this must be referenced as self.unlink, because the - # name TemporaryFileWrapper may also get None'd out before - # __del__ is called. - self.unlink = _os.unlink - - def __getattr__(self, name): - # Attribute lookups are delegated to the underlying file - # and cached for non-numeric results - # (i.e. methods are cached, closed and friends are not) - file = self.__dict__['file'] - a = getattr(file, name) - if type(a) != type(0): - setattr(self, name, a) - return a - - # The underlying __enter__ method returns the wrong object - # (self.file) so override it to return the wrapper - def __enter__(self): - self.file.__enter__() - return self - - # NT provides delete-on-close as a primitive, so we don't need - # the wrapper to do anything special. We still use it so that - # file.name is useful (i.e. not "(fdopen)") with NamedTemporaryFile. - if _os.name != 'nt': - def close(self): - if not self.close_called: - self.close_called = True - self.file.close() - self.unlink(self.name) - - def __del__(self): - self.close() - - # Need to trap __exit__ as well to ensure the file gets - # deleted when used in a with statement - def __exit__(self, exc, value, tb): - result = self.file.__exit__(exc, value, tb) - self.close() - return result - - -def NamedTemporaryFile(mode='w+b', bufsize=-1, suffix="", - prefix=template, dir=None): - """Create and return a temporary file. - Arguments: - 'prefix', 'suffix', 'dir' -- as for mkstemp. - 'mode' -- the mode argument to os.fdopen (default "w+b"). - 'bufsize' -- the buffer size argument to os.fdopen (default -1). - The file is created as mkstemp() would do it. - - Returns an object with a file-like interface; the name of the file - is accessible as file.name. The file will be automatically deleted - when it is closed. - """ - - if dir is None: - dir = gettempdir() - - if 'b' in mode: - flags = _bin_openflags - else: - flags = _text_openflags - - # Setting O_TEMPORARY in the flags causes the OS to delete - # the file when it is closed. This is only supported by Windows. - if _os.name == 'nt': - flags |= _os.O_TEMPORARY - - (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) - file = _os.fdopen(fd, mode, bufsize) - return _TemporaryFileWrapper(file, name) - -if _os.name != 'posix' or _os.sys.platform == 'cygwin': - # On non-POSIX and Cygwin systems, assume that we cannot unlink a file - # while it is open. - TemporaryFile = NamedTemporaryFile - -else: - def TemporaryFile(mode='w+b', bufsize=-1, suffix="", - prefix=template, dir=None): - """Create and return a temporary file. - Arguments: - 'prefix', 'suffix', 'dir' -- as for mkstemp. - 'mode' -- the mode argument to os.fdopen (default "w+b"). - 'bufsize' -- the buffer size argument to os.fdopen (default -1). - The file is created as mkstemp() would do it. - - Returns an object with a file-like interface. The file has no - name, and will cease to exist when it is closed. - """ - - if dir is None: - dir = gettempdir() - - if 'b' in mode: - flags = _bin_openflags - else: - flags = _text_openflags - - (fd, name) = _mkstemp_inner(dir, prefix, suffix, flags) - try: - _os.unlink(name) - return _os.fdopen(fd, mode, bufsize) - except: - _os.close(fd) - raise Modified: trunk/jython/Lib/test/test_tempfile.py =================================================================== --- trunk/jython/Lib/test/test_tempfile.py 2009-10-27 23:54:38 UTC (rev 6920) +++ trunk/jython/Lib/test/test_tempfile.py 2009-10-28 02:28:34 UTC (rev 6921) @@ -208,18 +208,13 @@ class mkstemped: _bflags = tempfile._bin_openflags _tflags = tempfile._text_openflags + _close = os.close + _unlink = os.unlink def __init__(self, dir, pre, suf, bin): if bin: flags = self._bflags else: flags = self._tflags - # XXX: CPython assigns _close/_unlink as class vars but this - # would rebind Jython's close/unlink (to be classmethods) - # because they're not built-in functions (unfortunately - # built-in functions act differently when binding: - # http://mail.python.org/pipermail/python-dev/2003-April/034749.html) - self._close = os.close - self._unlink = os.unlink (self.fd, self.name) = tempfile._mkstemp_inner(dir, pre, suf, flags) def write(self, str): @@ -494,7 +489,7 @@ # mkdtemp creates directories with the proper mode if not has_stat: return # ugh, can't use TestSkipped. - if os.name == 'java': + if sys.platform.startswith('java') and not os._native_posix: # Java doesn't support stating files for permissions return @@ -529,13 +524,10 @@ self.dir = None class mktemped: + _unlink = os.unlink _bflags = tempfile._bin_openflags def __init__(self, dir, pre, suf): - # XXX: Assign _unlink here, instead of as a class var. See - # mkstemped.__init__ for an explanation - self._unlink = os.unlink - self.name = tempfile.mktemp(dir=dir, prefix=pre, suffix=suf) # Create the file. This will raise an exception if it's # mysteriously appeared in the meanwhile. @@ -704,5 +696,5 @@ test_main() # XXX: Nudge Java's GC in an attempt to trigger any temp file's # __del__ (cause them to be deleted) that hasn't been called - from java.lang import System - System.gc() + import gc + gc.collect() Added: trunk/jython/src/org/python/modules/posix/Hider.java =================================================================== --- trunk/jython/src/org/python/modules/posix/Hider.java (rev 0) +++ trunk/jython/src/org/python/modules/posix/Hider.java 2009-10-28 02:28:34 UTC (rev 6921) @@ -0,0 +1,75 @@ +/* Copyright (c) Jython Developers */ +package org.python.modules.posix; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Method; + +import org.python.core.PyObject; + +/** + * Utility class for hiding PosixModule methods depending on the platform, or whether the + * underlying posix implementation is native. + */ +class Hider { + + /** + * Hide module level functions defined in the PosixModule dict not applicable to this + * OS, identified by the PosixModule.Hide annotation. + * + * @param cls the PosixModule class + * @param dict the PosixModule module dict + * @param os the underlying OS + * @param native whether the underlying posix is native + */ + public static void hideFunctions(Class<?> cls, PyObject dict, OS os, boolean isNative) { + for (Method method: cls.getDeclaredMethods()) { + if (isHidden(method, os, isNative ? PosixImpl.NATIVE : PosixImpl.JAVA)) { + dict.__setitem__(method.getName(), null); + } + } + } + + /** + * Determine if method should be hidden for this OS/PosixImpl. + */ + private static boolean isHidden(Method method, OS os, PosixImpl posixImpl) { + if (method.isAnnotationPresent(Hide.class)) { + Hide hide = method.getAnnotation(Hide.class); + if (hide.posixImpl() != PosixImpl.NOT_APPLICABLE && hide.posixImpl() == posixImpl) { + return true; + } + for (OS hideOS : hide.value()) { + if (os == hideOS) { + return true; + } + } + } + return false; + } +} + +/** + * Tags PosixModule methods as hidden on the specified OS or PosixImpl. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@interface Hide { + + /** Hide method on these OSes. */ + OS[] value() default {}; + + /** + * @Hide(posixImpl = PosixImpl.JAVA) hides the method from Python when the POSIX + * library isn't native. The default NOT_APPLICABLE means the POSIX implementation + * doesn't matter. + */ + PosixImpl posixImpl() default PosixImpl.NOT_APPLICABLE; +} + +/** + * The type of underlying POSIX library implementation (native or not). + */ +enum PosixImpl {NOT_APPLICABLE, NATIVE, JAVA}; Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-27 23:54:38 UTC (rev 6920) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-10-28 02:28:34 UTC (rev 6921) @@ -92,13 +92,15 @@ // Successful termination dict.__setitem__("EX_OK", Py.Zero); + boolean nativePosix = !(posix instanceof JavaPOSIX); + dict.__setitem__("_native_posix", Py.newBoolean(nativePosix)); + dict.__setitem__("_posix_impl", Py.java2py(posix)); dict.__setitem__("environ", getEnviron()); dict.__setitem__("error", Py.OSError); dict.__setitem__("stat_result", PyStatResult.TYPE); - dict.__setitem__("_posix_impl", Py.java2py(posix)); - dict.__setitem__("_native_posix", Py.newBoolean(!(posix instanceof JavaPOSIX))); // Hide from Python + Hider.hideFunctions(PosixModule.class, dict, os, nativePosix); dict.__setitem__("classDictInit", null); dict.__setitem__("getPOSIX", null); dict.__setitem__("getOSName", null); @@ -190,6 +192,7 @@ public static PyString __doc__chown = new PyString( "chown(path, uid, gid)\n\n" + "Change the owner and group id of path to the numeric uid and gid."); + @Hide(OS.POSIX) public static void chown(String path, int uid, int gid) { if (posix.chown(absolutePath(path), uid, gid) < 0) { throw errorFromErrno(path); @@ -263,6 +266,22 @@ return Py.newUnicode(Py.getSystemState().getCurrentWorkingDir()); } + public static PyString __doc___getpid = new PyString( + "getpid() -> pid\n\n" + + "Return the current process id"); + @Hide(posixImpl = PosixImpl.JAVA) + public static int getpid() { + return posix.getpid(); + } + + public static PyString __doc__link = new PyString( + "link(src, dst)\n\n" + + "Create a hard link to a file."); + @Hide(OS.NT) + public static void link(String src, String dst) { + posix.link(absolutePath(src), absolutePath(dst)); + } + public static PyString __doc__listdir = new PyString( "listdir(path) -> list_of_strings\n\n" + "Return a list containing the names of the entries in the directory.\n\n" + @@ -286,7 +305,6 @@ if (!file.canRead()) { throw Py.OSError(Errno.EACCES, path); } - // throw Py.OSError("listdir(): an unknown error occured: " + path); } for (String name : names) { @@ -399,6 +417,13 @@ } } + public static PyString __doc__remove = new PyString( + "remove(path)\n\n" + + "Remove a file (same as unlink(path))."); + public static void remove(String path) { + unlink(path); + } + public static PyString __doc__stat = new PyString( "stat(path) -> stat result\n\n" + "Perform a stat system call on the given path.\n\n" + @@ -425,6 +450,34 @@ return new PyString(errno.toString()); } + public static PyString __doc__umask = new PyString( + "umask(new_mask) -> old_mask\n\n" + + "Set the current numeric umask and return the previous umask."); + @Hide(posixImpl = PosixImpl.JAVA) + public static int umask(int mask) { + return posix.umask(mask); + } + + public static PyString __doc__unlink = new PyString( + "unlink(path)\n\n" + + "Remove a file (same as remove(path))."); + public static void unlink(String path) { + ensurePath(path); + File file = new RelativeFile(path); + if (!file.delete()) { + // Something went wrong, does stat raise an error? + posix.stat(absolutePath(path)); + // It exists, is it a directory, or do we not have permissions? + if (file.isDirectory()) { + throw Py.OSError(Errno.EISDIR, path); + } + if (!file.canWrite()) { + throw Py.OSError(Errno.EPERM, path); + } + throw Py.OSError("unlink(): an unknown error occured: " + path); + } + } + public static PyString __doc__write = new PyString( "write(fd, string) -> byteswritten\n\n" + "Write a string to a file descriptor."); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |