You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(107) |
Dec
(67) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(76) |
Feb
(125) |
Mar
(72) |
Apr
(13) |
May
(18) |
Jun
(12) |
Jul
(129) |
Aug
(47) |
Sep
(1) |
Oct
(36) |
Nov
(128) |
Dec
(124) |
2002 |
Jan
(59) |
Feb
|
Mar
(14) |
Apr
(14) |
May
(72) |
Jun
(9) |
Jul
(3) |
Aug
(5) |
Sep
(18) |
Oct
(65) |
Nov
(28) |
Dec
(12) |
2003 |
Jan
(10) |
Feb
(2) |
Mar
(4) |
Apr
(33) |
May
(21) |
Jun
(9) |
Jul
(29) |
Aug
(34) |
Sep
(4) |
Oct
(8) |
Nov
(15) |
Dec
(4) |
2004 |
Jan
(26) |
Feb
(12) |
Mar
(11) |
Apr
(9) |
May
(7) |
Jun
|
Jul
(5) |
Aug
|
Sep
(3) |
Oct
(7) |
Nov
(1) |
Dec
(10) |
2005 |
Jan
(2) |
Feb
(72) |
Mar
(16) |
Apr
(39) |
May
(48) |
Jun
(97) |
Jul
(57) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(100) |
Dec
(24) |
2006 |
Jan
(15) |
Feb
(34) |
Mar
(33) |
Apr
(31) |
May
(79) |
Jun
(64) |
Jul
(41) |
Aug
(64) |
Sep
(31) |
Oct
(46) |
Nov
(55) |
Dec
(37) |
2007 |
Jan
(32) |
Feb
(61) |
Mar
(11) |
Apr
(58) |
May
(46) |
Jun
(30) |
Jul
(94) |
Aug
(93) |
Sep
(86) |
Oct
(69) |
Nov
(125) |
Dec
(177) |
2008 |
Jan
(169) |
Feb
(97) |
Mar
(74) |
Apr
(113) |
May
(120) |
Jun
(334) |
Jul
(215) |
Aug
(237) |
Sep
(72) |
Oct
(189) |
Nov
(126) |
Dec
(160) |
2009 |
Jan
(180) |
Feb
(45) |
Mar
(98) |
Apr
(140) |
May
(151) |
Jun
(71) |
Jul
(107) |
Aug
(119) |
Sep
(73) |
Oct
(121) |
Nov
(14) |
Dec
(6) |
2010 |
Jan
(13) |
Feb
(9) |
Mar
(10) |
Apr
(64) |
May
(3) |
Jun
(16) |
Jul
(7) |
Aug
(23) |
Sep
(17) |
Oct
(37) |
Nov
(5) |
Dec
(8) |
2011 |
Jan
(10) |
Feb
(11) |
Mar
(77) |
Apr
(11) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <am...@us...> - 2008-07-15 21:05:15
|
Revision: 4946 http://jython.svn.sourceforge.net/jython/?rev=4946&view=rev Author: amak Date: 2008-07-15 14:05:06 -0700 (Tue, 15 Jul 2008) Log Message: ----------- 1. Support for the <broadcast> address for both server and client UDP sockets 2. Upgrade of the getaddrinfo function to support AF_INET6 and AF_UNSPEC. Still some more work to do on IPv6 support. Modified Paths: -------------- branches/Release_2_2maint/jython/Lib/socket.py branches/Release_2_2maint/jython/Lib/test/test_socket.py Added Paths: ----------- branches/Release_2_2maint/jython/Lib/test/test_socket_ipv6.py Modified: branches/Release_2_2maint/jython/Lib/socket.py =================================================================== --- branches/Release_2_2maint/jython/Lib/socket.py 2008-07-15 19:27:53 UTC (rev 4945) +++ branches/Release_2_2maint/jython/Lib/socket.py 2008-07-15 21:05:06 UTC (rev 4946) @@ -143,8 +143,8 @@ SHUT_WR = 1 SHUT_RDWR = 2 -__all__ = [ 'AF_INET', 'SOCK_DGRAM', 'SOCK_RAW', - 'SOCK_RDM', 'SOCK_SEQPACKET', 'SOCK_STREAM', 'SOL_SOCKET', +__all__ = ['AF_UNSPEC', 'AF_INET', 'AF_INET6', 'AI_PASSIVE', 'SOCK_DGRAM', + 'SOCK_RAW', 'SOCK_RDM', 'SOCK_SEQPACKET', 'SOCK_STREAM', 'SOL_SOCKET', 'SO_BROADCAST', 'SO_KEEPALIVE', 'SO_LINGER', 'SO_OOBINLINE', 'SO_RCVBUF', 'SO_REUSEADDR', 'SO_SNDBUF', 'SO_TIMEOUT', 'TCP_NODELAY', 'SocketType', 'error', 'herror', 'gaierror', 'timeout', @@ -154,8 +154,12 @@ 'SHUT_RD', 'SHUT_WR', 'SHUT_RDWR', ] +AF_UNSPEC = 0 AF_INET = 2 +AF_INET6 = 23 +AI_PASSIVE=1 + SOCK_DGRAM = 1 SOCK_STREAM = 2 SOCK_RAW = 3 # not supported @@ -364,8 +368,7 @@ bytes_sent = self.jchannel.send(byte_buf, socket_address) return bytes_sent - def sendto(self, byte_array, address, flags): - host, port = _unpack_address_tuple(address) + def sendto(self, byte_array, host, port, flags): socket_address = java.net.InetSocketAddress(host, port) if self.mode == MODE_TIMEOUT: return self._do_send_net(byte_array, socket_address, flags) @@ -422,6 +425,10 @@ else: return self._do_receive_nio(0, num_bytes, flags) +# Name and address functions + +has_ipv6 = 1 + def _gethostbyaddr(name): # This is as close as I can get; at least the types are correct... addresses = java.net.InetAddress.getAllByName(gethostbyname(name)) @@ -487,11 +494,29 @@ else: return _udpsocket() -def getaddrinfo(host, port, family=0, socktype=SOCK_STREAM, proto=0, flags=0): - return ( (AF_INET, socktype, 0, "", (gethostbyname(host), port)), ) +def getaddrinfo(host, port, family=None, socktype=None, proto=None, flags=None): + try: + if not family in [AF_INET, AF_INET6, AF_UNSPEC]: + raise NotSupportedError() + filter_fns = [] + filter_fns.append({ + AF_INET: lambda x: isinstance(x, java.net.Inet4Address), + AF_INET6: lambda x: isinstance(x, java.net.Inet6Address), + AF_UNSPEC: lambda x: isinstance(x, java.net.InetAddress), + }[family]) + # Cant see a way to support AI_PASSIVE right now. + # if flags and flags & AI_PASSIVE: + # pass + results = [] + for a in java.net.InetAddress.getAllByName(host): + if len([f for f in filter_fns if f(a)]): + family = {java.net.Inet4Address: AF_INET, java.net.Inet6Address: AF_INET6}[a.class] + # TODO: Include flowinfo and scopeid in a 4-tuple for IPv6 addresses + results.append( (family, socktype, proto, a.getCanonicalHostName(), (a.getHostAddress(), port)) ) + return results + except java.lang.Exception, jlx: + raise _map_exception(jlx) -has_ipv6 = 1 - def getnameinfo(sock_addr, flags): raise NotImplementedError("getnameinfo not yet supported on jython.") @@ -598,13 +623,22 @@ def _get_jsocket(self): return self.sock_impl.jsocket -def _unpack_address_tuple(address_tuple): +def _unpack_address_tuple(address_tuple, for_tx=False): + # TODO: Upgrade to support the 4-tuples used for IPv6 addresses + # which include flowinfo and scope_id. + # To be upgraded in synch with getaddrinfo error_message = "Address must be a tuple of (hostname, port)" if type(address_tuple) is not type( () ) \ or type(address_tuple[0]) is not type("") \ or type(address_tuple[1]) is not type(0): raise TypeError(error_message) - return address_tuple[0], address_tuple[1] + hostname = address_tuple[0].strip() + if hostname == "<broadcast>": + if for_tx: + hostname = "255.255.255.255" + else: + hostname = "0.0.0.0" + return hostname, address_tuple[1] class _tcpsocket(_nonblocking_api_mixin): @@ -621,7 +655,7 @@ assert not self.sock_impl assert not self.local_addr # Do the address format check - host, port = _unpack_address_tuple(addr) + _unpack_address_tuple(addr) self.local_addr = addr def listen(self, backlog=50): @@ -630,7 +664,7 @@ assert not self.sock_impl self.server = 1 if self.local_addr: - host, port = self.local_addr + host, port = _unpack_address_tuple(self.local_addr) else: host, port = "", 0 self.sock_impl = _server_socket_impl(host, port, backlog, self.pending_options[SO_REUSEADDR]) @@ -667,7 +701,7 @@ host, port = self._get_host_port(addr) self.sock_impl = _client_socket_impl() if self.local_addr: # Has the socket been bound to a local address? - bind_host, bind_port = self.local_addr + bind_host, bind_port = _unpack_address_tuple(self.local_addr) self.sock_impl.bind(bind_host, bind_port, self.pending_options[SO_REUSEADDR]) self._config() # Configure timeouts, etc, now that the socket exists self.sock_impl.connect(host, port) @@ -819,8 +853,9 @@ if not self.sock_impl: self.sock_impl = _datagram_socket_impl() self._config() + host, port = _unpack_address_tuple(addr, True) byte_array = java.lang.String(data).getBytes('iso-8859-1') - result = self.sock_impl.sendto(byte_array, addr, flags) + result = self.sock_impl.sendto(byte_array, host, port, flags) return result except java.lang.Exception, jlx: raise _map_exception(jlx) Modified: branches/Release_2_2maint/jython/Lib/test/test_socket.py =================================================================== --- branches/Release_2_2maint/jython/Lib/test/test_socket.py 2008-07-15 19:27:53 UTC (rev 4945) +++ branches/Release_2_2maint/jython/Lib/test/test_socket.py 2008-07-15 21:05:06 UTC (rev 4946) @@ -801,6 +801,21 @@ self.cli.settimeout(10) self.cli.sendto(EIGHT_BIT_MSG, 0, (HOST, PORT)) +class UDPBroadcastTest(ThreadedUDPSocketTest): + + def setUp(self): + self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + def testBroadcast(self): + self.serv.bind( ("<broadcast>", PORT) ) + msg = self.serv.recv(len(EIGHT_BIT_MSG)) + self.assertEqual(msg, EIGHT_BIT_MSG) + + def _testBroadcast(self): + self.cli.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + self.cli.sendto(EIGHT_BIT_MSG, ("<broadcast>", PORT) ) + class BasicSocketPairTest(SocketPairTest): def __init__(self, methodName='runTest'): @@ -1449,6 +1464,10 @@ if sys.platform[:4] == 'java': tests.append(TestJythonTCPExceptions) tests.append(TestJythonUDPExceptions) + # TODO: Broadcast requires permission, and is blocked by some firewalls + # Need some way to discover the network setup on the test machine + if False: + tests.append(UDPBroadcastTest) suites = [unittest.makeSuite(klass, 'test') for klass in tests] test_support.run_suite(unittest.TestSuite(suites)) Added: branches/Release_2_2maint/jython/Lib/test/test_socket_ipv6.py =================================================================== --- branches/Release_2_2maint/jython/Lib/test/test_socket_ipv6.py (rev 0) +++ branches/Release_2_2maint/jython/Lib/test/test_socket_ipv6.py 2008-07-15 21:05:06 UTC (rev 4946) @@ -0,0 +1,61 @@ +""" +AMAK: 20080714: +This module contains IPv6 related tests. +I have placed them in a separate module from the rest of the socket tests, because +1. The tests pass on my IPv6 enabled windows box, on JVMs >= 1.5 +2. They don't pass on Ubuntu, on any JVM version. The equivalent java code to lookup + IPv6 addresses doesn't work either, so I need to research how to configure Ubuntu + so that java.net.Inet6Address.getAllByName() actually returns IPv6 addresses. +3. I don't want to include these tests with the standard socket tests until + the network status and config of the various test environments, e.g. Mac, BSD, Solaris, etc, + are known. +""" + +import unittest +import test_support + +import socket + +class NameLookupTests(unittest.TestCase): + + def testLocalhostV4Lookup(self): + results = socket.getaddrinfo("localhost", 80, socket.AF_INET, socket.SOCK_STREAM, 0) + self.failUnlessEqual(len(results), 1) + self.failUnlessEqual('127.0.0.1', results[0][4][0]) + + def testRemoteV4Lookup(self): + results = socket.getaddrinfo("www.python.org", 80, socket.AF_INET, socket.SOCK_STREAM, 0) + self.failUnlessEqual(len(results), 1) + self.failUnlessEqual('82.94.237.218', results[0][4][0]) + + def testLocalhostV6Lookup(self): + results = socket.getaddrinfo("localhost", 80, socket.AF_INET6, socket.SOCK_STREAM, 0) + self.failUnlessEqual(len(results), 1) + self.failUnlessEqual('0:0:0:0:0:0:0:1', results[0][4][0]) + + def testRemoteV6Lookup(self): + # This test relies on those nice Dutch folks at sixxs.org keeping the same IPv6 address for their gateway + results = socket.getaddrinfo("www.python.org.sixxs.org", 80, socket.AF_INET6, socket.SOCK_STREAM, 0) + self.failUnlessEqual(len(results), 1) + self.failUnlessEqual('2001:838:2:1:2a0:24ff:feab:3b53', results[0][4][0]) + + def testLocalhostV4AndV6Lookup(self): + results = socket.getaddrinfo("localhost", 80, socket.AF_UNSPEC, socket.SOCK_STREAM, 0) + self.failUnlessEqual(len(results), 2) + + def testRemoteV4AndV6Lookup(self): + # Need a remote host with both IPv4 and IPv6 addresses; pass for now + pass + + def testAI_PASSIVE(self): + pass + +def test_main(): + tests = [ + NameLookupTests, + ] + suites = [unittest.makeSuite(klass, 'test') for klass in tests] + test_support.run_suite(unittest.TestSuite(suites)) + +if __name__ == "__main__": + test_main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-07-15 19:27:55
|
Revision: 4945 http://jython.svn.sourceforge.net/jython/?rev=4945&view=rev Author: fwierzbicki Date: 2008-07-15 12:27:53 -0700 (Tue, 15 Jul 2008) Log Message: ----------- already incrementing to 2.5a1 -- sourceforge is caching the old one too hard and I really need to get Windows fixed. Modified Paths: -------------- branches/asm/build.xml Modified: branches/asm/build.xml =================================================================== --- branches/asm/build.xml 2008-07-15 18:42:08 UTC (rev 4944) +++ branches/asm/build.xml 2008-07-15 19:27:53 UTC (rev 4945) @@ -183,11 +183,11 @@ <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> <!-- The current version info --> - <property name="jython.version" value="2.5a0+"/> - <property name="jython.version.noplus" value="2.5a0"/> + <property name="jython.version" value="2.5a1+"/> + <property name="jython.version.noplus" value="2.5a1"/> <property name="jython.major_version" value="2"/> <property name="jython.minor_version" value="5"/> - <property name="jython.micro_version" value="0"/> + <property name="jython.micro_version" value="1"/> <property name="jython.release_level" value="${PY_RELEASE_LEVEL_ALPHA}"/> <property name="jython.release_serial" value="0"/> @@ -377,7 +377,7 @@ <target name="brand-readme-version" depends="checkout" if="do.snapshot.build"> <!-- change README.txt version string, if so defined: used for snapshot builds. XXX: a bit broken for now--> - <replace file="${jython.base.dir}/README.txt" token='2.5a0+' + <replace file="${jython.base.dir}/README.txt" token='2.5a1+' value='2.5a${svn.revision}' /> <replace file="${jython.base.dir}/README.txt"> <replacetoken>=======================</replacetoken> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2008-07-15 18:42:13
|
Revision: 4944 http://jython.svn.sourceforge.net/jython/?rev=4944&view=rev Author: nriley Date: 2008-07-15 11:42:08 -0700 (Tue, 15 Jul 2008) Log Message: ----------- fix for startup problem on Windows - AttributeError was accidentally trapping posixpath abspath failure Modified Paths: -------------- branches/asm/Lib/site.py Modified: branches/asm/Lib/site.py =================================================================== --- branches/asm/Lib/site.py 2008-07-15 18:33:40 UTC (rev 4943) +++ branches/asm/Lib/site.py 2008-07-15 18:42:08 UTC (rev 4944) @@ -72,12 +72,10 @@ for m in sys.modules.values(): if hasattr(m, '__loader__'): continue # don't mess with a PEP 302-supplied __file__ - try: - #XXX: temp workaround while we figure out why this is None on NT. - if m.__file__ != None: - m.__file__ = os.path.abspath(m.__file__) - except AttributeError: + f = getattr(m, '__file__', None) + if f is None: continue + m.__file__ = os.path.abspath(f) def removeduppaths(): """ Remove duplicate entries from sys.path along with making them This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-07-15 18:33:43
|
Revision: 4943 http://jython.svn.sourceforge.net/jython/?rev=4943&view=rev Author: fwierzbicki Date: 2008-07-15 11:33:40 -0700 (Tue, 15 Jul 2008) Log Message: ----------- build tweaks + workaround for an NT problem in site.py Modified Paths: -------------- branches/asm/Lib/site.py branches/asm/build.xml Modified: branches/asm/Lib/site.py =================================================================== --- branches/asm/Lib/site.py 2008-07-15 18:00:57 UTC (rev 4942) +++ branches/asm/Lib/site.py 2008-07-15 18:33:40 UTC (rev 4943) @@ -73,7 +73,9 @@ if hasattr(m, '__loader__'): continue # don't mess with a PEP 302-supplied __file__ try: - m.__file__ = os.path.abspath(m.__file__) + #XXX: temp workaround while we figure out why this is None on NT. + if m.__file__ != None: + m.__file__ = os.path.abspath(m.__file__) except AttributeError: continue Modified: branches/asm/build.xml =================================================================== --- branches/asm/build.xml 2008-07-15 18:00:57 UTC (rev 4942) +++ branches/asm/build.xml 2008-07-15 18:33:40 UTC (rev 4943) @@ -336,8 +336,8 @@ <target name="checkout" depends="prepare" if="do.checkout"> <svn javahl="${javahl.dir}" > - <checkout url="https://jython.svn.sourceforge.net/svnroot/jython/${svn.main.dir}/${svn.installer.dir}" revision="${snapshot.revision}" destPath="${svn.checkout.dir}/${svn.installer.dir}" /> - <checkout url="https://jython.svn.sourceforge.net/svnroot/jython/${svn.main.dir}/${svn.code.dir}" revision="${snapshot.revision}" destPath="${svn.checkout.dir}/${svn.code.dir}" /> + <checkout url="https://jython.svn.sourceforge.net/svnroot/jython/${svn.main.dir}/${svn.installer.dir}" revision="${svn.revision}" destPath="${svn.checkout.dir}/${svn.installer.dir}" /> + <checkout url="https://jython.svn.sourceforge.net/svnroot/jython/${svn.main.dir}/${svn.code.dir}" revision="${svn.revision}" destPath="${svn.checkout.dir}/${svn.code.dir}" /> </svn> <!-- checkout cpython license from the correct python maintenance branch --> @@ -377,8 +377,8 @@ <target name="brand-readme-version" depends="checkout" if="do.snapshot.build"> <!-- change README.txt version string, if so defined: used for snapshot builds. XXX: a bit broken for now--> - <replace file="${jython.base.dir}/README.txt" token='2.2b2' - value='2.2b${snapshot.revision}' /> + <replace file="${jython.base.dir}/README.txt" token='2.5a0+' + value='2.5a${svn.revision}' /> <replace file="${jython.base.dir}/README.txt"> <replacetoken>=======================</replacetoken> <replacevalue>-------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2008-07-15 18:00:58
|
Revision: 4942 http://jython.svn.sourceforge.net/jython/?rev=4942&view=rev Author: leosoto Date: 2008-07-15 11:00:57 -0700 (Tue, 15 Jul 2008) Log Message: ----------- Removing decimal.py from CPythonLib.includes. I forgot to do that on r4939 Modified Paths: -------------- branches/asm/CPythonLib.includes Modified: branches/asm/CPythonLib.includes =================================================================== --- branches/asm/CPythonLib.includes 2008-07-15 17:16:16 UTC (rev 4941) +++ branches/asm/CPythonLib.includes 2008-07-15 18:00:57 UTC (rev 4942) @@ -43,7 +43,6 @@ copy.py copy_reg.py Cookie.py -decimal.py difflib.py dircache.py dircmp.py This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2008-07-15 17:16:20
|
Revision: 4941 http://jython.svn.sourceforge.net/jython/?rev=4941&view=rev Author: leosoto Date: 2008-07-15 10:16:16 -0700 (Tue, 15 Jul 2008) Log Message: ----------- Implemented __tojava__ on datetime.time, datetime.date and datetime.datetime. On the current implementation, they can be converted to java.sql.Time, java.sql.Date, java.sql.Timestamp, respectively. All of them can also be converted to java.util.Calendar. Only one caveat: the tzinfo attribute of times and datetimes is currently ignored Modified Paths: -------------- branches/asm/Lib/datetime.py Modified: branches/asm/Lib/datetime.py =================================================================== --- branches/asm/Lib/datetime.py 2008-07-15 16:24:18 UTC (rev 4940) +++ branches/asm/Lib/datetime.py 2008-07-15 17:16:16 UTC (rev 4941) @@ -981,6 +981,24 @@ def __reduce__(self): return (self.__class__, self.__getstate()) + def __tojava__(self, java_class): + from java.lang import Object + from java.sql import Date + from java.util import Calendar + from org.python.core import Py + + if java_class not in (Calendar, Date, Object): + return Py.NoConversion + + calendar = Calendar.getInstance() + calendar.clear() + calendar.set(self.year, self.month - 1, self.day) + if java_class == Calendar: + return calendar + else: + return Date(calendar.getTimeInMillis()) + + _date_class = date # so functions w/ args named "date" can get at the class date.min = date(1, 1, 1) @@ -1346,6 +1364,28 @@ def __reduce__(self): return (time, self.__getstate()) + def __tojava__(self, java_class): + # TODO, if self.tzinfo is not None, convert time to UTC + from java.lang import Object + from java.sql import Time + from java.util import Calendar + from org.python.core import Py + + if java_class not in (Calendar, Time, Object): + return Py.NoConversion + + calendar = Calendar.getInstance() + calendar.clear() + calendar.set(Calendar.HOUR_OF_DAY, self.hour) + calendar.set(Calendar.MINUTE, self.minute) + calendar.set(Calendar.SECOND, self.second) + calendar.set(Calendar.MILLISECOND, self.microsecond // 1000) + if java_class == Calendar: + return calendar + else: + return Time(calendar.getTimeInMillis()) + + _time_class = time # so functions w/ args named "time" can get at the class time.min = time(0, 0, 0) @@ -1799,7 +1839,28 @@ def __reduce__(self): return (self.__class__, self.__getstate()) + def __tojava__(self, java_class): + # TODO, if self.tzinfo is not None, convert time to UTC + from java.lang import Object + from java.sql import Timestamp + from java.util import Calendar + from org.python.core import Py + if java_class not in (Calendar, Timestamp, Object): + return Py.NoConversion + + calendar = Calendar.getInstance() + calendar.clear() + calendar.set(self.year, self.month - 1, self.day, + self.hour, self.minute, self.second) + calendar.set(Calendar.MILLISECOND, self.microsecond // 1000) + + if java_class == Calendar: + return calendar + else: + return Timestamp(calendar.getTimeInMillis()) + + datetime.min = datetime(1, 1, 1) datetime.max = datetime(9999, 12, 31, 23, 59, 59, 999999) datetime.resolution = timedelta(microseconds=1) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2008-07-15 16:24:46
|
Revision: 4940 http://jython.svn.sourceforge.net/jython/?rev=4940&view=rev Author: leosoto Date: 2008-07-15 09:24:18 -0700 (Tue, 15 Jul 2008) Log Message: ----------- Implemented decimal.Decimal.__tojava__ to convert decimal instances to java BigDecimal when python -> java conversion is requested Modified Paths: -------------- branches/asm/Lib/decimal.py Modified: branches/asm/Lib/decimal.py =================================================================== --- branches/asm/Lib/decimal.py 2008-07-15 16:13:50 UTC (rev 4939) +++ branches/asm/Lib/decimal.py 2008-07-15 16:24:18 UTC (rev 4940) @@ -3330,6 +3330,15 @@ return self # My components are also immutable return self.__class__(str(self)) + # support for Jython __tojava__: + def __tojava__(self, java_class): + from java.lang import Object + from java.math import BigDecimal + from org.python.core import Py + if java_class not in (BigDecimal, Object): + return Py.NoConversion + return BigDecimal(str(self)) + def _dec_from_triple(sign, coefficient, exponent, special=False): """Create a decimal instance directly, without any validation, normalization (e.g. removal of leading zeros) or argument This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2008-07-15 16:14:37
|
Revision: 4939 http://jython.svn.sourceforge.net/jython/?rev=4939&view=rev Author: leosoto Date: 2008-07-15 09:13:50 -0700 (Tue, 15 Jul 2008) Log Message: ----------- decimal.py from http://svn.python.org/projects/python/branches/release25-maint/Lib/decimal.py@64967 Added Paths: ----------- branches/asm/Lib/decimal.py Added: branches/asm/Lib/decimal.py =================================================================== --- branches/asm/Lib/decimal.py (rev 0) +++ branches/asm/Lib/decimal.py 2008-07-15 16:13:50 UTC (rev 4939) @@ -0,0 +1,5164 @@ +# Copyright (c) 2004 Python Software Foundation. +# All rights reserved. + +# Written by Eric Price <eprice at tjhsst.edu> +# and Facundo Batista <facundo at taniquetil.com.ar> +# and Raymond Hettinger <python at rcn.com> +# and Aahz <aahz at pobox.com> +# and Tim Peters + +# This module is currently Py2.3 compatible and should be kept that way +# unless a major compelling advantage arises. IOW, 2.3 compatibility is +# strongly preferred, but not guaranteed. + +# Also, this module should be kept in sync with the latest updates of +# the IBM specification as it evolves. Those updates will be treated +# as bug fixes (deviation from the spec is a compatibility, usability +# bug) and will be backported. At this point the spec is stabilizing +# and the updates are becoming fewer, smaller, and less significant. + +""" +This is a Py2.3 implementation of decimal floating point arithmetic based on +the General Decimal Arithmetic Specification: + + www2.hursley.ibm.com/decimal/decarith.html + +and IEEE standard 854-1987: + + www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html + +Decimal floating point has finite precision with arbitrarily large bounds. + +The purpose of this module is to support arithmetic using familiar +"schoolhouse" rules and to avoid some of the tricky representation +issues associated with binary floating point. The package is especially +useful for financial applications or for contexts where users have +expectations that are at odds with binary floating point (for instance, +in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead +of the expected Decimal("0.00") returned by decimal floating point). + +Here are some examples of using the decimal module: + +>>> from decimal import * +>>> setcontext(ExtendedContext) +>>> Decimal(0) +Decimal("0") +>>> Decimal("1") +Decimal("1") +>>> Decimal("-.0123") +Decimal("-0.0123") +>>> Decimal(123456) +Decimal("123456") +>>> Decimal("123.45e12345678901234567890") +Decimal("1.2345E+12345678901234567892") +>>> Decimal("1.33") + Decimal("1.27") +Decimal("2.60") +>>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41") +Decimal("-2.20") +>>> dig = Decimal(1) +>>> print dig / Decimal(3) +0.333333333 +>>> getcontext().prec = 18 +>>> print dig / Decimal(3) +0.333333333333333333 +>>> print dig.sqrt() +1 +>>> print Decimal(3).sqrt() +1.73205080756887729 +>>> print Decimal(3) ** 123 +4.85192780976896427E+58 +>>> inf = Decimal(1) / Decimal(0) +>>> print inf +Infinity +>>> neginf = Decimal(-1) / Decimal(0) +>>> print neginf +-Infinity +>>> print neginf + inf +NaN +>>> print neginf * inf +-Infinity +>>> print dig / 0 +Infinity +>>> getcontext().traps[DivisionByZero] = 1 +>>> print dig / 0 +Traceback (most recent call last): + ... + ... + ... +DivisionByZero: x / 0 +>>> c = Context() +>>> c.traps[InvalidOperation] = 0 +>>> print c.flags[InvalidOperation] +0 +>>> c.divide(Decimal(0), Decimal(0)) +Decimal("NaN") +>>> c.traps[InvalidOperation] = 1 +>>> print c.flags[InvalidOperation] +1 +>>> c.flags[InvalidOperation] = 0 +>>> print c.flags[InvalidOperation] +0 +>>> print c.divide(Decimal(0), Decimal(0)) +Traceback (most recent call last): + ... + ... + ... +InvalidOperation: 0 / 0 +>>> print c.flags[InvalidOperation] +1 +>>> c.flags[InvalidOperation] = 0 +>>> c.traps[InvalidOperation] = 0 +>>> print c.divide(Decimal(0), Decimal(0)) +NaN +>>> print c.flags[InvalidOperation] +1 +>>> +""" + +__all__ = [ + # Two major classes + 'Decimal', 'Context', + + # Contexts + 'DefaultContext', 'BasicContext', 'ExtendedContext', + + # Exceptions + 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', + 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', + + # Constants for use in setting up contexts + 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', + 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', + + # Functions for manipulating contexts + 'setcontext', 'getcontext', 'localcontext' +] + +import copy as _copy + +# Rounding +ROUND_DOWN = 'ROUND_DOWN' +ROUND_HALF_UP = 'ROUND_HALF_UP' +ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' +ROUND_CEILING = 'ROUND_CEILING' +ROUND_FLOOR = 'ROUND_FLOOR' +ROUND_UP = 'ROUND_UP' +ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' +ROUND_05UP = 'ROUND_05UP' + +# Errors + +class DecimalException(ArithmeticError): + """Base exception class. + + Used exceptions derive from this. + If an exception derives from another exception besides this (such as + Underflow (Inexact, Rounded, Subnormal) that indicates that it is only + called if the others are present. This isn't actually used for + anything, though. + + handle -- Called when context._raise_error is called and the + trap_enabler is set. First argument is self, second is the + context. More arguments can be given, those being after + the explanation in _raise_error (For example, + context._raise_error(NewError, '(-x)!', self._sign) would + call NewError().handle(context, self._sign).) + + To define a new exception, it should be sufficient to have it derive + from DecimalException. + """ + def handle(self, context, *args): + pass + + +class Clamped(DecimalException): + """Exponent of a 0 changed to fit bounds. + + This occurs and signals clamped if the exponent of a result has been + altered in order to fit the constraints of a specific concrete + representation. This may occur when the exponent of a zero result would + be outside the bounds of a representation, or when a large normal + number would have an encoded exponent that cannot be represented. In + this latter case, the exponent is reduced to fit and the corresponding + number of zero digits are appended to the coefficient ("fold-down"). + """ + +class InvalidOperation(DecimalException): + """An invalid operation was performed. + + Various bad things cause this: + + Something creates a signaling NaN + -INF + INF + 0 * (+-)INF + (+-)INF / (+-)INF + x % 0 + (+-)INF % x + x._rescale( non-integer ) + sqrt(-x) , x > 0 + 0 ** 0 + x ** (non-integer) + x ** (+-)INF + An operand is invalid + + The result of the operation after these is a quiet positive NaN, + except when the cause is a signaling NaN, in which case the result is + also a quiet NaN, but with the original sign, and an optional + diagnostic information. + """ + def handle(self, context, *args): + if args: + ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True) + return ans._fix_nan(context) + return NaN + +class ConversionSyntax(InvalidOperation): + """Trying to convert badly formed string. + + This occurs and signals invalid-operation if an string is being + converted to a number and it does not conform to the numeric string + syntax. The result is [0,qNaN]. + """ + def handle(self, context, *args): + return NaN + +class DivisionByZero(DecimalException, ZeroDivisionError): + """Division by 0. + + This occurs and signals division-by-zero if division of a finite number + by zero was attempted (during a divide-integer or divide operation, or a + power operation with negative right-hand operand), and the dividend was + not zero. + + The result of the operation is [sign,inf], where sign is the exclusive + or of the signs of the operands for divide, or is 1 for an odd power of + -0, for power. + """ + + def handle(self, context, sign, *args): + return Infsign[sign] + +class DivisionImpossible(InvalidOperation): + """Cannot perform the division adequately. + + This occurs and signals invalid-operation if the integer result of a + divide-integer or remainder operation had too many digits (would be + longer than precision). The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return NaN + +class DivisionUndefined(InvalidOperation, ZeroDivisionError): + """Undefined result of division. + + This occurs and signals invalid-operation if division by zero was + attempted (during a divide-integer, divide, or remainder operation), and + the dividend is also zero. The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return NaN + +class Inexact(DecimalException): + """Had to round, losing information. + + This occurs and signals inexact whenever the result of an operation is + not exact (that is, it needed to be rounded and any discarded digits + were non-zero), or if an overflow or underflow condition occurs. The + result in all cases is unchanged. + + The inexact signal may be tested (or trapped) to determine if a given + operation (or sequence of operations) was inexact. + """ + +class InvalidContext(InvalidOperation): + """Invalid context. Unknown rounding, for example. + + This occurs and signals invalid-operation if an invalid context was + detected during an operation. This can occur if contexts are not checked + on creation and either the precision exceeds the capability of the + underlying concrete representation or an unknown or unsupported rounding + was specified. These aspects of the context need only be checked when + the values are required to be used. The result is [0,qNaN]. + """ + + def handle(self, context, *args): + return NaN + +class Rounded(DecimalException): + """Number got rounded (not necessarily changed during rounding). + + This occurs and signals rounded whenever the result of an operation is + rounded (that is, some zero or non-zero digits were discarded from the + coefficient), or if an overflow or underflow condition occurs. The + result in all cases is unchanged. + + The rounded signal may be tested (or trapped) to determine if a given + operation (or sequence of operations) caused a loss of precision. + """ + +class Subnormal(DecimalException): + """Exponent < Emin before rounding. + + This occurs and signals subnormal whenever the result of a conversion or + operation is subnormal (that is, its adjusted exponent is less than + Emin, before any rounding). The result in all cases is unchanged. + + The subnormal signal may be tested (or trapped) to determine if a given + or operation (or sequence of operations) yielded a subnormal result. + """ + +class Overflow(Inexact, Rounded): + """Numerical overflow. + + This occurs and signals overflow if the adjusted exponent of a result + (from a conversion or from an operation that is not an attempt to divide + by zero), after rounding, would be greater than the largest value that + can be handled by the implementation (the value Emax). + + The result depends on the rounding mode: + + For round-half-up and round-half-even (and for round-half-down and + round-up, if implemented), the result of the operation is [sign,inf], + where sign is the sign of the intermediate result. For round-down, the + result is the largest finite number that can be represented in the + current precision, with the sign of the intermediate result. For + round-ceiling, the result is the same as for round-down if the sign of + the intermediate result is 1, or is [0,inf] otherwise. For round-floor, + the result is the same as for round-down if the sign of the intermediate + result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded + will also be raised. + """ + + def handle(self, context, sign, *args): + if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, + ROUND_HALF_DOWN, ROUND_UP): + return Infsign[sign] + if sign == 0: + if context.rounding == ROUND_CEILING: + return Infsign[sign] + return _dec_from_triple(sign, '9'*context.prec, + context.Emax-context.prec+1) + if sign == 1: + if context.rounding == ROUND_FLOOR: + return Infsign[sign] + return _dec_from_triple(sign, '9'*context.prec, + context.Emax-context.prec+1) + + +class Underflow(Inexact, Rounded, Subnormal): + """Numerical underflow with result rounded to 0. + + This occurs and signals underflow if a result is inexact and the + adjusted exponent of the result would be smaller (more negative) than + the smallest value that can be handled by the implementation (the value + Emin). That is, the result is both inexact and subnormal. + + The result after an underflow will be a subnormal number rounded, if + necessary, so that its exponent is not less than Etiny. This may result + in 0 with the sign of the intermediate result and an exponent of Etiny. + + In all cases, Inexact, Rounded, and Subnormal will also be raised. + """ + +# List of public traps and flags +_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, + Underflow, InvalidOperation, Subnormal] + +# Map conditions (per the spec) to signals +_condition_map = {ConversionSyntax:InvalidOperation, + DivisionImpossible:InvalidOperation, + DivisionUndefined:InvalidOperation, + InvalidContext:InvalidOperation} + +##### Context Functions ################################################## + +# The getcontext() and setcontext() function manage access to a thread-local +# current context. Py2.4 offers direct support for thread locals. If that +# is not available, use threading.currentThread() which is slower but will +# work for older Pythons. If threads are not part of the build, create a +# mock threading object with threading.local() returning the module namespace. + +try: + import threading +except ImportError: + # Python was compiled without threads; create a mock object instead + import sys + class MockThreading(object): + def local(self, sys=sys): + return sys.modules[__name__] + threading = MockThreading() + del sys, MockThreading + +try: + threading.local + +except AttributeError: + + # To fix reloading, force it to create a new context + # Old contexts have different exceptions in their dicts, making problems. + if hasattr(threading.currentThread(), '__decimal_context__'): + del threading.currentThread().__decimal_context__ + + def setcontext(context): + """Set this thread's context to context.""" + if context in (DefaultContext, BasicContext, ExtendedContext): + context = context.copy() + context.clear_flags() + threading.currentThread().__decimal_context__ = context + + def getcontext(): + """Returns this thread's context. + + If this thread does not yet have a context, returns + a new context and sets this thread's context. + New contexts are copies of DefaultContext. + """ + try: + return threading.currentThread().__decimal_context__ + except AttributeError: + context = Context() + threading.currentThread().__decimal_context__ = context + return context + +else: + + local = threading.local() + if hasattr(local, '__decimal_context__'): + del local.__decimal_context__ + + def getcontext(_local=local): + """Returns this thread's context. + + If this thread does not yet have a context, returns + a new context and sets this thread's context. + New contexts are copies of DefaultContext. + """ + try: + return _local.__decimal_context__ + except AttributeError: + context = Context() + _local.__decimal_context__ = context + return context + + def setcontext(context, _local=local): + """Set this thread's context to context.""" + if context in (DefaultContext, BasicContext, ExtendedContext): + context = context.copy() + context.clear_flags() + _local.__decimal_context__ = context + + del threading, local # Don't contaminate the namespace + +def localcontext(ctx=None): + """Return a context manager for a copy of the supplied context + + Uses a copy of the current context if no context is specified + The returned context manager creates a local decimal context + in a with statement: + def sin(x): + with localcontext() as ctx: + ctx.prec += 2 + # Rest of sin calculation algorithm + # uses a precision 2 greater than normal + return +s # Convert result to normal precision + + def sin(x): + with localcontext(ExtendedContext): + # Rest of sin calculation algorithm + # uses the Extended Context from the + # General Decimal Arithmetic Specification + return +s # Convert result to normal context + + """ + # The string below can't be included in the docstring until Python 2.6 + # as the doctest module doesn't understand __future__ statements + """ + >>> from __future__ import with_statement + >>> print getcontext().prec + 28 + >>> with localcontext(): + ... ctx = getcontext() + ... ctx.prec += 2 + ... print ctx.prec + ... + 30 + >>> with localcontext(ExtendedContext): + ... print getcontext().prec + ... + 9 + >>> print getcontext().prec + 28 + """ + if ctx is None: ctx = getcontext() + return _ContextManager(ctx) + + +##### Decimal class ####################################################### + +class Decimal(object): + """Floating point class for decimal arithmetic.""" + + __slots__ = ('_exp','_int','_sign', '_is_special') + # Generally, the value of the Decimal instance is given by + # (-1)**_sign * _int * 10**_exp + # Special values are signified by _is_special == True + + # We're immutable, so use __new__ not __init__ + def __new__(cls, value="0", context=None): + """Create a decimal point instance. + + >>> Decimal('3.14') # string input + Decimal("3.14") + >>> Decimal((0, (3, 1, 4), -2)) # tuple (sign, digit_tuple, exponent) + Decimal("3.14") + >>> Decimal(314) # int or long + Decimal("314") + >>> Decimal(Decimal(314)) # another decimal instance + Decimal("314") + """ + + # Note that the coefficient, self._int, is actually stored as + # a string rather than as a tuple of digits. This speeds up + # the "digits to integer" and "integer to digits" conversions + # that are used in almost every arithmetic operation on + # Decimals. This is an internal detail: the as_tuple function + # and the Decimal constructor still deal with tuples of + # digits. + + self = object.__new__(cls) + + # From a string + # REs insist on real strings, so we can too. + if isinstance(value, basestring): + m = _parser(value) + if m is None: + if context is None: + context = getcontext() + return context._raise_error(ConversionSyntax, + "Invalid literal for Decimal: %r" % value) + + if m.group('sign') == "-": + self._sign = 1 + else: + self._sign = 0 + intpart = m.group('int') + if intpart is not None: + # finite number + fracpart = m.group('frac') + exp = int(m.group('exp') or '0') + if fracpart is not None: + self._int = str((intpart+fracpart).lstrip('0') or '0') + self._exp = exp - len(fracpart) + else: + self._int = str(intpart.lstrip('0') or '0') + self._exp = exp + self._is_special = False + else: + diag = m.group('diag') + if diag is not None: + # NaN + self._int = str(diag.lstrip('0')) + if m.group('signal'): + self._exp = 'N' + else: + self._exp = 'n' + else: + # infinity + self._int = '0' + self._exp = 'F' + self._is_special = True + return self + + # From an integer + if isinstance(value, (int,long)): + if value >= 0: + self._sign = 0 + else: + self._sign = 1 + self._exp = 0 + self._int = str(abs(value)) + self._is_special = False + return self + + # From another decimal + if isinstance(value, Decimal): + self._exp = value._exp + self._sign = value._sign + self._int = value._int + self._is_special = value._is_special + return self + + # From an internal working value + if isinstance(value, _WorkRep): + self._sign = value.sign + self._int = str(value.int) + self._exp = int(value.exp) + self._is_special = False + return self + + # tuple/list conversion (possibly from as_tuple()) + if isinstance(value, (list,tuple)): + if len(value) != 3: + raise ValueError('Invalid tuple size in creation of Decimal ' + 'from list or tuple. The list or tuple ' + 'should have exactly three elements.') + # process sign. The isinstance test rejects floats + if not (isinstance(value[0], (int, long)) and value[0] in (0,1)): + raise ValueError("Invalid sign. The first value in the tuple " + "should be an integer; either 0 for a " + "positive number or 1 for a negative number.") + self._sign = value[0] + if value[2] == 'F': + # infinity: value[1] is ignored + self._int = '0' + self._exp = value[2] + self._is_special = True + else: + # process and validate the digits in value[1] + digits = [] + for digit in value[1]: + if isinstance(digit, (int, long)) and 0 <= digit <= 9: + # skip leading zeros + if digits or digit != 0: + digits.append(digit) + else: + raise ValueError("The second value in the tuple must " + "be composed of integers in the range " + "0 through 9.") + if value[2] in ('n', 'N'): + # NaN: digits form the diagnostic + self._int = ''.join(map(str, digits)) + self._exp = value[2] + self._is_special = True + elif isinstance(value[2], (int, long)): + # finite number: digits give the coefficient + self._int = ''.join(map(str, digits or [0])) + self._exp = value[2] + self._is_special = False + else: + raise ValueError("The third value in the tuple must " + "be an integer, or one of the " + "strings 'F', 'n', 'N'.") + return self + + if isinstance(value, float): + raise TypeError("Cannot convert float to Decimal. " + + "First convert the float to a string") + + raise TypeError("Cannot convert %r to Decimal" % value) + + def _isnan(self): + """Returns whether the number is not actually one. + + 0 if a number + 1 if NaN + 2 if sNaN + """ + if self._is_special: + exp = self._exp + if exp == 'n': + return 1 + elif exp == 'N': + return 2 + return 0 + + def _isinfinity(self): + """Returns whether the number is infinite + + 0 if finite or not a number + 1 if +INF + -1 if -INF + """ + if self._exp == 'F': + if self._sign: + return -1 + return 1 + return 0 + + def _check_nans(self, other=None, context=None): + """Returns whether the number is not actually one. + + if self, other are sNaN, signal + if self, other are NaN return nan + return 0 + + Done before operations. + """ + + self_is_nan = self._isnan() + if other is None: + other_is_nan = False + else: + other_is_nan = other._isnan() + + if self_is_nan or other_is_nan: + if context is None: + context = getcontext() + + if self_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + self) + if other_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + other) + if self_is_nan: + return self._fix_nan(context) + + return other._fix_nan(context) + return 0 + + def __nonzero__(self): + """Return True if self is nonzero; otherwise return False. + + NaNs and infinities are considered nonzero. + """ + return self._is_special or self._int != '0' + + def __cmp__(self, other): + other = _convert_other(other) + if other is NotImplemented: + # Never return NotImplemented + return 1 + + if self._is_special or other._is_special: + # check for nans, without raising on a signaling nan + if self._isnan() or other._isnan(): + return 1 # Comparison involving NaN's always reports self > other + + # INF = INF + return cmp(self._isinfinity(), other._isinfinity()) + + # check for zeros; note that cmp(0, -0) should return 0 + if not self: + if not other: + return 0 + else: + return -((-1)**other._sign) + if not other: + return (-1)**self._sign + + # If different signs, neg one is less + if other._sign < self._sign: + return -1 + if self._sign < other._sign: + return 1 + + self_adjusted = self.adjusted() + other_adjusted = other.adjusted() + if self_adjusted == other_adjusted: + self_padded = self._int + '0'*(self._exp - other._exp) + other_padded = other._int + '0'*(other._exp - self._exp) + return cmp(self_padded, other_padded) * (-1)**self._sign + elif self_adjusted > other_adjusted: + return (-1)**self._sign + else: # self_adjusted < other_adjusted + return -((-1)**self._sign) + + def __eq__(self, other): + if not isinstance(other, (Decimal, int, long)): + return NotImplemented + return self.__cmp__(other) == 0 + + def __ne__(self, other): + if not isinstance(other, (Decimal, int, long)): + return NotImplemented + return self.__cmp__(other) != 0 + + def compare(self, other, context=None): + """Compares one to another. + + -1 => a < b + 0 => a = b + 1 => a > b + NaN => one is NaN + Like __cmp__, but returns Decimal instances. + """ + other = _convert_other(other, raiseit=True) + + # Compare(NaN, NaN) = NaN + if (self._is_special or other and other._is_special): + ans = self._check_nans(other, context) + if ans: + return ans + + return Decimal(self.__cmp__(other)) + + def __hash__(self): + """x.__hash__() <==> hash(x)""" + # Decimal integers must hash the same as the ints + # + # The hash of a nonspecial noninteger Decimal must depend only + # on the value of that Decimal, and not on its representation. + # For example: hash(Decimal("100E-1")) == hash(Decimal("10")). + if self._is_special: + if self._isnan(): + raise TypeError('Cannot hash a NaN value.') + return hash(str(self)) + if not self: + return 0 + if self._isinteger(): + op = _WorkRep(self.to_integral_value()) + return hash((-1)**op.sign*op.int*10**op.exp) + # The value of a nonzero nonspecial Decimal instance is + # faithfully represented by the triple consisting of its sign, + # its adjusted exponent, and its coefficient with trailing + # zeros removed. + return hash((self._sign, + self._exp+len(self._int), + self._int.rstrip('0'))) + + def as_tuple(self): + """Represents the number as a triple tuple. + + To show the internals exactly as they are. + """ + return (self._sign, tuple(map(int, self._int)), self._exp) + + def __repr__(self): + """Represents the number as an instance of Decimal.""" + # Invariant: eval(repr(d)) == d + return 'Decimal("%s")' % str(self) + + def __str__(self, eng=False, context=None): + """Return string representation of the number in scientific notation. + + Captures all of the information in the underlying representation. + """ + + sign = ['', '-'][self._sign] + if self._is_special: + if self._exp == 'F': + return sign + 'Infinity' + elif self._exp == 'n': + return sign + 'NaN' + self._int + else: # self._exp == 'N' + return sign + 'sNaN' + self._int + + # number of digits of self._int to left of decimal point + leftdigits = self._exp + len(self._int) + + # dotplace is number of digits of self._int to the left of the + # decimal point in the mantissa of the output string (that is, + # after adjusting the exponent) + if self._exp <= 0 and leftdigits > -6: + # no exponent required + dotplace = leftdigits + elif not eng: + # usual scientific notation: 1 digit on left of the point + dotplace = 1 + elif self._int == '0': + # engineering notation, zero + dotplace = (leftdigits + 1) % 3 - 1 + else: + # engineering notation, nonzero + dotplace = (leftdigits - 1) % 3 + 1 + + if dotplace <= 0: + intpart = '0' + fracpart = '.' + '0'*(-dotplace) + self._int + elif dotplace >= len(self._int): + intpart = self._int+'0'*(dotplace-len(self._int)) + fracpart = '' + else: + intpart = self._int[:dotplace] + fracpart = '.' + self._int[dotplace:] + if leftdigits == dotplace: + exp = '' + else: + if context is None: + context = getcontext() + exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace) + + return sign + intpart + fracpart + exp + + def to_eng_string(self, context=None): + """Convert to engineering-type string. + + Engineering notation has an exponent which is a multiple of 3, so there + are up to 3 digits left of the decimal place. + + Same rules for when in exponential and when as a value as in __str__. + """ + return self.__str__(eng=True, context=context) + + def __neg__(self, context=None): + """Returns a copy with the sign switched. + + Rounds, if it has reason. + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if not self: + # -Decimal('0') is Decimal('0'), not Decimal('-0') + ans = self.copy_abs() + else: + ans = self.copy_negate() + + if context is None: + context = getcontext() + return ans._fix(context) + + def __pos__(self, context=None): + """Returns a copy, unless it is a sNaN. + + Rounds the number (if more then precision digits) + """ + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if not self: + # + (-0) = 0 + ans = self.copy_abs() + else: + ans = Decimal(self) + + if context is None: + context = getcontext() + return ans._fix(context) + + def __abs__(self, round=True, context=None): + """Returns the absolute value of self. + + If the keyword argument 'round' is false, do not round. The + expression self.__abs__(round=False) is equivalent to + self.copy_abs(). + """ + if not round: + return self.copy_abs() + + if self._is_special: + ans = self._check_nans(context=context) + if ans: + return ans + + if self._sign: + ans = self.__neg__(context=context) + else: + ans = self.__pos__(context=context) + + return ans + + def __add__(self, other, context=None): + """Returns self + other. + + -INF + INF (or the reverse) cause InvalidOperation errors. + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + # If both INF, same sign => same as both, opposite => error. + if self._sign != other._sign and other._isinfinity(): + return context._raise_error(InvalidOperation, '-INF + INF') + return Decimal(self) + if other._isinfinity(): + return Decimal(other) # Can't both be infinity here + + exp = min(self._exp, other._exp) + negativezero = 0 + if context.rounding == ROUND_FLOOR and self._sign != other._sign: + # If the answer is 0, the sign should be negative, in this case. + negativezero = 1 + + if not self and not other: + sign = min(self._sign, other._sign) + if negativezero: + sign = 1 + ans = _dec_from_triple(sign, '0', exp) + ans = ans._fix(context) + return ans + if not self: + exp = max(exp, other._exp - context.prec-1) + ans = other._rescale(exp, context.rounding) + ans = ans._fix(context) + return ans + if not other: + exp = max(exp, self._exp - context.prec-1) + ans = self._rescale(exp, context.rounding) + ans = ans._fix(context) + return ans + + op1 = _WorkRep(self) + op2 = _WorkRep(other) + op1, op2 = _normalize(op1, op2, context.prec) + + result = _WorkRep() + if op1.sign != op2.sign: + # Equal and opposite + if op1.int == op2.int: + ans = _dec_from_triple(negativezero, '0', exp) + ans = ans._fix(context) + return ans + if op1.int < op2.int: + op1, op2 = op2, op1 + # OK, now abs(op1) > abs(op2) + if op1.sign == 1: + result.sign = 1 + op1.sign, op2.sign = op2.sign, op1.sign + else: + result.sign = 0 + # So we know the sign, and op1 > 0. + elif op1.sign == 1: + result.sign = 1 + op1.sign, op2.sign = (0, 0) + else: + result.sign = 0 + # Now, op1 > abs(op2) > 0 + + if op2.sign == 0: + result.int = op1.int + op2.int + else: + result.int = op1.int - op2.int + + result.exp = op1.exp + ans = Decimal(result) + ans = ans._fix(context) + return ans + + __radd__ = __add__ + + def __sub__(self, other, context=None): + """Return self - other""" + other = _convert_other(other) + if other is NotImplemented: + return other + + if self._is_special or other._is_special: + ans = self._check_nans(other, context=context) + if ans: + return ans + + # self - other is computed as self + other.copy_negate() + return self.__add__(other.copy_negate(), context=context) + + def __rsub__(self, other, context=None): + """Return other - self""" + other = _convert_other(other) + if other is NotImplemented: + return other + + return other.__sub__(self, context=context) + + def __mul__(self, other, context=None): + """Return self * other. + + (+-) INF * 0 (or its reverse) raise InvalidOperation. + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + resultsign = self._sign ^ other._sign + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + if not other: + return context._raise_error(InvalidOperation, '(+-)INF * 0') + return Infsign[resultsign] + + if other._isinfinity(): + if not self: + return context._raise_error(InvalidOperation, '0 * (+-)INF') + return Infsign[resultsign] + + resultexp = self._exp + other._exp + + # Special case for multiplying by zero + if not self or not other: + ans = _dec_from_triple(resultsign, '0', resultexp) + # Fixing in case the exponent is out of bounds + ans = ans._fix(context) + return ans + + # Special case for multiplying by power of 10 + if self._int == '1': + ans = _dec_from_triple(resultsign, other._int, resultexp) + ans = ans._fix(context) + return ans + if other._int == '1': + ans = _dec_from_triple(resultsign, self._int, resultexp) + ans = ans._fix(context) + return ans + + op1 = _WorkRep(self) + op2 = _WorkRep(other) + + ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp) + ans = ans._fix(context) + + return ans + __rmul__ = __mul__ + + def __div__(self, other, context=None): + """Return self / other.""" + other = _convert_other(other) + if other is NotImplemented: + return NotImplemented + + if context is None: + context = getcontext() + + sign = self._sign ^ other._sign + + if self._is_special or other._is_special: + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity() and other._isinfinity(): + return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') + + if self._isinfinity(): + return Infsign[sign] + + if other._isinfinity(): + context._raise_error(Clamped, 'Division by infinity') + return _dec_from_triple(sign, '0', context.Etiny()) + + # Special cases for zeroes + if not other: + if not self: + return context._raise_error(DivisionUndefined, '0 / 0') + return context._raise_error(DivisionByZero, 'x / 0', sign) + + if not self: + exp = self._exp - other._exp + coeff = 0 + else: + # OK, so neither = 0, INF or NaN + shift = len(other._int) - len(self._int) + context.prec + 1 + exp = self._exp - other._exp - shift + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if shift >= 0: + coeff, remainder = divmod(op1.int * 10**shift, op2.int) + else: + coeff, remainder = divmod(op1.int, op2.int * 10**-shift) + if remainder: + # result is not exact; adjust to ensure correct rounding + if coeff % 5 == 0: + coeff += 1 + else: + # result is exact; get as close to ideal exponent as possible + ideal_exp = self._exp - other._exp + while exp < ideal_exp and coeff % 10 == 0: + coeff //= 10 + exp += 1 + + ans = _dec_from_triple(sign, str(coeff), exp) + return ans._fix(context) + + __truediv__ = __div__ + + def _divide(self, other, context): + """Return (self // other, self % other), to context.prec precision. + + Assumes that neither self nor other is a NaN, that self is not + infinite and that other is nonzero. + """ + sign = self._sign ^ other._sign + if other._isinfinity(): + ideal_exp = self._exp + else: + ideal_exp = min(self._exp, other._exp) + + expdiff = self.adjusted() - other.adjusted() + if not self or other._isinfinity() or expdiff <= -2: + return (_dec_from_triple(sign, '0', 0), + self._rescale(ideal_exp, context.rounding)) + if expdiff <= context.prec: + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if op1.exp >= op2.exp: + op1.int *= 10**(op1.exp - op2.exp) + else: + op2.int *= 10**(op2.exp - op1.exp) + q, r = divmod(op1.int, op2.int) + if q < 10**context.prec: + return (_dec_from_triple(sign, str(q), 0), + _dec_from_triple(self._sign, str(r), ideal_exp)) + + # Here the quotient is too large to be representable + ans = context._raise_error(DivisionImpossible, + 'quotient too large in //, % or divmod') + return ans, ans + + def __rdiv__(self, other, context=None): + """Swaps self/other and returns __div__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__div__(self, context=context) + __rtruediv__ = __rdiv__ + + def __divmod__(self, other, context=None): + """ + Return (self // other, self % other) + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return (ans, ans) + + sign = self._sign ^ other._sign + if self._isinfinity(): + if other._isinfinity(): + ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)') + return ans, ans + else: + return (Infsign[sign], + context._raise_error(InvalidOperation, 'INF % x')) + + if not other: + if not self: + ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)') + return ans, ans + else: + return (context._raise_error(DivisionByZero, 'x // 0', sign), + context._raise_error(InvalidOperation, 'x % 0')) + + quotient, remainder = self._divide(other, context) + remainder = remainder._fix(context) + return quotient, remainder + + def __rdivmod__(self, other, context=None): + """Swaps self/other and returns __divmod__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__divmod__(self, context=context) + + def __mod__(self, other, context=None): + """ + self % other + """ + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + return context._raise_error(InvalidOperation, 'INF % x') + elif not other: + if self: + return context._raise_error(InvalidOperation, 'x % 0') + else: + return context._raise_error(DivisionUndefined, '0 % 0') + + remainder = self._divide(other, context)[1] + remainder = remainder._fix(context) + return remainder + + def __rmod__(self, other, context=None): + """Swaps self/other and returns __mod__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__mod__(self, context=context) + + def remainder_near(self, other, context=None): + """ + Remainder nearest to 0- abs(remainder-near) <= other/2 + """ + if context is None: + context = getcontext() + + other = _convert_other(other, raiseit=True) + + ans = self._check_nans(other, context) + if ans: + return ans + + # self == +/-infinity -> InvalidOperation + if self._isinfinity(): + return context._raise_error(InvalidOperation, + 'remainder_near(infinity, x)') + + # other == 0 -> either InvalidOperation or DivisionUndefined + if not other: + if self: + return context._raise_error(InvalidOperation, + 'remainder_near(x, 0)') + else: + return context._raise_error(DivisionUndefined, + 'remainder_near(0, 0)') + + # other = +/-infinity -> remainder = self + if other._isinfinity(): + ans = Decimal(self) + return ans._fix(context) + + # self = 0 -> remainder = self, with ideal exponent + ideal_exponent = min(self._exp, other._exp) + if not self: + ans = _dec_from_triple(self._sign, '0', ideal_exponent) + return ans._fix(context) + + # catch most cases of large or small quotient + expdiff = self.adjusted() - other.adjusted() + if expdiff >= context.prec + 1: + # expdiff >= prec+1 => abs(self/other) > 10**prec + return context._raise_error(DivisionImpossible) + if expdiff <= -2: + # expdiff <= -2 => abs(self/other) < 0.1 + ans = self._rescale(ideal_exponent, context.rounding) + return ans._fix(context) + + # adjust both arguments to have the same exponent, then divide + op1 = _WorkRep(self) + op2 = _WorkRep(other) + if op1.exp >= op2.exp: + op1.int *= 10**(op1.exp - op2.exp) + else: + op2.int *= 10**(op2.exp - op1.exp) + q, r = divmod(op1.int, op2.int) + # remainder is r*10**ideal_exponent; other is +/-op2.int * + # 10**ideal_exponent. Apply correction to ensure that + # abs(remainder) <= abs(other)/2 + if 2*r + (q&1) > op2.int: + r -= op2.int + q += 1 + + if q >= 10**context.prec: + return context._raise_error(DivisionImpossible) + + # result has same sign as self unless r is negative + sign = self._sign + if r < 0: + sign = 1-sign + r = -r + + ans = _dec_from_triple(sign, str(r), ideal_exponent) + return ans._fix(context) + + def __floordiv__(self, other, context=None): + """self // other""" + other = _convert_other(other) + if other is NotImplemented: + return other + + if context is None: + context = getcontext() + + ans = self._check_nans(other, context) + if ans: + return ans + + if self._isinfinity(): + if other._isinfinity(): + return context._raise_error(InvalidOperation, 'INF // INF') + else: + return Infsign[self._sign ^ other._sign] + + if not other: + if self: + return context._raise_error(DivisionByZero, 'x // 0', + self._sign ^ other._sign) + else: + return context._raise_error(DivisionUndefined, '0 // 0') + + return self._divide(other, context)[0] + + def __rfloordiv__(self, other, context=None): + """Swaps self/other and returns __floordiv__.""" + other = _convert_other(other) + if other is NotImplemented: + return other + return other.__floordiv__(self, context=context) + + def __float__(self): + """Float representation.""" + return float(str(self)) + + def __int__(self): + """Converts self to an int, truncating if necessary.""" + if self._is_special: + if self._isnan(): + context = getcontext() + return context._raise_error(InvalidContext) + elif self._isinfinity(): + raise OverflowError("Cannot convert infinity to long") + s = (-1)**self._sign + if self._exp >= 0: + return s*int(self._int)*10**self._exp + else: + return s*int(self._int[:self._exp] or '0') + + def __long__(self): + """Converts to a long. + + Equivalent to long(int(self)) + """ + return long(self.__int__()) + + def _fix_nan(self, context): + """Decapitate the payload of a NaN to fit the context""" + payload = self._int + + # maximum length of payload is precision if _clamp=0, + # precision-1 if _clamp=1. + max_payload_len = context.prec - context._clamp + if len(payload) > max_payload_len: + payload = payload[len(payload)-max_payload_len:].lstrip('0') + return _dec_from_triple(self._sign, payload, self._exp, True) + return Decimal(self) + + def _fix(self, context): + """Round if it is necessary to keep self within prec precision. + + Rounds and fixes the exponent. Does not raise on a sNaN. + + Arguments: + self - Decimal instance + context - context used. + """ + + if self._is_special: + if self._isnan(): + # decapitate payload if necessary + return self._fix_nan(context) + else: + # self is +/-Infinity; return unaltered + return Decimal(self) + + # if self is zero then exponent should be between Etiny and + # Emax if _clamp==0, and between Etiny and Etop if _clamp==1. + Etiny = context.Etiny() + Etop = context.Etop() + if not self: + exp_max = [context.Emax, Etop][context._clamp] + new_exp = min(max(self._exp, Etiny), exp_max) + if new_exp != self._exp: + context._raise_error(Clamped) + return _dec_from_triple(self._sign, '0', new_exp) + else: + return Decimal(self) + + # exp_min is the smallest allowable exponent of the result, + # equal to max(self.adjusted()-context.prec+1, Etiny) + exp_min = len(self._int) + self._exp - context.prec + if exp_min > Etop: + # overflow: exp_min > Etop iff self.adjusted() > Emax + context._raise_error(Inexact) + context._raise_error(Rounded) + return context._raise_error(Overflow, 'above Emax', self._sign) + self_is_subnormal = exp_min < Etiny + if self_is_subnormal: + context._raise_error(Subnormal) + exp_min = Etiny + + # round if self has too many digits + if self._exp < exp_min: + context._raise_error(Rounded) + digits = len(self._int) + self._exp - exp_min + if digits < 0: + self = _dec_from_triple(self._sign, '1', exp_min-1) + digits = 0 + this_function = getattr(self, self._pick_rounding_function[context.rounding]) + changed = this_function(digits) + coeff = self._int[:digits] or '0' + if changed == 1: + coeff = str(int(coeff)+1) + ans = _dec_from_triple(self._sign, coeff, exp_min) + + if changed: + context._raise_error(Inexact) + if self_is_subnormal: + context._raise_error(Underflow) + if not ans: + # raise Clamped on underflow to 0 + context._raise_error(Clamped) + elif len(ans._int) == context.prec+1: + # we get here only if rescaling rounds the + # cofficient up to exactly 10**context.prec + if ans._exp < Etop: + ans = _dec_from_triple(ans._sign, + ans._int[:-1], ans._exp+1) + else: + # Inexact and Rounded have already been raised + ans = context._raise_error(Overflow, 'above Emax', + self._sign) + return ans + + # fold down if _clamp == 1 and self has too few digits + if context._clamp == 1 and self._exp > Etop: + context._raise_error(Clamped) + self_padded = self._int + '0'*(self._exp - Etop) + return _dec_from_triple(self._sign, self_padded, Etop) + + # here self was representable to begin with; return unchanged + return Decimal(self) + + _pick_rounding_function = {} + + # for each of the rounding functions below: + # self is a finite, nonzero Decimal + # prec is an integer satisfying 0 <= prec < len(self._int) + # + # each function returns either -1, 0, or 1, as follows: + # 1 indicates that self should be rounded up (away from zero) + # 0 indicates that self should be truncated, and that all the + # digits to be truncated are zeros (so the value is unchanged) + # -1 indicates that there are nonzero digits to be truncated + + def _round_down(self, prec): + """Also known as round-towards-0, truncate.""" + if _all_zeros(self._int, prec): + return 0 + else: + return -1 + + def _round_up(self, prec): + """Rounds away from 0.""" + return -self._round_down(prec) + + def _round_half_up(self, prec): + """Rounds 5 up (away from 0)""" + if self._int[prec] in '56789': + return 1 + elif _all_zeros(self._int, prec): + return 0 + else: + return -1 + + def _round_half_down(self, prec): + """Round 5 down""" + if _exact_half(self._int, prec): + return -1 + else: + return self._round_half_up(prec) + + def _round_half_even(self, prec): + """Round 5 to even, rest to nearest.""" + if _exact_half(self._int, prec) and \ + (prec == 0 or self._int[prec-1] in '02468'): + return -1 + else: + return self._round_half_up(prec) + + def _round_ceiling(self, prec): + """Rounds up (not away from 0 if negative.)""" + if self._sign: + return self._round_down(prec) + else: + return -self._round_down(prec) + + def _round_floor(self, prec): + """Rounds down (not towards 0 if negative)""" + if not self._sign: + return self._round_down(prec) + else: + return -self._round_down(prec) + + def _round_05up(self, prec): + """Round down unless digit prec-1 is 0 or 5.""" + if prec and self._int[prec-1] not in '05': + return self._round_down(prec) + else: + return -self._round_down(prec) + + def fma(self, other, third, context=None): + """Fused multiply-add. + + Returns self*other+third with no rounding of the intermediate + product self*other. + + self and other are multiplied together, with no rounding of + the result. The third operand is then added to the result, + and a single final rounding is performed. + """ + + other = _convert_other(other, raiseit=True) + + # compute product; raise InvalidOperation if either operand is + # a signaling NaN or if the product is zero times infinity. + if self._is_special or other._is_special: + if context is None: + context = getcontext() + if self._exp == 'N': + return context._raise_error(InvalidOperation, 'sNaN', self) + if other._exp == 'N': + return context._raise_error(InvalidOperation, 'sNaN', other) + if self._exp == 'n': + product = self + elif other._exp == 'n': + product = other + elif self._exp == 'F': + if not other: + return context._raise_error(InvalidOperation, + 'INF * 0 in fma') + product = Infsign[self._sign ^ other._sign] + elif other._exp == 'F': + if not self: + return context._raise_error(InvalidOperation, + '0 * INF in fma') + product = Infsign[self._sign ^ other._sign] + else: + product = _dec_from_triple(self._sign ^ other._sign, + str(int(self._int) * int(other._int)), + self._exp + other._exp) + + third = _convert_other(third, raiseit=True) + return product.__add__(third, context) + + def _power_modulo(self, other, modulo, context=None): + """Three argument version of __pow__""" + + # if can't convert other and modulo to Decimal, raise + # TypeError; there's no point returning NotImplemented (no + # equivalent of __rpow__ for three argument pow) + other = _convert_other(other, raiseit=True) + modulo = _convert_other(modulo, raiseit=True) + + if context is None: + context = getcontext() + + # deal with NaNs: if there are any sNaNs then first one wins, + # (i.e. behaviour for NaNs is identical to that of fma) + self_is_nan = self._isnan() + other_is_nan = other._isnan() + modulo_is_nan = modulo._isnan() + if self_is_nan or other_is_nan or modulo_is_nan: + if self_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + self) + if other_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + other) + if modulo_is_nan == 2: + return context._raise_error(InvalidOperation, 'sNaN', + modulo) + if self_is_nan: + return self._fix_n... [truncated message content] |
From: <fwi...@us...> - 2008-07-15 16:07:38
|
Revision: 4938 http://jython.svn.sourceforge.net/jython/?rev=4938&view=rev Author: fwierzbicki Date: 2008-07-15 08:41:20 -0700 (Tue, 15 Jul 2008) Log Message: ----------- tagging alpha0 release. Added Paths: ----------- tags/Release_2_5alpha0/ Copied: tags/Release_2_5alpha0 (from rev 4937, branches/asm) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-07-15 15:23:37
|
Revision: 4937 http://jython.svn.sourceforge.net/jython/?rev=4937&view=rev Author: fwierzbicki Date: 2008-07-15 08:23:32 -0700 (Tue, 15 Jul 2008) Log Message: ----------- Fixes in build.xml to make full-build work again. Some cleanup like the removal of old parser and old website tasks. Changed README to describe 2.5 alpha release. Modified Paths: -------------- branches/asm/README.txt branches/asm/build.xml Modified: branches/asm/README.txt =================================================================== --- branches/asm/README.txt 2008-07-14 20:12:27 UTC (rev 4936) +++ branches/asm/README.txt 2008-07-15 15:23:32 UTC (rev 4937) @@ -1,30 +1,13 @@ -Welcome to Jython 2.2rc3 +Welcome to Jython 2.5a0+ ======================= -This is the third release candidate of the 2.2 version of Jython. It -contains all of the new features for the 2.2 release: - - new-style classes - - Java List integration - - a PEP 302 implementation - - iterators - - generators - - __future__ division - - support for running on modern JVMs - - a new installer - - ssl and non-blocking support for socket +This is the first alpha of the 2.5 version of Jython. It +contains all of the most of the new features for the 2.5 release: In addition to these major features, several bugs have been fixed from 2.2rc2. See the NEWS file for a more complete list of changes. -The release was compiled on Mac OS X with JDK 5 but it should run on -1.4.2+. +The release was compiled on Mac OS X with JDK 5 and requires JDK 5 to run. -This release is intended to find any major bugs before releasing 2.2. If none -are found, this will become the 2.2 release. If you can run this and check for -bugs, it will be greatly appreciated. Bug reports can be created at -http://jython.org/bugs whereas more general questions can be sent to the -Jython-users mailing list, jyt...@li.... - -If this release proves stable, the final release of 2.2 will be in a couple -weeks. If not, successive release candidates will be made until all the major -bugs are ironed out. +As an alpha release, this release is incomplete and contains bugs. Do not +use in a production environment. Modified: branches/asm/build.xml =================================================================== --- branches/asm/build.xml 2008-07-14 20:12:27 UTC (rev 4936) +++ branches/asm/build.xml 2008-07-15 15:23:32 UTC (rev 4937) @@ -21,17 +21,6 @@ To build older releases, it may be necessary to use an older build.xml, too (with the corresponding tag). For example it is not possible to build Release_2_2alpha1 with this version of build.xml. - -Use case 3: build only the parser (grammar) -------------------------------------------- - - override javaccHome in ant.properties (if necessary) - - call target 'parser' -or: - - set javaccHome, either on the command line, or inside parser/build.xml - - call parser/build.xml (default target) -This build will only create files inside org/python/parser. - - Note on targets --------------- The following targets are designed for direct invocation: @@ -39,7 +28,6 @@ - developer-build - full-build - clean (uses developer-build settings if called directly) - - parser (uses developer-build settings if called directly) Following an ant convention, the callable targets have a description attribute. All other targets may give unpredicted results if called directly. @@ -59,12 +47,6 @@ An example ant.properties file: ------------------------------- -# - define the home for javacc (only used for parser grammar) -javaccHome=${basedir}/../externals/javacc-4.0 - -# - ht2html tool for the doc target (only needed for full-build) -ht2html.dir=${basedir}/../externals/ht2html-2.0 - # - define the home of the corresponding CPython version python.home=c:/Programme/Python/Python23 @@ -162,7 +144,6 @@ <property name="gensrc.dir" value="${output.dir}/gensrc" /> <property name="dist.dir" value="${work.dir}/dist" /> <property name="apidoc.dir" value="${dist.dir}/Doc/javadoc" /> - <property name="parser.dir" value="${source.dir}/org/python/parser" /> <!-- classpaths --> <path id="main.classpath"> @@ -175,9 +156,6 @@ <pathelement path="${extlibs.dir}/mysql-connector-java-5.1.6.jar" /> <pathelement path="${extlibs.dir}/postgresql-8.3-603.jdbc4.jar" /> <pathelement path="${extlibs.dir}/antlr-2.7.7.jar" /> - <!-- - <pathelement path="${extlibs.dir}/antlr-3.0.1.jar" /> - --> <pathelement path="${extlibs.dir}/antlr-3.1b1.jar" /> <pathelement path="${extlibs.dir}/stringtemplate-3.1b1.jar" /> </path> @@ -205,7 +183,8 @@ <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> <!-- The current version info --> - <property name="jython.version" value="2.5a0" /> + <property name="jython.version" value="2.5a0+"/> + <property name="jython.version.noplus" value="2.5a0"/> <property name="jython.major_version" value="2"/> <property name="jython.minor_version" value="5"/> <property name="jython.micro_version" value="0"/> @@ -234,18 +213,23 @@ <property name="full-build" value="true" /> <!-- predefined main directory for checkout --> - <property name="svn.main.dir" value="trunk" /> + <property name="svn.main.dir" value="branches" /> + <property name="svn.code.dir" value="asm" /> + <property name="svn.installer.dir" value="installer25" /> <!-- properties work.dir and jython.base.dir are also definied in init, so full-preinit must run first to work --> - <property name="work.dir" value="${basedir}/../full_build/${svn.main.dir}" /> + <property name="work.dir" value="${basedir}/../full_build/work" /> <property name="svn.checkout.dir" value="${work.dir}/checkout" /> - <property name="jython.base.dir" value="${svn.checkout.dir}/jython" /> + <property name="jython.base.dir" value="${svn.checkout.dir}/${svn.code.dir}" /> <property name="has.repositories.connection" value="true" /> <property name="python.exe" value="${python.home}/python" /> + <property name="do.checkout" value="false" /> + <!-- <condition property="do.checkout" value="true"> <istrue value="${has.repositories.connection}" /> </condition> + --> <!-- classpath for svn ant task --> <path id="svn.classpath"> @@ -273,7 +257,6 @@ <echo>work.dir = '${work.dir}'</echo> <echo>jython.base.dir = '${jython.base.dir}'</echo> <echo>source.dir = '${source.dir}'</echo> - <echo>parser.dir = '${parser.dir}'</echo> <echo>output.dir = '${output.dir}'</echo> <echo>compile.dir = '${compile.dir}'</echo> <echo>exposed.dir = '${exposed.dir}'</echo> @@ -283,7 +266,6 @@ <echo>templates.lazy = '${templates.lazy}'</echo> <echo>python.lib = '${python.lib}'</echo> <echo>javaccHome = '${javaccHome}'</echo> - <echo>ht2html.dir = '${ht2html.dir}'</echo> <echo>build.compiler = '${build.compiler}'</echo> <echo>jdk.target.version = '${jdk.target.version}'</echo> <echo>jdk.source.version = '${jdk.source.version}'</echo> @@ -354,13 +336,13 @@ <target name="checkout" depends="prepare" if="do.checkout"> <svn javahl="${javahl.dir}" > - <checkout url="https://jython.svn.sourceforge.net/svnroot/jython/${svn.main.dir}/jython" revision="${snapshot.revision}" destPath="${svn.checkout.dir}/jython" /> - <checkout url="https://jython.svn.sourceforge.net/svnroot/jython/${svn.main.dir}/installer" revision="${snapshot.revision}" destPath="${svn.checkout.dir}/installer" /> + <checkout url="https://jython.svn.sourceforge.net/svnroot/jython/${svn.main.dir}/${svn.installer.dir}" revision="${snapshot.revision}" destPath="${svn.checkout.dir}/${svn.installer.dir}" /> + <checkout url="https://jython.svn.sourceforge.net/svnroot/jython/${svn.main.dir}/${svn.code.dir}" revision="${snapshot.revision}" destPath="${svn.checkout.dir}/${svn.code.dir}" /> </svn> <!-- checkout cpython license from the correct python maintenance branch --> <svn javahl="${javahl.dir}" > - <checkout url="http://svn.python.org/projects/python/branches/release23-maint/" destPath="${svn.checkout.dir}/python" recurse="false" /> + <checkout url="http://svn.python.org/projects/python/branches/release25-maint/" destPath="${svn.checkout.dir}/python" recurse="false" /> </svn> </target> @@ -410,13 +392,6 @@ </replace> </target> - <!-- separate build.xml for parser grammar --> - <!-- we use settings as in developer-build - at the moment all properties will already be set if we do a full build --> - <target name="parser" depends="init, prepare" if="javaccHome" description="the grammar build"> - <echo>processing ${parser.dir}/build.xml</echo> - <ant dir="${parser.dir}" /> - </target> - <target name="template-init" depends="prepare"> <javac srcdir="${source.dir}/" destdir="${compile.dir}" @@ -438,14 +413,14 @@ </target> <target name="antlr_gen" depends="init,needed-check,prepare-output" unless="antlr.notneeded"> - <java classname="org.antlr.Tool" failonerror="true"> + <java classname="org.antlr.Tool" failonerror="true" fork="true" dir="${jython.base.dir}"> <arg value="-fo"/> - <arg path="build/gensrc/org/python/antlr"/> + <arg path="${work.dir}/build/gensrc/org/python/antlr"/> <arg value="-lib"/> - <arg path="build/gensrc/org/python/antlr"/> - <arg file="grammar/Python.g"/> - <arg file="grammar/PythonWalker.g"/> - <arg file="grammar/PythonPartial.g"/> + <arg path="${work.dir}/build/gensrc/org/python/antlr"/> + <arg file="${jython.base.dir}/grammar/Python.g"/> + <arg file="${jython.base.dir}/grammar/PythonWalker.g"/> + <arg file="${jython.base.dir}/grammar/PythonPartial.g"/> <classpath refid="main.classpath"/> </java> @@ -460,7 +435,7 @@ </target> - <target name="compile" depends="init,antlr_gen,jarjar,brand-version"> + <target name="compile" depends="init,antlr_gen,copy-antlr,jarjar,brand-version"> <javac destdir="${compile.dir}" target="${jdk.target.version}" source="${jdk.source.version}" @@ -470,7 +445,6 @@ <src path="${source.dir}"/> <src path="${gensrc.dir}"/> - <exclude name="org/python/parser/python.java" /> <exclude name="**/handler/InformixDataHandler.java" unless="informix.present" /> <exclude name="**/handler/OracleDataHandler.java" unless="oracle.present" /> <classpath refid="main.classpath" /> @@ -590,26 +564,6 @@ </jar> </target> - <!-- build the .html files using the ht2html tool --> - <target name="doc" depends="compile" if="full-build"> - <fail unless="ht2html.dir" message="ht2html.dir is not set" /> - <copy todir="${dist.dir}/Doc" preservelastmodified="true"> - <fileset dir="Doc" includes="*.ht, **/*.gif" /> - </copy> - <!-- Create .html files in Doc --> - <apply executable="${python.exe}" dir="Doc"> - <env key="PYTHONPATH" path="${jython.base.dir}/Misc/htgen" /> - <arg line="${ht2html.dir}/ht2html.py" /> - <arg line="-s JyLocalGenerator" /> - <fileset dir="${dist.dir}/Doc"> - <include name="*.ht" /> - </fileset> - </apply> - <delete> - <fileset dir="${dist.dir}/Doc" includes="*.ht" /> - </delete> - </target> - <target name="javadoc" depends="compile"> <path id="javadoc.classpath"> <pathelement path="${java.class.path}" /> @@ -628,6 +582,12 @@ </javadoc> </target> + <target name="copy-antlr" if="full-build"> + <copy todir="${dist.dir}/src/java" preservelastmodified="true"> + <fileset dir="${gensrc.dir}" /> + </copy> + </target> + <target name="copy-full" depends="copy-lib" if="full-build"> <echo>copy misc files from ${jython.base.dir}</echo> <copy todir="${dist.dir}" preservelastmodified="true"> @@ -648,8 +608,6 @@ <include name="Lib/jxxload_help/*.java" /> <include name="tests/java/**/*.java" /> <include name="src/org/**/ucnhash.dat" /> - <include name="src/org/python/parser/build.xml" /> - <exclude name="src/org/python/parser/python.java" /> </fileset> </copy> @@ -695,7 +653,7 @@ <fileset dir="${jython.base.dir}/extlibs"> <exclude name="profile.properties"/> </fileset> - <fileset dir="${jython.base.dir}/build"> + <fileset dir="${work.dir}/build"> <include name="*.jar"/> <include name="*.properties"/> </fileset> @@ -703,7 +661,7 @@ </target> <!-- wrap the build into the installer --> - <target name="install" depends="brand-readme-version, doc, jar-complete, javadoc, copy-full"> + <target name="install" depends="brand-readme-version, jar-complete, javadoc, copy-full"> <property name="install.src.dir" value="${jython.base.dir}/../installer25/src/java" /> <echo>compiling installer from ${install.src.dir}</echo> <javac srcdir="${install.src.dir}" @@ -730,7 +688,7 @@ <fileset dir="${install.src.dir}" includes="**/*.png" excludes="bin/**" /> </copy> <echo>building installer .jar file</echo> - <jar destfile="${work.dir}/jython_installer-${jython.version}.jar" basedir="${dist.dir}" update="true"> + <jar destfile="${work.dir}/jython_installer-${jython.version.noplus}.jar" basedir="${dist.dir}" update="true"> <manifest> <attribute name="Main-Class" value="org.python.util.install.Installation" /> <attribute name="Built-By" value="${user.name}" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2008-07-14 20:12:30
|
Revision: 4936 http://jython.svn.sourceforge.net/jython/?rev=4936&view=rev Author: leosoto Date: 2008-07-14 13:12:27 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Allow derived types written in Jython to implement a __tojava__ method. This will allow better integration with java for python types such as decimal.Decimal, datetime.date, etc. Modified Paths: -------------- branches/asm/src/org/python/core/PyArrayDerived.java branches/asm/src/org/python/core/PyBaseExceptionDerived.java branches/asm/src/org/python/core/PyBooleanDerived.java branches/asm/src/org/python/core/PyClassMethodDerived.java branches/asm/src/org/python/core/PyComplexDerived.java branches/asm/src/org/python/core/PyDictionaryDerived.java branches/asm/src/org/python/core/PyEnumerateDerived.java branches/asm/src/org/python/core/PyFileDerived.java branches/asm/src/org/python/core/PyFloatDerived.java branches/asm/src/org/python/core/PyFrozenSetDerived.java branches/asm/src/org/python/core/PyIntegerDerived.java branches/asm/src/org/python/core/PyListDerived.java branches/asm/src/org/python/core/PyLongDerived.java branches/asm/src/org/python/core/PyModuleDerived.java branches/asm/src/org/python/core/PyObjectDerived.java branches/asm/src/org/python/core/PyPropertyDerived.java branches/asm/src/org/python/core/PySetDerived.java branches/asm/src/org/python/core/PySliceDerived.java branches/asm/src/org/python/core/PyStringDerived.java branches/asm/src/org/python/core/PySuperDerived.java branches/asm/src/org/python/core/PyTupleDerived.java branches/asm/src/org/python/core/PyTypeDerived.java branches/asm/src/org/python/core/PyUnicodeDerived.java branches/asm/src/org/python/modules/_weakref/ReferenceTypeDerived.java branches/asm/src/org/python/modules/collections/PyDefaultDictDerived.java branches/asm/src/org/python/modules/collections/PyDequeDerived.java branches/asm/src/org/python/modules/random/PyRandomDerived.java branches/asm/src/org/python/modules/thread/PyLocalDerived.java branches/asm/src/org/python/modules/zipimport/zipimporterDerived.java branches/asm/src/templates/object.derived Modified: branches/asm/src/org/python/core/PyArrayDerived.java =================================================================== --- branches/asm/src/org/python/core/PyArrayDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyArrayDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyBaseExceptionDerived.java =================================================================== --- branches/asm/src/org/python/core/PyBaseExceptionDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyBaseExceptionDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1029,6 +1029,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyBooleanDerived.java =================================================================== --- branches/asm/src/org/python/core/PyBooleanDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyBooleanDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyClassMethodDerived.java =================================================================== --- branches/asm/src/org/python/core/PyClassMethodDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyClassMethodDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyComplexDerived.java =================================================================== --- branches/asm/src/org/python/core/PyComplexDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyComplexDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyDictionaryDerived.java =================================================================== --- branches/asm/src/org/python/core/PyDictionaryDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyDictionaryDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyEnumerateDerived.java =================================================================== --- branches/asm/src/org/python/core/PyEnumerateDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyEnumerateDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -553,104 +553,156 @@ public PyObject __iadd__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__iadd__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__iadd__(other); } public PyObject __isub__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__isub__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__isub__(other); } public PyObject __imul__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__imul__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__imul__(other); } public PyObject __idiv__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__idiv__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__idiv__(other); } public PyObject __ifloordiv__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__ifloordiv__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__ifloordiv__(other); } public PyObject __itruediv__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__itruediv__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__itruediv__(other); } public PyObject __imod__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__imod__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__imod__(other); } public PyObject __ipow__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__ipow__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__ipow__(other); } public PyObject __ilshift__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__ilshift__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__ilshift__(other); } public PyObject __irshift__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__irshift__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__irshift__(other); } public PyObject __iand__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__iand__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__iand__(other); } public PyObject __ior__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__ior__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__ior__(other); } public PyObject __ixor__(PyObject other) { PyType self_type=getType(); PyObject impl=self_type.lookup("__ixor__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res==Py.NotImplemented) + return null; + return res; + } return super.__ixor__(other); } @@ -683,12 +735,17 @@ PyObject impl=self_type.lookup("__hash__"); if (impl!=null) { PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyInteger) + if (res instanceof PyInteger) { return((PyInteger)res).getValue(); + } else + if (res instanceof PyLong) { + return((PyLong)res).getValue().intValue(); + } throw Py.TypeError("__hash__ should return a int"); } - if (self_type.lookup("__eq__")!=null||self_type.lookup("__cmp__")!=null) + if (self_type.lookup("__eq__")!=null||self_type.lookup("__cmp__")!=null) { throw Py.TypeError("unhashable type"); + } return super.hashCode(); } @@ -708,16 +765,22 @@ public int __cmp__(PyObject other) { PyType self_type=getType(); - PyObject impl=self_type.lookup("__cmp__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res instanceof PyInteger) { - int v=((PyInteger)res).getValue(); - return v<0?-1:v>0?1:0; - } - throw Py.TypeError("__cmp__ should return a int"); + PyType[]where_type=new PyType[1]; + PyObject impl=self_type.lookup_where("__cmp__",where_type); + // Full Compatibility with CPython __cmp__: + // If the derived type don't override __cmp__, the + // *internal* super().__cmp__ should be called, not the + // exposed one. The difference is that the exposed __cmp__ + // throws a TypeError if the argument is an instance of the same type. + if (impl==null||where_type[0]==TYPE||Py.isSubClass(TYPE,where_type[0])) { + return super.__cmp__(other); } - return super.__cmp__(other); + PyObject res=impl.__get__(this,self_type).__call__(other); + if (res instanceof PyInteger) { + int v=((PyInteger)res).getValue(); + return v<0?-1:v>0?1:0; + } + throw Py.TypeError("__cmp__ should return a int"); } public boolean __nonzero__() { @@ -990,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyFileDerived.java =================================================================== --- branches/asm/src/org/python/core/PyFileDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyFileDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyFloatDerived.java =================================================================== --- branches/asm/src/org/python/core/PyFloatDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyFloatDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyFrozenSetDerived.java =================================================================== --- branches/asm/src/org/python/core/PyFrozenSetDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyFrozenSetDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyIntegerDerived.java =================================================================== --- branches/asm/src/org/python/core/PyIntegerDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyIntegerDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyListDerived.java =================================================================== --- branches/asm/src/org/python/core/PyListDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyListDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyLongDerived.java =================================================================== --- branches/asm/src/org/python/core/PyLongDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyLongDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyModuleDerived.java =================================================================== --- branches/asm/src/org/python/core/PyModuleDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyModuleDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1029,6 +1029,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyObjectDerived.java =================================================================== --- branches/asm/src/org/python/core/PyObjectDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyObjectDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyPropertyDerived.java =================================================================== --- branches/asm/src/org/python/core/PyPropertyDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyPropertyDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PySetDerived.java =================================================================== --- branches/asm/src/org/python/core/PySetDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PySetDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PySliceDerived.java =================================================================== --- branches/asm/src/org/python/core/PySliceDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PySliceDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyStringDerived.java =================================================================== --- branches/asm/src/org/python/core/PyStringDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyStringDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,4 +1053,21 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + } Modified: branches/asm/src/org/python/core/PySuperDerived.java =================================================================== --- branches/asm/src/org/python/core/PySuperDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PySuperDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyTupleDerived.java =================================================================== --- branches/asm/src/org/python/core/PyTupleDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyTupleDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,6 +1053,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyTypeDerived.java =================================================================== --- branches/asm/src/org/python/core/PyTypeDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyTypeDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1029,6 +1029,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/core/PyUnicodeDerived.java =================================================================== --- branches/asm/src/org/python/core/PyUnicodeDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/core/PyUnicodeDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1053,4 +1053,21 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + } Modified: branches/asm/src/org/python/modules/_weakref/ReferenceTypeDerived.java =================================================================== --- branches/asm/src/org/python/modules/_weakref/ReferenceTypeDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/modules/_weakref/ReferenceTypeDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1055,6 +1055,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/modules/collections/PyDefaultDictDerived.java =================================================================== --- branches/asm/src/org/python/modules/collections/PyDefaultDictDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/modules/collections/PyDefaultDictDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1055,6 +1055,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/modules/collections/PyDequeDerived.java =================================================================== --- branches/asm/src/org/python/modules/collections/PyDequeDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/modules/collections/PyDequeDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1055,6 +1055,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/modules/random/PyRandomDerived.java =================================================================== --- branches/asm/src/org/python/modules/random/PyRandomDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/modules/random/PyRandomDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1055,6 +1055,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/modules/thread/PyLocalDerived.java =================================================================== --- branches/asm/src/org/python/modules/thread/PyLocalDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/modules/thread/PyLocalDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1031,6 +1031,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/org/python/modules/zipimport/zipimporterDerived.java =================================================================== --- branches/asm/src/org/python/modules/zipimport/zipimporterDerived.java 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/org/python/modules/zipimport/zipimporterDerived.java 2008-07-14 20:12:27 UTC (rev 4936) @@ -1031,6 +1031,23 @@ } } + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c!=Object.class)&&(c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } + public String toString() { PyType self_type=getType(); PyObject impl=self_type.lookup("__repr__"); Modified: branches/asm/src/templates/object.derived =================================================================== --- branches/asm/src/templates/object.derived 2008-07-14 19:31:38 UTC (rev 4935) +++ branches/asm/src/templates/object.derived 2008-07-14 20:12:27 UTC (rev 4936) @@ -385,3 +385,20 @@ } } } + + public Object __tojava__(Class c) { + // If we are not being asked by the "default" conversion to java, then + // we can provide this as the result, as long as it is a instance of the + // specified class. Without this, derived.__tojava__(PyObject.class) + // would broke. (And that's not pure speculation: PyReflectedFunction's + // ReflectedArgs asks for things like that). + if ((c != Object.class) && (c.isInstance(this))) { + return this; + } + // Otherwise, we call the derived __tojava__, if it exists: + PyType self_type=getType(); + PyObject impl=self_type.lookup("__tojava__"); + if (impl!=null) + return impl.__get__(this,self_type).__call__(Py.java2py(c)).__tojava__(Object.class); + return super.__tojava__(c); + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-14 19:31:40
|
Revision: 4935 http://jython.svn.sourceforge.net/jython/?rev=4935&view=rev Author: pjenvey Date: 2008-07-14 12:31:38 -0700 (Mon, 14 Jul 2008) Log Message: ----------- o re-integrate Jython distutils changes o check for $py.class on Jython instead of pyc in test_build_py Modified Paths: -------------- branches/asm/Lib/distutils/ccompiler.py branches/asm/Lib/distutils/command/bdist.py branches/asm/Lib/distutils/command/bdist_dumb.py branches/asm/Lib/distutils/command/install.py branches/asm/Lib/distutils/command/sdist.py branches/asm/Lib/distutils/file_util.py branches/asm/Lib/distutils/spawn.py branches/asm/Lib/distutils/sysconfig.py branches/asm/Lib/distutils/tests/test_build_py.py branches/asm/Lib/distutils/util.py Modified: branches/asm/Lib/distutils/ccompiler.py =================================================================== --- branches/asm/Lib/distutils/ccompiler.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/ccompiler.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -1059,6 +1059,7 @@ # compiler ('cygwin.*', 'unix'), ('os2emx', 'emx'), + ('java.*', 'jython'), # OS name mappings ('posix', 'unix'), @@ -1107,6 +1108,8 @@ "MetroWerks CodeWarrior"), 'emx': ('emxccompiler', 'EMXCCompiler', "EMX port of GNU C Compiler for OS/2"), + 'jython': ('jythoncompiler', 'JythonCompiler', + "Compiling is not supported on Jython"), } def show_compilers(): Modified: branches/asm/Lib/distutils/command/bdist.py =================================================================== --- branches/asm/Lib/distutils/command/bdist.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/command/bdist.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -59,6 +59,7 @@ # This won't do in reality: will need to distinguish RPM-ish Linux, # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. default_format = { 'posix': 'gztar', + 'java': 'gztar', 'nt': 'zip', 'os2': 'zip', } Modified: branches/asm/Lib/distutils/command/bdist_dumb.py =================================================================== --- branches/asm/Lib/distutils/command/bdist_dumb.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/command/bdist_dumb.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -42,6 +42,7 @@ boolean_options = ['keep-temp', 'skip-build', 'relative'] default_format = { 'posix': 'gztar', + 'java': 'gztar', 'nt': 'zip', 'os2': 'zip' } Modified: branches/asm/Lib/distutils/command/install.py =================================================================== --- branches/asm/Lib/distutils/command/install.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/command/install.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -65,6 +65,13 @@ 'headers': '$base/Include/$dist_name', 'scripts': '$base/Scripts', 'data' : '$base', + }, + 'java': { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', } } Modified: branches/asm/Lib/distutils/command/sdist.py =================================================================== --- branches/asm/Lib/distutils/command/sdist.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/command/sdist.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -80,6 +80,7 @@ 'no-prune': 'prune' } default_format = { 'posix': 'gztar', + 'java': 'gztar', 'nt': 'zip' } def initialize_options (self): @@ -376,13 +377,16 @@ """ log.info("reading manifest file '%s'", self.manifest) manifest = open(self.manifest) - while 1: - line = manifest.readline() - if line == '': # end of file - break - if line[-1] == '\n': - line = line[0:-1] - self.filelist.append(line) + try: + while 1: + line = manifest.readline() + if line == '': # end of file + break + if line[-1] == '\n': + line = line[0:-1] + self.filelist.append(line) + finally: + manifest.close() # read_manifest () Modified: branches/asm/Lib/distutils/file_util.py =================================================================== --- branches/asm/Lib/distutils/file_util.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/file_util.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -170,7 +170,7 @@ # before chmod() (at least under NT). if preserve_times: os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) - if preserve_mode: + if preserve_mode and hasattr(os, 'chmod'): os.chmod(dst, S_IMODE(st[ST_MODE])) return (dst, 1) Modified: branches/asm/Lib/distutils/spawn.py =================================================================== --- branches/asm/Lib/distutils/spawn.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/spawn.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -39,6 +39,8 @@ _spawn_nt(cmd, search_path, dry_run=dry_run) elif os.name == 'os2': _spawn_os2(cmd, search_path, dry_run=dry_run) + elif os.name == 'java': + _spawn_java(cmd, search_path, dry_run=dry_run) else: raise DistutilsPlatformError, \ "don't know how to spawn programs on platform '%s'" % os.name @@ -176,6 +178,27 @@ # _spawn_posix () +def _spawn_java(cmd, + search_path=1, + verbose=0, + dry_run=0): + executable = cmd[0] + cmd = ' '.join(_nt_quote_args(cmd)) + log.info(cmd) + if not dry_run: + try: + rc = os.system(cmd) >> 8 + except OSError, exc: + # this seems to happen when the command isn't found + raise DistutilsExecError, \ + "command '%s' failed: %s" % (executable, exc[-1]) + if rc != 0: + # and this reflects the command running but failing + print "command '%s' failed with exit status %d" % (executable, rc) + raise DistutilsExecError, \ + "command '%s' failed with exit status %d" % (executable, rc) + + def find_executable(executable, path=None): """Try to find 'executable' in the directories listed in 'path' (a string listing directories separated by 'os.pathsep'; defaults to Modified: branches/asm/Lib/distutils/sysconfig.py =================================================================== --- branches/asm/Lib/distutils/sysconfig.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/sysconfig.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -73,7 +73,7 @@ return os.path.join(prefix, "Mac", "Include") else: return os.path.join(prefix, "Include") - elif os.name == "os2": + elif os.name == "os2" or os.name == "java": return os.path.join(prefix, "Include") else: raise DistutilsPlatformError( @@ -127,7 +127,7 @@ else: return os.path.join(prefix, "Lib", "site-packages") - elif os.name == "os2": + elif os.name == "os2" or os.name == "java": if standard_lib: return os.path.join(PREFIX, "Lib") else: @@ -476,6 +476,13 @@ _config_vars = g +def _init_jython(): + """Initialize the module as appropriate for Jython""" + # Stub out some values that build_ext expects; they don't matter + # anyway + _init_os2() + + def get_config_vars(*args): """With no arguments, return a dictionary of all configuration variables relevant for the current platform. Generally this includes @@ -488,7 +495,12 @@ """ global _config_vars if _config_vars is None: - func = globals().get("_init_" + os.name) + if sys.platform.startswith('java'): + # Jython might pose as a different os.name, but we always + # want _init_jython regardless + func = _init_jython + else: + func = globals().get("_init_" + os.name) if func: func() else: Modified: branches/asm/Lib/distutils/tests/test_build_py.py =================================================================== --- branches/asm/Lib/distutils/tests/test_build_py.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/tests/test_build_py.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -53,7 +53,10 @@ pkgdest = os.path.join(destination, "pkg") files = os.listdir(pkgdest) self.assert_("__init__.py" in files) - self.assert_("__init__.pyc" in files) + if sys.platform.startswith('java'): + self.assert_("__init__$py.class" in files, files) + else: + self.assert_("__init__.pyc" in files) self.assert_("README.txt" in files) def test_empty_package_dir (self): Modified: branches/asm/Lib/distutils/util.py =================================================================== --- branches/asm/Lib/distutils/util.py 2008-07-14 19:27:40 UTC (rev 4934) +++ branches/asm/Lib/distutils/util.py 2008-07-14 19:31:38 UTC (rev 4935) @@ -155,7 +155,7 @@ Otherwise, it requires making 'pathname' relative and then joining the two, which is tricky on DOS/Windows and Mac OS. """ - if os.name == 'posix': + if os.name == 'posix' or os.name == 'java': if not os.path.isabs(pathname): return os.path.join(new_root, pathname) else: @@ -480,7 +480,10 @@ # Terminology from the py_compile module: # cfile - byte-compiled file # dfile - purported source filename (same as 'file' by default) - cfile = file + (__debug__ and "c" or "o") + if sys.platform.startswith('java'): + cfile = file[:-3] + '$py.class' + else: + cfile = file + (__debug__ and "c" or "o") dfile = file if prefix: if file[:len(prefix)] != prefix: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-07-14 19:27:43
|
Revision: 4934 http://jython.svn.sourceforge.net/jython/?rev=4934&view=rev Author: fwierzbicki Date: 2008-07-14 12:27:40 -0700 (Mon, 14 Jul 2008) Log Message: ----------- generate newlines before the dedents again. Although the reverse was solving some problems, it was creating more. Modified Paths: -------------- branches/asm/src/org/python/antlr/PythonTokenSource.java Modified: branches/asm/src/org/python/antlr/PythonTokenSource.java =================================================================== --- branches/asm/src/org/python/antlr/PythonTokenSource.java 2008-07-14 19:26:58 UTC (rev 4933) +++ branches/asm/src/org/python/antlr/PythonTokenSource.java 2008-07-14 19:27:40 UTC (rev 4934) @@ -174,6 +174,8 @@ newline = new CommonToken(PythonLexer.NEWLINE, "\n"); newline.setLine(t.getLine()); newline.setCharPositionInLine(t.getCharPositionInLine()); + //XXX: should be moved to after DEDENTS are generated, but doesn't work yet. + tokens.addElement(newline); } // compute cpos as the char pos of next non-WS token in line @@ -216,9 +218,13 @@ } sp = prevIndex; // pop those off indent level } + /* + //XXX: I think this is really where this needs to be, but causes more problems than it + // solves at the moment. if (t.getType() == PythonLexer.EOF) { tokens.addElement(newline); } + */ if (t.getType() != PythonLexer.LEADING_WS) { // discard WS tokens.addElement(t); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-14 19:27:04
|
Revision: 4933 http://jython.svn.sourceforge.net/jython/?rev=4933&view=rev Author: pjenvey Date: 2008-07-14 12:26:58 -0700 (Mon, 14 Jul 2008) Log Message: ----------- from: http://svn.python.org/projects/python/branches/release25-maint/Lib/distutils@64955 Modified Paths: -------------- branches/asm/Lib/distutils/ccompiler.py branches/asm/Lib/distutils/command/bdist.py branches/asm/Lib/distutils/command/bdist_dumb.py branches/asm/Lib/distutils/command/install.py branches/asm/Lib/distutils/command/sdist.py branches/asm/Lib/distutils/file_util.py branches/asm/Lib/distutils/spawn.py branches/asm/Lib/distutils/sysconfig.py branches/asm/Lib/distutils/util.py Added Paths: ----------- branches/asm/Lib/distutils/tests/ branches/asm/Lib/distutils/tests/test_build_py.py Modified: branches/asm/Lib/distutils/ccompiler.py =================================================================== --- branches/asm/Lib/distutils/ccompiler.py 2008-07-14 19:25:59 UTC (rev 4932) +++ branches/asm/Lib/distutils/ccompiler.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -3,9 +3,9 @@ Contains CCompiler, an abstract base class that defines the interface for the Distutils compiler abstraction model.""" -# This module should be kept compatible with Python 1.5.2. +# This module should be kept compatible with Python 2.1. -__revision__ = "$Id: ccompiler.py 37185 2004-08-29 16:45:13Z loewis $" +__revision__ = "$Id: ccompiler.py 46331 2006-05-26 14:07:23Z bob.ippolito $" import sys, os, re from types import * @@ -15,7 +15,6 @@ from distutils.file_util import move_file from distutils.dir_util import mkpath from distutils.dep_util import newer_pairwise, newer_group -from distutils.sysconfig import python_build from distutils.util import split_quoted, execute from distutils import log @@ -368,7 +367,7 @@ # Get the list of expected output (object) files objects = self.object_filenames(sources, - strip_dir=python_build, + strip_dir=0, output_dir=outdir) assert len(objects) == len(sources) @@ -475,8 +474,7 @@ which source files can be skipped. """ # Get the list of expected output (object) files - objects = self.object_filenames(sources, strip_dir=python_build, - output_dir=output_dir) + objects = self.object_filenames(sources, output_dir=output_dir) assert len(objects) == len(sources) if self.force: @@ -685,13 +683,17 @@ # A concrete compiler class can either override this method # entirely or implement _compile(). - + macros, objects, extra_postargs, pp_opts, build = \ self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) - for obj, (src, ext) in build.items(): + for obj in objects: + try: + src, ext = build[obj] + except KeyError: + continue self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) # Return *all* object filenames, not just the ones we just built. @@ -699,7 +701,7 @@ def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): """Compile 'src' to product 'obj'.""" - + # A concrete compiler class that does not override compile() # should implement _compile(). pass @@ -1057,7 +1059,6 @@ # compiler ('cygwin.*', 'unix'), ('os2emx', 'emx'), - ('java.*', 'jython'), # OS name mappings ('posix', 'unix'), @@ -1106,8 +1107,6 @@ "MetroWerks CodeWarrior"), 'emx': ('emxccompiler', 'EMXCCompiler', "EMX port of GNU C Compiler for OS/2"), - 'jython': ('jythoncompiler', 'JythonCompiler', - "Compiling is not supported on Jython"), } def show_compilers(): Modified: branches/asm/Lib/distutils/command/bdist.py =================================================================== --- branches/asm/Lib/distutils/command/bdist.py 2008-07-14 19:25:59 UTC (rev 4932) +++ branches/asm/Lib/distutils/command/bdist.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -3,9 +3,9 @@ Implements the Distutils 'bdist' command (create a built [binary] distribution).""" -# This module should be kept compatible with Python 1.5.2. +# This module should be kept compatible with Python 2.1. -__revision__ = "$Id: bdist.py 29762 2002-11-19 13:12:28Z akuchling $" +__revision__ = "$Id: bdist.py 37828 2004-11-10 22:23:15Z loewis $" import os, string from types import * @@ -59,7 +59,6 @@ # This won't do in reality: will need to distinguish RPM-ish Linux, # Debian-ish Linux, Solaris, FreeBSD, ..., Windows, Mac OS. default_format = { 'posix': 'gztar', - 'java': 'gztar', 'nt': 'zip', 'os2': 'zip', } @@ -79,7 +78,7 @@ 'wininst': ('bdist_wininst', "Windows executable installer"), 'zip': ('bdist_dumb', "ZIP file"), - #'pkgtool': ('bdist_pkgtool', + #'pkgtool': ('bdist_pkgtool', # "Solaris pkgtool distribution"), #'sdux': ('bdist_sdux', "HP-UX swinstall depot"), } Modified: branches/asm/Lib/distutils/command/bdist_dumb.py =================================================================== --- branches/asm/Lib/distutils/command/bdist_dumb.py 2008-07-14 19:25:59 UTC (rev 4932) +++ branches/asm/Lib/distutils/command/bdist_dumb.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -4,15 +4,16 @@ distribution -- i.e., just an archive to be unpacked under $prefix or $exec_prefix).""" -# This module should be kept compatible with Python 1.5.2. +# This module should be kept compatible with Python 2.1. -__revision__ = "$Id: bdist_dumb.py 29901 2002-11-26 17:45:19Z akuchling $" +__revision__ = "$Id: bdist_dumb.py 38697 2005-03-23 18:54:36Z loewis $" import os from distutils.core import Command from distutils.util import get_platform from distutils.dir_util import create_tree, remove_tree, ensure_relative from distutils.errors import * +from distutils.sysconfig import get_python_version from distutils import log class bdist_dumb (Command): @@ -41,7 +42,6 @@ boolean_options = ['keep-temp', 'skip-build', 'relative'] default_format = { 'posix': 'gztar', - 'java': 'gztar', 'nt': 'zip', 'os2': 'zip' } @@ -54,7 +54,7 @@ self.dist_dir = None self.skip_build = 0 self.relative = 0 - + # initialize_options() @@ -118,8 +118,14 @@ ensure_relative(install.install_base)) # Make the archive - self.make_archive(pseudoinstall_root, - self.format, root_dir=archive_root) + filename = self.make_archive(pseudoinstall_root, + self.format, root_dir=archive_root) + if self.distribution.has_ext_modules(): + pyversion = get_python_version() + else: + pyversion = 'any' + self.distribution.dist_files.append(('bdist_dumb', pyversion, + filename)) if not self.keep_temp: remove_tree(self.bdist_dir, dry_run=self.dry_run) Modified: branches/asm/Lib/distutils/command/install.py =================================================================== --- branches/asm/Lib/distutils/command/install.py 2008-07-14 19:25:59 UTC (rev 4932) +++ branches/asm/Lib/distutils/command/install.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -4,9 +4,9 @@ from distutils import log -# This module should be kept compatible with Python 1.5.2. +# This module should be kept compatible with Python 2.1. -__revision__ = "$Id: install.py 38351 2005-01-20 19:16:27Z theller $" +__revision__ = "$Id: install.py 43363 2006-03-27 21:55:21Z phillip.eby $" import sys, os, string from types import * @@ -65,13 +65,6 @@ 'headers': '$base/Include/$dist_name', 'scripts': '$base/Scripts', 'data' : '$base', - }, - 'java': { - 'purelib': '$base/Lib/site-packages', - 'platlib': '$base/Lib/site-packages', - 'headers': '$base/Include/$dist_name', - 'scripts': '$base/bin', - 'data' : '$base', } } @@ -244,19 +237,15 @@ ("must supply either prefix/exec-prefix/home or " + "install-base/install-platbase -- not both") + if self.home and (self.prefix or self.exec_prefix): + raise DistutilsOptionError, \ + "must supply either home or prefix/exec-prefix -- not both" + # Next, stuff that's wrong (or dubious) only on certain platforms. - if os.name == 'posix': - if self.home and (self.prefix or self.exec_prefix): - raise DistutilsOptionError, \ - ("must supply either home or prefix/exec-prefix -- " + - "not both") - else: + if os.name != "posix": if self.exec_prefix: self.warn("exec-prefix option ignored on this platform") self.exec_prefix = None - if self.home: - self.warn("home option ignored on this platform") - self.home = None # Now the interesting logic -- so interesting that we farm it out # to other methods. The goal of these methods is to set the final @@ -412,15 +401,19 @@ def finalize_other (self): # Windows and Mac OS for now - if self.prefix is None: - self.prefix = os.path.normpath(sys.prefix) + if self.home is not None: + self.install_base = self.install_platbase = self.home + self.select_scheme("unix_home") + else: + if self.prefix is None: + self.prefix = os.path.normpath(sys.prefix) - self.install_base = self.install_platbase = self.prefix - try: - self.select_scheme(os.name) - except KeyError: - raise DistutilsPlatformError, \ - "I don't know how to install stuff on '%s'" % os.name + self.install_base = self.install_platbase = self.prefix + try: + self.select_scheme(os.name) + except KeyError: + raise DistutilsPlatformError, \ + "I don't know how to install stuff on '%s'" % os.name # finalize_other () @@ -538,7 +531,7 @@ not (self.path_file and self.install_path_file) and install_lib not in sys_path): log.debug(("modules installed to '%s', which is not in " - "Python's module search path (sys.path) -- " + "Python's module search path (sys.path) -- " "you'll have to change the search path yourself"), self.install_lib) @@ -608,6 +601,7 @@ ('install_headers', has_headers), ('install_scripts', has_scripts), ('install_data', has_data), + ('install_egg_info', lambda self:True), ] # class install Modified: branches/asm/Lib/distutils/command/sdist.py =================================================================== --- branches/asm/Lib/distutils/command/sdist.py 2008-07-14 19:25:59 UTC (rev 4932) +++ branches/asm/Lib/distutils/command/sdist.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -2,9 +2,9 @@ Implements the Distutils 'sdist' command (create a source distribution).""" -# This module should be kept compatible with Python 1.5.2. +# This module should be kept compatible with Python 2.1. -__revision__ = "$Id: sdist.py 37012 2004-08-16 12:15:00Z doko $" +__revision__ = "$Id: sdist.py 61268 2008-03-06 07:14:26Z martin.v.loewis $" import sys, os, string from types import * @@ -80,7 +80,6 @@ 'no-prune': 'prune' } default_format = { 'posix': 'gztar', - 'java': 'gztar', 'nt': 'zip' } def initialize_options (self): @@ -348,14 +347,14 @@ * the build tree (typically "build") * the release tree itself (only an issue if we ran "sdist" previously with --keep-temp, or it aborted) - * any RCS or CVS directories + * any RCS, CVS, .svn, .hg, .git, .bzr, _darcs directories """ build = self.get_finalized_command('build') base_dir = self.distribution.get_fullname() self.filelist.exclude_pattern(None, prefix=build.build_base) self.filelist.exclude_pattern(None, prefix=base_dir) - self.filelist.exclude_pattern(r'/(RCS|CVS|\.svn)/.*', is_regex=1) + self.filelist.exclude_pattern(r'(^|/)(RCS|CVS|\.svn|\.hg|\.git|\.bzr|_darcs)/.*', is_regex=1) def write_manifest (self): @@ -377,16 +376,13 @@ """ log.info("reading manifest file '%s'", self.manifest) manifest = open(self.manifest) - try: - while 1: - line = manifest.readline() - if line == '': # end of file - break - if line[-1] == '\n': - line = line[0:-1] - self.filelist.append(line) - finally: - manifest.close() + while 1: + line = manifest.readline() + if line == '': # end of file + break + if line[-1] == '\n': + line = line[0:-1] + self.filelist.append(line) # read_manifest () @@ -453,6 +449,7 @@ for fmt in self.formats: file = self.make_archive(base_name, fmt, base_dir=base_dir) archive_files.append(file) + self.distribution.dist_files.append(('sdist', '', file)) self.archive_files = archive_files Modified: branches/asm/Lib/distutils/file_util.py =================================================================== --- branches/asm/Lib/distutils/file_util.py 2008-07-14 19:25:59 UTC (rev 4932) +++ branches/asm/Lib/distutils/file_util.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -3,9 +3,9 @@ Utility functions for operating on single files. """ -# This module should be kept compatible with Python 1.5.2. +# This module should be kept compatible with Python 2.1. -__revision__ = "$Id: file_util.py 29762 2002-11-19 13:12:28Z akuchling $" +__revision__ = "$Id: file_util.py 37828 2004-11-10 22:23:15Z loewis $" import os from distutils.errors import DistutilsFileError @@ -42,7 +42,7 @@ except os.error, (errno, errstr): raise DistutilsFileError, \ "could not delete '%s': %s" % (dst, errstr) - + try: fdst = open(dst, 'wb') except os.error, (errno, errstr): @@ -170,7 +170,7 @@ # before chmod() (at least under NT). if preserve_times: os.utime(dst, (st[ST_ATIME], st[ST_MTIME])) - if preserve_mode and hasattr(os, 'chmod'): + if preserve_mode: os.chmod(dst, S_IMODE(st[ST_MODE])) return (dst, 1) Modified: branches/asm/Lib/distutils/spawn.py =================================================================== --- branches/asm/Lib/distutils/spawn.py 2008-07-14 19:25:59 UTC (rev 4932) +++ branches/asm/Lib/distutils/spawn.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -6,9 +6,9 @@ executable name. """ -# This module should be kept compatible with Python 1.5.2. +# This module should be kept compatible with Python 2.1. -__revision__ = "$Id: spawn.py 29801 2002-11-21 20:41:07Z akuchling $" +__revision__ = "$Id: spawn.py 37828 2004-11-10 22:23:15Z loewis $" import sys, os, string from distutils.errors import * @@ -39,8 +39,6 @@ _spawn_nt(cmd, search_path, dry_run=dry_run) elif os.name == 'os2': _spawn_os2(cmd, search_path, dry_run=dry_run) - elif os.name == 'java': - _spawn_java(cmd, search_path, dry_run=dry_run) else: raise DistutilsPlatformError, \ "don't know how to spawn programs on platform '%s'" % os.name @@ -99,7 +97,7 @@ #cmd = _nt_quote_args(cmd) if search_path: # either we find one or it stays the same - executable = find_executable(executable) or executable + executable = find_executable(executable) or executable log.info(string.join([executable] + cmd[1:], ' ')) if not dry_run: # spawnv for OS/2 EMX requires a full path to the .exe @@ -146,7 +144,14 @@ # Loop until the child either exits or is terminated by a signal # (ie. keep waiting if it's merely stopped) while 1: - (pid, status) = os.waitpid(pid, 0) + try: + (pid, status) = os.waitpid(pid, 0) + except OSError, exc: + import errno + if exc.errno == errno.EINTR: + continue + raise DistutilsExecError, \ + "command '%s' failed: %s" % (cmd[0], exc[-1]) if os.WIFSIGNALED(status): raise DistutilsExecError, \ "command '%s' terminated by signal %d" % \ @@ -171,27 +176,6 @@ # _spawn_posix () -def _spawn_java(cmd, - search_path=1, - verbose=0, - dry_run=0): - executable = cmd[0] - cmd = ' '.join(_nt_quote_args(cmd)) - log.info(cmd) - if not dry_run: - try: - rc = os.system(cmd) >> 8 - except OSError, exc: - # this seems to happen when the command isn't found - raise DistutilsExecError, \ - "command '%s' failed: %s" % (executable, exc[-1]) - if rc != 0: - # and this reflects the command running but failing - print "command '%s' failed with exit status %d" % (executable, rc) - raise DistutilsExecError, \ - "command '%s' failed with exit status %d" % (executable, rc) - - def find_executable(executable, path=None): """Try to find 'executable' in the directories listed in 'path' (a string listing directories separated by 'os.pathsep'; defaults to Modified: branches/asm/Lib/distutils/sysconfig.py =================================================================== --- branches/asm/Lib/distutils/sysconfig.py 2008-07-14 19:25:59 UTC (rev 4932) +++ branches/asm/Lib/distutils/sysconfig.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -9,14 +9,14 @@ Email: <fd...@ac...> """ -__revision__ = "$Id: sysconfig.py 38269 2005-01-11 13:49:02Z jackjansen $" +__revision__ = "$Id: sysconfig.py 52234 2006-10-08 17:50:26Z ronald.oussoren $" import os import re import string import sys -from errors import DistutilsPlatformError +from distutils.errors import DistutilsPlatformError # These are needed in a couple of spots, so just compute them once. PREFIX = os.path.normpath(sys.prefix) @@ -31,10 +31,10 @@ python_build = os.path.isfile(landmark) -del argv0_path, landmark +del landmark -def get_python_version (): +def get_python_version(): """Return a string containing the major and minor Python version, leaving off the patchlevel. Sample return values could be '1.5' or '2.2'. @@ -65,15 +65,15 @@ if not os.path.exists(inc_dir): inc_dir = os.path.join(os.path.dirname(base), "Include") return inc_dir - return os.path.join(prefix, "include", "python" + sys.version[:3]) + return os.path.join(prefix, "include", "python" + get_python_version()) elif os.name == "nt": return os.path.join(prefix, "include") elif os.name == "mac": if plat_specific: - return os.path.join(prefix, "Mac", "Include") + return os.path.join(prefix, "Mac", "Include") else: - return os.path.join(prefix, "Include") - elif os.name == "os2" or os.name == "java": + return os.path.join(prefix, "Include") + elif os.name == "os2": return os.path.join(prefix, "Include") else: raise DistutilsPlatformError( @@ -110,7 +110,7 @@ if standard_lib: return os.path.join(prefix, "Lib") else: - if sys.version < "2.2": + if get_python_version() < "2.2": return prefix else: return os.path.join(PREFIX, "Lib", "site-packages") @@ -127,7 +127,7 @@ else: return os.path.join(prefix, "Lib", "site-packages") - elif os.name == "os2" or os.name == "java": + elif os.name == "os2": if standard_lib: return os.path.join(PREFIX, "Lib") else: @@ -146,30 +146,31 @@ varies across Unices and is stored in Python's Makefile. """ if compiler.compiler_type == "unix": - (cc, cxx, opt, basecflags, ccshared, ldshared, so_ext) = \ - get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS', 'CCSHARED', 'LDSHARED', 'SO') + (cc, cxx, opt, cflags, ccshared, ldshared, so_ext) = \ + get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', + 'CCSHARED', 'LDSHARED', 'SO') if os.environ.has_key('CC'): cc = os.environ['CC'] if os.environ.has_key('CXX'): cxx = os.environ['CXX'] + if os.environ.has_key('LDSHARED'): + ldshared = os.environ['LDSHARED'] if os.environ.has_key('CPP'): cpp = os.environ['CPP'] else: cpp = cc + " -E" # not always if os.environ.has_key('LDFLAGS'): ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if basecflags: - opt = basecflags + ' ' + opt if os.environ.has_key('CFLAGS'): - opt = opt + ' ' + os.environ['CFLAGS'] + cflags = opt + ' ' + os.environ['CFLAGS'] ldshared = ldshared + ' ' + os.environ['CFLAGS'] if os.environ.has_key('CPPFLAGS'): cpp = cpp + ' ' + os.environ['CPPFLAGS'] - opt = opt + ' ' + os.environ['CPPFLAGS'] + cflags = cflags + ' ' + os.environ['CPPFLAGS'] ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - cc_cmd = cc + ' ' + opt + cc_cmd = cc + ' ' + cflags compiler.set_executables( preprocessor=cpp, compiler=cc_cmd, @@ -184,10 +185,10 @@ def get_config_h_filename(): """Return full pathname of installed pyconfig.h file.""" if python_build: - inc_dir = os.curdir + inc_dir = argv0_path else: inc_dir = get_python_inc(plat_specific=1) - if sys.version < '2.2': + if get_python_version() < '2.2': config_h = 'config.h' else: # The name of the config.h file changed in 2.2 @@ -212,8 +213,8 @@ """ if g is None: g = {} - define_rx = re.compile("#define ([A-Z][A-Z0-9_]+) (.*)\n") - undef_rx = re.compile("/[*] #undef ([A-Z][A-Z0-9_]+) [*]/\n") + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") # while 1: line = fp.readline() @@ -275,25 +276,20 @@ m = _findvar1_rx.search(value) or _findvar2_rx.search(value) if m: n = m.group(1) + found = True if done.has_key(n): - after = value[m.end():] - value = value[:m.start()] + str(done[n]) + after - if "$" in after: - notdone[name] = value - else: - try: value = int(value) - except ValueError: - done[name] = string.strip(value) - else: - done[name] = value - del notdone[name] + item = str(done[n]) elif notdone.has_key(n): # get it on a subsequent round - pass + found = False + elif os.environ.has_key(n): + # do it like make: fall back to environment + item = os.environ[n] else: - done[n] = "" + done[n] = item = "" + if found: after = value[m.end():] - value = value[:m.start()] + after + value = value[:m.start()] + item + after if "$" in after: notdone[name] = value else: @@ -355,28 +351,39 @@ raise DistutilsPlatformError(my_msg) + # load the installed pyconfig.h: + try: + filename = get_config_h_filename() + parse_config_h(file(filename), g) + except IOError, msg: + my_msg = "invalid Python installation: unable to open %s" % filename + if hasattr(msg, "strerror"): + my_msg = my_msg + " (%s)" % msg.strerror + + raise DistutilsPlatformError(my_msg) + # On MacOSX we need to check the setting of the environment variable # MACOSX_DEPLOYMENT_TARGET: configure bases some choices on it so # it needs to be compatible. # If it isn't set we set it to the configure-time value - if sys.platform == 'darwin' and g.has_key('CONFIGURE_MACOSX_DEPLOYMENT_TARGET'): - cfg_target = g['CONFIGURE_MACOSX_DEPLOYMENT_TARGET'] + if sys.platform == 'darwin' and g.has_key('MACOSX_DEPLOYMENT_TARGET'): + cfg_target = g['MACOSX_DEPLOYMENT_TARGET'] cur_target = os.getenv('MACOSX_DEPLOYMENT_TARGET', '') if cur_target == '': cur_target = cfg_target os.putenv('MACOSX_DEPLOYMENT_TARGET', cfg_target) - if cfg_target != cur_target: + elif map(int, cfg_target.split('.')) > map(int, cur_target.split('.')): my_msg = ('$MACOSX_DEPLOYMENT_TARGET mismatch: now "%s" but "%s" during configure' % (cur_target, cfg_target)) raise DistutilsPlatformError(my_msg) - + # On AIX, there are wrong paths to the linker scripts in the Makefile # -- these paths are relative to the Python source, but when installed # the scripts are in another directory. if python_build: g['LDSHARED'] = g['BLDSHARED'] - elif sys.version < '2.1': + elif get_python_version() < '2.1': # The following two branches are for 1.5.2 compatibility. if sys.platform == 'aix4': # what about AIX 3.x ? # Linker script is in the config directory, not in Modules as the @@ -403,7 +410,7 @@ # it's taken care of for them by the 'build_ext.get_libraries()' # method.) g['LDSHARED'] = ("%s -L%s/lib -lpython%s" % - (linkerscript, PREFIX, sys.version[0:3])) + (linkerscript, PREFIX, get_python_version())) global _config_vars _config_vars = g @@ -469,13 +476,6 @@ _config_vars = g -def _init_jython(): - """Initialize the module as appropriate for Jython""" - # Stub out some values that build_ext expects; they don't matter - # anyway - _init_os2() - - def get_config_vars(*args): """With no arguments, return a dictionary of all configuration variables relevant for the current platform. Generally this includes @@ -488,12 +488,7 @@ """ global _config_vars if _config_vars is None: - if sys.platform.startswith('java'): - # Jython might pose as a different os.name, but we always - # want _init_jython regardless - func = _init_jython - else: - func = globals().get("_init_" + os.name) + func = globals().get("_init_" + os.name) if func: func() else: @@ -505,6 +500,25 @@ _config_vars['prefix'] = PREFIX _config_vars['exec_prefix'] = EXEC_PREFIX + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # are in CFLAGS or LDFLAGS and remove them if they are. + # This is needed when building extensions on a 10.3 system + # using a universal build of python. + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _config_vars[key] + flags = re.sub('-arch\s+\w+\s', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) + _config_vars[key] = flags + if args: vals = [] for name in args: Added: branches/asm/Lib/distutils/tests/test_build_py.py =================================================================== --- branches/asm/Lib/distutils/tests/test_build_py.py (rev 0) +++ branches/asm/Lib/distutils/tests/test_build_py.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -0,0 +1,96 @@ +"""Tests for distutils.command.build_py.""" + +import os +import sys +import StringIO +import unittest + +from distutils.command.build_py import build_py +from distutils.core import Distribution +from distutils.errors import DistutilsFileError + +from distutils.tests import support + + +class BuildPyTestCase(support.TempdirManager, + support.LoggingSilencer, + unittest.TestCase): + + def test_package_data(self): + sources = self.mkdtemp() + f = open(os.path.join(sources, "__init__.py"), "w") + f.write("# Pretend this is a package.") + f.close() + f = open(os.path.join(sources, "README.txt"), "w") + f.write("Info about this package") + f.close() + + destination = self.mkdtemp() + + dist = Distribution({"packages": ["pkg"], + "package_dir": {"pkg": sources}}) + # script_name need not exist, it just need to be initialized + dist.script_name = os.path.join(sources, "setup.py") + dist.command_obj["build"] = support.DummyCommand( + force=0, + build_lib=destination) + dist.packages = ["pkg"] + dist.package_data = {"pkg": ["README.txt"]} + dist.package_dir = {"pkg": sources} + + cmd = build_py(dist) + cmd.compile = 1 + cmd.ensure_finalized() + self.assertEqual(cmd.package_data, dist.package_data) + + cmd.run() + + # This makes sure the list of outputs includes byte-compiled + # files for Python modules but not for package data files + # (there shouldn't *be* byte-code files for those!). + # + self.assertEqual(len(cmd.get_outputs()), 3) + pkgdest = os.path.join(destination, "pkg") + files = os.listdir(pkgdest) + self.assert_("__init__.py" in files) + self.assert_("__init__.pyc" in files) + self.assert_("README.txt" in files) + + def test_empty_package_dir (self): + # See SF 1668596/1720897. + cwd = os.getcwd() + + # create the distribution files. + sources = self.mkdtemp() + open(os.path.join(sources, "__init__.py"), "w").close() + + testdir = os.path.join(sources, "doc") + os.mkdir(testdir) + open(os.path.join(testdir, "testfile"), "w").close() + + os.chdir(sources) + sys.stdout = StringIO.StringIO() + + try: + dist = Distribution({"packages": ["pkg"], + "package_dir": {"pkg": ""}, + "package_data": {"pkg": ["doc/*"]}}) + # script_name need not exist, it just need to be initialized + dist.script_name = os.path.join(sources, "setup.py") + dist.script_args = ["build"] + dist.parse_command_line() + + try: + dist.run_commands() + except DistutilsFileError: + self.fail("failed package_data test when package_dir is ''") + finally: + # Restore state. + os.chdir(cwd) + sys.stdout = sys.__stdout__ + +def test_suite(): + return unittest.makeSuite(BuildPyTestCase) + +if __name__ == "__main__": + unittest.main(defaultTest="test_suite") Modified: branches/asm/Lib/distutils/util.py =================================================================== --- branches/asm/Lib/distutils/util.py 2008-07-14 19:25:59 UTC (rev 4932) +++ branches/asm/Lib/distutils/util.py 2008-07-14 19:26:58 UTC (rev 4933) @@ -4,7 +4,7 @@ one of the other *util.py modules. """ -__revision__ = "$Id: util.py 30621 2003-01-06 13:28:12Z akuchling $" +__revision__ = "$Id: util.py 59116 2007-11-22 10:14:26Z ronald.oussoren $" import sys, os, string, re from distutils.errors import DistutilsPlatformError @@ -45,6 +45,7 @@ osname = string.lower(osname) osname = string.replace(osname, '/', '') machine = string.replace(machine, ' ', '_') + machine = string.replace(machine, '/', '-') if osname[:5] == "linux": # At least on Linux/Intel, 'machine' is the processor -- @@ -66,7 +67,55 @@ m = rel_re.match(release) if m: release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + from distutils.sysconfig import get_config_vars + cfgvars = get_config_vars() + macver = os.environ.get('MACOSX_DEPLOYMENT_TARGET') + if not macver: + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if not macver: + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + m = re.search( + r'<key>ProductUserVisibleVersion</key>\s*' + + r'<string>(.*?)</string>', f.read()) + f.close() + if m is not None: + macver = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + + if macver: + from distutils.sysconfig import get_config_vars + release = macver + osname = "macosx" + + + if (release + '.') >= '10.4.' and \ + get_config_vars().get('UNIVERSALSDK', '').strip(): + # The universal build will build fat binaries, but not on + # systems before 10.4 + machine = 'fat' + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + machine = 'ppc' + return "%s-%s-%s" % (osname, release, machine) # get_platform () @@ -106,7 +155,7 @@ Otherwise, it requires making 'pathname' relative and then joining the two, which is tricky on DOS/Windows and Mac OS. """ - if os.name == 'posix' or os.name == 'java': + if os.name == 'posix': if not os.path.isabs(pathname): return os.path.join(new_root, pathname) else: @@ -209,9 +258,12 @@ # Needed by 'split_quoted()' -_wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace) -_squote_re = re.compile(r"'(?:[^'\\]|\\.)*'") -_dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"') +_wordchars_re = _squote_re = _dquote_re = None +def _init_regex(): + global _wordchars_re, _squote_re, _dquote_re + _wordchars_re = re.compile(r'[^\\\'\"%s ]*' % string.whitespace) + _squote_re = re.compile(r"'(?:[^'\\]|\\.)*'") + _dquote_re = re.compile(r'"(?:[^"\\]|\\.)*"') def split_quoted (s): """Split a string up according to Unix shell-like rules for quotes and @@ -227,6 +279,7 @@ # This is a nice algorithm for splitting up a single string, since it # doesn't require character-by-character examination. It was a little # bit of a brain-bender to get it working right, though... + if _wordchars_re is None: _init_regex() s = string.strip(s) words = [] @@ -285,7 +338,7 @@ print. """ if msg is None: - msg = "%s%s" % (func.__name__, `args`) + msg = "%s%r" % (func.__name__, args) if msg[-2:] == ',)': # correct for singleton tuple msg = msg[0:-2] + ')' @@ -296,7 +349,7 @@ def strtobool (val): """Convert a string representation of truth to true (1) or false (0). - + True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values are 'n', 'no', 'f', 'false', 'off', and '0'. Raises ValueError if 'val' is anything else. @@ -307,7 +360,7 @@ elif val in ('n', 'no', 'f', 'false', 'off', '0'): return 0 else: - raise ValueError, "invalid truth value %s" % `val` + raise ValueError, "invalid truth value %r" % (val,) def byte_compile (py_files, @@ -394,11 +447,11 @@ script.write(string.join(map(repr, py_files), ",\n") + "]\n") script.write(""" -byte_compile(files, optimize=%s, force=%s, - prefix=%s, base_dir=%s, - verbose=%s, dry_run=0, +byte_compile(files, optimize=%r, force=%r, + prefix=%r, base_dir=%r, + verbose=%r, dry_run=0, direct=1) -""" % (`optimize`, `force`, `prefix`, `base_dir`, `verbose`)) +""" % (optimize, force, prefix, base_dir, verbose)) script.close() @@ -427,16 +480,13 @@ # Terminology from the py_compile module: # cfile - byte-compiled file # dfile - purported source filename (same as 'file' by default) - if sys.platform.startswith('java'): - cfile = file[:-3] + '$py.class' - else: - cfile = file + (__debug__ and "c" or "o") + cfile = file + (__debug__ and "c" or "o") dfile = file if prefix: if file[:len(prefix)] != prefix: raise ValueError, \ - ("invalid prefix: filename %s doesn't start with %s" - % (`file`, `prefix`)) + ("invalid prefix: filename %r doesn't start with %r" + % (file, prefix)) dfile = dfile[len(prefix):] if base_dir: dfile = os.path.join(base_dir, dfile) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-07-14 19:26:04
|
Revision: 4932 http://jython.svn.sourceforge.net/jython/?rev=4932&view=rev Author: fwierzbicki Date: 2008-07-14 12:25:59 -0700 (Mon, 14 Jul 2008) Log Message: ----------- unbreak --memo again :) Modified Paths: -------------- branches/asm/Lib/test/regrtest.py Modified: branches/asm/Lib/test/regrtest.py =================================================================== --- branches/asm/Lib/test/regrtest.py 2008-07-14 19:25:31 UTC (rev 4931) +++ branches/asm/Lib/test/regrtest.py 2008-07-14 19:25:59 UTC (rev 4932) @@ -209,7 +209,7 @@ test_support.record_original_stdout(sys.stdout) try: - opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsrf:lu:t:TD:NLR:wM:emj:', + opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsrf:lu:t:TD:NLR:wM:em:j:', ['help', 'verbose', 'quiet', 'generate', 'exclude', 'single', 'random', 'fromfile', 'findleaks', 'use=', 'threshold=', 'trace', This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-14 19:25:34
|
Revision: 4931 http://jython.svn.sourceforge.net/jython/?rev=4931&view=rev Author: pjenvey Date: 2008-07-14 12:25:31 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Merged revisions 4900-4930 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4915 | pjenvey | 2008-07-12 19:59:32 -0700 (Sat, 12 Jul 2008) | 1 line use bin instead of Scripts ........ Modified Paths: -------------- branches/asm/Lib/distutils/command/install.py Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4899 + /trunk/jython:1-4930 Modified: branches/asm/Lib/distutils/command/install.py =================================================================== --- branches/asm/Lib/distutils/command/install.py 2008-07-14 19:24:49 UTC (rev 4930) +++ branches/asm/Lib/distutils/command/install.py 2008-07-14 19:25:31 UTC (rev 4931) @@ -70,7 +70,7 @@ 'purelib': '$base/Lib/site-packages', 'platlib': '$base/Lib/site-packages', 'headers': '$base/Include/$dist_name', - 'scripts': '$base/Scripts', + 'scripts': '$base/bin', 'data' : '$base', } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-07-14 19:24:57
|
Revision: 4930 http://jython.svn.sourceforge.net/jython/?rev=4930&view=rev Author: pjenvey Date: 2008-07-14 12:24:49 -0700 (Mon, 14 Jul 2008) Log Message: ----------- couple small array fixes Modified Paths: -------------- branches/asm/src/org/python/core/PyArray.java Modified: branches/asm/src/org/python/core/PyArray.java =================================================================== --- branches/asm/src/org/python/core/PyArray.java 2008-07-14 17:41:33 UTC (rev 4929) +++ branches/asm/src/org/python/core/PyArray.java 2008-07-14 19:24:49 UTC (rev 4930) @@ -91,13 +91,16 @@ if (obj instanceof PyString) { String code = obj.toString(); if (code.length() != 1) { - throw Py.ValueError("array() argument 1 must be char, not str"); + throw Py.TypeError("array() argument 1 must be char, not str"); } type = char2class(code.charAt(0)); typecode = code; } else if (obj instanceof PyJavaClass) { type = ((PyJavaClass)obj).proxyClass; typecode = type.getName(); + } else { + throw Py.TypeError("array() argument 1 must be char, not " + + obj.getType().fastGetName()); } data = Array.newInstance(type, 0); delegate = new ArrayDelegate(); @@ -227,6 +230,10 @@ seq___delslice__(start, stop, step); } + public PyObject __add__(PyObject other) { + return array___add__(other); + } + /** * Adds (appends) two PyArrays together * @@ -234,7 +241,8 @@ * a PyArray to be added to the instance * @return the result of the addition as a new PyArray instance */ - public PyObject __add__(PyObject other) { + @ExposedMethod + final PyObject array___add__(PyObject other) { PyArray otherArr = null; if(!(other instanceof PyArray)) { throw Py.TypeError("can only append another array to an array"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2008-07-14 17:41:42
|
Revision: 4929 http://jython.svn.sourceforge.net/jython/?rev=4929&view=rev Author: thobes Date: 2008-07-14 10:41:33 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Verifying that svnmerge works on the advanced branch now. Merged revisions 4928 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/branches/asm ........ r4928 | zyasoft | 2008-07-14 17:19:01 +0200 (Mon, 14 Jul 2008) | 3 lines ReferenceQueue objs, by their nature, only make sense if transient. So make them so, this enables interoperation with Terracotta. ........ Modified Paths: -------------- branches/advanced/src/org/python/core/AutoInternalTables.java branches/advanced/src/org/python/core/IdImpl.java Property Changed: ---------------- branches/advanced/ Property changes on: branches/advanced ___________________________________________________________________ Name: svnmerge-integrated - /branches/asm:1-4926 + /branches/asm:1-4928 Modified: branches/advanced/src/org/python/core/AutoInternalTables.java =================================================================== --- branches/advanced/src/org/python/core/AutoInternalTables.java 2008-07-14 15:19:01 UTC (rev 4928) +++ branches/advanced/src/org/python/core/AutoInternalTables.java 2008-07-14 17:41:33 UTC (rev 4929) @@ -8,7 +8,7 @@ public abstract class AutoInternalTables extends InternalTables { - protected ReferenceQueue queue = new ReferenceQueue(); + protected transient ReferenceQueue queue = new ReferenceQueue(); protected abstract Reference newAutoRef(short type, Object key, Object obj); Modified: branches/advanced/src/org/python/core/IdImpl.java =================================================================== --- branches/advanced/src/org/python/core/IdImpl.java 2008-07-14 15:19:01 UTC (rev 4928) +++ branches/advanced/src/org/python/core/IdImpl.java 2008-07-14 17:41:33 UTC (rev 4929) @@ -8,7 +8,7 @@ public static class WeakIdentityMap { - private ReferenceQueue refqueue = new ReferenceQueue(); + private transient ReferenceQueue refqueue = new ReferenceQueue(); private HashMap hashmap = new HashMap(); private void cleanup() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-14 15:19:03
|
Revision: 4928 http://jython.svn.sourceforge.net/jython/?rev=4928&view=rev Author: zyasoft Date: 2008-07-14 08:19:01 -0700 (Mon, 14 Jul 2008) Log Message: ----------- ReferenceQueue objs, by their nature, only make sense if transient. So make them so, this enables interoperation with Terracotta. Modified Paths: -------------- branches/asm/src/org/python/core/AutoInternalTables.java branches/asm/src/org/python/core/IdImpl.java Modified: branches/asm/src/org/python/core/AutoInternalTables.java =================================================================== --- branches/asm/src/org/python/core/AutoInternalTables.java 2008-07-14 13:32:52 UTC (rev 4927) +++ branches/asm/src/org/python/core/AutoInternalTables.java 2008-07-14 15:19:01 UTC (rev 4928) @@ -8,7 +8,7 @@ public abstract class AutoInternalTables extends InternalTables { - protected ReferenceQueue queue = new ReferenceQueue(); + protected transient ReferenceQueue queue = new ReferenceQueue(); protected abstract Reference newAutoRef(short type, Object key, Object obj); Modified: branches/asm/src/org/python/core/IdImpl.java =================================================================== --- branches/asm/src/org/python/core/IdImpl.java 2008-07-14 13:32:52 UTC (rev 4927) +++ branches/asm/src/org/python/core/IdImpl.java 2008-07-14 15:19:01 UTC (rev 4928) @@ -8,7 +8,7 @@ public static class WeakIdentityMap { - private ReferenceQueue refqueue = new ReferenceQueue(); + private transient ReferenceQueue refqueue = new ReferenceQueue(); private HashMap hashmap = new HashMap(); private void cleanup() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2008-07-14 13:32:54
|
Revision: 4927 http://jython.svn.sourceforge.net/jython/?rev=4927&view=rev Author: thobes Date: 2008-07-14 06:32:52 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Initialized merge tracking via "svnmerge" with revisions "1-4926" from https://jython.svn.sourceforge.net/svnroot/jython/branches/asm I believe that svnmerge will work on the advanced branch from now on. As I learn more about svnmerge it migh have been possible to get the merging to work before, if I had specified the revision from where the branching occured manually, that could have saved us revision 4923, but as stated in my last commit message the manual merge process was fairly simple. I have configured it to only be able to pull in changes from the asm branch, so if changes are made on trunk, these need to go through the asm branch before going into the advanced branch. I think this is ok, since 1. the asm branch is where things are happening, 2. the advanced branch is not about keeping up to date with the 2.5 development of Jython, but to explore advanced compiling strategies in Jython, it is however important to not lose compatibility with Jython 2.5, which is why it makes sense to keep up to date with at least the asm branch, and 3. if/when the asm branch is merged back onto trunk it is very possible to redirect the advanced branch to merge from there instead, this should be particularly easy if the advanced branch is kept up to date with the asm branch. Revision Links: -------------- http://jython.svn.sourceforge.net/jython/?rev=4923&view=rev Property Changed: ---------------- branches/advanced/ Property changes on: branches/advanced ___________________________________________________________________ Name: svnmerge-integrated + /branches/asm:1-4926 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2008-07-14 13:03:23
|
Revision: 4926 http://jython.svn.sourceforge.net/jython/?rev=4926&view=rev Author: thobes Date: 2008-07-14 06:03:20 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Manually merging changes from the asm-branch onto the advanced compiler branch. The reason for doing it manually is because I am so hard core... No, just kidding, it's because svnmerge.py doesn't work that well when one branch is a branch from another branch. Luckily the changes were not that hard. The advanced branch has the same test status as the asm branch. While comparing the regtest results I found a previously undiscovered bug, In org.python.core.PyFunction#setFuncCode the first check doesn't check to see if the passed in argument is null, it checks to see if the code object already in there is null, which is silly. The reason this worked before is that the instanceof test that was removed in the advanced branch guarantees that the object is not null. Modified Paths: -------------- branches/advanced/CPythonLib.includes branches/advanced/Lib/datetime.py branches/advanced/Lib/gzip.py branches/advanced/Lib/popen2.py branches/advanced/Lib/test/regrtest.py branches/advanced/Lib/test/string_tests.py branches/advanced/Lib/test/test_cpickle.py branches/advanced/Lib/test/test_enumerate.py branches/advanced/Lib/test/test_float_jy.py branches/advanced/Lib/test/test_format_jy.py branches/advanced/Lib/test/test_iter.py branches/advanced/Lib/test/test_jy_compile.py branches/advanced/Lib/test/test_largefile.py branches/advanced/Lib/test/test_mhlib.py branches/advanced/Lib/test/test_repr.py branches/advanced/Lib/test/test_richcmp.py branches/advanced/Lib/test/test_scope.py branches/advanced/Lib/test/test_time.py branches/advanced/Lib/test/test_types.py branches/advanced/Lib/test/test_zlib.py branches/advanced/Lib/threading.py branches/advanced/Lib/zlib.py branches/advanced/build.xml branches/advanced/grammar/Python.g branches/advanced/grammar/PythonPartial.g branches/advanced/src/com/ziclix/python/sql/zxJDBC.java branches/advanced/src/org/python/antlr/PythonPartialTokenSource.java branches/advanced/src/org/python/antlr/PythonTokenSource.java branches/advanced/src/org/python/compiler/CodeCompiler.java branches/advanced/src/org/python/core/Options.java branches/advanced/src/org/python/core/Py.java branches/advanced/src/org/python/core/PyCallIter.java branches/advanced/src/org/python/core/PyEnumerate.java branches/advanced/src/org/python/core/PyException.java branches/advanced/src/org/python/core/PyFile.java branches/advanced/src/org/python/core/PyFunction.java branches/advanced/src/org/python/core/PyIterator.java branches/advanced/src/org/python/core/PySequenceIter.java branches/advanced/src/org/python/core/PyString.java branches/advanced/src/org/python/core/PyUnicode.java branches/advanced/src/org/python/core/ThreadStateMapping.java branches/advanced/src/org/python/core/__builtin__.java branches/advanced/src/org/python/core/codecs.java branches/advanced/src/org/python/core/imp.java branches/advanced/src/org/python/modules/imp.java branches/advanced/src/org/python/modules/time/PyTimeTuple.java branches/advanced/src/org/python/modules/time/Time.java branches/advanced/src/templates/mappings branches/advanced/tests/shell/test-jython.sh Added Paths: ----------- branches/advanced/Lib/_rawffi.py branches/advanced/Lib/platform.py branches/advanced/Lib/test/junit_xml.py branches/advanced/Lib/test/test__rawffi.py branches/advanced/Lib/test/test_cmath_jy.py branches/advanced/Lib/test/test_complex_jy.py branches/advanced/Lib/test/test_str.py branches/advanced/Lib/test/test_support.py branches/advanced/Lib/uu.py branches/advanced/extlibs/svnant-jars/ branches/advanced/extlibs/svnant-jars/svnClientAdapter.jar branches/advanced/extlibs/svnant-jars/svnant.jar branches/advanced/extlibs/svnant-jars/svnjavahl.jar branches/advanced/src/org/python/core/PyEnumerateDerived.java branches/advanced/src/templates/enumerate.derived branches/advanced/tests/c/ branches/advanced/tests/c/ctypes_test.c Removed Paths: ------------- branches/advanced/Lib/test/output/test_operations branches/advanced/Lib/test/output/test_types branches/advanced/Lib/test/test_complex.py branches/advanced/Lib/test/test_datetime.py branches/advanced/Lib/test/test_long.py branches/advanced/Lib/test/test_operations.py branches/advanced/extlibs/svnant-jars/svnClientAdapter.jar branches/advanced/extlibs/svnant-jars/svnant.jar branches/advanced/extlibs/svnant-jars/svnjavahl.jar branches/advanced/tests/c/ctypes_test.c Property Changed: ---------------- branches/advanced/ Property changes on: branches/advanced ___________________________________________________________________ Name: svnmerge-integrated - /branches/asm:1-4922 /trunk/jython:1-4738 Modified: branches/advanced/CPythonLib.includes =================================================================== --- branches/advanced/CPythonLib.includes 2008-07-14 12:19:10 UTC (rev 4925) +++ branches/advanced/CPythonLib.includes 2008-07-14 13:03:20 UTC (rev 4926) @@ -13,6 +13,8 @@ __future__.py _LWPCookieJar.py _MozillaCookieJar.py +_strptime.py +_threading_local.py aifc.py anydbm.py atexit.py Copied: branches/advanced/Lib/_rawffi.py (from rev 4923, branches/asm/Lib/_rawffi.py) =================================================================== --- branches/advanced/Lib/_rawffi.py (rev 0) +++ branches/advanced/Lib/_rawffi.py 2008-07-14 13:03:20 UTC (rev 4926) @@ -0,0 +1,57 @@ +import com.sun.jna as jna + +def get_libc(): + return CDLL("c") + +typecode_map = {'h': 2, 'H': 2} + +class Array(object): + def __init__(self, typecode): + self.typecode = typecode + self.itemsize = typecode_map[typecode] + + def __call__(self, size, autofree=False): + if not autofree: + raise Exception + return ArrayInstance(self, size) + +class ArrayInstance(object): + def __init__(self, shape, size): + self.shape = shape + self.alloc = jna.Memory(shape.itemsize * size) + + def __setitem__(self, index, value): + self.alloc.setShort(index, value) + + def __getitem__(self, index): + return self.alloc.getShort(index) + +class FuncPtr(object): + def __init__(self, fn, name, argtypes, restype): + self.fn = fn + self.name = name + self.argtypes = argtypes + self.restype = restype + + def __call__(self, *args): + container = Array('H')(1, autofree=True) + container[0] = self.fn.invokeInt([i[0] for i in args]) + return container + +class CDLL(object): + def __init__(self, libname): + self.lib = jna.NativeLibrary.getInstance(libname) + self.cache = dict() + + def ptr(self, name, argtypes, restype): + key = (name, tuple(argtypes), restype) + try: + return self.cache[key] + except KeyError: + fn = self.lib.getFunction(name) + fnp = FuncPtr(fn, name, argtypes, restype) + self.cache[key] = fnp + return fnp + + + Modified: branches/advanced/Lib/datetime.py =================================================================== --- branches/advanced/Lib/datetime.py 2008-07-14 12:19:10 UTC (rev 4925) +++ branches/advanced/Lib/datetime.py 2008-07-14 13:03:20 UTC (rev 4926) @@ -12,6 +12,8 @@ Sources for time zone and DST data: http://www.twinsun.com/tz/tz-link.htm +This was originally copied from the sandbox of the CPython CVS repository. +Thanks to Tim Peters for suggesting using it. """ import time as _time @@ -575,9 +577,11 @@ def __add__(self, other): if isinstance(other, timedelta): - return self.__class__(self.__days + other.__days, - self.__seconds + other.__seconds, - self.__microseconds + other.__microseconds) + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self.__days + other.__days, + self.__seconds + other.__seconds, + self.__microseconds + other.__microseconds) return NotImplemented __radd__ = __add__ @@ -593,9 +597,11 @@ return NotImplemented def __neg__(self): - return self.__class__(-self.__days, - -self.__seconds, - -self.__microseconds) + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(-self.__days, + -self.__seconds, + -self.__microseconds) def __pos__(self): return self @@ -608,9 +614,11 @@ def __mul__(self, other): if isinstance(other, (int, long)): - return self.__class__(self.__days * other, - self.__seconds * other, - self.__microseconds * other) + # for CPython compatibility, we cannot use + # our __class__ here, but need a real timedelta + return timedelta(self.__days * other, + self.__seconds * other, + self.__microseconds * other) return NotImplemented __rmul__ = __mul__ @@ -619,7 +627,7 @@ if isinstance(other, (int, long)): usec = ((self.__days * (24*3600L) + self.__seconds) * 1000000 + self.__microseconds) - return self.__class__(0, 0, usec // other) + return timedelta(0, 0, usec // other) return NotImplemented __floordiv__ = __div__ @@ -728,7 +736,7 @@ if isinstance(year, str): # Pickle support self = object.__new__(cls) - self.__setstate((year,)) + self.__setstate(year) return self _check_date_fields(year, month, day) self = object.__new__(cls) @@ -901,9 +909,10 @@ self.__month, self.__day + other.days) self._checkOverflow(t.year) - result = self.__class__(t.year, t.month, t.day) + result = date(t.year, t.month, t.day) return result - return NotImplemented + raise TypeError + # XXX Should be 'return NotImplemented', but there's a bug in 2.2... __radd__ = __add__ @@ -963,10 +972,9 @@ yhi, ylo = divmod(self.__year, 256) return ("%c%c%c%c" % (yhi, ylo, self.__month, self.__day), ) - def __setstate(self, t): - assert isinstance(t, tuple) and len(t) == 1, `t` - string = t[0] - assert len(string) == 4 + def __setstate(self, string): + if len(string) != 4 or not (1 <= ord(string[2]) <= 12): + raise TypeError("not enough arguments") yhi, ylo, self.__month, self.__day = map(ord, string) self.__year = yhi * 256 + ylo @@ -1089,7 +1097,7 @@ self = object.__new__(cls) if isinstance(hour, str): # Pickle support - self.__setstate((hour, minute or None)) + self.__setstate(hour, minute or None) return self _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) @@ -1327,21 +1335,16 @@ else: return (basestate, self._tzinfo) - def __setstate(self, state): - assert isinstance(state, tuple) - assert 1 <= len(state) <= 2 - string = state[0] - assert len(string) == 6 + def __setstate(self, string, tzinfo): + if len(string) != 6 or ord(string[0]) >= 24: + raise TypeError("an integer is required") self.__hour, self.__minute, self.__second, us1, us2, us3 = \ map(ord, string) self.__microsecond = (((us1 << 8) | us2) << 8) | us3 - if len(state) == 1: - self._tzinfo = None - else: - self._tzinfo = state[1] + self._tzinfo = tzinfo def __reduce__(self): - return (self.__class__, self.__getstate()) + return (time, self.__getstate()) _time_class = time # so functions w/ args named "time" can get at the class @@ -1359,7 +1362,7 @@ if isinstance(year, str): # Pickle support self = date.__new__(cls, year[:4]) - self.__setstate((year, month)) + self.__setstate(year, month) return self _check_tzinfo_arg(tzinfo) _check_time_fields(hour, minute, second, microsecond) @@ -1396,8 +1399,17 @@ converter = _time.gmtime y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) us = int((t % 1.0) * 1000000) + + if us == 1000001 or us == 999999: + us = 0 + rounded = True + else: + rounded = False + ss = min(ss, 59) # clamp out leap seconds if the platform has them result = cls(y, m, d, hh, mm, ss, us, tz) + if rounded: + result += timedelta(seconds=1) if tz is not None: result = tz.fromutc(result) return result @@ -1439,6 +1451,15 @@ time.tzinfo) combine = classmethod(combine) + def strptime(cls, date_string, format): + """datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]]) + + The year, month and day arguments are required. tzinfo may be None, or an + instance of a tzinfo subclass. The remaining arguments may be ints or longs.""" + return cls(*(_time.strptime(date_string, format))[0:6]) + + strptime = classmethod(strptime) + def timetuple(self): "Return local time tuple compatible with time.localtime()." dst = self._dst() @@ -1561,7 +1582,7 @@ if L[-1] == 0: del L[-1] if L[-1] == 0: - del L[-1] + del L[-1] s = ", ".join(map(str, L)) s = "%s(%s)" % ('datetime.' + self.__class__.__name__, s) if self._tzinfo is not None: @@ -1625,7 +1646,7 @@ def __eq__(self, other): if isinstance(other, datetime): return self.__cmp(other) == 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: return False @@ -1633,7 +1654,7 @@ def __ne__(self, other): if isinstance(other, datetime): return self.__cmp(other) != 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: return True @@ -1641,7 +1662,7 @@ def __le__(self, other): if isinstance(other, datetime): return self.__cmp(other) <= 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1649,7 +1670,7 @@ def __lt__(self, other): if isinstance(other, datetime): return self.__cmp(other) < 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1657,7 +1678,7 @@ def __ge__(self, other): if isinstance(other, datetime): return self.__cmp(other) >= 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1665,7 +1686,7 @@ def __gt__(self, other): if isinstance(other, datetime): return self.__cmp(other) > 0 - elif hasattr(other, "timetuple"): + elif hasattr(other, "timetuple") and not isinstance(other, date): return NotImplemented else: _cmperror(self, other) @@ -1713,7 +1734,7 @@ self.__second + other.seconds, self.__microsecond + other.microseconds) self._checkOverflow(t.year) - result = self.__class__(t.year, t.month, t.day, + result = datetime(t.year, t.month, t.day, t.hour, t.minute, t.second, t.microsecond, tzinfo=self._tzinfo) return result @@ -1768,19 +1789,12 @@ else: return (basestate, self._tzinfo) - def __setstate(self, state): - assert isinstance(state, tuple) - assert 1 <= len(state) <= 2 - string = state[0] - assert len(string) == 10 + def __setstate(self, string, tzinfo): (yhi, ylo, self.__month, self.__day, self.__hour, self.__minute, self.__second, us1, us2, us3) = map(ord, string) self.__year = yhi * 256 + ylo self.__microsecond = (((us1 << 8) | us2) << 8) | us3 - if len(state) == 1: - self._tzinfo = None - else: - self._tzinfo = state[1] + self._tzinfo = tzinfo def __reduce__(self): return (self.__class__, self.__getstate()) @@ -2000,9 +2014,3 @@ pretty bizarre, and a tzinfo subclass can override fromutc() if it is. """ -def _test(): - import test_datetime - test_datetime.test_main() - -if __name__ == "__main__": - _test() Modified: branches/advanced/Lib/gzip.py =================================================================== --- branches/advanced/Lib/gzip.py 2008-07-14 12:19:10 UTC (rev 4925) +++ branches/advanced/Lib/gzip.py 2008-07-14 13:03:20 UTC (rev 4926) @@ -55,7 +55,11 @@ """ myfileobj = None - max_read_chunk = 10 * 1024 * 1024 # 10Mb + # XXX: repeated 10mb chunk reads hurt test_gzip.test_many_append's + # performance on Jython (maybe CPython's allocator recycles the same + # 10mb buffer whereas Java's doesn't) + #max_read_chunk = 10 * 1024 * 1024 # 10Mb + max_read_chunk = 256 * 1024 # 256kb def __init__(self, filename=None, mode=None, compresslevel=9, fileobj=None): Copied: branches/advanced/Lib/platform.py (from rev 4923, branches/asm/Lib/platform.py) =================================================================== --- branches/advanced/Lib/platform.py (rev 0) +++ branches/advanced/Lib/platform.py 2008-07-14 13:03:20 UTC (rev 4926) @@ -0,0 +1,1270 @@ +#!/usr/bin/env python + +""" This module tries to retrieve as much platform-identifying data as + possible. It makes this information available via function APIs. + + If called from the command line, it prints the platform + information concatenated as single string to stdout. The output + format is useable as part of a filename. + +""" +# This module is maintained by Marc-Andre Lemburg <ma...@eg...>. +# If you find problems, please submit bug reports/patches via the +# Python SourceForge Project Page and assign them to "lemburg". +# +# Note: Please keep this module compatible to Python 1.5.2. +# +# Still needed: +# * more support for WinCE +# * support for MS-DOS (PythonDX ?) +# * support for Amiga and other still unsupported platforms running Python +# * support for additional Linux distributions +# +# Many thanks to all those who helped adding platform-specific +# checks (in no particular order): +# +# Charles G Waldman, David Arnold, Gordon McMillan, Ben Darnell, +# Jeff Bauer, Cliff Crawford, Ivan Van Laningham, Josef +# Betancourt, Randall Hopper, Karl Putland, John Farrell, Greg +# Andruk, Just van Rossum, Thomas Heller, Mark R. Levinson, Mark +# Hammond, Bill Tutt, Hans Nowak, Uwe Zessin (OpenVMS support), +# Colin Kong, Trent Mick, Guido van Rossum +# +# History: +# +# <see CVS and SVN checkin messages for history> +# +# 1.0.3 - added normalization of Windows system name +# 1.0.2 - added more Windows support +# 1.0.1 - reformatted to make doc.py happy +# 1.0.0 - reformatted a bit and checked into Python CVS +# 0.8.0 - added sys.version parser and various new access +# APIs (python_version(), python_compiler(), etc.) +# 0.7.2 - fixed architecture() to use sizeof(pointer) where available +# 0.7.1 - added support for Caldera OpenLinux +# 0.7.0 - some fixes for WinCE; untabified the source file +# 0.6.2 - support for OpenVMS - requires version 1.5.2-V006 or higher and +# vms_lib.getsyi() configured +# 0.6.1 - added code to prevent 'uname -p' on platforms which are +# known not to support it +# 0.6.0 - fixed win32_ver() to hopefully work on Win95,98,NT and Win2k; +# did some cleanup of the interfaces - some APIs have changed +# 0.5.5 - fixed another type in the MacOS code... should have +# used more coffee today ;-) +# 0.5.4 - fixed a few typos in the MacOS code +# 0.5.3 - added experimental MacOS support; added better popen() +# workarounds in _syscmd_ver() -- still not 100% elegant +# though +# 0.5.2 - fixed uname() to return '' instead of 'unknown' in all +# return values (the system uname command tends to return +# 'unknown' instead of just leaving the field emtpy) +# 0.5.1 - included code for slackware dist; added exception handlers +# to cover up situations where platforms don't have os.popen +# (e.g. Mac) or fail on socket.gethostname(); fixed libc +# detection RE +# 0.5.0 - changed the API names referring to system commands to *syscmd*; +# added java_ver(); made syscmd_ver() a private +# API (was system_ver() in previous versions) -- use uname() +# instead; extended the win32_ver() to also return processor +# type information +# 0.4.0 - added win32_ver() and modified the platform() output for WinXX +# 0.3.4 - fixed a bug in _follow_symlinks() +# 0.3.3 - fixed popen() and "file" command invokation bugs +# 0.3.2 - added architecture() API and support for it in platform() +# 0.3.1 - fixed syscmd_ver() RE to support Windows NT +# 0.3.0 - added system alias support +# 0.2.3 - removed 'wince' again... oh well. +# 0.2.2 - added 'wince' to syscmd_ver() supported platforms +# 0.2.1 - added cache logic and changed the platform string format +# 0.2.0 - changed the API to use functions instead of module globals +# since some action take too long to be run on module import +# 0.1.0 - first release +# +# You can always get the latest version of this module at: +# +# http://www.egenix.com/files/python/platform.py +# +# If that URL should fail, try contacting the author. + +__copyright__ = """ + Copyright (c) 1999-2000, Marc-Andre Lemburg; mailto:ma...@le... + Copyright (c) 2000-2003, eGenix.com Software GmbH; mailto:in...@eg... + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee or royalty is hereby granted, + provided that the above copyright notice appear in all copies and that + both that copyright notice and this permission notice appear in + supporting documentation or portions thereof, including modifications, + that you make. + + EGENIX.COM SOFTWARE GMBH DISCLAIMS ALL WARRANTIES WITH REGARD TO + THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS, IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, + INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + WITH THE USE OR PERFORMANCE OF THIS SOFTWARE ! + +""" + +__version__ = '1.0.4' + +import sys,string,os,re + +### Platform specific APIs + +_libc_search = re.compile(r'(__libc_init)' + '|' + '(GLIBC_([0-9.]+))' + '|' + '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)') + +def libc_ver(executable=sys.executable,lib='',version='', + + chunksize=2048): + + """ Tries to determine the libc version that the file executable + (which defaults to the Python interpreter) is linked against. + + Returns a tuple of strings (lib,version) which default to the + given parameters in case the lookup fails. + + Note that the function has intimate knowledge of how different + libc versions add symbols to the executable and thus is probably + only useable for executables compiled using gcc. + + The file is read and scanned in chunks of chunksize bytes. + + """ + f = open(executable,'rb') + binary = f.read(chunksize) + pos = 0 + while 1: + m = _libc_search.search(binary,pos) + if not m: + binary = f.read(chunksize) + if not binary: + break + pos = 0 + continue + libcinit,glibc,glibcversion,so,threads,soversion = m.groups() + if libcinit and not lib: + lib = 'libc' + elif glibc: + if lib != 'glibc': + lib = 'glibc' + version = glibcversion + elif glibcversion > version: + version = glibcversion + elif so: + if lib != 'glibc': + lib = 'libc' + if soversion > version: + version = soversion + if threads and version[-len(threads):] != threads: + version = version + threads + pos = m.end() + f.close() + return lib,version + +def _dist_try_harder(distname,version,id): + + """ Tries some special tricks to get the distribution + information in case the default method fails. + + Currently supports older SuSE Linux, Caldera OpenLinux and + Slackware Linux distributions. + + """ + if os.path.exists('/var/adm/inst-log/info'): + # SuSE Linux stores distribution information in that file + info = open('/var/adm/inst-log/info').readlines() + distname = 'SuSE' + for line in info: + tv = string.split(line) + if len(tv) == 2: + tag,value = tv + else: + continue + if tag == 'MIN_DIST_VERSION': + version = string.strip(value) + elif tag == 'DIST_IDENT': + values = string.split(value,'-') + id = values[2] + return distname,version,id + + if os.path.exists('/etc/.installed'): + # Caldera OpenLinux has some infos in that file (thanks to Colin Kong) + info = open('/etc/.installed').readlines() + for line in info: + pkg = string.split(line,'-') + if len(pkg) >= 2 and pkg[0] == 'OpenLinux': + # XXX does Caldera support non Intel platforms ? If yes, + # where can we find the needed id ? + return 'OpenLinux',pkg[1],id + + if os.path.isdir('/usr/lib/setup'): + # Check for slackware verson tag file (thanks to Greg Andruk) + verfiles = os.listdir('/usr/lib/setup') + for n in range(len(verfiles)-1, -1, -1): + if verfiles[n][:14] != 'slack-version-': + del verfiles[n] + if verfiles: + verfiles.sort() + distname = 'slackware' + version = verfiles[-1][14:] + return distname,version,id + + return distname,version,id + +_release_filename = re.compile(r'(\w+)[-_](release|version)') +_release_version = re.compile(r'([\d.]+)[^(]*(?:\((.+)\))?') + +# Note:In supported_dists below we need 'fedora' before 'redhat' as in +# Fedora redhat-release is a link to fedora-release. + +def dist(distname='',version='',id='', + + supported_dists=('SuSE', 'debian', 'fedora', 'redhat', 'mandrake')): + + """ Tries to determine the name of the Linux OS distribution name. + + The function first looks for a distribution release file in + /etc and then reverts to _dist_try_harder() in case no + suitable files are found. + + Returns a tuple (distname,version,id) which default to the + args given as parameters. + + """ + try: + etc = os.listdir('/etc') + except os.error: + # Probably not a Unix system + return distname,version,id + for file in etc: + m = _release_filename.match(file) + if m: + _distname,dummy = m.groups() + if _distname in supported_dists: + distname = _distname + break + else: + return _dist_try_harder(distname,version,id) + f = open('/etc/'+file,'r') + firstline = f.readline() + f.close() + m = _release_version.search(firstline) + if m: + _version,_id = m.groups() + if _version: + version = _version + if _id: + id = _id + else: + # Unkown format... take the first two words + l = string.split(string.strip(firstline)) + if l: + version = l[0] + if len(l) > 1: + id = l[1] + return distname,version,id + +class _popen: + + """ Fairly portable (alternative) popen implementation. + + This is mostly needed in case os.popen() is not available, or + doesn't work as advertised, e.g. in Win9X GUI programs like + PythonWin or IDLE. + + Writing to the pipe is currently not supported. + + """ + tmpfile = '' + pipe = None + bufsize = None + mode = 'r' + + def __init__(self,cmd,mode='r',bufsize=None): + + if mode != 'r': + raise ValueError,'popen()-emulation only supports read mode' + import tempfile + self.tmpfile = tmpfile = tempfile.mktemp() + os.system(cmd + ' > %s' % tmpfile) + self.pipe = open(tmpfile,'rb') + self.bufsize = bufsize + self.mode = mode + + def read(self): + + return self.pipe.read() + + def readlines(self): + + if self.bufsize is not None: + return self.pipe.readlines() + + def close(self, + + remove=os.unlink,error=os.error): + + if self.pipe: + rc = self.pipe.close() + else: + rc = 255 + if self.tmpfile: + try: + remove(self.tmpfile) + except error: + pass + return rc + + # Alias + __del__ = close + +def popen(cmd, mode='r', bufsize=None): + + """ Portable popen() interface. + """ + # Find a working popen implementation preferring win32pipe.popen + # over os.popen over _popen + popen = None + if os.environ.get('OS','') == 'Windows_NT': + # On NT win32pipe should work; on Win9x it hangs due to bugs + # in the MS C lib (see MS KnowledgeBase article Q150956) + try: + import win32pipe + except ImportError: + pass + else: + popen = win32pipe.popen + if popen is None: + if hasattr(os,'popen'): + popen = os.popen + # Check whether it works... it doesn't in GUI programs + # on Windows platforms + if sys.platform == 'win32': # XXX Others too ? + try: + popen('') + except os.error: + popen = _popen + else: + popen = _popen + if bufsize is None: + return popen(cmd,mode) + else: + return popen(cmd,mode,bufsize) + +def _norm_version(version,build=''): + + """ Normalize the version and build strings and return a single + version string using the format major.minor.build (or patchlevel). + """ + l = string.split(version,'.') + if build: + l.append(build) + try: + ints = map(int,l) + except ValueError: + strings = l + else: + strings = map(str,ints) + version = string.join(strings[:3],'.') + return version + +_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' + '.*' + 'Version ([\d.]+))') + +def _syscmd_ver(system='',release='',version='', + + supported_platforms=('win32','win16','dos','os2')): + + """ Tries to figure out the OS version used and returns + a tuple (system,release,version). + + It uses the "ver" shell command for this which is known + to exists on Windows, DOS and OS/2. XXX Others too ? + + In case this fails, the given parameters are used as + defaults. + + """ + if sys.platform not in supported_platforms: + return system,release,version + + # Try some common cmd strings + for cmd in ('ver','command /c ver','cmd /c ver'): + try: + pipe = popen(cmd) + info = pipe.read() + if pipe.close(): + raise os.error,'command failed' + # XXX How can I supress shell errors from being written + # to stderr ? + except os.error,why: + #print 'Command %s failed: %s' % (cmd,why) + continue + except IOError,why: + #print 'Command %s failed: %s' % (cmd,why) + continue + else: + break + else: + return system,release,version + + # Parse the output + info = string.strip(info) + m = _ver_output.match(info) + if m: + system,release,version = m.groups() + # Strip trailing dots from version and release + if release[-1] == '.': + release = release[:-1] + if version[-1] == '.': + version = version[:-1] + # Normalize the version and build strings (eliminating additional + # zeros) + version = _norm_version(version) + return system,release,version + +def _win32_getvalue(key,name,default=''): + + """ Read a value for name from the registry key. + + In case this fails, default is returned. + + """ + from win32api import RegQueryValueEx + try: + return RegQueryValueEx(key,name) + except: + return default + +def win32_ver(release='',version='',csd='',ptype=''): + + """ Get additional version information from the Windows Registry + and return a tuple (version,csd,ptype) referring to version + number, CSD level and OS type (multi/single + processor). + + As a hint: ptype returns 'Uniprocessor Free' on single + processor NT machines and 'Multiprocessor Free' on multi + processor machines. The 'Free' refers to the OS version being + free of debugging code. It could also state 'Checked' which + means the OS version uses debugging code, i.e. code that + checks arguments, ranges, etc. (Thomas Heller). + + Note: this function only works if Mark Hammond's win32 + package is installed and obviously only runs on Win32 + compatible platforms. + + """ + # XXX Is there any way to find out the processor type on WinXX ? + # XXX Is win32 available on Windows CE ? + # + # Adapted from code posted by Karl Putland to comp.lang.python. + # + # The mappings between reg. values and release names can be found + # here: http://msdn.microsoft.com/library/en-us/sysinfo/base/osversioninfo_str.asp + + # Import the needed APIs + try: + import win32api + except ImportError: + return release,version,csd,ptype + from win32api import RegQueryValueEx,RegOpenKeyEx,RegCloseKey,GetVersionEx + from win32con import HKEY_LOCAL_MACHINE,VER_PLATFORM_WIN32_NT,\ + VER_PLATFORM_WIN32_WINDOWS + + # Find out the registry key and some general version infos + maj,min,buildno,plat,csd = GetVersionEx() + version = '%i.%i.%i' % (maj,min,buildno & 0xFFFF) + if csd[:13] == 'Service Pack ': + csd = 'SP' + csd[13:] + if plat == VER_PLATFORM_WIN32_WINDOWS: + regkey = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion' + # Try to guess the release name + if maj == 4: + if min == 0: + release = '95' + elif min == 10: + release = '98' + elif min == 90: + release = 'Me' + else: + release = 'postMe' + elif maj == 5: + release = '2000' + elif plat == VER_PLATFORM_WIN32_NT: + regkey = 'SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion' + if maj <= 4: + release = 'NT' + elif maj == 5: + if min == 0: + release = '2000' + elif min == 1: + release = 'XP' + elif min == 2: + release = '2003Server' + else: + release = 'post2003' + else: + if not release: + # E.g. Win3.1 with win32s + release = '%i.%i' % (maj,min) + return release,version,csd,ptype + + # Open the registry key + try: + keyCurVer = RegOpenKeyEx(HKEY_LOCAL_MACHINE,regkey) + # Get a value to make sure the key exists... + RegQueryValueEx(keyCurVer,'SystemRoot') + except: + return release,version,csd,ptype + + # Parse values + #subversion = _win32_getvalue(keyCurVer, + # 'SubVersionNumber', + # ('',1))[0] + #if subversion: + # release = release + subversion # 95a, 95b, etc. + build = _win32_getvalue(keyCurVer, + 'CurrentBuildNumber', + ('',1))[0] + ptype = _win32_getvalue(keyCurVer, + 'CurrentType', + (ptype,1))[0] + + # Normalize version + version = _norm_version(version,build) + + # Close key + RegCloseKey(keyCurVer) + return release,version,csd,ptype + +def _mac_ver_lookup(selectors,default=None): + + from gestalt import gestalt + import MacOS + l = [] + append = l.append + for selector in selectors: + try: + append(gestalt(selector)) + except (RuntimeError, MacOS.Error): + append(default) + return l + +def _bcd2str(bcd): + + return hex(bcd)[2:] + +def mac_ver(release='',versioninfo=('','',''),machine=''): + + """ Get MacOS version information and return it as tuple (release, + versioninfo, machine) with versioninfo being a tuple (version, + dev_stage, non_release_version). + + Entries which cannot be determined are set to the paramter values + which default to ''. All tuple entries are strings. + + Thanks to Mark R. Levinson for mailing documentation links and + code examples for this function. Documentation for the + gestalt() API is available online at: + + http://www.rgaros.nl/gestalt/ + + """ + # Check whether the version info module is available + try: + import gestalt + import MacOS + except ImportError: + return release,versioninfo,machine + # Get the infos + sysv,sysu,sysa = _mac_ver_lookup(('sysv','sysu','sysa')) + # Decode the infos + if sysv: + major = (sysv & 0xFF00) >> 8 + minor = (sysv & 0x00F0) >> 4 + patch = (sysv & 0x000F) + + if (major, minor) >= (10, 4): + # the 'sysv' gestald cannot return patchlevels + # higher than 9. Apple introduced 3 new + # gestalt codes in 10.4 to deal with this + # issue (needed because patch levels can + # run higher than 9, such as 10.4.11) + major,minor,patch = _mac_ver_lookup(('sys1','sys2','sys3')) + release = '%i.%i.%i' %(major, minor, patch) + else: + release = '%s.%i.%i' % (_bcd2str(major),minor,patch) + if sysu: + major = int((sysu & 0xFF000000L) >> 24) + minor = (sysu & 0x00F00000) >> 20 + bugfix = (sysu & 0x000F0000) >> 16 + stage = (sysu & 0x0000FF00) >> 8 + nonrel = (sysu & 0x000000FF) + version = '%s.%i.%i' % (_bcd2str(major),minor,bugfix) + nonrel = _bcd2str(nonrel) + stage = {0x20:'development', + 0x40:'alpha', + 0x60:'beta', + 0x80:'final'}.get(stage,'') + versioninfo = (version,stage,nonrel) + if sysa: + machine = {0x1: '68k', + 0x2: 'PowerPC', + 0xa: 'i386'}.get(sysa,'') + return release,versioninfo,machine + +def _java_getprop(name,default): + + from java.lang import System + try: + return System.getProperty(name) + except: + return default + +def java_ver(release='',vendor='',vminfo=('','',''),osinfo=('','','')): + + """ Version interface for Jython. + + Returns a tuple (release,vendor,vminfo,osinfo) with vminfo being + a tuple (vm_name,vm_release,vm_vendor) and osinfo being a + tuple (os_name,os_version,os_arch). + + Values which cannot be determined are set to the defaults + given as parameters (which all default to ''). + + """ + # Import the needed APIs + try: + import java.lang + except ImportError: + return release,vendor,vminfo,osinfo + + vendor = _java_getprop('java.vendor',vendor) + release = _java_getprop('java.version',release) + vm_name,vm_release,vm_vendor = vminfo + vm_name = _java_getprop('java.vm.name',vm_name) + vm_vendor = _java_getprop('java.vm.vendor',vm_vendor) + vm_release = _java_getprop('java.vm.version',vm_release) + vminfo = vm_name,vm_release,vm_vendor + os_name,os_version,os_arch = osinfo + os_arch = _java_getprop('os.arch',os_arch) + os_name = _java_getprop('os.name',os_name) + os_version = _java_getprop('os.version',os_version) + osinfo = os_name,os_version,os_arch + + return release,vendor,vminfo,osinfo + +### System name aliasing + +def system_alias(system,release,version): + + """ Returns (system,release,version) aliased to common + marketing names used for some systems. + + It also does some reordering of the information in some cases + where it would otherwise cause confusion. + + """ + if system == 'Rhapsody': + # Apple's BSD derivative + # XXX How can we determine the marketing release number ? + return 'MacOS X Server',system+release,version + + elif system == 'SunOS': + # Sun's OS + if release < '5': + # These releases use the old name SunOS + return system,release,version + # Modify release (marketing release = SunOS release - 3) + l = string.split(release,'.') + if l: + try: + major = int(l[0]) + except ValueError: + pass + else: + major = major - 3 + l[0] = str(major) + release = string.join(l,'.') + if release < '6': + system = 'Solaris' + else: + # XXX Whatever the new SunOS marketing name is... + system = 'Solaris' + + elif system == 'IRIX64': + # IRIX reports IRIX64 on platforms with 64-bit support; yet it + # is really a version and not a different platform, since 32-bit + # apps are also supported.. + system = 'IRIX' + if version: + version = version + ' (64bit)' + else: + version = '64bit' + + elif system in ('win32','win16'): + # In case one of the other tricks + system = 'Windows' + + return system,release,version + +### Various internal helpers + +def _platform(*args): + + """ Helper to format the platform string in a filename + compatible format e.g. "system-version-machine". + """ + # Format the platform string + platform = string.join( + map(string.strip, + filter(len,args)), + '-') + + # Cleanup some possible filename obstacles... + replace = string.replace + platform = replace(platform,' ','_') + platform = replace(platform,'/','-') + platform = replace(platform,'\\','-') + platform = replace(platform,':','-') + platform = replace(platform,';','-') + platform = replace(platform,'"','-') + platform = replace(platform,'(','-') + platform = replace(platform,')','-') + + # No need to report 'unknown' information... + platform = replace(platform,'unknown','') + + # Fold '--'s and remove trailing '-' + while 1: + cleaned = replace(platform,'--','-') + if cleaned == platform: + break + platform = cleaned + while platform[-1] == '-': + platform = platform[:-1] + + return platform + +def _node(default=''): + + """ Helper to determine the node name of this machine. + """ + try: + import socket + except ImportError: + # No sockets... + return default + try: + return socket.gethostname() + except socket.error: + # Still not working... + return default + +# os.path.abspath is new in Python 1.5.2: +if not hasattr(os.path,'abspath'): + + def _abspath(path, + + isabs=os.path.isabs,join=os.path.join,getcwd=os.getcwd, + normpath=os.path.normpath): + + if not isabs(path): + path = join(getcwd(), path) + return normpath(path) + +else: + + _abspath = os.path.abspath + +def _follow_symlinks(filepath): + + """ In case filepath is a symlink, follow it until a + real file is reached. + """ + filepath = _abspath(filepath) + while os.path.islink(filepath): + filepath = os.path.normpath( + os.path.join(filepath,os.readlink(filepath))) + return filepath + +def _syscmd_uname(option,default=''): + + """ Interface to the system's uname command. + """ + if sys.platform in ('dos','win32','win16','os2'): + # XXX Others too ? + return default + try: + f = os.popen('uname %s 2> /dev/null' % option) + except (AttributeError,os.error): + return default + output = string.strip(f.read()) + rc = f.close() + if not output or rc: + return default + else: + return output + +def _syscmd_file(target,default=''): + + """ Interface to the system's file command. + + The function uses the -b option of the file command to have it + ommit the filename in its output and if possible the -L option + to have the command follow symlinks. It returns default in + case the command should fail. + + """ + target = _follow_symlinks(target) + try: + f = os.popen('file %s 2> /dev/null' % target) + except (AttributeError,os.error): + return default + output = string.strip(f.read()) + rc = f.close() + if not output or rc: + return default + else: + return output + +### Information about the used architecture + +# Default values for architecture; non-empty strings override the +# defaults given as parameters +_default_architecture = { + 'win32': ('','WindowsPE'), + 'win16': ('','Windows'), + 'dos': ('','MSDOS'), +} + +_architecture_split = re.compile(r'[\s,]').split + +def architecture(executable=sys.executable,bits='',linkage=''): + + """ Queries the given executable (defaults to the Python interpreter + binary) for various architecture information. + + Returns a tuple (bits,linkage) which contains information about + the bit architecture and the linkage format used for the + executable. Both values are returned as strings. + + Values that cannot be determined are returned as given by the + parameter presets. If bits is given as '', the sizeof(pointer) + (or sizeof(long) on Python version < 1.5.2) is used as + indicator for the supported pointer size. + + The function relies on the system's "file" command to do the + actual work. This is available on most if not all Unix + platforms. On some non-Unix platforms where the "file" command + does not exist and the executable is set to the Python interpreter + binary defaults from _default_architecture are used. + + """ + # Use the sizeof(pointer) as default number of bits if nothing + # else is given as default. + if not bits: + import struct + try: + size = struct.calcsize('P') + except struct.error: + # Older installations can only query longs + size = struct.calcsize('l') + bits = str(size*8) + 'bit' + + # Get data from the 'file' system command + output = _syscmd_file(executable,'') + + if not output and \ + executable == sys.executable: + # "file" command did not return anything; we'll try to provide + # some sensible defaults then... + if _default_architecture.has_key(sys.platform): + b,l = _default_architecture[sys.platform] + if b: + bits = b + if l: + linkage = l + return bits,linkage + + # Split the output into a list of strings omitting the filename + fileout = _architecture_split(output)[1:] + + if 'executable' not in fileout: + # Format not supported + return bits,linkage + + # Bits + if '32-bit' in fileout: + bits = '32bit' + elif 'N32' in fileout: + # On Irix only + bits = 'n32bit' + elif '64-bit' in fileout: + bits = '64bit' + + # Linkage + if 'ELF' in fileout: + linkage = 'ELF' + elif 'PE' in fileout: + # E.g. Windows uses this format + if 'Windows' in fileout: + linkage = 'WindowsPE' + else: + linkage = 'PE' + elif 'COFF' in fileout: + linkage = 'COFF' + elif 'MS-DOS' in fileout: + linkage = 'MSDOS' + else: + # XXX the A.OUT format also falls under this class... + pass + + return bits,linkage + +### Portable uname() interface + +_uname_cache = None + +def uname(): + + """ Fairly portable uname interface. Returns a tuple + of strings (system,node,release,version,machine,processor) + identifying the underlying platform. + + Note that unlike the os.uname function this also returns + possible processor information as an additional tuple entry. + + Entries which cannot be determined are set to ''. + + """ + global _uname_cache + + if _uname_cache is not None: + return _uname_cache + + # Get some infos from the builtin os.uname API... + try: + system,node,release,version,machine = os.uname() + + except AttributeError: + # Hmm, no uname... we'll have to poke around the system then. + system = sys.platform + release = '' + version = '' + node = _node() + machine = '' + processor = '' + use_syscmd_ver = 1 + + # Try win32_ver() on win32 platforms + if system == 'win32': + release,version,csd,ptype = win32_ver() + if release and version: + use_syscmd_ver = 0 + + # Try the 'ver' system command available on some + # platforms + if use_syscmd_ver: + system,release,version = _syscmd_ver(system) + # Normalize system to what win32_ver() normally returns + # (_syscmd_ver() tends to return the vendor name as well) + if system == 'Microsoft Windows': + system = 'Windows' + + # In case we still don't know anything useful, we'll try to + # help ourselves + if system in ('win32','win16'): + if not version: + if system == 'win32': + version = '32bit' + else: + version = '16bit' + system = 'Windows' + + elif system[:4] == 'java': + release,vendor,vminfo,osinfo = java_ver() + system = 'Java' + version = string.join(vminfo,', ') + if not version: + version = vendor + + elif os.name == 'mac': + release,(version,stage,nonrel),machine = mac_ver() + system = 'MacOS' + + else: + # System specific extensions + if system == 'OpenVMS': + # OpenVMS seems to have release and version mixed up + if not release or release == '0': + release = version + version = '' + # Get processor information + try: + import vms_lib + except ImportError: + pass + else: + csid, cpu_number = vms_lib.getsyi('SYI$_CPU',0) + if (cpu_number >= 128): + processor = 'Alpha' + else: + processor = 'VAX' + else: + # Get processor information from the uname system command + processor = _syscmd_uname('-p','') + + # 'unknown' is not really any useful as information; we'll convert + # it to '' which is more portable + if system == 'unknown': + system = '' + if node == 'unknown': + node = '' + if release == 'unknown': + release = '' + if version == 'unknown': + version = '' + if machine == 'unknown': + machine = '' + if processor == 'unknown': + processor = '' + + # normalize name + if system == 'Microsoft' and release == 'Windows': + system = 'Windows' + release = 'Vista' + + _uname_cache = system,node,release,version,machine,processor + return _uname_cache + +### Direct interfaces to some of the uname() return values + +def system(): + + """ Returns the system/OS name, e.g. 'Linux', 'Windows' or 'Java'. + + An empty string is returned if the value cannot be determined. + + """ + return uname()[0] + +def node(): + + """ Returns the computer's network name (which may not be fully + qualified) + + An empty string is returned if the value cannot be determined. + + """ + return uname()[1] + +def release(): + + """ Returns the system's release, e.g. '2.2.0' or 'NT' + + An empty string is returned if the value cannot be determined. + + """ + return uname()[2] + +def version(): + + """ Returns the system's release version, e.g. '#3 on degas' + + An empty string is returned if the value cannot be determined. + + """ + return uname()[3] + +def machine(): + + """ Returns the machine type, e.g. 'i386' + + An empty string is returned if the value cannot be determined. + + """ + return uname()[4] + +def processor(): + + """ Returns the (true) processor name, e.g. 'amdk6' + + An empty string is returned if the value cannot be + determined. Note that many platforms do not provide this + information or simply return the same value as for machine(), + e.g. NetBSD does this. + + """ + return uname()[5] + +### Various APIs for extracting information from sys.version + +_sys_version_parser = re.compile(r'([\w.+]+)\s*' + '\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' + '\[([^\]]+)\]?') +_sys_version_cache = None + +def _sys_version(): + + """ Returns a parsed version of Python's sys.version as tuple + (version, buildno, builddate, compiler) referring to the Python + version, build number, build date/time as string and the compiler + identification string. + + Note that unlike the Python sys.version, the returned value + for the Python version will always include the patchlevel (it + defaults to '.0'). + + """ + global _sys_version_cache + + if _sys_version_cache is not None: + return _sys_version_cache + version, buildno, builddate, buildtime, compiler = \ + _sys_version_parser.match(sys.version).groups() + builddate = builddate + ' ' + buildtime + l = string.split(version, '.') + if len(l) == 2: + l.append('0') + version = string.join(l, '.') + _sys_version_cache = (version, buildno, builddate, compiler) + return _sys_version_cache + +def python_version(): + + """ Returns the Python version as string 'major.minor.patchlevel' + + Note that unlike the Python sys.version, the returned value + will always include the patchlevel (it defaults to 0). + + """ + return _sys_version()[0] + +def python_version_tuple(): + + """ Returns the Python version as tuple (major, minor, patchlevel) + of strings. + + Note that unlike the Python sys.version, the returned value + will always include the patchlevel (it defaults to 0). + + """ + return string.split(_sys_version()[0], '.') + +def python_build(): + + """ Returns a tuple (buildno, builddate) stating the Python + build number and date as strings. + + """ + return _sys_version()[1:3] + +def python_compiler(): + + """ Returns a string identifying the compiler used for compiling + Python. + + """ + return _sys_version()[3] + +### The Opus Magnum of platform strings :-) + +_platform_cache = {} + +def platform(aliased=0, terse=0): + + """ Returns a single string identifying the underlying platform + with as much useful information as possible (but no more :). + + The output is intended to be human readable rather than + machine parseable. It may look different on different + platforms and this is intended. + + If "aliased" is true, the function will use aliases for + various platforms that report system names which differ from + their common names, e.g. SunOS will be reported as + Solaris. The system_alias() function is used to implement + this. + + Setting terse to true causes the function to return only the + absolute minimum information needed to identify the platform. + + """ + result = _platform_cache.get((aliased, terse), None) + if result is not None: + return result + + # Get uname information and then apply platform specific cosmetics + # to it... + system,node,release,version,machine,processor = uname() + if machine == processor: + processor = '' + if aliased: + system,release,version = system_alias(system,release,version) + + if system == 'Windows': + # MS platforms + rel,vers,csd,ptype = win32_ver(version) + if terse: + platform = _platform(system,release) + else: + platform = _platform(system,release,version,csd) + + elif system in ('Linux',): + # Linux based systems + distname,distversion,distid = dist('') + if distname and not terse: + platform = _platform(system,release,machine,processor, + 'with', + distname,distversion,distid) + else: + # If the distribution name is unknown check for libc vs. glibc + libcname,libcversion = libc_ver(sys.executable) + platform = _platform(system,release,machine,processor, + 'with', + libcname+libcversion) + elif system == 'Java': + # Java platforms + r,v,vminfo,(os_name,os_version,os_arch) = java_ver() + if terse: + platform = _platform(system,release,version) + else: + platform = _platform(system,release,version, + 'on', + os_name,os_version,os_arch) + + elif system == 'MacOS': + # MacOS platforms + if terse: + platform = _platform(system,release) + else: + platform = _platform(system,release,machine) + + else: + # Generic handler + if terse: + platform = _platform(system,release) + else: + bits,linkage = architecture(sys.executable) + platform = _platform(system,release,machi... [truncated message content] |
From: <zy...@us...> - 2008-07-14 12:19:15
|
Revision: 4925 http://jython.svn.sourceforge.net/jython/?rev=4925&view=rev Author: zyasoft Date: 2008-07-14 05:19:10 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Fixed uu.encode, decode so that it does not rely on refcounting to close files Modified Paths: -------------- branches/asm/Lib/uu.py Modified: branches/asm/Lib/uu.py =================================================================== --- branches/asm/Lib/uu.py 2008-07-14 12:11:26 UTC (rev 4924) +++ branches/asm/Lib/uu.py 2008-07-14 12:19:10 UTC (rev 4925) @@ -44,6 +44,10 @@ # # If in_file is a pathname open it and change defaults # + + close_in_file = False + close_out_file = False + if in_file == '-': in_file = sys.stdin elif isinstance(in_file, basestring): @@ -55,6 +59,7 @@ except AttributeError: pass in_file = open(in_file, 'rb') + close_in_file = True # # Open out_file if it is a pathname # @@ -62,6 +67,7 @@ out_file = sys.stdout elif isinstance(out_file, basestring): out_file = open(out_file, 'w') + close_out_file = True # # Set defaults for name and mode # @@ -79,15 +85,26 @@ data = in_file.read(45) out_file.write(' \nend\n') + # Jython and other implementations requires files to be explicitly + # closed if we don't want to wait for GC + if close_in_file: + in_file.close() + if close_out_file: + out_file.close() def decode(in_file, out_file=None, mode=None, quiet=0): """Decode uuencoded file""" + + close_in_file = False + close_out_file = False + # # Open the input file, if needed. # if in_file == '-': in_file = sys.stdin elif isinstance(in_file, basestring): + close_in_file = True in_file = open(in_file) # # Read until a begin is encountered or we've exhausted the file @@ -118,6 +135,7 @@ if out_file == '-': out_file = sys.stdout elif isinstance(out_file, basestring): + close_out_file = True fp = open(out_file, 'wb') try: os.path.chmod(out_file, mode) @@ -145,6 +163,13 @@ if opened: out_file.close() + # Jython and other implementations requires files to be explicitly + # closed if we don't want to wait for GC + if close_in_file: + in_file.close() + if close_out_file: + out_file.close() + def test(): """uuencode/uudecode main program""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-14 12:11:28
|
Revision: 4924 http://jython.svn.sourceforge.net/jython/?rev=4924&view=rev Author: zyasoft Date: 2008-07-14 05:11:26 -0700 (Mon, 14 Jul 2008) Log Message: ----------- From http://svn.python.org/projects/python/branches/release25-maint/Lib/uu.py@64946 Added Paths: ----------- branches/asm/Lib/uu.py Added: branches/asm/Lib/uu.py =================================================================== --- branches/asm/Lib/uu.py (rev 0) +++ branches/asm/Lib/uu.py 2008-07-14 12:11:26 UTC (rev 4924) @@ -0,0 +1,186 @@ +#! /usr/bin/env python + +# Copyright 1994 by Lance Ellinghouse +# Cathedral City, California Republic, United States of America. +# All Rights Reserved +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose and without fee is hereby granted, +# provided that the above copyright notice appear in all copies and that +# both that copyright notice and this permission notice appear in +# supporting documentation, and that the name of Lance Ellinghouse +# not be used in advertising or publicity pertaining to distribution +# of the software without specific, written prior permission. +# LANCE ELLINGHOUSE DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS, IN NO EVENT SHALL LANCE ELLINGHOUSE CENTRUM BE LIABLE +# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# Modified by Jack Jansen, CWI, July 1995: +# - Use binascii module to do the actual line-by-line conversion +# between ascii and binary. This results in a 1000-fold speedup. The C +# version is still 5 times faster, though. +# - Arguments more compliant with python standard + +"""Implementation of the UUencode and UUdecode functions. + +encode(in_file, out_file [,name, mode]) +decode(in_file [, out_file, mode]) +""" + +import binascii +import os +import sys + +__all__ = ["Error", "encode", "decode"] + +class Error(Exception): + pass + +def encode(in_file, out_file, name=None, mode=None): + """Uuencode file""" + # + # If in_file is a pathname open it and change defaults + # + if in_file == '-': + in_file = sys.stdin + elif isinstance(in_file, basestring): + if name is None: + name = os.path.basename(in_file) + if mode is None: + try: + mode = os.stat(in_file).st_mode + except AttributeError: + pass + in_file = open(in_file, 'rb') + # + # Open out_file if it is a pathname + # + if out_file == '-': + out_file = sys.stdout + elif isinstance(out_file, basestring): + out_file = open(out_file, 'w') + # + # Set defaults for name and mode + # + if name is None: + name = '-' + if mode is None: + mode = 0666 + # + # Write the data + # + out_file.write('begin %o %s\n' % ((mode&0777),name)) + data = in_file.read(45) + while len(data) > 0: + out_file.write(binascii.b2a_uu(data)) + data = in_file.read(45) + out_file.write(' \nend\n') + + +def decode(in_file, out_file=None, mode=None, quiet=0): + """Decode uuencoded file""" + # + # Open the input file, if needed. + # + if in_file == '-': + in_file = sys.stdin + elif isinstance(in_file, basestring): + in_file = open(in_file) + # + # Read until a begin is encountered or we've exhausted the file + # + while True: + hdr = in_file.readline() + if not hdr: + raise Error('No valid begin line found in input file') + if not hdr.startswith('begin'): + continue + hdrfields = hdr.split(' ', 2) + if len(hdrfields) == 3 and hdrfields[0] == 'begin': + try: + int(hdrfields[1], 8) + break + except ValueError: + pass + if out_file is None: + out_file = hdrfields[2].rstrip() + if os.path.exists(out_file): + raise Error('Cannot overwrite existing file: %s' % out_file) + if mode is None: + mode = int(hdrfields[1], 8) + # + # Open the output file + # + opened = False + if out_file == '-': + out_file = sys.stdout + elif isinstance(out_file, basestring): + fp = open(out_file, 'wb') + try: + os.path.chmod(out_file, mode) + except AttributeError: + pass + out_file = fp + opened = True + # + # Main decoding loop + # + s = in_file.readline() + while s and s.strip() != 'end': + try: + data = binascii.a2b_uu(s) + except binascii.Error, v: + # Workaround for broken uuencoders by /Fredrik Lundh + nbytes = (((ord(s[0])-32) & 63) * 4 + 5) // 3 + data = binascii.a2b_uu(s[:nbytes]) + if not quiet: + sys.stderr.write("Warning: %s\n" % v) + out_file.write(data) + s = in_file.readline() + if not s: + raise Error('Truncated input file') + if opened: + out_file.close() + +def test(): + """uuencode/uudecode main program""" + + import optparse + parser = optparse.OptionParser(usage='usage: %prog [-d] [-t] [input [output]]') + parser.add_option('-d', '--decode', dest='decode', help='Decode (instead of encode)?', default=False, action='store_true') + parser.add_option('-t', '--text', dest='text', help='data is text, encoded format unix-compatible text?', default=False, action='store_true') + + (options, args) = parser.parse_args() + if len(args) > 2: + parser.error('incorrect number of arguments') + sys.exit(1) + + input = sys.stdin + output = sys.stdout + if len(args) > 0: + input = args[0] + if len(args) > 1: + output = args[1] + + if options.decode: + if options.text: + if isinstance(output, basestring): + output = open(output, 'w') + else: + print sys.argv[0], ': cannot do -t to stdout' + sys.exit(1) + decode(input, output) + else: + if options.text: + if isinstance(input, basestring): + input = open(input, 'r') + else: + print sys.argv[0], ': cannot do -t from stdin' + sys.exit(1) + encode(input, output) + +if __name__ == '__main__': + test() Property changes on: branches/asm/Lib/uu.py ___________________________________________________________________ Name: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2008-07-14 11:51:11
|
Revision: 4923 http://jython.svn.sourceforge.net/jython/?rev=4923&view=rev Author: thobes Date: 2008-07-14 04:51:08 -0700 (Mon, 14 Jul 2008) Log Message: ----------- Initialized merge tracking via "svnmerge" with revisions "1-4922" from https://jython.svn.sourceforge.net/svnroot/jython/branches/asm Property Changed: ---------------- branches/advanced/ Property changes on: branches/advanced ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4738 + /branches/asm:1-4922 /trunk/jython:1-4738 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2008-07-14 11:44:29
|
Revision: 4922 http://jython.svn.sourceforge.net/jython/?rev=4922&view=rev Author: zyasoft Date: 2008-07-14 04:44:28 -0700 (Mon, 14 Jul 2008) Log Message: ----------- time.struct_time can now take any obj that can be turned into a list and converted into 9 integers Modified Paths: -------------- branches/asm/src/org/python/modules/time/PyTimeTuple.java Modified: branches/asm/src/org/python/modules/time/PyTimeTuple.java =================================================================== --- branches/asm/src/org/python/modules/time/PyTimeTuple.java 2008-07-14 11:37:10 UTC (rev 4921) +++ branches/asm/src/org/python/modules/time/PyTimeTuple.java 2008-07-14 11:44:28 UTC (rev 4922) @@ -26,19 +26,22 @@ @ExposedGet public PyInteger tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst; + @ExposedGet + public final int n_sequence_fields = 9, n_fields = 9, n_unnamed_fields = 0; + public static final PyType TYPE = PyType.fromClass(PyTimeTuple.class); PyTimeTuple(PyObject... vals) { super(TYPE, vals); - tm_year = (PyInteger)vals[0]; - tm_mon = (PyInteger)vals[1]; - tm_mday = (PyInteger)vals[2]; - tm_hour = (PyInteger)vals[3]; - tm_min = (PyInteger)vals[4]; - tm_sec = (PyInteger)vals[5]; - tm_wday = (PyInteger)vals[6]; - tm_yday = (PyInteger)vals[7]; - tm_isdst = (PyInteger)vals[8]; + tm_year = (PyInteger)vals[0].__int__(); + tm_mon = (PyInteger)vals[1].__int__(); + tm_mday = (PyInteger)vals[2].__int__(); + tm_hour = (PyInteger)vals[3].__int__(); + tm_min = (PyInteger)vals[4].__int__(); + tm_sec = (PyInteger)vals[5].__int__();; + tm_wday = (PyInteger)vals[6].__int__();; + tm_yday = (PyInteger)vals[7].__int__();; + tm_isdst =(PyInteger)vals[8].__int__();; } @ExposedNew @@ -52,14 +55,14 @@ } // tuples are immutable, so we can just use its underlying array return new PyTimeTuple(((PyTuple)obj).getArray()); - } else if (obj instanceof PySequence) { - PySequence seq = (PySequence)obj; + } + else { + PyList seq = new PyList(obj); if (seq.__len__() != 9) { throw Py.TypeError("time.struct_time() takes a 9-sequence (1-sequence given)"); - } - return new PyTimeTuple((PyObject[])seq.__tojava__(PyObject[].class)); + } + return new PyTimeTuple((PyObject[])seq.__tojava__(PyObject[].class)); } - throw Py.TypeError("constructor requires a sequence"); } public synchronized PyObject __eq__(PyObject o) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |