From: <pj...@us...> - 2010-04-04 18:02:08
|
Revision: 7000 http://jython.svn.sourceforge.net/jython/?rev=7000&view=rev Author: pjenvey Date: 2010-04-04 18:02:02 +0000 (Sun, 04 Apr 2010) Log Message: ----------- allow more arities on some not implemented functions fixes #1517 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/modules/gc.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-04 00:16:58 UTC (rev 6999) +++ trunk/jython/NEWS 2010-04-04 18:02:02 UTC (rev 7000) @@ -22,6 +22,7 @@ - [ 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 + - [ 1517 ] TypeError: get_referrers - 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/modules/gc.java =================================================================== --- trunk/jython/src/org/python/modules/gc.java 2010-04-04 00:16:58 UTC (rev 6999) +++ trunk/jython/src/org/python/modules/gc.java 2010-04-04 18:02:02 UTC (rev 7000) @@ -1,9 +1,6 @@ package org.python.modules; -import org.python.core.ClassDictInit; import org.python.core.Py; -import org.python.core.PyException; -import org.python.core.PyInteger; import org.python.core.PyObject; public class gc { @@ -34,12 +31,12 @@ throw Py.NotImplementedError("not applicable to Java GC"); } - public static void set_debug() { + public static void set_debug(int flags) { throw Py.NotImplementedError("not applicable to Java GC"); } public static int get_debug() { return 0; } - public static void set_threshold() { + public static void set_threshold(PyObject[] args, String[] kwargs) { throw Py.NotImplementedError("not applicable to Java GC"); } public static PyObject get_threshold() { @@ -49,10 +46,10 @@ public static PyObject get_objects() { throw Py.NotImplementedError("not applicable to Java GC"); } - public static PyObject get_referrers() { + public static PyObject get_referrers(PyObject[] args, String[] kwargs) { throw Py.NotImplementedError("not applicable to Java GC"); } - public static PyObject get_referents() { + public static PyObject get_referents(PyObject[] args, String[] kwargs) { throw Py.NotImplementedError("not applicable to Java GC"); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-05 01:49:24
|
Revision: 7001 http://jython.svn.sourceforge.net/jython/?rev=7001&view=rev Author: pjenvey Date: 2010-04-05 01:49:16 +0000 (Mon, 05 Apr 2010) Log Message: ----------- fix the string-escape codec not escaping the escape char fixes #1502 thanks gz Modified Paths: -------------- trunk/jython/Lib/test/test_codecs_jy.py trunk/jython/NEWS trunk/jython/src/org/python/modules/_codecs.java Modified: trunk/jython/Lib/test/test_codecs_jy.py =================================================================== --- trunk/jython/Lib/test/test_codecs_jy.py 2010-04-04 18:02:02 UTC (rev 7000) +++ trunk/jython/Lib/test/test_codecs_jy.py 2010-04-05 01:49:16 UTC (rev 7001) @@ -1,19 +1,28 @@ import subprocess import sys -import test_support import unittest +from test import test_support -class AccessBuiltinCodecs(unittest.TestCase): +class CodecsTestCase(unittest.TestCase): + def test_print_sans_lib(self): - '''Encodes and decodes using utf-8 after in an environment without the standard library + """Encodes and decodes using utf-8 after in an environment + without the standard library - Checks that the builtin utf-8 codec is always available: http://bugs.jython.org/issue1458''' + Checks that the builtin utf-8 codec is always available: + http://bugs.jython.org/issue1458""" subprocess.call([sys.executable, "-J-Dpython.cachedir.skip=true", - "-J-Dpython.security.respectJavaAccessibility=false", + "-J-Dpython.security.respectJavaAccessibility=false", test_support.findfile('print_sans_lib.py')]) + def test_string_escape_1502(self): + # http://bugs.jython.org/issue1502 + self.assertEqual('\\x00'.encode('string-escape'), '\\\\x00') + + def test_main(): - test_support.run_unittest(AccessBuiltinCodecs) + test_support.run_unittest(CodecsTestCase) + if __name__ == "__main__": test_main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-04 18:02:02 UTC (rev 7000) +++ trunk/jython/NEWS 2010-04-05 01:49:16 UTC (rev 7001) @@ -23,6 +23,7 @@ - [ 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 - [ 1517 ] TypeError: get_referrers + - [ 1502 ] string-escape codec incorrect - 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/modules/_codecs.java =================================================================== --- trunk/jython/src/org/python/modules/_codecs.java 2010-04-04 18:02:02 UTC (rev 7000) +++ trunk/jython/src/org/python/modules/_codecs.java 2010-04-05 01:49:16 UTC (rev 7001) @@ -118,9 +118,10 @@ } public static PyTuple escape_encode(String str, String errors) { - return encode_tuple(PyString.encode_UnicodeEscape(str, false), - str.length()); - + int size = str.length(); + str = PyString.encode_UnicodeEscape(str, true); + // The string will be quoted, unquote + return encode_tuple(str.substring(1, str.length() - 1), size); } /* --- Character Mapping Codec --------------------------------------- */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-06 02:02:54
|
Revision: 7002 http://jython.svn.sourceforge.net/jython/?rev=7002&view=rev Author: pjenvey Date: 2010-04-06 02:02:34 +0000 (Tue, 06 Apr 2010) Log Message: ----------- better fix for r7001, also fixes unicode-escape not escaping the escape char fixes #1502 patch from gz Modified Paths: -------------- trunk/jython/Lib/test/test_codecs_jy.py trunk/jython/src/org/python/core/PyString.java trunk/jython/src/org/python/modules/_codecs.java Modified: trunk/jython/Lib/test/test_codecs_jy.py =================================================================== --- trunk/jython/Lib/test/test_codecs_jy.py 2010-04-05 01:49:16 UTC (rev 7001) +++ trunk/jython/Lib/test/test_codecs_jy.py 2010-04-06 02:02:34 UTC (rev 7002) @@ -18,6 +18,7 @@ def test_string_escape_1502(self): # http://bugs.jython.org/issue1502 self.assertEqual('\\x00'.encode('string-escape'), '\\\\x00') + self.assertEqual('\\x00'.encode('unicode-escape'), '\\\\x00') def test_main(): Modified: trunk/jython/src/org/python/core/PyString.java =================================================================== --- trunk/jython/src/org/python/core/PyString.java 2010-04-05 01:49:16 UTC (rev 7001) +++ trunk/jython/src/org/python/core/PyString.java 2010-04-06 02:02:34 UTC (rev 7002) @@ -154,7 +154,7 @@ for (int i = 0; size-- > 0; ) { int ch = str.charAt(i++); /* Escape quotes */ - if (use_quotes && (ch == quote || ch == '\\')) { + if ((use_quotes && ch == quote) || ch == '\\') { v.append('\\'); v.append((char) ch); continue; Modified: trunk/jython/src/org/python/modules/_codecs.java =================================================================== --- trunk/jython/src/org/python/modules/_codecs.java 2010-04-05 01:49:16 UTC (rev 7001) +++ trunk/jython/src/org/python/modules/_codecs.java 2010-04-06 02:02:34 UTC (rev 7002) @@ -118,10 +118,7 @@ } public static PyTuple escape_encode(String str, String errors) { - int size = str.length(); - str = PyString.encode_UnicodeEscape(str, true); - // The string will be quoted, unquote - return encode_tuple(str.substring(1, str.length() - 1), size); + return encode_tuple(PyString.encode_UnicodeEscape(str, false), str.length()); } /* --- Character Mapping Codec --------------------------------------- */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-09 03:22:01
|
Revision: 7007 http://jython.svn.sourceforge.net/jython/?rev=7007&view=rev Author: pjenvey Date: 2010-04-09 03:21:55 +0000 (Fri, 09 Apr 2010) Log Message: ----------- fix an incompat. with CPython: allow data descriptors without a __get__ to override themselves in the instance dict fixes #1534 Modified Paths: -------------- trunk/jython/Lib/test/test_descr_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyJavaType.java trunk/jython/src/org/python/core/PyObject.java trunk/jython/src/org/python/core/PyType.java trunk/jython/src/org/python/expose/generate/DescriptorExposer.java Modified: trunk/jython/Lib/test/test_descr_jy.py =================================================================== --- trunk/jython/Lib/test/test_descr_jy.py 2010-04-09 03:01:56 UTC (rev 7006) +++ trunk/jython/Lib/test/test_descr_jy.py 2010-04-09 03:21:55 UTC (rev 7007) @@ -97,7 +97,25 @@ except AttributeError, e: self.assertEquals("Custom message", str(e)) + def test_set_without_get(self): + class Descr(object): + def __init__(self, name): + self.name = name + + def __set__(self, obj, value): + obj.__dict__[self.name] = value + descr = Descr("a") + + class X(object): + a = descr + + x = X() + self.assertTrue(x.a is descr) + x.a = 42 + self.assertEqual(x.a, 42) + + class SubclassDescrTestCase(unittest.TestCase): def test_subclass_cmp_right_op(self): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-09 03:01:56 UTC (rev 7006) +++ trunk/jython/NEWS 2010-04-09 03:21:55 UTC (rev 7007) @@ -24,6 +24,7 @@ - [ 1566 ] os.popen(cmd).read() returns `\r\n` as newline on Windows with Jython 2.5 - [ 1517 ] TypeError: get_referrers - [ 1502 ] string-escape codec incorrect + - [ 1534 ] new style object __dict__[name] ignored - 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-09 03:01:56 UTC (rev 7006) +++ trunk/jython/src/org/python/core/PyJavaType.java 2010-04-09 03:21:55 UTC (rev 7007) @@ -507,9 +507,12 @@ } } if (baseClass != Object.class) { - has_set = getDescrMethod(forClass, "__set__", OO) != null + hasGet = getDescrMethod(forClass, "__get__", OO) != null + || getDescrMethod(forClass, "_doget", PyObject.class) != null + || getDescrMethod(forClass, "_doget", OO) != null; + hasSet = getDescrMethod(forClass, "__set__", OO) != null || getDescrMethod(forClass, "_doset", OO) != null; - has_delete = getDescrMethod(forClass, "__delete__", PyObject.class) != null + hasDelete = getDescrMethod(forClass, "__delete__", PyObject.class) != null || getDescrMethod(forClass, "_dodel", PyObject.class) != null; } if (forClass == Object.class) { Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2010-04-09 03:01:56 UTC (rev 7006) +++ trunk/jython/src/org/python/core/PyObject.java 2010-04-09 03:21:55 UTC (rev 7007) @@ -3639,22 +3639,22 @@ throw Py.TypeError("can't delete attribute '__dict__' of instance of '" + getType().fastGetName()+ "'"); } + public boolean implementsDescrGet() { + return objtype.hasGet; + } + public boolean implementsDescrSet() { - return objtype.has_set; + return objtype.hasSet; } public boolean implementsDescrDelete() { - return objtype.has_delete; + return objtype.hasDelete; } - public boolean isDataDescr() { // implements either __set__ or __delete__ - return objtype.has_set || objtype.has_delete; + public boolean isDataDescr() { + return objtype.hasSet || objtype.hasDelete; } - // doc & xxx ok this way? - // can return null meaning set-only or throw exception - - // backward comp impls. /** * Get descriptor for this PyObject. * @@ -3685,8 +3685,9 @@ final PyObject object___getattribute__(PyObject arg0) { String name = asName(arg0); PyObject ret = object___findattr__(name); - if(ret == null) + if (ret == null) { noAttributeError(name); + } return ret; } @@ -3694,26 +3695,31 @@ final PyObject object___findattr__(String name) { PyObject descr = objtype.lookup(name); PyObject res; + boolean get = false; if (descr != null) { - if (descr.isDataDescr()) { - res = descr.__get__(this, objtype); - if (res != null) - return res; + get = descr.implementsDescrGet(); + if (get && descr.isDataDescr()) { + return descr.__get__(this, objtype); } } PyObject obj_dict = fastGetDict(); if (obj_dict != null) { res = obj_dict.__finditem__(name); - if (res != null) + if (res != null) { return res; + } } - if (descr != null) { + if (get) { return descr.__get__(this, objtype); } + if (descr != null) { + return descr; + } + return null; } @@ -3783,10 +3789,11 @@ try { obj_dict.__delitem__(name); } catch (PyException exc) { - if (exc.match(Py.KeyError)) + if (exc.match(Py.KeyError)) { noAttributeError(name); - else + } else { throw exc; + } } return; } Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2010-04-09 03:01:56 UTC (rev 7006) +++ trunk/jython/src/org/python/core/PyType.java 2010-04-09 03:21:55 UTC (rev 7007) @@ -63,9 +63,10 @@ /** Whether new instances of this type can be instantiated */ protected boolean instantiable = true; - /** Whether this type has set/delete descriptors */ - boolean has_set; - boolean has_delete; + /** Whether this type implements descriptor __get/set/delete__ methods. */ + boolean hasGet; + boolean hasSet; + boolean hasDelete; /** Whether this type allows subclassing. */ private boolean isBaseType = true; @@ -294,6 +295,11 @@ String doc = "dictionary for instance variables (if defined)"; dict.__setitem__("__dict__", new PyDataDescr(this, "__dict__", PyObject.class, doc) { @Override + public boolean implementsDescrGet() { + return true; + } + + @Override public Object invokeGet(PyObject obj) { return obj.getDict(); } @@ -336,6 +342,11 @@ } @Override + public boolean implementsDescrGet() { + return true; + } + + @Override public Object invokeGet(PyObject obj) { PyList weakrefs = WeakrefModule.getweakrefs(obj); switch (weakrefs.size()) { @@ -391,7 +402,7 @@ // Calculate method resolution order mro_internal(); - fillHasSetAndDelete(); + cacheDescrBinds(); } /** @@ -498,7 +509,7 @@ setIsBaseType(builder.getIsBaseType()); needs_userdict = dict.__finditem__("__dict__") != null; instantiable = dict.__finditem__("__new__") != null; - fillHasSetAndDelete(); + cacheDescrBinds(); } /** @@ -513,9 +524,14 @@ bases = new PyObject[] {base}; } - private void fillHasSetAndDelete() { - has_set = lookup_mro("__set__") != null; - has_delete = lookup_mro("__delete__") != null; + + /** + * Determine if this type is a descriptor, and if so what kind. + */ + private void cacheDescrBinds() { + hasGet = lookup_mro("__get__") != null; + hasSet = lookup_mro("__set__") != null; + hasDelete = lookup_mro("__delete__") != null; } public PyObject getStatic() { @@ -1298,11 +1314,12 @@ // name must be interned final PyObject type___findattr_ex__(String name) { PyType metatype = getType(); - PyObject metaattr = metatype.lookup(name); + boolean get = false; - if (metaattr != null && useMetatypeFirst(metaattr)) { - if (metaattr.isDataDescr()) { + if (metaattr != null) { + get = metaattr.implementsDescrGet(); + if (useMetatypeFirst(metaattr) && get && metaattr.isDataDescr()) { PyObject res = metaattr.__get__(this, metatype); if (res != null) return res; @@ -1318,10 +1335,14 @@ } } - if (metaattr != null) { + if (get) { return metaattr.__get__(this, metatype); } + if (metaattr != null) { + return metaattr; + } + return null; } @@ -1369,22 +1390,32 @@ void postSetattr(String name) { invalidateMethodCache(); - if (name == "__set__") { - if (!has_set && lookup("__set__") != null) { + if (name == "__get__") { + if (!hasGet && lookup("__get__") != null) { traverse_hierarchy(false, new OnType() { public boolean onType(PyType type) { - boolean old = type.has_set; - type.has_set = true; + boolean old = type.hasGet; + type.hasGet = true; return old; } }); } + } else if (name == "__set__") { + if (!hasSet && lookup("__set__") != null) { + traverse_hierarchy(false, new OnType() { + public boolean onType(PyType type) { + boolean old = type.hasSet; + type.hasSet = true; + return old; + } + }); + } } else if (name == "__delete__") { - if (!has_delete && lookup("__delete__") != null) { + if (!hasDelete && lookup("__delete__") != null) { traverse_hierarchy(false, new OnType() { public boolean onType(PyType type) { - boolean old = type.has_delete; - type.has_delete = true; + boolean old = type.hasDelete; + type.hasDelete = true; return old; } }); @@ -1421,13 +1452,26 @@ void postDelattr(String name) { invalidateMethodCache(); - if (name == "__set__") { - if (has_set && lookup("__set__") == null) { + if (name == "__get__") { + if (hasGet && lookup("__get__") == null) { traverse_hierarchy(false, new OnType() { public boolean onType(PyType type) { + boolean absent = type.getDict().__finditem__("__get__") == null; + if (absent) { + type.hasGet = false; + return false; + } + return true; + } + }); + } + } else if (name == "__set__") { + if (hasSet && lookup("__set__") == null) { + traverse_hierarchy(false, new OnType() { + public boolean onType(PyType type) { boolean absent = type.getDict().__finditem__("__set__") == null; if (absent) { - type.has_set = false; + type.hasSet = false; return false; } return true; @@ -1435,12 +1479,12 @@ }); } } else if (name == "__delete__") { - if (has_delete && lookup("__delete__") == null) { + if (hasDelete && lookup("__delete__") == null) { traverse_hierarchy(false, new OnType() { public boolean onType(PyType type) { boolean absent = type.getDict().__finditem__("__delete__") == null; if (absent) { - type.has_delete = false; + type.hasDelete = false; return false; } return true; Modified: trunk/jython/src/org/python/expose/generate/DescriptorExposer.java =================================================================== --- trunk/jython/src/org/python/expose/generate/DescriptorExposer.java 2010-04-09 03:01:56 UTC (rev 7006) +++ trunk/jython/src/org/python/expose/generate/DescriptorExposer.java 2010-04-09 03:21:55 UTC (rev 7007) @@ -121,6 +121,7 @@ } else { generateFieldGetter(); } + generateImplement("Get", getterMethodName != null || getterFieldName != null); if(setterMethodName != null) { generateMethodSetter(); } else if(setterFieldName != null) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-10 02:13:18
|
Revision: 7012 http://jython.svn.sourceforge.net/jython/?rev=7012&view=rev Author: pjenvey Date: 2010-04-10 02:13:10 +0000 (Sat, 10 Apr 2010) Log Message: ----------- close file handles fixes #1479 Modified Paths: -------------- trunk/jython/Lib/test/test_xml_etree_jy.py trunk/jython/Lib/xml/etree/ElementTree.py trunk/jython/NEWS Modified: trunk/jython/Lib/test/test_xml_etree_jy.py =================================================================== --- trunk/jython/Lib/test/test_xml_etree_jy.py 2010-04-10 02:09:19 UTC (rev 7011) +++ trunk/jython/Lib/test/test_xml_etree_jy.py 2010-04-10 02:13:10 UTC (rev 7012) @@ -750,5 +750,22 @@ Entity name: entity """ +def test_close_files(): + # http://bugs.jython.org/issue1479 + """ + >>> import os + >>> from test import test_support + >>> from xml.etree import ElementTree as ET + + >>> ET.ElementTree(ET.XML('<test/>')).write(test_support.TESTFN) + >>> os.remove(test_support.TESTFN) + + >>> fp = open(test_support.TESTFN, 'w') + >>> fp.write('<test/>') + >>> fp.close() + >>> tree = ET.parse(test_support.TESTFN) + >>> os.remove(test_support.TESTFN) + """ + if __name__ == "__main__": doctest.testmod() Modified: trunk/jython/Lib/xml/etree/ElementTree.py =================================================================== --- trunk/jython/Lib/xml/etree/ElementTree.py 2010-04-10 02:09:19 UTC (rev 7011) +++ trunk/jython/Lib/xml/etree/ElementTree.py 2010-04-10 02:13:10 UTC (rev 7012) @@ -575,17 +575,22 @@ # @defreturn Element def parse(self, source, parser=None): - if not hasattr(source, "read"): + managed_file = not hasattr(source, "read") + if managed_file: source = open(source, "rb") - if not parser: - parser = XMLTreeBuilder() - while 1: - data = source.read(32768) - if not data: - break - parser.feed(data) - self._root = parser.close() - return self._root + try: + if not parser: + parser = XMLTreeBuilder() + while 1: + data = source.read(32768) + if not data: + break + parser.feed(data) + self._root = parser.close() + return self._root + finally: + if managed_file: + source.close() ## # Creates a tree iterator for the root element. The iterator loops @@ -654,13 +659,18 @@ def write(self, file, encoding="us-ascii"): assert self._root is not None - if not hasattr(file, "write"): + managed_file = not hasattr(file, "write") + if managed_file: file = open(file, "wb") - if not encoding: - encoding = "us-ascii" - elif encoding != "utf-8" and encoding != "us-ascii": - file.write("<?xml version='1.0' encoding='%s'?>\n" % encoding) - self._write(file, self._root, encoding, {}) + try: + if not encoding: + encoding = "us-ascii" + elif encoding != "utf-8" and encoding != "us-ascii": + file.write("<?xml version='1.0' encoding='%s'?>\n" % encoding) + self._write(file, self._root, encoding, {}) + finally: + if managed_file: + file.close() def _write(self, file, node, encoding, namespaces): # write XML to file @@ -874,7 +884,8 @@ class iterparse: def __init__(self, source, events=None): - if not hasattr(source, "read"): + self._managed_file = not hasattr(source, "read") + if self._managed_file: source = open(source, "rb") self._file = source self._events = [] @@ -938,6 +949,8 @@ else: self._root = self._parser.close() self._parser = None + if self._managed_file: + self._file.close() else: self._index = self._index + 1 return item Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-10 02:09:19 UTC (rev 7011) +++ trunk/jython/NEWS 2010-04-10 02:13:10 UTC (rev 7012) @@ -25,6 +25,7 @@ - [ 1517 ] TypeError: get_referrers - [ 1502 ] string-escape codec incorrect - [ 1534 ] new style object __dict__[name] ignored + - [ 1479 ] xml parser file lock - 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. |
From: <pj...@us...> - 2010-04-10 20:50:52
|
Revision: 7015 http://jython.svn.sourceforge.net/jython/?rev=7015&view=rev Author: pjenvey Date: 2010-04-10 20:50:46 +0000 (Sat, 10 Apr 2010) Log Message: ----------- o bring in Java 6's Collections.newSetFromMap as Generic.newSetFromMap which makes our ConcurrentHashSet redundant o hold PyConnection cursors/statements in a weak Set so they can be GC'd easier. synchronize these sets too fixes #1582 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/com/ziclix/python/sql/PyConnection.java trunk/jython/src/org/python/util/Generic.java Removed Paths: ------------- trunk/jython/src/org/python/core/util/ConcurrentHashSet.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-10 20:48:35 UTC (rev 7014) +++ trunk/jython/NEWS 2010-04-10 20:50:46 UTC (rev 7015) @@ -26,6 +26,7 @@ - [ 1502 ] string-escape codec incorrect - [ 1534 ] new style object __dict__[name] ignored - [ 1479 ] xml parser file lock + - [ 1582 ] com.ziclix.python.sql.PyConnection leaks memory - 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/com/ziclix/python/sql/PyConnection.java =================================================================== --- trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2010-04-10 20:48:35 UTC (rev 7014) +++ trunk/jython/src/com/ziclix/python/sql/PyConnection.java 2010-04-10 20:50:46 UTC (rev 7015) @@ -11,10 +11,11 @@ import java.sql.Connection; import java.sql.SQLException; import java.util.Collections; -import java.util.HashSet; +import java.util.WeakHashMap; import java.util.Set; import org.python.core.ClassDictInit; +import org.python.core.ContextManager; import org.python.core.Py; import org.python.core.PyBuiltinMethodSet; import org.python.core.PyException; @@ -23,12 +24,11 @@ import org.python.core.PyObject; import org.python.core.PyString; import org.python.core.PyUnicode; +import org.python.core.ThreadState; +import org.python.util.Generic; import com.ziclix.python.sql.util.PyArgParser; -import org.python.core.ContextManager; -import org.python.core.ThreadState; - /** * A connection to the database. * @@ -93,9 +93,11 @@ */ public PyConnection(Connection connection) throws SQLException { this.closed = false; - this.cursors = new HashSet<PyCursor>(); + cursors = Generic.newSetFromMap(new WeakHashMap<PyCursor, Boolean>()); + cursors = Collections.synchronizedSet(cursors); this.connection = connection; - this.statements = new HashSet<PyStatement>(); + statements = Generic.newSetFromMap(new WeakHashMap<PyStatement, Boolean>()); + statements = Collections.synchronizedSet(statements); this.supportsTransactions = this.connection.getMetaData().supportsTransactions(); this.supportsMultipleResultSets = this.connection.getMetaData().supportsMultipleResultSets(); Deleted: trunk/jython/src/org/python/core/util/ConcurrentHashSet.java =================================================================== --- trunk/jython/src/org/python/core/util/ConcurrentHashSet.java 2010-04-10 20:48:35 UTC (rev 7014) +++ trunk/jython/src/org/python/core/util/ConcurrentHashSet.java 2010-04-10 20:50:46 UTC (rev 7015) @@ -1,109 +0,0 @@ -/* Copyright (c) Jython Developers */ -package org.python.core.util; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.util.AbstractSet; -import java.util.Collection; -import java.util.Iterator; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -/** - * A Set backed by ConcurrentHashMap. - */ -public class ConcurrentHashSet<E> extends AbstractSet<E> implements Serializable { - - /** The backing Map. */ - private final ConcurrentMap<E, Boolean> map; - - /** Backing's KeySet. */ - private transient Set<E> keySet; - - public ConcurrentHashSet() { - map = new ConcurrentHashMap<E, Boolean>(); - keySet = map.keySet(); - } - - public ConcurrentHashSet(int initialCapacity) { - map = new ConcurrentHashMap<E, Boolean>(initialCapacity); - keySet = map.keySet(); - } - - public ConcurrentHashSet(int initialCapacity, float loadFactor, int concurrencyLevel) { - map = new ConcurrentHashMap<E, Boolean>(initialCapacity, loadFactor, concurrencyLevel); - keySet = map.keySet(); - } - - @Override - public int size() { - return map.size(); - } - - @Override - public boolean isEmpty() { - return map.isEmpty(); - } - - @Override - public boolean contains(Object o) { - return map.containsKey(o); - } - - @Override - public Iterator<E> iterator() { - return keySet.iterator(); - } - - @Override - public Object[] toArray() { - return keySet.toArray(); - } - - @Override - public <T> T[] toArray(T[] a) { - return keySet.toArray(a); - } - - @Override - public boolean add(E e) { - return map.put(e, Boolean.TRUE) == null; - } - - @Override - public boolean remove(Object o) { - return map.remove(o) != null; - } - - @Override - public boolean removeAll(Collection<?> c) { - return keySet.removeAll(c); - } - - @Override - public boolean retainAll(Collection<?> c) { - return keySet.retainAll(c); - } - - @Override - public void clear() { - map.clear(); - } - - @Override - public boolean equals(Object o) { - return keySet.equals(o); - } - - @Override - public int hashCode() { - return keySet.hashCode(); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - keySet = map.keySet(); - } -} Modified: trunk/jython/src/org/python/util/Generic.java =================================================================== --- trunk/jython/src/org/python/util/Generic.java 2010-04-10 20:48:35 UTC (rev 7014) +++ trunk/jython/src/org/python/util/Generic.java 2010-04-10 20:50:46 UTC (rev 7015) @@ -1,16 +1,20 @@ package org.python.util; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.AbstractSet; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import org.python.core.util.ConcurrentHashSet; - /** * Static methods to make instances of collections with their generic types inferred from what * they're being assigned to. The idea is stolen from <code>Sets</code>, <code>Lists</code> and @@ -64,8 +68,8 @@ /** * Makes a Set using the generic type inferred from whatever this is being assigned to. */ - public static <T> Set<T> set() { - return new HashSet<T>(); + public static <E> Set<E> set() { + return new HashSet<E>(); } /** @@ -84,8 +88,128 @@ * Makes a Set, ensuring safe concurrent operations, using generic types inferred from * whatever this is being assigned to. */ - public static <T> Set<T> concurrentSet() { - return new ConcurrentHashSet<T>(CHM_INITIAL_CAPACITY, CHM_LOAD_FACTOR, - CHM_CONCURRENCY_LEVEL); + public static <E> Set<E> concurrentSet() { + return newSetFromMap(new ConcurrentHashMap<E, Boolean>(CHM_INITIAL_CAPACITY, + CHM_LOAD_FACTOR, + CHM_CONCURRENCY_LEVEL)); } + + /** + * Return a Set backed by the specified Map with the same ordering, concurrency and + * performance characteristics. + * + * The specified Map must be empty at the time this method is invoked. + * + * Note that this method is based on Java 6's Collections.newSetFromMap, and will be + * removed in a future version of Jython (likely 2.6) that will rely on Java 6. + * + * @param map the backing Map + * @return a Set backed by the Map + * @throws IllegalArgumentException if Map is not empty + */ + public static <E> Set<E> newSetFromMap(Map<E, Boolean> map) { + return new SetFromMap<E>(map); + } + + /** + * A Set backed by a generic Map. + */ + private static class SetFromMap<E> extends AbstractSet<E> + implements Serializable { + + /** The backing Map. */ + private final Map<E, Boolean> map; + + /** Backing's KeySet. */ + private transient Set<E> keySet; + + public SetFromMap(Map<E, Boolean> map) { + if (!map.isEmpty()) { + throw new IllegalArgumentException("Map is non-empty"); + } + this.map = map; + keySet = map.keySet(); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return map.containsKey(o); + } + + @Override + public boolean containsAll(Collection<?> c) { + return keySet.containsAll(c); + } + + @Override + public Iterator<E> iterator() { + return keySet.iterator(); + } + + @Override + public Object[] toArray() { + return keySet.toArray(); + } + + @Override + public <T> T[] toArray(T[] a) { + return keySet.toArray(a); + } + + @Override + public boolean add(E e) { + return map.put(e, Boolean.TRUE) == null; + } + + @Override + public boolean remove(Object o) { + return map.remove(o) != null; + } + + @Override + public boolean removeAll(Collection<?> c) { + return keySet.removeAll(c); + } + + @Override + public boolean retainAll(Collection<?> c) { + return keySet.retainAll(c); + } + + @Override + public void clear() { + map.clear(); + } + + @Override + public boolean equals(Object o) { + return o == this || keySet.equals(o); + } + + @Override + public int hashCode() { + return keySet.hashCode(); + } + + @Override + public String toString() { + return keySet.toString(); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + keySet = map.keySet(); + } + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-11 03:18:43
|
Revision: 7016 http://jython.svn.sourceforge.net/jython/?rev=7016&view=rev Author: pjenvey Date: 2010-04-11 03:18:37 +0000 (Sun, 11 Apr 2010) Log Message: ----------- have os.listdir return unicode when requested fixes #1520 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-10 20:50:46 UTC (rev 7015) +++ trunk/jython/NEWS 2010-04-11 03:18:37 UTC (rev 7016) @@ -17,7 +17,7 @@ - [ 1396 ] Assigning os module funcs as class attributes incompatible with CPython - [ 1504 ] Inheriting twice from the same Java interface causes MRO problems - [ 1511 ] PySet doesn't support Java serialization - - [ 1426 ] JSR 223 Bindings changes not taking effect and leaking between threads; unnecessary synchronization + - [ 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 @@ -27,6 +27,7 @@ - [ 1534 ] new style object __dict__[name] ignored - [ 1479 ] xml parser file lock - [ 1582 ] com.ziclix.python.sql.PyConnection leaks memory + - [ 1520 ] os.listdir doesn't return unicode when requested - 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/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-10 20:50:46 UTC (rev 7015) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-11 03:18:37 UTC (rev 7016) @@ -474,12 +474,12 @@ "path: path of directory to list\n\n" + "The list is in arbitrary order. It does not include the special\n" + "entries '.' and '..' even if they are present in the directory."); - public static PyList listdir(String path) { - ensurePath(path); + public static PyList listdir(PyObject pathObj) { + ensurePath(pathObj); + String path = pathObj.asString(); PyList list = new PyList(); File file = new RelativeFile(path); String[] names = file.list(); - if (names == null) { // Can't read the path for some reason. stat will throw an error if it can't // read it either @@ -493,8 +493,10 @@ } throw Py.OSError("listdir(): an unknown error occured: " + path); } + + PyString string = (PyString) pathObj; for (String name : names) { - list.append(new PyString(name)); + list.append(string.createInstance(name)); } return list; } @@ -894,6 +896,13 @@ return new RelativeFile(path).getPath(); } + private static void ensurePath(PyObject path) { + if (!(path instanceof PyString)) { + throw Py.TypeError(String.format("coercing to Unicode: need string, %s type found", + path.getType().fastGetName())); + } + } + private static void ensurePath(String path) { if (path == null) { throw Py.TypeError("coercing to Unicode: need string or buffer, NoneType found"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-11 17:37:36
|
Revision: 7017 http://jython.svn.sourceforge.net/jython/?rev=7017&view=rev Author: pjenvey Date: 2010-04-11 17:37:29 +0000 (Sun, 11 Apr 2010) Log Message: ----------- fix unicode.translate not properly dealing in code points fixes #1483 Modified Paths: -------------- trunk/jython/Lib/test/test_unicode_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyUnicode.java trunk/jython/src/org/python/modules/_codecs.java Modified: trunk/jython/Lib/test/test_unicode_jy.py =================================================================== --- trunk/jython/Lib/test/test_unicode_jy.py 2010-04-11 03:18:37 UTC (rev 7016) +++ trunk/jython/Lib/test/test_unicode_jy.py 2010-04-11 17:37:29 UTC (rev 7017) @@ -138,7 +138,17 @@ self.assertEquals('\xe2\x82\xac', encoded_euro) self.assertEquals(EURO_SIGN, encoded_euro.decode('utf-8')) + def test_translate(self): + # http://bugs.jython.org/issue1483 + self.assertEqual( + u'\u0443\u043a\u0430\u0437\u0430\u0442\u044c'.translate({}), + u'\u0443\u043a\u0430\u0437\u0430\u0442\u044c') + self.assertEqual(u'\u0443oo'.translate({0x443: 102}), u'foo') + self.assertEqual( + unichr(sys.maxunicode).translate({sys.maxunicode: 102}), + u'f') + class UnicodeFormatTestCase(unittest.TestCase): def test_unicode_mapping(self): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-11 03:18:37 UTC (rev 7016) +++ trunk/jython/NEWS 2010-04-11 17:37:29 UTC (rev 7017) @@ -28,6 +28,7 @@ - [ 1479 ] xml parser file lock - [ 1582 ] com.ziclix.python.sql.PyConnection leaks memory - [ 1520 ] os.listdir doesn't return unicode when requested + - [ 1483 ] optparse std module dies on non-ASCII unicode data - 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/PyUnicode.java =================================================================== --- trunk/jython/src/org/python/core/PyUnicode.java 2010-04-11 03:18:37 UTC (rev 7016) +++ trunk/jython/src/org/python/core/PyUnicode.java 2010-04-11 17:37:29 UTC (rev 7017) @@ -1147,8 +1147,7 @@ @ExposedMethod(doc = BuiltinDocs.unicode_translate_doc) final PyObject unicode_translate(PyObject table) { - String trans = _codecs.translate_charmap(string, "ignore", table, true).__getitem__(0).toString(); - return new PyUnicode(trans); + return _codecs.translateCharmap(this, "ignore", table); } // these tests need to be UTF-16 aware because they are character-by-character tests, Modified: trunk/jython/src/org/python/modules/_codecs.java =================================================================== --- trunk/jython/src/org/python/modules/_codecs.java 2010-04-11 03:18:37 UTC (rev 7016) +++ trunk/jython/src/org/python/modules/_codecs.java 2010-04-11 17:37:29 UTC (rev 7017) @@ -9,6 +9,7 @@ import java.nio.ByteBuffer; import java.nio.charset.Charset; +import java.util.Iterator; import org.python.core.Py; import org.python.core.PyDictionary; @@ -183,60 +184,38 @@ } // parallel to CPython's PyUnicode_TranslateCharmap - public static PyTuple translate_charmap(String str, - String errors, - PyObject mapping, boolean ignoreUnmapped) { + public static PyObject translateCharmap(PyUnicode str, String errors, PyObject mapping) { + StringBuilder buf = new StringBuilder(str.toString().length()); - int size = str.length(); - StringBuilder v = new StringBuilder(size); - for (int i = 0; i < size; i++) { - char ch = str.charAt(i); - if (ch > 0xFF) { - i = codecs.insertReplacementAndGetResume(v, - errors, - "charmap", - str, - i, - i + 1, - "ordinal not in range(255)") - 1; - continue; - } - PyObject w = Py.newInteger(ch); - PyObject x = mapping.__finditem__(w); - if (x == null) { - if (ignoreUnmapped) { - v.append(ch); - } else { - i = codecs.insertReplacementAndGetResume(v, errors, "charmap", str, i, i + 1, "no mapping found") - 1; - } - continue; - } - /* Apply mapping */ - if (x instanceof PyInteger) { - int value = ((PyInteger) x).getValue(); + for (Iterator<Integer> iter = str.newSubsequenceIterator(); iter.hasNext();) { + int codePoint = iter.next(); + PyObject result = mapping.__finditem__(Py.newInteger(codePoint)); + if (result == null) { + // No mapping found means: use 1:1 mapping + buf.appendCodePoint(codePoint); + } else if (result == Py.None) { + // XXX: We don't support the fancier error handling CPython does here of + // capturing regions of chars removed by the None mapping to optionally + // pass to an error handler. Though we don't seem to even use this + // functionality anywhere either + ; + } else if (result instanceof PyInteger) { + int value = result.asInt(); if (value < 0 || value > PySystemState.maxunicode) { - throw Py.TypeError("character mapping must return " + "integer greater than 0 and less than sys.maxunicode"); + throw Py.TypeError(String.format("character mapping must be in range(0x%x)", + PySystemState.maxunicode + 1)); } - v.append((char) value); - } else if (x == Py.None) { - i = codecs.insertReplacementAndGetResume(v, - errors, - "charmap", - str, - i, - i + 1, - "character maps to <undefined>") - 1; - } else if (x instanceof PyUnicode) { - v.append(x.toString()); + buf.appendCodePoint(value); + } else if (result instanceof PyUnicode) { + buf.append(result.toString()); } else { - /* wrong return value */ - throw Py.TypeError("character mapping must return " + "integer, None or unicode"); + // wrong return value + throw Py.TypeError("character mapping must return integer, None or unicode"); } } - return decode_tuple(v.toString(), size); + return new PyUnicode(buf.toString()); } - - + public static PyTuple charmap_encode(String str, String errors, PyObject mapping) { //Default to Latin-1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-11 19:20:47
|
Revision: 7018 http://jython.svn.sourceforge.net/jython/?rev=7018&view=rev Author: pjenvey Date: 2010-04-11 19:20:41 +0000 (Sun, 11 Apr 2010) Log Message: ----------- add missing imp.is_builtin/frozen and load_compiled fixes #1390 Modified Paths: -------------- trunk/jython/Lib/test/test_chdir.py trunk/jython/Lib/test/test_import_jy.py trunk/jython/NEWS trunk/jython/src/org/python/modules/imp.java Modified: trunk/jython/Lib/test/test_chdir.py =================================================================== --- trunk/jython/Lib/test/test_chdir.py 2010-04-11 17:37:29 UTC (rev 7017) +++ trunk/jython/Lib/test/test_chdir.py 2010-04-11 19:20:41 UTC (rev 7018) @@ -269,7 +269,14 @@ self.assertEqual(mod.__file__, self.basename1) self.assert_(os.path.exists(self.bytecode)) + def test_imp_load_compiled(self): + __import__(self.mod_name) + self.assertTrue(os.path.exists(self.bytecode)) + basename = os.path.basename(self.bytecode) + mod = imp.load_compiled(self.mod_name, basename) + self.assertEqual(mod.__file__, basename) + class ImportPackageTestCase(BaseChdirTestCase): SYSPATH = ('',) Modified: trunk/jython/Lib/test/test_import_jy.py =================================================================== --- trunk/jython/Lib/test/test_import_jy.py 2010-04-11 17:37:29 UTC (rev 7017) +++ trunk/jython/Lib/test/test_import_jy.py 2010-04-11 19:20:41 UTC (rev 7018) @@ -2,6 +2,7 @@ Made for Jython. """ +from __future__ import with_statement import imp import os import shutil @@ -143,6 +144,24 @@ (None, '__builtin__', ('', '', 6))) self.assertEqual(imp.find_module('imp'), (None, 'imp', ('', '', 6))) + def test_imp_is_builtin(self): + self.assertTrue(all(imp.is_builtin(mod) + for mod in ['sys', '__builtin__', 'imp'])) + self.assertFalse(imp.is_builtin('os')) + + def test_load_compiled(self): + compiled = os.__file__ + if compiled.endswith('.py'): + compiled = compiled[:-3] + COMPILED_SUFFIX + + os.__doc__ = 'foo' + self.assertEqual(os, imp.load_compiled("os", compiled)) + self.assertFalse(os.__doc__ == 'foo') + with open(compiled, 'rb') as fp: + os.__doc__ = 'foo' + self.assertEqual(os, imp.load_compiled("os", compiled, fp)) + self.assertFalse(os.__doc__ == 'foo') + def test_getattr_module(self): '''Replacing __getattr__ in a class shouldn't lead to calls to __getitem__ Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-11 17:37:29 UTC (rev 7017) +++ trunk/jython/NEWS 2010-04-11 19:20:41 UTC (rev 7018) @@ -29,6 +29,7 @@ - [ 1582 ] com.ziclix.python.sql.PyConnection leaks memory - [ 1520 ] os.listdir doesn't return unicode when requested - [ 1483 ] optparse std module dies on non-ASCII unicode data + - [ 1390 ] ihooks fails due to unimplemented methods in imp module - 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/modules/imp.java =================================================================== --- trunk/jython/src/org/python/modules/imp.java 2010-04-11 17:37:29 UTC (rev 7017) +++ trunk/jython/src/org/python/modules/imp.java 2010-04-11 19:20:41 UTC (rev 7018) @@ -159,6 +159,25 @@ return mod; } + public static PyObject load_compiled(String name, String pathname) { + return load_compiled(name, pathname, new PyFile(pathname, "rb", -1)); + } + + public static PyObject load_compiled(String name, String pathname, PyObject file) { + InputStream stream = (InputStream) file.__tojava__(InputStream.class); + if (stream == Py.NoConversion) { + throw Py.TypeError("must be a file-like object"); + } + + // XXX: Ideally we wouldn't care about sourceName here (see + // http://bugs.jython.org/issue1605847 msg3805) + String sourceName = pathname; + if (sourceName.endsWith("$py.class")) { + sourceName = sourceName.substring(0, sourceName.length() - 9) + ".py"; + } + return org.python.core.imp.loadFromCompiled(name.intern(), stream, sourceName, pathname); + } + public static PyObject find_module(String name) { return find_module(name, Py.None); } @@ -192,13 +211,14 @@ PySystemState sys = Py.getSystemState(); int type = data.__getitem__(2).asInt(); while(mod == Py.None) { - Object o = file.__tojava__(InputStream.class); - if (o == Py.NoConversion) { - throw Py.TypeError("must be a file-like object"); - } String compiledName; switch (type) { case PY_SOURCE: + Object o = file.__tojava__(InputStream.class); + if (o == Py.NoConversion) { + throw Py.TypeError("must be a file-like object"); + } + // XXX: This should load the accompanying byte code file instead, if it exists String resolvedFilename = sys.getPath(filename.toString()); compiledName = org.python.core.imp.makeCompiledFilename(resolvedFilename); @@ -221,15 +241,7 @@ mtime); break; case PY_COMPILED: - compiledName = filename.toString(); - // XXX: Ideally we wouldn't care about sourceName here (see - // http://bugs.jython.org/issue1605847 msg3805) - String sourceName = compiledName; - if (compiledName.endsWith("$py.class")) { - sourceName = compiledName.substring(0, compiledName.length() - 9) + ".py"; - } - mod = org.python.core.imp.loadFromCompiled( - name.intern(), (InputStream)o, sourceName, filename.toString()); + mod = load_compiled(name, filename.toString(), file); break; case PKG_DIRECTORY: PyModule m = org.python.core.imp.addModule(name); @@ -262,6 +274,14 @@ return new PyModule(name, null); } + public static boolean is_builtin(String name) { + return PySystemState.getBuiltin(name) != null; + } + + public static boolean is_frozen(String name) { + return false; + } + /** * Acquires the interpreter's import lock for the current thread. * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-11 22:21:43
|
Revision: 7020 http://jython.svn.sourceforge.net/jython/?rev=7020&view=rev Author: pjenvey Date: 2010-04-11 22:21:31 +0000 (Sun, 11 Apr 2010) Log Message: ----------- remove bean accessors for sys.settrace/profile that we don't want fixes #1456 Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/core/PySystemState.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-11 19:49:26 UTC (rev 7019) +++ trunk/jython/NEWS 2010-04-11 22:21:31 UTC (rev 7020) @@ -30,6 +30,7 @@ - [ 1520 ] os.listdir doesn't return unicode when requested - [ 1483 ] optparse std module dies on non-ASCII unicode data - [ 1390 ] ihooks fails due to unimplemented methods in imp module + - [ 1456 ] sys.trace/profile attributes cause: AttributeError: write-only attr: trace in PyAMF - 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/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2010-04-11 19:49:26 UTC (rev 7019) +++ trunk/jython/src/org/python/core/PySystemState.java 2010-04-11 22:21:31 UTC (rev 7020) @@ -34,8 +34,7 @@ */ // xxx Many have lamented, this should really be a module! // but it will require some refactoring to see this wish come true. -public class PySystemState extends PyObject -{ +public class PySystemState extends PyObject implements ClassDictInit { public static final String PYTHON_CACHEDIR = "python.cachedir"; public static final String PYTHON_CACHEDIR_SKIP = "python.cachedir.skip"; public static final String PYTHON_CONSOLE_ENCODING = "python.console.encoding"; @@ -191,6 +190,12 @@ __dict__.__setitem__("excepthook", __excepthook__); } + public static void classDictInit(PyObject dict) { + // XXX: Remove bean accessors for settrace/profile that we don't want + dict.__setitem__("trace", null); + dict.__setitem__("profile", null); + } + void reload() throws PyIgnoreMethodTag { __dict__.invoke("update", getType().fastGetDict()); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-12 22:03:23
|
Revision: 7022 http://jython.svn.sourceforge.net/jython/?rev=7022&view=rev Author: amak Date: 2010-04-12 22:03:17 +0000 (Mon, 12 Apr 2010) Log Message: ----------- Fixing a bug with translation of line endings when that should not be happening. Fixes http://bugs.jython.org/issue1549 Thanks to Jacob Fenwick for the (jfenwick) for the patch. Modified Paths: -------------- trunk/jython/Lib/modjy/modjy_wsgi.py trunk/jython/src/org/python/core/PyFile.java trunk/jython/src/org/python/core/util/FileUtil.java trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java Added Paths: ----------- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestPostData.java trunk/jython/tests/modjy/test_apps_dir/post_data_tests.py Modified: trunk/jython/Lib/modjy/modjy_wsgi.py =================================================================== --- trunk/jython/Lib/modjy/modjy_wsgi.py 2010-04-12 16:47:34 UTC (rev 7021) +++ trunk/jython/Lib/modjy/modjy_wsgi.py 2010-04-12 22:03:17 UTC (rev 7022) @@ -125,7 +125,7 @@ def set_wsgi_streams(self, req, resp, dict): try: - dict["wsgi.input"] = create_py_file(req.getInputStream()) + dict["wsgi.input"] = create_py_file(req.getInputStream(), "rb") dict["wsgi.errors"] = create_py_file(System.err) except IOException, iox: raise ModjyIOException(iox) Modified: trunk/jython/src/org/python/core/PyFile.java =================================================================== --- trunk/jython/src/org/python/core/PyFile.java 2010-04-12 16:47:34 UTC (rev 7021) +++ trunk/jython/src/org/python/core/PyFile.java 2010-04-12 22:03:17 UTC (rev 7022) @@ -96,7 +96,7 @@ file___init__(raw, name, mode, bufsize); } - PyFile(InputStream istream, String name, String mode, int bufsize, boolean closefd) { + public PyFile(InputStream istream, String name, String mode, int bufsize, boolean closefd) { parseMode(mode); file___init__(new StreamIO(istream, closefd), name, mode, bufsize); } Modified: trunk/jython/src/org/python/core/util/FileUtil.java =================================================================== --- trunk/jython/src/org/python/core/util/FileUtil.java 2010-04-12 16:47:34 UTC (rev 7021) +++ trunk/jython/src/org/python/core/util/FileUtil.java 2010-04-12 22:03:17 UTC (rev 7022) @@ -14,6 +14,13 @@ public class FileUtil { /** + * Creates a PyFile that reads from the given <code>InputStream</code> with mode. + */ + public static PyFile wrap(InputStream is, String mode) { + return new PyFile(is, "<Java InputStream '" + is + "' as file>", mode, -1, true); + } + + /** * Creates a PyFile that reads from the given <code>InputStream</code> with bufsize. */ public static PyFile wrap(InputStream is, int bufsize) { Modified: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2010-04-12 16:47:34 UTC (rev 7021) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestBase.java 2010-04-12 22:03:17 UTC (rev 7022) @@ -95,6 +95,12 @@ getFactory().addRequestWrapper(request); } + public void setMethod(String method) { + MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); + request.setMethod(method); + getFactory().addRequestWrapper(request); + } + public void setBodyContent(String content) { MockHttpServletRequest request = (MockHttpServletRequest)getFactory().getWrappedRequest(); request.setBodyContent(content); @@ -244,6 +250,7 @@ suite.addTestSuite(ModjyTestInterpreterLifecycle.class); suite.addTestSuite(ModjyTestWebInf.class); suite.addTestSuite(ModjyTestWSGIStreams.class); + suite.addTestSuite(ModjyTestPostData.class); suite.addTestSuite(PyServletTest.class); suite.addTestSuite(PyFilterTest.class); junit.textui.TestRunner.run(suite); Added: trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestPostData.java =================================================================== --- trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestPostData.java (rev 0) +++ trunk/jython/tests/modjy/java/com/xhaus/modjy/ModjyTestPostData.java 2010-04-12 22:03:17 UTC (rev 7022) @@ -0,0 +1,47 @@ +/*### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +###*/ + +package com.xhaus.modjy; + +public class ModjyTestPostData extends ModjyTestBase { + + protected void postDataTestSetUp() throws Exception { + baseSetUp(); + setAppFile("post_data_tests.py"); + } + + public void doHeaderTest(String appName, String postData) throws Exception { + postDataTestSetUp(); + setMethod("POST"); + setAppName(appName); + createServlet(); + if (postData != null) + setBodyContent(postData); + doPost(); + } + + public void testPostDataLineEndsNotTranslated() throws Exception { + String testData = "this\r\ndata\r\ncontains\r\ncarriage\r\nreturns\r\n"; + String expectedData = "'"+testData.replace("\r", "\\r").replace("\n", "\\n")+"'"; + doHeaderTest("test_return_post_data", testData); + assertEquals("Wrong post data returned >>" + getOutput() + "<< != >>"+expectedData+"<<", expectedData, getOutput()); + } + +} Added: trunk/jython/tests/modjy/test_apps_dir/post_data_tests.py =================================================================== --- trunk/jython/tests/modjy/test_apps_dir/post_data_tests.py (rev 0) +++ trunk/jython/tests/modjy/test_apps_dir/post_data_tests.py 2010-04-12 22:03:17 UTC (rev 7022) @@ -0,0 +1,31 @@ +# -*- coding: windows-1252 -*- + +### +# +# Copyright Alan Kennedy. +# +# You may contact the copyright holder at this uri: +# +# http://www.xhaus.com/contact/modjy +# +# The licence under which this code is released is the Apache License v2.0. +# +# The terms and conditions of this license are listed in a file contained +# in the distribution that also contained this file, under the name +# LICENSE.txt. +# +# You may also read a copy of the license at the following web address. +# +# http://modjy.xhaus.com/LICENSE.txt +# +### + +""" + App callables used to test post data +""" + +def test_return_post_data(environ, start_response): + post_data = environ['wsgi.input'].read() + return_value = repr(post_data) + start_response("200 OK", [('content-length', '%s' % len(return_value))]) + return [return_value] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-13 02:16:20
|
Revision: 7024 http://jython.svn.sourceforge.net/jython/?rev=7024&view=rev Author: pjenvey Date: 2010-04-13 02:16:14 +0000 (Tue, 13 Apr 2010) Log Message: ----------- fix throw on a just started generator not fully stopping it fixes #1385 Modified Paths: -------------- trunk/jython/Lib/test/test_generators_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyGenerator.java Modified: trunk/jython/Lib/test/test_generators_jy.py =================================================================== --- trunk/jython/Lib/test/test_generators_jy.py 2010-04-13 00:35:47 UTC (rev 7023) +++ trunk/jython/Lib/test/test_generators_jy.py 2010-04-13 02:16:14 UTC (rev 7024) @@ -1,7 +1,7 @@ from __future__ import generators import unittest -#tests for deeply nested try/except/finally's +# tests for deeply nested try/except/finally's class FinallyTests(unittest.TestCase): def gen1(self): @@ -160,5 +160,13 @@ def testExcept(self): self.assertEquals([1, 1, 1], list(self.genNestedExcept())) +class TestThrowTestCase(unittest.TestCase): + + def test_just_started_throw(self): + genexp = (i for i in range(2)) + self.assertRaises(IOError, genexp.throw, IOError) + self.assertEqual(genexp.gi_frame, None) + self.assertRaises(StopIteration, genexp.next) + if __name__ == "__main__": unittest.main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-13 00:35:47 UTC (rev 7023) +++ trunk/jython/NEWS 2010-04-13 02:16:14 UTC (rev 7024) @@ -31,6 +31,7 @@ - [ 1483 ] optparse std module dies on non-ASCII unicode data - [ 1390 ] ihooks fails due to unimplemented methods in imp module - [ 1456 ] sys.trace/profile attributes cause: AttributeError: write-only attr: trace in PyAMF + - [ 1385 ] generator.throw uncaught on new generator doesn't stop the generator - 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/PyGenerator.java =================================================================== --- trunk/jython/src/org/python/core/PyGenerator.java 2010-04-13 00:35:47 UTC (rev 7023) +++ trunk/jython/src/org/python/core/PyGenerator.java 2010-04-13 02:16:14 UTC (rev 7024) @@ -93,6 +93,7 @@ private PyObject raiseException(PyException ex) { if (gi_frame == null || gi_frame.f_lasti == 0) { + gi_frame = null; throw ex; } gi_frame.setGeneratorInput(ex); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-14 02:40:01
|
Revision: 7026 http://jython.svn.sourceforge.net/jython/?rev=7026&view=rev Author: pjenvey Date: 2010-04-14 02:39:55 +0000 (Wed, 14 Apr 2010) Log Message: ----------- make the SynchronizedCallable callable fixes #1596 Modified Paths: -------------- trunk/jython/Lib/test/test_thread_jy.py trunk/jython/NEWS trunk/jython/src/org/python/modules/synchronize.java Modified: trunk/jython/Lib/test/test_thread_jy.py =================================================================== --- trunk/jython/Lib/test/test_thread_jy.py 2010-04-14 01:59:14 UTC (rev 7025) +++ trunk/jython/Lib/test/test_thread_jy.py 2010-04-14 02:39:55 UTC (rev 7026) @@ -8,12 +8,13 @@ class AllocateLockTest(unittest.TestCase): def test_lock_type(self): - "thread.LockType should exist" + """thread.LockType should exist""" t = thread.LockType self.assertEquals(t, type(thread.allocate_lock()), "thread.LockType has wrong value") class SynchronizeTest(unittest.TestCase): + def test_make_synchronized(self): doneSignal = CountDownLatch(10) class SynchedRunnable(Runnable): @@ -28,7 +29,10 @@ doneSignal.await() self.assertEquals(10, runner.i) + def test_synchronized_callable(self): + self.assertTrue(callable(synchronize.make_synchronized(lambda: None))) + def test_main(): test.test_support.run_unittest(AllocateLockTest, SynchronizeTest) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-14 01:59:14 UTC (rev 7025) +++ trunk/jython/NEWS 2010-04-14 02:39:55 UTC (rev 7026) @@ -32,6 +32,7 @@ - [ 1390 ] ihooks fails due to unimplemented methods in imp module - [ 1456 ] sys.trace/profile attributes cause: AttributeError: write-only attr: trace in PyAMF - [ 1385 ] generator.throw uncaught on new generator doesn't stop the generator + - [ 1596 ] SynchronizedCallable does not report that it is callable [suggested fix] - 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/modules/synchronize.java =================================================================== --- trunk/jython/src/org/python/modules/synchronize.java 2010-04-14 01:59:14 UTC (rev 7025) +++ trunk/jython/src/org/python/modules/synchronize.java 2010-04-14 02:39:55 UTC (rev 7026) @@ -89,5 +89,10 @@ return callable.__call__(arg1, args, keywords); } } + + @Override + public boolean isCallable() { + return true; + } } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-18 00:59:08
|
Revision: 7034 http://jython.svn.sourceforge.net/jython/?rev=7034&view=rev Author: pjenvey Date: 2010-04-18 00:59:01 +0000 (Sun, 18 Apr 2010) Log Message: ----------- update to jffi-1.0.1/jaffl-0.5.1/jnr-posix-1.1.4-79b6c76/constantine-0.7 Modified Paths: -------------- trunk/jython/build.xml trunk/jython/extlibs/constantine.jar 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-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-SunOS.jar trunk/jython/extlibs/jffi.jar trunk/jython/extlibs/jnr-posix.jar trunk/jython/src/org/python/modules/posix/PosixModule.java trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java Added Paths: ----------- trunk/jython/extlibs/jffi-ppc-Linux.jar trunk/jython/extlibs/jffi-ppc64-Linux.jar trunk/jython/extlibs/jffi-x86_64-Windows.jar Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2010-04-17 19:35:37 UTC (rev 7033) +++ trunk/jython/build.xml 2010-04-18 00:59:01 UTC (rev 7034) @@ -196,6 +196,8 @@ <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-ppc-Linux.jar"/> + <pathelement path="${extlibs.dir}/jffi-ppc64-Linux.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"/> @@ -203,6 +205,7 @@ <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-x86_64-Windows.jar"/> <pathelement path="${extlibs.dir}/jffi.jar"/> <pathelement path="${extlibs.dir}/jnr-posix.jar"/> <pathelement path="${extlibs.dir}/jnr-netdb-0.4.jar"/> @@ -589,6 +592,8 @@ <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-ppc-Linux.jar"/> + <zipfileset src="extlibs/jffi-ppc64-Linux.jar"/> <zipfileset src="extlibs/jffi-s390x-Linux.jar"/> <zipfileset src="extlibs/jffi-sparc-SunOS.jar"/> <zipfileset src="extlibs/jffi-sparcv9-SunOS.jar"/> @@ -596,6 +601,7 @@ <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-x86_64-Windows.jar"/> <zipfileset src="extlibs/jffi.jar"/> <zipfileset src="extlibs/jnr-posix.jar"/> <zipfileset src="extlibs/jnr-netdb-0.4.jar"/> Modified: trunk/jython/extlibs/constantine.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jaffl.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-Darwin.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-i386-FreeBSD.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-i386-Linux.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-i386-SunOS.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-i386-Windows.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-ppc-AIX.jar =================================================================== (Binary files differ) Added: trunk/jython/extlibs/jffi-ppc-Linux.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-ppc-Linux.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Added: trunk/jython/extlibs/jffi-ppc64-Linux.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-ppc64-Linux.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/jython/extlibs/jffi-s390x-Linux.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-sparc-SunOS.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-sparcv9-SunOS.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-x86_64-FreeBSD.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-x86_64-Linux.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jffi-x86_64-SunOS.jar =================================================================== (Binary files differ) Added: trunk/jython/extlibs/jffi-x86_64-Windows.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jffi-x86_64-Windows.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/jython/extlibs/jffi.jar =================================================================== (Binary files differ) Modified: trunk/jython/extlibs/jnr-posix.jar =================================================================== (Binary files differ) Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-17 19:35:37 UTC (rev 7033) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-04-18 00:59:01 UTC (rev 7034) @@ -18,7 +18,6 @@ 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; @@ -104,7 +103,7 @@ // Successful termination dict.__setitem__("EX_OK", Py.Zero); - boolean nativePosix = !(posix instanceof JavaPOSIX); + boolean nativePosix = posix.isNative(); dict.__setitem__("_native_posix", Py.newBoolean(nativePosix)); dict.__setitem__("_posix_impl", Py.java2py(posix)); dict.__setitem__("environ", getEnviron()); Modified: trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java 2010-04-17 19:35:37 UTC (rev 7033) +++ trunk/jython/src/org/python/modules/posix/PythonPOSIXHandler.java 2010-04-18 00:59:01 UTC (rev 7034) @@ -1,8 +1,7 @@ /* Copyright (c) Jython Developers */ package org.python.modules.posix; -import com.kenai.constantine.Constant; -import com.kenai.constantine.ConstantSet; +import com.kenai.constantine.platform.Errno; import java.io.File; import java.io.InputStream; @@ -21,14 +20,8 @@ */ public class PythonPOSIXHandler implements POSIXHandler { - private ConstantSet errnos = ConstantSet.getConstantSet("Errno"); - - public void error(POSIX.ERRORS error, String extraData) { - Constant errno = errnos.getConstant(error.name()); - if (errno == null) { - throw Py.OSError(extraData); - } - throw Py.OSError(errno, extraData); + public void error(Errno error, String extraData) { + throw Py.OSError(error, extraData); } public void unimplementedError(String methodName) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-18 05:46:31
|
Revision: 7035 http://jython.svn.sourceforge.net/jython/?rev=7035&view=rev Author: pjenvey Date: 2010-04-18 05:46:24 +0000 (Sun, 18 Apr 2010) Log Message: ----------- constantine now has accurate Windows errnos so we actually have to map the missing errnos to the WSA equivalents like CPython does. and update to constantine-0.8-2355d07 for more WSA errnos Modified Paths: -------------- trunk/jython/extlibs/constantine.jar trunk/jython/src/org/python/modules/errno.java Modified: trunk/jython/extlibs/constantine.jar =================================================================== (Binary files differ) Modified: trunk/jython/src/org/python/modules/errno.java =================================================================== --- trunk/jython/src/org/python/modules/errno.java 2010-04-18 00:59:01 UTC (rev 7034) +++ trunk/jython/src/org/python/modules/errno.java 2010-04-18 05:46:24 UTC (rev 7035) @@ -3,6 +3,8 @@ import com.kenai.constantine.Constant; import com.kenai.constantine.ConstantSet; +import com.kenai.constantine.Platform; +import com.kenai.constantine.platform.Errno; import org.python.core.ClassDictInit; import org.python.core.Py; import org.python.core.PyDictionary; @@ -32,9 +34,12 @@ public static final PyObject errorcode = new PyDictionary(); public static void classDictInit(PyObject dict) { - for (Constant constant : ConstantSet.getConstantSet("Errno")) { - addCode(dict, constant.name(), constant.value(), constant.toString()); + if (Platform.OS.equals("windows")) { + initWindows(dict); + } else { + initPosix(dict); } + // XXX: necessary? addCode(dict, "ESOCKISBLOCKING", 20000, "Socket is in blocking mode"); addCode(dict, "EGETADDRINFOFAILED", 20001, "getaddrinfo failed"); @@ -43,6 +48,44 @@ dict.__setitem__("classDictInit", null); } + /** + * Setup errnos for Windows. + * + * Windows replaced the BSD/POSIX socket errnos with its own Winsock equivalents + * (e.g. EINVAL -> WSAEINVAL). We painstakenly map the missing constants to their WSA + * equivalent values and expose the WSA constants on their own. + */ + private static void initWindows(PyObject dict) { + // the few POSIX errnos Windows defines + ConstantSet winErrnos = ConstantSet.getConstantSet("Errno"); + // WSA errnos (and other Windows LastErrors) + ConstantSet lastErrors = ConstantSet.getConstantSet("LastError"); + + // Fill the gaps by searching through every possible constantine Errno first + // checking if it's defined on Windows, then falling back to the WSA prefixed + // version if it exists + Constant constant; + for (Constant errno : Errno.values()) { + String errnoName = errno.name(); + if ((constant = winErrnos.getConstant(errnoName)) != null + || (constant = lastErrors.getConstant("WSA" + errnoName)) != null) { + addCode(dict, errnoName, constant.value(), constant.toString()); + } + } + // Then provide the WSA names + for (Constant lastError : lastErrors) { + if (lastError.name().startsWith("WSA")) { + addCode(dict, lastError.name(), lastError.value(), lastError.toString()); + } + } + } + + private static void initPosix(PyObject dict) { + for (Constant constant : ConstantSet.getConstantSet("Errno")) { + addCode(dict, constant.name(), constant.value(), constant.toString()); + } + } + private static void addCode(PyObject dict, String name, int code, String message) { PyObject nameObj = Py.newString(name); PyObject codeObj = Py.newInteger(code); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2010-04-18 09:52:19
|
Revision: 7036 http://jython.svn.sourceforge.net/jython/?rev=7036&view=rev Author: otmarhumbel Date: 2010-04-18 09:52:12 +0000 (Sun, 18 Apr 2010) Log Message: ----------- enable jython.bat in the 4nt (Take Command) shell fixes bug #1557 many thanks to stuaxo for the patch Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/shell/jython.bat Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-18 05:46:24 UTC (rev 7035) +++ trunk/jython/NEWS 2010-04-18 09:52:12 UTC (rev 7036) @@ -33,6 +33,7 @@ - [ 1456 ] sys.trace/profile attributes cause: AttributeError: write-only attr: trace in PyAMF - [ 1385 ] generator.throw uncaught on new generator doesn't stop the generator - [ 1596 ] SynchronizedCallable does not report that it is callable [suggested fix] + - [ 1557 ] jython.bat doesn't work in 4nt - 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/shell/jython.bat =================================================================== --- trunk/jython/src/shell/jython.bat 2010-04-18 05:46:24 UTC (rev 7035) +++ trunk/jython/src/shell/jython.bat 2010-04-18 09:52:12 UTC (rev 7036) @@ -12,6 +12,12 @@ rem rem --------------------------------------------------------------------------- +rem If running in Take Command (4NT), force to run in cmd.exe +if not "%@eval[2+2]" == "4" goto normalstart +cmd /C %0 %* +goto finish + +:normalstart setlocal enabledelayedexpansion rem ----- Verify and set required environment variables ----------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2010-04-25 17:46:40
|
Revision: 7045 http://jython.svn.sourceforge.net/jython/?rev=7045&view=rev Author: zyasoft Date: 2010-04-25 17:46:34 +0000 (Sun, 25 Apr 2010) Log Message: ----------- Added support for __copy__, __deepcopy__ of Java objects (fixes #1551); and (somewhat) related serialization of PyCode objects (fixes #1601); some unit testing; bumped bytecode magic Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/src/org/python/core/CompilerFlags.java trunk/jython/src/org/python/core/PyFunctionTable.java trunk/jython/src/org/python/core/PyJavaType.java trunk/jython/src/org/python/core/imp.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2010-04-24 17:30:40 UTC (rev 7044) +++ trunk/jython/Lib/test/test_java_integration.py 2010-04-25 17:46:34 UTC (rev 7045) @@ -1,3 +1,4 @@ +import copy import operator import os import unittest @@ -5,6 +6,7 @@ import sys import re +from collections import deque from test import test_support from java.lang import (ClassCastException, ExceptionInInitializerError, String, Runnable, System, @@ -469,19 +471,78 @@ self.assertRaises(TypeError, __import__, "org.python.tests.mro.ConfusedOnImport") self.assertRaises(TypeError, GetitemAdder.addPostdefined) + +def roundtrip_serialization(obj): + """Returns a deep copy of an object, via serializing it + + see http://weblogs.java.net/blog/emcmanus/archive/2007/04/cloning_java_ob.html + """ + output = ByteArrayOutputStream() + serializer = CloneOutput(output) + serializer.writeObject(obj) + serializer.close() + input = ByteArrayInputStream(output.toByteArray()) + unserializer = CloneInput(input, serializer) # to get the list of classes seen, in order + return unserializer.readObject() + +class CloneOutput(ObjectOutputStream): + def __init__(self, output): + ObjectOutputStream.__init__(self, output) + self.classQueue = deque() + + def annotateClass(self, c): + self.classQueue.append(c) + + def annotateProxyClass(self, c): + self.classQueue.append(c) + +class CloneInput(ObjectInputStream): + + def __init__(self, input, output): + ObjectInputStream.__init__(self, input); + self.output = output; + + def resolveClass(self, obj_stream_class): + c = self.output.classQueue.popleft() + return c + + def resolveProxyClass(self, interfaceNames): + return self.output.classQueue.popleft() + + class SerializationTest(unittest.TestCase): def test_java_serialization(self): date_list = [Date(), Date()] - output = ByteArrayOutputStream() - serializer = ObjectOutputStream(output) - serializer.writeObject(date_list) - serializer.close() + self.assertEqual(date_list, roundtrip_serialization(date_list)) - input = ByteArrayInputStream(output.toByteArray()) - unserializer = ObjectInputStream(input) - self.assertEqual(date_list, unserializer.readObject()) + def test_java_serialization_pycode(self): + def universal_answer(): + return 42 + + serialized_code = roundtrip_serialization(universal_answer.func_code) + self.assertEqual(eval(serialized_code), universal_answer()) + + +class CopyTest(unittest.TestCase): + + def test_copy(self): + fruits = ArrayList(["apple", "banana"]) + fruits_copy = copy.copy(fruits) + self.assertEqual(fruits, fruits_copy) + self.assertNotEqual(id(fruits), id(fruits_copy)) + + def test_deepcopy(self): + items = ArrayList([ArrayList(["apple", "banana"]), + ArrayList(["trs80", "vic20"])]) + items_copy = copy.deepcopy(items) + self.assertEqual(items, items_copy) + self.assertNotEqual(id(items), id(items_copy)) + self.assertNotEqual(id(items[0]), id(items_copy[0])) + self.assertNotEqual(id(items[1]), id(items_copy[1])) + + class UnicodeTest(unittest.TestCase): def test_unicode_conversion(self): @@ -505,6 +566,7 @@ SecurityManagerTest, JavaWrapperCustomizationTest, SerializationTest, + CopyTest, UnicodeTest) if __name__ == "__main__": Modified: trunk/jython/src/org/python/core/CompilerFlags.java =================================================================== --- trunk/jython/src/org/python/core/CompilerFlags.java 2010-04-24 17:30:40 UTC (rev 7044) +++ trunk/jython/src/org/python/core/CompilerFlags.java 2010-04-25 17:46:34 UTC (rev 7045) @@ -6,11 +6,12 @@ package org.python.core; +import java.io.Serializable; import java.util.Set; import org.python.Version; -public class CompilerFlags { +public class CompilerFlags implements Serializable { // These flags don't mean anything to the code, only to the compiler public static final int PyCF_SOURCE_IS_UTF8 = 0x0100; public static final int PyCF_DONT_IMPLY_DEDENT = 0x0200; Modified: trunk/jython/src/org/python/core/PyFunctionTable.java =================================================================== --- trunk/jython/src/org/python/core/PyFunctionTable.java 2010-04-24 17:30:40 UTC (rev 7044) +++ trunk/jython/src/org/python/core/PyFunctionTable.java 2010-04-25 17:46:34 UTC (rev 7045) @@ -1,6 +1,8 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; +import java.io.Serializable; + /** * An entry point for class that implements several function calls. * <P> @@ -9,6 +11,6 @@ * @see PyTableCode */ -public abstract class PyFunctionTable { +public abstract class PyFunctionTable implements Serializable { abstract public PyObject call_function(int index, PyFrame frame, ThreadState ts); } Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2010-04-24 17:30:40 UTC (rev 7044) +++ trunk/jython/src/org/python/core/PyJavaType.java 2010-04-25 17:46:34 UTC (rev 7045) @@ -1,5 +1,15 @@ package org.python.core; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InvalidClassException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; +import java.io.OutputStream; +import java.io.Serializable; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Member; @@ -10,9 +20,11 @@ import java.util.Enumeration; import java.util.EventListener; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Queue; import org.python.core.util.StringUtil; import org.python.util.Generic; @@ -578,8 +590,113 @@ } }); } + + // TODO consider adding support for __copy__ of immutable Java objects + // (__deepcopy__ should just work since it uses serialization) + + if(forClass == Cloneable.class) { + addMethod(new PyBuiltinMethodNarrow("__copy__") { + @Override + public PyObject __call__() { + Object obj = self.getJavaProxy(); + Method clone; + // we could specialize so that for well known objects like collections, + // we don't use reflection to get around the fact that Object#clone is protected (but most subclasses are not); + // also we can potentially cache the method handle in the proxy instead of looking it up each time + try { + clone = obj.getClass().getMethod("clone"); + Object copy; + copy = clone.invoke(obj); + return Py.java2py(copy); + } catch (Exception ex) { + throw Py.TypeError("Could not copy Java object"); + } + } + }); + } + + if(forClass == Serializable.class) { + addMethod(new PyBuiltinMethodNarrow("__deepcopy__") { + @Override + public PyObject __call__(PyObject memo) { + Object obj = self.getJavaProxy(); + try { + Object copy = cloneX(obj); + return Py.java2py(copy); + } catch (Exception ex) { + throw Py.TypeError("Could not copy Java object"); + } + } + }); + + } } + // cloneX, CloneOutput, CloneInput are verbatim from Eamonn McManus' + // http://weblogs.java.net/blog/emcmanus/archive/2007/04/cloning_java_ob.html + // blog post on deep cloning through serialization - + // just what we need for __deepcopy__ support of Java objects + + private static <T> T cloneX(T x) throws IOException, ClassNotFoundException { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + CloneOutput cout = new CloneOutput(bout); + cout.writeObject(x); + byte[] bytes = bout.toByteArray(); + + ByteArrayInputStream bin = new ByteArrayInputStream(bytes); + CloneInput cin = new CloneInput(bin, cout); + + @SuppressWarnings("unchecked") // thanks to Bas de Bakker for the tip! + T clone = (T) cin.readObject(); + return clone; + } + + private static class CloneOutput extends ObjectOutputStream { + Queue<Class<?>> classQueue = new LinkedList<Class<?>>(); + + CloneOutput(OutputStream out) throws IOException { + super(out); + } + + @Override + protected void annotateClass(Class<?> c) { + classQueue.add(c); + } + + @Override + protected void annotateProxyClass(Class<?> c) { + classQueue.add(c); + } + } + + private static class CloneInput extends ObjectInputStream { + private final CloneOutput output; + + CloneInput(InputStream in, CloneOutput output) throws IOException { + super(in); + this.output = output; + } + + @Override + protected Class<?> resolveClass(ObjectStreamClass osc) + throws IOException, ClassNotFoundException { + Class<?> c = output.classQueue.poll(); + String expected = osc.getName(); + String found = (c == null) ? null : c.getName(); + if (!expected.equals(found)) { + throw new InvalidClassException("Classes desynchronized: " + + "found " + found + " when expecting " + expected); + } + return c; + } + + @Override + protected Class<?> resolveProxyClass(String[] interfaceNames) + throws IOException, ClassNotFoundException { + return output.classQueue.poll(); + } + } + /** * Private, protected or package protected classes that implement public interfaces or extend * public classes can't have their implementations of the methods of their supertypes called Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2010-04-24 17:30:40 UTC (rev 7044) +++ trunk/jython/src/org/python/core/imp.java 2010-04-25 17:46:34 UTC (rev 7045) @@ -21,7 +21,7 @@ private static final String UNKNOWN_SOURCEFILE = "<unknown>"; - private static final int APIVersion = 27; + private static final int APIVersion = 28; public static final int NO_MTIME = -1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2010-04-26 14:27:44
|
Revision: 7047 http://jython.svn.sourceforge.net/jython/?rev=7047&view=rev Author: zyasoft Date: 2010-04-26 14:27:38 +0000 (Mon, 26 Apr 2010) Log Message: ----------- Fixed weakref leak in calling functions with kwargs by nulling out after call (in compiler). Fixes #1586. Bumped bytecode magic Modified Paths: -------------- trunk/jython/Lib/test/test_weakref_jy.py trunk/jython/src/org/python/compiler/CodeCompiler.java trunk/jython/src/org/python/core/imp.java trunk/jython/src/org/python/modules/thread/PyLocal.java Modified: trunk/jython/Lib/test/test_weakref_jy.py =================================================================== --- trunk/jython/Lib/test/test_weakref_jy.py 2010-04-25 18:33:34 UTC (rev 7046) +++ trunk/jython/Lib/test/test_weakref_jy.py 2010-04-26 14:27:38 UTC (rev 7047) @@ -5,6 +5,7 @@ import unittest import weakref from test import test_support +from test_weakref import extra_collect class ReferencesTestCase(unittest.TestCase): @@ -38,8 +39,45 @@ self.assertEqual(len(hash_called), 2) +class ArgsTestCase(unittest.TestCase): + + # XXX consider adding other tests for dict, list, etc + + def test_python_fn_kwargs(self): + + weakrefs = [] + sentinel = [] + + def watch(obj, kwarg=True): + self.assertEqual(kwarg, True) + # log the death of the reference by appending to the sentinel + ref = weakref.ref(obj, sentinel.append) + weakrefs.append(ref) + + self.assert_(not sentinel) + + thunk1 = lambda: None + watch(thunk1) + self.assert_(not sentinel) + + del thunk1 + extra_collect() + self.assert_(sentinel) + + del sentinel[:] + + thunk2 = lambda: None + watch(thunk2, kwarg=True) # <--- only difference: called with a kwarg + self.assert_(not sentinel) + + del thunk2 + extra_collect() + self.assert_(sentinel) + + + def test_main(): - test_support.run_unittest(ReferencesTestCase) + test_support.run_unittest(ReferencesTestCase, ArgsTestCase) if __name__ == '__main__': Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2010-04-25 18:33:34 UTC (rev 7046) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2010-04-26 14:27:38 UTC (rev 7047) @@ -1804,15 +1804,14 @@ code.aload(argArray); code.aload(strArray); - code.freeLocal(argArray); code.freeLocal(strArray); code.dup2_x2(); code.pop2(); stackConsume(3); // target + starargs + kwargs - code.invokevirtual(p(PyObject.class), "_callextra", sig(PyObject.class, PyObject[].class, String[].class, PyObject.class, PyObject.class)); + freeArray(argArray); } else if (keys.size() > 0) { loadThreadState(); stackProduce(p(ThreadState.class)); @@ -1820,11 +1819,11 @@ int strArray = makeStrings(code, keys); code.aload(argArray); code.aload(strArray); - code.freeLocal(argArray); code.freeLocal(strArray); stackConsume(2); // target + ts code.invokevirtual(p(PyObject.class), "__call__", sig(PyObject.class, ThreadState.class, PyObject[].class, String[].class)); + freeArray(argArray); } else { loadThreadState(); stackProduce(p(ThreadState.class)); Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2010-04-25 18:33:34 UTC (rev 7046) +++ trunk/jython/src/org/python/core/imp.java 2010-04-26 14:27:38 UTC (rev 7047) @@ -21,7 +21,7 @@ private static final String UNKNOWN_SOURCEFILE = "<unknown>"; - private static final int APIVersion = 28; + private static final int APIVersion = 29; public static final int NO_MTIME = -1; Modified: trunk/jython/src/org/python/modules/thread/PyLocal.java =================================================================== --- trunk/jython/src/org/python/modules/thread/PyLocal.java 2010-04-25 18:33:34 UTC (rev 7046) +++ trunk/jython/src/org/python/modules/thread/PyLocal.java 2010-04-26 14:27:38 UTC (rev 7047) @@ -59,7 +59,9 @@ if (where[0] == TYPE && args.length > 0) { throw Py.TypeError("Initialization arguments are not supported"); } - this.args = args; + // caller zeros out `args` + this.args = new PyObject[args.length]; + System.arraycopy(args, 0, this.args, 0, args.length); this.keywords = keywords; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: Philip J. <pj...@un...> - 2010-04-27 03:47:14
|
On Apr 26, 2010, at 7:27 AM, zy...@us... wrote: > Revision: 7047 > http://jython.svn.sourceforge.net/jython/?rev=7047&view=rev > Author: zyasoft > Date: 2010-04-26 14:27:38 +0000 (Mon, 26 Apr 2010) > > Log Message: > ----------- > Fixed weakref leak in calling functions with kwargs by nulling out after call (in compiler). Fixes #1586. Bumped bytecode magic > > Modified Paths: > -------------- > trunk/jython/Lib/test/test_weakref_jy.py > trunk/jython/src/org/python/compiler/CodeCompiler.java > trunk/jython/src/org/python/core/imp.java > trunk/jython/src/org/python/modules/thread/PyLocal.java > > Modified: trunk/jython/src/org/python/modules/thread/PyLocal.java > =================================================================== > --- trunk/jython/src/org/python/modules/thread/PyLocal.java 2010-04-25 18:33:34 UTC (rev 7046) > +++ trunk/jython/src/org/python/modules/thread/PyLocal.java 2010-04-26 14:27:38 UTC (rev 7047) > @@ -59,7 +59,9 @@ > if (where[0] == TYPE && args.length > 0) { > throw Py.TypeError("Initialization arguments are not supported"); > } > - this.args = args; > + // caller zeros out `args` > + this.args = new PyObject[args.length]; > + System.arraycopy(args, 0, this.args, 0, args.length); > this.keywords = keywords; > } This this can affect any class that saves args for later, like _functools.partial (and I think there's others), right? Can we have the compiler just null its reference to the array instead of zero'ing it, and avoid the need for copying? -- Philip Jenvey |
From: <otm...@us...> - 2010-04-28 23:16:33
|
Revision: 7052 http://jython.svn.sourceforge.net/jython/?rev=7052&view=rev Author: otmarhumbel Date: 2010-04-28 23:16:27 +0000 (Wed, 28 Apr 2010) Log Message: ----------- add test cases for most of the use cases of jython.bat Modified Paths: -------------- trunk/jython/src/shell/jython.bat Added Paths: ----------- trunk/jython/Lib/test/test_bat_jy.py Added: trunk/jython/Lib/test/test_bat_jy.py =================================================================== --- trunk/jython/Lib/test/test_bat_jy.py (rev 0) +++ trunk/jython/Lib/test/test_bat_jy.py 2010-04-28 23:16:27 UTC (rev 7052) @@ -0,0 +1,333 @@ +'''Tests jython.bat using the --print option''' + +import os +import sys +import unittest +import tempfile + +from test import test_support +from subprocess import Popen, PIPE + +from java.lang import IllegalThreadStateException +from java.lang import Runtime +from java.lang import Thread +from java.io import File +from java.io import BufferedReader; +from java.io import InputStreamReader; + +class Monitor(Thread): + def __init__(self, process): + self.process = process + self.output = '' + + def run(self): + reader = BufferedReader(InputStreamReader(self.getStream())) + try: + line = reader.readLine() + while line: + self.output += line + line = reader.readLine() + finally: + reader.close() + + def getOutput(self): + return self.output + +class StdoutMonitor(Monitor): + def __init_(self, process): + Monitor.__init__(self, process) + + def getStream(self): + return self.process.getInputStream() + +class StderrMonitor(Monitor): + def __init_(self, process): + Monitor.__init__(self, process) + + def getStream(self): + return self.process.getErrorStream() + +class SimpleSubprocess: + def __init__(self, args): + self.args = args + self.exitValue = -999 + + def run(self): + self.process = Runtime.getRuntime().exec(self.args) + self.stdoutMonitor = StdoutMonitor(self.process) + self.stderrMonitor = StderrMonitor(self.process) + self.stdoutMonitor.start() + self.stderrMonitor.start() + while self.isAlive(): + Thread.sleep(1000) + return self.exitValue + + def getStdout(self): + return self.stdoutMonitor.getOutput() + + def getStderr(self): + return self.stderrMonitor.getOutput() + + def isAlive(self): + try: + self.exitValue = self.process.exitValue() + return False + except IllegalThreadStateException: + return True + +class BaseTest(unittest.TestCase): + def quote(self, s): + return '"' + s + '"' + + def unquote(self, s): + if len(s) > 0: + if s[:1] == '"': + s = s[1:] + if len(s) > 0: + if s[-1:] == '"': + s = s[:-1] + return s + + def getHomeDir(self): + ex = sys.executable + tail = ex[-15:] + if tail == '\\bin\\jython.bat': + home = ex[:-15] + else: + home = ex[:-11] # \jython.bat + return home + + def copyOsEnviron(self): + theCopy = {} + for key in os.environ.keys(): + theCopy[key] = os.environ[key] + return theCopy + + def assertOutput(self, flags=None, javaHome=None, jythonHome=None, jythonOpts=None): + args = [sys.executable, '--print'] + memory = None + stack = None + prop = None + jythonArgs = None + boot = False + jdb = False + if flags: + for flag in flags: + if flag[:2] == '-J': + if flag[2:6] == '-Xmx': + memory = flag[6:] + elif flag[2:6] == '-Xss': + stack = flag[6:] + elif flag[2:4] == '-D': + prop = flag[2:] + elif flag[:2] == '--': + if flag[2:6] == 'boot': + boot = True + elif flag[2:5] == 'jdb': + jdb = True + else: + if jythonArgs: + jythonArgs += ' ' + jythonArgs += flag + else: + jythonArgs = flag + args.append(flag) + environ = None + if javaHome or jythonHome or jythonOpts: + environ = self.copyOsEnviron() # copy to prevent os.environ from being changed + if javaHome: + environ['JAVA_HOME'] = javaHome + if jythonHome: + environ['JYTHON_HOME'] = jythonHome + if jythonOpts: + environ['JYTHON_OPTS'] = jythonOpts + if environ: + # env changes can only be handled by Popen + process = Popen(args, stdout=PIPE, stderr=PIPE, env=environ) + out = process.stdout.read() + err = process.stderr.read() + else: + # since Popen escapes double quotes, we use a simple subprocess if no env changes are needed + simpleProcess = SimpleSubprocess(args) + simpleProcess.run() + out = simpleProcess.getStdout() + err = simpleProcess.getStderr() + self.assertEquals('', err) + self.assertNotEquals('', out) + homeIdx = out.find('-Dpython.home=') + java = 'java' + if javaHome: + java = self.quote(self.unquote(javaHome) + '\\bin\\java') + elif jdb: + java = 'jdb' + if not memory: + memory = '512m' + if not stack: + stack = '1152k' + beginning = java + ' ' + if prop: + beginning += ' ' + prop + beginning += ' -Xmx' + memory + ' -Xss' + stack + ' ' + self.assertEquals(beginning, out[:homeIdx]) + executableIdx = out.find('-Dpython.executable=') + homeDir = self.getHomeDir() + if jythonHome: + homeDir = self.unquote(jythonHome) + home = '-Dpython.home=' + self.quote(homeDir) + ' ' + self.assertEquals(home, out[homeIdx:executableIdx]) + if boot: + classpathFlag = '-Xbootclasspath/a:' + else: + classpathFlag = '-classpath' + classpathIdx = out.find(classpathFlag) + executable = '-Dpython.executable=' + self.quote(sys.executable) + ' ' + if not boot: + executable += ' ' + self.assertEquals(executable, out[executableIdx:classpathIdx]) + # ignore full contents of classpath at the moment + classIdx = out.find('org.python.util.jython') + self.assertTrue(classIdx > classpathIdx) + restIdx = classIdx + len('org.python.util.jython') + rest = out[restIdx:].strip() + if jythonOpts: + self.assertEquals(self.quote(jythonOpts), rest) + else: + if jythonArgs: + self.assertEquals(jythonArgs, rest) + else: + self.assertEquals('', rest) + +class VanillaTest(BaseTest): + def test_plain(self): + self.assertOutput() + +class JavaHomeTest(BaseTest): + def test_unquoted(self): + self.assertOutput(javaHome='C:\\Program Files\\Java\\someJava') + + def test_quoted(self): + self.assertOutput(javaHome=self.quote('C:\\Program Files\\Java\\someJava')) + + # this currently fails, meaning we accept only quoted (x86) homes ... + def __test_x86_unquoted(self): + self.assertOutput(javaHome='C:\\Program Files (x86)\\Java\\someJava') + + def test_x86_quoted(self): + self.assertOutput(javaHome=self.quote('C:\\Program Files (x86)\\Java\\someJava')) + +class JythonHomeTest(BaseTest): + def createJythonJar(self, parentDir): + jar = File(parentDir, 'jython.jar') + if not jar.exists(): + self.assertTrue(jar.createNewFile()) + return jar + + def cleanup(self, tmpdir, jar=None): + if jar and jar.exists(): + self.assertTrue(jar.delete()) + os.rmdir(tmpdir) + + def test_unquoted(self): + jythonHomeDir = tempfile.mkdtemp() + jar = self.createJythonJar(jythonHomeDir) + self.assertOutput(jythonHome=jythonHomeDir) + self.cleanup(jythonHomeDir, jar) + + def test_quoted(self): + jythonHomeDir = tempfile.mkdtemp() + jar = self.createJythonJar(jythonHomeDir) + self.assertOutput(jythonHome=self.quote(jythonHomeDir)) + self.cleanup(jythonHomeDir, jar) + +class JythonOptsTest(BaseTest): + def test_single(self): + self.assertOutput(jythonOpts='myOpt') + + def test_multiple(self): + self.assertOutput(jythonOpts='some arbitrary options') + +class JavaOptsTest(BaseTest): + def test_memory(self): + self.assertOutput(['-J-Xmx321m']) + + def test_stack(self): + self.assertOutput(['-J-Xss321k']) + + def test_property(self): + self.assertOutput(['-J-DmyProperty=myValue']) + + def test_property_singlequote(self): + self.assertOutput(["-J-DmyProperty='myValue'"]) # a space inside value does not work in jython.bat + + def test_property_doublequote(self): + self.assertOutput(['-J-DmyProperty="myValue"']) # a space inside value does not work in jython.bat + + def test_property_underscore(self): + self.assertOutput(['-J-Dmy_Property=my_Value']) + +class ArgsTest(BaseTest): + def test_file(self): + self.assertOutput(['test.py']) + + def test_dash(self): + self.assertOutput(['-i']) + + def test_combined(self): + self.assertOutput(['-W', 'action', 'line']) + + # something adds double quotes, but in real life this works: + # jython.bat --print -c 'import sys;' + def test_singlequoted(self): + args = [sys.executable] + args.append('--print') + args.append('-c') + args.append("'import sys;'") + simpleProcess = SimpleSubprocess(args) + simpleProcess.run() + out = simpleProcess.getStdout() + err = simpleProcess.getStderr() + self.assertEquals('', err) + self.assertNotEquals('', out) + tail = out[-19:] + self.assertEquals('-c "\'import sys;\'" ', tail) + + def test_doublequoted(self): + self.assertOutput(['-c', '"print \'something\'"']) + + def test_underscored(self): + self.assertOutput(['-jar', 'my_stuff.jar']) + + def test_property(self): + self.assertOutput(['-DmyProperty=myValue']) + + def test_property_underscored(self): + self.assertOutput(['-DmyProperty=my_Value']) + + def test_property_singlequoted(self): + self.assertOutput(["-DmyProperty='my_Value'"]) + + def test_property_doublequoted(self): + self.assertOutput(['-DmyProperty="my_Value"']) + +class DoubleDashTest(BaseTest): + def test_boot(self): + self.assertOutput(['--boot']) + + def test_jdb(self): + self.assertOutput(['--jdb']) + +def test_main(): + test_support.run_unittest( + VanillaTest, + JavaHomeTest, + JythonHomeTest, + JythonOptsTest, + JavaOptsTest, + ArgsTest, + DoubleDashTest) + + +if __name__ == '__main__': + # these tests currently only make sense on windows + if os._name == 'nt': + test_main() Modified: trunk/jython/src/shell/jython.bat =================================================================== --- trunk/jython/src/shell/jython.bat 2010-04-27 06:07:08 UTC (rev 7051) +++ trunk/jython/src/shell/jython.bat 2010-04-28 23:16:27 UTC (rev 7052) @@ -183,7 +183,7 @@ set CLASSPATH=%_CP:"=%;%CLASSPATH:"=% :fullCmd -set _FULL_CMD=%_JAVA_CMD% %_JAVA_OPTS% %_JAVA_MEM% %_JAVA_STACK% %_BOOT_CP% -Dpython.home=%_JYTHON_HOME% -Dpython.executable="%~f0" -classpath "%CLASSPATH%" org.python.util.jython %_JYTHON_OPTS% %_JYTHON_ARGS% %_ARGS% +set _FULL_CMD=%_JAVA_CMD% %_JAVA_OPTS% %_JAVA_MEM% %_JAVA_STACK% -Dpython.home=%_JYTHON_HOME% -Dpython.executable="%~f0" %_BOOT_CP% -classpath "%CLASSPATH%" org.python.util.jython %_JYTHON_OPTS% %_JYTHON_ARGS% %_ARGS% if defined _PRINT ( echo %_FULL_CMD% ) else ( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2010-06-01 22:59:28
|
Revision: 7060 http://jython.svn.sourceforge.net/jython/?rev=7060&view=rev Author: otmarhumbel Date: 2010-06-01 22:59:22 +0000 (Tue, 01 Jun 2010) Log Message: ----------- do not expand * in arguments any more (expected to fix #1567, #1594 and #1356) many thanks to Pekka Kl?\195?\164rck and Andreas Ebbert-Karroum for their analysis and suggestions! Modified Paths: -------------- trunk/jython/Lib/test/test_bat_jy.py trunk/jython/Lib/test/test_subprocess.py trunk/jython/src/shell/jython.bat Modified: trunk/jython/Lib/test/test_bat_jy.py =================================================================== --- trunk/jython/Lib/test/test_bat_jy.py 2010-05-31 04:36:44 UTC (rev 7059) +++ trunk/jython/Lib/test/test_bat_jy.py 2010-06-01 22:59:22 UTC (rev 7060) @@ -291,6 +291,12 @@ def test_doublequoted(self): self.assertOutput(['-c', '"print \'something\'"']) + def test_nestedquotes(self): + self.assertOutput(['-c', '"print \'something \"really\" cool\'"']) + + def test_nestedquotes2(self): + self.assertOutput(['-c', "'print \"something \'really\' cool\"'"]) + def test_underscored(self): self.assertOutput(['-jar', 'my_stuff.jar']) @@ -313,6 +319,25 @@ def test_jdb(self): self.assertOutput(['--jdb']) +class GlobPatternTest(BaseTest): + def test_star_nonexisting(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', '*.nonexisting', '*.nonexisting']) + + def test_star_nonexisting_doublequoted(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', '"*.nonexisting"', '"*.nonexisting"']) + + def test_star_nonexistingfile_singlequoted(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', "'*.nonexisting'", "'*.nonexisting'"]) + + def test_star_existing(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', '*.bat', '*.bat']) + + def test_star_existing_doublequoted(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', '"*.bat"', '"*.bat"']) + + def test_star_existing_singlequoted(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', "'*.bat'", "'*.bat'"]) + class DummyTest(unittest.TestCase): def test_nothing(self): pass @@ -325,7 +350,8 @@ JythonOptsTest, JavaOptsTest, ArgsTest, - DoubleDashTest) + DoubleDashTest, + GlobPatternTest) else: # provide at least one test for the other platforms - happier build bots test_support.run_unittest(DummyTest) Modified: trunk/jython/Lib/test/test_subprocess.py =================================================================== --- trunk/jython/Lib/test/test_subprocess.py 2010-05-31 04:36:44 UTC (rev 7059) +++ trunk/jython/Lib/test/test_subprocess.py 2010-06-01 22:59:22 UTC (rev 7060) @@ -707,7 +707,8 @@ def test_main(): # Spawning many new jython processes takes a long time - test_support.requires('subprocess') + # TODO:oti uncomment the next line as soon as the fix to #1356 is verified on the build bots + #test_support.requires('subprocess') test_support.run_unittest(ProcessTestCase) if hasattr(test_support, "reap_children"): test_support.reap_children() Modified: trunk/jython/src/shell/jython.bat =================================================================== --- trunk/jython/src/shell/jython.bat 2010-05-31 04:36:44 UTC (rev 7059) +++ trunk/jython/src/shell/jython.bat 2010-06-01 22:59:22 UTC (rev 7060) @@ -106,7 +106,7 @@ :getArg rem remove quotes around first arg -for %%i in (%1) do set _CMP=%%~i +set _CMP=%~1 set _ARGS=%2 goto :EOF @@ -140,7 +140,7 @@ goto :nextArg ) -rem now unescape _D, _S and _Q +rem now unescape _D, _S and _U set _CMP=%_CMP:_D="% set _CMP=%_CMP:_S='% set _CMP=%_CMP:_U=_% This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-06-03 03:53:18
|
Revision: 7063 http://jython.svn.sourceforge.net/jython/?rev=7063&view=rev Author: pjenvey Date: 2010-06-03 03:53:11 +0000 (Thu, 03 Jun 2010) Log Message: ----------- fix caching of packages with dir listings larger than the 64k DataOutputStream UTF-8 string limit. changes the packagecache on disk format but in a backwards compatible way fixes #1595 patch from bpedman Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java Added Paths: ----------- trunk/jython/tests/java/org/python/core/packagecache/ trunk/jython/tests/java/org/python/core/packagecache/CachedJarsOver64kTest.java trunk/jython/tests/java/org/python/core/packagecache/vim25-small.jar Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-06-03 02:38:42 UTC (rev 7062) +++ trunk/jython/NEWS 2010-06-03 03:53:11 UTC (rev 7063) @@ -48,6 +48,7 @@ - [ 1567 ] [Windows] Wildcard Parameter * gets expanded to filename - [ 1594 ] Glob patterns like *.txt processed incorrectly on startup - [ 1356 ] [Windows] test_subprocess test_communicate_pipe_buf fails + - [ 1595 ] [patch] CachedJarsPackageManager cannot write cache for packages in jar over 64k - 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/packagecache/CachedJarsPackageManager.java =================================================================== --- trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java 2010-06-03 02:38:42 UTC (rev 7062) +++ trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java 2010-06-03 03:53:11 UTC (rev 7063) @@ -371,6 +371,14 @@ while (true) { String packageName = istream.readUTF(); String classes = istream.readUTF(); + // XXX: Handle multiple chunks of classes and concatenate them + // together. Multiple chunks were added in 2.5.2 (for #1595) in this + // way to maintain compatibility with the pre 2.5.2 format. In the + // future we should consider changing the cache format to prepend a + // count of chunks to avoid this check + if (packs.containsKey(packageName)) { + classes = packs.get(packageName) + classes; + } packs.put(packageName, classes); } } catch (EOFException eof) { @@ -396,8 +404,12 @@ for (Entry<String,String> kv : zipPackages.entrySet()) { String classes = kv.getValue(); - ostream.writeUTF(kv.getKey()); - ostream.writeUTF(classes); + // Make sure each package is not larger than 64k + for (String part : splitString(classes, 65535)) { + // For each chunk, write the package name followed by the classes. + ostream.writeUTF(kv.getKey()); + ostream.writeUTF(part); + } } ostream.close(); } catch (IOException ioe) { @@ -406,6 +418,35 @@ } /** + * Split up a string into several chunks based on a certain size + * + * The writeCacheFile method will use the writeUTF method on a + * DataOutputStream which only allows writing 64k chunks, so use + * this utility method to split it up + * + * @param str - The string to split up into chunks + * @param maxLength - The max size a string should be + * @return - An array of strings, each of which will not be larger than maxLength + */ + protected static String[] splitString(String str, int maxLength) { + if (str == null) { + return null; + } + + int len = str.length(); + if (len <= maxLength) { + return new String[] {str}; + } + + int chunkCount = (int) Math.ceil((float) len / maxLength); + String[] chunks = new String[chunkCount]; + for (int i = 0; i < chunkCount; i++) { + chunks[i] = str.substring(i * maxLength, Math.min(i * maxLength + maxLength, len)); + } + return chunks; + } + + /** * Initializes cache. Eventually reads back cache index. Index persistent * storage is accessed through inOpenIndex(). */ Added: trunk/jython/tests/java/org/python/core/packagecache/CachedJarsOver64kTest.java =================================================================== --- trunk/jython/tests/java/org/python/core/packagecache/CachedJarsOver64kTest.java (rev 0) +++ trunk/jython/tests/java/org/python/core/packagecache/CachedJarsOver64kTest.java 2010-06-03 03:53:11 UTC (rev 7063) @@ -0,0 +1,63 @@ +package org.python.core.packagecache; + +import java.io.File; + +import org.python.core.PyJavaPackage; +import org.python.core.PyList; +import org.python.core.packagecache.CachedJarsPackageManager; + +import junit.framework.TestCase; + +public class CachedJarsOver64kTest extends TestCase { + + private TestCachePackageManager packageManager = null; + + private File jarFile = null; + + @Override + public void setUp() { + // Find the jar to use + packageManager = new TestCachePackageManager(new File(System + .getProperty("java.io.tmpdir"))); + File cwd = new File(System.getProperty("python.test.source.dir"), + getClass().getPackage().getName().replace(".", "/")); + jarFile = new File(cwd, "vim25-small.jar"); + } + + public void testJarOver64k() { + assertTrue(jarFile.exists()); + packageManager.addJarToPackages(jarFile, true); + assertFalse(packageManager.failed); + } + + private class TestCachePackageManager extends CachedJarsPackageManager { + + public boolean failed; + + public TestCachePackageManager(File cachedir) { + if (useCacheDir(cachedir)){ + initCache(); + } + } + + @Override + protected void warning(String msg){ + failed = true; + } + + @Override + public void addDirectory(File dir) {} + @Override + public void addJar(String jarfile, boolean cache) {} + @Override + public void addJarDir(String dir, boolean cache) {} + @Override + public PyList doDir(PyJavaPackage jpkg, boolean instantiate, boolean exclpkgs) { + return null; + } + @Override + public Class<?> findClass(String pkg, String name, String reason) { return null; } + @Override + public boolean packageExists(String pkg, String name) { return false; } + } +} Added: trunk/jython/tests/java/org/python/core/packagecache/vim25-small.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/tests/java/org/python/core/packagecache/vim25-small.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: <otm...@us...> - 2010-06-15 06:34:22
|
Revision: 7065 http://jython.svn.sourceforge.net/jython/?rev=7065&view=rev Author: otmarhumbel Date: 2010-06-15 06:34:16 +0000 (Tue, 15 Jun 2010) Log Message: ----------- handle arguments containing % signs partly fixes issue #1599 Modified Paths: -------------- trunk/jython/Lib/test/test_bat_jy.py trunk/jython/src/shell/jython.bat Modified: trunk/jython/Lib/test/test_bat_jy.py =================================================================== --- trunk/jython/Lib/test/test_bat_jy.py 2010-06-15 06:33:20 UTC (rev 7064) +++ trunk/jython/Lib/test/test_bat_jy.py 2010-06-15 06:34:16 UTC (rev 7065) @@ -102,7 +102,7 @@ stdoutMonitor.start() stderrMonitor.start() while self.isAlive(process): - Thread.sleep(500) + Thread.sleep(300) return self.getOutput(outfilePath) finally: os.remove(starterPath) @@ -158,6 +158,7 @@ jythonArgs += flag else: jythonArgs = flag + jythonArgs = jythonArgs.replace('%%', '%') # workaround two .bat files args.append(flag) process = StarterProcess() out = process.run(args, javaHome, jythonHome, jythonOpts) @@ -267,11 +268,19 @@ self.assertOutput(['-J-DmyProperty=myValue']) def test_property_singlequote(self): - self.assertOutput(["-J-DmyProperty='myValue'"]) # a space inside value does not work in jython.bat + self.assertOutput(["-J-DmyProperty='myValue'"]) + # a space inside value does not work in jython.bat + def __test_property_singlequote_space(self): + self.assertOutput(["-J-DmyProperty='my Value'"]) + def test_property_doublequote(self): - self.assertOutput(['-J-DmyProperty="myValue"']) # a space inside value does not work in jython.bat + self.assertOutput(['-J-DmyProperty="myValue"']) + # a space inside value does not work in jython.bat + def __test_property_doublequote_space(self): + self.assertOutput(['-J-DmyProperty="my Value"']) + def test_property_underscore(self): self.assertOutput(['-J-Dmy_Property=my_Value']) @@ -338,6 +347,36 @@ def test_star_existing_singlequoted(self): self.assertOutput(['-c', 'import sys; print sys.argv[1:]', "'*.bat'", "'*.bat'"]) +class ArgsSpacesTest(BaseTest): + def test_doublequoted(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', '"part1 part2"', '2nd']) + + def test_singlequoted(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', "'part1 part2'", '2nd']) + + # this test currently fails + def __test_unbalanced_doublequote(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', 'Scarlet O"Hara', '2nd']) + + def test_unbalanced_singlequote(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', "Scarlet O'Hara", '2nd']) + +class ArgsSpecialCharsTest(BaseTest): + # exclamation marks are still very special ... + def __test_exclamationmark(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', 'foo!', 'ba!r', '!baz', '!']) + + # because we go through a starter.bat file, we have to simulate % with %% + def test_percentsign(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', 'foo%%1', '%%1bar', '%%1', '%%']) + + def test_colon(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', 'foo:', ':bar']) + + # a semicolon at the beginning of an arg currently fails (e.g. ;bar) + def test_semicolon(self): + self.assertOutput(['-c', 'import sys; print sys.argv[1:]', 'foo;']) + class DummyTest(unittest.TestCase): def test_nothing(self): pass @@ -351,7 +390,9 @@ JavaOptsTest, ArgsTest, DoubleDashTest, - GlobPatternTest) + GlobPatternTest, + ArgsSpacesTest, + ArgsSpecialCharsTest) else: # provide at least one test for the other platforms - happier build bots test_support.run_unittest(DummyTest) Modified: trunk/jython/src/shell/jython.bat =================================================================== --- trunk/jython/src/shell/jython.bat 2010-06-15 06:33:20 UTC (rev 7064) +++ trunk/jython/src/shell/jython.bat 2010-06-15 06:34:16 UTC (rev 7065) @@ -18,6 +18,8 @@ goto finish :normalstart +set _PERCENT=%% +set _EXCLAMATION=! setlocal enabledelayedexpansion rem ----- Verify and set required environment variables ----------------------- @@ -25,21 +27,21 @@ set _JAVA_CMD=java rem remove surrounding quotes from java home, to be able to safely empty-test it set _TRIMMED_JAVA_HOME=%JAVA_HOME% -for /f "useback tokens=*" %%a in ('%_TRIMMED_JAVA_HOME%') do set _TRIMMED_JAVA_HOME=%%~a +for /f "usebackq tokens=*" %%a in ('%_TRIMMED_JAVA_HOME%') do set _TRIMMED_JAVA_HOME=%%~a if not "%_TRIMMED_JAVA_HOME%"=="" ( set _JAVA_CMD="%JAVA_HOME:"=%\bin\java" ) rem remove surrounding quotes from jython opts, to be able to safely empty-test it set _TRIMMED_JYTHON_OPTS=%JYTHON_OPTS% -for /f "useback tokens=*" %%a in ('%_TRIMMED_JYTHON_OPTS%') do set _TRIMMED_JYTHON_OPTS=%%~a +for /f "usebackq tokens=*" %%a in ('%_TRIMMED_JYTHON_OPTS%') do set _TRIMMED_JYTHON_OPTS=%%~a if not "%_TRIMMED_JYTHON_OPTS%"=="" ( set _JYTHON_OPTS="%_TRIMMED_JYTHON_OPTS%" ) rem remove surrounding quotes from jython home, to be able to safely empty-test it set _TRIMMED_JYTHON_HOME=%JYTHON_HOME% -for /f "useback tokens=*" %%a in ('%_TRIMMED_JYTHON_HOME%') do set _TRIMMED_JYTHON_HOME=%%~a +for /f "usebackq tokens=*" %%a in ('%_TRIMMED_JYTHON_HOME%') do set _TRIMMED_JYTHON_HOME=%%~a if not "%_TRIMMED_JYTHON_HOME%"=="" ( set _JYTHON_HOME="%_TRIMMED_JYTHON_HOME%" goto gotHome @@ -95,6 +97,10 @@ set _ARGS=%_ARGS:_=_U% set _ARGS=%_ARGS:'=_S% set _ARGS=%_ARGS:"=_D% +rem also escape % signs +set _replaceVal=%_ARGS% +call :escape +set _ARGS=%_replaceVal% set _ARGS="%_ARGS%" set _JYTHON_ARGS= @@ -140,7 +146,10 @@ goto :nextArg ) -rem now unescape _D, _S and _U +rem now unescape everything +set _replaceVal=%_CMP% +call :escape +set _CMP=%_replaceVal% set _CMP=%_CMP:_D="% set _CMP=%_CMP:_S='% set _CMP=%_CMP:_U=_% @@ -210,6 +219,80 @@ set _TRIMMED_JAVA_HOME= set _TRIMMED_JYTHON_HOME= set _TRIMMED_JYTHON_OPTS= +goto finish + + +REM escapes or unescapes % with @@P@@, and ! with @@E@@ +REM input: a text variable named _replaceVal +REM result: _replaceVal has the new value +:escape +if not defined _replaceVal goto :EOF +set /a _index=-1 +set _replaced= + +:escapeNext +set /a _index=%_index% + 1 +call set _escapeChar=%%_replaceVal:~%_index%,1%% +if ^"==^%_escapeChar% goto noEscape +if ''=='%_escapeChar%' goto escapeEnd +if "%_escapeChar%"==" " goto noEscape +if "%_escapeChar%"=="@" goto unescapeCheck +if "%_escapeChar%"=="%_EXCLAMATION%" goto escapeExclamation +if "%_escapeChar%"=="%_PERCENT%" goto escapePercent +:noEscape +set _replaced=%_replaced%%_escapeChar% +goto escapeNext + +:escapeExclamation +set _replaced=%_replaced%@@E@@ +goto escapeNext + +:escapePercent +set _replaced=%_replaced%@@P@@ +goto escapeNext + +:unescapeCheck +set _isExclamation= +set _isPercent= +set _isUnrecognized=true +set /a _aheadIndex=%_index% + 1 +call set _aheadChar=%%_replaceVal:~%_aheadIndex%,1%% +if ^"==^%_aheadChar% goto noEscape +if "%_aheadChar%"=="@" set /a _aheadIndex=%_aheadIndex% + 1 +call set _aheadChar=%%_replaceVal:~%_aheadIndex%,1%% +if ^"==^%_aheadChar% goto noEscape +if "%_aheadChar%"=="E" set _isExclamation=true & set _isUnrecognized= +if "%_aheadChar%"=="P" set _isPercent=true & set _isUnrecognized= +if defined _isUnrecognized goto noEscape +set _isUnrecognized=true +set /a _aheadIndex=%_aheadIndex% + 1 +call set _aheadChar=%%_replaceVal:~%_aheadIndex%,1%% +if ^"==^%_aheadChar% goto noEscape +if "%_aheadChar%"=="@" set /a _aheadIndex=%_aheadIndex% + 1 +call set _aheadChar=%%_replaceVal:~%_aheadIndex%,1%% +if ^"==^%_aheadChar% goto noEscape +if "%_aheadChar%"=="@" set _isUnrecognized= +if defined _isUnrecognized goto noEscape +if defined _isExclamation goto unescapeExclamation +if defined _isPercent goto unescapePercent +goto noEscape + +:unescapeExclamation +set _replaced=%_replaced%%_EXCLAMATION% +set /a _index=%_index% + 4 +goto escapeNext + +:unescapePercent +set _replaced=%_replaced%%_PERCENT% +set /a _index=%_index% + 4 +goto escapeNext + +:escapeEnd +set _replaceVal=%_replaced% +goto :EOF + + + :finish %COMSPEC% /c exit /b %E% This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2010-06-16 14:46:41
|
Revision: 7066 http://jython.svn.sourceforge.net/jython/?rev=7066&view=rev Author: zyasoft Date: 2010-06-16 14:46:34 +0000 (Wed, 16 Jun 2010) Log Message: ----------- Reflected method fixes: Fixes #1605 by having PyComplex#__tojava__ refuse to convert to anything but itself (restores old behavior before adding support for faux floats) Fixes #1615 by supporting varargs Java methods, so that a method marked as test(String...) can be called as either test("abc", "xyz") or, because it's reasonable in Java, test(["abc", "xyz"]) Modified Paths: -------------- trunk/jython/Lib/test/test_joverload.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyComplex.java trunk/jython/src/org/python/core/PyReflectedFunction.java trunk/jython/src/org/python/core/ReflectedArgs.java Added Paths: ----------- trunk/jython/tests/java/javatests/Reflection.java Modified: trunk/jython/Lib/test/test_joverload.py =================================================================== --- trunk/jython/Lib/test/test_joverload.py 2010-06-15 06:34:16 UTC (rev 7065) +++ trunk/jython/Lib/test/test_joverload.py 2010-06-16 14:46:34 UTC (rev 7066) @@ -3,9 +3,12 @@ # (can be adapted to test alternative re-implemations even while they are developed # write a *Envl class and change/add to to_test for that) +import sys import unittest import java +from java.util import ArrayList +from javatests import JOverload, Reflection from org.python.core import PyReflectedFunction class PyReflFuncEnvl: @@ -25,7 +28,6 @@ meth_dict[name] = envl_class(name,[ m for m in meths if m.name == name ]) return meth_dict -from javatests import JOverload jo = JOverload() to_test = [extract_ov_meths(JOverload,PyReflFuncEnvl)] @@ -119,11 +121,55 @@ """) +class VarargsDispatchTests(unittest.TestCase): + + def test_strings(self): + t = Reflection.StringVarargs() + self.assertEqual(t.test("abc", "xyz"), + "String...:[abc, xyz]") + self.assertEqual(t.test("abc"), + "String...:[abc]") + self.assertEqual(t.test(), + "String...:[]") + + self.assertEqual(t.test(["abc", "xyz"]), + "String...:[abc, xyz]") + self.assertEqual(t.test(["abc"]), + "String...:[abc]") + self.assertEqual(t.test([]), + "String...:[]") + + + def test_lists(self): + t = Reflection.ListVarargs() + self.assertEqual(t.test(ArrayList([1,2,3]), ArrayList([4,5,6])), + "List...:[[1, 2, 3], [4, 5, 6]]") + self.assertEqual(t.test(ArrayList([1,2,3])), + "List...:[[1, 2, 3]]") + self.assertEqual(t.test(), + "List...:[]") + + self.assertEqual(t.test([ArrayList([1,2,3]), ArrayList([4,5,6])]), + "List...:[[1, 2, 3], [4, 5, 6]]") + self.assertEqual(t.test([ArrayList([1,2,3])]), + "List...:[[1, 2, 3]]") + self.assertEqual(t.test([]), + "List...:[]") + + +class ComplexOverloadingTests(unittest.TestCase): + + def test_complex(self): + o = Reflection.Overloaded() + self.assertEqual(o(2.), "class java.lang.Double=2.0") + self.assertEqual(o(1+2j), "class org.python.core.PyComplex=(1+2j)") + + + def printout(meth_dict,lbl,rng,args): for i in rng: print meth_dict['ov_%s%s' % (lbl,i)](jo,args) -import sys if __name__ == '__main__' and not sys.argv[1:] == ['break-out']: try: @@ -131,4 +177,4 @@ except ImportError: unittest.main() else: - test_support.run_unittest(OverloadedDispatchTests) + test_support.run_unittest(OverloadedDispatchTests, VarargsDispatchTests, ComplexOverloadingTests) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-06-15 06:34:16 UTC (rev 7065) +++ trunk/jython/NEWS 2010-06-16 14:46:34 UTC (rev 7066) @@ -2,6 +2,8 @@ Jython 2.5.2a1 Bugs Fixed + - [ 1615 ] Can't invoke Java method that takes a variable number of arguments with zero arguments + - [ 1605 ] float preference over PyComplex as arg to __call__ breaks logic - [ 1586 ] weakref reference count leak when kwargs are used - [ 1601 ] Can't serialize PyCode object - [ 1551 ] Java objects cannot be copied by the copy module Modified: trunk/jython/src/org/python/core/PyComplex.java =================================================================== --- trunk/jython/src/org/python/core/PyComplex.java 2010-06-15 06:34:16 UTC (rev 7065) +++ trunk/jython/src/org/python/core/PyComplex.java 2010-06-16 14:46:34 UTC (rev 7066) @@ -482,7 +482,17 @@ return _divmod(coerce(left), this).__finditem__(0); } + // Special case __tojava__ for bug 1605, since we broke it with our support for faux floats. + @Override + public Object __tojava__(Class<?> c) { + if (c.isInstance(this)) { + return this; + } + return Py.NoConversion; + } + + @Override public PyObject __truediv__(PyObject right) { return complex___truediv__(right); } Modified: trunk/jython/src/org/python/core/PyReflectedFunction.java =================================================================== --- trunk/jython/src/org/python/core/PyReflectedFunction.java 2010-06-15 06:34:16 UTC (rev 7065) +++ trunk/jython/src/org/python/core/PyReflectedFunction.java 2010-06-16 14:46:34 UTC (rev 7066) @@ -55,9 +55,10 @@ private ReflectedArgs makeArgs(Method m) { return new ReflectedArgs(m, - m.getParameterTypes(), - m.getDeclaringClass(), - Modifier.isStatic(m.getModifiers())); + m.getParameterTypes(), + m.getDeclaringClass(), + Modifier.isStatic(m.getModifiers()), + m.isVarArgs()); } public PyReflectedFunction copy() { Modified: trunk/jython/src/org/python/core/ReflectedArgs.java =================================================================== --- trunk/jython/src/org/python/core/ReflectedArgs.java 2010-06-15 06:34:16 UTC (rev 7065) +++ trunk/jython/src/org/python/core/ReflectedArgs.java 2010-06-16 14:46:34 UTC (rev 7066) @@ -10,6 +10,8 @@ public boolean isStatic; + public boolean isVarArgs; + public int flags; public static final int StandardCall = 0; @@ -19,10 +21,15 @@ public static final int PyArgsKeywordsCall = 2; public ReflectedArgs(Object data, Class<?>[] args, Class<?> declaringClass, boolean isStatic) { + this(data, args, declaringClass, isStatic, false); + } + + public ReflectedArgs(Object data, Class<?>[] args, Class<?> declaringClass, boolean isStatic, boolean isVarArgs) { this.data = data; this.args = args; this.declaringClass = declaringClass; this.isStatic = isStatic; + this.isVarArgs = isVarArgs; // only used for varargs matching; it should be added after the unboxed form if (args.length == 1 && args[0] == PyObject[].class) { this.flags = PyArgsCall; @@ -90,6 +97,38 @@ } int n = this.args.length; + + // if we have a varargs method AND the last PyObject is not a list/tuple + // we need to do box (wrap with an array) the last pyArgs.length - n args + // (which might be empty) + // + // examples: + // test(String... x) + // test(List... x) + // + // in this last example, don't worry if someone is overly clever in calling this, + // they can always write their own version of PyReflectedFunction and put it in the proxy + // if that's what they need to do ;) + + if (isVarArgs) { + if (pyArgs.length == 0 || !(pyArgs[pyArgs.length - 1] instanceof PySequenceList)) { + int non_varargs_len = n - 1; + if (pyArgs.length >= non_varargs_len) { + PyObject[] boxedPyArgs = new PyObject[n]; + for (int i = 0; i < non_varargs_len; i++) { + boxedPyArgs[i] = pyArgs[i]; + } + int varargs_len = pyArgs.length - non_varargs_len; + PyObject[] varargs = new PyObject[varargs_len]; + for (int i = 0; i < varargs_len; i++) { + varargs[i] = pyArgs[non_varargs_len + i]; + } + boxedPyArgs[non_varargs_len] = new PyList(varargs); + pyArgs = boxedPyArgs; + } + } + } + if (pyArgs.length != n) { return false; } @@ -111,8 +150,11 @@ Object[] javaArgs = callData.args; for (int i = 0; i < n; i++) { - if ((javaArgs[i] = pyArgs[i].__tojava__(this.args[i])) == Py.NoConversion) { - // Make error messages clearer + PyObject pyArg = pyArgs[i]; + Class targetClass = this.args[i]; + Object javaArg = pyArg.__tojava__(targetClass); + javaArgs[i] = javaArg; + if (javaArg == Py.NoConversion) { if (i > callData.errArg) { callData.errArg = i; } @@ -253,7 +295,7 @@ @Override public String toString() { - String s = declaringClass + ", " + isStatic + ", " + flags + ", " + data + "\n"; + String s = declaringClass + ", static=" + isStatic + ", varargs=" + isVarArgs + ",flags=" + flags + ", " + data + "\n"; s = s + "\t("; for (Class<?> arg : args) { s += arg.getName() + ", "; Added: trunk/jython/tests/java/javatests/Reflection.java =================================================================== --- trunk/jython/tests/java/javatests/Reflection.java (rev 0) +++ trunk/jython/tests/java/javatests/Reflection.java 2010-06-16 14:46:34 UTC (rev 7066) @@ -0,0 +1,44 @@ +package javatests; + +import java.util.Arrays; +import java.util.List; + +import org.python.core.Py; +import org.python.core.PyComplex; +import org.python.core.PyObject; + +public class Reflection { + + public static class StringVarargs { + + public String test(String... args) { + return "String...:" + Arrays.toString(args); + } + } + + public static class ListVarargs { + + public String test(List... args) { + return "List...:" + Arrays.toString(args); + } + } + + public static class Overloaded { + + public PyObject __call__(float x) { + return dump(x); + } + + public PyObject __call__(double x) { + return dump(x); + } + + public PyObject __call__(PyComplex x) { + return dump(x); + } + + private PyObject dump(Object o) { + return Py.newString(o.getClass() + "=" + o); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-06-25 14:22:15
|
Revision: 7070 http://jython.svn.sourceforge.net/jython/?rev=7070&view=rev Author: amak Date: 2010-06-25 14:22:08 +0000 (Fri, 25 Jun 2010) Log Message: ----------- Fix for bug 1614: minidom chunks the character input on multi-line values Modified Paths: -------------- trunk/jython/Lib/test/test_minidom.py trunk/jython/Lib/xml/dom/minidom.py trunk/jython/NEWS Modified: trunk/jython/Lib/test/test_minidom.py =================================================================== --- trunk/jython/Lib/test/test_minidom.py 2010-06-25 13:16:13 UTC (rev 7069) +++ trunk/jython/Lib/test/test_minidom.py 2010-06-25 14:22:08 UTC (rev 7070) @@ -523,6 +523,29 @@ "testNormalize -- single empty node removed") doc.unlink() +def testNormalizedAfterLoad(): + """ + Introduced this test on jython because + 1. Cpython guarantees, by the use of xml.dom.expatbuilder, + that all text nodes are normalized after loading. + 2. Jython has no expat, and thus uses xml.dom.pulldom.parse + (which uses any java SAX2 compliant parser), and which makes + no guarantees about text node normalization. + Thus we have to check if text nodes are normalized after a parse. + See this bug for further information + minidom chunks the character input on multi-line values + http://bugs.jython.org/issue1614 + """ + num_lines = 2 + # Up to 16K lines should be enough to guarantee failure without normalization + while num_lines <= 2**14: + doc_content = "\n".join( ("Line %d" % i for i in xrange(num_lines)) ) + doc_text = "<document>%s</document>" % doc_content + dom = parseString(doc_text) + node_content = dom.getElementsByTagName("document")[0].childNodes[0].nodeValue + confirm(node_content == doc_content, "testNormalizedAfterLoad") + num_lines *= 2 + def testSiblings(): doc = parseString("<doc><?pi?>text?<elm/></doc>") root = doc.documentElement Modified: trunk/jython/Lib/xml/dom/minidom.py =================================================================== --- trunk/jython/Lib/xml/dom/minidom.py 2010-06-25 13:16:13 UTC (rev 7069) +++ trunk/jython/Lib/xml/dom/minidom.py 2010-06-25 14:22:08 UTC (rev 7070) @@ -1908,6 +1908,7 @@ toktype, rootNode = events.getEvent() events.expandNode(rootNode) events.clear() + rootNode.normalize() return rootNode def parse(file, parser=None, bufsize=None): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-06-25 13:16:13 UTC (rev 7069) +++ trunk/jython/NEWS 2010-06-25 14:22:08 UTC (rev 7070) @@ -2,6 +2,7 @@ Jython 2.5.2a1 Bugs Fixed + - [ 1614 ] minidom chunks the character input on multi-line values - [ 1615 ] Can't invoke Java method that takes a variable number of arguments with zero arguments - [ 1605 ] float preference over PyComplex as arg to __call__ breaks logic - [ 1586 ] weakref reference count leak when kwargs are used This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |