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: <pj...@us...> - 2010-03-13 03:38:47
|
Revision: 6983 http://jython.svn.sourceforge.net/jython/?rev=6983&view=rev Author: pjenvey Date: 2010-03-13 03:38:40 +0000 (Sat, 13 Mar 2010) Log Message: ----------- fix defaultdict __reduce__ not returning an actual iterator for dictitems Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/modules/_collections/PyDefaultDict.java Added Paths: ----------- trunk/jython/Lib/test/test_defaultdict_jy.py Added: trunk/jython/Lib/test/test_defaultdict_jy.py =================================================================== --- trunk/jython/Lib/test/test_defaultdict_jy.py (rev 0) +++ trunk/jython/Lib/test/test_defaultdict_jy.py 2010-03-13 03:38:40 UTC (rev 6983) @@ -0,0 +1,23 @@ +"""Misc defaultdict tests. + +Made for Jython. +""" +import pickle +import unittest +from collections import defaultdict +from test import test_support + +class PickleTestCase(unittest.TestCase): + + def test_pickle(self): + d = defaultdict(str, a='foo', b='bar') + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + self.assertEqual(pickle.loads(pickle.dumps(d, proto)), d) + + +def test_main(): + test_support.run_unittest(PickleTestCase) + + +if __name__ == '__main__': + test_main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-02-25 03:53:18 UTC (rev 6982) +++ trunk/jython/NEWS 2010-03-13 03:38:40 UTC (rev 6983) @@ -19,6 +19,7 @@ - [ 1548 ] Parentheses in CLASSPATH cause errors in jython.bat - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) + - Fix pickling of collections.defaultdict objects Jython 2.5.1rc3 Bugs Fixed Modified: trunk/jython/src/org/python/modules/_collections/PyDefaultDict.java =================================================================== --- trunk/jython/src/org/python/modules/_collections/PyDefaultDict.java 2010-02-25 03:53:18 UTC (rev 6982) +++ trunk/jython/src/org/python/modules/_collections/PyDefaultDict.java 2010-03-13 03:38:40 UTC (rev 6983) @@ -100,7 +100,7 @@ PyObject[] ob = {defaultFactory}; args = new PyTuple(ob); } - return new PyTuple(getType(), args, Py.None, Py.None, items()); + return new PyTuple(getType(), args, Py.None, Py.None, iteritems()); } @Override This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2010-02-25 03:53:24
|
Revision: 6982 http://jython.svn.sourceforge.net/jython/?rev=6982&view=rev Author: thobes Date: 2010-02-25 03:53:18 +0000 (Thu, 25 Feb 2010) Log Message: ----------- Added an update/fix for the automatic coercion of PyFunction to single method interfaces. Modified Paths: -------------- trunk/jython/src/org/python/core/PyFunction.java Modified: trunk/jython/src/org/python/core/PyFunction.java =================================================================== --- trunk/jython/src/org/python/core/PyFunction.java 2010-02-22 22:55:30 UTC (rev 6981) +++ trunk/jython/src/org/python/core/PyFunction.java 2010-02-25 03:53:18 UTC (rev 6982) @@ -16,7 +16,7 @@ * A Python function. */ @ExposedType(name = "function", isBaseType = false, doc = BuiltinDocs.function_doc) -public class PyFunction extends PyObject { +public class PyFunction extends PyObject implements InvocationHandler { public static final PyType TYPE = PyType.fromClass(PyFunction.class); @@ -301,7 +301,7 @@ public PyObject __call__() { return __call__(Py.getThreadState()); } - + @Override public PyObject __call__(ThreadState state) { return func_code.call(state, func_globals, func_defaults, func_closure); @@ -311,7 +311,7 @@ public PyObject __call__(PyObject arg) { return __call__(Py.getThreadState(), arg); } - + @Override public PyObject __call__(ThreadState state, PyObject arg0) { return func_code.call(state, arg0, func_globals, func_defaults, func_closure); @@ -321,7 +321,7 @@ public PyObject __call__(PyObject arg1, PyObject arg2) { return __call__(Py.getThreadState(), arg1, arg2); } - + @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1) { return func_code.call(state, arg0, arg1, func_globals, func_defaults, func_closure); @@ -331,31 +331,31 @@ public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) { return __call__(Py.getThreadState(), arg1, arg2, arg3); } - + @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1, PyObject arg2) { return func_code.call(state, arg0, arg1, arg2, func_globals, func_defaults, func_closure); } - + @Override public PyObject __call__(PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3) { return __call__(Py.getThreadState(), arg0, arg1, arg2, arg3); } - + @Override public PyObject __call__(ThreadState state, PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3) { return func_code.call(state, arg0, arg1, arg2, arg3, func_globals, func_defaults, func_closure); } - + @Override public PyObject __call__(PyObject[] args) { return __call__(Py.getThreadState(), args); } - + @Override public PyObject __call__(ThreadState state, PyObject[] args) { return __call__(state, args, Py.NoKeywords); @@ -365,7 +365,7 @@ public PyObject __call__(PyObject[] args, String[] keywords) { return __call__(Py.getThreadState(), args, keywords); } - + @Override public PyObject __call__(ThreadState state, PyObject[] args, String[] keywords) { return function___call__(state, args, keywords); @@ -380,7 +380,7 @@ public PyObject __call__(PyObject arg1, PyObject[] args, String[] keywords) { return __call__(Py.getThreadState(), arg1, args, keywords); } - + @Override public PyObject __call__(ThreadState state, PyObject arg1, PyObject[] args, String[] keywords) { @@ -392,25 +392,56 @@ public String toString() { return String.format("<function %s at %s>", __name__, Py.idstr(this)); } - + @Override public Object __tojava__(Class<?> c) { // Automatically coerce to single method interfaces - if (c.isInterface() && c.getDeclaredMethods().length == 1) { - return Proxy.newProxyInstance(c.getClassLoader(), new Class[]{c}, new InvocationHandler() { - // XXX: not the most efficient implementation - the invocation handler could be shared - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if (args == null || args.length == 0) { - return __call__().__tojava__(method.getReturnType()); - } else { - return __call__(Py.javas2pys(args)).__tojava__(method.getReturnType()); + if (c.isInstance(this) && c != InvocationHandler.class) { + // for base types, conversion is simple - so don't wrap! + // InvocationHandler is special, since it's a single method interface + // that we implement, but if we coerce to it we want the arguments + return c.cast( this ); + } else if (c.isInterface()) { + if (c.getDeclaredMethods().length == 1 && c.getInterfaces().length == 0) { + // Proper single method interface + return proxy(c); + } else { + // Try coerce to interface with multiple overloaded versions of + // the same method (name) + String name = null; + for (Method method : c.getMethods()) { + if (method.getDeclaringClass() != Object.class) { + if (name == null || name.equals(method.getName())) { + name = method.getName(); + } else { + name = null; + break; + } } } - }); + if (name != null) { // single unique method name + return proxy(c); + } + } } - return super.__tojava__( c ); + return super.__tojava__(c); } + private Object proxy( Class<?> c ) { + return Proxy.newProxyInstance(c.getClassLoader(), new Class[]{c}, this); + } + + public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable { + // Handle invocation when invoked through Proxy (as coerced to single method interface) + if (method.getDeclaringClass() == Object.class) { + return method.invoke( this, args ); + } else if (args == null || args.length == 0) { + return __call__().__tojava__(method.getReturnType()); + } else { + return __call__(Py.javas2pys(args)).__tojava__(method.getReturnType()); + } + } + @Override public boolean isMappingType() { return false; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2010-02-22 22:55:36
|
Revision: 6981 http://jython.svn.sourceforge.net/jython/?rev=6981&view=rev Author: zyasoft Date: 2010-02-22 22:55:30 +0000 (Mon, 22 Feb 2010) Log Message: ----------- Fixed #1559 by refactoring time.strptime so it uses the same correct day of week conversion from Java's Calendar class Modified Paths: -------------- trunk/jython/src/org/python/modules/time/Time.java Modified: trunk/jython/src/org/python/modules/time/Time.java =================================================================== --- trunk/jython/src/org/python/modules/time/Time.java 2010-02-14 19:32:04 UTC (rev 6980) +++ trunk/jython/src/org/python/modules/time/Time.java 2010-02-22 22:55:30 UTC (rev 6981) @@ -255,26 +255,28 @@ throw Py.ValueError("timestamp out of range for platform time_t"); } cal.setTime(new Date((long)secs)); - // This call used to be needed to work around JVM bugs. - // It appears to break jdk1.2, so it's not removed. - // cal.clear(); - int dow = cal.get(Calendar.DAY_OF_WEEK)-2; - if (dow<0) - dow = dow+7; - // TBD: is this date dst? - boolean isdst = tz.inDaylightTime(cal.getTime()); + int isdst = tz.inDaylightTime(cal.getTime()) ? 1 : 0; + return toTimeTuple(cal, isdst); + } + + private static PyTimeTuple toTimeTuple(Calendar cal, int isdst) { + int dow = cal.get(Calendar.DAY_OF_WEEK) - 2; + if (dow < 0) { + dow += 7; + } return new PyTimeTuple(new PyInteger(cal.get(Calendar.YEAR)), - new PyInteger(cal.get(Calendar.MONTH)+1), - new PyInteger(cal.get(Calendar.DAY_OF_MONTH)), - new PyInteger(cal.get(Calendar.HOUR) + - 12*cal.get(Calendar.AM_PM)), - new PyInteger(cal.get(Calendar.MINUTE)), - new PyInteger(cal.get(Calendar.SECOND)), - new PyInteger(dow), - new PyInteger(cal.get(Calendar.DAY_OF_YEAR)), - new PyInteger(isdst ? 1 : 0)); + new PyInteger(cal.get(Calendar.MONTH) + 1), + new PyInteger(cal.get(Calendar.DAY_OF_MONTH)), + new PyInteger(cal.get(Calendar.HOUR) + + 12 * cal.get(Calendar.AM_PM)), + new PyInteger(cal.get(Calendar.MINUTE)), + new PyInteger(cal.get(Calendar.SECOND)), + new PyInteger(dow), + new PyInteger(cal.get(Calendar.DAY_OF_YEAR)), + new PyInteger(isdst)); } + /** * Convert a time argument that may be an optional float or None value to a * double. Throws a TypeError on failure. @@ -713,17 +715,7 @@ if (jformat.contains("zzz")) { isdst = cal.getTimeZone().inDaylightTime(cal.getTime()) ? 1 : 0; } - return new PyTuple(new PyObject[] { - new PyInteger(cal.get(Calendar.YEAR)), - new PyInteger(cal.get(Calendar.MONTH)+1), - new PyInteger(cal.get(Calendar.DAY_OF_MONTH)), - new PyInteger(cal.get(Calendar.HOUR) + 12*cal.get(Calendar.AM_PM)), - new PyInteger(cal.get(Calendar.MINUTE)), - new PyInteger(cal.get(Calendar.SECOND)), - new PyInteger((cal.get(Calendar.DAY_OF_WEEK)-2) % 7), // refactored for mon(0)-sun(6) - new PyInteger(cal.get(Calendar.DAY_OF_YEAR)), - new PyInteger(isdst) } - ); + return toTimeTuple(cal, isdst); } private static final String DEFAULT_FORMAT_PY = "%a %b %d %H:%M:%S %Y"; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-02-14 19:32:10
|
Revision: 6980 http://jython.svn.sourceforge.net/jython/?rev=6980&view=rev Author: pjenvey Date: 2010-02-14 19:32:04 +0000 (Sun, 14 Feb 2010) Log Message: ----------- oops, commit the real jar Modified Paths: -------------- trunk/jython/extlibs/jffi-x86_64-Linux.jar Modified: trunk/jython/extlibs/jffi-x86_64-Linux.jar =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-02-14 03:11:12
|
Revision: 6979 http://jython.svn.sourceforge.net/jython/?rev=6979&view=rev Author: pjenvey Date: 2010-02-14 03:11:06 +0000 (Sun, 14 Feb 2010) Log Message: ----------- use a Linux jffi stub built for older Linuxes (ubuntu dapper) fixes #1518 Modified Paths: -------------- trunk/jython/extlibs/jffi-x86_64-Linux.jar Modified: trunk/jython/extlibs/jffi-x86_64-Linux.jar =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-02-14 03:05:04
|
Revision: 6978 http://jython.svn.sourceforge.net/jython/?rev=6978&view=rev Author: pjenvey Date: 2010-02-14 03:04:57 +0000 (Sun, 14 Feb 2010) Log Message: ----------- unused imports Modified Paths: -------------- trunk/jython/src/org/python/core/util/FileUtil.java Modified: trunk/jython/src/org/python/core/util/FileUtil.java =================================================================== --- trunk/jython/src/org/python/core/util/FileUtil.java 2010-02-12 21:53:00 UTC (rev 6977) +++ trunk/jython/src/org/python/core/util/FileUtil.java 2010-02-14 03:04:57 UTC (rev 6978) @@ -2,14 +2,10 @@ package org.python.core.util; import java.io.ByteArrayOutputStream; -import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import org.python.core.imp; -import org.python.core.Py; -import org.python.core.PyException; import org.python.core.PyFile; /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wme...@us...> - 2010-02-12 21:53:07
|
Revision: 6977 http://jython.svn.sourceforge.net/jython/?rev=6977&view=rev Author: wmeissner Date: 2010-02-12 21:53:00 +0000 (Fri, 12 Feb 2010) Log Message: ----------- Fix issue #1554 ctypes module has no attribute '__version__' ctypes.__version__ is now 0.0.1 Modified Paths: -------------- trunk/jython/Lib/ctypes/__init__.py Modified: trunk/jython/Lib/ctypes/__init__.py =================================================================== --- trunk/jython/Lib/ctypes/__init__.py 2010-02-03 01:28:54 UTC (rev 6976) +++ trunk/jython/Lib/ctypes/__init__.py 2010-02-12 21:53:00 UTC (rev 6977) @@ -1,5 +1,7 @@ import jffi +__version__ = "0.0.1" + _TypeMap = { 'b': jffi.Type.BYTE, 'B': jffi.Type.UBYTE, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wme...@us...> - 2010-02-03 01:29:02
|
Revision: 6976 http://jython.svn.sourceforge.net/jython/?rev=6976&view=rev Author: wmeissner Date: 2010-02-03 01:28:54 +0000 (Wed, 03 Feb 2010) Log Message: ----------- Merge ctypes branch revisions r6701:6975 into trunk Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/src/org/python/modules/Setup.java Added Paths: ----------- trunk/jython/Lib/ctypes/ trunk/jython/Lib/ctypes/__init__.py trunk/jython/src/org/python/modules/jffi/ trunk/jython/src/org/python/modules/jffi/AbstractMemoryCData.java trunk/jython/src/org/python/modules/jffi/AllocatedDirectMemory.java trunk/jython/src/org/python/modules/jffi/AllocatedNativeMemory.java trunk/jython/src/org/python/modules/jffi/ArrayCData.java trunk/jython/src/org/python/modules/jffi/BasePointer.java trunk/jython/src/org/python/modules/jffi/BoundedNativeMemory.java trunk/jython/src/org/python/modules/jffi/ByReference.java trunk/jython/src/org/python/modules/jffi/CData.java trunk/jython/src/org/python/modules/jffi/CType.java trunk/jython/src/org/python/modules/jffi/DefaultInvokerFactory.java trunk/jython/src/org/python/modules/jffi/DirectMemory.java trunk/jython/src/org/python/modules/jffi/DynamicLibrary.java trunk/jython/src/org/python/modules/jffi/FastIntInvokerFactory.java trunk/jython/src/org/python/modules/jffi/Function.java trunk/jython/src/org/python/modules/jffi/HeapMemory.java trunk/jython/src/org/python/modules/jffi/InvalidMemory.java trunk/jython/src/org/python/modules/jffi/Invoker.java trunk/jython/src/org/python/modules/jffi/Memory.java trunk/jython/src/org/python/modules/jffi/MemoryOp.java trunk/jython/src/org/python/modules/jffi/NativeMemory.java trunk/jython/src/org/python/modules/jffi/NativeType.java trunk/jython/src/org/python/modules/jffi/NullMemory.java trunk/jython/src/org/python/modules/jffi/Pointer.java trunk/jython/src/org/python/modules/jffi/PointerCData.java trunk/jython/src/org/python/modules/jffi/ScalarCData.java trunk/jython/src/org/python/modules/jffi/StringCData.java trunk/jython/src/org/python/modules/jffi/StructLayout.java trunk/jython/src/org/python/modules/jffi/Structure.java trunk/jython/src/org/python/modules/jffi/Util.java trunk/jython/src/org/python/modules/jffi/jffi.java Removed Paths: ------------- trunk/jython/Lib/ctypes/__init__.py trunk/jython/src/org/python/modules/jffi/AbstractMemoryCData.java trunk/jython/src/org/python/modules/jffi/AllocatedDirectMemory.java trunk/jython/src/org/python/modules/jffi/AllocatedNativeMemory.java trunk/jython/src/org/python/modules/jffi/ArrayCData.java trunk/jython/src/org/python/modules/jffi/BasePointer.java trunk/jython/src/org/python/modules/jffi/BoundedNativeMemory.java trunk/jython/src/org/python/modules/jffi/ByReference.java trunk/jython/src/org/python/modules/jffi/CData.java trunk/jython/src/org/python/modules/jffi/CType.java trunk/jython/src/org/python/modules/jffi/DefaultInvokerFactory.java trunk/jython/src/org/python/modules/jffi/DirectMemory.java trunk/jython/src/org/python/modules/jffi/DynamicLibrary.java trunk/jython/src/org/python/modules/jffi/FastIntInvokerFactory.java trunk/jython/src/org/python/modules/jffi/Function.java trunk/jython/src/org/python/modules/jffi/HeapMemory.java trunk/jython/src/org/python/modules/jffi/InvalidMemory.java trunk/jython/src/org/python/modules/jffi/Invoker.java trunk/jython/src/org/python/modules/jffi/Memory.java trunk/jython/src/org/python/modules/jffi/MemoryOp.java trunk/jython/src/org/python/modules/jffi/NativeMemory.java trunk/jython/src/org/python/modules/jffi/NativeType.java trunk/jython/src/org/python/modules/jffi/NullMemory.java trunk/jython/src/org/python/modules/jffi/Pointer.java trunk/jython/src/org/python/modules/jffi/PointerCData.java trunk/jython/src/org/python/modules/jffi/ScalarCData.java trunk/jython/src/org/python/modules/jffi/StringCData.java trunk/jython/src/org/python/modules/jffi/StructLayout.java trunk/jython/src/org/python/modules/jffi/Structure.java trunk/jython/src/org/python/modules/jffi/Util.java trunk/jython/src/org/python/modules/jffi/jffi.java Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2010-02-03 00:30:00 UTC (rev 6975) +++ trunk/jython/CoreExposed.includes 2010-02-03 01:28:54 UTC (rev 6976) @@ -55,6 +55,22 @@ org/python/modules/_csv/PyWriter.class org/python/modules/_functools/PyPartial.class org/python/modules/_hashlib$Hash.class +org/python/modules/jffi/ArrayCData.class +org/python/modules/jffi/ByReference.class +org/python/modules/jffi/CData.class +org/python/modules/jffi/CType.class +org/python/modules/jffi/CType$Array.class +org/python/modules/jffi/CType$Pointer.class +org/python/modules/jffi/DynamicLibrary.class +org/python/modules/jffi/DynamicLibrary$Symbol.class +org/python/modules/jffi/Function.class +org/python/modules/jffi/PointerCData.class +org/python/modules/jffi/Structure.class +org/python/modules/jffi/ScalarCData.class +org/python/modules/jffi/StringCData.class +org/python/modules/jffi/StructLayout.class +org/python/modules/jffi/StructLayout$Field.class +org/python/modules/jffi/StructLayout$ScalarField.class org/python/modules/_threading/Condition.class org/python/modules/_threading/Lock.class org/python/modules/_weakref/CallableProxyType.class Property changes on: trunk/jython/Lib/ctypes ___________________________________________________________________ Added: svn:ignore + *.class Deleted: trunk/jython/Lib/ctypes/__init__.py =================================================================== --- branches/ctypes-jffi/Lib/ctypes/__init__.py 2010-02-03 00:30:00 UTC (rev 6975) +++ trunk/jython/Lib/ctypes/__init__.py 2010-02-03 01:28:54 UTC (rev 6976) @@ -1,289 +0,0 @@ -import jffi - -_TypeMap = { - 'b': jffi.Type.BYTE, - 'B': jffi.Type.UBYTE, - 'h': jffi.Type.SHORT, - 'H': jffi.Type.USHORT, - 'i': jffi.Type.INT, - 'I': jffi.Type.UINT, - 'l': jffi.Type.LONG, - 'L': jffi.Type.ULONG, - 'q': jffi.Type.LONGLONG, - 'Q': jffi.Type.ULONGLONG, - 'f': jffi.Type.FLOAT, - 'd': jffi.Type.DOUBLE, - '?': jffi.Type.BOOL, - 'z': jffi.Type.STRING, - 'P': jffi.Type.POINTER -} - -class _CTypeMetaClass(type): - - def __new__(cls, name, bases, dict): - return type.__new__(cls, name, bases, dict) - - def __mul__(self, len): - dict = { '_jffi_type': jffi.Type.Array(self, len) } - - # Look back up the stack frame to find out the module this new type is declared in - import inspect - mod = inspect.getmodule(inspect.stack()[1][0]) - if mod is None: - name = "__main__" - else: - name = mod.__name__ - dict["__module__"] = name - return type("%s_Array_%d" % (self.__name__, len), (jffi.ArrayCData, _ArrayCData, _CData), dict) - -class _CData(object): - @classmethod - def in_dll(self, lib, name): - return self.from_address(lib[name]) - - @classmethod - def size(self): - return self._jffi_type.size() - -class _ScalarCData(jffi.ScalarCData, _CData): - __metaclass__ = _CTypeMetaClass - - -class _ArrayCData(object): - def __len__(self): - return self._jffi_type.length - -class _StructLayoutBuilder(object): - def __init__(self, union = False): - self.size = 0 - self.offset = 0 - self.fields = [] - self.union = union - - def align(self, offset, align): - return align + ((offset - 1) & ~(align - 1)); - - def add_fields(self, fields): - for f in fields: - self.add_field(f) - return self - - def add_field(self, f): - if not issubclass(f[1], _ScalarCData): - raise RuntimeError("non-scalar fields not supported") - - if len(f) != 2: - raise RuntimeError("structs with bitfields not supported") - - self.offset = self.align(self.offset, alignment(f[1])) - self.fields.append(jffi.StructLayout.ScalarField(f[0], f[1], self.offset)) - if not self.union: - self.offset += sizeof(f[1]) - self.size = max(self.offset, sizeof(f[1])) - - return self - - def build(self): - return jffi.StructLayout(fields = self.fields, union = self.union) - -class _AggregateMetaClass(type): - @staticmethod - def __new_aggregate__(cls, name, bases, dict, union = False): - if dict.has_key('_fields_'): - layout = dict['_jffi_type'] = _StructLayoutBuilder(union).add_fields(dict['_fields_']).build() - # make all fields accessible via .foo - for f in dict['_fields_']: - dict[f[0]] = layout[f[0]] - dict['__fields_'] = dict['_fields_'] - else: - dict['__fields_'] = [] - if dict.has_key('_pack_'): - raise NotImplementedError("struct packing not implemented") - if dict.has_key('_anonymous_'): - raise NotImplementedError("anonymous fields not implemented") - - return type.__new__(cls, name, bases, dict) - - def get_fields(self): - return self.__fields_ - - def set_fields(self, fields): - layout = _StructLayoutBuilder(union = issubclass(Union, self)).add_fields(fields).build() - self.__fields_ = fields - self._jffi_type = layout - # make all fields accessible via .foo - for f in fields: - setattr(self, f[0], layout[f[0]]) - - _fields_ = property(get_fields, set_fields) - # Make _pack_ and _anonymous_ throw errors if anyone tries to use them - _pack_ = property(None) - _anonymous_ = property(None) - -class _StructMetaClass(_AggregateMetaClass): - def __new__(cls, name, bases, dict): - return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = False) - -class _UnionMetaClass(_AggregateMetaClass): - def __new__(cls, name, bases, dict): - return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = True) - -class Structure(jffi.Structure, _CData): - __metaclass__ = _StructMetaClass - -class Union(jffi.Structure, _CData): - __metaclass__ = _UnionMetaClass - -def sizeof(type): - if hasattr(type, '_jffi_type'): - return type._jffi_type.size() - else: - raise TypeError("this type has no size") - -def alignment(type): - return type._jffi_type.alignment() - -def addressof(cdata): - return cdata.address() - -def byref(cdata, offset = 0): - return cdata.byref(offset) - -def pointer(cdata): - return cdata.pointer(POINTER(cdata.__class__)) - -memmove = jffi.memmove -memset = jffi.memset - -_pointer_type_cache = {} -def POINTER(ctype): - # If a pointer class for the C type has been created, re-use it - if _pointer_type_cache.has_key(ctype): - return _pointer_type_cache[ctype] - - # Create a new class for this particular C type - dict = { '_jffi_type': jffi.Type.Pointer(ctype) } - # Look back up the stack frame to find out the module this new type is declared in - import inspect - mod = inspect.getmodule(inspect.stack()[1][0]) - if mod is None: - name = "__main__" - else: - name = mod.__name__ - dict["__module__"] = name - - ptype = type("LP_%s" % (ctype.__name__,), (jffi.PointerCData, _CData), dict) - _pointer_type_cache[ctype] = ptype - return ptype - -class c_bool(_ScalarCData): - _type_ = '?' - _jffi_type = jffi.Type.BOOL - -class c_byte(_ScalarCData): - _type_ = 'b' - _jffi_type = jffi.Type.BYTE - -class c_ubyte(_ScalarCData): - _type_ = 'B' - _jffi_type = jffi.Type.UBYTE - -class c_short(_ScalarCData): - _type_ = 'h' - _jffi_type = jffi.Type.SHORT - -class c_ushort(_ScalarCData): - _type_ = 'H' - _jffi_type = jffi.Type.USHORT - -class c_int(_ScalarCData): - _type_ = 'i' - _jffi_type = jffi.Type.INT - -class c_uint(_ScalarCData): - _type_ = 'I' - _jffi_type = jffi.Type.UINT - -class c_longlong(_ScalarCData): - _type_ = 'q' - _jffi_type = jffi.Type.LONGLONG - -class c_ulonglong(_ScalarCData): - _type_ = 'Q' - _jffi_type = jffi.Type.ULONGLONG - -class c_long(_ScalarCData): - _type_ = 'l' - _jffi_type = jffi.Type.LONG - -class c_ulong(_ScalarCData): - _type_ = 'L' - _jffi_type = jffi.Type.ULONG - -class c_float(_ScalarCData): - _type_ = 'f' - _jffi_type = jffi.Type.FLOAT - -class c_double(_ScalarCData): - _type_ = 'd' - _jffi_type = jffi.Type.DOUBLE - -c_int8 = c_byte -c_uint8 = c_ubyte -c_int16 = c_short -c_uint16 = c_ushort -c_int32 = c_int -c_uint32 = c_uint -c_int64 = c_longlong -c_uint64 = c_ulonglong - -c_size_t = c_ulong -c_ssize_t = c_long - -class c_char_p(jffi.StringCData, _CData): - _type_ = 'z' - _jffi_type = jffi.Type.STRING - -class c_void_p(_ScalarCData): - _type_ = 'P' - _jffi_type = jffi.Type.POINTER - -class _Function(jffi.Function): - _restype = c_int - _argtypes = None - - -class CDLL: - DEFAULT_MODE = jffi.RTLD_GLOBAL | jffi.RTLD_LAZY - - def __init__(self, name, mode = DEFAULT_MODE, handle = None): - self._handle = jffi.dlopen(name, mode) - - def __getattr__(self, name): - if name.startswith('__') and name.endswith('__'): - raise AttributeError, name - func = self.__getitem__(name) - setattr(self, name, func) - return func - - def __getitem__(self, name): - return _Function(self._handle.find_symbol(name)) - -class LibraryLoader(object): - def __init__(self, dlltype): - self._dlltype = dlltype - - def __getattr__(self, name): - if name[0] == '_': - raise AttributeError(name) - dll = self._dlltype(name) - setattr(self, name, dll) - return dll - - def __getitem__(self, name): - return getattr(self, name) - - def LoadLibrary(self, name): - return self._dlltype(name) - -cdll = LibraryLoader(CDLL) Copied: trunk/jython/Lib/ctypes/__init__.py (from rev 6975, branches/ctypes-jffi/Lib/ctypes/__init__.py) =================================================================== --- trunk/jython/Lib/ctypes/__init__.py (rev 0) +++ trunk/jython/Lib/ctypes/__init__.py 2010-02-03 01:28:54 UTC (rev 6976) @@ -0,0 +1,289 @@ +import jffi + +_TypeMap = { + 'b': jffi.Type.BYTE, + 'B': jffi.Type.UBYTE, + 'h': jffi.Type.SHORT, + 'H': jffi.Type.USHORT, + 'i': jffi.Type.INT, + 'I': jffi.Type.UINT, + 'l': jffi.Type.LONG, + 'L': jffi.Type.ULONG, + 'q': jffi.Type.LONGLONG, + 'Q': jffi.Type.ULONGLONG, + 'f': jffi.Type.FLOAT, + 'd': jffi.Type.DOUBLE, + '?': jffi.Type.BOOL, + 'z': jffi.Type.STRING, + 'P': jffi.Type.POINTER +} + +class _CTypeMetaClass(type): + + def __new__(cls, name, bases, dict): + return type.__new__(cls, name, bases, dict) + + def __mul__(self, len): + dict = { '_jffi_type': jffi.Type.Array(self, len) } + + # Look back up the stack frame to find out the module this new type is declared in + import inspect + mod = inspect.getmodule(inspect.stack()[1][0]) + if mod is None: + name = "__main__" + else: + name = mod.__name__ + dict["__module__"] = name + return type("%s_Array_%d" % (self.__name__, len), (jffi.ArrayCData, _ArrayCData, _CData), dict) + +class _CData(object): + @classmethod + def in_dll(self, lib, name): + return self.from_address(lib[name]) + + @classmethod + def size(self): + return self._jffi_type.size() + +class _ScalarCData(jffi.ScalarCData, _CData): + __metaclass__ = _CTypeMetaClass + + +class _ArrayCData(object): + def __len__(self): + return self._jffi_type.length + +class _StructLayoutBuilder(object): + def __init__(self, union = False): + self.size = 0 + self.offset = 0 + self.fields = [] + self.union = union + + def align(self, offset, align): + return align + ((offset - 1) & ~(align - 1)); + + def add_fields(self, fields): + for f in fields: + self.add_field(f) + return self + + def add_field(self, f): + if not issubclass(f[1], _ScalarCData): + raise RuntimeError("non-scalar fields not supported") + + if len(f) != 2: + raise RuntimeError("structs with bitfields not supported") + + self.offset = self.align(self.offset, alignment(f[1])) + self.fields.append(jffi.StructLayout.ScalarField(f[0], f[1], self.offset)) + if not self.union: + self.offset += sizeof(f[1]) + self.size = max(self.offset, sizeof(f[1])) + + return self + + def build(self): + return jffi.StructLayout(fields = self.fields, union = self.union) + +class _AggregateMetaClass(type): + @staticmethod + def __new_aggregate__(cls, name, bases, dict, union = False): + if dict.has_key('_fields_'): + layout = dict['_jffi_type'] = _StructLayoutBuilder(union).add_fields(dict['_fields_']).build() + # make all fields accessible via .foo + for f in dict['_fields_']: + dict[f[0]] = layout[f[0]] + dict['__fields_'] = dict['_fields_'] + else: + dict['__fields_'] = [] + if dict.has_key('_pack_'): + raise NotImplementedError("struct packing not implemented") + if dict.has_key('_anonymous_'): + raise NotImplementedError("anonymous fields not implemented") + + return type.__new__(cls, name, bases, dict) + + def get_fields(self): + return self.__fields_ + + def set_fields(self, fields): + layout = _StructLayoutBuilder(union = issubclass(Union, self)).add_fields(fields).build() + self.__fields_ = fields + self._jffi_type = layout + # make all fields accessible via .foo + for f in fields: + setattr(self, f[0], layout[f[0]]) + + _fields_ = property(get_fields, set_fields) + # Make _pack_ and _anonymous_ throw errors if anyone tries to use them + _pack_ = property(None) + _anonymous_ = property(None) + +class _StructMetaClass(_AggregateMetaClass): + def __new__(cls, name, bases, dict): + return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = False) + +class _UnionMetaClass(_AggregateMetaClass): + def __new__(cls, name, bases, dict): + return _AggregateMetaClass.__new_aggregate__(cls, name, bases, dict, union = True) + +class Structure(jffi.Structure, _CData): + __metaclass__ = _StructMetaClass + +class Union(jffi.Structure, _CData): + __metaclass__ = _UnionMetaClass + +def sizeof(type): + if hasattr(type, '_jffi_type'): + return type._jffi_type.size() + else: + raise TypeError("this type has no size") + +def alignment(type): + return type._jffi_type.alignment() + +def addressof(cdata): + return cdata.address() + +def byref(cdata, offset = 0): + return cdata.byref(offset) + +def pointer(cdata): + return cdata.pointer(POINTER(cdata.__class__)) + +memmove = jffi.memmove +memset = jffi.memset + +_pointer_type_cache = {} +def POINTER(ctype): + # If a pointer class for the C type has been created, re-use it + if _pointer_type_cache.has_key(ctype): + return _pointer_type_cache[ctype] + + # Create a new class for this particular C type + dict = { '_jffi_type': jffi.Type.Pointer(ctype) } + # Look back up the stack frame to find out the module this new type is declared in + import inspect + mod = inspect.getmodule(inspect.stack()[1][0]) + if mod is None: + name = "__main__" + else: + name = mod.__name__ + dict["__module__"] = name + + ptype = type("LP_%s" % (ctype.__name__,), (jffi.PointerCData, _CData), dict) + _pointer_type_cache[ctype] = ptype + return ptype + +class c_bool(_ScalarCData): + _type_ = '?' + _jffi_type = jffi.Type.BOOL + +class c_byte(_ScalarCData): + _type_ = 'b' + _jffi_type = jffi.Type.BYTE + +class c_ubyte(_ScalarCData): + _type_ = 'B' + _jffi_type = jffi.Type.UBYTE + +class c_short(_ScalarCData): + _type_ = 'h' + _jffi_type = jffi.Type.SHORT + +class c_ushort(_ScalarCData): + _type_ = 'H' + _jffi_type = jffi.Type.USHORT + +class c_int(_ScalarCData): + _type_ = 'i' + _jffi_type = jffi.Type.INT + +class c_uint(_ScalarCData): + _type_ = 'I' + _jffi_type = jffi.Type.UINT + +class c_longlong(_ScalarCData): + _type_ = 'q' + _jffi_type = jffi.Type.LONGLONG + +class c_ulonglong(_ScalarCData): + _type_ = 'Q' + _jffi_type = jffi.Type.ULONGLONG + +class c_long(_ScalarCData): + _type_ = 'l' + _jffi_type = jffi.Type.LONG + +class c_ulong(_ScalarCData): + _type_ = 'L' + _jffi_type = jffi.Type.ULONG + +class c_float(_ScalarCData): + _type_ = 'f' + _jffi_type = jffi.Type.FLOAT + +class c_double(_ScalarCData): + _type_ = 'd' + _jffi_type = jffi.Type.DOUBLE + +c_int8 = c_byte +c_uint8 = c_ubyte +c_int16 = c_short +c_uint16 = c_ushort +c_int32 = c_int +c_uint32 = c_uint +c_int64 = c_longlong +c_uint64 = c_ulonglong + +c_size_t = c_ulong +c_ssize_t = c_long + +class c_char_p(jffi.StringCData, _CData): + _type_ = 'z' + _jffi_type = jffi.Type.STRING + +class c_void_p(_ScalarCData): + _type_ = 'P' + _jffi_type = jffi.Type.POINTER + +class _Function(jffi.Function): + _restype = c_int + _argtypes = None + + +class CDLL: + DEFAULT_MODE = jffi.RTLD_GLOBAL | jffi.RTLD_LAZY + + def __init__(self, name, mode = DEFAULT_MODE, handle = None): + self._handle = jffi.dlopen(name, mode) + + def __getattr__(self, name): + if name.startswith('__') and name.endswith('__'): + raise AttributeError, name + func = self.__getitem__(name) + setattr(self, name, func) + return func + + def __getitem__(self, name): + return _Function(self._handle.find_symbol(name)) + +class LibraryLoader(object): + def __init__(self, dlltype): + self._dlltype = dlltype + + def __getattr__(self, name): + if name[0] == '_': + raise AttributeError(name) + dll = self._dlltype(name) + setattr(self, name, dll) + return dll + + def __getitem__(self, name): + return getattr(self, name) + + def LoadLibrary(self, name): + return self._dlltype(name) + +cdll = LibraryLoader(CDLL) Modified: trunk/jython/src/org/python/modules/Setup.java =================================================================== --- trunk/jython/src/org/python/modules/Setup.java 2010-02-03 00:30:00 UTC (rev 6975) +++ trunk/jython/src/org/python/modules/Setup.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -59,6 +59,7 @@ "_ast:org.python.antlr.ast.AstModule", "_marshal", "_threading:org.python.modules._threading._threading", - PosixModule.getOSName() + ":org.python.modules.posix.PosixModule" + PosixModule.getOSName() + ":org.python.modules.posix.PosixModule", + "jffi:org.python.modules.jffi.jffi" }; } Deleted: trunk/jython/src/org/python/modules/jffi/AbstractMemoryCData.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/AbstractMemoryCData.java 2010-02-03 00:30:00 UTC (rev 6975) +++ trunk/jython/src/org/python/modules/jffi/AbstractMemoryCData.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -1,25 +0,0 @@ - -package org.python.modules.jffi; - -import org.python.core.PyType; - -public abstract class AbstractMemoryCData extends CData implements Pointer { - protected DirectMemory memory; - - AbstractMemoryCData(PyType subtype, CType type, DirectMemory memory) { - super(subtype, type); - this.memory = memory; - } - @Override - public boolean __nonzero__() { - return !getMemory().isNull(); - } - - protected void initReferenceMemory(Memory m) { - m.putAddress(0, memory); - } - - public final DirectMemory getMemory() { - return hasReferenceMemory() ? getReferenceMemory().getMemory(0) : memory; - } -} Copied: trunk/jython/src/org/python/modules/jffi/AbstractMemoryCData.java (from rev 6975, branches/ctypes-jffi/src/org/python/modules/jffi/AbstractMemoryCData.java) =================================================================== --- trunk/jython/src/org/python/modules/jffi/AbstractMemoryCData.java (rev 0) +++ trunk/jython/src/org/python/modules/jffi/AbstractMemoryCData.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -0,0 +1,25 @@ + +package org.python.modules.jffi; + +import org.python.core.PyType; + +public abstract class AbstractMemoryCData extends CData implements Pointer { + protected DirectMemory memory; + + AbstractMemoryCData(PyType subtype, CType type, DirectMemory memory) { + super(subtype, type); + this.memory = memory; + } + @Override + public boolean __nonzero__() { + return !getMemory().isNull(); + } + + protected void initReferenceMemory(Memory m) { + m.putAddress(0, memory); + } + + public final DirectMemory getMemory() { + return hasReferenceMemory() ? getReferenceMemory().getMemory(0) : memory; + } +} Deleted: trunk/jython/src/org/python/modules/jffi/AllocatedDirectMemory.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/AllocatedDirectMemory.java 2010-02-03 00:30:00 UTC (rev 6975) +++ trunk/jython/src/org/python/modules/jffi/AllocatedDirectMemory.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -1,7 +0,0 @@ - -package org.python.modules.jffi; - -public interface AllocatedDirectMemory extends DirectMemory { - public void free(); - public void setAutoRelease(boolean autorelease); -} Copied: trunk/jython/src/org/python/modules/jffi/AllocatedDirectMemory.java (from rev 6975, branches/ctypes-jffi/src/org/python/modules/jffi/AllocatedDirectMemory.java) =================================================================== --- trunk/jython/src/org/python/modules/jffi/AllocatedDirectMemory.java (rev 0) +++ trunk/jython/src/org/python/modules/jffi/AllocatedDirectMemory.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -0,0 +1,7 @@ + +package org.python.modules.jffi; + +public interface AllocatedDirectMemory extends DirectMemory { + public void free(); + public void setAutoRelease(boolean autorelease); +} Deleted: trunk/jython/src/org/python/modules/jffi/AllocatedNativeMemory.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/AllocatedNativeMemory.java 2010-02-03 00:30:00 UTC (rev 6975) +++ trunk/jython/src/org/python/modules/jffi/AllocatedNativeMemory.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -1,67 +0,0 @@ - -package org.python.modules.jffi; - -import org.python.core.Py; - -class AllocatedNativeMemory extends BoundedNativeMemory implements AllocatedDirectMemory { - private volatile boolean released = false; - private volatile boolean autorelease = true; - - /** The real memory address */ - private final long storage; - - /** - * Allocates native memory - * - * @param size The number of bytes to allocate - * @param clear Whether the memory should be cleared (zeroed) - * @return A new {@link AllocatedDirectMemory} - */ - static final AllocatedNativeMemory allocate(int size, boolean clear) { - return allocateAligned(size, 1, clear); - } - - /** - * Allocates native memory, aligned to a minimum boundary. - * - * @param size The number of bytes to allocate - * @param align The minimum alignment of the memory - * @param clear Whether the memory should be cleared (zeroed) - * @return A new {@link AllocatedDirectMemory} - */ - static final AllocatedNativeMemory allocateAligned(int size, int align, boolean clear) { - long memory = IO.allocateMemory(size + align - 1, clear); - if (memory == 0) { - throw Py.RuntimeError("failed to allocate " + size + " bytes"); - } - return new AllocatedNativeMemory(memory, size, align); - } - - private AllocatedNativeMemory(long address, int size, int align) { - super(((address - 1) & ~(align - 1)) + align, size); - this.storage = address; - } - - public void free() { - if (!released) { - IO.freeMemory(storage); - released = true; - } - } - - public void setAutoRelease(boolean release) { - this.autorelease = release; - } - - @Override - protected void finalize() throws Throwable { - try { - if (!released && autorelease) { - IO.freeMemory(storage); - released = true; - } - } finally { - super.finalize(); - } - } -} Copied: trunk/jython/src/org/python/modules/jffi/AllocatedNativeMemory.java (from rev 6975, branches/ctypes-jffi/src/org/python/modules/jffi/AllocatedNativeMemory.java) =================================================================== --- trunk/jython/src/org/python/modules/jffi/AllocatedNativeMemory.java (rev 0) +++ trunk/jython/src/org/python/modules/jffi/AllocatedNativeMemory.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -0,0 +1,67 @@ + +package org.python.modules.jffi; + +import org.python.core.Py; + +class AllocatedNativeMemory extends BoundedNativeMemory implements AllocatedDirectMemory { + private volatile boolean released = false; + private volatile boolean autorelease = true; + + /** The real memory address */ + private final long storage; + + /** + * Allocates native memory + * + * @param size The number of bytes to allocate + * @param clear Whether the memory should be cleared (zeroed) + * @return A new {@link AllocatedDirectMemory} + */ + static final AllocatedNativeMemory allocate(int size, boolean clear) { + return allocateAligned(size, 1, clear); + } + + /** + * Allocates native memory, aligned to a minimum boundary. + * + * @param size The number of bytes to allocate + * @param align The minimum alignment of the memory + * @param clear Whether the memory should be cleared (zeroed) + * @return A new {@link AllocatedDirectMemory} + */ + static final AllocatedNativeMemory allocateAligned(int size, int align, boolean clear) { + long memory = IO.allocateMemory(size + align - 1, clear); + if (memory == 0) { + throw Py.RuntimeError("failed to allocate " + size + " bytes"); + } + return new AllocatedNativeMemory(memory, size, align); + } + + private AllocatedNativeMemory(long address, int size, int align) { + super(((address - 1) & ~(align - 1)) + align, size); + this.storage = address; + } + + public void free() { + if (!released) { + IO.freeMemory(storage); + released = true; + } + } + + public void setAutoRelease(boolean release) { + this.autorelease = release; + } + + @Override + protected void finalize() throws Throwable { + try { + if (!released && autorelease) { + IO.freeMemory(storage); + released = true; + } + } finally { + super.finalize(); + } + } +} Deleted: trunk/jython/src/org/python/modules/jffi/ArrayCData.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/ArrayCData.java 2010-02-03 00:30:00 UTC (rev 6975) +++ trunk/jython/src/org/python/modules/jffi/ArrayCData.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -1,175 +0,0 @@ - -package org.python.modules.jffi; - -import org.python.core.Py; -import org.python.core.PyIterator; -import org.python.core.PyList; -import org.python.core.PyNewWrapper; -import org.python.core.PyObject; -import org.python.core.PySequenceList; -import org.python.core.PyType; -import org.python.core.SequenceIndexDelegate; -import org.python.expose.ExposedClassMethod; -import org.python.expose.ExposedNew; -import org.python.expose.ExposedType; - -@ExposedType(name = "jffi.ArrayCData", base = CData.class) -public class ArrayCData extends CData implements Pointer { - public static final PyType TYPE = PyType.fromClass(ArrayCData.class); - - final CType.Array arrayType; - final CType componentType; - final MemoryOp componentMemoryOp; - - ArrayCData(PyType subtype, CType.Array arrayType, DirectMemory memory, MemoryOp componentMemoryOp) { - super(subtype, arrayType, memory); - this.arrayType = arrayType; - this.componentType = arrayType.componentType; - this.componentMemoryOp = componentMemoryOp; - } - - @ExposedNew - public static PyObject ArrayCData_new(PyNewWrapper new_, boolean init, PyType subtype, - PyObject[] args, String[] keywords) { - - CType.Array arrayType = getArrayType(subtype); - - // Only clear the array if it is not going to be completely filled - boolean clear = args.length < arrayType.length; - DirectMemory memory = AllocatedNativeMemory.allocateAligned(arrayType.componentType.size() * arrayType.length, - arrayType.componentType.alignment(), clear); - int offset = 0; - for (PyObject value : args) { - arrayType.componentMemoryOp.put(memory, offset, value); - offset += arrayType.componentType.size(); - } - return new ArrayCData(subtype, arrayType, memory, arrayType.componentMemoryOp); - } - - static final CType.Array getArrayType(PyType subtype) { - PyObject jffi_type = subtype.__getattr__("_jffi_type"); - - if (!(jffi_type instanceof CType.Array)) { - throw Py.TypeError("invalid _jffi_type for " + subtype.getName()); - } - - return (CType.Array) jffi_type; - } - - @ExposedClassMethod(names= { "from_address" }) - public static final PyObject from_address(PyType subtype, PyObject address) { - - CType.Array arrayType = getArrayType(subtype); - DirectMemory m = Util.getMemoryForAddress(address); - PointerCData cdata = new PointerCData(subtype, arrayType, m.getMemory(0), arrayType.componentMemoryOp); - cdata.setReferenceMemory(m); - - return cdata; - } - - public final DirectMemory getMemory() { - return getReferenceMemory(); - } - - protected final void initReferenceMemory(Memory m) { - // Nothing to do, since the reference memory was initialized during construction - } - - @Override - public PyObject __finditem__(int index) { - return delegator.checkIdxAndFindItem(index); - } - - @Override - public PyObject __getitem__(PyObject index) { - return delegator.checkIdxAndGetItem(index); - } - - @Override - public void __setitem__(int index, PyObject value) { - delegator.checkIdxAndSetItem(index, value); - } - - @Override - public void __setitem__(PyObject index, PyObject value) { - delegator.checkIdxAndSetItem(index, value); - } - - @Override - public void __delitem__(PyObject key) { - throw Py.TypeError("Array does not support item deletion"); - } - - - @Override - public PyObject __iter__() { - return new ArrayIter(); - } - - protected final SequenceIndexDelegate delegator = new SequenceIndexDelegate() { - - @Override - public String getTypeName() { - return getType().fastGetName(); - } - - @Override - public void setItem(int idx, PyObject value) { - componentMemoryOp.put(getReferenceMemory(), idx * componentType.size(), value); - } - - @Override - public void setSlice(int start, int stop, int step, PyObject value) { - if (!(value instanceof PySequenceList)) { - throw Py.TypeError("expected list or tuple"); - } - PySequenceList list = (PySequenceList) value; - for (int i = 0; i < stop - start; ++i) { - setItem(start + i, list.pyget(i)); - } - } - - @Override - public int len() { - return arrayType.length; - } - - @Override - public void delItem(int idx) { - throw Py.TypeError("Array does not support item deletion"); - } - - @Override - public void delItems(int start, int stop) { - throw Py.TypeError("Array does not support item deletion"); - } - - - @Override - public PyObject getItem(int idx) { - return componentMemoryOp.get(getReferenceMemory(), idx * componentType.size()); - } - - @Override - public PyObject getSlice(int start, int stop, int step) { - PyObject[] result = new PyObject[stop - start]; - for (int i = 0; i < result.length; ++i) { - result[i] = getItem(start + i); - } - return new PyList(result); - } - }; - - public class ArrayIter extends PyIterator { - - private int index = 0; - - public PyObject __iternext__() { - if (index >= arrayType.length) { - return null; - } - return componentMemoryOp.get(getReferenceMemory(), index++ * componentType.size()); - } - } - -} Copied: trunk/jython/src/org/python/modules/jffi/ArrayCData.java (from rev 6975, branches/ctypes-jffi/src/org/python/modules/jffi/ArrayCData.java) =================================================================== --- trunk/jython/src/org/python/modules/jffi/ArrayCData.java (rev 0) +++ trunk/jython/src/org/python/modules/jffi/ArrayCData.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -0,0 +1,175 @@ + +package org.python.modules.jffi; + +import org.python.core.Py; +import org.python.core.PyIterator; +import org.python.core.PyList; +import org.python.core.PyNewWrapper; +import org.python.core.PyObject; +import org.python.core.PySequenceList; +import org.python.core.PyType; +import org.python.core.SequenceIndexDelegate; +import org.python.expose.ExposedClassMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedType; + +@ExposedType(name = "jffi.ArrayCData", base = CData.class) +public class ArrayCData extends CData implements Pointer { + public static final PyType TYPE = PyType.fromClass(ArrayCData.class); + + final CType.Array arrayType; + final CType componentType; + final MemoryOp componentMemoryOp; + + ArrayCData(PyType subtype, CType.Array arrayType, DirectMemory memory, MemoryOp componentMemoryOp) { + super(subtype, arrayType, memory); + this.arrayType = arrayType; + this.componentType = arrayType.componentType; + this.componentMemoryOp = componentMemoryOp; + } + + @ExposedNew + public static PyObject ArrayCData_new(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { + + CType.Array arrayType = getArrayType(subtype); + + // Only clear the array if it is not going to be completely filled + boolean clear = args.length < arrayType.length; + DirectMemory memory = AllocatedNativeMemory.allocateAligned(arrayType.componentType.size() * arrayType.length, + arrayType.componentType.alignment(), clear); + int offset = 0; + for (PyObject value : args) { + arrayType.componentMemoryOp.put(memory, offset, value); + offset += arrayType.componentType.size(); + } + return new ArrayCData(subtype, arrayType, memory, arrayType.componentMemoryOp); + } + + static final CType.Array getArrayType(PyType subtype) { + PyObject jffi_type = subtype.__getattr__("_jffi_type"); + + if (!(jffi_type instanceof CType.Array)) { + throw Py.TypeError("invalid _jffi_type for " + subtype.getName()); + } + + return (CType.Array) jffi_type; + } + + @ExposedClassMethod(names= { "from_address" }) + public static final PyObject from_address(PyType subtype, PyObject address) { + + CType.Array arrayType = getArrayType(subtype); + DirectMemory m = Util.getMemoryForAddress(address); + PointerCData cdata = new PointerCData(subtype, arrayType, m.getMemory(0), arrayType.componentMemoryOp); + cdata.setReferenceMemory(m); + + return cdata; + } + + public final DirectMemory getMemory() { + return getReferenceMemory(); + } + + protected final void initReferenceMemory(Memory m) { + // Nothing to do, since the reference memory was initialized during construction + } + + @Override + public PyObject __finditem__(int index) { + return delegator.checkIdxAndFindItem(index); + } + + @Override + public PyObject __getitem__(PyObject index) { + return delegator.checkIdxAndGetItem(index); + } + + @Override + public void __setitem__(int index, PyObject value) { + delegator.checkIdxAndSetItem(index, value); + } + + @Override + public void __setitem__(PyObject index, PyObject value) { + delegator.checkIdxAndSetItem(index, value); + } + + @Override + public void __delitem__(PyObject key) { + throw Py.TypeError("Array does not support item deletion"); + } + + + @Override + public PyObject __iter__() { + return new ArrayIter(); + } + + protected final SequenceIndexDelegate delegator = new SequenceIndexDelegate() { + + @Override + public String getTypeName() { + return getType().fastGetName(); + } + + @Override + public void setItem(int idx, PyObject value) { + componentMemoryOp.put(getReferenceMemory(), idx * componentType.size(), value); + } + + @Override + public void setSlice(int start, int stop, int step, PyObject value) { + if (!(value instanceof PySequenceList)) { + throw Py.TypeError("expected list or tuple"); + } + PySequenceList list = (PySequenceList) value; + for (int i = 0; i < stop - start; ++i) { + setItem(start + i, list.pyget(i)); + } + } + + @Override + public int len() { + return arrayType.length; + } + + @Override + public void delItem(int idx) { + throw Py.TypeError("Array does not support item deletion"); + } + + @Override + public void delItems(int start, int stop) { + throw Py.TypeError("Array does not support item deletion"); + } + + + @Override + public PyObject getItem(int idx) { + return componentMemoryOp.get(getReferenceMemory(), idx * componentType.size()); + } + + @Override + public PyObject getSlice(int start, int stop, int step) { + PyObject[] result = new PyObject[stop - start]; + for (int i = 0; i < result.length; ++i) { + result[i] = getItem(start + i); + } + return new PyList(result); + } + }; + + public class ArrayIter extends PyIterator { + + private int index = 0; + + public PyObject __iternext__() { + if (index >= arrayType.length) { + return null; + } + return componentMemoryOp.get(getReferenceMemory(), index++ * componentType.size()); + } + } + +} Deleted: trunk/jython/src/org/python/modules/jffi/BasePointer.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/BasePointer.java 2010-02-03 00:30:00 UTC (rev 6975) +++ trunk/jython/src/org/python/modules/jffi/BasePointer.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -1,33 +0,0 @@ -package org.python.modules.jffi; - -import org.python.core.Py; -import org.python.core.PyObject; -import org.python.core.PyType; -import org.python.expose.ExposedGet; - -public abstract class BasePointer extends PyObject implements Pointer { - - BasePointer(PyType subtype) { - super(subtype); - } - - @ExposedGet(name = "address") - public PyObject address() { - return Py.newInteger(getMemory().getAddress()); - } - - @Override - public boolean __nonzero__() { - return !getMemory().isNull(); - } - - @Override - public PyObject __int__() { - return address(); - } - - @Override - public PyObject __long__() { - return address(); - } -} Copied: trunk/jython/src/org/python/modules/jffi/BasePointer.java (from rev 6975, branches/ctypes-jffi/src/org/python/modules/jffi/BasePointer.java) =================================================================== --- trunk/jython/src/org/python/modules/jffi/BasePointer.java (rev 0) +++ trunk/jython/src/org/python/modules/jffi/BasePointer.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -0,0 +1,33 @@ +package org.python.modules.jffi; + +import org.python.core.Py; +import org.python.core.PyObject; +import org.python.core.PyType; +import org.python.expose.ExposedGet; + +public abstract class BasePointer extends PyObject implements Pointer { + + BasePointer(PyType subtype) { + super(subtype); + } + + @ExposedGet(name = "address") + public PyObject address() { + return Py.newInteger(getMemory().getAddress()); + } + + @Override + public boolean __nonzero__() { + return !getMemory().isNull(); + } + + @Override + public PyObject __int__() { + return address(); + } + + @Override + public PyObject __long__() { + return address(); + } +} Deleted: trunk/jython/src/org/python/modules/jffi/BoundedNativeMemory.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/BoundedNativeMemory.java 2010-02-03 00:30:00 UTC (rev 6975) +++ trunk/jython/src/org/python/modules/jffi/BoundedNativeMemory.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -1,235 +0,0 @@ - -package org.python.modules.jffi; - -import com.kenai.jffi.Platform; - -class BoundedNativeMemory implements Memory, DirectMemory { - protected static final com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance(); - protected static final int LONG_SIZE = Platform.getPlatform().longSize(); - protected static final int ADDRESS_SIZE = Platform.getPlatform().addressSize(); - - final long address; - final long size; - final BoundedNativeMemory parent; // keep a reference to avoid the memory being freed - - BoundedNativeMemory(long address, int size) { - this.address = address; - this.size = size; - this.parent = null; - } - - private BoundedNativeMemory(BoundedNativeMemory parent, long offset) { - this.address = parent.address + offset; - this.size = parent.size - offset; - this.parent = parent; - } - - private final void checkBounds(long off, long len) { - Util.checkBounds(size, off, len); - } - - public final long getAddress() { - return address; - } - - public BoundedNativeMemory slice(long offset) { - checkBounds(offset, 1); - return offset == 0 ? this :new BoundedNativeMemory(this, offset); - } - @Override - public final boolean equals(Object obj) { - return (obj instanceof DirectMemory) && ((DirectMemory) obj).getAddress() == address; - } - - @Override - public final int hashCode() { - int hash = 5; - hash = 53 * hash + (int) (this.address ^ (this.address >>> 32)); - return hash; - } - - public final boolean isNull() { - return address == 0; - } - - public final boolean isDirect() { - return true; - } - - public final byte getByte(long offset) { - checkBounds(offset, 1); - return IO.getByte(address + offset); - } - - public final short getShort(long offset) { - checkBounds(offset, 2); - return IO.getShort(address + offset); - } - - public final int getInt(long offset) { - checkBounds(offset, 4); - return IO.getInt(address + offset); - } - - public final long getLong(long offset) { - checkBounds(offset, 8); - return IO.getLong(address + offset); - } - - public final long getNativeLong(long offset) { - return LONG_SIZE == 32 ? getInt(offset) : getLong(offset); - } - - public final float getFloat(long offset) { - checkBounds(offset, 4); - return IO.getFloat(address + offset); - } - - public final double getDouble(long offset) { - checkBounds(offset, 8); - return IO.getDouble(address + offset); - } - - public final long getAddress(long offset) { - checkBounds(offset, ADDRESS_SIZE >> 3); - return IO.getAddress(address + offset); - } - - public final DirectMemory getMemory(long offset) { - checkBounds(offset, ADDRESS_SIZE >> 3); - final long ptr = IO.getAddress(address + offset); - return ptr != 0 ? new NativeMemory(ptr) : null; - } - - public final byte[] getZeroTerminatedByteArray(long offset) { - checkBounds(offset, 1); - return IO.getZeroTerminatedByteArray(address + offset, (int) (size - offset)); - } - - public void putZeroTerminatedByteArray(long offset, byte[] bytes, int off, int len) { - // Ensure room for terminating zero byte - checkBounds(offset, len + 1); - IO.putZeroTerminatedByteArray(address + offset, bytes, off, len); - } - - public final void putByte(long offset, byte value) { - checkBounds(offset, 1); - IO.putByte(address + offset, value); - } - - public final void putShort(long offset, short value) { - checkBounds(offset, 2); - IO.putShort(address + offset, value); - } - - public final void putInt(long offset, int value) { - checkBounds(offset, 4); - IO.putInt(address + offset, value); - } - - public final void putLong(long offset, long value) { - checkBounds(offset, 8); - IO.putLong(address + offset, value); - } - - public final void putNativeLong(long offset, long value) { - if (LONG_SIZE == 32) { - putInt(offset, (int) value); - } else { - putLong(offset, value); - } - } - public final void putAddress(long offset, long value) { - checkBounds(offset, ADDRESS_SIZE >> 3); - IO.putAddress(address + offset, value); - } - public final void putFloat(long offset, float value) { - checkBounds(offset, 4); - IO.putFloat(address + offset, value); - } - - public final void putDouble(long offset, double value) { - checkBounds(offset, 8); - IO.putDouble(address + offset, value); - } - - public final void putAddress(long offset, Memory value) { - checkBounds(offset, ADDRESS_SIZE >> 3); - IO.putAddress(address + offset, ((DirectMemory) value).getAddress()); - } - - public final void get(long offset, byte[] dst, int off, int len) { - checkBounds(offset, len); - IO.getByteArray(address + offset, dst, off, len); - } - - public final void put(long offset, byte[] src, int off, int len) { - checkBounds(offset, len); - IO.putByteArray(address + offset, src, off, len); - } - - public final void get(long offset, short[] dst, int off, int len) { - checkBounds(offset, len << 1); - IO.getShortArray(address + offset, dst, off, len); - } - - public final void put(long offset, short[] src, int off, int len) { - checkBounds(offset, len << 1); - IO.putShortArray(address + offset, src, off, len); - } - - public final void get(long offset, int[] dst, int off, int len) { - checkBounds(offset, len << 2); - IO.getIntArray(address + offset, dst, off, len); - } - - public final void put(long offset, int[] src, int off, int len) { - checkBounds(offset, len << 2); - IO.putIntArray(address + offset, src, off, len); - } - - public final void get(long offset, long[] dst, int off, int len) { - checkBounds(offset, len << 3); - IO.getLongArray(address + offset, dst, off, len); - } - - public final void put(long offset, long[] src, int off, int len) { - checkBounds(offset, len << 3); - IO.putLongArray(address + offset, src, off, len); - } - - public final void get(long offset, float[] dst, int off, int len) { - checkBounds(offset, len << 2); - IO.getFloatArray(address + offset, dst, off, len); - } - - public final void put(long offset, float[] src, int off, int len) { - checkBounds(offset, len << 2); - IO.putFloatArray(address + offset, src, off, len); - } - - public final void get(long offset, double[] dst, int off, int len) { - checkBounds(offset, len << 3); - IO.getDoubleArray(address + offset, dst, off, len); - } - - public final void put(long offset, double[] src, int off, int len) { - checkBounds(offset, len << 3); - IO.putDoubleArray(address + offset, src, off, len); - } - - public final int indexOf(long offset, byte value) { - return value == 0 - ? (int) IO.getStringLength(address + offset) - : (int) IO.indexOf(address + offset, value); - } - - public final int indexOf(long offset, byte value, int maxlen) { - return (int) IO.indexOf(address, value, maxlen); - } - - public final void setMemory(long offset, long size, byte value) { - checkBounds(offset, size); - IO.setMemory(address + offset, size, value); - } -} Copied: trunk/jython/src/org/python/modules/jffi/BoundedNativeMemory.java (from rev 6975, branches/ctypes-jffi/src/org/python/modules/jffi/BoundedNativeMemory.java) =================================================================== --- trunk/jython/src/org/python/modules/jffi/BoundedNativeMemory.java (rev 0) +++ trunk/jython/src/org/python/modules/jffi/BoundedNativeMemory.java 2010-02-03 01:28:54 UTC (rev 6976) @@ -0,0 +1,235 @@ + +package org.python.modules.jffi; + +import com.kenai.jffi.Platform; + +class BoundedNativeMemory implements Memory, DirectMemory { + protected static final com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance(); + protected static final int LONG_SIZE = Platform.getPlatform().longSize(); + protected static final int ADDRESS_SIZE = Platform.getPlatform().addressSize(); + + final long address; + final long size; + final BoundedNativeMemory parent; // keep a reference to avoid the memory being freed + + BoundedNativeMemory(long address, int size) { + this.address = address; + this.size = size; + this.parent = null; + } + + private BoundedNativeMemory(BoundedNativeMemory parent, long offset) { + this.address = parent.address + offset; + this.size = parent.size - offset; + this.parent = parent; + } + + private final void checkBounds(long off, long len) { + Util.checkBounds(size, off, len); + } + + public final long getAddress() { + return address; + } + + public BoundedNativeMemory slice(long offset) { + checkBounds(offset, 1); + return offset == 0 ? this :new BoundedNativeMemory(this, offset); + } + @Override + public final boolean equals(Object obj) { + return (obj instanceof DirectMemory) && ((DirectMemory) obj).getAddress() == address; + } + + @Override + public final int hashCode() { + int hash = 5; + hash = 53 * hash + (int) (this.address ^ (this.address >>> 32)); + return hash; + } + + public final boolean isNull() { + return address == 0; + } + + public final boolean isDirect() { + return true; + } + + public final byte getByte(long offset) { + checkBounds(offset, 1); + return IO.getByte(address + offset); + } + + public final short getShort(long offset) { + checkBounds(offset, 2); + return IO.getShort(address + offset); + } + + public final int getInt(long offset) { + checkBounds(offset, 4); + return IO.getInt(address + offset); + } + + public final long getLong(long offset) { + checkBounds(offset, 8); + return IO.getLong(address + offset); + } + + public final long getNativeLong(long offset) { + return LONG_SIZE == 32 ? getInt(offset) : getLong(offset); + } + + public final float getFloat(long offset) { + checkBounds(offset, 4); + return IO.getFloat(address + offset); + } + + public final double getDouble(long offset) { + checkBounds(offset, 8); + return IO.getDouble(address + offset); + } + + public final long getAddress(long offset) { + checkBounds(offset, ADDRESS_SIZE >> 3); + return IO.getAddress(address + offset); + } + + public final DirectMemory getMemory(long offset) { + checkBounds(offset, ADDRESS_SIZE >> 3); + final long ptr = IO.getAddress(address + offset); + return ptr != 0 ? new NativeMemory(ptr) : null; + } + + public final byte[] getZeroTerminatedByteArray(long offset) { + checkBounds(offset, 1); + return IO.getZeroTerminatedByteArray(address + offset, (int) (size - offset)); + } + + public void putZeroTerminatedByteArray(long offset, byte[] bytes, int off, int len) { + // Ensure room for terminating zero byte + checkBounds(offset, len + 1); + IO.putZeroTerminatedByteArray(address + offset, bytes, off, len); + } + + public final void putByte(long offset, byte value) { + checkBounds(offset, 1); + IO.putByte(address + offset, value); + } + + public final void putShort(long offset, short value) { + checkBounds(offset, 2); + IO.putShort(address + offset, value); + } + + public final void putInt(long offset, int value) { + checkBounds(offset, 4); + IO.putInt(address + offset, value); + } + + public final void putLong(long offset, long value) { + checkBounds(offset, 8); + IO.putLong(address + offset, value); + } + + public final void putNativeLong(long offset, long value) { + if (LONG_SIZE == 32) { + putInt(offset, (int) value); + } else { + putLong(offset, value); + } + } + public final void putAddress(long offset, long value) { + checkBounds(offset, ADDRESS_SIZE >> 3); + IO.putAddress(address + offset, value); + } + public final void putFloat(long offset, float value) { + checkBounds(offset, 4); + IO.putFloat(address + offset, value); + } + + public final void putDouble(long offset, double value) { + checkBounds(offset, 8); + IO.putDouble(address + offset, value); + } + + public final void putAddress(long offset, Memory value) { + checkBounds(offset, ADDRESS_SIZE >> 3); + IO.putAddress(address + offset, ((DirectMemory) value).getAddress()); + } + + public final void get(long offset, byte[] dst, int off, int len) { + checkBounds(offset, len); + IO.getByteArray(address + offset, dst, off, len); + } + + public final void put(long offset, byte[] src, int off, int len) { + checkBounds(offset, len); + IO.putByteArray(address + offset, src, off, len); + } + + public final void get(long offset, short[] dst, int off, int len) { + checkBounds(offset, len << 1); + IO.getShortArray(address + offset, dst, off, len); + } + + public final void put(long offset, short[] src, int off, int len) { + checkBounds(offset, len << 1); + IO.putShortArray(address + offset, src, off, len); + } + + public final void get(long offset, int[] dst, int off, int len) { + checkBounds(offset, len << 2); + IO.getIntArray(address + offset, dst, off, len); + } + + public final void put(long offset, int[] src, int off, int len) { + checkBounds(offset, len << 2); + IO.putIntArray(address + offset, src, off, len); + } + + public final void get(long offset, long[] dst, int off, int len) { + checkBounds(offset, len << 3); + IO.getLongArray(... [truncated message content] |
From: <wme...@us...> - 2010-02-03 00:30:10
|
Revision: 6975 http://jython.svn.sourceforge.net/jython/?rev=6975&view=rev Author: wmeissner Date: 2010-02-03 00:30:00 +0000 (Wed, 03 Feb 2010) Log Message: ----------- Add jffi-0.6.5.jar. This is a java-only change, so no stub libs need to be updated. Modified Paths: -------------- trunk/jython/extlibs/jffi.jar Modified: trunk/jython/extlibs/jffi.jar =================================================================== (Binary files differ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2010-02-02 17:14:00
|
Revision: 6974 http://jython.svn.sourceforge.net/jython/?rev=6974&view=rev Author: nriley Date: 2010-02-02 17:13:53 +0000 (Tue, 02 Feb 2010) Log Message: ----------- Missed updating NEWS Modified Paths: -------------- trunk/jython/NEWS Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-01-31 06:16:21 UTC (rev 6973) +++ trunk/jython/NEWS 2010-02-02 17:13:53 UTC (rev 6974) @@ -15,6 +15,7 @@ - [ 1396 ] Assigning os module funcs as class attributes incompatible with CPython - [ 1504 ] Inheriting twice from the same Java interface causes MRO problems - [ 1511 ] PySet doesn't support Java serialization + - [ 1426 ] JSR 223 Bindings changes not taking effect and leaking between threads; unnecessary synchronization - [ 1548 ] Parentheses in CLASSPATH cause errors in jython.bat - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2010-01-31 06:16:27
|
Revision: 6973 http://jython.svn.sourceforge.net/jython/?rev=6973&view=rev Author: leosoto Date: 2010-01-31 06:16:21 +0000 (Sun, 31 Jan 2010) Log Message: ----------- Fixed problems introduced with the recent class loading refactor. Note that we still do not have a stable/consistent classloading hierarchy in place. But we are closer. Modified Paths: -------------- trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/imp.java Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2010-01-30 16:36:46 UTC (rev 6972) +++ trunk/jython/src/org/python/core/Py.java 2010-01-31 06:16:21 UTC (rev 6973) @@ -787,7 +787,7 @@ * @param name Name of the Java class to load and initialize * @param reason Reason for loading it, used for debugging. No debug output * is generated if it is null - * @return the loaded class, or null if no class loader is accessible + * @return the loaded class * @throws ClassNotFoundException if the class wasn't found by the class loader */ private static Class<?> findClassInternal(String name, String reason) throws ClassNotFoundException { @@ -799,39 +799,42 @@ } return loadAndInitClass(name, classLoader); } - if (!syspathJavaLoaderRestricted) { try { classLoader = imp.getSyspathJavaLoader(); + if (classLoader != null && reason != null) { + writeDebug("import", "trying " + name + " as " + reason + + " in SysPathJavaLoader"); + } } catch (SecurityException e) { syspathJavaLoaderRestricted = true; } - if (classLoader != null) { - if (reason != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in SysPathJavaLoader"); - } - try { - return loadAndInitClass(name, classLoader); - } catch (ClassNotFoundException cnfe) { - // let the default classloader try - } + } + if (syspathJavaLoaderRestricted) { + classLoader = imp.getParentClassLoader(); + if (classLoader != null && reason != null) { + writeDebug("import", "trying " + name + " as " + reason + + " in Jython's parent class loader"); } + } + if (classLoader != null) { + try { + return loadAndInitClass(name, classLoader); + } catch (ClassNotFoundException cnfe) { + // let the default classloader try + // XXX: by trying another classloader that may not be on a + // parent/child relationship with the Jython's parent + // classsloader we are risking some nasty class loading + // problems (such as having two incompatible copies for + // the same class that is itself a dependency of two + // classes loaded from these two different class loaders) + } } if (reason != null) { writeDebug("import", "trying " + name + " as " + reason + - " in Jython's parent class loader"); + " in context class loader, for backwards compatibility"); } - classLoader = imp.getParentClassLoader(); - if (classLoader != null) { - return loadAndInitClass(name, classLoader); - } - - if (reason != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in Class.forName"); - } - return Class.forName(name); + return loadAndInitClass(name, Thread.currentThread().getContextClassLoader()); } /** Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2010-01-30 16:36:46 UTC (rev 6972) +++ trunk/jython/src/org/python/core/imp.java 2010-01-31 06:16:21 UTC (rev 6973) @@ -48,36 +48,63 @@ } /** - * Returns the parent class loader for Jython. In most environments - * is just the class loader that loaded this class (imp.class). However, - * when that class loader is null (e.g., when Jython has been - * loaded using the boot loader) we return the Thread's context class - * loader (which can also be null, but in such case we return null anyway). + * <p> + * Selects the parent class loader for Jython, used for dinamically load classes and resources * - * @return the parent class loader for Jython + * <p> + * The current implementation chooses between the current and context + * classloader based on the following criteria:<ul> + * + * <li>If both are the same, that one is returned. + * <li>If either is null, the non-null one is selected. + * <li>If both are not null, and a parent/child relationship can be determined, + * the child is selected. + * <li>If both are not null and not on a parent/child relationship, the + * current class loader is returned (since it is likely for the + * context class loader to <b>not</b> see the Jython classes) + * + * @return the parent class loader for Jython or null if both the current and context classloaders are null; */ public static ClassLoader getParentClassLoader() { - ClassLoader parent = null; - // XXX: While trying the current class loader before using the context class - // loader seems like the saner approach, there may be legacy code - // expecting Jython to use the context class loader, - // - // Se we should uncomment the following line when we feel like - // doing backwards-incompatible changes (3.0?) - // - // parent = imp.class.getClassLoader(); - if (parent == null) { - // Try the context class loader - try { - parent = Thread.currentThread().getContextClassLoader(); - } catch (SecurityException e) { - // We just give up - } - } - return parent; - } + ClassLoader current = imp.class.getClassLoader(); + ClassLoader context = Thread.currentThread().getContextClassLoader(); + if (context == current) { + return current; + } + if (context == null) { + return current; + } + if (current == null) { + return context; + } + if (isParentClassLoader(context, current)) { + return current; + } + if (isParentClassLoader(current, context)) { + return context; + } + return current; + } - private imp() { + private static boolean isParentClassLoader( + ClassLoader suspectedParent, ClassLoader child) { + try { + ClassLoader parent = child.getParent(); + if (suspectedParent == parent) { + return true; + } + if (parent == null || parent == child) { + // We reached the boot class loader + return false; + } + return isParentClassLoader(suspectedParent, parent); + + } catch (SecurityException e) { + return false; + } + } + + private imp() { } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2010-01-30 16:07:07
|
Revision: 6970 http://jython.svn.sourceforge.net/jython/?rev=6970&view=rev Author: leosoto Date: 2010-01-30 16:06:59 +0000 (Sat, 30 Jan 2010) Log Message: ----------- Cleanup of class-loading strategy SyspathJavaLoader is now a delegating classloader. Its parent is the context class loader, for backwards compatibility. And when sys.classLoader is set, it willdelegate to it, WITHOUT searching on sys.path, but after the regular parent delegation. The parent of SyspathJavaLoader is determined by imp.getParentClassLoader, to allow other class loading components to use a consistent parent. Refactored findClass/findClassEx to eliminate code duplications and to use: - only sys.classLoader if it is set - SyspathJavaLoader if it can be used - SyspathJavaLoader's parent if SyspathJavaLoader can't be used - Class.forName(String) as a last resort Refactored ClassPathImporter to use SyspathJavaLoader's parent if sys.classLoader is not set. Modified Paths: -------------- trunk/jython/src/org/python/core/ClasspathPyImporter.java trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/SyspathJavaLoader.java trunk/jython/src/org/python/core/imp.java Modified: trunk/jython/src/org/python/core/ClasspathPyImporter.java =================================================================== --- trunk/jython/src/org/python/core/ClasspathPyImporter.java 2010-01-30 10:14:30 UTC (rev 6969) +++ trunk/jython/src/org/python/core/ClasspathPyImporter.java 2010-01-30 16:06:59 UTC (rev 6970) @@ -89,13 +89,12 @@ if (entries.containsKey(filename)) { return filename; } - InputStream is = tryClassLoader(filename, Py.getSystemState().getClassLoader(), "sys"); - if (is == null) { - is = tryClassLoader(filename, Thread.currentThread().getContextClassLoader(), "context"); + InputStream is; + if (Py.getSystemState().getClassLoader() != null) { + is = tryClassLoader(filename, Py.getSystemState().getClassLoader(), "sys"); + } else { + is = tryClassLoader(filename, imp.getParentClassLoader(), "parent"); } - if (is == null) { - is = tryClassLoader(filename, ClasspathPyImporter.class.getClassLoader(), "current"); - } if (is != null) { entries.put(filename, is); return filename; Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2010-01-30 10:14:30 UTC (rev 6969) +++ trunk/jython/src/org/python/core/Py.java 2010-01-30 16:06:59 UTC (rev 6970) @@ -780,35 +780,68 @@ return true; } - private static boolean secEnv = false; + private static boolean syspathJavaLoaderRestricted = false; - public static Class<?> findClass(String name) { - try { - ClassLoader classLoader = Py.getSystemState().getClassLoader(); + /** + * Common code for findClass and findClassEx + * @param name Name of the Java class to load and initialize + * @param reason Reason for loading it, used for debugging. No debug output + * is generated if it is null + * @return the loaded class, or null if no class loader is accessible + * @throws ClassNotFoundException if the class wasn't found by the class loader + */ + private static Class<?> findClassInternal(String name, String reason) throws ClassNotFoundException { + ClassLoader classLoader = Py.getSystemState().getClassLoader(); + if (classLoader != null) { + if (reason != null) { + writeDebug("import", "trying " + name + " as " + reason + + " in sys.classLoader"); + } + return loadAndInitClass(name, classLoader); + } + + if (!syspathJavaLoaderRestricted) { + try { + classLoader = imp.getSyspathJavaLoader(); + } catch (SecurityException e) { + syspathJavaLoaderRestricted = true; + } if (classLoader != null) { - return classLoader.loadClass(name); - } - - if (!secEnv) { + if (reason != null) { + writeDebug("import", "trying " + name + " as " + reason + + " in SysPathJavaLoader"); + } try { - classLoader = imp.getSyspathJavaLoader(); - } catch (SecurityException e) { - secEnv = true; + return loadAndInitClass(name, classLoader); + } catch (ClassNotFoundException cnfe) { + // let the default classloader try } - if (classLoader != null) { - try { - return classLoader.loadClass(name); - } catch (ClassNotFoundException cnfe) { - // let the context classloader try - } - } } - - classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader != null) { - return classLoader.loadClass(name); - } - return null; + } + if (reason != null) { + writeDebug("import", "trying " + name + " as " + reason + + " in Jython's parent class loader"); + } + classLoader = imp.getParentClassLoader(); + if (classLoader != null) { + return loadAndInitClass(name, classLoader); + } + + if (reason != null) { + writeDebug("import", "trying " + name + " as " + reason + + " in Class.forName"); + } + return Class.forName(name); + } + + /** + * Tries to find a Java class. + * @param name Name of the Java class. + * @return The class, or null if it wasn't found + */ + public static Class<?> findClass(String name) { + try { + return findClassInternal(name, null); } catch (ClassNotFoundException e) { // e.printStackTrace(); return null; @@ -821,39 +854,20 @@ } } + /** + * Tries to find a Java class. + * + * Unless {@link #findClass(String)}, it raises a JavaError + * if the class was found but there were problems loading it. + * @param name Name of the Java class. + * @param reason Reason for finding the class. Used for debugging messages. + * @return The class, or null if it wasn't found + * @throws JavaError wrapping LinkageErrors/IllegalArgumentExceptions + * occurred when the class is found but can't be loaded. + */ public static Class<?> findClassEx(String name, String reason) { - try { - ClassLoader classLoader = Py.getSystemState().getClassLoader(); - if (classLoader != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in classLoader"); - return classLoader.loadClass(name); - } - - if (!secEnv) { - try { - classLoader = imp.getSyspathJavaLoader(); - } catch (SecurityException e) { - secEnv = true; - } - if (classLoader != null) { - writeDebug("import", "trying " + name + " as " + reason + - " in syspath loader"); - try { - return classLoader.loadClass(name); - } catch (ClassNotFoundException cnfe) { - // let the context classloader try - } - } - } - - writeDebug("import", "trying " + name + " as " + reason + - " in Class.forName"); - classLoader = Thread.currentThread().getContextClassLoader(); - if (classLoader != null) { - return classLoader.loadClass(name); - } - return null; + try { + return findClassInternal(name, reason); } catch (ClassNotFoundException e) { return null; } catch (IllegalArgumentException e) { @@ -863,6 +877,14 @@ } } + // An alias to express intent (since boolean flags aren't exactly obvious). + // We *need* to initialize classes on findClass/findClassEx, so that import + // statements can trigger static initializers + private static Class<?> loadAndInitClass(String name, ClassLoader loader) throws ClassNotFoundException { + return Class.forName(name, true, loader); + } + + public static void initProxy(PyProxy proxy, String module, String pyclass, Object[] args) { if (proxy._getPyInstance() != null) Modified: trunk/jython/src/org/python/core/SyspathJavaLoader.java =================================================================== --- trunk/jython/src/org/python/core/SyspathJavaLoader.java 2010-01-30 10:14:30 UTC (rev 6969) +++ trunk/jython/src/org/python/core/SyspathJavaLoader.java 2010-01-30 16:06:59 UTC (rev 6970) @@ -9,40 +9,118 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; import java.util.StringTokenizer; import java.util.zip.ZipEntry; +import javax.management.RuntimeErrorException; + import org.python.core.util.RelativeFile; public class SyspathJavaLoader extends ClassLoader { private static final char SLASH_CHAR = '/'; - public InputStream getResourceAsStream(String res) { - Py.writeDebug("resource", "trying resource: " + res); - PySystemState sys = Py.getSystemState(); - ClassLoader classLoader = sys.getClassLoader(); - if (classLoader != null) { - return classLoader.getResourceAsStream(res); + public SyspathJavaLoader(ClassLoader parent) { + super(parent); + } + + + /** + * Returns a byte[] with the contents read from an InputStream. + * + * The stream is closed after reading the bytes. + * + * @param input The input stream + * @param size The number of bytes to read + * + * @return an array of byte[size] with the contents read + * */ + private byte[] getBytesFromInputStream(InputStream input, int size) { + try { + byte[] buffer = new byte[size]; + int nread = 0; + while(nread < size) { + nread += input.read(buffer, nread, size - nread); + } + return buffer; + } catch (IOException exc) { + return null; + } finally { + try { + input.close(); + } catch (IOException e) { + // Nothing to do + } + } + } + + private byte[] getBytesFromDir(String dir, String name) { + try { + File file = getFile(dir, name); + if (file == null) { + return null; + } + return getBytesFromInputStream(new FileInputStream(file), (int)file.length()); + } catch (FileNotFoundException e) { + return null; + } catch(SecurityException e) { + return null; } - classLoader = Thread.currentThread().getContextClassLoader(); - - InputStream ret; - - if (classLoader != null) { - ret = classLoader.getResourceAsStream(res); - } else { - ret = ClassLoader.getSystemResourceAsStream(res); + } + + private byte[] getBytesFromArchive(SyspathArchive archive, String name) { + String entryname = name.replace('.', SLASH_CHAR) + ".class"; + ZipEntry ze = archive.getEntry(entryname); + if (ze == null) { + return null; } - if (ret != null) { - return ret; + try { + return getBytesFromInputStream(archive.getInputStream(ze), + (int)ze.getSize()); + } catch (IOException e) { + return null; + } + } + + @Override + protected Class<?> findClass(String name) throws ClassNotFoundException { + PySystemState sys = Py.getSystemState(); + ClassLoader sysClassLoader = sys.getClassLoader(); + if (sysClassLoader != null) { + // sys.classLoader overrides this class loader! + return sysClassLoader.loadClass(name); + } + // Search the sys.path for a .class file matching the named class. + PyList path = sys.path; + for (int i = 0; i < path.__len__(); i++) { + byte[] buffer; + PyObject entry = replacePathItem(sys, i, path); + if (entry instanceof SyspathArchive) { + SyspathArchive archive = (SyspathArchive)entry; + buffer = getBytesFromArchive(archive, name); + } else { + String dir = entry.__str__().toString(); + buffer = getBytesFromDir(dir, name); + } + if (buffer != null) { + return defineClass(name, buffer, 0, buffer.length); + } } - - if (res.charAt(0) == SLASH_CHAR) { + // couldn't find the .class file on sys.path + throw new ClassNotFoundException(name); + } + + @Override + protected URL findResource(String res) { + PySystemState sys = Py.getSystemState(); + + if (res.charAt(0) == SLASH_CHAR) { res = res.substring(1); } - String entryRes = res; + String entryRes = res; if (File.separatorChar != SLASH_CHAR) { res = res.replace(SLASH_CHAR, File.separatorChar); entryRes = entryRes.replace(File.separatorChar, SLASH_CHAR); @@ -55,25 +133,25 @@ SyspathArchive archive = (SyspathArchive) entry; ZipEntry ze = archive.getEntry(entryRes); if (ze != null) { - try { - return archive.getInputStream(ze); - } catch (IOException e) { - ; - } + try { + return new URL("jar:" + entry.__str__().toString() + "!/" + entryRes); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } } continue; } String dir = sys.getPath(entry.__str__().toString()); try { - return new BufferedInputStream(new FileInputStream(new File(dir, res))); - } catch (IOException e) { - continue; - } + return new File(dir, res).toURI().toURL(); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } } - return null; } + static PyObject replacePathItem(PySystemState sys, int idx, PyList paths) { PyObject path = paths.__getitem__(idx); if (path instanceof SyspathArchive) { @@ -92,91 +170,6 @@ return path; } - // override from abstract base class - protected Class<?> loadClass(String name, boolean resolve) - throws ClassNotFoundException { - // First, if the Python runtime system has a default class loader, defer to it. - PySystemState sys = Py.getSystemState(); - ClassLoader classLoader = sys.getClassLoader(); - if (classLoader != null) { - return classLoader.loadClass(name); - } - - // Search the sys.path for a .class file matching the named class. - try { - return Class.forName(name); - } catch(ClassNotFoundException e) { - } - - // The current class loader may be null (e.g., when Jython is loaded - // from the boot classpath); try the system class loader. - try { - return Class.forName(name, true, ClassLoader.getSystemClassLoader()); - } catch(ClassNotFoundException e) { - } catch (SecurityException se) { - } - - Class<?> c = findLoadedClass(name); - if(c != null) { - return c; - } - - PyList path = sys.path; - for(int i = 0; i < path.__len__(); i++) { - - InputStream fis; - int size; - PyObject entry = replacePathItem(sys, i, path); - if(entry instanceof SyspathArchive) { - SyspathArchive archive = (SyspathArchive)entry; - String entryname = name.replace('.', SLASH_CHAR) + ".class"; - ZipEntry ze = archive.getEntry(entryname); - if(ze == null) { - continue; - } - try { - fis = archive.getInputStream(ze); - size = (int)ze.getSize(); - } catch (IOException exc) { - continue; - } - } else { - String dir = entry.__str__().toString(); - File file = getFile(dir, name); - if (file == null) { - continue; - } - try { - size = (int)file.length(); - fis = new FileInputStream(file); - } catch (FileNotFoundException e) { - continue; - } catch(SecurityException e) { - continue; - } - } - try { - byte[] buffer = new byte[size]; - int nread = 0; - while(nread < size) { - nread += fis.read(buffer, nread, size - nread); - } - fis.close(); - return loadClassFromBytes(name, buffer); - } catch (IOException e) { - - } finally { - try { - fis.close(); - } catch (IOException e) { - } - } - } - - // couldn't find the .class file on sys.path - throw new ClassNotFoundException(name); - } - private File getFile(String dir, String name) { String accum = ""; boolean first = true; @@ -192,12 +185,5 @@ return new RelativeFile(dir, accum + ".class"); } - private Class<?> loadClassFromBytes(String name, byte[] data) { - // System.err.println("loadClassFromBytes("+name+", byte[])"); - Class<?> c = defineClass(name, data, 0, data.length); - resolveClass(c); - Compiler.compileClass(c); - return c; - } } Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2010-01-30 10:14:30 UTC (rev 6969) +++ trunk/jython/src/org/python/core/imp.java 2010-01-30 16:06:59 UTC (rev 6970) @@ -41,11 +41,41 @@ public static ClassLoader getSyspathJavaLoader() { synchronized (syspathJavaLoaderLock) { if (syspathJavaLoader == null) { - syspathJavaLoader = new SyspathJavaLoader(); - } + syspathJavaLoader = new SyspathJavaLoader(getParentClassLoader()); + } } return syspathJavaLoader; } + + /** + * Returns the parent class loader for Jython. In most environments + * is just the class loader that loaded this class (imp.class). However, + * when that class loader is null (e.g., when Jython has been + * loaded using the boot loader) we return the Thread's context class + * loader (which can also be null, but in such case we return null anyway). + * + * @return the parent class loader for Jython + */ + public static ClassLoader getParentClassLoader() { + ClassLoader parent = null; + // XXX: While trying the current class loader before using the context class + // loader seems like the saner approach, there may be legacy code + // expecting Jython to use the context class loader, + // + // Se we should uncomment the following line when we feel like + // doing backwards-incompatible changes (3.0?) + // + // parent = imp.class.getClassLoader(); + if (parent == null) { + // Try the context class loader + try { + parent = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException e) { + // We just give up + } + } + return parent; + } private imp() { } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wme...@us...> - 2010-01-30 10:14:36
|
Revision: 6969 http://jython.svn.sourceforge.net/jython/?rev=6969&view=rev Author: wmeissner Date: 2010-01-30 10:14:30 +0000 (Sat, 30 Jan 2010) Log Message: ----------- Fixes for CType changes Modified Paths: -------------- branches/ctypes-jffi/Lib/ctypes/__init__.py branches/ctypes-jffi/src/org/python/modules/jffi/CType.java Modified: branches/ctypes-jffi/Lib/ctypes/__init__.py =================================================================== --- branches/ctypes-jffi/Lib/ctypes/__init__.py 2010-01-30 08:08:55 UTC (rev 6968) +++ branches/ctypes-jffi/Lib/ctypes/__init__.py 2010-01-30 10:14:30 UTC (rev 6969) @@ -43,7 +43,7 @@ @classmethod def size(self): - return self._jffi_type.size + return self._jffi_type.size() class _ScalarCData(jffi.ScalarCData, _CData): __metaclass__ = _CTypeMetaClass @@ -136,12 +136,12 @@ def sizeof(type): if hasattr(type, '_jffi_type'): - return type._jffi_type.size + return type._jffi_type.size() else: raise TypeError("this type has no size") def alignment(type): - return type._jffi_type.alignment + return type._jffi_type.alignment() def addressof(cdata): return cdata.address() Modified: branches/ctypes-jffi/src/org/python/modules/jffi/CType.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/CType.java 2010-01-30 08:08:55 UTC (rev 6968) +++ branches/ctypes-jffi/src/org/python/modules/jffi/CType.java 2010-01-30 10:14:30 UTC (rev 6969) @@ -96,7 +96,8 @@ } } - static abstract class Custom extends CType implements ExposeAsSuperclass { + @ExposedType(name = "jffi.Type.Custom", base = CType.class) + static class Custom extends CType { final com.kenai.jffi.Type jffiType; public Custom(NativeType type, com.kenai.jffi.Type jffiType, MemoryOp op) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wme...@us...> - 2010-01-30 08:09:04
|
Revision: 6968 http://jython.svn.sourceforge.net/jython/?rev=6968&view=rev Author: wmeissner Date: 2010-01-30 08:08:55 +0000 (Sat, 30 Jan 2010) Log Message: ----------- Remove the float paths from fast-int invokers, so ctypes works with jffi-0.6 Modified Paths: -------------- branches/ctypes-jffi/src/org/python/modules/jffi/FastIntInvokerFactory.java Modified: branches/ctypes-jffi/src/org/python/modules/jffi/FastIntInvokerFactory.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/FastIntInvokerFactory.java 2010-01-30 08:02:18 UTC (rev 6967) +++ branches/ctypes-jffi/src/org/python/modules/jffi/FastIntInvokerFactory.java 2010-01-30 08:08:55 UTC (rev 6968) @@ -3,7 +3,6 @@ import com.kenai.jffi.Function; import com.kenai.jffi.Platform; -import com.kenai.jffi.Type; import org.python.core.Py; import org.python.core.PyObject; @@ -102,10 +101,6 @@ case ULONG: return Platform.getPlatform().longSize() == 32; - case FLOAT: - return Platform.getPlatform().getCPU() == Platform.CPU.I386 - || Platform.getPlatform().getCPU() == Platform.CPU.X86_64; - case STRING: return Platform.getPlatform().addressSize() == 32; } @@ -143,12 +138,9 @@ case LONG: case ULONG: return Platform.getPlatform().longSize() == 32; - - case FLOAT: - return Platform.getPlatform().getCPU() == Platform.CPU.I386 - || Platform.getPlatform().getCPU() == Platform.CPU.X86_64; } } + return false; } @@ -177,11 +169,8 @@ for (int i = 0; i < parameterConverters.length; ++i) { parameterConverters[i] = getIntParameterConverter(parameterTypes[i]); } - if (returnType.nativeType == NativeType.FLOAT) { - return createFloatInvoker(function, null, parameterConverters); - } else { - return createIntInvoker(function, getIntResultConverter(returnType), parameterConverters); - } + + return createIntInvoker(function, getIntResultConverter(returnType), parameterConverters); } /** @@ -200,28 +189,9 @@ parameterConverters[i] = getIntParameterConverter(parameterTypes[i]); } - if (function.getReturnType().equals(Type.FLOAT)) { - return createFloatInvoker(function, null, parameterConverters); - } else { - return createIntInvoker(function, getIntResultConverter(returnType), parameterConverters); - } + return createIntInvoker(function, getIntResultConverter(returnType), parameterConverters); } - - final Invoker createFloatInvoker(Function function, IntResultConverter resultConverter, IntParameterConverter[] parameterConverters) { - switch (parameterConverters.length) { - case 0: - return new FastFloatInvokerZero(function, null, parameterConverters); - case 1: - return new FastFloatInvokerOne(function, null, parameterConverters); - case 2: - return new FastFloatInvokerTwo(function, null, parameterConverters); - case 3: - return new FastFloatInvokerThree(function, null, parameterConverters); - } - throw Py.RuntimeError("fast int invoker does not support functions with arity=" + parameterConverters.length); - } - final Invoker createIntInvoker(Function function, IntResultConverter resultConverter, IntParameterConverter[] parameterConverters) { switch (parameterConverters.length) { case 0: @@ -520,76 +490,8 @@ c0.intValue(arg0), c1.intValue(arg1), c2.intValue(arg2))); } } - + /** - * Fast-int invoker that takes no parameters and returns a float - */ - private static final class FastFloatInvokerZero extends BaseFastIntInvoker { - - public FastFloatInvokerZero(Function function, IntResultConverter resultConverter, - IntParameterConverter parameterConverters[]) { - super(function, resultConverter, parameterConverters); - } - - @Override - public final PyObject invoke() { - return Py.newFloat(jffiInvoker.invokeVrF(function)); - } - } - - /** - * Fast-int invoker that takes one parameter and returns a float - */ - private static final class FastFloatInvokerOne extends BaseFastIntInvoker { - - public FastFloatInvokerOne(Function function, IntResultConverter resultConverter, - IntParameterConverter parameterConverters[]) { - super(function, resultConverter, parameterConverters); - } - - @Override - public final PyObject invoke(PyObject arg0) { - return Py.newFloat(jffiInvoker.invokeIrF(function, - c0.intValue(arg0))); - } - } - - - /** - * Fast-int invoker that takes two parameters and returns a float - */ - private static final class FastFloatInvokerTwo extends BaseFastIntInvoker { - - public FastFloatInvokerTwo(Function function, IntResultConverter resultConverter, - IntParameterConverter parameterConverters[]) { - super(function, resultConverter, parameterConverters); - } - - @Override - public PyObject invoke(PyObject arg0, PyObject arg1) { - return Py.newFloat(jffiInvoker.invokeIIrF(function, - c0.intValue(arg0), c1.intValue(arg1))); - } - } - - /** - * Fast-int invoker that takes three parameters and returns a float - */ - private static final class FastFloatInvokerThree extends BaseFastIntInvoker { - - public FastFloatInvokerThree(Function function, IntResultConverter resultConverter, - IntParameterConverter parameterConverters[]) { - super(function, resultConverter, parameterConverters); - } - - @Override - public PyObject invoke(PyObject arg0, PyObject arg1, PyObject arg2) { - return Py.newFloat(jffiInvoker.invokeIIIrF(function, - c0.intValue(arg0), c1.intValue(arg1), c2.intValue(arg2))); - } - } - - /** * Base class for all fast-int result converters */ static abstract class BaseResultConverter implements IntResultConverter { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <wme...@us...> - 2010-01-30 08:02:25
|
Revision: 6967 http://jython.svn.sourceforge.net/jython/?rev=6967&view=rev Author: wmeissner Date: 2010-01-30 08:02:18 +0000 (Sat, 30 Jan 2010) Log Message: ----------- Add workarounds to make sure jffi.Type does not get loaded by the exposed types processor, so jython still builds, even if there is not libjffi stub lib available for the current arch Modified Paths: -------------- branches/ctypes-jffi/src/org/python/modules/jffi/CType.java branches/ctypes-jffi/src/org/python/modules/jffi/Function.java branches/ctypes-jffi/src/org/python/modules/jffi/StructLayout.java branches/ctypes-jffi/src/org/python/modules/jffi/Util.java Modified: branches/ctypes-jffi/src/org/python/modules/jffi/CType.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/CType.java 2010-01-30 07:53:18 UTC (rev 6966) +++ branches/ctypes-jffi/src/org/python/modules/jffi/CType.java 2010-01-30 08:02:18 UTC (rev 6967) @@ -9,11 +9,12 @@ import org.python.core.PyType; import org.python.expose.ExposeAsSuperclass; import org.python.expose.ExposedGet; +import org.python.expose.ExposedMethod; import org.python.expose.ExposedNew; import org.python.expose.ExposedType; @ExposedType(name = "jffi.Type", base = PyObject.class) -public class CType extends PyObject { +public abstract class CType extends PyObject { public static final PyType TYPE = PyType.fromClass(CType.class); static { TYPE.fastGetDict().__setitem__("Array", Array.TYPE); @@ -36,26 +37,13 @@ public static final CType POINTER = primitive(NativeType.POINTER); public static final CType STRING = primitive(NativeType.STRING); - final com.kenai.jffi.Type jffiType; - final NativeType nativeType; - /** Size of this type in bytes */ - @ExposedGet - public final int size; - - /** Minimum alignment of this type in bytes */ - @ExposedGet - public final int alignment; - /** The <tt>MemoryOp</tt> used to read/write items of this type */ private final MemoryOp memoryOp; - CType(NativeType type, com.kenai.jffi.Type jffiType, MemoryOp memoryOp) { + CType(NativeType type, MemoryOp memoryOp) { this.nativeType = type; - this.jffiType = jffiType; - this.size = jffiType.size(); - this.alignment = jffiType.alignment(); this.memoryOp = memoryOp; } @@ -63,35 +51,64 @@ return nativeType; } + abstract com.kenai.jffi.Type jffiType(); + MemoryOp getMemoryOp() { return memoryOp; } - public int alignment() { - return alignment; + public final int alignment() { + return jffiType().alignment(); } - public int size() { - return size; + public final int size() { + return jffiType().size(); } - + + @ExposedMethod(names={"size"}) + public final PyObject pysize() { + return Py.newInteger(size()); + } + + @ExposedMethod(names={"alignment"}) + public final PyObject pyalignment() { + return Py.newInteger(alignment()); + } + static final CType primitive(NativeType type) { - CType t = new Builtin(type, NativeType.jffiType(type)); + CType t = new Builtin(type); CType.TYPE.fastGetDict().__setitem__(type.name(), t); return t; } static final class Builtin extends CType implements ExposeAsSuperclass { - public Builtin(NativeType type, com.kenai.jffi.Type jffiType) { - super(type, jffiType, MemoryOp.getMemoryOp(type)); + public Builtin(NativeType type) { + super(type, MemoryOp.getMemoryOp(type)); } @Override public final String toString() { return "<jffi.Type." + nativeType.name() + ">"; } + + final com.kenai.jffi.Type jffiType() { + return NativeType.jffiType(nativeType); + } } + static abstract class Custom extends CType implements ExposeAsSuperclass { + final com.kenai.jffi.Type jffiType; + + public Custom(NativeType type, com.kenai.jffi.Type jffiType, MemoryOp op) { + super(type, op); + this.jffiType = jffiType; + } + + final com.kenai.jffi.Type jffiType() { + return jffiType; + } + } + static CType typeOf(PyObject obj) { if (obj instanceof CType) { return (CType) obj; @@ -107,17 +124,17 @@ } @ExposedType(name = "jffi.Type.Array", base = CType.class) - static final class Array extends CType { + static final class Array extends CType.Custom { public static final PyType TYPE = PyType.fromClass(Array.class); final CType componentType; final PyType pyComponentType; final MemoryOp componentMemoryOp; - + @ExposedGet public final int length; public Array(PyType pyComponentType, CType componentType, int length) { - super(NativeType.ARRAY, new com.kenai.jffi.Array(componentType.jffiType, length), null); + super(NativeType.ARRAY, new com.kenai.jffi.Array(Util.jffiType(componentType), length), null); this.pyComponentType = pyComponentType; this.componentType = componentType; this.componentMemoryOp = getComponentMemoryOp((PyType) pyComponentType, componentType); @@ -163,7 +180,7 @@ @ExposedType(name = "jffi.Type.Pointer", base = CType.class) - final static class Pointer extends CType { + final static class Pointer extends Custom { public static final PyType TYPE = PyType.fromClass(Pointer.class); private static final ConcurrentMap<PyObject, Pointer> typeCache = new ConcurrentHashMap<PyObject, Pointer>(); Modified: branches/ctypes-jffi/src/org/python/modules/jffi/Function.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/Function.java 2010-01-30 07:53:18 UTC (rev 6966) +++ branches/ctypes-jffi/src/org/python/modules/jffi/Function.java 2010-01-30 08:02:18 UTC (rev 6967) @@ -162,10 +162,10 @@ throw Py.NotImplementedError("variadic functions not supported yet; specify a parameter list"); } - com.kenai.jffi.Type jffiReturnType = CType.typeOf(restype).jffiType; + com.kenai.jffi.Type jffiReturnType = Util.jffiType(CType.typeOf(restype)); com.kenai.jffi.Type[] jffiParamTypes = new com.kenai.jffi.Type[argtypes.length]; for (int i = 0; i < jffiParamTypes.length; ++i) { - jffiParamTypes[i] = CType.typeOf(argtypes[i]).jffiType; + jffiParamTypes[i] = Util.jffiType(CType.typeOf(argtypes[i])); } com.kenai.jffi.Function jffiFunction = new com.kenai.jffi.Function(getMemory().getAddress(), jffiReturnType, jffiParamTypes); Modified: branches/ctypes-jffi/src/org/python/modules/jffi/StructLayout.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/StructLayout.java 2010-01-30 07:53:18 UTC (rev 6966) +++ branches/ctypes-jffi/src/org/python/modules/jffi/StructLayout.java 2010-01-30 08:02:18 UTC (rev 6967) @@ -18,7 +18,7 @@ import org.python.expose.ExposedType; @ExposedType(name = "jffi.StructLayout", base = CType.class) -public class StructLayout extends CType { +public class StructLayout extends CType.Custom { public static final PyType TYPE = PyType.fromClass(StructLayout.class); static { TYPE.fastGetDict().__setitem__("Field", Field.TYPE); @@ -106,6 +106,28 @@ } } + /** + * We enclose any references to the jffi Type class in a lazily-loaded class + * so the exposed types processor does not crash when jffi can't load the + * native stub lib. + */ + private static final class StructUtil { + + public static final StructLayout newStructLayout(Field[] fields, boolean isUnion) { + com.kenai.jffi.Type[] fieldTypes = new com.kenai.jffi.Type[fields.length]; + + for (int i = 0; i < fields.length; ++i) { + fieldTypes[i] = Util.jffiType(fields[i].ctype); + } + + com.kenai.jffi.Type jffiType = isUnion + ? new com.kenai.jffi.Union(fieldTypes) + : new com.kenai.jffi.Struct(fieldTypes); + + return new StructLayout(fields, jffiType, MemoryOp.INVALID); + } + } + @ExposedNew public static PyObject StructLayout_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { @@ -117,7 +139,6 @@ } PyList pyFields = (PyList) ap.getPyObject(0); - com.kenai.jffi.Type[] fieldTypes = new com.kenai.jffi.Type[pyFields.size()]; Field[] fields = new Field[pyFields.size()]; for (int i = 0; i < fields.length; ++i) { @@ -125,16 +146,11 @@ if (!(pyField instanceof Field)) { throw Py.TypeError(String.format("element %d of field list is not an instance of jffi.StructLayout.Field", i)); } - Field f = (Field) pyField; - fields[i] = f; - fieldTypes[i] = f.ctype.jffiType; + + fields[i] = (Field) pyField; } - com.kenai.jffi.Type jffiType = ap.getPyObject(1, Py.False).__nonzero__() - ? new com.kenai.jffi.Union(fieldTypes) - : new com.kenai.jffi.Struct(fieldTypes); - - return new StructLayout(fields, jffiType, MemoryOp.INVALID); + return StructUtil.newStructLayout(fields, ap.getPyObject(1, Py.False).__nonzero__()); } @ExposedType(name = "jffi.StructLayout.ScalarField", base = Field.class) Modified: branches/ctypes-jffi/src/org/python/modules/jffi/Util.java =================================================================== --- branches/ctypes-jffi/src/org/python/modules/jffi/Util.java 2010-01-30 07:53:18 UTC (rev 6966) +++ branches/ctypes-jffi/src/org/python/modules/jffi/Util.java 2010-01-30 08:02:18 UTC (rev 6967) @@ -2,6 +2,8 @@ package org.python.modules.jffi; import java.math.BigInteger; +import java.util.HashMap; +import java.util.Map; import org.python.core.Py; import org.python.core.PyInteger; import org.python.core.PyLong; @@ -140,4 +142,8 @@ } throw Py.TypeError("invalid address"); } + + static final com.kenai.jffi.Type jffiType(CType type) { + return (com.kenai.jffi.Type) type.jffiType(); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2010-01-30 07:53:25
|
Revision: 6966 http://jython.svn.sourceforge.net/jython/?rev=6966&view=rev Author: otmarhumbel Date: 2010-01-30 07:53:18 +0000 (Sat, 30 Jan 2010) Log Message: ----------- handle CLASSPATH containing () - fixes issue #1548 Modified Paths: -------------- trunk/jython/NEWS Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-01-30 06:31:45 UTC (rev 6965) +++ trunk/jython/NEWS 2010-01-30 07:53:18 UTC (rev 6966) @@ -15,6 +15,7 @@ - [ 1396 ] Assigning os module funcs as class attributes incompatible with CPython - [ 1504 ] Inheriting twice from the same Java interface causes MRO problems - [ 1511 ] PySet doesn't support Java serialization + - [ 1548 ] Parentheses in CLASSPATH cause errors in jython.bat - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2010-01-30 06:31:51
|
Revision: 6965 http://jython.svn.sourceforge.net/jython/?rev=6965&view=rev Author: otmarhumbel Date: 2010-01-30 06:31:45 +0000 (Sat, 30 Jan 2010) Log Message: ----------- handle CLASSPATH containing () - fixes issue #1548 Modified Paths: -------------- trunk/installer/src/java/org/python/util/install/driver/jython_test.bat.template trunk/jython/src/shell/jython.bat Modified: trunk/installer/src/java/org/python/util/install/driver/jython_test.bat.template =================================================================== --- trunk/installer/src/java/org/python/util/install/driver/jython_test.bat.template 2010-01-24 01:19:10 UTC (rev 6964) +++ trunk/installer/src/java/org/python/util/install/driver/jython_test.bat.template 2010-01-30 06:31:45 UTC (rev 6965) @@ -5,9 +5,10 @@ set _SCRIPT={1} set _JAVA_HOME={2} -rem save old home env vars: +rem save old home env vars and classpath: set _OLD_JAVA_HOME=%JAVA_HOME% set _OLD_JYTHON_HOME=%JYTHON_HOME% +set _OLD_CLASSPATH=%CLASSPATH% cd /d "%_INSTALL_DIR%\bin" @@ -57,8 +58,16 @@ call "%_INSTALL_DIR%\bin\jython.bat" "%_SCRIPT%" set E=%ERRORLEVEL% +echo {3}: no home, setting CLASSPATH, calling /jython.bat from another working dir:" +set JAVA_HOME= +set JYTHON_HOME= +set CLASSPATH=.;C:\Program Files (x86)\Java\jre6\lib\ext\QTJava.zip +call "%_INSTALL_DIR%\jython.bat" "%_SCRIPT%" +set E=%ERRORLEVEL% + rem cleanup: set JAVA_HOME=%_OLD_JAVA_HOME% set JYTHON_HOME=%_OLD_JYTHON_HOME% +set CLASSPATH=%_OLD_CLASSPATH% cd /d "%~dp0%" exit /b %E% Modified: trunk/jython/src/shell/jython.bat =================================================================== --- trunk/jython/src/shell/jython.bat 2010-01-24 01:19:10 UTC (rev 6964) +++ trunk/jython/src/shell/jython.bat 2010-01-30 06:31:45 UTC (rev 6965) @@ -168,13 +168,15 @@ goto scanArgs :argsDone -if not defined _BOOT_CP ( - if defined CLASSPATH ( - set CLASSPATH=%_CP:"=%;%CLASSPATH:"=% - ) else ( - set CLASSPATH=%_CP:"=% - ) -) +rem do not use 'if () else ()': this does not work with CLASSPATH containing '(x86)' +if defined _BOOT_CP goto fullCmd +if defined CLASSPATH goto classpathDefined +set CLASSPATH=%_CP:"=% +goto fullCmd +:classpathDefined +set CLASSPATH=%_CP:"=%;%CLASSPATH:"=% + +:fullCmd set _FULL_CMD=%_JAVA_CMD% %_JAVA_OPTS% %_JAVA_MEM% %_JAVA_STACK% %_BOOT_CP% -Dpython.home=%_JYTHON_HOME% -Dpython.executable="%~f0" -classpath "%CLASSPATH%" org.python.util.jython %_JYTHON_OPTS% %_JYTHON_ARGS% %_ARGS% if defined _PRINT ( echo %_FULL_CMD% This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2010-01-24 01:19:16
|
Revision: 6964 http://jython.svn.sourceforge.net/jython/?rev=6964&view=rev Author: nriley Date: 2010-01-24 01:19:10 +0000 (Sun, 24 Jan 2010) Log Message: ----------- Undo an unnecessary double check. Modified Paths: -------------- trunk/jython/src/org/python/core/ParserFacade.java Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2010-01-24 01:15:55 UTC (rev 6963) +++ trunk/jython/src/org/python/core/ParserFacade.java 2010-01-24 01:19:10 UTC (rev 6964) @@ -130,8 +130,7 @@ throw fixParseError(bufReader, tt, filename); } } finally { - if (bufReader != null) - close(bufReader); + close(bufReader); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2010-01-24 01:16:02
|
Revision: 6963 http://jython.svn.sourceforge.net/jython/?rev=6963&view=rev Author: nriley Date: 2010-01-24 01:15:55 +0000 (Sun, 24 Jan 2010) Log Message: ----------- Better handle errors where a BufferedReader cannot be constructed while parsing (i.e., there are issues with underlying Reader). Partially addresses #1536. Modified Paths: -------------- trunk/jython/src/org/python/core/ParserFacade.java Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2010-01-23 22:58:13 UTC (rev 6962) +++ trunk/jython/src/org/python/core/ParserFacade.java 2010-01-24 01:15:55 UTC (rev 6963) @@ -118,8 +118,10 @@ try { bufReader = prepBufReader(reader, cflags, filename); // first, try parsing as an expression - return parse(bufReader, CompileMode.eval, filename, cflags ); + return parse(bufReader, CompileMode.eval, filename, cflags); } catch (Throwable t) { + if (bufReader == null) + throw Py.JavaError(t); // can't do any more try { // then, try parsing as a module bufReader.reset(); @@ -128,7 +130,8 @@ throw fixParseError(bufReader, tt, filename); } } finally { - close(bufReader); + if (bufReader != null) + close(bufReader); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2010-01-23 22:58:24
|
Revision: 6962 http://jython.svn.sourceforge.net/jython/?rev=6962&view=rev Author: nriley Date: 2010-01-23 22:58:13 +0000 (Sat, 23 Jan 2010) Log Message: ----------- - optional thread locals for PythonInterpreter - fix up Javadocs for PythonInterpreter - JSR 223: fix Bindings?\194?\160changes not taking effect and leaking between threads; remove unnecessary synchronization (#1426). Thanks, emblemparade. Modified Paths: -------------- trunk/jython/src/org/python/jsr223/PyScriptEngine.java trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java trunk/jython/src/org/python/util/PythonInterpreter.java trunk/jython/src/org/python/util/jython.java trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java Modified: trunk/jython/src/org/python/jsr223/PyScriptEngine.java =================================================================== --- trunk/jython/src/org/python/jsr223/PyScriptEngine.java 2010-01-23 22:57:19 UTC (rev 6961) +++ trunk/jython/src/org/python/jsr223/PyScriptEngine.java 2010-01-23 22:58:13 UTC (rev 6962) @@ -21,12 +21,10 @@ private final PythonInterpreter interp; private final ScriptEngineFactory factory; - private final PyModule module; PyScriptEngine(ScriptEngineFactory factory) { this.factory = factory; - interp = new PythonInterpreter(new PyScriptEngineScope(this, context)); - module = (PyModule)Py.getSystemState().modules.__finditem__("__main__"); + interp = PythonInterpreter.threadLocalStateInterpreter(new PyScriptEngineScope(this, context)); } public Object eval(String script, ScriptContext context) throws ScriptException { @@ -38,6 +36,7 @@ interp.setIn(context.getReader()); interp.setOut(context.getWriter()); interp.setErr(context.getErrorWriter()); + interp.setLocals(new PyScriptEngineScope(this, context)); return interp.eval(code).__tojava__(Object.class); } catch (PyException pye) { throw scriptException(pye); @@ -93,6 +92,7 @@ public Object invokeMethod(Object thiz, String name, Object... args) throws ScriptException, NoSuchMethodException { try { + interp.setLocals(new PyScriptEngineScope(this, context)); if (!(thiz instanceof PyObject)) { thiz = Py.java2py(thiz); } @@ -109,6 +109,7 @@ public Object invokeFunction(String name, Object... args) throws ScriptException, NoSuchMethodException { try { + interp.setLocals(new PyScriptEngineScope(this, context)); PyObject function = interp.get(name); if (function == null) { throw new NoSuchMethodException(name); @@ -120,7 +121,7 @@ } public <T> T getInterface(Class<T> clazz) { - return getInterface(module, clazz); + return getInterface(new PyModule("__jsr223__", interp.getLocals()), clazz); } public <T> T getInterface(Object obj, Class<T> clazz) { @@ -130,6 +131,7 @@ if (clazz == null || !clazz.isInterface()) { throw new IllegalArgumentException("interface expected"); } + interp.setLocals(new PyScriptEngineScope(this, context)); final PyObject thiz = Py.java2py(obj); @SuppressWarnings("unchecked") T proxy = (T) Proxy.newProxyInstance( @@ -138,6 +140,7 @@ new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { try { + interp.setLocals(new PyScriptEngineScope(PyScriptEngine.this, context)); PyObject pyMethod = thiz.__findattr__(method.getName()); if (pyMethod == null) throw new NoSuchMethodException(method.getName()); Modified: trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java =================================================================== --- trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java 2010-01-23 22:57:19 UTC (rev 6961) +++ trunk/jython/src/org/python/jsr223/PyScriptEngineScope.java 2010-01-23 22:58:13 UTC (rev 6962) @@ -13,6 +13,12 @@ import org.python.expose.ExposedGet; import org.python.expose.ExposedMethod; +/** + * JSR 223 does not map well to Jython's concept of "locals" and "globals". + * Instead, SimpleScriptContext provides ENGINE_SCOPE and GLOBAL_SCOPE, each + * with its own bindings. We adapt this multi-scope object for use as both + * a local and global dictionary. + */ @ExposedType(name = "scope", isBaseType = false) public final class PyScriptEngineScope extends PyObject { public static final PyType TYPE = PyType.fromClass(PyScriptEngineScope.class); @@ -38,15 +44,13 @@ @ExposedMethod public PyObject scope_keys() { PyList members = new PyList(); - synchronized (context) { - List<Integer> scopes = context.getScopes(); - for (int scope : scopes) { - Bindings bindings = context.getBindings(scope); - if (bindings == null) - continue; - for (String key : bindings.keySet()) - members.append(new PyString(key)); - } + List<Integer> scopes = context.getScopes(); + for (int scope : scopes) { + Bindings bindings = context.getBindings(scope); + if (bindings == null) + continue; + for (String key : bindings.keySet()) + members.append(new PyString(key)); } members.sort(); return members; @@ -63,12 +67,10 @@ } public PyObject __finditem__(String key) { - synchronized (context) { - int scope = context.getAttributesScope(key); - if (scope == -1) - return null; - return Py.java2py(context.getAttribute(key, scope)); - } + int scope = context.getAttributesScope(key); + if (scope == -1) + return null; + return Py.java2py(context.getAttribute(key, scope)); } @ExposedMethod @@ -77,12 +79,10 @@ } public void __setitem__(String key, PyObject value) { - synchronized (context) { - int scope = context.getAttributesScope(key); - if (scope == -1) - scope = ScriptContext.ENGINE_SCOPE; - context.setAttribute(key, value.__tojava__(Object.class), scope); - } + int scope = context.getAttributesScope(key); + if (scope == -1) + scope = ScriptContext.ENGINE_SCOPE; + context.setAttribute(key, value.__tojava__(Object.class), scope); } @ExposedMethod @@ -91,11 +91,9 @@ } public void __delitem__(String key) { - synchronized (context) { - int scope = context.getAttributesScope(key); - if (scope == -1) - throw Py.KeyError(key); - context.removeAttribute(key, scope); - } + int scope = context.getAttributesScope(key); + if (scope == -1) + throw Py.KeyError(key); + context.removeAttribute(key, scope); } } Modified: trunk/jython/src/org/python/util/PythonInterpreter.java =================================================================== --- trunk/jython/src/org/python/util/PythonInterpreter.java 2010-01-23 22:57:19 UTC (rev 6961) +++ trunk/jython/src/org/python/util/PythonInterpreter.java 2010-01-23 22:58:13 UTC (rev 6962) @@ -22,80 +22,111 @@ import org.python.core.PyFileReader; /** - * The PythonInterpreter class is a standard wrapper for a Jython interpreter for use embedding in a - * Java application. + * The PythonInterpreter class is a standard wrapper for a Jython interpreter + * for embedding in a Java application. */ public class PythonInterpreter { - PyModule module; - + // Defaults if the interpreter uses thread-local state protected PySystemState systemState; + PyObject globals; - PyObject locals; + protected ThreadLocal<PyObject> threadLocals; protected CompilerFlags cflags = new CompilerFlags(); /** - * Initializes the jython runtime. This should only be called once, and should be called before - * any other python objects are created (including a PythonInterpreter). + * Initializes the Jython runtime. This should only be called + * once, before any other Python objects (including + * PythonInterpreter) are created. * * @param preProperties - * A set of properties. Typically System.getProperties() is used. - * PreProperties override properties from the registry file. + * A set of properties. Typically + * System.getProperties() is used. preProperties + * override properties from the registry file. * @param postProperties - * An other set of properties. Values like python.home, python.path and all other - * values from the registry files can be added to this property set. PostProperties - * will override system properties and registry properties. + * Another set of properties. Values like python.home, + * python.path and all other values from the registry + * files can be added to this property + * set. postProperties override system properties and + * registry properties. * @param argv - * Command line argument. These values will assigned to sys.argv. + * Command line arguments, assigned to sys.argv. */ public static void initialize(Properties preProperties, Properties postProperties, String[] argv) { PySystemState.initialize(preProperties, postProperties, argv); } /** - * Create a new Interpreter with an empty dictionary + * Creates a new interpreter with an empty local namespace. */ public PythonInterpreter() { this(null, null); } /** - * Create a new interpreter with the given dictionary to use as its namespace + * Creates a new interpreter with the ability to maintain a + * separate local namespace for each thread (set by invoking + * setLocals()). + * + * @param dict + * a Python mapping object (e.g., a dictionary) for use + * as the default namespace */ + public static PythonInterpreter threadLocalStateInterpreter(PyObject dict) { + return new PythonInterpreter(dict, null, true); + } + + /** + * Creates a new interpreter with a specified local namespace. + * + * @param dict + * a Python mapping object (e.g., a dictionary) for use + * as the namespace + */ public PythonInterpreter(PyObject dict) { this(dict, null); } public PythonInterpreter(PyObject dict, PySystemState systemState) { + this(dict, systemState, false); + } + + protected PythonInterpreter(PyObject dict, PySystemState systemState, boolean useThreadLocalState) { if (dict == null) { dict = new PyStringMap(); } - if (systemState == null) { + globals = dict; + + if (systemState == null) systemState = Py.getSystemState(); - if (systemState == null) { - systemState = new PySystemState(); - } + this.systemState = systemState; + setSystemState(); + + if (useThreadLocalState) { + threadLocals = new ThreadLocal<PyObject>(); + } else { + PyModule module = new PyModule("__main__", dict); + systemState.modules.__setitem__("__main__", module); } - this.systemState = systemState; - setState(); - module = new PyModule("__main__", dict); - systemState.modules.__setitem__("__main__", module); - locals = dict; } - protected void setState() { - Py.setSystemState(systemState); + public PySystemState getSystemState() { + return systemState; } + protected void setSystemState() { + Py.setSystemState(getSystemState()); + } + /** - * Set the Python object to use for the standard input stream + * Sets a Python object to use for the standard input stream. * * @param inStream - * Python file-like object to use as input stream + * a Python file-like object to use as input stream */ public void setIn(PyObject inStream) { - systemState.stdin = inStream; + getSystemState().stdin = inStream; } public void setIn(java.io.Reader inStream) { @@ -103,7 +134,8 @@ } /** - * Set a java.io.InputStream to use for the standard input stream + * Sets a java.io.InputStream to use for the standard input + * stream. * * @param inStream * InputStream to use as input stream @@ -113,13 +145,13 @@ } /** - * Set the Python object to use for the standard output stream + * Sets a Python object to use for the standard output stream. * * @param outStream * Python file-like object to use as output stream */ public void setOut(PyObject outStream) { - systemState.stdout = outStream; + getSystemState().stdout = outStream; } public void setOut(java.io.Writer outStream) { @@ -127,7 +159,8 @@ } /** - * Set a java.io.OutputStream to use for the standard output stream + * Sets a java.io.OutputStream to use for the standard output + * stream. * * @param outStream * OutputStream to use as output stream @@ -137,7 +170,7 @@ } public void setErr(PyObject outStream) { - systemState.stderr = outStream; + getSystemState().stderr = outStream; } public void setErr(java.io.Writer outStream) { @@ -149,44 +182,46 @@ } /** - * Evaluate a string as Python source and return the result + * Evaluates a string as a Python expression and returns the + * result. */ public PyObject eval(String s) { - setState(); - return __builtin__.eval(new PyString(s), locals); + setSystemState(); + return __builtin__.eval(new PyString(s), getLocals()); } /** - * Evaluate a Python code object and return the result + * Evaluates a Python code object and returns the result. */ public PyObject eval(PyObject code) { - setState(); - return __builtin__.eval(code, locals, locals); + setSystemState(); + return __builtin__.eval(code, getLocals()); } /** - * Execute a string of Python source in the local namespace + * Executes a string of Python source in the local namespace. */ public void exec(String s) { - setState(); - Py.exec(Py.compile_flags(s, "<string>", CompileMode.exec, cflags), locals, locals); + setSystemState(); + Py.exec(Py.compile_flags(s, "<string>", CompileMode.exec, cflags), getLocals(), null); Py.flushLine(); } /** - * Execute a Python code object in the local namespace + * Executes a Python code object in the local namespace. */ public void exec(PyObject code) { - setState(); - Py.exec(code, locals, locals); + setSystemState(); + Py.exec(code, getLocals(), null); Py.flushLine(); } /** - * Execute a file of Python source in the local namespace + * Executes a file of Python source in the local namespace. */ public void execfile(String filename) { - setState(); + PyObject locals = getLocals(); + setSystemState(); __builtin__.execfile_flags(filename, locals, locals, cflags); Py.flushLine(); } @@ -196,17 +231,20 @@ } public void execfile(java.io.InputStream s, String name) { - setState(); - Py.runCode(Py.compile_flags(s, name, CompileMode.exec, cflags), locals, locals); + setSystemState(); + Py.runCode(Py.compile_flags(s, name, CompileMode.exec, cflags), null, getLocals()); Py.flushLine(); } /** - * Compile a string of Python source as either an expression (if possible) or module. + * Compiles a string of Python source as either an expression (if + * possible) or a module. * - * Designed for use by a JSR 223 implementation: "the Scripting API does not distinguish - * between scripts which return values and those which do not, nor do they make the - * corresponding distinction between evaluating or executing objects." (SCR.4.2.1) + * Designed for use by a JSR 223 implementation: "the Scripting + * API does not distinguish between scripts which return values + * and those which do not, nor do they make the corresponding + * distinction between evaluating or executing objects." + * (SCR.4.2.1) */ public PyCode compile(String script) { return compile(script, "<script>"); @@ -219,68 +257,81 @@ } public PyCode compile(Reader reader, String filename) { mod node = ParserFacade.parseExpressionOrModule(reader, filename, cflags); - setState(); + setSystemState(); return Py.compile_flags(node, filename, CompileMode.eval, cflags); } public PyObject getLocals() { - return locals; + if (threadLocals == null) + return globals; + + PyObject locals = threadLocals.get(); + if (locals != null) + return locals; + return globals; } public void setLocals(PyObject d) { - locals = d; + if (threadLocals == null) + globals = d; + else + threadLocals.set(d); } /** - * Set a variable in the local namespace + * Sets a variable in the local namespace. * * @param name * the name of the variable * @param value - * the value to set the variable to. Will be automatically converted to an - * appropriate Python object. + * the object to set the variable to (as converted to + * an appropriate Python object) */ public void set(String name, Object value) { - locals.__setitem__(name.intern(), Py.java2py(value)); + getLocals().__setitem__(name.intern(), Py.java2py(value)); } /** - * Set a variable in the local namespace + * Sets a variable in the local namespace. * * @param name * the name of the variable * @param value - * the value to set the variable to + * the Python object to set the variable to */ public void set(String name, PyObject value) { - locals.__setitem__(name.intern(), value); + getLocals().__setitem__(name.intern(), value); } /** - * Get the value of a variable in the local namespace + * Returns the value of a variable in the local namespace. * * @param name * the name of the variable - * @return the value of the variable, or null if that name isn't assigned + * @return the value of the variable, or null if that name isn't + * assigned */ public PyObject get(String name) { - return locals.__finditem__(name.intern()); + return getLocals().__finditem__(name.intern()); } /** - * Get the value of a variable in the local namespace Value will be returned as an instance of - * the given Java class. <code>interp.get("foo", Object.class)</code> will return the most + * Returns the value of a variable in the local namespace. + * + * The value will be returned as an instance of the given Java class. + * <code>interp.get("foo", Object.class)</code> will return the most * appropriate generic Java object. * * @param name * the name of the variable * @param javaclass * the class of object to return - * @return the value of the variable as the given class, or null if that name isn't assigned + * @return the value of the variable as the given class, or null + * if that name isn't assigned */ public <T> T get(String name, Class<T> javaclass) { - PyObject val = locals.__finditem__(name.intern()); + PyObject val = getLocals().__finditem__(name.intern()); if (val == null) { return null; } @@ -288,7 +339,8 @@ } public void cleanup() { - systemState.callExitFunc(); + setSystemState(); + Py.getSystemState().callExitFunc(); try { Py.getSystemState().stdout.invoke("flush"); } catch (PyException pye) { Modified: trunk/jython/src/org/python/util/jython.java =================================================================== --- trunk/jython/src/org/python/util/jython.java 2010-01-23 22:57:19 UTC (rev 6961) +++ trunk/jython/src/org/python/util/jython.java 2010-01-23 22:58:13 UTC (rev 6962) @@ -221,15 +221,15 @@ } } else if (opts.filename.equals("-")) { try { - interp.locals.__setitem__(new PyString("__file__"), new PyString("<stdin>")); + interp.globals.__setitem__(new PyString("__file__"), new PyString("<stdin>")); interp.execfile(System.in, "<stdin>"); } catch (Throwable t) { Py.printException(t); } } else { try { - interp.locals.__setitem__(new PyString("__file__"), - new PyString(opts.filename)); + interp.globals.__setitem__(new PyString("__file__"), + new PyString(opts.filename)); FileInputStream file; try { Modified: trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java =================================================================== --- trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java 2010-01-23 22:57:19 UTC (rev 6961) +++ trunk/jython/tests/java/org/python/jsr223/ScriptEngineTest.java 2010-01-23 22:58:13 UTC (rev 6962) @@ -2,6 +2,7 @@ import java.io.IOException; import java.io.StringReader; +import javax.script.Bindings; import javax.script.Compilable; import javax.script.CompiledScript; import javax.script.Invocable; @@ -102,6 +103,46 @@ assertNull(pythonEngine.get("x")); } + class ThreadLocalBindingsTest implements Runnable { + ScriptEngine engine; + Object x; + Throwable exception; + + public ThreadLocalBindingsTest(ScriptEngine engine) { + this.engine = engine; + } + + public void run() { + try { + Bindings bindings = engine.createBindings(); + assertNull(engine.eval("try: a\nexcept NameError: pass\nelse: raise Exception('a is defined', a)", bindings)); + bindings.put("x", -7); + x = engine.eval("x", bindings); + } catch (Throwable e) { + e.printStackTrace(); + exception = e; + } + } + } + + public void testThreadLocalBindings() throws ScriptException, InterruptedException { + ScriptEngineManager manager = new ScriptEngineManager(); + ScriptEngine pythonEngine = manager.getEngineByName("python"); + + pythonEngine.put("a", 42); + pythonEngine.put("x", 15); + + ThreadLocalBindingsTest test = new ThreadLocalBindingsTest(pythonEngine); + Thread thread = new Thread(test); + thread.run(); + thread.join(); + assertNull(test.exception); + assertEquals(Integer.valueOf(-7), test.x); + assertEquals(Integer.valueOf(15), pythonEngine.get("x")); + assertNull(pythonEngine.eval("del x")); + assertNull(pythonEngine.get("x")); + } + public void testInvoke() throws ScriptException, NoSuchMethodException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine pythonEngine = manager.getEngineByName("python"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2010-01-23 22:57:27
|
Revision: 6961 http://jython.svn.sourceforge.net/jython/?rev=6961&view=rev Author: nriley Date: 2010-01-23 22:57:19 +0000 (Sat, 23 Jan 2010) Log Message: ----------- Better documentation and cleanup of some obsolete bits of build.xml. Modified Paths: -------------- trunk/jython/build.xml Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2010-01-22 02:51:19 UTC (rev 6960) +++ trunk/jython/build.xml 2010-01-23 22:57:19 UTC (rev 6961) @@ -1,42 +1,43 @@ <!-- Copyright 2000 Dj Walker-Morgan --> <project name="jython" default="developer-build" basedir="."> - <target name="usage" description="prints usage hints"> + <target name="usage" description="print usage hints (-emacs removes [echo] prefix)"> <echo> -Use case 1: developer build (in your local jython copy) +Use case 1: developer build (in your local Jython copy) ------------------------------------------------------- - - call target 'developer-build' (which is the default for this build.xml) + - call target 'developer-build' (the default for this build.xml) + This build will create directories /build and /dist below basedir. Use case 2: full build for a release (using svn checkout) --------------------------------------------------------- - - make sure you have access to the jython subversion repository (https://jython.svn.sourceforge.net/svnroot/jython/trunk) + - make sure you have access to the Jython Subversion repository + (https://jython.svn.sourceforge.net/svnroot/jython/trunk) - override svn.main.dir in ant.properties (if necessary) - call target 'full-build' -This build will create a working directory named full_build/${svn.main.dir} at the same -level as your local directories jython, sandbox and installer. -It will contain a big jython_installer-${jython.version}.jar file suitable for installation. -Please be aware: -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. +This build will create a working directory named +full_build/${svn.main.dir} at the same level as your local directories +jython, sandbox and installer. It will contain a big +jython_installer-${jython.version}.jar file suitable for installation. +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. + Note on targets --------------- -The following targets are designed for direct invocation: - - usage - - developer-build - - full-build - - clean (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. +A subset of the available targets are designed for direct invocation. +Following an ant convention, the callable targets have a description +attribute. Use ant -p to display these targets. All other targets +may behave unpredictably if called directly. -Where ant.properties are searched ---------------------------------- +Where ant looks for ant.properties +---------------------------------- 1. in user.home 2. in the same directory as this build.xml file -The first setting of a property wins, further settings are ignored. +The first setting of a property wins. Further settings are ignored. Actions for a release @@ -47,9 +48,6 @@ An example ant.properties file: ------------------------------- -# - define the home of the corresponding CPython version -python.home=c:/Programme/Python/Python23 - # - zxJDBC oracle.jar=C:/workspace/HEAD/for_development/bisdevsrv28/jboss/server/infra/lib/ojdbc14.jar #informix.jar=${basedir}/../externals/external-jars/ifxjdbc.jar @@ -244,7 +242,6 @@ <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}/${svn.code.dir}" /> - <property name="python.exe" value="${python.home}/python" /> <!-- set has.repositories.connection to false in ant.properties if you want to skip checkout --> <property name="has.repositories.connection" value="true" /> <condition property="do.checkout" value="true"> @@ -292,7 +289,6 @@ <echo>debug = '${debug}'</echo> <echo>nowarn = '${nowarn}'</echo> <echo>--- properties (used for full-build only) ---</echo> - <echo>python.exe = '${python.exe}'</echo> <echo>svn.main.dir = '${svn.main.dir}'</echo> <echo>svn.revision = '${svn.revision}'</echo> <echo>svn.checkout.dir = '${svn.checkout.dir}'</echo> @@ -323,7 +319,7 @@ </target> <target name="devclean" depends="init" - description="clean up build working directories, without deleting antlr files, cachedir, or Lib."> + description="clean up build working directories without deleting antlr files, cachedir, or Lib"> <delete includeemptydirs="true" failonerror="false"> <fileset dir="${output.dir}" includes="**/*" excludes="gensrc/**"/> @@ -866,8 +862,8 @@ </jar> </target> - <target name="test" depends="prepare-test,javatest,launchertest,regrtest,modjytest"/> - <target name="singlejavatest" depends="compile,expose"> + <target name="test" depends="prepare-test,javatest,launchertest,regrtest,modjytest" description="run all the tests"/> + <target name="singlejavatest" depends="compile,expose" description="run a single JUnit test (specify with -Dtest=classname)"> <junit haltonfailure="true" fork="true"> <formatter type="brief" usefile="false"/> <sysproperty key="python.cachedir.skip" value="true"/> @@ -882,7 +878,7 @@ <!-- Clean any old test output --> <delete dir="${junit.reports}"/> </target> - <target name="javatest" depends="developer-build"> + <target name="javatest" depends="developer-build" description="run all the JUnit tests"> <mkdir dir="${junit.reports}"/> <junit fork="true" printsummary="true"> <formatter type="xml"/> @@ -908,7 +904,7 @@ <arg value="${dist.dir}"/> </exec> </target> - <target name="regrtest" depends="developer-build,regrtest-unix,regrtest-windows"/> + <target name="regrtest" depends="developer-build,regrtest-unix,regrtest-windows" description="run Python tests expected to work on Jython"/> <target name="regrtest-unix" if="os.family.unix"> <exec executable="${dist.dir}/bin/jython"> <arg value="${dist.dir}/Lib/test/regrtest.py"/> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-01-22 02:51:26
|
Revision: 6960 http://jython.svn.sourceforge.net/jython/?rev=6960&view=rev Author: pjenvey Date: 2010-01-22 02:51:19 +0000 (Fri, 22 Jan 2010) Log Message: ----------- make getattr maintain custom AttributeErrors Modified Paths: -------------- trunk/jython/Lib/test/test_builtin_jy.py trunk/jython/src/org/python/core/__builtin__.java Modified: trunk/jython/Lib/test/test_builtin_jy.py =================================================================== --- trunk/jython/Lib/test/test_builtin_jy.py 2010-01-09 06:38:57 UTC (rev 6959) +++ trunk/jython/Lib/test/test_builtin_jy.py 2010-01-22 02:51:19 UTC (rev 6960) @@ -18,6 +18,17 @@ raise TypeError() self.assert_(not hasattr(Foo(), 'bar')) + def test_getattr_custom_AttributeError(self): + class Foo(object): + def __getattr__(self, name): + raise AttributeError('baz') + try: + getattr(Foo(), 'bar') + except AttributeError, ae: + self.assertEqual(str(ae), 'baz') + else: + self.assertTrue(False) + def test_dir(self): # for http://bugs.jython.org/issue1196 class Foo(object): Modified: trunk/jython/src/org/python/core/__builtin__.java =================================================================== --- trunk/jython/src/org/python/core/__builtin__.java 2010-01-09 06:38:57 UTC (rev 6959) +++ trunk/jython/src/org/python/core/__builtin__.java 2010-01-22 02:51:19 UTC (rev 6960) @@ -613,16 +613,29 @@ public static PyObject getattr(PyObject obj, PyObject nameObj, PyObject def) { String name = asName(nameObj, "getattr"); - PyObject result = obj.__findattr__(name); + PyObject result = null; + PyException attributeError = null; + + try { + result = obj.__findattr_ex__(name); + } catch (PyException pye) { + if (!pye.match(Py.AttributeError)) { + throw pye; + } + attributeError = pye; + } if (result != null) { return result; } if (def != null) { return def; } - // throws AttributeError - obj.noAttributeError(name); - return null; + + if (attributeError == null) { + // throws AttributeError + obj.noAttributeError(name); + } + throw attributeError; } public static PyObject globals() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-01-09 06:39:03
|
Revision: 6959 http://jython.svn.sourceforge.net/jython/?rev=6959&view=rev Author: pjenvey Date: 2010-01-09 06:38:57 +0000 (Sat, 09 Jan 2010) Log Message: ----------- have the compiler setup class __doc__s as local variables fixes #1532 Modified Paths: -------------- trunk/jython/Lib/test/test_class_jy.py trunk/jython/NEWS trunk/jython/src/org/python/compiler/CodeCompiler.java trunk/jython/src/org/python/compiler/Module.java trunk/jython/src/org/python/core/Py.java Modified: trunk/jython/Lib/test/test_class_jy.py =================================================================== --- trunk/jython/Lib/test/test_class_jy.py 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/Lib/test/test_class_jy.py 2010-01-09 06:38:57 UTC (rev 6959) @@ -310,7 +310,13 @@ self.assertEqual(MyFields2.fields, ['FIELDGATHERERMETA', 'JAVA', 'JYTHON', 'SOMECLASS']) + def test___doc__(self): + class Test(object): + """doc""" + test = 'Test %s' % __doc__ + self.assertEqual(Test.test, 'Test doc') + class IsDescendentTestCase(unittest.TestCase): def test_newstyle_descendent_of_oldstyle(self): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/NEWS 2010-01-09 06:38:57 UTC (rev 6959) @@ -2,6 +2,7 @@ Jython 2.5.2a1 Bugs Fixed + - [ 1532 ] Cannot use docstring when defining class - [ 1530 ] BoolOp in multiple assign causes VerifyError - [ 1478 ] defaultdict & weakref.WeakKeyDictionary [TypeError: first argument must be callable] - [ 1487 ] Import of module with latin-1 chars fails on utf-8 file encoding Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2010-01-09 06:38:57 UTC (rev 6959) @@ -248,10 +248,8 @@ return fast_locals && !scope.exec && !scope.from_import_star; } - void parse(mod node, Code code, - boolean fast_locals, String className, - boolean classBody, ScopeInfo scope, CompilerFlags cflags) - throws Exception { + void parse(mod node, Code code, boolean fast_locals, String className, Str classDoc, + boolean classBody, ScopeInfo scope, CompilerFlags cflags) throws Exception { this.fast_locals = fast_locals; this.className = className; this.code = code; @@ -262,14 +260,22 @@ //BEGIN preparse if (classBody) { // Set the class's __module__ to __name__. fails when there's no __name__ - code.aload(1); + loadFrame(); code.ldc("__module__"); - code.aload(1); + loadFrame(); code.ldc("__name__"); code.invokevirtual(p(PyFrame.class), "getname", sig(PyObject.class, String.class)); code.invokevirtual(p(PyFrame.class), "setlocal", sig(Void.TYPE, String.class, - PyObject.class)); + PyObject.class)); + + if (classDoc != null) { + loadFrame(); + code.ldc("__doc__"); + visit(classDoc); + code.invokevirtual(p(PyFrame.class), "setlocal", sig(Void.TYPE, String.class, + PyObject.class)); + } } Label genswitch = new Label(); @@ -345,16 +351,14 @@ } @Override - public Object visitModule(org.python.antlr.ast.Module suite) - throws Exception { - if (suite.getInternalBody().size() > 0 && - suite.getInternalBody().get(0) instanceof Expr && - ((Expr) suite.getInternalBody().get(0)).getInternalValue() instanceof Str) { + public Object visitModule(org.python.antlr.ast.Module suite) throws Exception { + Str docStr = getDocStr(suite.getInternalBody()); + if (docStr != null) { loadFrame(); code.ldc("__doc__"); - visit(((Expr) suite.getInternalBody().get(0)).getInternalValue()); + visit(docStr); code.invokevirtual(p(PyFrame.class), "setglobal", sig(Void.TYPE, String.class, - PyObject.class)); + PyObject.class)); } traverse(suite); return null; @@ -409,13 +413,14 @@ code.freeLocal(array); } - public void getDocString(java.util.List<stmt> suite) throws Exception { - if (suite.size() > 0 && suite.get(0) instanceof Expr && - ((Expr) suite.get(0)).getInternalValue() instanceof Str) { - visit(((Expr) suite.get(0)).getInternalValue()); - } else { - code.aconst_null(); + public Str getDocStr(java.util.List<stmt> suite) { + if (suite.size() > 0) { + stmt stmt = suite.get(0); + if (stmt instanceof Expr && ((Expr) stmt).getInternalValue() instanceof Str) { + return (Str) ((Expr) stmt).getInternalValue(); + } } + return null; } public boolean makeClosure(ScopeInfo scope) throws Exception { @@ -476,7 +481,12 @@ className, false, false, node.getLine(), scope, cflags).get(code); - getDocString(node.getInternalBody()); + Str docStr = getDocStr(node.getInternalBody()); + if (docStr != null) { + visit(docStr); + } else { + code.aconst_null(); + } if (!makeClosure(scope)) { code.invokespecial(p(PyFunction.class), "<init>", sig(Void.TYPE, PyObject.class, @@ -2259,19 +2269,18 @@ scope.setup_closure(); scope.dump(); //Make code object out of suite + module.codeConstant(new Suite(node, node.getInternalBody()), name, false, name, - true, false, node.getLine(), scope, cflags).get(code); + getDocStr(node.getInternalBody()), true, false, node.getLine(), scope, + cflags).get(code); - //Get doc string (if there) - getDocString(node.getInternalBody()); - //Make class out of name, bases, and code if (!makeClosure(scope)) { code.invokestatic(p(Py.class), "makeClass", sig(PyObject.class, String.class, - PyObject[].class, PyCode.class, PyObject.class)); + PyObject[].class, PyCode.class)); } else { code.invokestatic(p(Py.class), "makeClass", sig(PyObject.class, String.class, - PyObject[].class, PyCode.class, PyObject.class, PyObject[].class)); + PyObject[].class, PyCode.class, PyObject[].class)); } applyDecorators(node.getInternalDecorator_list()); Modified: trunk/jython/src/org/python/compiler/Module.java =================================================================== --- trunk/jython/src/org/python/compiler/Module.java 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/src/org/python/compiler/Module.java 2010-01-09 06:38:57 UTC (rev 6959) @@ -7,7 +7,6 @@ import java.util.Enumeration; import java.util.Hashtable; import java.util.List; -import java.util.Map; import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; @@ -33,6 +32,7 @@ import org.objectweb.asm.Type; import org.python.antlr.ParseException; import org.python.antlr.PythonTree; +import org.python.antlr.ast.Str; import org.python.antlr.ast.Suite; import org.python.antlr.base.mod; import static org.python.util.CodegenUtils.*; @@ -485,16 +485,16 @@ } PyCodeConstant codeConstant(mod tree, String name, boolean fast_locals, String className, - boolean classBody, boolean printResults, int firstlineno, ScopeInfo scope) - throws Exception { - return codeConstant(tree, name, fast_locals, className, classBody, - printResults, firstlineno, scope, null); + boolean classBody, boolean printResults, int firstlineno, + ScopeInfo scope, CompilerFlags cflags) throws Exception { + return codeConstant(tree, name, fast_locals, className, null, classBody, printResults, + firstlineno, scope, cflags); } PyCodeConstant codeConstant(mod tree, String name, boolean fast_locals, String className, - boolean classBody, boolean printResults, int firstlineno, ScopeInfo scope, - CompilerFlags cflags) - throws Exception { + Str classDoc, boolean classBody, boolean printResults, + int firstlineno, ScopeInfo scope, CompilerFlags cflags) + throws Exception { PyCodeConstant code = new PyCodeConstant(tree, name, fast_locals, className, classBody, printResults, firstlineno, scope, cflags, this); @@ -507,7 +507,7 @@ sig(PyObject.class, PyFrame.class, ThreadState.class), ACC_PUBLIC); - compiler.parse(tree, c, fast_locals, className, classBody, scope, cflags); + compiler.parse(tree, c, fast_locals, className, classDoc, classBody, scope, cflags); return code; } Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/src/org/python/core/Py.java 2010-01-09 06:38:57 UTC (rev 6959) @@ -1555,20 +1555,15 @@ // XXX: The following two makeClass overrides are *only* for the // old compiler, they should be removed when the newcompiler hits - public static PyObject makeClass(String name, PyObject[] bases, - PyCode code, PyObject doc) { - return makeClass(name, bases, code, doc, null); + public static PyObject makeClass(String name, PyObject[] bases, PyCode code) { + return makeClass(name, bases, code, null); } - public static PyObject makeClass(String name, PyObject[] bases, - PyCode code, PyObject doc, + public static PyObject makeClass(String name, PyObject[] bases, PyCode code, PyObject[] closure_cells) { ThreadState state = getThreadState(); PyObject dict = code.call(state, Py.EmptyObjects, Py.NoKeywords, state.frame.f_globals, Py.EmptyObjects, new PyTuple(closure_cells)); - if (doc != null && dict.__finditem__("__doc__") == null) { - dict.__setitem__("__doc__", doc); - } return makeClass(name, bases, dict); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-12-30 15:38:51
|
Revision: 6958 http://jython.svn.sourceforge.net/jython/?rev=6958&view=rev Author: fwierzbicki Date: 2009-12-30 15:38:42 +0000 (Wed, 30 Dec 2009) Log Message: ----------- Fix for http://bugs.jython.org/issue1530: BoolOp in multiple assign causes VerifyError. Thanks to Philip Cannata for reporting the issue. I also added a test but unfortunately it had to be disabled until I can rework PythonPartial.g to also call this (and other) bad syntax invalid. Modified Paths: -------------- trunk/jython/Lib/test/test_codeop.py trunk/jython/NEWS trunk/jython/src/org/python/antlr/GrammarActions.java Modified: trunk/jython/Lib/test/test_codeop.py =================================================================== --- trunk/jython/Lib/test/test_codeop.py 2009-12-14 15:51:11 UTC (rev 6957) +++ trunk/jython/Lib/test/test_codeop.py 2009-12-30 15:38:42 UTC (rev 6958) @@ -292,7 +292,6 @@ ai("return 2.3") ai("if (a == 1 and b = 2): pass") - # XXX: PythonPartial.g needs to reject these. if not is_jython: ai("del 1") @@ -301,6 +300,7 @@ ai("del [1]") ai("del '1'") ai("[i for i in range(10)] = (1, 2, 3)") + ai("a = 1 and b = 2"); def test_filename(self): self.assertEquals(compile_command("a = 1\n", "abc").co_filename, Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-12-14 15:51:11 UTC (rev 6957) +++ trunk/jython/NEWS 2009-12-30 15:38:42 UTC (rev 6958) @@ -2,6 +2,7 @@ Jython 2.5.2a1 Bugs Fixed + - [ 1530 ] BoolOp in multiple assign causes VerifyError - [ 1478 ] defaultdict & weakref.WeakKeyDictionary [TypeError: first argument must be callable] - [ 1487 ] Import of module with latin-1 chars fails on utf-8 file encoding - [ 1449 ] Ellipsis comparison different from Python 2.5 to Jython 2.5 Modified: trunk/jython/src/org/python/antlr/GrammarActions.java =================================================================== --- trunk/jython/src/org/python/antlr/GrammarActions.java 2009-12-14 15:51:11 UTC (rev 6957) +++ trunk/jython/src/org/python/antlr/GrammarActions.java 2009-12-30 15:38:42 UTC (rev 6958) @@ -535,6 +535,8 @@ errorHandler.error("can't assign to yield expression", e); } else if (e instanceof BinOp) { errorHandler.error("can't assign to operator", e); + } else if (e instanceof BoolOp) { + errorHandler.error("can't assign to operator", e); } else if (e instanceof Lambda) { errorHandler.error("can't assign to lambda", e); } else if (e instanceof Call) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-12-14 15:51:23
|
Revision: 6957 http://jython.svn.sourceforge.net/jython/?rev=6957&view=rev Author: amak Date: 2009-12-14 15:51:11 +0000 (Mon, 14 Dec 2009) Log Message: ----------- Fix for bug 1515 modjy sometimes adds None to the sys.path http://bugs.jython.org/issue1515 Thanks to Victor Ng (crankycoder) for the report and the patch. Modified Paths: -------------- trunk/jython/Lib/modjy/modjy_publish.py Modified: trunk/jython/Lib/modjy/modjy_publish.py =================================================================== --- trunk/jython/Lib/modjy/modjy_publish.py 2009-12-09 07:48:45 UTC (rev 6956) +++ trunk/jython/Lib/modjy/modjy_publish.py 2009-12-14 15:51:11 UTC (rev 6957) @@ -34,7 +34,7 @@ else: self.app_directory = self.servlet_context.getRealPath('/') self.params['app_directory'] = self.app_directory - if not self.app_directory in sys.path: + if self.app_directory is not None and not self.app_directory in sys.path: sys.path.append(self.app_directory) def map_uri(self, req, environ): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |