From: <pj...@us...> - 2009-10-29 04:57:55
|
Revision: 6930 http://jython.svn.sourceforge.net/jython/?rev=6930&view=rev Author: pjenvey Date: 2009-10-29 04:57:43 +0000 (Thu, 29 Oct 2009) Log Message: ----------- expose PyStringMap so unsuspecting users of it avoid reflection costs Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/src/org/python/core/PyStringMap.java Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2009-10-29 04:28:03 UTC (rev 6929) +++ trunk/jython/CoreExposed.includes 2009-10-29 04:57:43 UTC (rev 6930) @@ -37,6 +37,7 @@ org/python/core/PySlot.class org/python/core/PyStaticMethod.class org/python/core/PyString.class +org/python/core/PyStringMap.class org/python/core/PySuper.class org/python/core/PyTraceback.class org/python/core/PyTuple.class Modified: trunk/jython/src/org/python/core/PyStringMap.java =================================================================== --- trunk/jython/src/org/python/core/PyStringMap.java 2009-10-29 04:28:03 UTC (rev 6929) +++ trunk/jython/src/org/python/core/PyStringMap.java 2009-10-29 04:57:43 UTC (rev 6930) @@ -1,4 +1,7 @@ -// Copyright (c) Corporation for National Research Initiatives +/* + * Copyright (c) Corporation for National Research Initiatives + * Copyright (c) Jython Developers + */ package org.python.core; import java.util.Collection; @@ -9,14 +12,25 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedType; +import org.python.expose.MethodType; import org.python.util.Generic; /** * Special fast dict implementation for __dict__ instances. Allows interned String keys in addition * to PyObject unlike PyDictionary. */ +@ExposedType(name = "stringmap", isBaseType = false) public class PyStringMap extends PyObject { + /** + * TYPE computed lazily, PyStringMap is used early in the bootstrap process and + * statically calling fromClass(PyStringMap.class) is unsafe. + */ + private static PyType lazyType; + private final ConcurrentMap<Object, PyObject> table; public PyStringMap() { @@ -24,11 +38,13 @@ } public PyStringMap(int capacity) { + super(getLazyType()); table = new ConcurrentHashMap<Object, PyObject>(capacity, Generic.CHM_LOAD_FACTOR, Generic.CHM_CONCURRENCY_LEVEL); } public PyStringMap(Map<Object, PyObject> map) { + super(getLazyType()); table = Generic.concurrentMap(); table.putAll(map); } @@ -40,14 +56,37 @@ } } + private static PyType getLazyType() { + if (lazyType == null) { + lazyType = PyType.fromClass(PyStringMap.class); + } + return lazyType; + } + + @ExposedNew + final static PyObject stringmap_new(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { + PyStringMap map = new PyStringMap(); + map.stringmap_update(args, keywords); + return map; + } + + @Override public int __len__() { + return stringmap___len__(); + } + + @ExposedMethod(doc = BuiltinDocs.dict___len___doc) + final int stringmap___len__() { return table.size(); } + @Override public boolean __nonzero__() { return table.size() != 0; } + @Override public PyObject __finditem__(String key) { if (key == null) { return null; @@ -55,6 +94,7 @@ return table.get(key); } + @Override public PyObject __finditem__(PyObject key) { if (key instanceof PyString) { return __finditem__(((PyString)key).internedString()); @@ -71,7 +111,13 @@ } } + @Override public PyObject __getitem__(PyObject key) { + return stringmap___getitem__(key); + } + + @ExposedMethod(doc = BuiltinDocs.dict___getitem___doc) + final PyObject stringmap___getitem__(PyObject key) { if (key instanceof PyString) { return __getitem__(((PyString)key).internedString()); } else { @@ -84,10 +130,17 @@ } } + @Override public PyObject __iter__() { - return iterkeys(); + return stringmap___iter__(); } + @ExposedMethod(doc = BuiltinDocs.dict___iter___doc) + final PyObject stringmap___iter__() { + return stringmap_iterkeys(); + } + + @Override public void __setitem__(String key, PyObject value) { if (value == null) { table.remove(key); @@ -96,7 +149,13 @@ } } + @Override public void __setitem__(PyObject key, PyObject value) { + stringmap___setitem__(key, value); + } + + @ExposedMethod(doc = BuiltinDocs.dict___setitem___doc) + final void stringmap___setitem__(PyObject key, PyObject value) { if (value == null) { table.remove(pyToKey(key)); } else if (key instanceof PyString) { @@ -106,6 +165,7 @@ } } + @Override public void __delitem__(String key) { Object ret = table.remove(key); if (ret == null) { @@ -113,7 +173,13 @@ } } + @Override public void __delitem__(PyObject key) { + stringmap___delitem__(key); + } + + @ExposedMethod(doc = BuiltinDocs.dict___delitem___doc) + final void stringmap___delitem__(PyObject key) { if (key instanceof PyString) { __delitem__(((PyString)key).internedString()); } else { @@ -128,10 +194,21 @@ * Remove all items from the dictionary. */ public void clear() { + stringmap_clear(); + } + + @ExposedMethod(doc = BuiltinDocs.dict_clear_doc) + final void stringmap_clear() { table.clear(); } + @Override public String toString() { + return stringmap_toString(); + } + + @ExposedMethod(names = {"__repr__", "__str__"}, doc = BuiltinDocs.dict___str___doc) + final String stringmap_toString() { ThreadState ts = Py.getThreadState(); if (!ts.enterRepr(this)) { return "{...}"; @@ -158,7 +235,13 @@ return buf.toString(); } + @Override public int __cmp__(PyObject other) { + return stringmap___cmp__(other); + } + + @ExposedMethod(type = MethodType.CMP, doc = BuiltinDocs.dict___cmp___doc) + final int stringmap___cmp__(PyObject other) { if (!(other instanceof PyStringMap || other instanceof PyDictionary)) { return -2; } @@ -204,26 +287,42 @@ } public boolean has_key(PyObject key) { + return stringmap_has_key(key); + } + + @ExposedMethod(doc = BuiltinDocs.dict_has_key_doc) + final boolean stringmap_has_key(PyObject key) { return table.containsKey(pyToKey(key)); } + @Override + public boolean __contains__(PyObject o) { + return stringmap___contains__(o); + } + + @ExposedMethod(doc = BuiltinDocs.dict___contains___doc) + final boolean stringmap___contains__(PyObject o) { + return stringmap_has_key(o); + } + /** - * Return this[key] if the key exists in the mapping, default_object is returned otherwise. + * Return this[key] if the key exists in the mapping, defaultObj is returned otherwise. * * @param key * the key to lookup in the mapping. - * @param default_object + * @param defaultObj * the value to return if the key does not exists in the mapping. */ - public PyObject get(PyObject key, PyObject default_object) { - PyObject o = __finditem__(key); - if (o == null) { - return default_object; - } else { - return o; - } + public PyObject get(PyObject key, PyObject defaultObj) { + return stringmap_get(key, defaultObj); } + @ExposedMethod(defaults = "Py.None", doc = BuiltinDocs.dict_get_doc) + final PyObject stringmap_get(PyObject key, PyObject defaultObj) { + PyObject obj = __finditem__(key); + return obj == null ? defaultObj : obj; + } + /** * Return this[key] if the key exists in the mapping, None is returned otherwise. * @@ -231,20 +330,30 @@ * the key to lookup in the mapping. */ public PyObject get(PyObject key) { - return get(key, Py.None); + return stringmap_get(key, Py.None); } /** * Return a shallow copy of the dictionary. */ public PyStringMap copy() { + return stringmap_copy(); + } + + @ExposedMethod(doc = BuiltinDocs.dict_copy_doc) + final PyStringMap stringmap_copy() { return new PyStringMap(table); } + public void update(PyObject other) { + stringmap_update(new PyObject[] {other}, Py.NoKeywords); + } + /** * Insert all the key:value pairs from <code>dict</code> into this mapping. */ - public void update(PyObject[] args, String[] keywords) { + @ExposedMethod(doc = BuiltinDocs.dict_update_doc) + final void stringmap_update(PyObject[] args, String[] keywords) { int nargs = args.length - keywords.length; if (nargs > 1) { throw PyBuiltinCallable.DefaultInfo.unexpectedCall(nargs, false, "update", 0, 1); @@ -339,19 +448,25 @@ * the default value to insert in the mapping if key does not already exist. */ public PyObject setdefault(PyObject key, PyObject failobj) { + return stringmap_setdefault(key, failobj); + } + + @ExposedMethod(defaults = "Py.None", doc = BuiltinDocs.dict_setdefault_doc) + final PyObject stringmap_setdefault(PyObject key, PyObject failobj) { Object internedKey = (key instanceof PyString) ? ((PyString)key).internedString() : key; PyObject oldValue = table.putIfAbsent(internedKey, failobj); - if (oldValue == null) { - return failobj; - } else { - return oldValue; - } + return oldValue == null ? failobj : oldValue; } /** * Return a random (key, value) tuple pair and remove the pair from the mapping. */ public PyObject popitem() { + return stringmap_popitem(); + } + + @ExposedMethod(doc = BuiltinDocs.dict_popitem_doc) + final PyObject stringmap_popitem() { Iterator<Entry<Object, PyObject>> it = table.entrySet().iterator(); if (!it.hasNext()) { throw Py.KeyError("popitem(): dictionary is empty"); @@ -366,10 +481,15 @@ if (table.size() == 0) { throw Py.KeyError("pop(): dictionary is empty"); } - return pop(key, null); + return stringmap_pop(key, null); } public PyObject pop(PyObject key, PyObject failobj) { + return stringmap_pop(key, failobj); + } + + @ExposedMethod(defaults = "null", doc = BuiltinDocs.dict_pop_doc) + final PyObject stringmap_pop(PyObject key, PyObject failobj) { PyObject value = table.remove(pyToKey(key)); if (value == null) { if (failobj == null) { @@ -385,9 +505,14 @@ * Return a copy of the mappings list of (key, value) tuple pairs. */ public PyList items() { - return new PyList(iteritems()); + return stringmap_items(); } + @ExposedMethod(doc = BuiltinDocs.dict_items_doc) + final PyList stringmap_items() { + return new PyList(stringmap_iteritems()); + } + private PyTuple itemTuple(Entry<Object, PyObject> entry) { return new PyTuple(keyToPy(entry.getKey()), entry.getValue()); } @@ -397,6 +522,11 @@ * storing String or PyObject objects */ public PyList keys() { + return stringmap_keys(); + } + + @ExposedMethod(doc = BuiltinDocs.dict_keys_doc) + final PyList stringmap_keys() { PyObject[] keyArray = new PyObject[table.size()]; int i = 0; for (Object key : table.keySet()) { @@ -409,6 +539,11 @@ * Return a copy of the mappings list of values. */ public PyList values() { + return stringmap_values(); + } + + @ExposedMethod(doc = BuiltinDocs.dict_values_doc) + final PyList stringmap_values() { return new PyList(table.values()); } @@ -416,15 +551,25 @@ * return an iterator over (key, value) pairs */ public PyObject iteritems() { + return stringmap_iteritems(); + } + + @ExposedMethod(doc = BuiltinDocs.dict_iteritems_doc) + final PyObject stringmap_iteritems() { return new ItemsIter(table.entrySet()); } /** * return an iterator over the keys */ - // Python allows one to change the dict while iterating over it, - // including deletion. Java does not. Can we resolve with CHM? public PyObject iterkeys() { + return stringmap_iterkeys(); + } + + @ExposedMethod(doc = BuiltinDocs.dict_iterkeys_doc) + final PyObject stringmap_iterkeys() { + // Python allows one to change the dict while iterating over it, including + // deletion. Java does not. Can we resolve with CHM? return new KeysIter(table.keySet()); } @@ -432,10 +577,25 @@ * return an iterator over the values */ public PyObject itervalues() { + return stringmap_itervalues(); + } + + @ExposedMethod(doc = BuiltinDocs.dict_itervalues_doc) + final PyObject stringmap_itervalues() { return new ValuesIter(table.values()); } @Override + public int hashCode() { + return stringmap___hash__(); + } + + @ExposedMethod(doc = BuiltinDocs.dict___hash___doc) + final int stringmap___hash__() { + throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName())); + } + + @Override public boolean isMappingType() { return true; } @@ -456,6 +616,7 @@ size = c.size(); } + @Override public PyObject __iternext__() { if (table.size() != size) { throw Py.RuntimeError("dictionary changed size during iteration"); @@ -475,7 +636,8 @@ super(c); } - public PyObject stringMapNext() { + @Override + public PyObject stringMapNext() { return iterator.next(); } } @@ -486,6 +648,7 @@ super(s); } + @Override protected PyObject stringMapNext() { return keyToPy(iterator.next()); } @@ -497,6 +660,7 @@ super(s); } + @Override public PyObject stringMapNext() { return itemTuple(iterator.next()); } @@ -517,8 +681,4 @@ return pyKey; } } - - public int hashCode() { - throw Py.TypeError(String.format("unhashable type: '%.200s'", getType().fastGetName())); - } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-10-30 01:34:27
|
Revision: 6933 http://jython.svn.sourceforge.net/jython/?rev=6933&view=rev Author: pjenvey Date: 2009-10-30 01:34:16 +0000 (Fri, 30 Oct 2009) Log Message: ----------- correct the numeric check on the right side Modified Paths: -------------- trunk/jython/Lib/test/test_builtin_jy.py trunk/jython/src/org/python/core/PyObject.java Modified: trunk/jython/Lib/test/test_builtin_jy.py =================================================================== --- trunk/jython/Lib/test/test_builtin_jy.py 2009-10-29 07:19:33 UTC (rev 6932) +++ trunk/jython/Lib/test/test_builtin_jy.py 2009-10-30 01:34:16 UTC (rev 6933) @@ -29,6 +29,7 @@ # http://bugs.jython.org/issue1449 for numeric in 1, 2L, 3.0, 4j: self.assertTrue(numeric < Ellipsis) + self.assertTrue(Ellipsis > numeric) class LoopTest(unittest.TestCase): Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-10-29 07:19:33 UTC (rev 6932) +++ trunk/jython/src/org/python/core/PyObject.java 2009-10-30 01:34:16 UTC (rev 6933) @@ -1321,7 +1321,7 @@ // different type: compare type names; numbers are smaller String typeName = isNumberType() ? "" : type.fastGetName(); - String otherTypeName = otherType.isNumberType() ? "" : otherType.fastGetName(); + String otherTypeName = other.isNumberType() ? "" : otherType.fastGetName(); result = typeName.compareTo(otherTypeName); if (result == 0) { // Same type name, or (more likely) incomparable numeric types This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <le...@us...> - 2009-11-04 01:11:32
|
Revision: 6937 http://jython.svn.sourceforge.net/jython/?rev=6937&view=rev Author: leosoto Date: 2009-11-04 01:11:20 +0000 (Wed, 04 Nov 2009) Log Message: ----------- Fix for issue 1499: PostgreSQL data handler now return Decimals for NUMERIC columns Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/com/ziclix/python/sql/handler/PostgresqlDataHandler.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-10-31 01:48:29 UTC (rev 6936) +++ trunk/jython/NEWS 2009-11-04 01:11:20 UTC (rev 6937) @@ -8,6 +8,7 @@ - [ 1493 ] tarfile.extractall() throws "AttributeError: 'module' object has no attribute 'chown'" when called by root - [ 1470 ] os.mkdir Errno difference from cpython - [ 1496 ] fix os.listdir errno for non-existing dirs + - [ 1499 ] PostgreSQL datahandler should return Decimals instead of floats for NUMERIC/DECIMAL columns - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) Modified: trunk/jython/src/com/ziclix/python/sql/handler/PostgresqlDataHandler.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/handler/PostgresqlDataHandler.java 2009-10-31 01:48:29 UTC (rev 6936) +++ trunk/jython/src/com/ziclix/python/sql/handler/PostgresqlDataHandler.java 2009-11-04 01:11:20 UTC (rev 6937) @@ -61,7 +61,7 @@ case Types.DECIMAL: BigDecimal bd = set.getBigDecimal(col); - obj = (bd == null) ? Py.None : Py.newFloat(bd.doubleValue()); + obj = (bd == null) ? Py.None : Py.newDecimal(bd.toString()); break; case Types.OTHER: @@ -78,7 +78,6 @@ default : obj = super.getPyObject(set, col, type); } - return (set.wasNull() || (obj == null)) ? Py.None : obj; } @@ -108,7 +107,7 @@ } else { varchar = (String) object.__tojava__(String.class); } - + stmt.setObject(index, varchar, type); break; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-11-09 00:08:41
|
Revision: 6941 http://jython.svn.sourceforge.net/jython/?rev=6941&view=rev Author: pjenvey Date: 2009-11-09 00:08:21 +0000 (Mon, 09 Nov 2009) Log Message: ----------- swap jna/jna-posix for jffi 0.6.2/jaffl 0.4.1-57919f3abc0a/jnr-posix 1.0.6-044e3646a308 Modified Paths: -------------- trunk/jython/.classpath trunk/jython/build.xml Added Paths: ----------- trunk/jython/extlibs/jaffl.jar trunk/jython/extlibs/jffi-Darwin.jar trunk/jython/extlibs/jffi-i386-FreeBSD.jar trunk/jython/extlibs/jffi-i386-Linux.jar trunk/jython/extlibs/jffi-i386-OpenBSD.jar trunk/jython/extlibs/jffi-i386-SunOS.jar trunk/jython/extlibs/jffi-i386-Windows.jar trunk/jython/extlibs/jffi-ppc-AIX.jar trunk/jython/extlibs/jffi-s390x-Linux.jar trunk/jython/extlibs/jffi-sparc-SunOS.jar trunk/jython/extlibs/jffi-sparcv9-SunOS.jar trunk/jython/extlibs/jffi-x86_64-FreeBSD.jar trunk/jython/extlibs/jffi-x86_64-Linux.jar trunk/jython/extlibs/jffi-x86_64-OpenBSD.jar trunk/jython/extlibs/jffi-x86_64-SunOS.jar trunk/jython/extlibs/jffi.jar trunk/jython/extlibs/jnr-posix.jar Removed Paths: ------------- trunk/jython/extlibs/jna-posix.jar trunk/jython/extlibs/jna.jar Modified: trunk/jython/.classpath =================================================================== --- trunk/jython/.classpath 2009-11-08 22:59:13 UTC (rev 6940) +++ trunk/jython/.classpath 2009-11-09 00:08:21 UTC (rev 6941) @@ -17,10 +17,25 @@ <classpathentry kind="lib" path="extlibs/asm-3.1.jar"/> <classpathentry kind="lib" path="extlibs/asm-commons-3.1.jar"/> <classpathentry kind="lib" path="extlibs/constantine.jar"/> - <classpathentry kind="lib" path="extlibs/jna-posix.jar"/> <classpathentry kind="lib" path="extlibs/mockrunner-0.4.1/jar/jdom.jar"/> <classpathentry kind="lib" path="extlibs/mockrunner-0.4.1/lib/jdk1.5/j2ee1.3/mockrunner-servlet.jar"/> - <classpathentry kind="lib" path="extlibs/jna.jar"/> <classpathentry kind="lib" path="extlibs/livetribe-jsr223-2.0.5.jar"/> + <classpathentry kind="lib" path="extlibs/jaffl.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-Darwin.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-i386-FreeBSD.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-i386-Linux.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-i386-OpenBSD.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-i386-SunOS.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-i386-Windows.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-ppc-AIX.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-s390x-Linux.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-sparc-SunOS.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-sparcv9-SunOS.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-x86_64-FreeBSD.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-x86_64-Linux.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-x86_64-OpenBSD.jar"/> + <classpathentry kind="lib" path="extlibs/jffi-x86_64-SunOS.jar"/> + <classpathentry kind="lib" path="extlibs/jffi.jar"/> + <classpathentry kind="lib" path="extlibs/jnr-posix.jar"/> <classpathentry kind="output" path="build/classes"/> </classpath> Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-11-08 22:59:13 UTC (rev 6940) +++ trunk/jython/build.xml 2009-11-09 00:08:21 UTC (rev 6941) @@ -190,8 +190,23 @@ <pathelement path="${extlibs.dir}/asm-3.1.jar" /> <pathelement path="${extlibs.dir}/asm-commons-3.1.jar" /> <pathelement path="${extlibs.dir}/constantine.jar" /> - <pathelement path="${extlibs.dir}/jna.jar"/> - <pathelement path="${extlibs.dir}/jna-posix.jar"/> + <pathelement path="${extlibs.dir}/jaffl.jar"/> + <pathelement path="${extlibs.dir}/jffi-Darwin.jar"/> + <pathelement path="${extlibs.dir}/jffi-i386-FreeBSD.jar"/> + <pathelement path="${extlibs.dir}/jffi-i386-Linux.jar"/> + <pathelement path="${extlibs.dir}/jffi-i386-OpenBSD.jar"/> + <pathelement path="${extlibs.dir}/jffi-i386-SunOS.jar"/> + <pathelement path="${extlibs.dir}/jffi-i386-Windows.jar"/> + <pathelement path="${extlibs.dir}/jffi-ppc-AIX.jar"/> + <pathelement path="${extlibs.dir}/jffi-s390x-Linux.jar"/> + <pathelement path="${extlibs.dir}/jffi-sparc-SunOS.jar"/> + <pathelement path="${extlibs.dir}/jffi-sparcv9-SunOS.jar"/> + <pathelement path="${extlibs.dir}/jffi-x86_64-FreeBSD.jar"/> + <pathelement path="${extlibs.dir}/jffi-x86_64-Linux.jar"/> + <pathelement path="${extlibs.dir}/jffi-x86_64-OpenBSD.jar"/> + <pathelement path="${extlibs.dir}/jffi-x86_64-SunOS.jar"/> + <pathelement path="${extlibs.dir}/jffi.jar"/> + <pathelement path="${extlibs.dir}/jnr-posix.jar"/> </path> <available property="informix.present" classname="com.informix.jdbc.IfxDriver" classpath="${informix.jar}" /> @@ -569,8 +584,23 @@ <zipfileset src="extlibs/asm-commons-3.1.jar"/> <zipfileset src="extlibs/asm-util-3.1.jar"/> <rule pattern="org.objectweb.asm.**" result="org.python.objectweb.asm.@1"/> - <zipfileset src="extlibs/jna.jar"/> - <zipfileset src="extlibs/jna-posix.jar"/> + <zipfileset src="extlibs/jaffl.jar"/> + <zipfileset src="extlibs/jffi-Darwin.jar"/> + <zipfileset src="extlibs/jffi-i386-FreeBSD.jar"/> + <zipfileset src="extlibs/jffi-i386-Linux.jar"/> + <zipfileset src="extlibs/jffi-i386-OpenBSD.jar"/> + <zipfileset src="extlibs/jffi-i386-SunOS.jar"/> + <zipfileset src="extlibs/jffi-i386-Windows.jar"/> + <zipfileset src="extlibs/jffi-ppc-AIX.jar"/> + <zipfileset src="extlibs/jffi-s390x-Linux.jar"/> + <zipfileset src="extlibs/jffi-sparc-SunOS.jar"/> + <zipfileset src="extlibs/jffi-sparcv9-SunOS.jar"/> + <zipfileset src="extlibs/jffi-x86_64-FreeBSD.jar"/> + <zipfileset src="extlibs/jffi-x86_64-Linux.jar"/> + <zipfileset src="extlibs/jffi-x86_64-OpenBSD.jar"/> + <zipfileset src="extlibs/jffi-x86_64-SunOS.jar"/> + <zipfileset src="extlibs/jffi.jar"/> + <zipfileset src="extlibs/jnr-posix.jar"/> <!-- <rule pattern="com.sun.jna.**" result="org.python.jna.@1"/> --> <rule pattern="org.jruby.ext.posix.**" result="org.python.posix.@1"/> <zipfileset src="extlibs/constantine.jar"/> Added: trunk/jython/extlibs/jaffl.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jaffl.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-Darwin.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-Darwin.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-i386-FreeBSD.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-i386-FreeBSD.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-i386-Linux.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-i386-Linux.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-i386-OpenBSD.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-i386-OpenBSD.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-i386-SunOS.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-i386-SunOS.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-i386-Windows.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-i386-Windows.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-ppc-AIX.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-ppc-AIX.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-s390x-Linux.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-s390x-Linux.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-sparc-SunOS.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-sparc-SunOS.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-sparcv9-SunOS.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-sparcv9-SunOS.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-x86_64-FreeBSD.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-x86_64-FreeBSD.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-x86_64-Linux.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-x86_64-Linux.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-x86_64-OpenBSD.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-x86_64-OpenBSD.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-x86_64-SunOS.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-x86_64-SunOS.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Deleted: trunk/jython/extlibs/jna-posix.jar =================================================================== (Binary files differ) Deleted: trunk/jython/extlibs/jna.jar =================================================================== (Binary files differ) Added: trunk/jython/extlibs/jnr-posix.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jnr-posix.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-11-16 01:58:12
|
Revision: 6945 http://jython.svn.sourceforge.net/jython/?rev=6945&view=rev Author: pjenvey Date: 2009-11-16 01:58:00 +0000 (Mon, 16 Nov 2009) Log Message: ----------- fix chown's visibility and posix.setpgrp and port the remaining posix calls to PosixModule fixes #1477 Modified Paths: -------------- trunk/jython/Lib/posix.py trunk/jython/NEWS trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-11-15 05:18:17 UTC (rev 6944) +++ trunk/jython/Lib/posix.py 2009-11-16 01:58:00 UTC (rev 6945) @@ -14,7 +14,7 @@ import sys __all__ = [name for name in _posix.__all__ if not name.startswith('__doc__')] -__all__.extend(['fsync', 'getenv', 'isatty', 'popen', 'putenv', +__all__.extend(['getenv', 'isatty', 'popen', 'putenv', 'rename', 'rmdir', 'system', 'unsetenv', 'urandom', 'utime']) @@ -169,153 +169,6 @@ import os return os.environ.get(key, default) -if _name == 'posix': - def symlink(src, dst): - """symlink(src, dst) - - Create a symbolic link pointing to src named dst. - """ - _posix_impl.symlink(src, sys.getPath(dst)) - - def readlink(path): - """readlink(path) -> path - - Return a string representing the path to which the symbolic link - points. - """ - return _posix_impl.readlink(sys.getPath(path)) - - def getegid(): - """getegid() -> egid - - Return the current process's effective group id.""" - return _posix_impl.getegid() - - def geteuid(): - """geteuid() -> euid - - Return the current process's effective user id.""" - return _posix_impl.geteuid() - - def getgid(): - """getgid() -> gid - - Return the current process's group id.""" - return _posix_impl.getgid() - - def getlogin(): - """getlogin() -> string - - Return the actual login name.""" - return _posix_impl.getlogin() - - def getpgrp(): - """getpgrp() -> pgrp - - Return the current process group id.""" - return _posix_impl.getpgrp() - - def getppid(): - """getppid() -> ppid - - Return the parent's process id.""" - return _posix_impl.getppid() - - def getuid(): - """getuid() -> uid - - Return the current process's user id.""" - return _posix_impl.getuid() - - def setpgrp(): - """setpgrp() - - Make this process a session leader.""" - return _posix_impl.setpgrp() - - def setsid(): - """setsid() - - Call the system call setsid().""" - return _posix_impl.setsid() - - # This implementation of fork partially works on - # Jython. Diagnosing what works, what doesn't, and fixing it is - # left for another day. In any event, this would only be - # marginally useful. - - # def fork(): - # """fork() -> pid - # - # Fork a child process. - # Return 0 to child process and PID of child to parent process.""" - # return _posix_impl.fork() - - def kill(pid, sig): - """kill(pid, sig) - - Kill a process with a signal.""" - return _posix_impl.kill(pid, sig) - - def wait(): - """wait() -> (pid, status) - - Wait for completion of a child process.""" - import jarray - status = jarray.zeros(1, 'i') - res_pid = _posix_impl.wait(status) - if res_pid == -1: - raise OSError(status[0], strerror(status[0])) - return res_pid, status[0] - - def waitpid(pid, options): - """waitpid(pid, options) -> (pid, status) - - Wait for completion of a given child process.""" - import jarray - status = jarray.zeros(1, 'i') - res_pid = _posix_impl.waitpid(pid, status, options) - if res_pid == -1: - raise OSError(status[0], strerror(status[0])) - return res_pid, status[0] - - def fdatasync(fd): - """fdatasync(fildes) - - force write of file with filedescriptor to disk. - does not force update of metadata. - """ - _fsync(fd, False) - - __all__.extend(['symlink', 'readlink', 'getegid', 'geteuid', - 'getgid', 'getlogin', 'getpgrp', 'getppid', 'getuid', - 'setpgrp', 'setsid', 'kill', 'wait', 'waitpid', - 'fdatasync']) - -def fsync(fd): - """fsync(fildes) - - force write of file with filedescriptor to disk. - """ - _fsync(fd, True) - -def _fsync(fd, metadata): - """Internal fsync impl""" - from org.python.core.io import FileDescriptors - rawio = FileDescriptors.get(fd) - rawio.checkClosed() - - from java.io import IOException - from java.nio.channels import FileChannel - channel = rawio.getChannel() - if not isinstance(channel, FileChannel): - raise OSError(errno.EINVAL, strerror(errno.EINVAL)) - - try: - channel.force(metadata) - except IOException, ioe: - raise OSError(ioe) - def isatty(fileno): """isatty(fd) -> bool Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-11-15 05:18:17 UTC (rev 6944) +++ trunk/jython/NEWS 2009-11-16 01:58:00 UTC (rev 6945) @@ -9,6 +9,7 @@ - [ 1470 ] os.mkdir Errno difference from cpython - [ 1496 ] fix os.listdir errno for non-existing dirs - [ 1499 ] PostgreSQL datahandler should return Decimals instead of floats for NUMERIC/DECIMAL columns + - [ 1477 ] os.setpgrp and posix.setpgrp fail with TypeError - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-11-15 05:18:17 UTC (rev 6944) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-11-16 01:58:00 UTC (rev 6945) @@ -9,6 +9,9 @@ import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; +import java.nio.channels.Channel; +import java.nio.channels.ClosedChannelException; +import java.nio.channels.FileChannel; import java.util.Map; import org.jruby.ext.posix.FileStat; @@ -199,7 +202,7 @@ public static PyString __doc__chown = new PyString( "chown(path, uid, gid)\n\n" + "Change the owner and group id of path to the numeric uid and gid."); - @Hide(OS.POSIX) + @Hide(OS.NT) public static void chown(String path, int uid, int gid) { if (posix.chown(absolutePath(path), uid, gid) < 0) { throw errorFromErrno(path); @@ -248,6 +251,43 @@ } } + public static PyString __doc__fdatasync = new PyString( + "fdatasync(fildes)\n\n" + + "force write of file with filedescriptor to disk.\n" + + "does not force update of metadata."); + @Hide(OS.NT) + public static void fdatasync(PyObject fd) { + fsync(fd, false); + } + + public static PyString __doc__fsync = new PyString( + "fsync(fildes)\n\n" + + "force write of file with filedescriptor to disk."); + public static void fsync(PyObject fd) { + fsync(fd, true); + } + + /** + * Internal fsync implementation. + */ + private static void fsync(PyObject fd, boolean metadata) { + RawIOBase rawIO = FileDescriptors.get(fd); + rawIO.checkClosed(); + Channel channel = rawIO.getChannel(); + if (!(channel instanceof FileChannel)) { + throw Py.OSError(Errno.EINVAL); + } + + try { + ((FileChannel)channel).force(metadata); + } catch (ClosedChannelException cce) { + // In the rare case it's closed but the rawIO wasn't + throw Py.ValueError("I/O operation on closed file"); + } catch (IOException ioe) { + throw Py.OSError(ioe); + } + } + public static PyString __doc__ftruncate = new PyString( "ftruncate(fd, length)\n\n" + "Truncate a file to a specified length."); @@ -273,6 +313,54 @@ return Py.newUnicode(Py.getSystemState().getCurrentWorkingDir()); } + public static PyString __doc__getegid = new PyString( + "getegid() -> egid\n\n" + + "Return the current process's effective group id."); + @Hide(OS.NT) + public static int getegid() { + return posix.getegid(); + } + + public static PyString __doc__geteuid = new PyString( + "geteuid() -> euid\n\n" + + "Return the current process's effective user id."); + @Hide(OS.NT) + public static int geteuid() { + return posix.geteuid(); + } + + public static PyString __doc__getgid = new PyString( + "getgid() -> gid\n\n" + + "Return the current process's group id."); + @Hide(OS.NT) + public static int getgid() { + return posix.getgid(); + } + + public static PyString __doc__getlogin = new PyString( + "getlogin() -> string\n\n" + + "Return the actual login name."); + @Hide(OS.NT) + public static PyObject getlogin() { + return new PyString(posix.getlogin()); + } + + public static PyString __doc__getppid = new PyString( + "getppid() -> ppid\n\n" + + "Return the parent's process id."); + @Hide(OS.NT) + public static int getppid() { + return posix.getppid(); + } + + public static PyString __doc__getuid = new PyString( + "getuid() -> uid\n\n" + + "Return the current process's user id."); + @Hide(OS.NT) + public static int getuid() { + return posix.getuid(); + } + public static PyString __doc__getpid = new PyString( "getpid() -> pid\n\n" + "Return the current process id"); @@ -281,6 +369,46 @@ return posix.getpid(); } + public static PyString __doc__getpgrp = new PyString( + "getpgrp() -> pgrp\n\n" + + "Return the current process group id."); + @Hide(OS.NT) + public static int getpgrp() { + return posix.getpgrp(); + } + + public static PyString __doc__kill = new PyString( + "kill(pid, sig)\n\n" + + "Kill a process with a signal."); + @Hide(OS.NT) + public static void kill(int pid, int sig) { + if (posix.kill(pid, sig) < 0) { + throw errorFromErrno(); + } + } + + public static PyString __doc__lchmod = new PyString( + "lchmod(path, mode)\n\n" + + "Change the access permissions of a file. If path is a symlink, this\n" + + "affects the link itself rather than the target."); + @Hide(OS.NT) + public static void lchmod(String path, int mode) { + if (posix.lchmod(absolutePath(path), mode) < 0) { + throw errorFromErrno(path); + } + } + + public static PyString __doc__lchown = new PyString( + "lchown(path, uid, gid)\n\n" + + "Change the owner and group id of path to the numeric uid and gid.\n" + + "This function will not follow symbolic links."); + @Hide(OS.NT) + public static void lchown(String path, int uid, int gid) { + if (posix.lchown(absolutePath(path), uid, gid) < 0) { + throw errorFromErrno(path); + } + } + public static PyString __doc__link = new PyString( "link(src, dst)\n\n" + "Create a hard link to a file."); @@ -417,6 +545,18 @@ } } + public static PyString __doc__readlink = new PyString( + "readlink(path) -> path\n\n" + + "Return a string representing the path to which the symbolic link points."); + @Hide(OS.NT) + public static String readlink(String path) { + try { + return posix.readlink(absolutePath(path)); + } catch (IOException ioe) { + throw Py.OSError(ioe); + } + } + public static PyString __doc__remove = new PyString( "remove(path)\n\n" + "Remove a file (same as unlink(path))."); @@ -424,6 +564,26 @@ unlink(path); } + public static PyString __doc__setpgrp = new PyString( + "setpgrp()\n\n" + + "Make this process a session leader."); + @Hide(OS.NT) + public static void setpgrp() { + if (posix.setpgrp(0, 0) < 0) { + throw errorFromErrno(); + } + } + + public static PyString __doc__setsid = new PyString( + "setsid()\n\n" + + "Call the system call setsid()."); + @Hide(OS.NT) + public static void setsid() { + if (posix.setsid() < 0) { + throw errorFromErrno(); + } + } + public static PyString __doc__strerror = new PyString( "strerror(code) -> string\n\n" + "Translate an error code to a message string."); @@ -441,6 +601,15 @@ return new PyString(errno.toString()); } + public static PyString __doc__symlink = new PyString( + "symlink(src, dst)\n\n" + + "Create a symbolic link pointing to src named dst."); + @Hide(OS.NT) + public static void symlink(String src, String dst) { + ensurePath(src); + posix.symlink(src, absolutePath(dst)); + } + public static PyString __doc__umask = new PyString( "umask(new_mask) -> old_mask\n\n" + "Set the current numeric umask and return the previous umask."); @@ -469,6 +638,31 @@ } } + public static PyString __doc__wait = new PyString( + "wait() -> (pid, status)\n\n" + + "Wait for completion of a child process."); + @Hide(OS.NT) + public static PyObject wait$() { + int[] status = new int[1]; + int pid = posix.wait(status); + if (pid < 0) { + throw errorFromErrno(); + } + return new PyTuple(Py.newInteger(pid), Py.newInteger(status[0])); + } + + public static PyString __doc__waitpid = new PyString( + "wait() -> (pid, status)\n\n" + + "Wait for completion of a child process."); + public static PyObject waitpid(int pid, int options) { + int[] status = new int[1]; + pid = posix.waitpid(pid, status, options); + if (pid < 0) { + throw errorFromErrno(); + } + return new PyTuple(Py.newInteger(pid), Py.newInteger(status[0])); + } + public static PyString __doc__write = new PyString( "write(fd, string) -> byteswritten\n\n" + "Write a string to a file descriptor."); @@ -539,6 +733,10 @@ return Py.OSError(Errno.EBADF); } + private static PyException errorFromErrno() { + return Py.OSError(Errno.valueOf(posix.errno())); + } + private static PyException errorFromErrno(String path) { return Py.OSError(Errno.valueOf(posix.errno()), path); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-11-22 20:24:52
|
Revision: 6947 http://jython.svn.sourceforge.net/jython/?rev=6947&view=rev Author: pjenvey Date: 2009-11-22 20:24:31 +0000 (Sun, 22 Nov 2009) Log Message: ----------- o add PyObject.asLong, remove asLong(int) uses o fix PyString not overriding asDouble o asDouble already __float__s for us in Condition.wait Modified Paths: -------------- trunk/jython/Lib/test/test_builtin_jy.py trunk/jython/src/org/python/core/PyFile.java trunk/jython/src/org/python/core/PyInteger.java trunk/jython/src/org/python/core/PyLong.java trunk/jython/src/org/python/core/PyObject.java trunk/jython/src/org/python/core/PyString.java trunk/jython/src/org/python/modules/_threading/Condition.java trunk/jython/src/org/python/modules/random/PyRandom.java Modified: trunk/jython/Lib/test/test_builtin_jy.py =================================================================== --- trunk/jython/Lib/test/test_builtin_jy.py 2009-11-17 16:16:14 UTC (rev 6946) +++ trunk/jython/Lib/test/test_builtin_jy.py 2009-11-22 20:24:31 UTC (rev 6947) @@ -136,6 +136,8 @@ def test_round_non_float(self): self.assertEqual(round(self.Foo(), 1), 3.1) + # 2.5/2.5.1 regression + self.assertRaises(TypeError, round, '1.5') class ExecEvalTest(unittest.TestCase): Modified: trunk/jython/src/org/python/core/PyFile.java =================================================================== --- trunk/jython/src/org/python/core/PyFile.java 2009-11-17 16:16:14 UTC (rev 6946) +++ trunk/jython/src/org/python/core/PyFile.java 2009-11-22 20:24:31 UTC (rev 6947) @@ -464,11 +464,7 @@ file_truncate(); return; } - try { - file_truncate(position.asLong(0)); - } catch (PyObject.ConversionException ce) { - throw Py.TypeError("an integer is required"); - } + file_truncate(position.asLong()); } final synchronized void file_truncate(long position) { Modified: trunk/jython/src/org/python/core/PyInteger.java =================================================================== --- trunk/jython/src/org/python/core/PyInteger.java 2009-11-17 16:16:14 UTC (rev 6946) +++ trunk/jython/src/org/python/core/PyInteger.java 2009-11-22 20:24:31 UTC (rev 6947) @@ -854,4 +854,9 @@ public int asInt() { return getValue(); } + + @Override + public long asLong() { + return getValue(); + } } Modified: trunk/jython/src/org/python/core/PyLong.java =================================================================== --- trunk/jython/src/org/python/core/PyLong.java 2009-11-17 16:16:14 UTC (rev 6946) +++ trunk/jython/src/org/python/core/PyLong.java 2009-11-22 20:24:31 UTC (rev 6947) @@ -199,7 +199,7 @@ } public long asLong(int index) { - return getLong(Long.MIN_VALUE, Long.MAX_VALUE, "long too big to convert"); + return asLong(); } public int asInt(int index) { @@ -213,6 +213,11 @@ "long int too large to convert to int"); } + @Override + public long asLong() { + return getLong(Long.MIN_VALUE, Long.MAX_VALUE, "long too big to convert"); + } + public Object __tojava__(Class c) { try { if (c == Byte.TYPE || c == Byte.class) { Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-11-17 16:16:14 UTC (rev 6946) +++ trunk/jython/src/org/python/core/PyObject.java 2009-11-22 20:24:31 UTC (rev 6947) @@ -4006,6 +4006,11 @@ throw new ConversionException(index); } + /** + * Convert this object into an int. Throws a PyException on failure. + * + * @return an int value + */ public int asInt() { PyObject intObj; try { @@ -4016,7 +4021,7 @@ } throw pye; } - if (!(intObj instanceof PyInteger) && !(intObj instanceof PyLong)) { + if (!(intObj instanceof PyInteger || intObj instanceof PyLong)) { // Shouldn't happen except with buggy builtin types throw Py.TypeError("nb_int should return int object"); } @@ -4028,6 +4033,28 @@ } /** + * Convert this object longo an long. Throws a PyException on failure. + * + * @return an long value + */ + public long asLong() { + PyObject longObj; + try { + longObj = __long__(); + } catch (PyException pye) { + if (pye.match(Py.AttributeError)) { + throw Py.TypeError("an integer is required"); + } + throw pye; + } + if (!(longObj instanceof PyLong)) { + // Shouldn't happen except with buggy builtin types + throw Py.TypeError("integer conversion failed"); + } + return longObj.asLong(); + } + + /** * Convert this object into a double. Throws a PyException on failure. * * @return a double value Modified: trunk/jython/src/org/python/core/PyString.java =================================================================== --- trunk/jython/src/org/python/core/PyString.java 2009-11-17 16:16:14 UTC (rev 6946) +++ trunk/jython/src/org/python/core/PyString.java 2009-11-22 20:24:31 UTC (rev 6947) @@ -2459,13 +2459,29 @@ @Override public int asInt() { - // We have to override asInt because we override __int__, but generally don't want - // implicit atoi conversions for the base types. blah + // We have to override asInt/Long/Double because we override __int/long/float__, + // but generally don't want implicit atoi conversions for the base types. blah + asNumberCheck("__int__", "an integer"); + return super.asInt(); + } + + @Override + public long asLong() { + asNumberCheck("__long__", "an integer"); + return super.asLong(); + } + + @Override + public double asDouble() { + asNumberCheck("__float__", "a float"); + return super.asDouble(); + } + + private void asNumberCheck(String methodName, String description) { PyType type = getType(); - if (type == PyString.TYPE || type == PyUnicode.TYPE || type.lookup("__int__") == null) { - throw Py.TypeError("an integer is required"); + if (type == PyString.TYPE || type == PyUnicode.TYPE || type.lookup(methodName) == null) { + throw Py.TypeError(description + " is required"); } - return super.asInt(); } public String asName(int index) throws PyObject.ConversionException { Modified: trunk/jython/src/org/python/modules/_threading/Condition.java =================================================================== --- trunk/jython/src/org/python/modules/_threading/Condition.java 2009-11-17 16:16:14 UTC (rev 6946) +++ trunk/jython/src/org/python/modules/_threading/Condition.java 2009-11-22 20:24:31 UTC (rev 6947) @@ -86,7 +86,7 @@ if (timeout == Py.None) { _condition.await(); } else { - long nanos = (long) (timeout.__float__().asDouble() * 1e9); + long nanos = (long) (timeout.asDouble() * 1e9); _condition.awaitNanos(nanos); } } Modified: trunk/jython/src/org/python/modules/random/PyRandom.java =================================================================== --- trunk/jython/src/org/python/modules/random/PyRandom.java 2009-11-17 16:16:14 UTC (rev 6946) +++ trunk/jython/src/org/python/modules/random/PyRandom.java 2009-11-22 20:24:31 UTC (rev 6947) @@ -19,7 +19,6 @@ import org.python.expose.ExposedNew; import org.python.expose.ExposedType; - @ExposedType(name = "_random.Random") public class PyRandom extends PyObject { @@ -41,46 +40,39 @@ * uses the value, else it uses the hash function of PyObject */ @ExposedMethod(defaults = "null") - final PyObject Random_seed(PyObject seed) { + final void Random_seed(PyObject seed) { + long n; if (seed == null) { seed = new PyLong(System.currentTimeMillis()); } if (seed instanceof PyLong) { PyLong max = new PyLong(Long.MAX_VALUE); - PyLong seed_modulus = (PyLong)(seed.__mod__(max)); - this.javaRandom.setSeed(seed_modulus.asLong(0)); + n = seed.__mod__(max).asLong(); } else if (seed instanceof PyInteger) { - this.javaRandom.setSeed(((PyInteger)seed).getValue()); + n = seed.asLong(); } else { - this.javaRandom.setSeed(seed.hashCode()); + n = seed.hashCode(); } - - // duplicating the _randommodule.c::init_by_array return - return Py.None; + this.javaRandom.setSeed(n); } @ExposedNew @ExposedMethod - public void Random___init__(PyObject[] args, String[] keywords) {} + final void Random___init__(PyObject[] args, String[] keywords) {} @ExposedMethod - public PyObject Random_jumpahead(PyObject arg0) { - long inc; - if (arg0 instanceof PyLong) { - inc=((PyLong)arg0).asLong(0); - } else if (arg0 instanceof PyInteger) { - inc=((PyInteger)arg0).getValue(); - } else { - throw Py.TypeError("jumpahead requires an integer"); + final void Random_jumpahead(PyObject arg0) { + if (!(arg0 instanceof PyInteger || arg0 instanceof PyLong)) { + throw Py.TypeError(String.format("jumpahead requires an integer, not '%s'", + arg0.getType().fastGetName())); } - for(int i=0;i<inc;i++) { + for (long i = arg0.asLong(); i > 0; i--) { this.javaRandom.nextInt(); } - return Py.None; } @ExposedMethod - public PyObject Random_setstate(PyObject arg0) { + final void Random_setstate(PyObject arg0) { if (!(arg0 instanceof PyTuple)) { throw Py.TypeError("state vector must be a tuple"); } @@ -104,13 +96,10 @@ } catch (ClassNotFoundException e) { throw Py.SystemError("state vector invalid: "+e.getMessage()); } - - // duplicating the _randommodule.c::random_setstate return - return Py.None; } @ExposedMethod - public PyObject Random_getstate() { + final PyObject Random_getstate() { try { ByteArrayOutputStream bout=new ByteArrayOutputStream(); ObjectOutputStream oout=new ObjectOutputStream(bout); @@ -134,7 +123,7 @@ * problems. */ @ExposedMethod - public PyObject Random_random() { + final PyObject Random_random() { long a=this.javaRandom.nextInt()>>>5; long b=this.javaRandom.nextInt()>>>6; double ret=(a*67108864.0+b)*(1.0/9007199254740992.0); @@ -142,7 +131,7 @@ } @ExposedMethod - public PyLong Random_getrandbits(int k) { + final PyLong Random_getrandbits(int k) { return new PyLong(new BigInteger(k, javaRandom)); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-11-22 22:10:11
|
Revision: 6948 http://jython.svn.sourceforge.net/jython/?rev=6948&view=rev Author: pjenvey Date: 2009-11-22 22:09:52 +0000 (Sun, 22 Nov 2009) Log Message: ----------- finally move the remaining functions to PosixModule, hide posix's __docs__ fixes #1396 Modified Paths: -------------- trunk/jython/Lib/os.py trunk/jython/NEWS trunk/jython/src/org/python/modules/Setup.java trunk/jython/src/org/python/modules/posix/PosixModule.java Removed Paths: ------------- trunk/jython/Lib/nt.py trunk/jython/Lib/posix.py Deleted: trunk/jython/Lib/nt.py =================================================================== --- trunk/jython/Lib/nt.py 2009-11-22 20:24:31 UTC (rev 6947) +++ trunk/jython/Lib/nt.py 2009-11-22 22:09:52 UTC (rev 6948) @@ -1,2 +0,0 @@ -from posix import __all__ -from posix import * Modified: trunk/jython/Lib/os.py =================================================================== --- trunk/jython/Lib/os.py 2009-11-22 20:24:31 UTC (rev 6947) +++ trunk/jython/Lib/os.py 2009-11-22 22:09:52 UTC (rev 6948) @@ -39,7 +39,7 @@ return [n for n in dir(module) if n[0] != '_'] name = 'java' -if '_posix' in _names: +if 'posix' in _names: _name = 'posix' linesep = '\n' from posix import * @@ -53,7 +53,7 @@ __all__.extend(_get_exports_list(posix)) del posix -elif '_nt' in _names: +elif 'nt' in _names: _name = 'nt' linesep = '\r\n' from nt import * @@ -67,7 +67,7 @@ __all__.extend(_get_exports_list(nt)) del nt -elif '_os2' in _names: +elif 'os2' in _names: _name = 'os2' linesep = '\r\n' from os2 import * @@ -85,7 +85,7 @@ __all__.extend(_get_exports_list(os2)) del os2 -elif '_ce' in _names: +elif 'ce' in _names: _name = 'ce' linesep = '\r\n' from ce import * @@ -100,7 +100,7 @@ __all__.extend(_get_exports_list(ce)) del ce -elif '_riscos' in _names: +elif 'riscos' in _names: _name = 'riscos' linesep = '\n' from riscos import * @@ -663,3 +663,42 @@ bytes += read(_urandomfd, n - len(bytes)) close(_urandomfd) return bytes + +# Supply os.popen() +def popen(cmd, mode='r', bufsize=-1): + """popen(command [, mode='r' [, bufsize]]) -> pipe + + Open a pipe to/from a command returning a file object. + """ + if not isinstance(cmd, (str, unicode)): + raise TypeError('invalid cmd type (%s, expected string)' % type(cmd)) + if mode not in ('r', 'w'): + raise ValueError("invalid mode %r" % mode) + import subprocess + if mode == 'r': + proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True, + stdout=subprocess.PIPE) + return _wrap_close(proc.stdout, proc) + elif mode == 'w': + proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True, + stdin=subprocess.PIPE) + return _wrap_close(proc.stdin, proc) + +# Helper for popen() -- a proxy for a file whose close waits for the process +class _wrap_close(object): + def __init__(self, stream, proc): + self._stream = stream + self._proc = proc + def close(self): + self._stream.close() + returncode = self._proc.wait() + if returncode == 0: + return None + if _name == 'nt': + return returncode + else: + return returncode + def __getattr__(self, name): + return getattr(self._stream, name) + def __iter__(self): + return iter(self._stream) Deleted: trunk/jython/Lib/posix.py =================================================================== --- trunk/jython/Lib/posix.py 2009-11-22 20:24:31 UTC (rev 6947) +++ trunk/jython/Lib/posix.py 2009-11-22 22:09:52 UTC (rev 6948) @@ -1,209 +0,0 @@ -""" -This module provides access to operating system functionality that is -standardized by the C Standard and the POSIX standard (a thinly -disguised Unix interface). Refer to the library manual and -corresponding Unix manual entries for more information on calls. -""" -try: - import _posix - from _posix import * -except: - import _nt as _posix - from _nt import * -import errno -import sys - -__all__ = [name for name in _posix.__all__ if not name.startswith('__doc__')] -__all__.extend(['getenv', 'isatty', 'popen', 'putenv', - 'rename', 'rmdir', 'system', - 'unsetenv', 'urandom', 'utime']) - -_name = _posix.__name__[1:] - -# Java class representing the size of a time_t. internal use, lazily set -_time_t = None - -# For urandom -urandom_source = None - -def rename(path, newpath): - """rename(old, new) - - Rename a file or directory. - """ - from java.io import File - if not File(sys.getPath(path)).renameTo(File(sys.getPath(newpath))): - raise OSError(0, "couldn't rename file", path) - -def rmdir(path): - """rmdir(path) - - Remove a directory.""" - from java.io import File - f = File(sys.getPath(path)) - if not f.exists(): - raise OSError(errno.ENOENT, strerror(errno.ENOENT), path) - elif not f.isDirectory(): - raise OSError(errno.ENOTDIR, strerror(errno.ENOTDIR), path) - elif not f.delete(): - raise OSError(0, "couldn't delete directory", path) - -def utime(path, times): - """utime(path, (atime, mtime)) - utime(path, None) - - Set the access and modification time of the file to the given values. - If the second form is used, set the access and modification times to the - current time. - - Due to Java limitations, on some platforms only the modification time - may be changed. - """ - if path is None: - raise TypeError('path must be specified, not None') - - if times is None: - atimeval = mtimeval = None - elif isinstance(times, tuple) and len(times) == 2: - atimeval = _to_timeval(times[0]) - mtimeval = _to_timeval(times[1]) - else: - raise TypeError('utime() arg 2 must be a tuple (atime, mtime)') - - _posix_impl.utimes(path, atimeval, mtimeval) - -def _to_timeval(seconds): - """Convert seconds (with a fraction) from epoch to a 2 item tuple of - seconds, microseconds from epoch as longs - """ - global _time_t - if _time_t is None: - from java.lang import Integer, Long - try: - from org.python.posix.util import Platform - except ImportError: - from org.jruby.ext.posix.util import Platform - _time_t = Integer if Platform.IS_32_BIT else Long - - try: - floor = long(seconds) - except TypeError: - raise TypeError('an integer is required') - if not _time_t.MIN_VALUE <= floor <= _time_t.MAX_VALUE: - raise OverflowError('long int too large to convert to int') - - # usec can't exceed 1000000 - usec = long((seconds - floor) * 1e6) - if usec < 0: - # If rounding gave us a negative number, truncate - usec = 0 - return floor, usec - -def system(command): - """system(command) -> exit_status - - Execute the command (a string) in a subshell. - """ - import subprocess - return subprocess.call(command, shell=True) - -def popen(command, mode='r', bufsize=-1): - """popen(command [, mode='r' [, bufsize]]) -> pipe - - Open a pipe to/from a command returning a file object. - """ - import subprocess - if mode == 'r': - proc = subprocess.Popen(command, bufsize=bufsize, shell=True, - stdout=subprocess.PIPE) - return _wrap_close(proc.stdout, proc) - elif mode == 'w': - proc = subprocess.Popen(command, bufsize=bufsize, shell=True, - stdin=subprocess.PIPE) - return _wrap_close(proc.stdin, proc) - else: - raise OSError(errno.EINVAL, strerror(errno.EINVAL)) - -# Helper for popen() -- a proxy for a file whose close waits for the process -class _wrap_close(object): - def __init__(self, stream, proc): - self._stream = stream - self._proc = proc - def close(self): - self._stream.close() - returncode = self._proc.wait() - if returncode == 0: - return None - if _name == 'nt': - return returncode - else: - return returncode - def __getattr__(self, name): - return getattr(self._stream, name) - def __iter__(self): - return iter(self._stream) - -def putenv(key, value): - """putenv(key, value) - - Change or add an environment variable. - """ - # XXX: put/unset/getenv should probably be deprecated - import os - os.environ[key] = value - -def unsetenv(key): - """unsetenv(key) - - Delete an environment variable. - """ - import os - try: - del os.environ[key] - except KeyError: - pass - -def getenv(key, default=None): - """Get an environment variable, return None if it doesn't exist. - The optional second argument can specify an alternate default.""" - import os - return os.environ.get(key, default) - -def isatty(fileno): - """isatty(fd) -> bool - - Return True if the file descriptor 'fd' is an open file descriptor - connected to the slave end of a terminal.""" - from java.io import FileDescriptor - - if isinstance(fileno, int): - if fileno == 0: - fd = getattr(FileDescriptor, 'in') - elif fileno == 1: - fd = FileDescriptor.out - elif fileno == 2: - fd = FileDescriptor.err - else: - raise NotImplemented('Integer file descriptor compatibility only ' - 'available for stdin, stdout and stderr (0-2)') - - return _posix_impl.isatty(fd) - - if isinstance(fileno, FileDescriptor): - return _posix_impl.isatty(fileno) - - from org.python.core.io import IOBase - if not isinstance(fileno, IOBase): - raise TypeError('a file descriptor is required') - - return fileno.isatty() - -def urandom(n): - global urandom_source - if urandom_source is None: - from java.security import SecureRandom - urandom_source = SecureRandom() - import jarray - buffer = jarray.zeros(n, 'b') - urandom_source.nextBytes(buffer) - return buffer.tostring() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-11-22 20:24:31 UTC (rev 6947) +++ trunk/jython/NEWS 2009-11-22 22:09:52 UTC (rev 6948) @@ -10,6 +10,7 @@ - [ 1496 ] fix os.listdir errno for non-existing dirs - [ 1499 ] PostgreSQL datahandler should return Decimals instead of floats for NUMERIC/DECIMAL columns - [ 1477 ] os.setpgrp and posix.setpgrp fail with TypeError + - [ 1396 ] Assigning os module funcs as class attributes incompatible with CPython - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) Modified: trunk/jython/src/org/python/modules/Setup.java =================================================================== --- trunk/jython/src/org/python/modules/Setup.java 2009-11-22 20:24:31 UTC (rev 6947) +++ trunk/jython/src/org/python/modules/Setup.java 2009-11-22 22:09:52 UTC (rev 6948) @@ -59,6 +59,6 @@ "_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" }; } Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-11-22 20:24:31 UTC (rev 6947) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2009-11-22 22:09:52 UTC (rev 6948) @@ -5,6 +5,7 @@ import com.kenai.constantine.platform.Errno; import java.io.File; +import java.io.FileDescriptor; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; @@ -12,12 +13,15 @@ import java.nio.channels.Channel; import java.nio.channels.ClosedChannelException; import java.nio.channels.FileChannel; +import java.security.SecureRandom; +import java.util.Iterator; import java.util.Map; import org.jruby.ext.posix.FileStat; import org.jruby.ext.posix.JavaPOSIX; import org.jruby.ext.posix.POSIX; import org.jruby.ext.posix.POSIXFactory; +import org.jruby.ext.posix.util.Platform; import org.python.core.ClassDictInit; import org.python.core.Py; @@ -25,12 +29,15 @@ import org.python.core.PyDictionary; import org.python.core.PyException; import org.python.core.PyFile; +import org.python.core.PyFloat; +import org.python.core.PyInteger; import org.python.core.PyList; import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyTuple; import org.python.core.ThreadState; import org.python.core.imp; +import org.python.core.io.IOBase; import org.python.core.io.FileDescriptors; import org.python.core.io.FileIO; import org.python.core.io.RawIOBase; @@ -38,13 +45,7 @@ import org.python.core.util.StringUtil; /** - * The underlying _posix or _nt module, named depending on the platform. - * - * This currently contains only some of the basics of the posix/nt modules (which are - * implemented in Python), most importantly things like PythonPOSIXHandler that are slower - * to instantiate and thus would affect startup time. - * - * Eventually more if not all of the pure Python module should end up here. + * The posix/nt module, depending on the platform. */ public class PosixModule implements ClassDictInit { @@ -79,6 +80,11 @@ /** os.path.realpath function for use by chdir. Lazily loaded. */ private static PyObject realpath; + /** Lazily initialzed singleton source for urandom. */ + private static class UrandomSource { + static final SecureRandom INSTANCE = new SecureRandom(); + } + public static void classDictInit(PyObject dict) { // only expose the open flags we support dict.__setitem__("O_RDONLY", Py.newInteger(O_RDONLY)); @@ -116,9 +122,18 @@ dict.__setitem__("getOSName", null); dict.__setitem__("badFD", null); - dict.__setitem__("__all__", dict.invoke("keys")); + // Hide __doc__s + PyList keys = (PyList)dict.invoke("keys"); + for (Iterator<?> it = keys.listIterator(); it.hasNext();) { + String key = (String)it.next(); + if (key.startsWith("__doc__")) { + it.remove(); + dict.__setitem__(key, null); + } + } + dict.__setitem__("__all__", keys); - dict.__setitem__("__name__", new PyString("_" + os.getModuleName())); + dict.__setitem__("__name__", new PyString(os.getModuleName())); dict.__setitem__("__doc__", __doc__); } @@ -377,6 +392,42 @@ return posix.getpgrp(); } + public static PyString __doc__isatty = new PyString( + "isatty(fd) -> bool\n\n" + + "Return True if the file descriptor 'fd' is an open file descriptor\n" + + "connected to the slave end of a terminal."); + public static boolean isatty(PyObject fdObj) { + if (fdObj instanceof PyInteger) { + FileDescriptor fd; + switch (fdObj.asInt()) { + case 0: + fd = FileDescriptor.in; + break; + case 1: + fd = FileDescriptor.out; + break; + case 2: + fd = FileDescriptor.err; + break; + default: + throw Py.NotImplementedError("Integer file descriptor compatibility only " + + "available for stdin, stdout and stderr (0-2)"); + } + return posix.isatty(fd); + } + + Object tojava = fdObj.__tojava__(FileDescriptor.class); + if (tojava != Py.NoConversion) { + return posix.isatty((FileDescriptor)tojava); + } + + tojava = fdObj.__tojava__(IOBase.class); + if (tojava == Py.NoConversion) { + throw Py.TypeError("a file descriptor is required"); + } + return ((IOBase)tojava).isatty(); + } + public static PyString __doc__kill = new PyString( "kill(pid, sig)\n\n" + "Kill a process with a signal."); @@ -534,6 +585,26 @@ return new FileIO(path, fileIOMode); } + public static PyString __doc__popen = new PyString( + "popen(command [, mode='r' [, bufsize]]) -> pipe\n\n" + + "Open a pipe to/from a command returning a file object."); + public static PyObject popen(PyObject[] args, String[] kwds) { + // XXX: popen lives in posix in 2.x, but moves to os in 3.x. It's easier for us to + // keep it in os + // import os; return os.popen(*args, **kwargs) + return imp.load("os").__getattr__("popen").__call__(args, kwds); + } + + public static PyString __doc__putenv = new PyString( + "putenv(key, value)\n\n" + + "Change or add an environment variable."); + public static void putenv(String key, String value) { + // XXX: Consider deprecating putenv/unsetenv + // import os; os.environ[key] = value + PyObject environ = imp.load("os").__getattr__("environ"); + environ.__setitem__(key, new PyString(value)); + } + public static PyString __doc__read = new PyString( "read(fd, buffersize) -> string\n\n" + "Read a file descriptor."); @@ -564,6 +635,32 @@ unlink(path); } + public static PyString __doc__rename = new PyString( + "rename(old, new)\n\n" + + "Rename a file or directory."); + public static void rename(String oldpath, String newpath) { + if (!new RelativeFile(oldpath).renameTo(new RelativeFile(newpath))) { + PyObject args = new PyTuple(Py.Zero, new PyString("Couldn't rename file")); + throw new PyException(Py.OSError, args); + } + } + + public static PyString __doc__rmdir = new PyString( + "rmdir(path)\n\n" + + "Remove a directory."); + public static void rmdir(String path) { + File file = new RelativeFile(path); + if (!file.exists()) { + throw Py.OSError(Errno.ENOENT, path); + } else if (!file.isDirectory()) { + throw Py.OSError(Errno.ENOTDIR, path); + } else if (!file.delete()) { + PyObject args = new PyTuple(Py.Zero, new PyString("Couldn't delete directory"), + new PyString(path)); + throw new PyException(Py.OSError, args); + } + } + public static PyString __doc__setpgrp = new PyString( "setpgrp()\n\n" + "Make this process a session leader."); @@ -610,6 +707,15 @@ posix.symlink(src, absolutePath(dst)); } + public static PyString __doc__system = new PyString( + "system(command) -> exit_status\n\n" + + "Execute the command (a string) in a subshell."); + public static void system(PyObject command) { + // import subprocess; subprocess.call(command, shell=True) + imp.load("subprocess").invoke("call", command, new PyObject[] {Py.True}, + new String[] {"shell"}); + } + public static PyString __doc__umask = new PyString( "umask(new_mask) -> old_mask\n\n" + "Set the current numeric umask and return the previous umask."); @@ -638,6 +744,47 @@ } } + public static PyString __doc__utime = new PyString( + "utime(path, (atime, mtime))\n" + + "utime(path, None)\n\n" + + "Set the access and modified time of the file to the given values. If the\n" + + "second form is used, set the access and modified times to the current time."); + public static void utime(String path, PyObject times) { + long[] atimeval; + long[] mtimeval; + + if (times == Py.None) { + atimeval = mtimeval = null; + } else if (times instanceof PyTuple && times.__len__() == 2) { + atimeval = extractTimeval(times.__getitem__(0)); + mtimeval = extractTimeval(times.__getitem__(1)); + } else { + throw Py.TypeError("utime() arg 2 must be a tuple (atime, mtime)"); + } + posix.utimes(absolutePath(path), atimeval, mtimeval); + } + + /** + * Convert seconds (with a possible fraction) from epoch to a 2 item array of seconds, + * microseconds from epoch as longs. + * + * @param seconds a PyObject number + * @return a 2 item long[] + */ + private static long[] extractTimeval(PyObject seconds) { + long[] timeval = new long[] {Platform.IS_32_BIT ? seconds.asInt() : seconds.asLong(), 0L}; + if (seconds instanceof PyFloat) { + // can't exceed 1000000 + long usec = (long)((seconds.asDouble() % 1.0) * 1e6); + if (usec < 0) { + // If rounding gave us a negative number, truncate + usec = 0; + } + timeval[1] = usec; + } + return timeval; + } + public static PyString __doc__wait = new PyString( "wait() -> (pid, status)\n\n" + "Wait for completion of a child process."); @@ -674,6 +821,30 @@ } } + public static PyString __doc__unsetenv = new PyString( + "unsetenv(key)\n\n" + + "Delete an environment variable."); + public static void unsetenv(String key) { + // import os; try: del os.environ[key]; except KeyError: pass + PyObject environ = imp.load("os").__getattr__("environ"); + try { + environ.__delitem__(key); + } catch (PyException pye) { + if (!pye.match(Py.KeyError)) { + throw pye; + } + } + } + + public static PyString __doc__urandom = new PyString( + "urandom(n) -> str\n\n" + + "Return a string of n random bytes suitable for cryptographic use."); + public static PyObject urandom(int n) { + byte[] buf = new byte[n]; + UrandomSource.INSTANCE.nextBytes(buf); + return new PyString(StringUtil.fromBytes(buf)); + } + /** * Helper function for the subprocess module, returns the potential shell commands for * this OS. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-11-25 08:48:39
|
Revision: 6950 http://jython.svn.sourceforge.net/jython/?rev=6950&view=rev Author: pjenvey Date: 2009-11-25 08:48:20 +0000 (Wed, 25 Nov 2009) Log Message: ----------- correct the fix for #1297 (r6263) to avoid potentially adding the type's proxy to its mro twice fixes #1504 Modified Paths: -------------- trunk/jython/Lib/test/test_java_subclasses.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/Lib/test/test_java_subclasses.py =================================================================== --- trunk/jython/Lib/test/test_java_subclasses.py 2009-11-24 02:15:34 UTC (rev 6949) +++ trunk/jython/Lib/test/test_java_subclasses.py 2009-11-25 08:48:20 UTC (rev 6950) @@ -10,6 +10,7 @@ from java.util import Date, Hashtable, Vector from java.awt import Color, Component, Dimension, Rectangle +from javax.swing import ComboBoxModel, ListModel from javax.swing.table import AbstractTableModel from org.python.tests import BeanInterface, Callbacker, Coercions, OwnMethodCaller @@ -45,6 +46,15 @@ c.run() self.assertEquals(calls, ["ComparableRunner.compareTo", "Runner.run"]) + def test_inherit_interface_twice(self): + # http://bugs.jython.org/issue1504 + class A(ListModel): pass + class B(A, ComboBoxModel): pass + # Regression caused B's proxy to occur in B's mro twice. That + # caused the declaration of C to fail with an inconsistent mro + class C(B): pass + + class TableModelTest(unittest.TestCase): def test_class_coercion(self): '''Python type instances coerce to a corresponding Java wrapper type in Object.getClass''' @@ -328,3 +338,7 @@ PythonSubclassesTest, AbstractOnSyspathTest, ContextClassloaderTest) + + +if __name__ == '__main__': + test_main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-11-24 02:15:34 UTC (rev 6949) +++ trunk/jython/NEWS 2009-11-25 08:48:20 UTC (rev 6950) @@ -11,6 +11,7 @@ - [ 1499 ] PostgreSQL datahandler should return Decimals instead of floats for NUMERIC/DECIMAL columns - [ 1477 ] os.setpgrp and posix.setpgrp fail with TypeError - [ 1396 ] Assigning os module funcs as class attributes incompatible with CPython + - [ 1504 ] Inheriting twice from the same Java interface causes MRO problems - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-11-24 02:15:34 UTC (rev 6949) +++ trunk/jython/src/org/python/core/PyType.java 2009-11-25 08:48:20 UTC (rev 6950) @@ -891,6 +891,7 @@ PyObject[] computeMro(MROMergeState[] toMerge, List<PyObject> mro) { boolean addedProxy = false; + PyType proxyAsType = javaProxy == null ? null : PyType.fromClass(((Class<?>)javaProxy)); scan : for (int i = 0; i < toMerge.length; i++) { if (toMerge[i].isMerged()) { continue scan; @@ -911,14 +912,16 @@ // This exposes the methods from the proxy generated for this class in addition to // those generated for the superclass while allowing methods from the superclass to // remain visible from the proxies. + mro.add(proxyAsType); addedProxy = true; - mro.add(PyType.fromClass(((Class<?>)javaProxy))); } mro.add(candidate); + // Was that our own proxy? + addedProxy |= candidate == proxyAsType; for (MROMergeState element : toMerge) { element.noteMerged(candidate); } - i = -1;// restart scan + i = -1; // restart scan } for (MROMergeState mergee : toMerge) { if (!mergee.isMerged()) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2009-11-29 16:11:51
|
Revision: 6951 http://jython.svn.sourceforge.net/jython/?rev=6951&view=rev Author: amak Date: 2009-11-29 16:11:42 +0000 (Sun, 29 Nov 2009) Log Message: ----------- Fixing a bug with callable_query_string. Making treatment more strict when no value is supplied. Added unit tests to cover varying scenarios. modjy crashes if any query string parameters are not set with '=' http://bugs.jython.org/issue1507 Modified Paths: -------------- trunk/jython/Lib/modjy/modjy_publish.py trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java Modified: trunk/jython/Lib/modjy/modjy_publish.py =================================================================== --- trunk/jython/Lib/modjy/modjy_publish.py 2009-11-25 08:48:20 UTC (rev 6950) +++ trunk/jython/Lib/modjy/modjy_publish.py 2009-11-29 16:11:42 UTC (rev 6951) @@ -42,11 +42,16 @@ callable_name = self.params['app_callable_name'] if self.params['callable_query_name']: query_string = req.getQueryString() - if query_string and '=' in query_string: + if query_string: for name_val in query_string.split('&'): - name, value = name_val.split('=') + if name_val.find('=') != -1: + name, value = name_val.split('=', 1) + else: + name, value = name_val, '' if name == self.params['callable_query_name']: callable_name = value + else: + callable_name = '' return source_uri, callable_name def get_app_object(self, req, environ): @@ -55,7 +60,7 @@ environ["PATH_INFO"] = path_info environ["PATH_TRANSLATED"] = File(self.app_directory, path_info).getPath() - if self.params['app_import_name'] is not None: + if self.params['app_import_name']: return self.get_app_object_importable(self.params['app_import_name']) else: if self.cache is None: Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java 2009-11-25 08:48:20 UTC (rev 6950) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestAppInvocation.java 2009-11-29 16:11:42 UTC (rev 6951) @@ -68,6 +68,16 @@ return importPath.toString(); } + public void testAppImportCallableNoValue() throws Exception { + appInvocationTestSetUp(); + String importableName = setupAppImport("WSGIHandlerFunction"); + setAppImportable(""); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } + public void testAppImportCallable() throws Exception { appInvocationTestSetUp(); String importableName = setupAppImport("WSGIHandlerFunction"); @@ -183,4 +193,66 @@ doGet(); assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); } + + protected void callableQueryAppInvocationTestSetUp() throws Exception { + baseSetUp(); + setRealPath("/test_apps_dir", "test_apps_dir"); + setAppDir("$/test_apps_dir"); + setAppFile("invocation_tests.py"); + // Callable query names should never fall back on app_callable_name + setAppName("should_never_be_called"); + setCallableQueryName(""); + setQueryString(""); + } + + public void testCallableQueryString() throws Exception { + callableQueryAppInvocationTestSetUp(); + setCallableQueryName("python_object"); + setQueryString("python_object=valid_callable"); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("valid_callable invoked", result); + } + + public void testCallableQueryStringNoParam() throws Exception { + callableQueryAppInvocationTestSetUp(); + setCallableQueryName("python_object"); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } + + public void testCallableQueryStringParamNoValue() throws Exception { + callableQueryAppInvocationTestSetUp(); + setCallableQueryName("python_object"); + setQueryString("python_object"); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } + + public void testCallableQueryStringParamTwoValues() throws Exception { + // This has to fail, because a python identifier cannot contain an '=' + callableQueryAppInvocationTestSetUp(); + setCallableQueryName("python_object"); + setQueryString("python_object=valid_callable=extra_value"); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } + + public void testCallableQueryStringParamNonExistentValue() throws Exception { + callableQueryAppInvocationTestSetUp(); + setCallableQueryName("python_object"); + setQueryString("python_object=invalid_callable"); + createServlet(); + doGet(); + String result = getOutput(); + assertEquals("Status code != 500: ServerError, =='" + getStatus() + "'", 500, getStatus()); + } + } Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-11-25 08:48:20 UTC (rev 6950) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2009-11-29 16:11:42 UTC (rev 6951) @@ -173,6 +173,10 @@ setInitParameter("app_callable_name", app_name); } + public void setCallableQueryName(String query_name) { + setInitParameter("callable_query_name", query_name); + } + public void setAppImportable(String app_path) { setAppDir(""); setAppFile(""); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-12-03 03:22:33
|
Revision: 6954 http://jython.svn.sourceforge.net/jython/?rev=6954&view=rev Author: pjenvey Date: 2009-12-03 03:22:11 +0000 (Thu, 03 Dec 2009) Log Message: ----------- fix ConcurrentHashSet serialization: Object isn't serializable fixes #1511 Modified Paths: -------------- trunk/jython/Lib/test/test_set_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/util/ConcurrentHashSet.java Modified: trunk/jython/Lib/test/test_set_jy.py =================================================================== --- trunk/jython/Lib/test/test_set_jy.py 2009-12-01 09:51:33 UTC (rev 6953) +++ trunk/jython/Lib/test/test_set_jy.py 2009-12-03 03:22:11 UTC (rev 6954) @@ -2,6 +2,8 @@ from test import test_support if test_support.is_jython: + from java.io import (ByteArrayInputStream, ByteArrayOutputStream, + ObjectInputStream, ObjectOutputStream) from java.util import Random from javatests import PySetInJavaTest @@ -48,7 +50,18 @@ # Check that the Java removal affected the underlying set self.assertEquals(0, len(s)) + def test_serialization(self): + s = set(range(5, 10)) + output = ByteArrayOutputStream() + serializer = ObjectOutputStream(output) + serializer.writeObject(s) + serializer.close() + input = ByteArrayInputStream(output.toByteArray()) + unserializer = ObjectInputStream(input) + self.assertEqual(s, unserializer.readObject()) + + def test_main(): tests = [SetTestCase] if test_support.is_jython: Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-12-01 09:51:33 UTC (rev 6953) +++ trunk/jython/NEWS 2009-12-03 03:22:11 UTC (rev 6954) @@ -12,6 +12,7 @@ - [ 1477 ] os.setpgrp and posix.setpgrp fail with TypeError - [ 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 - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) Modified: trunk/jython/src/org/python/core/util/ConcurrentHashSet.java =================================================================== --- trunk/jython/src/org/python/core/util/ConcurrentHashSet.java 2009-12-01 09:51:33 UTC (rev 6953) +++ trunk/jython/src/org/python/core/util/ConcurrentHashSet.java 2009-12-03 03:22:11 UTC (rev 6954) @@ -17,26 +17,23 @@ public class ConcurrentHashSet<E> extends AbstractSet<E> implements Serializable { /** The backing Map. */ - private final ConcurrentMap<E, Object> map; + private final ConcurrentMap<E, Boolean> map; /** Backing's KeySet. */ private transient Set<E> keySet; - /** Dummy value to associate with the key in the backing map. */ - private static final Object PRESENT = new Object(); - public ConcurrentHashSet() { - map = new ConcurrentHashMap<E, Object>(); + map = new ConcurrentHashMap<E, Boolean>(); keySet = map.keySet(); } public ConcurrentHashSet(int initialCapacity) { - map = new ConcurrentHashMap<E, Object>(initialCapacity); + map = new ConcurrentHashMap<E, Boolean>(initialCapacity); keySet = map.keySet(); } public ConcurrentHashSet(int initialCapacity, float loadFactor, int concurrencyLevel) { - map = new ConcurrentHashMap<E, Object>(initialCapacity, loadFactor, concurrencyLevel); + map = new ConcurrentHashMap<E, Boolean>(initialCapacity, loadFactor, concurrencyLevel); keySet = map.keySet(); } @@ -72,7 +69,7 @@ @Override public boolean add(E e) { - return map.put(e, PRESENT) == null; + return map.put(e, Boolean.TRUE) == null; } @Override 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: <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: <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: <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: <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: <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: <pj...@us...> - 2010-03-13 17:33:20
|
Revision: 6984 http://jython.svn.sourceforge.net/jython/?rev=6984&view=rev Author: pjenvey Date: 2010-03-13 17:33:14 +0000 (Sat, 13 Mar 2010) Log Message: ----------- fix the cmath module to accept objects implementing __float__ and remove its duplicate implementation of asDouble Modified Paths: -------------- trunk/jython/Lib/test/test_cmath_jy.py trunk/jython/NEWS trunk/jython/src/org/python/modules/cmath.java Modified: trunk/jython/Lib/test/test_cmath_jy.py =================================================================== --- trunk/jython/Lib/test/test_cmath_jy.py 2010-03-13 03:38:40 UTC (rev 6983) +++ trunk/jython/Lib/test/test_cmath_jy.py 2010-03-13 17:33:14 UTC (rev 6984) @@ -99,6 +99,27 @@ self.assertAlmostEqual(complex(1.00071, 0.00490826), cmath.tanh(complex(3, 4))) + def test_faux_float(self): + class Foo: + def __float__(self): + return 1.0 + class Bar(object): + def __float__(self): + return 1.0 + self.assertEqual(cmath.log(Foo()), 0.0) + self.assertEqual(cmath.log(Bar()), 0.0) + + def test_faux_complex(self): + class Foo: + def __complex__(self): + return 1.0j + class Bar(object): + def __complex__(self): + return 1.0j + self.assertEqual(cmath.log(Foo()), cmath.log(1.0j)) + self.assertEqual(cmath.log(Bar()), cmath.log(1.0j)) + + def test_main(): test_support.run_unittest(CmathTestCase) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-03-13 03:38:40 UTC (rev 6983) +++ trunk/jython/NEWS 2010-03-13 17:33:14 UTC (rev 6984) @@ -20,6 +20,7 @@ - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects + - Fix the cmath module to accept objects implementing the __float__ method Jython 2.5.1rc3 Bugs Fixed Modified: trunk/jython/src/org/python/modules/cmath.java =================================================================== --- trunk/jython/src/org/python/modules/cmath.java 2010-03-13 03:38:40 UTC (rev 6983) +++ trunk/jython/src/org/python/modules/cmath.java 2010-03-13 17:33:14 UTC (rev 6984) @@ -2,8 +2,8 @@ import org.python.core.Py; import org.python.core.PyComplex; -import org.python.core.PyException; import org.python.core.PyFloat; +import org.python.core.PyInstance; import org.python.core.PyObject; import org.python.modules.math; @@ -24,28 +24,39 @@ return (Math.sqrt(x * x + y * y)); } - private static PyComplex complexFromPyObject(PyObject in) { - try{ - return(in.__complex__()); - } catch(PyException e){ - if(e.type == Py.AttributeError || e.type == Py.ValueError) { - throw Py.TypeError("a float is required"); + private static PyComplex complexFromPyObject(PyObject obj) { + // If op is already of type PyComplex_Type, return its value + if (obj instanceof PyComplex) { + return (PyComplex)obj; + } + + // If not, use op's __complex__ method, if it exists + PyObject newObj = null; + if (obj instanceof PyInstance) { + // this can go away in python 3000 + if (obj.__findattr__("__complex__") != null) { + newObj = obj.invoke("__complex__"); } - throw e; + // else try __float__ + } else { + PyObject complexFunc = obj.getType().lookup("__complex__"); + if (complexFunc != null) { + newObj = complexFunc.__call__(obj); + } } - } - - private static double doubleFromPyObject(PyObject in) { - try{ - return(in.__float__().getValue()); - } catch(PyException e){ - if(e.type == Py.AttributeError || e.type == Py.ValueError) { - throw Py.TypeError("a float is required"); + + if (newObj != null) { + if (!(newObj instanceof PyComplex)) { + throw Py.TypeError("__complex__ should return a complex object"); } - throw e; + return (PyComplex)newObj; } + + // If neither of the above works, interpret op as a float giving the real part of + // the result, and fill in the imaginary part as 0 + return new PyComplex(obj.asDouble(), 0); } - + public static PyObject acos(PyObject in) { PyComplex x = complexFromPyObject(in); return (c_prodi(log(x.__add__(i @@ -146,7 +157,7 @@ } public static PyComplex log(PyObject in, PyObject base) { - return log(complexFromPyObject(in), doubleFromPyObject(base)); + return log(complexFromPyObject(in), base.asDouble()); } public static PyComplex log(PyComplex x, double base) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-03-21 21:35:20
|
Revision: 6988 http://jython.svn.sourceforge.net/jython/?rev=6988&view=rev Author: pjenvey Date: 2010-03-21 21:35:14 +0000 (Sun, 21 Mar 2010) Log Message: ----------- can't use FileOutputStreams for O_APPEND in 'a+' mode because the underlying file isn't readable fixes #1576 Modified Paths: -------------- trunk/jython/Lib/test/test_file_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/io/FileIO.java Modified: trunk/jython/Lib/test/test_file_jy.py =================================================================== --- trunk/jython/Lib/test/test_file_jy.py 2010-03-21 17:52:36 UTC (rev 6987) +++ trunk/jython/Lib/test/test_file_jy.py 2010-03-21 21:35:14 UTC (rev 6988) @@ -14,13 +14,8 @@ os.remove(test_support.TESTFN) def test_append(self): - self._test_append('ab') - - def test_appendplus(self): - self._test_append('a+') - - def _test_append(self, mode): # http://bugs.jython.org/issue1466 + mode = 'ab' fp1 = open(test_support.TESTFN, mode) fp1.write('test1\n') fp2 = open(test_support.TESTFN, mode) @@ -30,7 +25,15 @@ with open(test_support.TESTFN) as fp: self.assertEqual('test1\ntest2\n', fp.read()) + def test_appendplus(self): + # regression with the test_append fix: + # http://bugs.jython.org/issue1576 + with open(test_support.TESTFN, 'ab+') as fp: + fp.write('test1\n') + fp.seek(0) + self.assertEqual(fp.read(), 'test1\n') + def test_main(): test_support.run_unittest(FileTestCase) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-03-21 17:52:36 UTC (rev 6987) +++ trunk/jython/NEWS 2010-03-21 21:35:14 UTC (rev 6988) @@ -17,6 +17,7 @@ - [ 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 + - [ 1576 ] files opened in 'a+' mode not readable - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/core/io/FileIO.java =================================================================== --- trunk/jython/src/org/python/core/io/FileIO.java 2010-03-21 17:52:36 UTC (rev 6987) +++ trunk/jython/src/org/python/core/io/FileIO.java 2010-03-21 21:35:14 UTC (rev 6988) @@ -65,7 +65,7 @@ File absPath = new RelativeFile(name); try { - if (appending && !reading) { + if (appending && !(reading || plus)) { // Take advantage of FileOutputStream's append mode fromFileOutputStream(absPath); } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2010-03-28 08:21:56
|
Revision: 6990 http://jython.svn.sourceforge.net/jython/?rev=6990&view=rev Author: otmarhumbel Date: 2010-03-28 08:21:48 +0000 (Sun, 28 Mar 2010) Log Message: ----------- add google indexer (by Yin Wang and Steve Yegge) Modified Paths: -------------- trunk/jython/ACKNOWLEDGMENTS trunk/jython/NEWS trunk/jython/build.xml trunk/jython/grammar/Python.g trunk/jython/src/org/python/antlr/BaseParser.java trunk/jython/src/org/python/antlr/GrammarActions.java trunk/jython/src/org/python/antlr/PythonTree.java trunk/jython/src/org/python/antlr/ast/Attribute.java trunk/jython/src/org/python/antlr/ast/ClassDef.java trunk/jython/src/org/python/antlr/ast/FunctionDef.java trunk/jython/src/org/python/antlr/ast/Global.java trunk/jython/src/org/python/antlr/ast/ImportFrom.java trunk/jython/src/org/python/antlr/ast/Name.java trunk/jython/src/org/python/antlr/ast/alias.java trunk/jython/src/org/python/antlr/ast/arguments.java Added Paths: ----------- trunk/jython/src/org/python/antlr/AnalyzingParser.java trunk/jython/src/org/python/antlr/RecordingErrorHandler.java trunk/jython/src/org/python/indexer/ trunk/jython/src/org/python/indexer/AstCache.java trunk/jython/src/org/python/indexer/AstConverter.java trunk/jython/src/org/python/indexer/Builtins.java trunk/jython/src/org/python/indexer/Def.java trunk/jython/src/org/python/indexer/Diagnostic.java trunk/jython/src/org/python/indexer/Indexer.java trunk/jython/src/org/python/indexer/IndexingException.java trunk/jython/src/org/python/indexer/NBinding.java trunk/jython/src/org/python/indexer/Outliner.java trunk/jython/src/org/python/indexer/Ref.java trunk/jython/src/org/python/indexer/Scope.java trunk/jython/src/org/python/indexer/StyleRun.java trunk/jython/src/org/python/indexer/Util.java trunk/jython/src/org/python/indexer/ast/ trunk/jython/src/org/python/indexer/ast/BindingFinder.java trunk/jython/src/org/python/indexer/ast/DefaultNodeVisitor.java trunk/jython/src/org/python/indexer/ast/GenericNodeVisitor.java trunk/jython/src/org/python/indexer/ast/NAlias.java trunk/jython/src/org/python/indexer/ast/NAssert.java trunk/jython/src/org/python/indexer/ast/NAssign.java trunk/jython/src/org/python/indexer/ast/NAttribute.java trunk/jython/src/org/python/indexer/ast/NAugAssign.java trunk/jython/src/org/python/indexer/ast/NBinOp.java trunk/jython/src/org/python/indexer/ast/NBlock.java trunk/jython/src/org/python/indexer/ast/NBody.java trunk/jython/src/org/python/indexer/ast/NBoolOp.java trunk/jython/src/org/python/indexer/ast/NBreak.java trunk/jython/src/org/python/indexer/ast/NCall.java trunk/jython/src/org/python/indexer/ast/NClassDef.java trunk/jython/src/org/python/indexer/ast/NCompare.java trunk/jython/src/org/python/indexer/ast/NComprehension.java trunk/jython/src/org/python/indexer/ast/NContinue.java trunk/jython/src/org/python/indexer/ast/NDelete.java trunk/jython/src/org/python/indexer/ast/NDict.java trunk/jython/src/org/python/indexer/ast/NEllipsis.java trunk/jython/src/org/python/indexer/ast/NExceptHandler.java trunk/jython/src/org/python/indexer/ast/NExec.java trunk/jython/src/org/python/indexer/ast/NExprStmt.java trunk/jython/src/org/python/indexer/ast/NFor.java trunk/jython/src/org/python/indexer/ast/NFunctionDef.java trunk/jython/src/org/python/indexer/ast/NGeneratorExp.java trunk/jython/src/org/python/indexer/ast/NGlobal.java trunk/jython/src/org/python/indexer/ast/NIf.java trunk/jython/src/org/python/indexer/ast/NIfExp.java trunk/jython/src/org/python/indexer/ast/NImport.java trunk/jython/src/org/python/indexer/ast/NImportFrom.java trunk/jython/src/org/python/indexer/ast/NIndex.java trunk/jython/src/org/python/indexer/ast/NKeyword.java trunk/jython/src/org/python/indexer/ast/NLambda.java trunk/jython/src/org/python/indexer/ast/NList.java trunk/jython/src/org/python/indexer/ast/NListComp.java trunk/jython/src/org/python/indexer/ast/NModule.java trunk/jython/src/org/python/indexer/ast/NName.java trunk/jython/src/org/python/indexer/ast/NNode.java trunk/jython/src/org/python/indexer/ast/NNodeVisitor.java trunk/jython/src/org/python/indexer/ast/NNum.java trunk/jython/src/org/python/indexer/ast/NPass.java trunk/jython/src/org/python/indexer/ast/NPlaceHolder.java trunk/jython/src/org/python/indexer/ast/NPrint.java trunk/jython/src/org/python/indexer/ast/NQname.java trunk/jython/src/org/python/indexer/ast/NRaise.java trunk/jython/src/org/python/indexer/ast/NRepr.java trunk/jython/src/org/python/indexer/ast/NReturn.java trunk/jython/src/org/python/indexer/ast/NSequence.java trunk/jython/src/org/python/indexer/ast/NSlice.java trunk/jython/src/org/python/indexer/ast/NStr.java trunk/jython/src/org/python/indexer/ast/NSubscript.java trunk/jython/src/org/python/indexer/ast/NTryExcept.java trunk/jython/src/org/python/indexer/ast/NTryFinally.java trunk/jython/src/org/python/indexer/ast/NTuple.java trunk/jython/src/org/python/indexer/ast/NUnaryOp.java trunk/jython/src/org/python/indexer/ast/NUrl.java trunk/jython/src/org/python/indexer/ast/NWhile.java trunk/jython/src/org/python/indexer/ast/NWith.java trunk/jython/src/org/python/indexer/ast/NYield.java trunk/jython/src/org/python/indexer/ast/NameBinder.java trunk/jython/src/org/python/indexer/demos/ trunk/jython/src/org/python/indexer/demos/DocStringParser.java trunk/jython/src/org/python/indexer/demos/HtmlDemo.java trunk/jython/src/org/python/indexer/demos/HtmlOutline.java trunk/jython/src/org/python/indexer/demos/Linker.java trunk/jython/src/org/python/indexer/demos/StyleApplier.java trunk/jython/src/org/python/indexer/demos/Styler.java trunk/jython/src/org/python/indexer/types/ trunk/jython/src/org/python/indexer/types/NClassType.java trunk/jython/src/org/python/indexer/types/NDictType.java trunk/jython/src/org/python/indexer/types/NFuncType.java trunk/jython/src/org/python/indexer/types/NInstanceType.java trunk/jython/src/org/python/indexer/types/NListType.java trunk/jython/src/org/python/indexer/types/NModuleType.java trunk/jython/src/org/python/indexer/types/NTupleType.java trunk/jython/src/org/python/indexer/types/NType.java trunk/jython/src/org/python/indexer/types/NUnionType.java trunk/jython/src/org/python/indexer/types/NUnknownType.java trunk/jython/tests/java/org/python/indexer/ trunk/jython/tests/java/org/python/indexer/IndexerTest.java trunk/jython/tests/java/org/python/indexer/TestBase.java trunk/jython/tests/java/org/python/indexer/data/ trunk/jython/tests/java/org/python/indexer/data/__init__.py trunk/jython/tests/java/org/python/indexer/data/attr_infer.py trunk/jython/tests/java/org/python/indexer/data/callnewref.py trunk/jython/tests/java/org/python/indexer/data/class1.py trunk/jython/tests/java/org/python/indexer/data/class2.py trunk/jython/tests/java/org/python/indexer/data/classtype_builtins.py trunk/jython/tests/java/org/python/indexer/data/empty_file.py trunk/jython/tests/java/org/python/indexer/data/foo.py trunk/jython/tests/java/org/python/indexer/data/hello.py trunk/jython/tests/java/org/python/indexer/data/mod1.py trunk/jython/tests/java/org/python/indexer/data/mod2.py trunk/jython/tests/java/org/python/indexer/data/mod3.py trunk/jython/tests/java/org/python/indexer/data/pkg/ trunk/jython/tests/java/org/python/indexer/data/pkg/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/ trunk/jython/tests/java/org/python/indexer/data/pkg/animal/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/animaltest.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/ trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/ape.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/cat.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/dog.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/reptile/ trunk/jython/tests/java/org/python/indexer/data/pkg/animal/reptile/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/reptile/croc.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/reptile/snake.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/ trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/ trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/gold.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/iron.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/lead.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/ trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/lapis.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/limestone.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/obsidian.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/ trunk/jython/tests/java/org/python/indexer/data/pkg/misc/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/m1.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/m2.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/m3.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/moduleA.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/moduleB.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/ trunk/jython/tests/java/org/python/indexer/data/pkg/other/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/ trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/bleu.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/blue.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/crimson.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/green.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/red.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/white.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/force/ trunk/jython/tests/java/org/python/indexer/data/pkg/other/force/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/ trunk/jython/tests/java/org/python/indexer/data/pkg/plant/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/food/ trunk/jython/tests/java/org/python/indexer/data/pkg/plant/food/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/food/peach.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/food/tofu.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/ trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/catnip.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/rose.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/weed.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/poison/ trunk/jython/tests/java/org/python/indexer/data/pkg/plant/poison/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/poison/eggplant.py trunk/jython/tests/java/org/python/indexer/data/pkg/test.py trunk/jython/tests/java/org/python/indexer/data/pkgload.py trunk/jython/tests/java/org/python/indexer/data/refs.py trunk/jython/tests/java/org/python/indexer/data/refs2.py trunk/jython/tests/java/org/python/indexer/data/test-load.txt trunk/jython/tests/java/org/python/indexer/data/test.py trunk/jython/tests/java/org/python/indexer/data/testfileload.py trunk/jython/tests/java/org/python/indexer/data/testload.py trunk/jython/tests/java/org/python/indexer/data/testsrc.txt trunk/jython/tests/java/org/python/indexer/data/yinw/ Modified: trunk/jython/ACKNOWLEDGMENTS =================================================================== --- trunk/jython/ACKNOWLEDGMENTS 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/ACKNOWLEDGMENTS 2010-03-28 08:21:48 UTC (rev 6990) @@ -34,6 +34,8 @@ Alan Kennedy contributed modjy, which bridges WSGI to the Servlet API Chris Gokey, David Syer and Finn Bock added PyServlet. + + Yin Wang and Steve Yegge contributed the static analyzer from Google (also called indexer). A huge thanks goes to all the members of the jpython/jython mailing lists. Other folks who have contributed to JPython and Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/NEWS 2010-03-28 08:21:48 UTC (rev 6990) @@ -22,6 +22,7 @@ during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects - Fix the cmath module to accept objects implementing the __float__ method + - Add google indexer (by Yin Wang and Steve Yegge) Jython 2.5.1rc3 Bugs Fixed Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/build.xml 2010-03-28 08:21:48 UTC (rev 6990) @@ -883,6 +883,7 @@ <junit fork="true" printsummary="true"> <formatter type="xml"/> <sysproperty key="python.home" value="${dist.dir}"/> + <sysproperty key="python.test.source.dir" value="${test.source.dir}"/> <classpath refid="test.classpath"/> <batchtest todir="${junit.reports}"> <fileset dir="${test.source.dir}" includes="**/*Test*.java"> @@ -893,6 +894,50 @@ </batchtest> </junit> </target> + <target name="idxtest" depends="developer-build"> + <mkdir dir="${junit.reports}"/> + <junit fork="true" printsummary="true" showoutput="true"> + <formatter type="xml"/> + <sysproperty key="python.home" value="${dist.dir}"/> + <sysproperty key="python.test.source.dir" value="${test.source.dir}"/> + <classpath refid="test.classpath"/> + <batchtest todir="${junit.reports}"> + <fileset dir="${test.source.dir}" includes="**/*Test*.java"> + <exclude name="javatests/**/*" /> + <exclude name="**/InterpTestCase.java" /> + <exclude name="org/python/antlr/**" /> + <exclude name="org/python/core/**" /> + <exclude name="org/python/expose/**" /> + <exclude name="org/python/jsr223/**" /> + <exclude name="org/python/tests/**" /> + <exclude name="org/python/util/**" /> + </fileset> + </batchtest> + </junit> + </target> + <!-- XXX: how do I share common stuff with "idxtest" target? --> + <target name="idxtest-debug" depends="developer-build"> + <mkdir dir="${junit.reports}"/> + <junit fork="true" printsummary="true"> + <formatter type="xml"/> + <sysproperty key="python.home" value="${dist.dir}"/> + <sysproperty key="python.test.source.dir" value="${test.source.dir}"/> + <classpath refid="test.classpath"/> + <jvmarg value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5000"/> + <batchtest todir="${junit.reports}"> + <fileset dir="${test.source.dir}" includes="**/*Test*.java"> + <exclude name="javatests/**/*" /> + <exclude name="**/InterpTestCase.java" /> + <exclude name="org/python/antlr/**" /> + <exclude name="org/python/core/**" /> + <exclude name="org/python/expose/**" /> + <exclude name="org/python/jsr223/**" /> + <exclude name="org/python/tests/**" /> + <exclude name="org/python/util/**" /> + </fileset> + </batchtest> + </junit> + </target> <target name="modjytest" depends="developer-build"> <ant dir="tests/modjy"> <property name="jython_home" value="${dist.dir}"/> Modified: trunk/jython/grammar/Python.g =================================================================== --- trunk/jython/grammar/Python.g 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/grammar/Python.g 2010-03-28 08:21:48 UTC (rev 6990) @@ -367,7 +367,7 @@ } | { - $etype = new Name($n1, $n1.text, expr_contextType.Load); + $etype = actions.makeNameNode($n1); } ) ; @@ -783,13 +783,16 @@ import_from : FROM (d+=DOT* dotted_name | d+=DOT+) IMPORT (STAR - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.names), + actions.makeModuleNameNode($d, $dotted_name.names), actions.makeStarAlias($STAR), actions.makeLevel($d)]) | i1=import_as_names - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.names), + actions.makeModuleNameNode($d, $dotted_name.names), actions.makeAliases($i1.atypes), actions.makeLevel($d)]) | LPAREN i2=import_as_names COMMA? RPAREN - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.names), + actions.makeModuleNameNode($d, $dotted_name.names), actions.makeAliases($i2.atypes), actions.makeLevel($d)]) ) ; @@ -811,7 +814,7 @@ } : name=NAME (AS asname=NAME)? { - $atype = new alias($name, $name.text, $asname.text); + $atype = new alias(actions.makeNameNode($name), actions.makeNameNode($asname)); } ; @@ -822,10 +825,9 @@ @after { $dotted_as_name.tree = $atype; } - - : dotted_name (AS NAME)? + : dotted_name (AS asname=NAME)? { - $atype = new alias($NAME, $dotted_name.name, $NAME.text); + $atype = new alias($dotted_name.names, actions.makeNameNode($asname)); } ; @@ -840,17 +842,17 @@ //dotted_name: NAME ('.' NAME)* dotted_name - returns [String name] + returns [List<Name> names] : NAME (DOT dn+=attr)* { - $name = actions.makeDottedText($NAME, $dn); + $names = actions.makeDottedName($NAME, $dn); } ; //global_stmt: 'global' NAME (',' NAME)* global_stmt : GLOBAL n+=NAME (COMMA n+=NAME)* - -> ^(GLOBAL<Global>[$GLOBAL, actions.makeNames($n)]) + -> ^(GLOBAL<Global>[$GLOBAL, actions.makeNames($n), actions.makeNameNodes($n)]) ; //exec_stmt: 'exec' expr ['in' test [',' test]] @@ -1522,7 +1524,7 @@ | LBRACK subscriptlist[$begin] RBRACK -> ^(LBRACK<Subscript>[$begin, actions.castExpr($tree), actions.castSlice($subscriptlist.tree), $expr::ctype]) | DOT attr - -> ^(DOT<Attribute>[$begin, actions.castExpr($tree), $attr.text, $expr::ctype]) + -> ^(DOT<Attribute>[$begin, actions.castExpr($tree), new Name($attr.tree, $attr.text, expr_contextType.Load), $expr::ctype]) ; //subscriptlist: subscript (',' subscript)* [','] @@ -1630,7 +1632,7 @@ if ($decorators.start != null) { t = $decorators.start; } - stype = new ClassDef(t, actions.cantBeNone($NAME), + stype = new ClassDef(t, actions.cantBeNoneName($NAME), actions.makeBases(actions.castExpr($testlist.tree)), actions.castStmts($suite.stypes), actions.castExprs($decorators.etypes)); Added: trunk/jython/src/org/python/antlr/AnalyzingParser.java =================================================================== --- trunk/jython/src/org/python/antlr/AnalyzingParser.java (rev 0) +++ trunk/jython/src/org/python/antlr/AnalyzingParser.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -0,0 +1,71 @@ +/** + * Copyright 2009, Google Inc. All rights reserved. + * Licensed to PSF under a Contributor Agreement. + */ +package org.python.antlr; + +import org.antlr.runtime.ANTLRFileStream; +import org.antlr.runtime.CharStream; +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.Token; +import org.python.antlr.ast.Name; +import org.python.antlr.base.mod; + +import java.util.List; + +/** + * Parser used by the indexer. + */ +public class AnalyzingParser extends BaseParser { + + public static class AnalyzerTreeAdaptor extends PythonTreeAdaptor { + /** + * Make sure a parenthesized {@link Name} expr has its start/stop bounds + * set to the bounds of the identifier. + */ + @Override + public void setTokenBoundaries(Object t, Token startToken, Token stopToken) { + //XXX: should do this for all expr types, and have a prop list on Expr + //that records all enclosing paren locations for IDE use cases. + if (!(t instanceof Name) + || startToken == null + || stopToken == null + || startToken.getType() != PythonParser.LPAREN + || stopToken.getType() != PythonParser.RPAREN) { + super.setTokenBoundaries(t, startToken, stopToken); + } + } + } + + public AnalyzingParser(CharStream stream, String filename, String encoding) { + super(stream, filename, encoding); + errorHandler = new RecordingErrorHandler(); + } + + public List<RecognitionException> getRecognitionErrors() { + return ((RecordingErrorHandler)errorHandler).errs; + } + + @Override + protected PythonParser setupParser(boolean single) { + PythonParser parser = super.setupParser(single); + parser.setTreeAdaptor(new AnalyzerTreeAdaptor()); + return parser; + } + + public static void main(String[] args) { + CharStream in = null; + try { + in = new ANTLRFileStream(args[0]); + } catch (Exception x) { + x.printStackTrace(); + } + AnalyzingParser p = new AnalyzingParser(in, args[0], "ascii"); + mod ast = p.parseModule(); + if (ast != null) { + System.out.println("parse result: \n" + ast.toStringTree()); + } else { + System.out.println("failure: \n" + p.getRecognitionErrors()); + } + } +} Modified: trunk/jython/src/org/python/antlr/BaseParser.java =================================================================== --- trunk/jython/src/org/python/antlr/BaseParser.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/BaseParser.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -31,7 +31,7 @@ this.errorHandler = eh; } - private PythonParser setupParser(boolean single) { + protected PythonParser setupParser(boolean single) { PythonLexer lexer = new PythonLexer(charStream); lexer.setErrorHandler(errorHandler); lexer.single = single; Modified: trunk/jython/src/org/python/antlr/GrammarActions.java =================================================================== --- trunk/jython/src/org/python/antlr/GrammarActions.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/GrammarActions.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -61,19 +61,41 @@ this.errorHandler = eh; } - String makeFromText(List dots, String name) { - StringBuffer d = new StringBuffer(); + String makeFromText(List dots, List<Name> names) { + StringBuilder d = new StringBuilder(); if (dots != null) { for (int i=0;i<dots.size();i++) { d.append("."); } } - if (name != null) { - d.append(name); - } + d.append(PythonTree.dottedNameListToString(names)); return d.toString(); } + List<Name> makeModuleNameNode(List dots, List<Name> names) { + List<Name> result = new ArrayList<Name>(); + if (dots != null) { + for (Object o : dots) { + Token tok = (Token)o; + result.add(new Name(tok, tok.getText(), expr_contextType.Load)); + } + } + result.addAll(names); + return result; + } + + List<Name> makeDottedName(Token top, List<PythonTree> attrs) { + List<Name> result = new ArrayList<Name>(); + result.add(new Name(top, top.getText(), expr_contextType.Load)); + if (attrs != null) { + for (PythonTree attr : attrs) { + Token token = attr.getToken(); + result.add(new Name(token, token.getText(), expr_contextType.Load)); + } + } + return result; + } + int makeLevel(List lev) { if (lev == null) { return 0; @@ -113,6 +135,21 @@ return s; } + Name makeNameNode(Token t) { + if (t == null) { + return null; + } + return new Name(t, t.getText(), expr_contextType.Load); + } + + List<Name> makeNameNodes(List<Token> names) { + List<Name> s = new ArrayList<Name>(); + for (int i=0; i<names.size(); i++) { + s.add(makeNameNode(names.get(i))); + } + return s; + } + void errorGenExpNotSoleArg(PythonTree t) { errorHandler.error("Generator expression must be parenthesized if not sole argument", t); } @@ -191,7 +228,7 @@ expr current = new Name(nameToken, nameToken.getText(), expr_contextType.Load); for (Object o: attrs) { Token t = (Token)o; - current = new Attribute(t, current, t.getText(), + current = new Attribute(t, current, cantBeNoneName(t), expr_contextType.Load); } return current; @@ -236,21 +273,21 @@ List<stmt> f = castStmts(finBody); return new TryFinally(t, b, f); } - + stmt makeFuncdef(Token t, Token nameToken, arguments args, List funcStatements, List decorators) { if (nameToken == null) { return errorHandler.errorStmt(new PythonTree(t)); } - cantBeNone(nameToken); + Name n = cantBeNoneName(nameToken); arguments a; if (args != null) { a = args; } else { - a = new arguments(t, new ArrayList<expr>(), null, null, new ArrayList<expr>()); + a = new arguments(t, new ArrayList<expr>(), (Name)null, null, new ArrayList<expr>()); } List<stmt> s = castStmts(funcStatements); List<expr> d = castExprs(decorators); - return new FunctionDef(t, nameToken.getText(), a, s, d); + return new FunctionDef(t, n, a, s, d); } List<expr> makeAssignTargets(expr lhs, List rhs) { @@ -293,17 +330,17 @@ List<expr> p = castExprs(params); List<expr> d = castExprs(defaults); - String s; - String k; + Name s; + Name k; if (snameToken == null) { s = null; } else { - s = cantBeNone(snameToken); + s = cantBeNoneName(snameToken); } if (knameToken == null) { k = null; } else { - k = cantBeNone(knameToken); + k = cantBeNoneName(knameToken); } return new arguments(t, p, s, k, d); } @@ -516,6 +553,13 @@ return t.getText(); } + Name cantBeNoneName(Token t) { + if (t == null || t.getText().equals("None")) { + errorHandler.error("can't be None", new PythonTree(t)); + } + return new Name(t, t.getText(), expr_contextType.Load); + } + void cantBeNone(PythonTree e) { if (e.getText().equals("None")) { errorHandler.error("can't be None", e); @@ -722,18 +766,4 @@ } return s; } - - public String makeDottedText(Token name, List<PythonTree> c) { - final String dot = "."; - if (c == null || c.isEmpty()) { - return name.getText(); - } - StringBuilder b = new StringBuilder(name.getText()); - for (PythonTree t : c) { - b.append(dot); - b.append(t.getToken().getText()); - } - return b.toString(); - } - } Modified: trunk/jython/src/org/python/antlr/PythonTree.java =================================================================== --- trunk/jython/src/org/python/antlr/PythonTree.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/PythonTree.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -5,6 +5,7 @@ import org.antlr.runtime.tree.CommonTree; import org.python.core.PyType; +import org.python.antlr.ast.Name; import org.python.antlr.ast.VisitorIF; import java.util.ArrayList; @@ -165,6 +166,35 @@ node.setChildIndex(index); } + /** + * Converts a list of Name to a dotted-name string. + * Because leading dots are indexable identifiers (referring + * to parent directories in relative imports), a Name list + * may include leading dots, but not dots between names. + */ + public static String dottedNameListToString(List<Name> names) { + if (names == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + boolean leadingDot = true; + for (int i = 0, len = names.size(); i < len; i++) { + Name name = names.get(i); + String id = name.getInternalId(); + if (id == null) { + continue; + } + if (!".".equals(id)) { + leadingDot = false; + } + sb.append(id); + if (i < len - 1 && !leadingDot) { + sb.append("."); + } + } + return sb.toString(); + } + @Override public String toString() { if (isNil()) { Added: trunk/jython/src/org/python/antlr/RecordingErrorHandler.java =================================================================== --- trunk/jython/src/org/python/antlr/RecordingErrorHandler.java (rev 0) +++ trunk/jython/src/org/python/antlr/RecordingErrorHandler.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -0,0 +1,69 @@ +/** + * Copyright 2009, Google Inc. All rights reserved. + * Licensed to PSF under a Contributor Agreement. + */ +package org.python.antlr; + +import org.antlr.runtime.BaseRecognizer; +import org.antlr.runtime.BitSet; +import org.antlr.runtime.IntStream; +import org.antlr.runtime.Lexer; +import org.antlr.runtime.RecognitionException; +import org.python.antlr.ast.ErrorExpr; +import org.python.antlr.ast.ErrorMod; +import org.python.antlr.ast.ErrorSlice; +import org.python.antlr.ast.ErrorStmt; +import org.python.antlr.base.expr; +import org.python.antlr.base.mod; +import org.python.antlr.base.slice; +import org.python.antlr.base.stmt; + +import java.util.ArrayList; +import java.util.List; + +public class RecordingErrorHandler implements ErrorHandler { + + public List<RecognitionException> errs = new ArrayList<RecognitionException>(); + + public void reportError(BaseRecognizer br, RecognitionException re) { + br.reportError(re); + errs.add(re); + } + + public void recover(Lexer lex, RecognitionException re) { + lex.recover(re); + } + + public void recover(BaseRecognizer br, IntStream input, RecognitionException re) { + br.recover(input, re); + } + + public boolean mismatch(BaseRecognizer br, IntStream input, int ttype, BitSet follow) { + return true; + } + + public Object recoverFromMismatchedToken(BaseRecognizer br, IntStream input, + int ttype, BitSet follow) { + return null; + } + + public expr errorExpr(PythonTree t) { + return new ErrorExpr(t); + } + + public mod errorMod(PythonTree t) { + return new ErrorMod(t); + } + + public slice errorSlice(PythonTree t) { + return new ErrorSlice(t); + } + + public stmt errorStmt(PythonTree t) { + return new ErrorStmt(t); + } + + public void error(String message, PythonTree t) { + System.err.println(message); + } +} Modified: trunk/jython/src/org/python/antlr/ast/Attribute.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/Attribute.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/Attribute.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -45,6 +45,10 @@ public String getInternalAttr() { return attr; } + private Name attrName; + public Name getInternalAttrName() { + return attrName; + } @ExposedGet(name = "attr") public PyObject getAttr() { if (attr == null) return Py.None; @@ -119,6 +123,24 @@ this.ctx = ctx; } + public Attribute(Token token, expr value, Name attr, expr_contextType ctx) { + super(token); + this.value = value; + addChild(value); + this.attr = attr.getText(); + this.attrName = attr; + this.ctx = ctx; + } + + public Attribute(Integer ttype, Token token, expr value, Name attr, expr_contextType ctx) { + super(ttype, token); + this.value = value; + addChild(value); + this.attr = attr.getText(); + this.attrName = attr; + this.ctx = ctx; + } + public Attribute(Integer ttype, Token token, expr value, String attr, expr_contextType ctx) { super(ttype, token); this.value = value; Modified: trunk/jython/src/org/python/antlr/ast/ClassDef.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/ClassDef.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/ClassDef.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -32,6 +32,10 @@ public String getInternalName() { return name; } + private Name nameNode; + public Name getInternalNameNode() { + return nameNode; + } @ExposedGet(name = "name") public PyObject getName() { if (name == null) return Py.None; @@ -154,6 +158,34 @@ } } + public ClassDef(Token token, Name name, java.util.List<expr> bases, java.util.List<stmt> + body, java.util.List<expr> decorator_list) { + super(token); + this.name = name.getText(); + this.nameNode = name; + this.bases = bases; + if (bases == null) { + this.bases = new ArrayList<expr>(); + } + for(PythonTree t : this.bases) { + addChild(t); + } + this.body = body; + if (body == null) { + this.body = new ArrayList<stmt>(); + } + for(PythonTree t : this.body) { + addChild(t); + } + this.decorator_list = decorator_list; + if (decorator_list == null) { + this.decorator_list = new ArrayList<expr>(); + } + for(PythonTree t : this.decorator_list) { + addChild(t); + } + } + public ClassDef(Integer ttype, Token token, String name, java.util.List<expr> bases, java.util.List<stmt> body, java.util.List<expr> decorator_list) { super(ttype, token); Modified: trunk/jython/src/org/python/antlr/ast/FunctionDef.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/FunctionDef.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/FunctionDef.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -32,6 +32,10 @@ public String getInternalName() { return name; } + private Name nameNode; + public Name getInternalNameNode() { + return nameNode; + } @ExposedGet(name = "name") public PyObject getName() { if (name == null) return Py.None; @@ -148,6 +152,28 @@ } } + public FunctionDef(Token token, Name name, arguments args, java.util.List<stmt> body, + java.util.List<expr> decorator_list) { + super(token); + this.name = name.getText(); + this.nameNode = name; + this.args = args; + this.body = body; + if (body == null) { + this.body = new ArrayList<stmt>(); + } + for(PythonTree t : this.body) { + addChild(t); + } + this.decorator_list = decorator_list; + if (decorator_list == null) { + this.decorator_list = new ArrayList<expr>(); + } + for(PythonTree t : this.decorator_list) { + addChild(t); + } + } + public FunctionDef(Integer ttype, Token token, String name, arguments args, java.util.List<stmt> body, java.util.List<expr> decorator_list) { super(ttype, token); Modified: trunk/jython/src/org/python/antlr/ast/Global.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/Global.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/Global.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -40,8 +40,11 @@ public void setNames(PyObject names) { this.names = AstAdapters.py2identifierList(names); } + private java.util.List<Name> nameNodes; + public java.util.List<Name> getInternalNameNodes() { + return nameNodes; + } - private final static PyString[] fields = new PyString[] {new PyString("names")}; @ExposedGet(name = "_fields") @@ -85,6 +88,12 @@ this.names = names; } + public Global(Integer ttype, Token token, java.util.List<String> names, java.util.List<Name> nameNodes) { + super(ttype, token); + this.names = names; + this.nameNodes = nameNodes; + } + public Global(Integer ttype, Token token, java.util.List<String> names) { super(ttype, token); this.names = names; Modified: trunk/jython/src/org/python/antlr/ast/ImportFrom.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/ImportFrom.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/ImportFrom.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -1,4 +1,4 @@ -// Autogenerated AST node +// Autogenerated AST node -*- c-basic-offset:4 -*- package org.python.antlr.ast; import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; @@ -24,6 +24,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.List; @ExposedType(name = "_ast.ImportFrom", base = AST.class) public class ImportFrom extends stmt { @@ -42,8 +43,8 @@ this.module = AstAdapters.py2identifier(module); } - private java.util.List<alias> names; - public java.util.List<alias> getInternalNames() { + private List<alias> names; + public List<alias> getInternalNames() { return names; } @ExposedGet(name = "names") @@ -55,6 +56,11 @@ this.names = AstAdapters.py2aliasList(names); } + private List<Name> moduleNames; + public List<Name> getInternalModuleNames() { + return moduleNames; + } + private Integer level; public Integer getInternalLevel() { return level; @@ -111,8 +117,10 @@ setLevel(level); } - public ImportFrom(Token token, String module, java.util.List<alias> names, Integer level) { - super(token); + public ImportFrom(int ttype, Token token, + String module, List<Name> moduleNames, + List<alias> names, Integer level) { + super(ttype, token); this.module = module; this.names = names; if (names == null) { @@ -121,10 +129,17 @@ for(PythonTree t : this.names) { addChild(t); } + this.moduleNames = moduleNames; + if (moduleNames == null) { + this.moduleNames = new ArrayList<Name>(); + } + for(PythonTree t : this.moduleNames) { + addChild(t); + } this.level = level; } - public ImportFrom(Integer ttype, Token token, String module, java.util.List<alias> names, + public ImportFrom(Integer ttype, Token token, String module, List<alias> names, Integer level) { super(ttype, token); this.module = module; @@ -138,7 +153,7 @@ this.level = level; } - public ImportFrom(PythonTree tree, String module, java.util.List<alias> names, Integer level) { + public ImportFrom(PythonTree tree, String module, List<alias> names, Integer level) { super(tree); this.module = module; this.names = names; Modified: trunk/jython/src/org/python/antlr/ast/Name.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/Name.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/Name.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -1,4 +1,4 @@ -// Autogenerated AST node +// Autogenerated AST node -*- c-basic-offset:4 -*- package org.python.antlr.ast; import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; @@ -55,7 +55,6 @@ this.ctx = AstAdapters.py2expr_context(ctx); } - private final static PyString[] fields = new PyString[] {new PyString("id"), new PyString("ctx")}; @ExposedGet(name = "_fields") Modified: trunk/jython/src/org/python/antlr/ast/alias.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/alias.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/alias.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -42,6 +42,10 @@ this.name = AstAdapters.py2identifier(name); } + private java.util.List<Name> nameNodes; + public java.util.List<Name> getInternalNameNodes() { + return nameNodes; + } private String asname; public String getInternalAsname() { return asname; @@ -56,6 +60,10 @@ this.asname = AstAdapters.py2identifier(asname); } + private Name asnameNode; + public Name getInternalAsnameNode() { + return asnameNode; + } private final static PyString[] fields = new PyString[] {new PyString("name"), new PyString("asname")}; @@ -92,6 +100,21 @@ this.asname = asname; } + // [import] name [as asname] + public alias(Name name, Name asname) { + this(java.util.Arrays.asList(new Name[]{name}), asname); + } + + // [import] ...foo.bar.baz [as asname] + public alias(java.util.List<Name> nameNodes, Name asname) { + this.nameNodes = nameNodes; + this.name = dottedNameListToString(nameNodes); + if (asname != null) { + this.asnameNode = asname; + this.asname = asname.getInternalId(); + } + } + public alias(Integer ttype, Token token, String name, String asname) { super(ttype, token); this.name = name; Modified: trunk/jython/src/org/python/antlr/ast/arguments.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/arguments.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/arguments.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -45,6 +45,12 @@ public String getInternalVararg() { return vararg; } + + private Name varargName; + public Name getInternalVarargName() { + return varargName; + } + @ExposedGet(name = "vararg") public PyObject getVararg() { if (vararg == null) return Py.None; @@ -59,6 +65,12 @@ public String getInternalKwarg() { return kwarg; } + + private Name kwargName; + public Name getInternalKwargName() { + return kwargName; + } + @ExposedGet(name = "kwarg") public PyObject getKwarg() { if (kwarg == null) return Py.None; @@ -117,8 +129,29 @@ setDefaults(defaults); } - public arguments(Token token, java.util.List<expr> args, String vararg, String kwarg, - java.util.List<expr> defaults) { + // public arguments(Token token, java.util.List<expr> args, String vararg, String kwarg, + // java.util.List<expr> defaults) { + // super(token); + // this.args = args; + // if (args == null) { + // this.args = new ArrayList<expr>(); + // } + // for(PythonTree t : this.args) { + // addChild(t); + // } + // this.vararg = vararg; + // this.kwarg = kwarg; + // this.defaults = defaults; + // if (defaults == null) { + // this.defaults = new ArrayList<expr>(); + // } + // for(PythonTree t : this.defaults) { + // addChild(t); + // } + // } + + public arguments(Token token, java.util.List<expr> args, Name vararg, Name kwarg, + java.util.List<expr> defaults) { super(token); this.args = args; if (args == null) { @@ -127,8 +160,10 @@ for(PythonTree t : this.args) { addChild(t); } - this.vararg = vararg; - this.kwarg = kwarg; + this.vararg = vararg == null ? null : vararg.getText(); + this.varargName = vararg; + this.kwarg = kwarg == null ? null : kwarg.getText(); + this.kwargName = kwarg; this.defaults = defaults; if (defaults == null) { this.defaults = new ArrayList<expr>(); Added: trunk/jython/src/org/python/indexer/AstCache.java =================================================================== --- trunk/jython/src/org/python/indexer/AstCache.java (rev 0) +++ trunk/jython/src/org/python/indexer/AstCache.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -0,0 +1,325 @@ +/** + * Copyright 2009, Google Inc. All rights reserved. + * Licensed to PSF under a Contributor Agreement. + */ +package org.python.indexer; + +import org.antlr.runtime.ANTLRFileStream; +import org.antlr.runtime.ANTLRStringStream; +import org.antlr.runtime.CharStream; +import org.antlr.runtime.RecognitionException; +import org.python.antlr.AnalyzingParser; +import org.python.antlr.base.mod; +import org.python.indexer.ast.NModule; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Provides a factory for python source ASTs. Maintains configurable on-disk and + * in-memory caches to avoid re-parsing files during analysis. + */ +public class AstCache { + + public static final String CACHE_DIR = Util.getSystemTempDir() + "jython/ast_cache/"; + + private static final Logger LOG = Logger.getLogger(AstCache.class.getCanonicalName()); + + private Map<String, NModule> cache = new HashMap<String, NModule>(); + + private static AstCache INSTANCE; + + private AstCache() throws Exception { + File f = new File(CACHE_DIR); + if (!f.exists()) { + f.mkdirs(); + } + } + + public static AstCache get() throws Exception { + if (INSTANCE == null) { + INSTANCE = new AstCache(); + } + return INSTANCE; + } + + /** + * Clears the memory cache. + */ + public void clear() { + cache.clear(); + } + + /** + * Removes all serialized ASTs from the on-disk cache. + * @return {@code true} if all cached AST files were removed + */ + public boolean clearDiskCache() { + try { + File dir = new File(CACHE_DIR); + for (File f : dir.listFiles()) { + if (f.isFile()) { + f.delete(); + } + } + return true; + } catch (Exception x) { + severe("Failed to clear disk cache: " + x); + return false; + } + } + + /** + * Returns the syntax tree for {@code path}. May find and/or create a + * cached copy in the mem cache or the disk cache. + * @param path absolute path to a source file + * @return the AST, or {@code null} if the parse failed for any reason + * @throws Exception if anything unexpected occurs + */ + public NModule getAST(String path) throws Exception { + if (path == null) throw new IllegalArgumentException("null path"); + return fetch(path); + } + + /** + * Returns the syntax tree for {@code path} with {@code contents}. + * Uses the memory cache but not the disk cache. + * This method exists primarily for unit testing. + * @param path a name for the file. Can be relative. + * @param contents the source to parse + */ + public NModule getAST(String path, String contents) throws Exception { + if (path == null) throw new IllegalArgumentException("null path"); + if (contents == null) throw new IllegalArgumentException("null contents"); + + // Cache stores null value if the parse failed. + if (cache.containsKey(path)) { + return cache.get(path); + } + + NModule mod = null; + try { + mod = parse(path, contents); + if (mod != null) { + mod.setFileAndMD5(path, Util.getMD5(contents.getBytes("UTF-8"))); + } + } finally { + cache.put(path, mod); // may be null + } + return mod; + } + + /** + * Get or create an AST for {@code path}, checking and if necessary updating + * the disk and memory caches. + * @param path absolute source path + */ + private NModule fetch(String path) throws Exception { + // Cache stores null value if the parse failed. + if (cache.containsKey(path)) { + return cache.get(path); + } + + // Might be cached on disk but not in memory. + NModule mod = getSerializedModule(path); + if (mod != null) { + fine("reusing " + path); + cache.put(path, mod); + return mod; + } + + try { + mod = parse(path); + } finally { + cache.put(path, mod); // may be null + } + + if (mod != null) { + serialize(mod); + } + + return mod; + } + + /** + * Parse a file. Does not look in the cache or cache the result. + */ + private NModule parse(String path) throws Exception { + fine("parsing " + path); + mod ast = invokeANTLR(path); + return generateAST(ast, path); + } + + /** + * Parse a string. Does not look in the cache or cache the result. + */ + private NModule parse(String path, String contents) throws Exception { + fine("parsing " + path); + mod ast = invokeANTLR(path, contents); + return generateAST(ast, path); + } + + private NModule generateAST(mod ast, String path) throws Exception { + if (ast == null) { + Indexer.idx.reportFailedAssertion("ANTLR returned NULL for " + path); + return null; + } + + // Convert to indexer's AST. Type conversion warnings are harmless here. + Object obj = ast.accept(new AstConverter()); + if (!(obj instanceof NModule)) { + warn("\n[warning] converted AST is not a module: " + obj); + return null; + } + + NModule module = (NModule)obj; + if (new File(path).canRead()) { + module.setFile(path); + } + return module; + } + + private mod invokeANTLR(String filename) { + CharStream text = null; + try { + text = new ANTLRFileStream(filename); + } catch (IOException iox) { + fine(filename + ": " + iox); + return null; + } + return invokeANTLR(text, filename); + } + + private mod invokeANTLR(String filename, String contents) { + CharStream text = new ANTLRStringStream(contents); + return invokeANTLR(text, filename); + } + + private mod invokeANTLR(CharStream text, String filename) { + AnalyzingParser p = new AnalyzingParser(text, filename, null); + mod ast = null; + try { + ast = p.parseModule(); + } catch (Exception x) { + fine("parse for " + filename + " failed: " + x); + } + recordParseErrors(filename, p.getRecognitionErrors()); + return ast; + } + + private void recordParseErrors(String path, List<RecognitionException> errs) { + if (errs.isEmpty()) { + return; + } + List<Diagnostic> diags = Indexer.idx.getParseErrs(path); + for (RecognitionException rx : errs) { + String msg = rx.line + ":" + rx.charPositionInLine + ":" + rx; + diags.add(new Diagnostic(path, Diagnostic.Type.ERROR, -1, -1, msg)); + } + } + + /** + * Each source file's AST is saved in an object file named for the MD5 + * checksum of the source file. All that is needed is the MD5, but the + * file's base name is included for ease of debugging. + */ + public String getCachePath(File sourcePath) throws Exception { + return getCachePath(Util.getMD5(sourcePath), sourcePath.getName()); + } + + public String getCachePath(String md5, String name) { + return CACHE_DIR + name + md5 + ".ast"; + } + + // package-private for testing + void serialize(NModule ast) throws Exception { + String path = getCachePath(ast.getMD5(), new File(ast.getFile()).getName()); + ObjectOutputStream oos = null; + FileOutputStream fos = null; + try { + fos = new FileOutputStream(path); + oos = new ObjectOutputStream(fos); + oos.writeObject(ast); + } finally { + if (oos != null) { + oos.close(); + } else if (fos != null) { + fos.close(); + } + } + } + + // package-private for testing + NModule getSerializedModule(String sourcePath) { + try { + File sourceFile = new File(sourcePath); + if (sourceFile == null || !sourceFile.canRead()) { + return null; + } + File cached = new File(getCachePath(sourceFile)); + if (!cached.canRead()) { + return null; + } + return deserialize(sourceFile); + } catch (Exception x) { + severe("Failed to deserialize " + sourcePath + ": " + x); + return null; + } + } + + // package-private for testing + NModule deserialize(File sourcePath) throws Exception { + String cachePath = getCachePath(sourcePath); + FileInputStream fis = null; + ObjectInputStream ois = null; + try { + fis = new FileInputStream(cachePath); + ois = new ObjectInputStream(fis); + NModule mod = (NModule)ois.readObject(); + // Files in different dirs may have the same base name and contents. + mod.setFile(sourcePath); + return mod; + } finally { + if (ois != null) { + ois.close(); + } else if (fis != null) { + fis.close(); + } + } + } + + private void log(Level level, String msg) { + if (LOG.isLoggable(level)) { + LOG.log(level, msg); + } + } + + private void severe(String msg) { + log(Level.SEVERE, msg); + } + + private void warn(String msg) { + log(Level.WARNING, msg); + } + + private void info(String msg) { + log(Level.INFO, msg); + } + + private void fine(String msg) { + log(Level.FINE, msg); + } + + private void finer(String msg) { + log(Level.FINER, msg); + } +} Added: trunk/jython/src/org/python/indexer/AstConverter.java =================================================================== --- trunk/jython/src/org/python/indexer/AstConverter.java (rev 0) +++ trunk/jython/src/org/python/indexer/AstConverter.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -0,0 +1,676 @@ +/** + * Copyright 2009, Google Inc. All rights reserved. + * Licensed to PSF under a Contributor Agreement. + */ +package org.python.indexer; + +import org.python.antlr.PythonTree; +import org.python.antlr.Visitor; +import org.python.antlr.ast.Assert; +import org.python.antlr.ast.Assign; +import org.python.antlr.ast.Attribute; +import org.python.antlr.ast.AugAssign; +import org.python.antlr.ast.BinOp; +import org.python.antlr.ast.BoolOp; +import org.python.antlr.ast.Break; +import org.python.antlr.ast.Call; +import org.python.antlr.ast.ClassDef; +import org.python.antlr.ast.Compare; +import org.python.antlr.ast.Continue; +import org.python.antlr.ast.Delete; +import org.python.antlr.ast.Dict; +import org.python.antlr.ast.Ellipsis; +import org.python.antlr.ast.ExceptHandler; +import org.python.antlr.ast.Exec; +import org.python.antlr.ast.Expr; +import org.python.antlr.ast.For; +import org.python.antlr.ast.FunctionDef; +import org.python.antlr.ast.GeneratorExp; +import org.python.antlr.ast.Global; +import org.python.antlr.ast.If; +import org.python.antlr.ast.IfExp; +import org.python.antlr.ast.Import; +import org.python.antlr.ast.ImportFrom; +import org.python.antlr.ast.Index; +import org.python.antlr.ast.Lambda; +import org.python.antlr.ast.ListComp; +import org.python.antlr.ast.Module; +import org.python.antlr.ast.Name; +import org.python.antlr.ast.Num; +import org.python.antlr.ast.Pass; +import org.python.antlr.ast.Print; +import org.python.antlr.ast.Raise; +import org.python.antlr.ast.Repr; +import org.python.antlr.ast.Return; +import org.python.antlr.ast.Slice; +import org.python.antlr.ast.Str; +import org.python.antlr.ast.Subscript; +import org.python.antlr.ast.TryExcept; +import org.python.antlr.ast.TryFinally; +import org.python.antlr.ast.Tuple; +import org.python.antlr.ast.UnaryOp; +import org.python.antlr.ast.While; +import org.python.antlr.ast.With; +import org.python.antlr.ast.Yield; +import org.python.antlr.ast.alias; +import org.python.antlr.ast.arguments; +import org.python.antlr.ast.boolopType; +import org.python.antlr.ast.cmpopType; +import org.python.antlr.ast.comprehension; +import org.python.antlr.ast.keyword; +import org.python.antlr.ast.operatorType; +import org.python.antlr.ast.unaryopType; +import org.python.antlr.base.excepthandler; +import org.python.antlr.base.expr; +import org.python.antlr.base.stmt; +import org.python.indexer.ast.NAlias; +import org.python.indexer.ast.NAssert; +import org.python.indexer.ast.NAssign; +import org.python.indexer.ast.NAttribute; +import org.python.indexer.ast.NAugAssign; +import org.python.indexer.ast.NBinOp; +import org.python.indexer.ast.NBlock; +import org.python.indexer.ast.NBoolOp; +import org.python.indexer.ast.NBreak; +import org.python.indexer.ast.NCall; +import org.python.indexer.ast.NClassDef; +import org.python.indexer.ast.NCompare; +import org.python.indexer.ast.NComprehension; +import org.python.indexer.ast.NContinue; +import org.python.indexer.ast.NDelete; +import org.python.indexer.ast.NDict; +import org.python.indexer.ast.NEllipsis; +import org.python.indexer.ast.NExceptHandler; +import org.python.indexer.ast.NExec; +import org.python.indexer.ast.NFor; +import org.python.indexer.ast.NFunctionDef; +import org.python.indexer.ast.NGeneratorExp; +import org.python.indexer.ast.NGlobal; +import org.python.indexer.ast.NIf; +import org.python.indexer... [truncated message content] |
From: <otm...@us...> - 2010-03-28 17:28:45
|
Revision: 6992 http://jython.svn.sourceforge.net/jython/?rev=6992&view=rev Author: otmarhumbel Date: 2010-03-28 17:28:38 +0000 (Sun, 28 Mar 2010) Log Message: ----------- add @SuppressWarnings("unchecked") Modified Paths: -------------- trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java trunk/jython/tests/java/javatests/PySetInJavaTest.java Modified: trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java =================================================================== --- trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java 2010-03-28 09:11:22 UTC (rev 6991) +++ trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java 2010-03-28 17:28:38 UTC (rev 6992) @@ -142,7 +142,7 @@ List<String>[] vec = zipPackages.get(packageName); if (vec == null) { - vec = new List[] { Generic.list(), Generic.list() }; + vec = createGenericStringListArray(); zipPackages.put(packageName, vec); } int access = checkAccess(zip); @@ -153,6 +153,11 @@ } } + @SuppressWarnings("unchecked") + private List<String>[] createGenericStringListArray(){ + return new List[] { Generic.list(), Generic.list() }; + } + // Extract all of the packages in a single jarfile private Map<String, String> getZipPackages(InputStream jarin) throws IOException { Map<String, List<String>[]> zipPackages = Generic.map(); Modified: trunk/jython/tests/java/javatests/PySetInJavaTest.java =================================================================== --- trunk/jython/tests/java/javatests/PySetInJavaTest.java 2010-03-28 09:11:22 UTC (rev 6991) +++ trunk/jython/tests/java/javatests/PySetInJavaTest.java 2010-03-28 17:28:38 UTC (rev 6992) @@ -10,6 +10,7 @@ public class PySetInJavaTest { + @SuppressWarnings("unchecked") public static Set<Object> createPySetContainingJavaObjects() { PySet s = new PySet(); s.add("value"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-03-29 17:17:24
|
Revision: 6993 http://jython.svn.sourceforge.net/jython/?rev=6993&view=rev Author: amak Date: 2010-03-29 17:17:18 +0000 (Mon, 29 Mar 2010) Log Message: ----------- Adding support for socket.getservbyname, getservbyport and getprotobyname. Support made possible by Wayne Meissner's jnr-netdb project. http://github.com/wmeissner/jnr-netdb Many thanks to Wayne for his work. Modified Paths: -------------- trunk/jython/Lib/socket.py trunk/jython/Lib/test/test_socket.py trunk/jython/build.xml Added Paths: ----------- trunk/jython/extlibs/jnr-netdb-0.4.jar Modified: trunk/jython/Lib/socket.py =================================================================== --- trunk/jython/Lib/socket.py 2010-03-28 17:28:38 UTC (rev 6992) +++ trunk/jython/Lib/socket.py 2010-03-29 17:17:18 UTC (rev 6993) @@ -454,9 +454,9 @@ return num_bytes def _do_send_nio(self, byte_array, socket_address, flags): - byte_buf = java.nio.ByteBuffer.wrap(byte_array) - if self.jchannel.isConnected() and socket_address is None: - bytes_sent = self.jchannel.write(byte_buf) + byte_buf = java.nio.ByteBuffer.wrap(byte_array) + if self.jchannel.isConnected() and socket_address is None: + bytes_sent = self.jchannel.write(byte_buf) else: bytes_sent = self.jchannel.send(byte_buf, socket_address) return bytes_sent @@ -566,18 +566,26 @@ names, addrs = _gethostbyaddr(name) return (names[0], names, addrs) -def getservbyname(servicename, protocolname=None): - # http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071389 - # How complex is the structure of /etc/services? - raise NotImplementedError("getservbyname not yet supported on jython.") +def getservbyname(service_name, protocol_name=None): + try: + from jnr.netdb import Service + except ImportError: + return None + return Service.getServiceByName(service_name, protocol_name).getPort() -def getservbyport(port, protocolname=None): - # Same situation as above - raise NotImplementedError("getservbyport not yet supported on jython.") +def getservbyport(port, protocol_name=None): + try: + from jnr.netdb import Service + except ImportError: + return None + return Service.getServiceByPort(port, protocol_name).getName() -def getprotobyname(protocolname=None): - # Same situation as above - raise NotImplementedError("getprotobyname not yet supported on jython.") +def getprotobyname(protocol_name=None): + try: + from jnr.netdb import Protocol + except ImportError: + return None + return Protocol.getProtocolByName(protocol_name).getProto() def _realsocket(family = AF_INET, type = SOCK_STREAM, protocol=0): assert family == AF_INET, "Only AF_INET sockets are currently supported on jython" Modified: trunk/jython/Lib/test/test_socket.py =================================================================== --- trunk/jython/Lib/test/test_socket.py 2010-03-28 17:28:38 UTC (rev 6992) +++ trunk/jython/Lib/test/test_socket.py 2010-03-29 17:17:18 UTC (rev 6993) @@ -349,7 +349,6 @@ self.assertRaises(OverflowError, func, 1L<<34) def testGetServBy(self): - if sys.platform[:4] == 'java': return # not implemented on java eq = self.assertEqual # Find one service that exists, then check all the related interfaces. # I've ordered this by protocols that have both a tcp and udp @@ -862,7 +861,7 @@ msg = self.serv.recv(len(MSG)) self.assertEqual(msg, MSG) - def _testSendAndRecv(self): + def _testSendAndRecv(self): self.cli.connect( (self.HOST, self.PORT) ) self.cli.send(MSG, 0) @@ -874,7 +873,7 @@ msg = self.serv.recv(len(MSG)) self.assertEqual(msg, MSG) - def _testSendAndRecvTimeoutMode(self): + def _testSendAndRecvTimeoutMode(self): self.cli.connect( (self.HOST, self.PORT) ) self.cli.settimeout(10) self.cli.send(MSG, 0) Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2010-03-28 17:28:38 UTC (rev 6992) +++ trunk/jython/build.xml 2010-03-29 17:17:18 UTC (rev 6993) @@ -205,6 +205,7 @@ <pathelement path="${extlibs.dir}/jffi-x86_64-SunOS.jar"/> <pathelement path="${extlibs.dir}/jffi.jar"/> <pathelement path="${extlibs.dir}/jnr-posix.jar"/> + <pathelement path="${extlibs.dir}/jnr-netdb-0.4.jar"/> </path> <available property="informix.present" classname="com.informix.jdbc.IfxDriver" classpath="${informix.jar}" /> @@ -597,6 +598,7 @@ <zipfileset src="extlibs/jffi-x86_64-SunOS.jar"/> <zipfileset src="extlibs/jffi.jar"/> <zipfileset src="extlibs/jnr-posix.jar"/> + <zipfileset src="extlibs/jnr-netdb-0.4.jar"/> <!-- <rule pattern="com.sun.jna.**" result="org.python.jna.@1"/> --> <rule pattern="org.jruby.ext.posix.**" result="org.python.posix.@1"/> <zipfileset src="extlibs/constantine.jar"/> Added: trunk/jython/extlibs/jnr-netdb-0.4.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jnr-netdb-0.4.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-01 07:41:47
|
Revision: 6994 http://jython.svn.sourceforge.net/jython/?rev=6994&view=rev Author: amak Date: 2010-04-01 07:41:40 +0000 (Thu, 01 Apr 2010) Log Message: ----------- A partial fix for xml.dom.Node.data returns bytestrings of decoded unicode http://bugs.jython.org/issue1583 Modified Paths: -------------- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py trunk/jython/NEWS Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-03-29 17:17:18 UTC (rev 6993) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-01 07:41:40 UTC (rev 6994) @@ -185,7 +185,7 @@ self._cont_handler.startPrefixMapping(prefix, uri) def characters(self, char, start, len): - self._cont_handler.characters(str(String(char, start, len))) + self._cont_handler.characters(String(char, start, len).getBytes('utf-8').tostring().decode('utf-8')) def ignorableWhitespace(self, char, start, len): self._cont_handler.ignorableWhitespace(str(String(char, start, len))) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-03-29 17:17:18 UTC (rev 6993) +++ trunk/jython/NEWS 2010-04-01 07:41:40 UTC (rev 6994) @@ -2,6 +2,7 @@ Jython 2.5.2a1 Bugs Fixed + - [ 1225 ] socket.getservbyname/port() not yet supported - [ 1532 ] Cannot use docstring when defining class - [ 1530 ] BoolOp in multiple assign causes VerifyError - [ 1478 ] defaultdict & weakref.WeakKeyDictionary [TypeError: first argument must be callable] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-01 12:07:35
|
Revision: 6995 http://jython.svn.sourceforge.net/jython/?rev=6995&view=rev Author: amak Date: 2010-04-01 12:07:25 +0000 (Thu, 01 Apr 2010) Log Message: ----------- Some unittests for unicode usage with xml.dom.pulldom Modified Paths: -------------- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py trunk/jython/NEWS Added Paths: ----------- trunk/jython/Lib/test/test_pulldom.py Added: trunk/jython/Lib/test/test_pulldom.py =================================================================== --- trunk/jython/Lib/test/test_pulldom.py (rev 0) +++ trunk/jython/Lib/test/test_pulldom.py 2010-04-01 12:07:25 UTC (rev 6995) @@ -0,0 +1,77 @@ +""" + This is not an exhaustive pulldom test suite. + Instead, it is a place to put jython-specific tests, + relating to bugs like this one, for example. + + "xml.dom.Node.data returns bytestrings of decoded unicode" + http://bugs.jython.org/issue1583 + + amak. +""" + +import StringIO +import unittest +from xml.dom import pulldom +from test import test_support + +class UnicodeTests(unittest.TestCase): + + testDoc = """\ +<?xml version="1.0" encoding="ascii"?> +<document> + <p>Some greek: ΑΒΓΔΕ</p> + <greek attrs="ΖΗΘΙΚ"/> + <?greek ΛΜΝΞΟ?> +</document> +""" + + def setUp(self): + self.testFile = StringIO.StringIO(self.testDoc) + + def testTextNodes(self): + text = [] + for event, node in pulldom.parse(self.testFile): + if event == pulldom.CHARACTERS: + text.append(node.data) + try: + result = u"".join(text) + self.failUnlessEqual(repr(result), r"u'\n Some greek: \u0391\u0392\u0393\u0394\u0395\n \n \n'") + except Exception, x: + self.fail("Unexpected exception joining text pieces: %s" % str(x)) + + def testAttributes(self): + attrText = [] + for event, node in pulldom.parse(self.testFile): + if event == pulldom.START_ELEMENT: + for attrIx in range(node.attributes.length): + attrText.append(node.attributes.item(attrIx).value) + try: + result = u"".join(attrText) + self.failUnlessEqual(repr(result), r"u'\u0396\u0397\u0398\u0399\u039a'") + except Exception, x: + self.fail("Unexpected exception joining attribute text pieces: %s" % str(x)) + + def testProcessingInstruction(self): + piText = [] + for event, node in pulldom.parse(self.testFile): + if event == pulldom.PROCESSING_INSTRUCTION: + piText.append(node.data) + try: + result = u"".join(piText) + # Weird how the repr for PI data is different from text and char data. + # Still, the whole xml.dom.* and xml.sax.* hierarchy is rather a + # labyrinthine mess under jython, mostly because it's so old, and + # yet survived through major evolutionary changes in both jython and java. + self.failUnlessEqual(repr(result), r"u'ΛΜΝΞΟ'") + except Exception, x: + self.fail("Unexpected exception joining pi data pieces: %s" % str(x)) + +def test_main(): + tests = [ + UnicodeTests, + ] + suites = [unittest.makeSuite(klass, 'test') for klass in tests] + test_support.run_suite(unittest.TestSuite(suites)) + +if __name__ == "__main__": + test_main() Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-01 07:41:40 UTC (rev 6994) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-01 12:07:25 UTC (rev 6995) @@ -188,7 +188,7 @@ self._cont_handler.characters(String(char, start, len).getBytes('utf-8').tostring().decode('utf-8')) def ignorableWhitespace(self, char, start, len): - self._cont_handler.ignorableWhitespace(str(String(char, start, len))) + self._cont_handler.ignorableWhitespace(String(char, start, len).getBytes('utf-8').tostring().decode('utf-8')) def endElement(self, uri, lname, qname): if self._namespaces: Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-01 07:41:40 UTC (rev 6994) +++ trunk/jython/NEWS 2010-04-01 12:07:25 UTC (rev 6995) @@ -2,6 +2,7 @@ Jython 2.5.2a1 Bugs Fixed + - [ 1583 ] xml.dom.Node.data returns bytestrings of decoded unicode - [ 1225 ] socket.getservbyname/port() not yet supported - [ 1532 ] Cannot use docstring when defining class - [ 1530 ] BoolOp in multiple assign causes VerifyError This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-02 01:42:13
|
Revision: 6996 http://jython.svn.sourceforge.net/jython/?rev=6996&view=rev Author: pjenvey Date: 2010-04-02 01:42:07 +0000 (Fri, 02 Apr 2010) Log Message: ----------- have Java objects' __unicode__ pass-thru the result of their toString fixes #1563 Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyJavaType.java Added Paths: ----------- trunk/jython/tests/java/org/python/tests/ToUnicode.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2010-04-01 12:07:25 UTC (rev 6995) +++ trunk/jython/Lib/test/test_java_integration.py 2010-04-02 01:42:07 UTC (rev 6996) @@ -20,7 +20,8 @@ from javax.swing.tree import TreePath from org.python.core.util import FileUtil -from org.python.tests import BeanImplementation, Child, Child2, Listenable, CustomizableMapHolder +from org.python.tests import (BeanImplementation, Child, Child2, + CustomizableMapHolder, Listenable, ToUnicode) from org.python.tests.mro import (ConfusedOnGetitemAdd, FirstPredefinedGetitem, GetitemAdder) class InstantiationTest(unittest.TestCase): @@ -478,6 +479,13 @@ unserializer = ObjectInputStream(input) self.assertEqual(date_list, unserializer.readObject()) +class UnicodeTest(unittest.TestCase): + + def test_unicode_conversion(self): + test = unicode(ToUnicode()) + self.assertEqual(type(test), unicode) + self.assertEqual(test, u"Circle is 360\u00B0") + def test_main(): test_support.run_unittest(InstantiationTest, BeanTest, @@ -493,7 +501,8 @@ JavaDelegationTest, SecurityManagerTest, JavaWrapperCustomizationTest, - SerializationTest) + SerializationTest, + UnicodeTest) if __name__ == "__main__": test_main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-01 12:07:25 UTC (rev 6995) +++ trunk/jython/NEWS 2010-04-02 01:42:07 UTC (rev 6996) @@ -20,6 +20,7 @@ - [ 1426 ] JSR 223 Bindings changes not taking effect and leaking between threads; unnecessary synchronization - [ 1548 ] Parentheses in CLASSPATH cause errors in jython.bat - [ 1576 ] files opened in 'a+' mode not readable + - [ 1563 ] unicode() for Java objects working differently in 2.2 and 2.5 - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2010-04-01 12:07:25 UTC (rev 6995) +++ trunk/jython/src/org/python/core/PyJavaType.java 2010-04-02 01:42:07 UTC (rev 6996) @@ -542,6 +542,12 @@ return Py.newString(self.getJavaProxy().toString()); } }); + addMethod(new PyBuiltinMethodNarrow("__unicode__") { + @Override + public PyObject __call__() { + return new PyUnicode(self.toString()); + } + }); } if(forClass == Comparable.class) { addMethod(new ComparableMethod("__lt__", 1) { Added: trunk/jython/tests/java/org/python/tests/ToUnicode.java =================================================================== --- trunk/jython/tests/java/org/python/tests/ToUnicode.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/ToUnicode.java 2010-04-02 01:42:07 UTC (rev 6996) @@ -0,0 +1,9 @@ +package org.python.tests; + +public class ToUnicode { + + @Override + public String toString() { + return "Circle is 360\u00B0"; + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-04 00:17:05
|
Revision: 6999 http://jython.svn.sourceforge.net/jython/?rev=6999&view=rev Author: pjenvey Date: 2010-04-04 00:16:58 +0000 (Sun, 04 Apr 2010) Log Message: ----------- os.popen files should use text mode fixes #1566 Modified Paths: -------------- trunk/jython/Lib/os.py trunk/jython/NEWS Modified: trunk/jython/Lib/os.py =================================================================== --- trunk/jython/Lib/os.py 2010-04-02 16:15:48 UTC (rev 6998) +++ trunk/jython/Lib/os.py 2010-04-04 00:16:58 UTC (rev 6999) @@ -678,11 +678,14 @@ if mode == 'r': proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True, stdout=subprocess.PIPE) - return _wrap_close(proc.stdout, proc) + fp = proc.stdout elif mode == 'w': proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True, stdin=subprocess.PIPE) - return _wrap_close(proc.stdin, proc) + fp = proc.stdin + # files from subprocess are in binary mode but popen needs text mode + fp = fdopen(fp.fileno(), mode, bufsize) + return _wrap_close(fp, proc) # Helper for popen() -- a proxy for a file whose close waits for the process class _wrap_close(object): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-02 16:15:48 UTC (rev 6998) +++ trunk/jython/NEWS 2010-04-04 00:16:58 UTC (rev 6999) @@ -21,6 +21,7 @@ - [ 1548 ] Parentheses in CLASSPATH cause errors in jython.bat - [ 1576 ] files opened in 'a+' mode not readable - [ 1563 ] unicode() for Java objects working differently in 2.2 and 2.5 + - [ 1566 ] os.popen(cmd).read() returns `\r\n` as newline on Windows with Jython 2.5 - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |