You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(107) |
Dec
(67) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(76) |
Feb
(125) |
Mar
(72) |
Apr
(13) |
May
(18) |
Jun
(12) |
Jul
(129) |
Aug
(47) |
Sep
(1) |
Oct
(36) |
Nov
(128) |
Dec
(124) |
2002 |
Jan
(59) |
Feb
|
Mar
(14) |
Apr
(14) |
May
(72) |
Jun
(9) |
Jul
(3) |
Aug
(5) |
Sep
(18) |
Oct
(65) |
Nov
(28) |
Dec
(12) |
2003 |
Jan
(10) |
Feb
(2) |
Mar
(4) |
Apr
(33) |
May
(21) |
Jun
(9) |
Jul
(29) |
Aug
(34) |
Sep
(4) |
Oct
(8) |
Nov
(15) |
Dec
(4) |
2004 |
Jan
(26) |
Feb
(12) |
Mar
(11) |
Apr
(9) |
May
(7) |
Jun
|
Jul
(5) |
Aug
|
Sep
(3) |
Oct
(7) |
Nov
(1) |
Dec
(10) |
2005 |
Jan
(2) |
Feb
(72) |
Mar
(16) |
Apr
(39) |
May
(48) |
Jun
(97) |
Jul
(57) |
Aug
(13) |
Sep
(16) |
Oct
(24) |
Nov
(100) |
Dec
(24) |
2006 |
Jan
(15) |
Feb
(34) |
Mar
(33) |
Apr
(31) |
May
(79) |
Jun
(64) |
Jul
(41) |
Aug
(64) |
Sep
(31) |
Oct
(46) |
Nov
(55) |
Dec
(37) |
2007 |
Jan
(32) |
Feb
(61) |
Mar
(11) |
Apr
(58) |
May
(46) |
Jun
(30) |
Jul
(94) |
Aug
(93) |
Sep
(86) |
Oct
(69) |
Nov
(125) |
Dec
(177) |
2008 |
Jan
(169) |
Feb
(97) |
Mar
(74) |
Apr
(113) |
May
(120) |
Jun
(334) |
Jul
(215) |
Aug
(237) |
Sep
(72) |
Oct
(189) |
Nov
(126) |
Dec
(160) |
2009 |
Jan
(180) |
Feb
(45) |
Mar
(98) |
Apr
(140) |
May
(151) |
Jun
(71) |
Jul
(107) |
Aug
(119) |
Sep
(73) |
Oct
(121) |
Nov
(14) |
Dec
(6) |
2010 |
Jan
(13) |
Feb
(9) |
Mar
(10) |
Apr
(64) |
May
(3) |
Jun
(16) |
Jul
(7) |
Aug
(23) |
Sep
(17) |
Oct
(37) |
Nov
(5) |
Dec
(8) |
2011 |
Jan
(10) |
Feb
(11) |
Mar
(77) |
Apr
(11) |
May
(2) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <pj...@us...> - 2010-04-09 05:06:14
|
Revision: 7009 http://jython.svn.sourceforge.net/jython/?rev=7009&view=rev Author: pjenvey Date: 2010-04-09 05:06:08 +0000 (Fri, 09 Apr 2010) Log Message: ----------- replace __int/long/float__ with asInt/Long/Double where appropriate Modified Paths: -------------- trunk/jython/src/org/python/core/PyString.java trunk/jython/src/org/python/modules/_sre.java trunk/jython/src/org/python/modules/jffi/Util.java trunk/jython/src/org/python/modules/math.java trunk/jython/src/org/python/modules/struct.java Modified: trunk/jython/src/org/python/core/PyString.java =================================================================== --- trunk/jython/src/org/python/core/PyString.java 2010-04-09 04:40:52 UTC (rev 7008) +++ trunk/jython/src/org/python/core/PyString.java 2010-04-09 05:06:08 UTC (rev 7009) @@ -2714,36 +2714,13 @@ return s; } - private String formatFloatDecimal(PyObject arg, boolean truncate) { - PyFloat argAsFloat; - if (arg instanceof PyFloat) { - // Fast path - argAsFloat = (PyFloat)arg; - } else { - // Use __float__ - if (arg instanceof PyInteger || arg instanceof PyLong) { - // Typical cases, safe to call __float__: - argAsFloat = arg.__float__(); - } else { - try { - // We can't simply call arg.__float__() because PyString implements - // it without exposing it to python (i.e, str instances has no - // __float__ attribute). So, we would support strings as arguments - // for %g format, which is forbidden by CPython tests (on - // test_format.py). - argAsFloat = (PyFloat)arg.__getattr__("__float__").__call__(); - } catch (PyException e) { - // XXX: Swallow customs AttributeError throws from __float__ methods - // No better alternative for the moment - if (e.match(Py.AttributeError)) { - throw Py.TypeError("float argument required"); + private double asDouble(PyObject obj) { + try { + return obj.asDouble(); + } catch (PyException pye) { + throw !pye.match(Py.TypeError) ? pye : Py.TypeError("float argument required"); } - throw e; } - } - } - return formatFloatDecimal(argAsFloat.getValue(), truncate); - } private String formatFloatDecimal(double v, boolean truncate) { checkPrecision("decimal"); @@ -2772,7 +2749,7 @@ boolean truncate) { StringBuilder buf = new StringBuilder(); - double v = arg.__float__().getValue(); + double v = asDouble(arg); boolean isNegative = false; if (v < 0) { v = -v; @@ -2971,10 +2948,8 @@ string = formatFloatExponential(arg, c, false); break; case 'f': - case 'F': - string = formatFloatDecimal(arg, false); -// if (altFlag && string.indexOf('.') == -1) -// string += '.'; + case 'F': + string = formatFloatDecimal(asDouble(arg), false); break; case 'g': case 'G': @@ -2983,7 +2958,7 @@ precision = 6; } - double v = arg.__float__().getValue(); + double v = asDouble(arg); int exponent = (int)ExtraMath.closeFloor(Math.log10(Math.abs(v == 0 ? 1 : v))); if (v == Double.POSITIVE_INFINITY) { string = "inf"; @@ -2991,7 +2966,7 @@ string = "-inf"; } else if (exponent >= -4 && exponent < precision) { precision -= exponent + 1; - string = formatFloatDecimal(arg, !altFlag); + string = formatFloatDecimal(v, !altFlag); // XXX: this block may be unnecessary now if (altFlag && string.indexOf('.') == -1) { Modified: trunk/jython/src/org/python/modules/_sre.java =================================================================== --- trunk/jython/src/org/python/modules/_sre.java 2010-04-09 04:40:52 UTC (rev 7008) +++ trunk/jython/src/org/python/modules/_sre.java 2010-04-09 05:06:08 UTC (rev 7009) @@ -12,60 +12,34 @@ * CNRI. Hewlett-Packard provided funding for 1.6 integration and * other compatibility work. */ - package org.python.modules; -import java.util.Iterator; -import org.python.core.Py; -import org.python.core.PyInteger; -import org.python.core.PyList; -import org.python.core.PyLong; import org.python.core.PyObject; import org.python.core.PyString; import org.python.modules.sre.PatternObject; import org.python.modules.sre.SRE_STATE; - public class _sre { public static int MAGIC = SRE_STATE.SRE_MAGIC; // workaround the fact that H, I types are unsigned, but we are not really using them as such - //XXX: May not be the right size, but I suspect it is -- see sre_compile.py + // XXX: May not be the right size, but I suspect it is -- see sre_compile.py public static int CODESIZE = 4; - public static PatternObject compile(PyString pattern, int flags, - PyObject code, int groups, - PyObject groupindex, - PyObject indexgroup) { - int[] ccode = null; - if (code instanceof PyList) { - int n = code.__len__(); - ccode = new int[n]; - int i = 0; - for (PyObject item : code.asIterable()) { - ccode[i] = (int)((PyLong)item.__long__()).getValue().longValue(); - i++; - } - } else { - throw Py.TypeError("Expected list"); + public static PatternObject compile(PyString pattern, int flags, PyObject code, int groups, + PyObject groupindex, PyObject indexgroup) { + int[] ccode = new int[code.__len__()]; + int i = 0; + for (PyObject item : code.asIterable()) { + ccode[i++] = (int)item.asLong(); } - - PatternObject po = new PatternObject(pattern, - flags, - ccode, - groups, - groupindex, - indexgroup); - return po; + return new PatternObject(pattern, flags, ccode, groups, groupindex, indexgroup); } - - public static int getcodesize() { return CODESIZE; } - public static int getlower(int ch, int flags) { return SRE_STATE.getlower(ch, flags); } Modified: trunk/jython/src/org/python/modules/jffi/Util.java =================================================================== --- trunk/jython/src/org/python/modules/jffi/Util.java 2010-04-09 04:40:52 UTC (rev 7008) +++ trunk/jython/src/org/python/modules/jffi/Util.java 2010-04-09 05:06:08 UTC (rev 7009) @@ -88,13 +88,7 @@ } public static final long int64Value(PyObject value) { - if (value instanceof PyLong) { - return ((PyLong) value).getLong(Long.MIN_VALUE, Long.MAX_VALUE); - } else if (value instanceof PyInteger) { - return value.asInt(); - } else { - return ((PyLong) value.__long__()).getLong(Long.MIN_VALUE, Long.MAX_VALUE); - } + return value.asLong(); } public static final long uint64Value(PyObject value) { Modified: trunk/jython/src/org/python/modules/math.java =================================================================== --- trunk/jython/src/org/python/modules/math.java 2010-04-09 04:40:52 UTC (rev 7008) +++ trunk/jython/src/org/python/modules/math.java 2010-04-09 05:06:08 UTC (rev 7009) @@ -53,7 +53,7 @@ } public static double floor(PyObject v) { - return floor(v.__float__().getValue()); + return floor(v.asDouble()); } public static double floor(double v) { @@ -69,7 +69,7 @@ if (v instanceof PyLong) { doubleValue = calculateLongLog((PyLong)v); } else { - doubleValue = log(v.__float__().getValue()); + doubleValue = log(v.asDouble()); } if (base != null) { return check(applyLoggedBase(doubleValue, base)); @@ -89,7 +89,7 @@ if (base instanceof PyLong) { loggedBase = calculateLongLog((PyLong)base); } else { - loggedBase = log(base.__float__().getValue()); + loggedBase = log(base.asDouble()); } return check(loggedValue / loggedBase); } @@ -103,7 +103,7 @@ } public static double sin(PyObject v) { - return sin(v.__float__().getValue()); + return sin(v.asDouble()); } public static double sin(double v) { @@ -111,7 +111,7 @@ } public static double sqrt(PyObject v) { - return sqrt(v.__float__().getValue()); + return sqrt(v.asDouble()); } public static double sqrt(double v) { @@ -129,7 +129,7 @@ if (x <= 0.0) throw Py.ValueError("math domain error"); return log10(x) + (e[0]*8.0)*log10(2.0); } - return log10(v.__float__().getValue()); + return log10(v.asDouble()); } private static double log10(double v) { Modified: trunk/jython/src/org/python/modules/struct.java =================================================================== --- trunk/jython/src/org/python/modules/struct.java 2010-04-09 04:40:52 UTC (rev 7008) +++ trunk/jython/src/org/python/modules/struct.java 2010-04-09 05:06:08 UTC (rev 7009) @@ -351,7 +351,7 @@ } double get_float(PyObject value) { - return value.__float__().getValue(); + return value.asDouble(); } @@ -1000,7 +1000,7 @@ throw Py.TypeError("pack_into takes an array arg"); // as well as a buffer, what else? } PyArray buffer = (PyArray)args[argstart]; - int offset = args[argstart + 1].__int__().asInt(); + int offset = args[argstart + 1].asInt(); ByteStream res = pack(format, f, size, argstart + 2, args); if (res.pos > buffer.__len__()) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-09 04:40:58
|
Revision: 7008 http://jython.svn.sourceforge.net/jython/?rev=7008&view=rev Author: pjenvey Date: 2010-04-09 04:40:52 +0000 (Fri, 09 Apr 2010) Log Message: ----------- accommodate __long__ returning an int Modified Paths: -------------- trunk/jython/src/org/python/core/PyObject.java Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2010-04-09 03:21:55 UTC (rev 7007) +++ trunk/jython/src/org/python/core/PyObject.java 2010-04-09 04:40:52 UTC (rev 7008) @@ -4054,7 +4054,7 @@ } throw pye; } - if (!(longObj instanceof PyLong)) { + if (!(longObj instanceof PyLong || longObj instanceof PyInteger)) { // Shouldn't happen except with buggy builtin types throw Py.TypeError("integer conversion failed"); } 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-09 03:02:02
|
Revision: 7006 http://jython.svn.sourceforge.net/jython/?rev=7006&view=rev Author: pjenvey Date: 2010-04-09 03:01:56 +0000 (Fri, 09 Apr 2010) Log Message: ----------- cleanup Modified Paths: -------------- trunk/jython/src/org/python/modules/synchronize.java Modified: trunk/jython/src/org/python/modules/synchronize.java =================================================================== --- trunk/jython/src/org/python/modules/synchronize.java 2010-04-09 02:54:17 UTC (rev 7005) +++ trunk/jython/src/org/python/modules/synchronize.java 2010-04-09 03:01:56 UTC (rev 7006) @@ -1,27 +1,31 @@ -// Copyright (c) Corporation for National Research Initiatives +/* + * Copyright (c) Corporation for National Research Initiatives + * Copyright (c) Jython Developers + */ package org.python.modules; -import org.python.core.*; -public class synchronize -{ +import org.python.core.__builtin__; +import org.python.core.PyDictionary; +import org.python.core.PyObject; +import org.python.core.PyMethod; +import org.python.core.Py; + +public class synchronize { + public static Object _getSync(PyObject obj) { return Py.tojava(obj, Object.class); } - public static PyObject apply_synchronized(PyObject sync_object, - PyObject callable, - PyObject args) - { - synchronized (_getSync(sync_object)) { + public static PyObject apply_synchronized(PyObject syncObject, PyObject callable, + PyObject args) { + synchronized (_getSync(syncObject)) { + return __builtin__.apply(callable, args); } } - public static PyObject apply_synchronized(PyObject sync_object, - PyObject callable, - PyObject args, - PyDictionary kws) - { - synchronized (_getSync(sync_object)) { + public static PyObject apply_synchronized(PyObject syncObject, PyObject callable, + PyObject args, PyDictionary kws) { + synchronized (_getSync(syncObject)) { return __builtin__.apply(callable, args, kws); } } @@ -30,58 +34,60 @@ return new SynchronizedCallable(callable); } - public static class SynchronizedCallable extends PyObject - { + public static class SynchronizedCallable extends PyObject { + PyObject callable; public SynchronizedCallable(PyObject callable) { this.callable = callable; } - public PyObject _doget(PyObject container) { - // TBD: third arg == null? Hmm... - return new PyMethod(this, container, null); + @Override + public PyObject __get__(PyObject obj, PyObject type) { + return new PyMethod(this, obj, type); } + @Override public PyObject __call__() { throw Py.TypeError("synchronized callable called with 0 args"); } + @Override public PyObject __call__(PyObject arg) { - synchronized(synchronize._getSync(arg)) { + synchronized (synchronize._getSync(arg)) { return callable.__call__(arg); } } + @Override public PyObject __call__(PyObject arg1, PyObject arg2) { - synchronized(synchronize._getSync(arg1)) { + synchronized (synchronize._getSync(arg1)) { return callable.__call__(arg1, arg2); } } + @Override public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) { - synchronized(synchronize._getSync(arg1)) { + synchronized (synchronize._getSync(arg1)) { return callable.__call__(arg1, arg2, arg3); } } + @Override public PyObject __call__(PyObject[] args, String[] keywords) { if (args.length == 0) { throw Py.TypeError("synchronized callable called with 0 args"); } - synchronized(synchronize._getSync(args[0])) { + synchronized (synchronize._getSync(args[0])) { return callable.__call__(args, keywords); } } - public PyObject __call__(PyObject arg1, PyObject[] args, - String[] keywords) - { - synchronized(synchronize._getSync(arg1)) { + @Override + public PyObject __call__(PyObject arg1, PyObject[] args, String[] keywords) { + synchronized (synchronize._getSync(arg1)) { return callable.__call__(arg1, args, keywords); } } - - } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-09 02:54:23
|
Revision: 7005 http://jython.svn.sourceforge.net/jython/?rev=7005&view=rev Author: pjenvey Date: 2010-04-09 02:54:17 +0000 (Fri, 09 Apr 2010) Log Message: ----------- make this SynchronizedCallable descriptor public so it can be introspected by future descriptor machinery Modified Paths: -------------- trunk/jython/src/org/python/modules/synchronize.java Modified: trunk/jython/src/org/python/modules/synchronize.java =================================================================== --- trunk/jython/src/org/python/modules/synchronize.java 2010-04-09 01:37:39 UTC (rev 7004) +++ trunk/jython/src/org/python/modules/synchronize.java 2010-04-09 02:54:17 UTC (rev 7005) @@ -2,61 +2,6 @@ package org.python.modules; import org.python.core.*; -class SynchronizedCallable extends PyObject -{ - PyObject callable; - - public SynchronizedCallable(PyObject callable) { - this.callable = callable; - } - - public PyObject _doget(PyObject container) { - // TBD: third arg == null? Hmm... - return new PyMethod(this, container, null); - } - - public PyObject __call__() { - throw Py.TypeError("synchronized callable called with 0 args"); - } - - public PyObject __call__(PyObject arg) { - synchronized(synchronize._getSync(arg)) { - return callable.__call__(arg); - } - } - - public PyObject __call__(PyObject arg1, PyObject arg2) { - synchronized(synchronize._getSync(arg1)) { - return callable.__call__(arg1, arg2); - } - } - - public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) { - synchronized(synchronize._getSync(arg1)) { - return callable.__call__(arg1, arg2, arg3); - } - } - - public PyObject __call__(PyObject[] args, String[] keywords) { - if (args.length == 0) { - throw Py.TypeError("synchronized callable called with 0 args"); - } - synchronized(synchronize._getSync(args[0])) { - return callable.__call__(args, keywords); - } - } - - public PyObject __call__(PyObject arg1, PyObject[] args, - String[] keywords) - { - synchronized(synchronize._getSync(arg1)) { - return callable.__call__(arg1, args, keywords); - } - } - - -} - public class synchronize { public static Object _getSync(PyObject obj) { @@ -84,4 +29,59 @@ public static PyObject make_synchronized(PyObject callable) { return new SynchronizedCallable(callable); } + + public static class SynchronizedCallable extends PyObject + { + PyObject callable; + + public SynchronizedCallable(PyObject callable) { + this.callable = callable; + } + + public PyObject _doget(PyObject container) { + // TBD: third arg == null? Hmm... + return new PyMethod(this, container, null); + } + + public PyObject __call__() { + throw Py.TypeError("synchronized callable called with 0 args"); + } + + public PyObject __call__(PyObject arg) { + synchronized(synchronize._getSync(arg)) { + return callable.__call__(arg); + } + } + + public PyObject __call__(PyObject arg1, PyObject arg2) { + synchronized(synchronize._getSync(arg1)) { + return callable.__call__(arg1, arg2); + } + } + + public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) { + synchronized(synchronize._getSync(arg1)) { + return callable.__call__(arg1, arg2, arg3); + } + } + + public PyObject __call__(PyObject[] args, String[] keywords) { + if (args.length == 0) { + throw Py.TypeError("synchronized callable called with 0 args"); + } + synchronized(synchronize._getSync(args[0])) { + return callable.__call__(args, keywords); + } + } + + public PyObject __call__(PyObject arg1, PyObject[] args, + String[] keywords) + { + synchronized(synchronize._getSync(arg1)) { + return callable.__call__(arg1, args, keywords); + } + } + + + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-09 01:37:45
|
Revision: 7004 http://jython.svn.sourceforge.net/jython/?rev=7004&view=rev Author: pjenvey Date: 2010-04-09 01:37:39 +0000 (Fri, 09 Apr 2010) Log Message: ----------- set needs_userdict on builtin types so their subclasses know not to need their own dict descriptor Modified Paths: -------------- trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2010-04-09 01:32:44 UTC (rev 7003) +++ trunk/jython/src/org/python/core/PyType.java 2010-04-09 01:37:39 UTC (rev 7004) @@ -496,6 +496,7 @@ dict.__setitem__("__doc__", docObj); } setIsBaseType(builder.getIsBaseType()); + needs_userdict = dict.__finditem__("__dict__") != null; instantiable = dict.__finditem__("__new__") != null; fillHasSetAndDelete(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-09 01:32:50
|
Revision: 7003 http://jython.svn.sourceforge.net/jython/?rev=7003&view=rev Author: pjenvey Date: 2010-04-09 01:32:44 +0000 (Fri, 09 Apr 2010) Log Message: ----------- workaround harmless failure on FreeBSD Modified Paths: -------------- trunk/jython/Lib/test/test_socket.py Modified: trunk/jython/Lib/test/test_socket.py =================================================================== --- trunk/jython/Lib/test/test_socket.py 2010-04-06 02:02:34 UTC (rev 7002) +++ trunk/jython/Lib/test/test_socket.py 2010-04-09 01:32:44 UTC (rev 7003) @@ -354,7 +354,7 @@ # I've ordered this by protocols that have both a tcp and udp # protocol, at least for modern Linuxes. if sys.platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6', - 'darwin'): + 'darwin') or is_bsd: # avoid the 'echo' service on this platform, as there is an # assumption breaking non-standard port/protocol entry services = ('daytime', 'qotd', 'domain') 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-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-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-04 00:17:05
|
Revision: 6999 http://jython.svn.sourceforge.net/jython/?rev=6999&view=rev Author: pjenvey Date: 2010-04-04 00:16:58 +0000 (Sun, 04 Apr 2010) Log Message: ----------- os.popen files should use text mode fixes #1566 Modified Paths: -------------- trunk/jython/Lib/os.py trunk/jython/NEWS Modified: trunk/jython/Lib/os.py =================================================================== --- trunk/jython/Lib/os.py 2010-04-02 16:15:48 UTC (rev 6998) +++ trunk/jython/Lib/os.py 2010-04-04 00:16:58 UTC (rev 6999) @@ -678,11 +678,14 @@ if mode == 'r': proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True, stdout=subprocess.PIPE) - return _wrap_close(proc.stdout, proc) + fp = proc.stdout elif mode == 'w': proc = subprocess.Popen(cmd, bufsize=bufsize, shell=True, stdin=subprocess.PIPE) - return _wrap_close(proc.stdin, proc) + fp = proc.stdin + # files from subprocess are in binary mode but popen needs text mode + fp = fdopen(fp.fileno(), mode, bufsize) + return _wrap_close(fp, proc) # Helper for popen() -- a proxy for a file whose close waits for the process class _wrap_close(object): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-02 16:15:48 UTC (rev 6998) +++ trunk/jython/NEWS 2010-04-04 00:16:58 UTC (rev 6999) @@ -21,6 +21,7 @@ - [ 1548 ] Parentheses in CLASSPATH cause errors in jython.bat - [ 1576 ] files opened in 'a+' mode not readable - [ 1563 ] unicode() for Java objects working differently in 2.2 and 2.5 + - [ 1566 ] os.popen(cmd).read() returns `\r\n` as newline on Windows with Jython 2.5 - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nr...@us...> - 2010-04-02 16:15:54
|
Revision: 6998 http://jython.svn.sourceforge.net/jython/?rev=6998&view=rev Author: nriley Date: 2010-04-02 16:15:48 +0000 (Fri, 02 Apr 2010) Log Message: ----------- Invalid and redundant regex anchor causes some systems to output a warning. Fixes #1588; thanks, Richard Shaffer. Modified Paths: -------------- trunk/jython/src/shell/jython Modified: trunk/jython/src/shell/jython =================================================================== --- trunk/jython/src/shell/jython 2010-04-02 01:56:15 UTC (rev 6997) +++ trunk/jython/src/shell/jython 2010-04-02 16:15:48 UTC (rev 6998) @@ -29,7 +29,7 @@ ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '.*/.*' > /dev/null; then - if expr "$link" : '^/' > /dev/null; then + if expr "$link" : '/' > /dev/null; then PRG="$link" else PRG="`dirname ${PRG}`/${link}" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-02 01:56:21
|
Revision: 6997 http://jython.svn.sourceforge.net/jython/?rev=6997&view=rev Author: pjenvey Date: 2010-04-02 01:56:15 +0000 (Fri, 02 Apr 2010) Log Message: ----------- better fix for #1583 with the changed unicode handling Modified Paths: -------------- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-02 01:42:07 UTC (rev 6996) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-02 01:56:15 UTC (rev 6997) @@ -185,10 +185,11 @@ self._cont_handler.startPrefixMapping(prefix, uri) def characters(self, char, start, len): - self._cont_handler.characters(String(char, start, len).getBytes('utf-8').tostring().decode('utf-8')) + self._cont_handler.characters(unicode(String(char, start, len))) def ignorableWhitespace(self, char, start, len): - self._cont_handler.ignorableWhitespace(String(char, start, len).getBytes('utf-8').tostring().decode('utf-8')) + self._cont_handler.ignorableWhitespace(unicode(String(char, start, + len))) def endElement(self, uri, lname, qname): if self._namespaces: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-04-02 01:42:13
|
Revision: 6996 http://jython.svn.sourceforge.net/jython/?rev=6996&view=rev Author: pjenvey Date: 2010-04-02 01:42:07 +0000 (Fri, 02 Apr 2010) Log Message: ----------- have Java objects' __unicode__ pass-thru the result of their toString fixes #1563 Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/NEWS trunk/jython/src/org/python/core/PyJavaType.java Added Paths: ----------- trunk/jython/tests/java/org/python/tests/ToUnicode.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2010-04-01 12:07:25 UTC (rev 6995) +++ trunk/jython/Lib/test/test_java_integration.py 2010-04-02 01:42:07 UTC (rev 6996) @@ -20,7 +20,8 @@ from javax.swing.tree import TreePath from org.python.core.util import FileUtil -from org.python.tests import BeanImplementation, Child, Child2, Listenable, CustomizableMapHolder +from org.python.tests import (BeanImplementation, Child, Child2, + CustomizableMapHolder, Listenable, ToUnicode) from org.python.tests.mro import (ConfusedOnGetitemAdd, FirstPredefinedGetitem, GetitemAdder) class InstantiationTest(unittest.TestCase): @@ -478,6 +479,13 @@ unserializer = ObjectInputStream(input) self.assertEqual(date_list, unserializer.readObject()) +class UnicodeTest(unittest.TestCase): + + def test_unicode_conversion(self): + test = unicode(ToUnicode()) + self.assertEqual(type(test), unicode) + self.assertEqual(test, u"Circle is 360\u00B0") + def test_main(): test_support.run_unittest(InstantiationTest, BeanTest, @@ -493,7 +501,8 @@ JavaDelegationTest, SecurityManagerTest, JavaWrapperCustomizationTest, - SerializationTest) + SerializationTest, + UnicodeTest) if __name__ == "__main__": test_main() Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-01 12:07:25 UTC (rev 6995) +++ trunk/jython/NEWS 2010-04-02 01:42:07 UTC (rev 6996) @@ -20,6 +20,7 @@ - [ 1426 ] JSR 223 Bindings changes not taking effect and leaking between threads; unnecessary synchronization - [ 1548 ] Parentheses in CLASSPATH cause errors in jython.bat - [ 1576 ] files opened in 'a+' mode not readable + - [ 1563 ] unicode() for Java objects working differently in 2.2 and 2.5 - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2010-04-01 12:07:25 UTC (rev 6995) +++ trunk/jython/src/org/python/core/PyJavaType.java 2010-04-02 01:42:07 UTC (rev 6996) @@ -542,6 +542,12 @@ return Py.newString(self.getJavaProxy().toString()); } }); + addMethod(new PyBuiltinMethodNarrow("__unicode__") { + @Override + public PyObject __call__() { + return new PyUnicode(self.toString()); + } + }); } if(forClass == Comparable.class) { addMethod(new ComparableMethod("__lt__", 1) { Added: trunk/jython/tests/java/org/python/tests/ToUnicode.java =================================================================== --- trunk/jython/tests/java/org/python/tests/ToUnicode.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/ToUnicode.java 2010-04-02 01:42:07 UTC (rev 6996) @@ -0,0 +1,9 @@ +package org.python.tests; + +public class ToUnicode { + + @Override + public String toString() { + return "Circle is 360\u00B0"; + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-01 12:07:35
|
Revision: 6995 http://jython.svn.sourceforge.net/jython/?rev=6995&view=rev Author: amak Date: 2010-04-01 12:07:25 +0000 (Thu, 01 Apr 2010) Log Message: ----------- Some unittests for unicode usage with xml.dom.pulldom Modified Paths: -------------- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py trunk/jython/NEWS Added Paths: ----------- trunk/jython/Lib/test/test_pulldom.py Added: trunk/jython/Lib/test/test_pulldom.py =================================================================== --- trunk/jython/Lib/test/test_pulldom.py (rev 0) +++ trunk/jython/Lib/test/test_pulldom.py 2010-04-01 12:07:25 UTC (rev 6995) @@ -0,0 +1,77 @@ +""" + This is not an exhaustive pulldom test suite. + Instead, it is a place to put jython-specific tests, + relating to bugs like this one, for example. + + "xml.dom.Node.data returns bytestrings of decoded unicode" + http://bugs.jython.org/issue1583 + + amak. +""" + +import StringIO +import unittest +from xml.dom import pulldom +from test import test_support + +class UnicodeTests(unittest.TestCase): + + testDoc = """\ +<?xml version="1.0" encoding="ascii"?> +<document> + <p>Some greek: ΑΒΓΔΕ</p> + <greek attrs="ΖΗΘΙΚ"/> + <?greek ΛΜΝΞΟ?> +</document> +""" + + def setUp(self): + self.testFile = StringIO.StringIO(self.testDoc) + + def testTextNodes(self): + text = [] + for event, node in pulldom.parse(self.testFile): + if event == pulldom.CHARACTERS: + text.append(node.data) + try: + result = u"".join(text) + self.failUnlessEqual(repr(result), r"u'\n Some greek: \u0391\u0392\u0393\u0394\u0395\n \n \n'") + except Exception, x: + self.fail("Unexpected exception joining text pieces: %s" % str(x)) + + def testAttributes(self): + attrText = [] + for event, node in pulldom.parse(self.testFile): + if event == pulldom.START_ELEMENT: + for attrIx in range(node.attributes.length): + attrText.append(node.attributes.item(attrIx).value) + try: + result = u"".join(attrText) + self.failUnlessEqual(repr(result), r"u'\u0396\u0397\u0398\u0399\u039a'") + except Exception, x: + self.fail("Unexpected exception joining attribute text pieces: %s" % str(x)) + + def testProcessingInstruction(self): + piText = [] + for event, node in pulldom.parse(self.testFile): + if event == pulldom.PROCESSING_INSTRUCTION: + piText.append(node.data) + try: + result = u"".join(piText) + # Weird how the repr for PI data is different from text and char data. + # Still, the whole xml.dom.* and xml.sax.* hierarchy is rather a + # labyrinthine mess under jython, mostly because it's so old, and + # yet survived through major evolutionary changes in both jython and java. + self.failUnlessEqual(repr(result), r"u'ΛΜΝΞΟ'") + except Exception, x: + self.fail("Unexpected exception joining pi data pieces: %s" % str(x)) + +def test_main(): + tests = [ + UnicodeTests, + ] + suites = [unittest.makeSuite(klass, 'test') for klass in tests] + test_support.run_suite(unittest.TestSuite(suites)) + +if __name__ == "__main__": + test_main() Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-01 07:41:40 UTC (rev 6994) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-01 12:07:25 UTC (rev 6995) @@ -188,7 +188,7 @@ self._cont_handler.characters(String(char, start, len).getBytes('utf-8').tostring().decode('utf-8')) def ignorableWhitespace(self, char, start, len): - self._cont_handler.ignorableWhitespace(str(String(char, start, len))) + self._cont_handler.ignorableWhitespace(String(char, start, len).getBytes('utf-8').tostring().decode('utf-8')) def endElement(self, uri, lname, qname): if self._namespaces: Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-04-01 07:41:40 UTC (rev 6994) +++ trunk/jython/NEWS 2010-04-01 12:07:25 UTC (rev 6995) @@ -2,6 +2,7 @@ Jython 2.5.2a1 Bugs Fixed + - [ 1583 ] xml.dom.Node.data returns bytestrings of decoded unicode - [ 1225 ] socket.getservbyname/port() not yet supported - [ 1532 ] Cannot use docstring when defining class - [ 1530 ] BoolOp in multiple assign causes VerifyError This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-04-01 07:41:47
|
Revision: 6994 http://jython.svn.sourceforge.net/jython/?rev=6994&view=rev Author: amak Date: 2010-04-01 07:41:40 +0000 (Thu, 01 Apr 2010) Log Message: ----------- A partial fix for xml.dom.Node.data returns bytestrings of decoded unicode http://bugs.jython.org/issue1583 Modified Paths: -------------- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py trunk/jython/NEWS Modified: trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py =================================================================== --- trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-03-29 17:17:18 UTC (rev 6993) +++ trunk/jython/Lib/xml/sax/drivers2/drv_javasax.py 2010-04-01 07:41:40 UTC (rev 6994) @@ -185,7 +185,7 @@ self._cont_handler.startPrefixMapping(prefix, uri) def characters(self, char, start, len): - self._cont_handler.characters(str(String(char, start, len))) + self._cont_handler.characters(String(char, start, len).getBytes('utf-8').tostring().decode('utf-8')) def ignorableWhitespace(self, char, start, len): self._cont_handler.ignorableWhitespace(str(String(char, start, len))) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-03-29 17:17:18 UTC (rev 6993) +++ trunk/jython/NEWS 2010-04-01 07:41:40 UTC (rev 6994) @@ -2,6 +2,7 @@ Jython 2.5.2a1 Bugs Fixed + - [ 1225 ] socket.getservbyname/port() not yet supported - [ 1532 ] Cannot use docstring when defining class - [ 1530 ] BoolOp in multiple assign causes VerifyError - [ 1478 ] defaultdict & weakref.WeakKeyDictionary [TypeError: first argument must be callable] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <am...@us...> - 2010-03-29 17:17:24
|
Revision: 6993 http://jython.svn.sourceforge.net/jython/?rev=6993&view=rev Author: amak Date: 2010-03-29 17:17:18 +0000 (Mon, 29 Mar 2010) Log Message: ----------- Adding support for socket.getservbyname, getservbyport and getprotobyname. Support made possible by Wayne Meissner's jnr-netdb project. http://github.com/wmeissner/jnr-netdb Many thanks to Wayne for his work. Modified Paths: -------------- trunk/jython/Lib/socket.py trunk/jython/Lib/test/test_socket.py trunk/jython/build.xml Added Paths: ----------- trunk/jython/extlibs/jnr-netdb-0.4.jar Modified: trunk/jython/Lib/socket.py =================================================================== --- trunk/jython/Lib/socket.py 2010-03-28 17:28:38 UTC (rev 6992) +++ trunk/jython/Lib/socket.py 2010-03-29 17:17:18 UTC (rev 6993) @@ -454,9 +454,9 @@ return num_bytes def _do_send_nio(self, byte_array, socket_address, flags): - byte_buf = java.nio.ByteBuffer.wrap(byte_array) - if self.jchannel.isConnected() and socket_address is None: - bytes_sent = self.jchannel.write(byte_buf) + byte_buf = java.nio.ByteBuffer.wrap(byte_array) + if self.jchannel.isConnected() and socket_address is None: + bytes_sent = self.jchannel.write(byte_buf) else: bytes_sent = self.jchannel.send(byte_buf, socket_address) return bytes_sent @@ -566,18 +566,26 @@ names, addrs = _gethostbyaddr(name) return (names[0], names, addrs) -def getservbyname(servicename, protocolname=None): - # http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4071389 - # How complex is the structure of /etc/services? - raise NotImplementedError("getservbyname not yet supported on jython.") +def getservbyname(service_name, protocol_name=None): + try: + from jnr.netdb import Service + except ImportError: + return None + return Service.getServiceByName(service_name, protocol_name).getPort() -def getservbyport(port, protocolname=None): - # Same situation as above - raise NotImplementedError("getservbyport not yet supported on jython.") +def getservbyport(port, protocol_name=None): + try: + from jnr.netdb import Service + except ImportError: + return None + return Service.getServiceByPort(port, protocol_name).getName() -def getprotobyname(protocolname=None): - # Same situation as above - raise NotImplementedError("getprotobyname not yet supported on jython.") +def getprotobyname(protocol_name=None): + try: + from jnr.netdb import Protocol + except ImportError: + return None + return Protocol.getProtocolByName(protocol_name).getProto() def _realsocket(family = AF_INET, type = SOCK_STREAM, protocol=0): assert family == AF_INET, "Only AF_INET sockets are currently supported on jython" Modified: trunk/jython/Lib/test/test_socket.py =================================================================== --- trunk/jython/Lib/test/test_socket.py 2010-03-28 17:28:38 UTC (rev 6992) +++ trunk/jython/Lib/test/test_socket.py 2010-03-29 17:17:18 UTC (rev 6993) @@ -349,7 +349,6 @@ self.assertRaises(OverflowError, func, 1L<<34) def testGetServBy(self): - if sys.platform[:4] == 'java': return # not implemented on java eq = self.assertEqual # Find one service that exists, then check all the related interfaces. # I've ordered this by protocols that have both a tcp and udp @@ -862,7 +861,7 @@ msg = self.serv.recv(len(MSG)) self.assertEqual(msg, MSG) - def _testSendAndRecv(self): + def _testSendAndRecv(self): self.cli.connect( (self.HOST, self.PORT) ) self.cli.send(MSG, 0) @@ -874,7 +873,7 @@ msg = self.serv.recv(len(MSG)) self.assertEqual(msg, MSG) - def _testSendAndRecvTimeoutMode(self): + def _testSendAndRecvTimeoutMode(self): self.cli.connect( (self.HOST, self.PORT) ) self.cli.settimeout(10) self.cli.send(MSG, 0) Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2010-03-28 17:28:38 UTC (rev 6992) +++ trunk/jython/build.xml 2010-03-29 17:17:18 UTC (rev 6993) @@ -205,6 +205,7 @@ <pathelement path="${extlibs.dir}/jffi-x86_64-SunOS.jar"/> <pathelement path="${extlibs.dir}/jffi.jar"/> <pathelement path="${extlibs.dir}/jnr-posix.jar"/> + <pathelement path="${extlibs.dir}/jnr-netdb-0.4.jar"/> </path> <available property="informix.present" classname="com.informix.jdbc.IfxDriver" classpath="${informix.jar}" /> @@ -597,6 +598,7 @@ <zipfileset src="extlibs/jffi-x86_64-SunOS.jar"/> <zipfileset src="extlibs/jffi.jar"/> <zipfileset src="extlibs/jnr-posix.jar"/> + <zipfileset src="extlibs/jnr-netdb-0.4.jar"/> <!-- <rule pattern="com.sun.jna.**" result="org.python.jna.@1"/> --> <rule pattern="org.jruby.ext.posix.**" result="org.python.posix.@1"/> <zipfileset src="extlibs/constantine.jar"/> Added: trunk/jython/extlibs/jnr-netdb-0.4.jar =================================================================== (Binary files differ) Property changes on: trunk/jython/extlibs/jnr-netdb-0.4.jar ___________________________________________________________________ Added: svn:mime-type + application/octet-stream This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2010-03-28 17:28:45
|
Revision: 6992 http://jython.svn.sourceforge.net/jython/?rev=6992&view=rev Author: otmarhumbel Date: 2010-03-28 17:28:38 +0000 (Sun, 28 Mar 2010) Log Message: ----------- add @SuppressWarnings("unchecked") Modified Paths: -------------- trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java trunk/jython/tests/java/javatests/PySetInJavaTest.java Modified: trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java =================================================================== --- trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java 2010-03-28 09:11:22 UTC (rev 6991) +++ trunk/jython/src/org/python/core/packagecache/CachedJarsPackageManager.java 2010-03-28 17:28:38 UTC (rev 6992) @@ -142,7 +142,7 @@ List<String>[] vec = zipPackages.get(packageName); if (vec == null) { - vec = new List[] { Generic.list(), Generic.list() }; + vec = createGenericStringListArray(); zipPackages.put(packageName, vec); } int access = checkAccess(zip); @@ -153,6 +153,11 @@ } } + @SuppressWarnings("unchecked") + private List<String>[] createGenericStringListArray(){ + return new List[] { Generic.list(), Generic.list() }; + } + // Extract all of the packages in a single jarfile private Map<String, String> getZipPackages(InputStream jarin) throws IOException { Map<String, List<String>[]> zipPackages = Generic.map(); Modified: trunk/jython/tests/java/javatests/PySetInJavaTest.java =================================================================== --- trunk/jython/tests/java/javatests/PySetInJavaTest.java 2010-03-28 09:11:22 UTC (rev 6991) +++ trunk/jython/tests/java/javatests/PySetInJavaTest.java 2010-03-28 17:28:38 UTC (rev 6992) @@ -10,6 +10,7 @@ public class PySetInJavaTest { + @SuppressWarnings("unchecked") public static Set<Object> createPySetContainingJavaObjects() { PySet s = new PySet(); s.add("value"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2010-03-28 09:11:29
|
Revision: 6991 http://jython.svn.sourceforge.net/jython/?rev=6991&view=rev Author: otmarhumbel Date: 2010-03-28 09:11:22 +0000 (Sun, 28 Mar 2010) Log Message: ----------- remove indexer warnings reported in hudson Modified Paths: -------------- trunk/jython/src/org/python/indexer/AstCache.java trunk/jython/src/org/python/indexer/AstConverter.java trunk/jython/src/org/python/indexer/Indexer.java Modified: trunk/jython/src/org/python/indexer/AstCache.java =================================================================== --- trunk/jython/src/org/python/indexer/AstCache.java 2010-03-28 08:21:48 UTC (rev 6990) +++ trunk/jython/src/org/python/indexer/AstCache.java 2010-03-28 09:11:22 UTC (rev 6991) @@ -175,6 +175,7 @@ } // Convert to indexer's AST. Type conversion warnings are harmless here. + @SuppressWarnings("unchecked") Object obj = ast.accept(new AstConverter()); if (!(obj instanceof NModule)) { warn("\n[warning] converted AST is not a module: " + obj); Modified: trunk/jython/src/org/python/indexer/AstConverter.java =================================================================== --- trunk/jython/src/org/python/indexer/AstConverter.java 2010-03-28 08:21:48 UTC (rev 6990) +++ trunk/jython/src/org/python/indexer/AstConverter.java 2010-03-28 09:11:22 UTC (rev 6991) @@ -215,6 +215,7 @@ List<NExceptHandler> out = new ArrayList<NExceptHandler>(in == null ? 0 : in.size()); if (in != null) { for (excepthandler e : in) { + @SuppressWarnings("unchecked") NExceptHandler nxh = (NExceptHandler)e.accept(this); if (nxh != null) { out.add(nxh); @@ -228,6 +229,7 @@ List<NNode> out = new ArrayList<NNode>(in == null ? 0 : in.size()); if (in != null) { for (expr e : in) { + @SuppressWarnings("unchecked") NNode nx = (NNode)e.accept(this); if (nx != null) { out.add(nx); @@ -241,6 +243,7 @@ List<NName> out = new ArrayList<NName>(in == null ? 0 : in.size()); if (in != null) { for (expr e : in) { + @SuppressWarnings("unchecked") NName nn = (NName)e.accept(this); if (nn != null) { out.add(nn); @@ -262,6 +265,7 @@ if (end == -1) { end = n.getCharStopIndex(); } + @SuppressWarnings("unchecked") NName nn = (NName)n.accept(this); out = new NQname(out, nn, n.getCharStartIndex(), end); } @@ -285,6 +289,7 @@ List<NNode> out = new ArrayList<NNode>(in == null ? 0 : in.size()); if (in != null) { for (stmt e : in) { + @SuppressWarnings("unchecked") NNode nx = (NNode)e.accept(this); if (nx != null) { out.add(nx); @@ -298,6 +303,7 @@ if (e == null) { return null; } + @SuppressWarnings("unchecked") Object o = e.accept(this); if (o instanceof NNode) { return (NNode)o; @@ -353,7 +359,7 @@ @Override public Object visitBoolOp(BoolOp n) throws Exception { NBoolOp.OpType op; - switch ((boolopType)n.getInternalOp()) { + switch (n.getInternalOp()) { case And: op = NBoolOp.OpType.AND; break; Modified: trunk/jython/src/org/python/indexer/Indexer.java =================================================================== --- trunk/jython/src/org/python/indexer/Indexer.java 2010-03-28 08:21:48 UTC (rev 6990) +++ trunk/jython/src/org/python/indexer/Indexer.java 2010-03-28 09:11:22 UTC (rev 6991) @@ -907,7 +907,7 @@ } public List<String> getLoadedFiles() { - List files = new ArrayList<String>(); + List<String> files = new ArrayList<String>(); for (String file : moduleTable.keySet()) { if (file.startsWith("/")) { files.add(file); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <otm...@us...> - 2010-03-28 08:21:56
|
Revision: 6990 http://jython.svn.sourceforge.net/jython/?rev=6990&view=rev Author: otmarhumbel Date: 2010-03-28 08:21:48 +0000 (Sun, 28 Mar 2010) Log Message: ----------- add google indexer (by Yin Wang and Steve Yegge) Modified Paths: -------------- trunk/jython/ACKNOWLEDGMENTS trunk/jython/NEWS trunk/jython/build.xml trunk/jython/grammar/Python.g trunk/jython/src/org/python/antlr/BaseParser.java trunk/jython/src/org/python/antlr/GrammarActions.java trunk/jython/src/org/python/antlr/PythonTree.java trunk/jython/src/org/python/antlr/ast/Attribute.java trunk/jython/src/org/python/antlr/ast/ClassDef.java trunk/jython/src/org/python/antlr/ast/FunctionDef.java trunk/jython/src/org/python/antlr/ast/Global.java trunk/jython/src/org/python/antlr/ast/ImportFrom.java trunk/jython/src/org/python/antlr/ast/Name.java trunk/jython/src/org/python/antlr/ast/alias.java trunk/jython/src/org/python/antlr/ast/arguments.java Added Paths: ----------- trunk/jython/src/org/python/antlr/AnalyzingParser.java trunk/jython/src/org/python/antlr/RecordingErrorHandler.java trunk/jython/src/org/python/indexer/ trunk/jython/src/org/python/indexer/AstCache.java trunk/jython/src/org/python/indexer/AstConverter.java trunk/jython/src/org/python/indexer/Builtins.java trunk/jython/src/org/python/indexer/Def.java trunk/jython/src/org/python/indexer/Diagnostic.java trunk/jython/src/org/python/indexer/Indexer.java trunk/jython/src/org/python/indexer/IndexingException.java trunk/jython/src/org/python/indexer/NBinding.java trunk/jython/src/org/python/indexer/Outliner.java trunk/jython/src/org/python/indexer/Ref.java trunk/jython/src/org/python/indexer/Scope.java trunk/jython/src/org/python/indexer/StyleRun.java trunk/jython/src/org/python/indexer/Util.java trunk/jython/src/org/python/indexer/ast/ trunk/jython/src/org/python/indexer/ast/BindingFinder.java trunk/jython/src/org/python/indexer/ast/DefaultNodeVisitor.java trunk/jython/src/org/python/indexer/ast/GenericNodeVisitor.java trunk/jython/src/org/python/indexer/ast/NAlias.java trunk/jython/src/org/python/indexer/ast/NAssert.java trunk/jython/src/org/python/indexer/ast/NAssign.java trunk/jython/src/org/python/indexer/ast/NAttribute.java trunk/jython/src/org/python/indexer/ast/NAugAssign.java trunk/jython/src/org/python/indexer/ast/NBinOp.java trunk/jython/src/org/python/indexer/ast/NBlock.java trunk/jython/src/org/python/indexer/ast/NBody.java trunk/jython/src/org/python/indexer/ast/NBoolOp.java trunk/jython/src/org/python/indexer/ast/NBreak.java trunk/jython/src/org/python/indexer/ast/NCall.java trunk/jython/src/org/python/indexer/ast/NClassDef.java trunk/jython/src/org/python/indexer/ast/NCompare.java trunk/jython/src/org/python/indexer/ast/NComprehension.java trunk/jython/src/org/python/indexer/ast/NContinue.java trunk/jython/src/org/python/indexer/ast/NDelete.java trunk/jython/src/org/python/indexer/ast/NDict.java trunk/jython/src/org/python/indexer/ast/NEllipsis.java trunk/jython/src/org/python/indexer/ast/NExceptHandler.java trunk/jython/src/org/python/indexer/ast/NExec.java trunk/jython/src/org/python/indexer/ast/NExprStmt.java trunk/jython/src/org/python/indexer/ast/NFor.java trunk/jython/src/org/python/indexer/ast/NFunctionDef.java trunk/jython/src/org/python/indexer/ast/NGeneratorExp.java trunk/jython/src/org/python/indexer/ast/NGlobal.java trunk/jython/src/org/python/indexer/ast/NIf.java trunk/jython/src/org/python/indexer/ast/NIfExp.java trunk/jython/src/org/python/indexer/ast/NImport.java trunk/jython/src/org/python/indexer/ast/NImportFrom.java trunk/jython/src/org/python/indexer/ast/NIndex.java trunk/jython/src/org/python/indexer/ast/NKeyword.java trunk/jython/src/org/python/indexer/ast/NLambda.java trunk/jython/src/org/python/indexer/ast/NList.java trunk/jython/src/org/python/indexer/ast/NListComp.java trunk/jython/src/org/python/indexer/ast/NModule.java trunk/jython/src/org/python/indexer/ast/NName.java trunk/jython/src/org/python/indexer/ast/NNode.java trunk/jython/src/org/python/indexer/ast/NNodeVisitor.java trunk/jython/src/org/python/indexer/ast/NNum.java trunk/jython/src/org/python/indexer/ast/NPass.java trunk/jython/src/org/python/indexer/ast/NPlaceHolder.java trunk/jython/src/org/python/indexer/ast/NPrint.java trunk/jython/src/org/python/indexer/ast/NQname.java trunk/jython/src/org/python/indexer/ast/NRaise.java trunk/jython/src/org/python/indexer/ast/NRepr.java trunk/jython/src/org/python/indexer/ast/NReturn.java trunk/jython/src/org/python/indexer/ast/NSequence.java trunk/jython/src/org/python/indexer/ast/NSlice.java trunk/jython/src/org/python/indexer/ast/NStr.java trunk/jython/src/org/python/indexer/ast/NSubscript.java trunk/jython/src/org/python/indexer/ast/NTryExcept.java trunk/jython/src/org/python/indexer/ast/NTryFinally.java trunk/jython/src/org/python/indexer/ast/NTuple.java trunk/jython/src/org/python/indexer/ast/NUnaryOp.java trunk/jython/src/org/python/indexer/ast/NUrl.java trunk/jython/src/org/python/indexer/ast/NWhile.java trunk/jython/src/org/python/indexer/ast/NWith.java trunk/jython/src/org/python/indexer/ast/NYield.java trunk/jython/src/org/python/indexer/ast/NameBinder.java trunk/jython/src/org/python/indexer/demos/ trunk/jython/src/org/python/indexer/demos/DocStringParser.java trunk/jython/src/org/python/indexer/demos/HtmlDemo.java trunk/jython/src/org/python/indexer/demos/HtmlOutline.java trunk/jython/src/org/python/indexer/demos/Linker.java trunk/jython/src/org/python/indexer/demos/StyleApplier.java trunk/jython/src/org/python/indexer/demos/Styler.java trunk/jython/src/org/python/indexer/types/ trunk/jython/src/org/python/indexer/types/NClassType.java trunk/jython/src/org/python/indexer/types/NDictType.java trunk/jython/src/org/python/indexer/types/NFuncType.java trunk/jython/src/org/python/indexer/types/NInstanceType.java trunk/jython/src/org/python/indexer/types/NListType.java trunk/jython/src/org/python/indexer/types/NModuleType.java trunk/jython/src/org/python/indexer/types/NTupleType.java trunk/jython/src/org/python/indexer/types/NType.java trunk/jython/src/org/python/indexer/types/NUnionType.java trunk/jython/src/org/python/indexer/types/NUnknownType.java trunk/jython/tests/java/org/python/indexer/ trunk/jython/tests/java/org/python/indexer/IndexerTest.java trunk/jython/tests/java/org/python/indexer/TestBase.java trunk/jython/tests/java/org/python/indexer/data/ trunk/jython/tests/java/org/python/indexer/data/__init__.py trunk/jython/tests/java/org/python/indexer/data/attr_infer.py trunk/jython/tests/java/org/python/indexer/data/callnewref.py trunk/jython/tests/java/org/python/indexer/data/class1.py trunk/jython/tests/java/org/python/indexer/data/class2.py trunk/jython/tests/java/org/python/indexer/data/classtype_builtins.py trunk/jython/tests/java/org/python/indexer/data/empty_file.py trunk/jython/tests/java/org/python/indexer/data/foo.py trunk/jython/tests/java/org/python/indexer/data/hello.py trunk/jython/tests/java/org/python/indexer/data/mod1.py trunk/jython/tests/java/org/python/indexer/data/mod2.py trunk/jython/tests/java/org/python/indexer/data/mod3.py trunk/jython/tests/java/org/python/indexer/data/pkg/ trunk/jython/tests/java/org/python/indexer/data/pkg/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/ trunk/jython/tests/java/org/python/indexer/data/pkg/animal/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/animaltest.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/ trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/ape.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/cat.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/mammal/dog.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/reptile/ trunk/jython/tests/java/org/python/indexer/data/pkg/animal/reptile/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/reptile/croc.py trunk/jython/tests/java/org/python/indexer/data/pkg/animal/reptile/snake.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/ trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/ trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/gold.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/iron.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/metal/lead.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/ trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/lapis.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/limestone.py trunk/jython/tests/java/org/python/indexer/data/pkg/mineral/stone/obsidian.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/ trunk/jython/tests/java/org/python/indexer/data/pkg/misc/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/m1.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/m2.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/m3.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/moduleA.py trunk/jython/tests/java/org/python/indexer/data/pkg/misc/moduleB.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/ trunk/jython/tests/java/org/python/indexer/data/pkg/other/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/ trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/bleu.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/blue.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/crimson.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/green.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/red.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/color/white.py trunk/jython/tests/java/org/python/indexer/data/pkg/other/force/ trunk/jython/tests/java/org/python/indexer/data/pkg/other/force/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/ trunk/jython/tests/java/org/python/indexer/data/pkg/plant/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/food/ trunk/jython/tests/java/org/python/indexer/data/pkg/plant/food/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/food/peach.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/food/tofu.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/ trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/catnip.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/rose.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/garden/weed.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/poison/ trunk/jython/tests/java/org/python/indexer/data/pkg/plant/poison/__init__.py trunk/jython/tests/java/org/python/indexer/data/pkg/plant/poison/eggplant.py trunk/jython/tests/java/org/python/indexer/data/pkg/test.py trunk/jython/tests/java/org/python/indexer/data/pkgload.py trunk/jython/tests/java/org/python/indexer/data/refs.py trunk/jython/tests/java/org/python/indexer/data/refs2.py trunk/jython/tests/java/org/python/indexer/data/test-load.txt trunk/jython/tests/java/org/python/indexer/data/test.py trunk/jython/tests/java/org/python/indexer/data/testfileload.py trunk/jython/tests/java/org/python/indexer/data/testload.py trunk/jython/tests/java/org/python/indexer/data/testsrc.txt trunk/jython/tests/java/org/python/indexer/data/yinw/ Modified: trunk/jython/ACKNOWLEDGMENTS =================================================================== --- trunk/jython/ACKNOWLEDGMENTS 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/ACKNOWLEDGMENTS 2010-03-28 08:21:48 UTC (rev 6990) @@ -34,6 +34,8 @@ Alan Kennedy contributed modjy, which bridges WSGI to the Servlet API Chris Gokey, David Syer and Finn Bock added PyServlet. + + Yin Wang and Steve Yegge contributed the static analyzer from Google (also called indexer). A huge thanks goes to all the members of the jpython/jython mailing lists. Other folks who have contributed to JPython and Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/NEWS 2010-03-28 08:21:48 UTC (rev 6990) @@ -22,6 +22,7 @@ during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects - Fix the cmath module to accept objects implementing the __float__ method + - Add google indexer (by Yin Wang and Steve Yegge) Jython 2.5.1rc3 Bugs Fixed Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/build.xml 2010-03-28 08:21:48 UTC (rev 6990) @@ -883,6 +883,7 @@ <junit fork="true" printsummary="true"> <formatter type="xml"/> <sysproperty key="python.home" value="${dist.dir}"/> + <sysproperty key="python.test.source.dir" value="${test.source.dir}"/> <classpath refid="test.classpath"/> <batchtest todir="${junit.reports}"> <fileset dir="${test.source.dir}" includes="**/*Test*.java"> @@ -893,6 +894,50 @@ </batchtest> </junit> </target> + <target name="idxtest" depends="developer-build"> + <mkdir dir="${junit.reports}"/> + <junit fork="true" printsummary="true" showoutput="true"> + <formatter type="xml"/> + <sysproperty key="python.home" value="${dist.dir}"/> + <sysproperty key="python.test.source.dir" value="${test.source.dir}"/> + <classpath refid="test.classpath"/> + <batchtest todir="${junit.reports}"> + <fileset dir="${test.source.dir}" includes="**/*Test*.java"> + <exclude name="javatests/**/*" /> + <exclude name="**/InterpTestCase.java" /> + <exclude name="org/python/antlr/**" /> + <exclude name="org/python/core/**" /> + <exclude name="org/python/expose/**" /> + <exclude name="org/python/jsr223/**" /> + <exclude name="org/python/tests/**" /> + <exclude name="org/python/util/**" /> + </fileset> + </batchtest> + </junit> + </target> + <!-- XXX: how do I share common stuff with "idxtest" target? --> + <target name="idxtest-debug" depends="developer-build"> + <mkdir dir="${junit.reports}"/> + <junit fork="true" printsummary="true"> + <formatter type="xml"/> + <sysproperty key="python.home" value="${dist.dir}"/> + <sysproperty key="python.test.source.dir" value="${test.source.dir}"/> + <classpath refid="test.classpath"/> + <jvmarg value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5000"/> + <batchtest todir="${junit.reports}"> + <fileset dir="${test.source.dir}" includes="**/*Test*.java"> + <exclude name="javatests/**/*" /> + <exclude name="**/InterpTestCase.java" /> + <exclude name="org/python/antlr/**" /> + <exclude name="org/python/core/**" /> + <exclude name="org/python/expose/**" /> + <exclude name="org/python/jsr223/**" /> + <exclude name="org/python/tests/**" /> + <exclude name="org/python/util/**" /> + </fileset> + </batchtest> + </junit> + </target> <target name="modjytest" depends="developer-build"> <ant dir="tests/modjy"> <property name="jython_home" value="${dist.dir}"/> Modified: trunk/jython/grammar/Python.g =================================================================== --- trunk/jython/grammar/Python.g 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/grammar/Python.g 2010-03-28 08:21:48 UTC (rev 6990) @@ -367,7 +367,7 @@ } | { - $etype = new Name($n1, $n1.text, expr_contextType.Load); + $etype = actions.makeNameNode($n1); } ) ; @@ -783,13 +783,16 @@ import_from : FROM (d+=DOT* dotted_name | d+=DOT+) IMPORT (STAR - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.names), + actions.makeModuleNameNode($d, $dotted_name.names), actions.makeStarAlias($STAR), actions.makeLevel($d)]) | i1=import_as_names - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.names), + actions.makeModuleNameNode($d, $dotted_name.names), actions.makeAliases($i1.atypes), actions.makeLevel($d)]) | LPAREN i2=import_as_names COMMA? RPAREN - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.names), + actions.makeModuleNameNode($d, $dotted_name.names), actions.makeAliases($i2.atypes), actions.makeLevel($d)]) ) ; @@ -811,7 +814,7 @@ } : name=NAME (AS asname=NAME)? { - $atype = new alias($name, $name.text, $asname.text); + $atype = new alias(actions.makeNameNode($name), actions.makeNameNode($asname)); } ; @@ -822,10 +825,9 @@ @after { $dotted_as_name.tree = $atype; } - - : dotted_name (AS NAME)? + : dotted_name (AS asname=NAME)? { - $atype = new alias($NAME, $dotted_name.name, $NAME.text); + $atype = new alias($dotted_name.names, actions.makeNameNode($asname)); } ; @@ -840,17 +842,17 @@ //dotted_name: NAME ('.' NAME)* dotted_name - returns [String name] + returns [List<Name> names] : NAME (DOT dn+=attr)* { - $name = actions.makeDottedText($NAME, $dn); + $names = actions.makeDottedName($NAME, $dn); } ; //global_stmt: 'global' NAME (',' NAME)* global_stmt : GLOBAL n+=NAME (COMMA n+=NAME)* - -> ^(GLOBAL<Global>[$GLOBAL, actions.makeNames($n)]) + -> ^(GLOBAL<Global>[$GLOBAL, actions.makeNames($n), actions.makeNameNodes($n)]) ; //exec_stmt: 'exec' expr ['in' test [',' test]] @@ -1522,7 +1524,7 @@ | LBRACK subscriptlist[$begin] RBRACK -> ^(LBRACK<Subscript>[$begin, actions.castExpr($tree), actions.castSlice($subscriptlist.tree), $expr::ctype]) | DOT attr - -> ^(DOT<Attribute>[$begin, actions.castExpr($tree), $attr.text, $expr::ctype]) + -> ^(DOT<Attribute>[$begin, actions.castExpr($tree), new Name($attr.tree, $attr.text, expr_contextType.Load), $expr::ctype]) ; //subscriptlist: subscript (',' subscript)* [','] @@ -1630,7 +1632,7 @@ if ($decorators.start != null) { t = $decorators.start; } - stype = new ClassDef(t, actions.cantBeNone($NAME), + stype = new ClassDef(t, actions.cantBeNoneName($NAME), actions.makeBases(actions.castExpr($testlist.tree)), actions.castStmts($suite.stypes), actions.castExprs($decorators.etypes)); Added: trunk/jython/src/org/python/antlr/AnalyzingParser.java =================================================================== --- trunk/jython/src/org/python/antlr/AnalyzingParser.java (rev 0) +++ trunk/jython/src/org/python/antlr/AnalyzingParser.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -0,0 +1,71 @@ +/** + * Copyright 2009, Google Inc. All rights reserved. + * Licensed to PSF under a Contributor Agreement. + */ +package org.python.antlr; + +import org.antlr.runtime.ANTLRFileStream; +import org.antlr.runtime.CharStream; +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.Token; +import org.python.antlr.ast.Name; +import org.python.antlr.base.mod; + +import java.util.List; + +/** + * Parser used by the indexer. + */ +public class AnalyzingParser extends BaseParser { + + public static class AnalyzerTreeAdaptor extends PythonTreeAdaptor { + /** + * Make sure a parenthesized {@link Name} expr has its start/stop bounds + * set to the bounds of the identifier. + */ + @Override + public void setTokenBoundaries(Object t, Token startToken, Token stopToken) { + //XXX: should do this for all expr types, and have a prop list on Expr + //that records all enclosing paren locations for IDE use cases. + if (!(t instanceof Name) + || startToken == null + || stopToken == null + || startToken.getType() != PythonParser.LPAREN + || stopToken.getType() != PythonParser.RPAREN) { + super.setTokenBoundaries(t, startToken, stopToken); + } + } + } + + public AnalyzingParser(CharStream stream, String filename, String encoding) { + super(stream, filename, encoding); + errorHandler = new RecordingErrorHandler(); + } + + public List<RecognitionException> getRecognitionErrors() { + return ((RecordingErrorHandler)errorHandler).errs; + } + + @Override + protected PythonParser setupParser(boolean single) { + PythonParser parser = super.setupParser(single); + parser.setTreeAdaptor(new AnalyzerTreeAdaptor()); + return parser; + } + + public static void main(String[] args) { + CharStream in = null; + try { + in = new ANTLRFileStream(args[0]); + } catch (Exception x) { + x.printStackTrace(); + } + AnalyzingParser p = new AnalyzingParser(in, args[0], "ascii"); + mod ast = p.parseModule(); + if (ast != null) { + System.out.println("parse result: \n" + ast.toStringTree()); + } else { + System.out.println("failure: \n" + p.getRecognitionErrors()); + } + } +} Modified: trunk/jython/src/org/python/antlr/BaseParser.java =================================================================== --- trunk/jython/src/org/python/antlr/BaseParser.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/BaseParser.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -31,7 +31,7 @@ this.errorHandler = eh; } - private PythonParser setupParser(boolean single) { + protected PythonParser setupParser(boolean single) { PythonLexer lexer = new PythonLexer(charStream); lexer.setErrorHandler(errorHandler); lexer.single = single; Modified: trunk/jython/src/org/python/antlr/GrammarActions.java =================================================================== --- trunk/jython/src/org/python/antlr/GrammarActions.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/GrammarActions.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -61,19 +61,41 @@ this.errorHandler = eh; } - String makeFromText(List dots, String name) { - StringBuffer d = new StringBuffer(); + String makeFromText(List dots, List<Name> names) { + StringBuilder d = new StringBuilder(); if (dots != null) { for (int i=0;i<dots.size();i++) { d.append("."); } } - if (name != null) { - d.append(name); - } + d.append(PythonTree.dottedNameListToString(names)); return d.toString(); } + List<Name> makeModuleNameNode(List dots, List<Name> names) { + List<Name> result = new ArrayList<Name>(); + if (dots != null) { + for (Object o : dots) { + Token tok = (Token)o; + result.add(new Name(tok, tok.getText(), expr_contextType.Load)); + } + } + result.addAll(names); + return result; + } + + List<Name> makeDottedName(Token top, List<PythonTree> attrs) { + List<Name> result = new ArrayList<Name>(); + result.add(new Name(top, top.getText(), expr_contextType.Load)); + if (attrs != null) { + for (PythonTree attr : attrs) { + Token token = attr.getToken(); + result.add(new Name(token, token.getText(), expr_contextType.Load)); + } + } + return result; + } + int makeLevel(List lev) { if (lev == null) { return 0; @@ -113,6 +135,21 @@ return s; } + Name makeNameNode(Token t) { + if (t == null) { + return null; + } + return new Name(t, t.getText(), expr_contextType.Load); + } + + List<Name> makeNameNodes(List<Token> names) { + List<Name> s = new ArrayList<Name>(); + for (int i=0; i<names.size(); i++) { + s.add(makeNameNode(names.get(i))); + } + return s; + } + void errorGenExpNotSoleArg(PythonTree t) { errorHandler.error("Generator expression must be parenthesized if not sole argument", t); } @@ -191,7 +228,7 @@ expr current = new Name(nameToken, nameToken.getText(), expr_contextType.Load); for (Object o: attrs) { Token t = (Token)o; - current = new Attribute(t, current, t.getText(), + current = new Attribute(t, current, cantBeNoneName(t), expr_contextType.Load); } return current; @@ -236,21 +273,21 @@ List<stmt> f = castStmts(finBody); return new TryFinally(t, b, f); } - + stmt makeFuncdef(Token t, Token nameToken, arguments args, List funcStatements, List decorators) { if (nameToken == null) { return errorHandler.errorStmt(new PythonTree(t)); } - cantBeNone(nameToken); + Name n = cantBeNoneName(nameToken); arguments a; if (args != null) { a = args; } else { - a = new arguments(t, new ArrayList<expr>(), null, null, new ArrayList<expr>()); + a = new arguments(t, new ArrayList<expr>(), (Name)null, null, new ArrayList<expr>()); } List<stmt> s = castStmts(funcStatements); List<expr> d = castExprs(decorators); - return new FunctionDef(t, nameToken.getText(), a, s, d); + return new FunctionDef(t, n, a, s, d); } List<expr> makeAssignTargets(expr lhs, List rhs) { @@ -293,17 +330,17 @@ List<expr> p = castExprs(params); List<expr> d = castExprs(defaults); - String s; - String k; + Name s; + Name k; if (snameToken == null) { s = null; } else { - s = cantBeNone(snameToken); + s = cantBeNoneName(snameToken); } if (knameToken == null) { k = null; } else { - k = cantBeNone(knameToken); + k = cantBeNoneName(knameToken); } return new arguments(t, p, s, k, d); } @@ -516,6 +553,13 @@ return t.getText(); } + Name cantBeNoneName(Token t) { + if (t == null || t.getText().equals("None")) { + errorHandler.error("can't be None", new PythonTree(t)); + } + return new Name(t, t.getText(), expr_contextType.Load); + } + void cantBeNone(PythonTree e) { if (e.getText().equals("None")) { errorHandler.error("can't be None", e); @@ -722,18 +766,4 @@ } return s; } - - public String makeDottedText(Token name, List<PythonTree> c) { - final String dot = "."; - if (c == null || c.isEmpty()) { - return name.getText(); - } - StringBuilder b = new StringBuilder(name.getText()); - for (PythonTree t : c) { - b.append(dot); - b.append(t.getToken().getText()); - } - return b.toString(); - } - } Modified: trunk/jython/src/org/python/antlr/PythonTree.java =================================================================== --- trunk/jython/src/org/python/antlr/PythonTree.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/PythonTree.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -5,6 +5,7 @@ import org.antlr.runtime.tree.CommonTree; import org.python.core.PyType; +import org.python.antlr.ast.Name; import org.python.antlr.ast.VisitorIF; import java.util.ArrayList; @@ -165,6 +166,35 @@ node.setChildIndex(index); } + /** + * Converts a list of Name to a dotted-name string. + * Because leading dots are indexable identifiers (referring + * to parent directories in relative imports), a Name list + * may include leading dots, but not dots between names. + */ + public static String dottedNameListToString(List<Name> names) { + if (names == null) { + return ""; + } + StringBuilder sb = new StringBuilder(); + boolean leadingDot = true; + for (int i = 0, len = names.size(); i < len; i++) { + Name name = names.get(i); + String id = name.getInternalId(); + if (id == null) { + continue; + } + if (!".".equals(id)) { + leadingDot = false; + } + sb.append(id); + if (i < len - 1 && !leadingDot) { + sb.append("."); + } + } + return sb.toString(); + } + @Override public String toString() { if (isNil()) { Added: trunk/jython/src/org/python/antlr/RecordingErrorHandler.java =================================================================== --- trunk/jython/src/org/python/antlr/RecordingErrorHandler.java (rev 0) +++ trunk/jython/src/org/python/antlr/RecordingErrorHandler.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -0,0 +1,69 @@ +/** + * Copyright 2009, Google Inc. All rights reserved. + * Licensed to PSF under a Contributor Agreement. + */ +package org.python.antlr; + +import org.antlr.runtime.BaseRecognizer; +import org.antlr.runtime.BitSet; +import org.antlr.runtime.IntStream; +import org.antlr.runtime.Lexer; +import org.antlr.runtime.RecognitionException; +import org.python.antlr.ast.ErrorExpr; +import org.python.antlr.ast.ErrorMod; +import org.python.antlr.ast.ErrorSlice; +import org.python.antlr.ast.ErrorStmt; +import org.python.antlr.base.expr; +import org.python.antlr.base.mod; +import org.python.antlr.base.slice; +import org.python.antlr.base.stmt; + +import java.util.ArrayList; +import java.util.List; + +public class RecordingErrorHandler implements ErrorHandler { + + public List<RecognitionException> errs = new ArrayList<RecognitionException>(); + + public void reportError(BaseRecognizer br, RecognitionException re) { + br.reportError(re); + errs.add(re); + } + + public void recover(Lexer lex, RecognitionException re) { + lex.recover(re); + } + + public void recover(BaseRecognizer br, IntStream input, RecognitionException re) { + br.recover(input, re); + } + + public boolean mismatch(BaseRecognizer br, IntStream input, int ttype, BitSet follow) { + return true; + } + + public Object recoverFromMismatchedToken(BaseRecognizer br, IntStream input, + int ttype, BitSet follow) { + return null; + } + + public expr errorExpr(PythonTree t) { + return new ErrorExpr(t); + } + + public mod errorMod(PythonTree t) { + return new ErrorMod(t); + } + + public slice errorSlice(PythonTree t) { + return new ErrorSlice(t); + } + + public stmt errorStmt(PythonTree t) { + return new ErrorStmt(t); + } + + public void error(String message, PythonTree t) { + System.err.println(message); + } +} Modified: trunk/jython/src/org/python/antlr/ast/Attribute.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/Attribute.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/Attribute.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -45,6 +45,10 @@ public String getInternalAttr() { return attr; } + private Name attrName; + public Name getInternalAttrName() { + return attrName; + } @ExposedGet(name = "attr") public PyObject getAttr() { if (attr == null) return Py.None; @@ -119,6 +123,24 @@ this.ctx = ctx; } + public Attribute(Token token, expr value, Name attr, expr_contextType ctx) { + super(token); + this.value = value; + addChild(value); + this.attr = attr.getText(); + this.attrName = attr; + this.ctx = ctx; + } + + public Attribute(Integer ttype, Token token, expr value, Name attr, expr_contextType ctx) { + super(ttype, token); + this.value = value; + addChild(value); + this.attr = attr.getText(); + this.attrName = attr; + this.ctx = ctx; + } + public Attribute(Integer ttype, Token token, expr value, String attr, expr_contextType ctx) { super(ttype, token); this.value = value; Modified: trunk/jython/src/org/python/antlr/ast/ClassDef.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/ClassDef.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/ClassDef.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -32,6 +32,10 @@ public String getInternalName() { return name; } + private Name nameNode; + public Name getInternalNameNode() { + return nameNode; + } @ExposedGet(name = "name") public PyObject getName() { if (name == null) return Py.None; @@ -154,6 +158,34 @@ } } + public ClassDef(Token token, Name name, java.util.List<expr> bases, java.util.List<stmt> + body, java.util.List<expr> decorator_list) { + super(token); + this.name = name.getText(); + this.nameNode = name; + this.bases = bases; + if (bases == null) { + this.bases = new ArrayList<expr>(); + } + for(PythonTree t : this.bases) { + addChild(t); + } + this.body = body; + if (body == null) { + this.body = new ArrayList<stmt>(); + } + for(PythonTree t : this.body) { + addChild(t); + } + this.decorator_list = decorator_list; + if (decorator_list == null) { + this.decorator_list = new ArrayList<expr>(); + } + for(PythonTree t : this.decorator_list) { + addChild(t); + } + } + public ClassDef(Integer ttype, Token token, String name, java.util.List<expr> bases, java.util.List<stmt> body, java.util.List<expr> decorator_list) { super(ttype, token); Modified: trunk/jython/src/org/python/antlr/ast/FunctionDef.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/FunctionDef.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/FunctionDef.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -32,6 +32,10 @@ public String getInternalName() { return name; } + private Name nameNode; + public Name getInternalNameNode() { + return nameNode; + } @ExposedGet(name = "name") public PyObject getName() { if (name == null) return Py.None; @@ -148,6 +152,28 @@ } } + public FunctionDef(Token token, Name name, arguments args, java.util.List<stmt> body, + java.util.List<expr> decorator_list) { + super(token); + this.name = name.getText(); + this.nameNode = name; + this.args = args; + this.body = body; + if (body == null) { + this.body = new ArrayList<stmt>(); + } + for(PythonTree t : this.body) { + addChild(t); + } + this.decorator_list = decorator_list; + if (decorator_list == null) { + this.decorator_list = new ArrayList<expr>(); + } + for(PythonTree t : this.decorator_list) { + addChild(t); + } + } + public FunctionDef(Integer ttype, Token token, String name, arguments args, java.util.List<stmt> body, java.util.List<expr> decorator_list) { super(ttype, token); Modified: trunk/jython/src/org/python/antlr/ast/Global.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/Global.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/Global.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -40,8 +40,11 @@ public void setNames(PyObject names) { this.names = AstAdapters.py2identifierList(names); } + private java.util.List<Name> nameNodes; + public java.util.List<Name> getInternalNameNodes() { + return nameNodes; + } - private final static PyString[] fields = new PyString[] {new PyString("names")}; @ExposedGet(name = "_fields") @@ -85,6 +88,12 @@ this.names = names; } + public Global(Integer ttype, Token token, java.util.List<String> names, java.util.List<Name> nameNodes) { + super(ttype, token); + this.names = names; + this.nameNodes = nameNodes; + } + public Global(Integer ttype, Token token, java.util.List<String> names) { super(ttype, token); this.names = names; Modified: trunk/jython/src/org/python/antlr/ast/ImportFrom.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/ImportFrom.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/ImportFrom.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -1,4 +1,4 @@ -// Autogenerated AST node +// Autogenerated AST node -*- c-basic-offset:4 -*- package org.python.antlr.ast; import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; @@ -24,6 +24,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.List; @ExposedType(name = "_ast.ImportFrom", base = AST.class) public class ImportFrom extends stmt { @@ -42,8 +43,8 @@ this.module = AstAdapters.py2identifier(module); } - private java.util.List<alias> names; - public java.util.List<alias> getInternalNames() { + private List<alias> names; + public List<alias> getInternalNames() { return names; } @ExposedGet(name = "names") @@ -55,6 +56,11 @@ this.names = AstAdapters.py2aliasList(names); } + private List<Name> moduleNames; + public List<Name> getInternalModuleNames() { + return moduleNames; + } + private Integer level; public Integer getInternalLevel() { return level; @@ -111,8 +117,10 @@ setLevel(level); } - public ImportFrom(Token token, String module, java.util.List<alias> names, Integer level) { - super(token); + public ImportFrom(int ttype, Token token, + String module, List<Name> moduleNames, + List<alias> names, Integer level) { + super(ttype, token); this.module = module; this.names = names; if (names == null) { @@ -121,10 +129,17 @@ for(PythonTree t : this.names) { addChild(t); } + this.moduleNames = moduleNames; + if (moduleNames == null) { + this.moduleNames = new ArrayList<Name>(); + } + for(PythonTree t : this.moduleNames) { + addChild(t); + } this.level = level; } - public ImportFrom(Integer ttype, Token token, String module, java.util.List<alias> names, + public ImportFrom(Integer ttype, Token token, String module, List<alias> names, Integer level) { super(ttype, token); this.module = module; @@ -138,7 +153,7 @@ this.level = level; } - public ImportFrom(PythonTree tree, String module, java.util.List<alias> names, Integer level) { + public ImportFrom(PythonTree tree, String module, List<alias> names, Integer level) { super(tree); this.module = module; this.names = names; Modified: trunk/jython/src/org/python/antlr/ast/Name.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/Name.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/Name.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -1,4 +1,4 @@ -// Autogenerated AST node +// Autogenerated AST node -*- c-basic-offset:4 -*- package org.python.antlr.ast; import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; @@ -55,7 +55,6 @@ this.ctx = AstAdapters.py2expr_context(ctx); } - private final static PyString[] fields = new PyString[] {new PyString("id"), new PyString("ctx")}; @ExposedGet(name = "_fields") Modified: trunk/jython/src/org/python/antlr/ast/alias.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/alias.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/alias.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -42,6 +42,10 @@ this.name = AstAdapters.py2identifier(name); } + private java.util.List<Name> nameNodes; + public java.util.List<Name> getInternalNameNodes() { + return nameNodes; + } private String asname; public String getInternalAsname() { return asname; @@ -56,6 +60,10 @@ this.asname = AstAdapters.py2identifier(asname); } + private Name asnameNode; + public Name getInternalAsnameNode() { + return asnameNode; + } private final static PyString[] fields = new PyString[] {new PyString("name"), new PyString("asname")}; @@ -92,6 +100,21 @@ this.asname = asname; } + // [import] name [as asname] + public alias(Name name, Name asname) { + this(java.util.Arrays.asList(new Name[]{name}), asname); + } + + // [import] ...foo.bar.baz [as asname] + public alias(java.util.List<Name> nameNodes, Name asname) { + this.nameNodes = nameNodes; + this.name = dottedNameListToString(nameNodes); + if (asname != null) { + this.asnameNode = asname; + this.asname = asname.getInternalId(); + } + } + public alias(Integer ttype, Token token, String name, String asname) { super(ttype, token); this.name = name; Modified: trunk/jython/src/org/python/antlr/ast/arguments.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/arguments.java 2010-03-28 04:12:27 UTC (rev 6989) +++ trunk/jython/src/org/python/antlr/ast/arguments.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -45,6 +45,12 @@ public String getInternalVararg() { return vararg; } + + private Name varargName; + public Name getInternalVarargName() { + return varargName; + } + @ExposedGet(name = "vararg") public PyObject getVararg() { if (vararg == null) return Py.None; @@ -59,6 +65,12 @@ public String getInternalKwarg() { return kwarg; } + + private Name kwargName; + public Name getInternalKwargName() { + return kwargName; + } + @ExposedGet(name = "kwarg") public PyObject getKwarg() { if (kwarg == null) return Py.None; @@ -117,8 +129,29 @@ setDefaults(defaults); } - public arguments(Token token, java.util.List<expr> args, String vararg, String kwarg, - java.util.List<expr> defaults) { + // public arguments(Token token, java.util.List<expr> args, String vararg, String kwarg, + // java.util.List<expr> defaults) { + // super(token); + // this.args = args; + // if (args == null) { + // this.args = new ArrayList<expr>(); + // } + // for(PythonTree t : this.args) { + // addChild(t); + // } + // this.vararg = vararg; + // this.kwarg = kwarg; + // this.defaults = defaults; + // if (defaults == null) { + // this.defaults = new ArrayList<expr>(); + // } + // for(PythonTree t : this.defaults) { + // addChild(t); + // } + // } + + public arguments(Token token, java.util.List<expr> args, Name vararg, Name kwarg, + java.util.List<expr> defaults) { super(token); this.args = args; if (args == null) { @@ -127,8 +160,10 @@ for(PythonTree t : this.args) { addChild(t); } - this.vararg = vararg; - this.kwarg = kwarg; + this.vararg = vararg == null ? null : vararg.getText(); + this.varargName = vararg; + this.kwarg = kwarg == null ? null : kwarg.getText(); + this.kwargName = kwarg; this.defaults = defaults; if (defaults == null) { this.defaults = new ArrayList<expr>(); Added: trunk/jython/src/org/python/indexer/AstCache.java =================================================================== --- trunk/jython/src/org/python/indexer/AstCache.java (rev 0) +++ trunk/jython/src/org/python/indexer/AstCache.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -0,0 +1,325 @@ +/** + * Copyright 2009, Google Inc. All rights reserved. + * Licensed to PSF under a Contributor Agreement. + */ +package org.python.indexer; + +import org.antlr.runtime.ANTLRFileStream; +import org.antlr.runtime.ANTLRStringStream; +import org.antlr.runtime.CharStream; +import org.antlr.runtime.RecognitionException; +import org.python.antlr.AnalyzingParser; +import org.python.antlr.base.mod; +import org.python.indexer.ast.NModule; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Provides a factory for python source ASTs. Maintains configurable on-disk and + * in-memory caches to avoid re-parsing files during analysis. + */ +public class AstCache { + + public static final String CACHE_DIR = Util.getSystemTempDir() + "jython/ast_cache/"; + + private static final Logger LOG = Logger.getLogger(AstCache.class.getCanonicalName()); + + private Map<String, NModule> cache = new HashMap<String, NModule>(); + + private static AstCache INSTANCE; + + private AstCache() throws Exception { + File f = new File(CACHE_DIR); + if (!f.exists()) { + f.mkdirs(); + } + } + + public static AstCache get() throws Exception { + if (INSTANCE == null) { + INSTANCE = new AstCache(); + } + return INSTANCE; + } + + /** + * Clears the memory cache. + */ + public void clear() { + cache.clear(); + } + + /** + * Removes all serialized ASTs from the on-disk cache. + * @return {@code true} if all cached AST files were removed + */ + public boolean clearDiskCache() { + try { + File dir = new File(CACHE_DIR); + for (File f : dir.listFiles()) { + if (f.isFile()) { + f.delete(); + } + } + return true; + } catch (Exception x) { + severe("Failed to clear disk cache: " + x); + return false; + } + } + + /** + * Returns the syntax tree for {@code path}. May find and/or create a + * cached copy in the mem cache or the disk cache. + * @param path absolute path to a source file + * @return the AST, or {@code null} if the parse failed for any reason + * @throws Exception if anything unexpected occurs + */ + public NModule getAST(String path) throws Exception { + if (path == null) throw new IllegalArgumentException("null path"); + return fetch(path); + } + + /** + * Returns the syntax tree for {@code path} with {@code contents}. + * Uses the memory cache but not the disk cache. + * This method exists primarily for unit testing. + * @param path a name for the file. Can be relative. + * @param contents the source to parse + */ + public NModule getAST(String path, String contents) throws Exception { + if (path == null) throw new IllegalArgumentException("null path"); + if (contents == null) throw new IllegalArgumentException("null contents"); + + // Cache stores null value if the parse failed. + if (cache.containsKey(path)) { + return cache.get(path); + } + + NModule mod = null; + try { + mod = parse(path, contents); + if (mod != null) { + mod.setFileAndMD5(path, Util.getMD5(contents.getBytes("UTF-8"))); + } + } finally { + cache.put(path, mod); // may be null + } + return mod; + } + + /** + * Get or create an AST for {@code path}, checking and if necessary updating + * the disk and memory caches. + * @param path absolute source path + */ + private NModule fetch(String path) throws Exception { + // Cache stores null value if the parse failed. + if (cache.containsKey(path)) { + return cache.get(path); + } + + // Might be cached on disk but not in memory. + NModule mod = getSerializedModule(path); + if (mod != null) { + fine("reusing " + path); + cache.put(path, mod); + return mod; + } + + try { + mod = parse(path); + } finally { + cache.put(path, mod); // may be null + } + + if (mod != null) { + serialize(mod); + } + + return mod; + } + + /** + * Parse a file. Does not look in the cache or cache the result. + */ + private NModule parse(String path) throws Exception { + fine("parsing " + path); + mod ast = invokeANTLR(path); + return generateAST(ast, path); + } + + /** + * Parse a string. Does not look in the cache or cache the result. + */ + private NModule parse(String path, String contents) throws Exception { + fine("parsing " + path); + mod ast = invokeANTLR(path, contents); + return generateAST(ast, path); + } + + private NModule generateAST(mod ast, String path) throws Exception { + if (ast == null) { + Indexer.idx.reportFailedAssertion("ANTLR returned NULL for " + path); + return null; + } + + // Convert to indexer's AST. Type conversion warnings are harmless here. + Object obj = ast.accept(new AstConverter()); + if (!(obj instanceof NModule)) { + warn("\n[warning] converted AST is not a module: " + obj); + return null; + } + + NModule module = (NModule)obj; + if (new File(path).canRead()) { + module.setFile(path); + } + return module; + } + + private mod invokeANTLR(String filename) { + CharStream text = null; + try { + text = new ANTLRFileStream(filename); + } catch (IOException iox) { + fine(filename + ": " + iox); + return null; + } + return invokeANTLR(text, filename); + } + + private mod invokeANTLR(String filename, String contents) { + CharStream text = new ANTLRStringStream(contents); + return invokeANTLR(text, filename); + } + + private mod invokeANTLR(CharStream text, String filename) { + AnalyzingParser p = new AnalyzingParser(text, filename, null); + mod ast = null; + try { + ast = p.parseModule(); + } catch (Exception x) { + fine("parse for " + filename + " failed: " + x); + } + recordParseErrors(filename, p.getRecognitionErrors()); + return ast; + } + + private void recordParseErrors(String path, List<RecognitionException> errs) { + if (errs.isEmpty()) { + return; + } + List<Diagnostic> diags = Indexer.idx.getParseErrs(path); + for (RecognitionException rx : errs) { + String msg = rx.line + ":" + rx.charPositionInLine + ":" + rx; + diags.add(new Diagnostic(path, Diagnostic.Type.ERROR, -1, -1, msg)); + } + } + + /** + * Each source file's AST is saved in an object file named for the MD5 + * checksum of the source file. All that is needed is the MD5, but the + * file's base name is included for ease of debugging. + */ + public String getCachePath(File sourcePath) throws Exception { + return getCachePath(Util.getMD5(sourcePath), sourcePath.getName()); + } + + public String getCachePath(String md5, String name) { + return CACHE_DIR + name + md5 + ".ast"; + } + + // package-private for testing + void serialize(NModule ast) throws Exception { + String path = getCachePath(ast.getMD5(), new File(ast.getFile()).getName()); + ObjectOutputStream oos = null; + FileOutputStream fos = null; + try { + fos = new FileOutputStream(path); + oos = new ObjectOutputStream(fos); + oos.writeObject(ast); + } finally { + if (oos != null) { + oos.close(); + } else if (fos != null) { + fos.close(); + } + } + } + + // package-private for testing + NModule getSerializedModule(String sourcePath) { + try { + File sourceFile = new File(sourcePath); + if (sourceFile == null || !sourceFile.canRead()) { + return null; + } + File cached = new File(getCachePath(sourceFile)); + if (!cached.canRead()) { + return null; + } + return deserialize(sourceFile); + } catch (Exception x) { + severe("Failed to deserialize " + sourcePath + ": " + x); + return null; + } + } + + // package-private for testing + NModule deserialize(File sourcePath) throws Exception { + String cachePath = getCachePath(sourcePath); + FileInputStream fis = null; + ObjectInputStream ois = null; + try { + fis = new FileInputStream(cachePath); + ois = new ObjectInputStream(fis); + NModule mod = (NModule)ois.readObject(); + // Files in different dirs may have the same base name and contents. + mod.setFile(sourcePath); + return mod; + } finally { + if (ois != null) { + ois.close(); + } else if (fis != null) { + fis.close(); + } + } + } + + private void log(Level level, String msg) { + if (LOG.isLoggable(level)) { + LOG.log(level, msg); + } + } + + private void severe(String msg) { + log(Level.SEVERE, msg); + } + + private void warn(String msg) { + log(Level.WARNING, msg); + } + + private void info(String msg) { + log(Level.INFO, msg); + } + + private void fine(String msg) { + log(Level.FINE, msg); + } + + private void finer(String msg) { + log(Level.FINER, msg); + } +} Added: trunk/jython/src/org/python/indexer/AstConverter.java =================================================================== --- trunk/jython/src/org/python/indexer/AstConverter.java (rev 0) +++ trunk/jython/src/org/python/indexer/AstConverter.java 2010-03-28 08:21:48 UTC (rev 6990) @@ -0,0 +1,676 @@ +/** + * Copyright 2009, Google Inc. All rights reserved. + * Licensed to PSF under a Contributor Agreement. + */ +package org.python.indexer; + +import org.python.antlr.PythonTree; +import org.python.antlr.Visitor; +import org.python.antlr.ast.Assert; +import org.python.antlr.ast.Assign; +import org.python.antlr.ast.Attribute; +import org.python.antlr.ast.AugAssign; +import org.python.antlr.ast.BinOp; +import org.python.antlr.ast.BoolOp; +import org.python.antlr.ast.Break; +import org.python.antlr.ast.Call; +import org.python.antlr.ast.ClassDef; +import org.python.antlr.ast.Compare; +import org.python.antlr.ast.Continue; +import org.python.antlr.ast.Delete; +import org.python.antlr.ast.Dict; +import org.python.antlr.ast.Ellipsis; +import org.python.antlr.ast.ExceptHandler; +import org.python.antlr.ast.Exec; +import org.python.antlr.ast.Expr; +import org.python.antlr.ast.For; +import org.python.antlr.ast.FunctionDef; +import org.python.antlr.ast.GeneratorExp; +import org.python.antlr.ast.Global; +import org.python.antlr.ast.If; +import org.python.antlr.ast.IfExp; +import org.python.antlr.ast.Import; +import org.python.antlr.ast.ImportFrom; +import org.python.antlr.ast.Index; +import org.python.antlr.ast.Lambda; +import org.python.antlr.ast.ListComp; +import org.python.antlr.ast.Module; +import org.python.antlr.ast.Name; +import org.python.antlr.ast.Num; +import org.python.antlr.ast.Pass; +import org.python.antlr.ast.Print; +import org.python.antlr.ast.Raise; +import org.python.antlr.ast.Repr; +import org.python.antlr.ast.Return; +import org.python.antlr.ast.Slice; +import org.python.antlr.ast.Str; +import org.python.antlr.ast.Subscript; +import org.python.antlr.ast.TryExcept; +import org.python.antlr.ast.TryFinally; +import org.python.antlr.ast.Tuple; +import org.python.antlr.ast.UnaryOp; +import org.python.antlr.ast.While; +import org.python.antlr.ast.With; +import org.python.antlr.ast.Yield; +import org.python.antlr.ast.alias; +import org.python.antlr.ast.arguments; +import org.python.antlr.ast.boolopType; +import org.python.antlr.ast.cmpopType; +import org.python.antlr.ast.comprehension; +import org.python.antlr.ast.keyword; +import org.python.antlr.ast.operatorType; +import org.python.antlr.ast.unaryopType; +import org.python.antlr.base.excepthandler; +import org.python.antlr.base.expr; +import org.python.antlr.base.stmt; +import org.python.indexer.ast.NAlias; +import org.python.indexer.ast.NAssert; +import org.python.indexer.ast.NAssign; +import org.python.indexer.ast.NAttribute; +import org.python.indexer.ast.NAugAssign; +import org.python.indexer.ast.NBinOp; +import org.python.indexer.ast.NBlock; +import org.python.indexer.ast.NBoolOp; +import org.python.indexer.ast.NBreak; +import org.python.indexer.ast.NCall; +import org.python.indexer.ast.NClassDef; +import org.python.indexer.ast.NCompare; +import org.python.indexer.ast.NComprehension; +import org.python.indexer.ast.NContinue; +import org.python.indexer.ast.NDelete; +import org.python.indexer.ast.NDict; +import org.python.indexer.ast.NEllipsis; +import org.python.indexer.ast.NExceptHandler; +import org.python.indexer.ast.NExec; +import org.python.indexer.ast.NFor; +import org.python.indexer.ast.NFunctionDef; +import org.python.indexer.ast.NGeneratorExp; +import org.python.indexer.ast.NGlobal; +import org.python.indexer.ast.NIf; +import org.python.indexer... [truncated message content] |
From: <pj...@us...> - 2010-03-21 21:35:20
|
Revision: 6988 http://jython.svn.sourceforge.net/jython/?rev=6988&view=rev Author: pjenvey Date: 2010-03-21 21:35:14 +0000 (Sun, 21 Mar 2010) Log Message: ----------- can't use FileOutputStreams for O_APPEND in 'a+' mode because the underlying file isn't readable fixes #1576 Modified Paths: -------------- trunk/jython/Lib/test/test_file_jy.py trunk/jython/NEWS trunk/jython/src/org/python/core/io/FileIO.java Modified: trunk/jython/Lib/test/test_file_jy.py =================================================================== --- trunk/jython/Lib/test/test_file_jy.py 2010-03-21 17:52:36 UTC (rev 6987) +++ trunk/jython/Lib/test/test_file_jy.py 2010-03-21 21:35:14 UTC (rev 6988) @@ -14,13 +14,8 @@ os.remove(test_support.TESTFN) def test_append(self): - self._test_append('ab') - - def test_appendplus(self): - self._test_append('a+') - - def _test_append(self, mode): # http://bugs.jython.org/issue1466 + mode = 'ab' fp1 = open(test_support.TESTFN, mode) fp1.write('test1\n') fp2 = open(test_support.TESTFN, mode) @@ -30,7 +25,15 @@ with open(test_support.TESTFN) as fp: self.assertEqual('test1\ntest2\n', fp.read()) + def test_appendplus(self): + # regression with the test_append fix: + # http://bugs.jython.org/issue1576 + with open(test_support.TESTFN, 'ab+') as fp: + fp.write('test1\n') + fp.seek(0) + self.assertEqual(fp.read(), 'test1\n') + def test_main(): test_support.run_unittest(FileTestCase) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-03-21 17:52:36 UTC (rev 6987) +++ trunk/jython/NEWS 2010-03-21 21:35:14 UTC (rev 6988) @@ -17,6 +17,7 @@ - [ 1511 ] PySet doesn't support Java serialization - [ 1426 ] JSR 223 Bindings changes not taking effect and leaking between threads; unnecessary synchronization - [ 1548 ] Parentheses in CLASSPATH cause errors in jython.bat + - [ 1576 ] files opened in 'a+' mode not readable - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects Modified: trunk/jython/src/org/python/core/io/FileIO.java =================================================================== --- trunk/jython/src/org/python/core/io/FileIO.java 2010-03-21 17:52:36 UTC (rev 6987) +++ trunk/jython/src/org/python/core/io/FileIO.java 2010-03-21 21:35:14 UTC (rev 6988) @@ -65,7 +65,7 @@ File absPath = new RelativeFile(name); try { - if (appending && !reading) { + if (appending && !(reading || plus)) { // Take advantage of FileOutputStream's append mode fromFileOutputStream(absPath); } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-03-21 17:52:42
|
Revision: 6987 http://jython.svn.sourceforge.net/jython/?rev=6987&view=rev Author: pjenvey Date: 2010-03-21 17:52:36 +0000 (Sun, 21 Mar 2010) Log Message: ----------- fix os.system not returning the command's exit code fixes #1577 and the test_chdir os.sytem tests patch from Alex Gr?\195?\182nholm Modified Paths: -------------- trunk/jython/src/org/python/modules/posix/PosixModule.java Modified: trunk/jython/src/org/python/modules/posix/PosixModule.java =================================================================== --- trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-03-15 01:37:30 UTC (rev 6986) +++ trunk/jython/src/org/python/modules/posix/PosixModule.java 2010-03-21 17:52:36 UTC (rev 6987) @@ -710,10 +710,10 @@ public static PyString __doc__system = new PyString( "system(command) -> exit_status\n\n" + "Execute the command (a string) in a subshell."); - public static void system(PyObject command) { - // import subprocess; subprocess.call(command, shell=True) - imp.load("subprocess").invoke("call", command, new PyObject[] {Py.True}, - new String[] {"shell"}); + public static PyObject system(PyObject command) { + // import subprocess; return subprocess.call(command, shell=True) + return imp.load("subprocess").invoke("call", command, new PyObject[] {Py.True}, + new String[] {"shell"}); } public static PyString __doc__umask = new PyString( This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-03-15 01:37:37
|
Revision: 6986 http://jython.svn.sourceforge.net/jython/?rev=6986&view=rev Author: pjenvey Date: 2010-03-15 01:37:30 +0000 (Mon, 15 Mar 2010) Log Message: ----------- coding standards, rename minLong -> MIN_LONG Modified Paths: -------------- trunk/jython/src/org/python/core/PyInteger.java trunk/jython/src/org/python/core/PyLong.java trunk/jython/src/org/python/core/PyString.java trunk/jython/src/org/python/modules/struct.java Modified: trunk/jython/src/org/python/core/PyInteger.java =================================================================== --- trunk/jython/src/org/python/core/PyInteger.java 2010-03-14 21:39:57 UTC (rev 6985) +++ trunk/jython/src/org/python/core/PyInteger.java 2010-03-15 01:37:30 UTC (rev 6986) @@ -21,11 +21,18 @@ public static final PyType TYPE = PyType.fromClass(PyInteger.class); /** The minimum value of an int represented by a BigInteger */ - public static final BigInteger minInt = BigInteger.valueOf(Integer.MIN_VALUE); + public static final BigInteger MIN_INT = BigInteger.valueOf(Integer.MIN_VALUE); /** The maximum value of an int represented by a BigInteger */ - public static final BigInteger maxInt = BigInteger.valueOf(Integer.MAX_VALUE); + public static final BigInteger MAX_INT = BigInteger.valueOf(Integer.MAX_VALUE); + /** @deprecated Use MIN_INT instead. */ + @Deprecated + public static final BigInteger minInt = MIN_INT; + /** @deprecated Use MAX_INT instead. */ + @Deprecated + public static final BigInteger maxInt = MAX_INT; + private int value; public PyInteger(PyType subType, int v) { Modified: trunk/jython/src/org/python/core/PyLong.java =================================================================== --- trunk/jython/src/org/python/core/PyLong.java 2010-03-14 21:39:57 UTC (rev 6985) +++ trunk/jython/src/org/python/core/PyLong.java 2010-03-15 01:37:30 UTC (rev 6986) @@ -21,11 +21,21 @@ public static final PyType TYPE = PyType.fromClass(PyLong.class); - public static final BigInteger minLong = BigInteger.valueOf(Long.MIN_VALUE); - public static final BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); - public static final BigInteger maxULong = + public static final BigInteger MIN_LONG = BigInteger.valueOf(Long.MIN_VALUE); + public static final BigInteger MAX_LONG = BigInteger.valueOf(Long.MAX_VALUE); + public static final BigInteger MAX_ULONG = BigInteger.valueOf(1).shiftLeft(64).subtract(BigInteger.valueOf(1)); + /** @deprecated Use MIN_INT instead. */ + @Deprecated + public static final BigInteger minLong = MIN_LONG; + /** @deprecated Use MAX_INT instead. */ + @Deprecated + public static final BigInteger maxLong = MAX_LONG; + /** @deprecated Use MAX_ULONG instead. */ + @Deprecated + public static final BigInteger maxULong = MAX_ULONG; + private BigInteger value; public PyLong(PyType subType, BigInteger v) { @@ -194,7 +204,7 @@ } public long getLong(long min, long max, String overflowMsg) { - if (value.compareTo(maxLong) <= 0 && value.compareTo(minLong) >= 0) { + if (value.compareTo(MAX_LONG) <= 0 && value.compareTo(MIN_LONG) >= 0) { long v = value.longValue(); if (v >= min && v <= max) { return v; @@ -853,7 +863,7 @@ @ExposedMethod(doc = BuiltinDocs.long___int___doc) final PyObject long___int__() { - if (value.compareTo(PyInteger.maxInt) <= 0 && value.compareTo(PyInteger.minInt) >= 0) { + if (value.compareTo(PyInteger.MAX_INT) <= 0 && value.compareTo(PyInteger.MIN_INT) >= 0) { return Py.newInteger(value.intValue()); } return long___long__(); @@ -960,8 +970,8 @@ @Override public int asIndex(PyObject err) { - boolean tooLow = value.compareTo(PyInteger.minInt) < 0; - boolean tooHigh = value.compareTo(PyInteger.maxInt) > 0; + boolean tooLow = value.compareTo(PyInteger.MIN_INT) < 0; + boolean tooHigh = value.compareTo(PyInteger.MAX_INT) > 0; if (tooLow || tooHigh) { if (err != null) { throw new PyException(err, "cannot fit 'long' into an index-sized integer"); Modified: trunk/jython/src/org/python/core/PyString.java =================================================================== --- trunk/jython/src/org/python/core/PyString.java 2010-03-14 21:39:57 UTC (rev 6985) +++ trunk/jython/src/org/python/core/PyString.java 2010-03-15 01:37:30 UTC (rev 6986) @@ -1570,7 +1570,7 @@ bi = new BigInteger("-" + s, base); } else bi = new BigInteger(s, base); - if (bi.compareTo(PyInteger.maxInt) > 0 || bi.compareTo(PyInteger.minInt) < 0) { + if (bi.compareTo(PyInteger.MAX_INT) > 0 || bi.compareTo(PyInteger.MIN_INT) < 0) { throw Py.OverflowError("long int too large to convert to int"); } return bi.intValue(); Modified: trunk/jython/src/org/python/modules/struct.java =================================================================== --- trunk/jython/src/org/python/modules/struct.java 2010-03-14 21:39:57 UTC (rev 6985) +++ trunk/jython/src/org/python/modules/struct.java 2010-03-15 01:37:30 UTC (rev 6986) @@ -342,7 +342,7 @@ BigInteger get_ulong(PyObject value) { if (value instanceof PyLong){ BigInteger v = (BigInteger)value.__tojava__(BigInteger.class); - if (v.compareTo(PyLong.maxULong) > 0){ + if (v.compareTo(PyLong.MAX_ULONG) > 0){ throw StructError("unsigned long int too long to convert"); } return v; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2010-03-14 21:40:07
|
Revision: 6985 http://jython.svn.sourceforge.net/jython/?rev=6985&view=rev Author: pjenvey Date: 2010-03-14 21:39:57 +0000 (Sun, 14 Mar 2010) Log Message: ----------- coding standards/cleanup Modified Paths: -------------- trunk/jython/src/org/python/core/PyComplex.java trunk/jython/src/org/python/core/PyFloat.java trunk/jython/src/org/python/core/PyInteger.java trunk/jython/src/org/python/core/PyLong.java Modified: trunk/jython/src/org/python/core/PyComplex.java =================================================================== --- trunk/jython/src/org/python/core/PyComplex.java 2010-03-13 17:33:14 UTC (rev 6984) +++ trunk/jython/src/org/python/core/PyComplex.java 2010-03-14 21:39:57 UTC (rev 6985) @@ -1,4 +1,7 @@ -// Copyright (c) Corporation for National Research Initiatives +/* + * Copyright (c) Corporation for National Research Initiatives + * Copyright (c) Jython Developers + */ package org.python.core; import org.python.expose.ExposedGet; @@ -15,14 +18,28 @@ public static final PyType TYPE = PyType.fromClass(PyComplex.class); + static PyComplex J = new PyComplex(0, 1.); + @ExposedGet(doc = BuiltinDocs.complex_real_doc) public double real; @ExposedGet(doc = BuiltinDocs.complex_imag_doc) public double imag; - static PyComplex J = new PyComplex(0, 1.); + public PyComplex(PyType subtype, double r, double i) { + super(subtype); + real = r; + imag = i; + } + public PyComplex(double r, double i) { + this(TYPE, r, i); + } + + public PyComplex(double r) { + this(r, 0.0); + } + @ExposedNew public static PyObject complex_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { @@ -58,7 +75,7 @@ PyComplex complexImag; PyFloat toFloat = null; if (real instanceof PyComplex) { - complexReal = (PyComplex)real; + complexReal = (PyComplex) real; } else { try { toFloat = real.__float__(); @@ -75,7 +92,7 @@ if (imag == null) { complexImag = new PyComplex(0.0); } else if (imag instanceof PyComplex) { - complexImag = (PyComplex)imag; + complexImag = (PyComplex) imag; } else { toFloat = null; try { @@ -98,20 +115,6 @@ return complexReal; } - public PyComplex(PyType subtype, double r, double i) { - super(subtype); - real = r; - imag = i; - } - - public PyComplex(double r, double i) { - this(TYPE, r, i); - } - - public PyComplex(double r) { - this(r, 0.0); - } - public final PyFloat getReal() { return Py.newFloat(real); } @@ -121,14 +124,14 @@ } public static String toString(double value) { - if (value == Math.floor(value) && - value <= Long.MAX_VALUE && value >= Long.MIN_VALUE) { - return Long.toString((long)value); + if (value == Math.floor(value) && value <= Long.MAX_VALUE && value >= Long.MIN_VALUE) { + return Long.toString((long) value); } else { return Double.toString(value); } } + @Override public String toString() { return complex_toString(); } @@ -136,16 +139,17 @@ @ExposedMethod(names = {"__repr__", "__str__"}, doc = BuiltinDocs.complex___str___doc) final String complex_toString() { if (real == 0.) { - return toString(imag)+"j"; + return toString(imag) + "j"; } else { if (imag >= 0) { - return "("+toString(real)+"+"+toString(imag)+"j)"; + return String.format("(%s+%sj)", toString(real), toString(imag)); } else { - return "("+toString(real)+"-"+toString(-imag)+"j)"; + return String.format("(%s-%sj)", toString(real), toString(-imag)); } } } + @Override public int hashCode() { return complex___hash__(); } @@ -155,12 +159,12 @@ if (imag == 0) { return new PyFloat(real).hashCode(); } else { - long v = Double.doubleToLongBits(real) ^ - Double.doubleToLongBits(imag); - return (int)v ^ (int)(v >> 32); + long v = Double.doubleToLongBits(real) ^ Double.doubleToLongBits(imag); + return (int) v ^ (int) (v >> 32); } } + @Override public boolean __nonzero__() { return complex___nonzero__(); } @@ -170,18 +174,17 @@ return real != 0 || imag != 0; } - /*public Object __tojava__(Class c) { - return super.__tojava__(c); - }*/ - + @Override public int __cmp__(PyObject other) { - if (!canCoerce(other)) + if (!canCoerce(other)) { return -2; + } PyComplex c = coerce(other); double oreal = c.real; double oimag = c.imag; - if (real == oreal && imag == oimag) + if (real == oreal && imag == oimag) { return 0; + } if (real != oreal) { return real < oreal ? -1 : 1; } else { @@ -189,42 +192,42 @@ } } - /* - * @see org.python.core.PyObject#__eq__(org.python.core.PyObject) - */ + @Override public PyObject __eq__(PyObject other) { return complex___eq__(other); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___eq___doc) final PyObject complex___eq__(PyObject other) { - if (!canCoerce(other)) + if (!canCoerce(other)) { return null; + } PyComplex c = coerce(other); return Py.newBoolean(real == c.real && imag == c.imag); } - /* - * @see org.python.core.PyObject#__ne__(org.python.core.PyObject) - */ + @Override public PyObject __ne__(PyObject other) { return complex___ne__(other); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___ne___doc) final PyObject complex___ne__(PyObject other) { - if (!canCoerce(other)) + if (!canCoerce(other)) { return null; + } PyComplex c = coerce(other); return Py.newBoolean(real != c.real || imag != c.imag); } private PyObject unsupported_comparison(PyObject other) { - if (!canCoerce(other)) + if (!canCoerce(other)) { return null; + } throw Py.TypeError("cannot compare complex numbers using <, <=, >, >="); } + @Override public PyObject __ge__(PyObject other) { return complex___ge__(other); } @@ -234,6 +237,7 @@ return unsupported_comparison(other); } + @Override public PyObject __gt__(PyObject other) { return complex___gt__(other); } @@ -243,6 +247,7 @@ return unsupported_comparison(other); } + @Override public PyObject __le__(PyObject other) { return complex___le__(other); } @@ -252,6 +257,7 @@ return unsupported_comparison(other); } + @Override public PyObject __lt__(PyObject other) { return complex___lt__(other); } @@ -261,62 +267,72 @@ return unsupported_comparison(other); } + @Override public Object __coerce_ex__(PyObject other) { return complex___coerce_ex__(other); } - + @ExposedMethod(doc = BuiltinDocs.complex___coerce___doc) final PyObject complex___coerce__(PyObject other) { return adaptToCoerceTuple(complex___coerce_ex__(other)); } - /** + /** * Coercion logic for complex. Implemented as a final method to avoid - * invocation of virtual methods from the exposed coerce. - */ + * invocation of virtual methods from the exposed coerce. + */ final PyObject complex___coerce_ex__(PyObject other) { - if (other instanceof PyComplex) + if (other instanceof PyComplex) { return other; - if (other instanceof PyFloat) - return new PyComplex(((PyFloat)other).getValue(), 0); - if (other instanceof PyInteger) - return new PyComplex(((PyInteger)other).getValue(), 0); - if (other instanceof PyLong) - return new PyComplex(((PyLong)other).doubleValue(), 0); + } + if (other instanceof PyFloat) { + return new PyComplex(((PyFloat) other).getValue(), 0); + } + if (other instanceof PyInteger) { + return new PyComplex(((PyInteger) other).getValue(), 0); + } + if (other instanceof PyLong) { + return new PyComplex(((PyLong) other).doubleValue(), 0); + } return Py.None; } private final boolean canCoerce(PyObject other) { - return other instanceof PyComplex || - other instanceof PyFloat || - other instanceof PyInteger || - other instanceof PyLong; + return other instanceof PyComplex || other instanceof PyFloat || other instanceof PyInteger + || other instanceof PyLong; } private final PyComplex coerce(PyObject other) { - if (other instanceof PyComplex) + if (other instanceof PyComplex) { return (PyComplex) other; - if (other instanceof PyFloat) - return new PyComplex(((PyFloat)other).getValue(), 0); - if (other instanceof PyInteger) - return new PyComplex(((PyInteger)other).getValue(), 0); - if (other instanceof PyLong) - return new PyComplex(((PyLong)other).doubleValue(), 0); + } + if (other instanceof PyFloat) { + return new PyComplex(((PyFloat) other).getValue(), 0); + } + if (other instanceof PyInteger) { + return new PyComplex(((PyInteger) other).getValue(), 0); + } + if (other instanceof PyLong) { + return new PyComplex(((PyLong) other).doubleValue(), 0); + } throw Py.TypeError("xxx"); } + @Override public PyObject __add__(PyObject right) { return complex___add__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___add___doc) final PyObject complex___add__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } PyComplex c = coerce(right); - return new PyComplex(real+c.real, imag+c.imag); + return new PyComplex(real + c.real, imag + c.imag); } + @Override public PyObject __radd__(PyObject left) { return complex___radd__(left); } @@ -327,55 +343,63 @@ } private final static PyObject _sub(PyComplex o1, PyComplex o2) { - return new PyComplex(o1.real-o2.real, o1.imag-o2.imag); + return new PyComplex(o1.real - o2.real, o1.imag - o2.imag); } + @Override public PyObject __sub__(PyObject right) { return complex___sub__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___sub___doc) final PyObject complex___sub__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } return _sub(this, coerce(right)); } + @Override public PyObject __rsub__(PyObject left) { return complex___rsub__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___rsub___doc) final PyObject complex___rsub__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return _sub(coerce(left), this); } private final static PyObject _mul(PyComplex o1, PyComplex o2) { - return new PyComplex(o1.real*o2.real-o1.imag*o2.imag, - o1.real*o2.imag+o1.imag*o2.real); + return new PyComplex(o1.real * o2.real - o1.imag * o2.imag, + o1.real * o2.imag + o1.imag * o2.real); } + @Override public PyObject __mul__(PyObject right) { return complex___mul__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___mul___doc) final PyObject complex___mul__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } return _mul(this, coerce(right)); } + @Override public PyObject __rmul__(PyObject left) { return complex___rmul__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___rmul___doc) final PyObject complex___rmul__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return _mul(coerce(left), this); } @@ -400,95 +424,113 @@ } } + @Override public PyObject __div__(PyObject right) { return complex___div__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___div___doc) final PyObject complex___div__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; - if (Options.divisionWarning >= 2) + } + if (Options.divisionWarning >= 2) { Py.warning(Py.DeprecationWarning, "classic complex division"); + } return _div(this, coerce(right)); } + @Override public PyObject __rdiv__(PyObject left) { return complex___rdiv__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___rdiv___doc) final PyObject complex___rdiv__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; - if (Options.divisionWarning >= 2) + } + if (Options.divisionWarning >= 2) { Py.warning(Py.DeprecationWarning, "classic complex division"); + } return _div(coerce(left), this); } + @Override public PyObject __floordiv__(PyObject right) { return complex___floordiv__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___floordiv___doc) final PyObject complex___floordiv__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } return _divmod(this, coerce(right)).__finditem__(0); } + @Override public PyObject __rfloordiv__(PyObject left) { return complex___rfloordiv__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___rfloordiv___doc) final PyObject complex___rfloordiv__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return _divmod(coerce(left), this).__finditem__(0); } + @Override public PyObject __truediv__(PyObject right) { return complex___truediv__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___truediv___doc) final PyObject complex___truediv__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } return _div(this, coerce(right)); } + @Override public PyObject __rtruediv__(PyObject left) { return complex___rtruediv__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___rtruediv___doc) final PyObject complex___rtruediv__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return _div(coerce(left), this); } + @Override public PyObject __mod__(PyObject right) { return complex___mod__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___mod___doc) final PyObject complex___mod__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } return _mod(this, coerce(right)); } + @Override public PyObject __rmod__(PyObject left) { return complex___rmod__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___rmod___doc) final PyObject complex___rmod__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return _mod(coerce(left), this); } @@ -502,25 +544,29 @@ return value.__sub__(z.__mul__(right)); } + @Override public PyObject __divmod__(PyObject right) { return complex___divmod__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___divmod___doc) final PyObject complex___divmod__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } return _divmod(this, coerce(right)); } + @Override public PyObject __rdivmod__(PyObject left) { return complex___rdivmod__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___rdivmod___doc) final PyObject complex___rdivmod__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return _divmod(coerce(left), this); } @@ -534,10 +580,11 @@ return new PyTuple(z, value.__sub__(z.__mul__(right))); } - private static PyObject ipow(PyComplex value, int iexp) { int pow = iexp; - if (pow < 0) pow = -pow; + if (pow < 0) { + pow = -pow; + } double xr = value.real; double xi = value.imag; @@ -549,25 +596,28 @@ while (pow > 0) { if ((pow & 0x1) != 0) { - tmp = zr*xr - zi*xi; - zi = zi*xr + zr*xi; + tmp = zr * xr - zi * xi; + zi = zi * xr + zr * xi; zr = tmp; } pow >>= 1; - if (pow == 0) + if (pow == 0) { break; - tmp = xr*xr - xi*xi; - xi = xr*xi*2; + } + tmp = xr * xr - xi * xi; + xi = xr * xi * 2; xr = tmp; } PyComplex ret = new PyComplex(zr, zi); - if (iexp < 0) - return new PyComplex(1,0).__div__(ret); + if (iexp < 0) { + return new PyComplex(1, 0).__div__(ret); + } return ret; } + @Override public PyObject __pow__(PyObject right, PyObject modulo) { return complex___pow__(right, modulo); } @@ -577,19 +627,22 @@ if (modulo != null) { throw Py.ValueError("complex modulo"); } - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } return _pow(this, coerce(right)); } + @Override public PyObject __rpow__(PyObject left) { return complex___rpow__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.complex___rpow___doc) final PyObject complex___rpow__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return _pow(coerce(left), this); } @@ -610,7 +663,7 @@ } // Check for integral powers - int iexp = (int)yr; + int iexp = (int) yr; if (yi == 0 && yr == iexp && iexp >= -128 && iexp <= 128) { return ipow(value, iexp); } @@ -619,14 +672,15 @@ double len = Math.pow(abs, yr); double at = Math.atan2(xi, xr); - double phase = at*yr; + double phase = at * yr; if (yi != 0) { - len /= Math.exp(at*yi); - phase += yi*Math.log(abs); + len /= Math.exp(at * yi); + phase += yi * Math.log(abs); } - return new PyComplex(len*Math.cos(phase), len*Math.sin(phase)); + return new PyComplex(len * Math.cos(phase), len * Math.sin(phase)); } + @Override public PyObject __neg__() { return complex___neg__(); } @@ -636,6 +690,7 @@ return new PyComplex(-real, -imag); } + @Override public PyObject __pos__() { return complex___pos__(); } @@ -648,10 +703,12 @@ return new PyComplex(real, imag); } + @Override public PyObject __invert__() { - throw Py.TypeError("bad operand type for unary ~"); + throw Py.TypeError("bad operand type for unary ~"); } + @Override public PyObject __abs__() { return complex___abs__(); } @@ -661,26 +718,27 @@ return new PyFloat(Math.hypot(real, imag)); } + @Override public PyObject __int__() { return complex___int__(); } @ExposedMethod(doc = BuiltinDocs.complex___int___doc) final PyInteger complex___int__() { - throw Py.TypeError( - "can't convert complex to int; use e.g. int(abs(z))"); + throw Py.TypeError("can't convert complex to int; use e.g. int(abs(z))"); } + @Override public PyObject __long__() { return complex___long__(); } @ExposedMethod(doc = BuiltinDocs.complex___long___doc) final PyObject complex___long__() { - throw Py.TypeError( - "can't convert complex to long; use e.g. long(abs(z))"); + throw Py.TypeError("can't convert complex to long; use e.g. long(abs(z))"); } + @Override public PyFloat __float__() { return complex___float__(); } @@ -690,6 +748,7 @@ throw Py.TypeError("can't convert complex to float; use e.g. abs(z)"); } + @Override public PyComplex __complex__() { return new PyComplex(real, imag); } @@ -708,6 +767,7 @@ return new PyTuple(new PyComplex(real, imag)); } + @Override public PyTuple __getnewargs__() { return complex___getnewargs__(); } Modified: trunk/jython/src/org/python/core/PyFloat.java =================================================================== --- trunk/jython/src/org/python/core/PyFloat.java 2010-03-13 17:33:14 UTC (rev 6984) +++ trunk/jython/src/org/python/core/PyFloat.java 2010-03-14 21:39:57 UTC (rev 6985) @@ -1,4 +1,7 @@ -// Copyright (c) Corporation for National Research Initiatives +/* + * Copyright (c) Corporation for National Research Initiatives + * Copyright (c) Jython Developers + */ package org.python.core; import java.io.Serializable; @@ -14,16 +17,33 @@ * A builtin python float. */ @ExposedType(name = "float", doc = BuiltinDocs.float_doc) -public class PyFloat extends PyObject -{ +public class PyFloat extends PyObject { + + public static final PyType TYPE = PyType.fromClass(PyFloat.class); + /** Precisions used by repr() and str(), respectively. */ private static final int PREC_REPR = 17; private static final int PREC_STR = 12; + private double value; + + public PyFloat(PyType subtype, double v) { + super(subtype); + value = v; + } + + public PyFloat(double v) { + this(TYPE, v); + } + + public PyFloat(float v) { + this((double) v); + } + @ExposedNew public static PyObject float_new(PyNewWrapper new_, boolean init, PyType subtype, - PyObject[] args, String[] keywords) { - ArgParser ap = new ArgParser("float", args, keywords, new String[] { "x" }, 0); + PyObject[] args, String[] keywords) { + ArgParser ap = new ArgParser("float", args, keywords, new String[] {"x"}, 0); PyObject x = ap.getPyObject(0, null); if (x == null) { if (new_.for_type == subtype) { @@ -54,23 +74,6 @@ } } - public static final PyType TYPE = PyType.fromClass(PyFloat.class); - - private double value; - - public PyFloat(PyType subtype, double v) { - super(subtype); - value = v; - } - - public PyFloat(double v) { - this(TYPE, v); - } - - public PyFloat(float v) { - this((double)v); - } - /** * Determine if this float is not infinity, nor NaN. */ @@ -82,10 +85,12 @@ return value; } + @Override public String toString() { return __str__().toString(); } + @Override public PyString __str__() { return float___str__(); } @@ -95,6 +100,7 @@ return Py.newString(formatDouble(PREC_STR)); } + @Override public PyString __repr__() { return float___repr__(); } @@ -108,7 +114,7 @@ if (Double.isNaN(value)) { return "nan"; } - + String result = String.format("%%.%dg", precision); result = Py.newString(result).__mod__(this).toString(); @@ -127,6 +133,7 @@ return result; } + @Override public int hashCode() { return float___hash__(); } @@ -134,19 +141,21 @@ @ExposedMethod(doc = BuiltinDocs.float___hash___doc) final int float___hash__() { double intPart = Math.floor(value); - double fractPart = value-intPart; + double fractPart = value - intPart; if (fractPart == 0) { - if (intPart <= Integer.MAX_VALUE && intPart >= Integer.MIN_VALUE) - return (int)value; - else + if (intPart <= Integer.MAX_VALUE && intPart >= Integer.MIN_VALUE) { + return (int) value; + } else { return __long__().hashCode(); + } } else { long v = Double.doubleToLongBits(value); - return (int)v ^ (int)(v >> 32); + return (int) v ^ (int) (v >> 32); } } + @Override public boolean __nonzero__() { return float___nonzero__(); } @@ -156,10 +165,10 @@ return value != 0; } - public Object __tojava__(Class c) { - if (c == Double.TYPE || c == Number.class || - c == Double.class || c == Object.class || c == Serializable.class) - { + @Override + public Object __tojava__(Class<?> c) { + if (c == Double.TYPE || c == Number.class || c == Double.class || c == Object.class + || c == Serializable.class) { return new Double(value); } if (c == Float.TYPE || c == Float.class) { @@ -168,6 +177,7 @@ return super.__tojava__(c); } + @Override public PyObject __eq__(PyObject other) { // preclude _cmp_unsafe's this == other shortcut because NaN != anything, even // itself @@ -177,6 +187,7 @@ return null; } + @Override public PyObject __ne__(PyObject other) { if (Double.isNaN(value)) { return Py.True; @@ -184,18 +195,19 @@ return null; } + @Override public int __cmp__(PyObject other) { return float___cmp__(other); } - //XXX: needs __doc__ + // XXX: needs __doc__ @ExposedMethod(type = MethodType.CMP) final int float___cmp__(PyObject other) { double i = value; double j; if (other instanceof PyFloat) { - j = ((PyFloat)other).value; + j = ((PyFloat) other).value; } else if (!isFinite()) { // we're infinity: our magnitude exceeds any finite // integer, so it doesn't matter which int we compare i @@ -206,10 +218,10 @@ return -2; } } else if (other instanceof PyInteger) { - j = ((PyInteger)other).getValue(); + j = ((PyInteger) other).getValue(); } else if (other instanceof PyLong) { BigDecimal v = new BigDecimal(value); - BigDecimal w = new BigDecimal(((PyLong)other).getValue()); + BigDecimal w = new BigDecimal(((PyLong) other).getValue()); return v.compareTo(w); } else { return -2; @@ -227,6 +239,7 @@ } } + @Override public Object __coerce_ex__(PyObject other) { return float___coerce_ex__(other); } @@ -236,22 +249,23 @@ return adaptToCoerceTuple(float___coerce_ex__(other)); } - /** + /** * Coercion logic for float. Implemented as a final method to avoid - * invocation of virtual methods from the exposed coerce. - */ + * invocation of virtual methods from the exposed coerce. + */ final Object float___coerce_ex__(PyObject other) { - if (other instanceof PyFloat) + if (other instanceof PyFloat) { return other; - else { - if (other instanceof PyInteger) - return new PyFloat((double)((PyInteger)other).getValue()); - if (other instanceof PyLong) - return new PyFloat(((PyLong)other).doubleValue()); - else + } else { + if (other instanceof PyInteger) { + return new PyFloat((double) ((PyInteger) other).getValue()); + } + if (other instanceof PyLong) { + return new PyFloat(((PyLong) other).doubleValue()); + } else { return Py.None; + } } - } private static final boolean canCoerce(PyObject other) { @@ -259,28 +273,32 @@ } private static final double coerce(PyObject other) { - if (other instanceof PyFloat) + if (other instanceof PyFloat) { return ((PyFloat) other).value; - else if (other instanceof PyInteger) + } else if (other instanceof PyInteger) { return ((PyInteger) other).getValue(); - else if (other instanceof PyLong) + } else if (other instanceof PyLong) { return ((PyLong) other).doubleValue(); - else + } else { throw Py.TypeError("xxx"); + } } + @Override public PyObject __add__(PyObject right) { return float___add__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___add___doc) final PyObject float___add__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } double rightv = coerce(right); return new PyFloat(value + rightv); } + @Override public PyObject __radd__(PyObject left) { return float___radd__(left); } @@ -290,42 +308,49 @@ return __add__(left); } + @Override public PyObject __sub__(PyObject right) { return float___sub__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___sub___doc) final PyObject float___sub__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } double rightv = coerce(right); return new PyFloat(value - rightv); } + @Override public PyObject __rsub__(PyObject left) { return float___rsub__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___rsub___doc) final PyObject float___rsub__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } double leftv = coerce(left); return new PyFloat(leftv - value); } + @Override public PyObject __mul__(PyObject right) { return float___mul__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___mul___doc) final PyObject float___mul__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } double rightv = coerce(right); return new PyFloat(value * rightv); } + @Override public PyObject __rmul__(PyObject left) { return float___rmul__(left); } @@ -335,151 +360,185 @@ return __mul__(left); } + @Override public PyObject __div__(PyObject right) { return float___div__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___div___doc) final PyObject float___div__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; - if (Options.divisionWarning >= 2) + } + if (Options.divisionWarning >= 2) { Py.warning(Py.DeprecationWarning, "classic float division"); + } + double rightv = coerce(right); - if (rightv == 0) + if (rightv == 0) { throw Py.ZeroDivisionError("float division"); + } return new PyFloat(value / rightv); } + @Override public PyObject __rdiv__(PyObject left) { return float___rdiv__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___rdiv___doc) final PyObject float___rdiv__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; - if (Options.divisionWarning >= 2) + } + if (Options.divisionWarning >= 2) { Py.warning(Py.DeprecationWarning, "classic float division"); + } + double leftv = coerce(left); - if (value == 0) + if (value == 0) { throw Py.ZeroDivisionError("float division"); + } return new PyFloat(leftv / value); } + @Override public PyObject __floordiv__(PyObject right) { return float___floordiv__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___floordiv___doc) final PyObject float___floordiv__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } double rightv = coerce(right); - if (rightv == 0) + if (rightv == 0) { throw Py.ZeroDivisionError("float division"); + } return new PyFloat(Math.floor(value / rightv)); } + @Override public PyObject __rfloordiv__(PyObject left) { return float___rfloordiv__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___rfloordiv___doc) final PyObject float___rfloordiv__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } double leftv = coerce(left); - if (value == 0) + if (value == 0) { throw Py.ZeroDivisionError("float division"); + } return new PyFloat(Math.floor(leftv / value)); } + @Override public PyObject __truediv__(PyObject right) { return float___truediv__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___truediv___doc) final PyObject float___truediv__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } double rightv = coerce(right); - if (rightv == 0) + if (rightv == 0) { throw Py.ZeroDivisionError("float division"); + } return new PyFloat(value / rightv); } + @Override public PyObject __rtruediv__(PyObject left) { return float___rtruediv__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___rtruediv___doc) final PyObject float___rtruediv__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } double leftv = coerce(left); - if (value == 0) + if (value == 0) { throw Py.ZeroDivisionError("float division"); + } return new PyFloat(leftv / value); } private static double modulo(double x, double y) { - if (y == 0) + if (y == 0) { throw Py.ZeroDivisionError("float modulo"); + } double z = Math.IEEEremainder(x, y); - if (z*y < 0) + if (z * y < 0) { z += y; + } return z; } + @Override public PyObject __mod__(PyObject right) { return float___mod__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___mod___doc) final PyObject float___mod__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } double rightv = coerce(right); return new PyFloat(modulo(value, rightv)); } + @Override public PyObject __rmod__(PyObject left) { return float___rmod__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___rmod___doc) final PyObject float___rmod__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } double leftv = coerce(left); return new PyFloat(modulo(leftv, value)); } + @Override public PyObject __divmod__(PyObject right) { return float___divmod__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___divmod___doc) final PyObject float___divmod__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } double rightv = coerce(right); - if (rightv == 0) + if (rightv == 0) { throw Py.ZeroDivisionError("float division"); + } double z = Math.floor(value / rightv); return new PyTuple(new PyFloat(z), new PyFloat(value - z * rightv)); } + @Override public PyObject __rdivmod__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } double leftv = coerce(left); - if (value == 0) + if (value == 0) { throw Py.ZeroDivisionError("float division"); + } double z = Math.floor(leftv / value); return new PyTuple(new PyFloat(z), new PyFloat(leftv - z * value)); @@ -487,22 +546,23 @@ @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___rdivmod___doc) final PyObject float___rdivmod__(PyObject left) { - return __rdivmod__(left); + return __rdivmod__(left); } - + @Override public PyObject __pow__(PyObject right, PyObject modulo) { return float___pow__(right, modulo); } - @ExposedMethod(type = MethodType.BINARY, defaults = "null", doc = BuiltinDocs.float___pow___doc) + @ExposedMethod(type = MethodType.BINARY, defaults = "null", + doc = BuiltinDocs.float___pow___doc) final PyObject float___pow__(PyObject right, PyObject modulo) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } if (modulo != null) { - throw Py.TypeError("pow() 3rd argument not allowed " + - "unless all arguments are integers"); + throw Py.TypeError("pow() 3rd argument not allowed unless all arguments are integers"); } return _pow(value, coerce(right), modulo); @@ -510,12 +570,14 @@ @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.float___rpow___doc) final PyObject float___rpow__(PyObject left) { - return __rpow__(left); + return __rpow__(left); } - + + @Override public PyObject __rpow__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return _pow(coerce(left), value, null); } @@ -523,28 +585,27 @@ private static PyFloat _pow(double value, double iw, PyObject modulo) { // Rely completely on Java's pow function if (iw == 0) { - if (modulo != null) + if (modulo != null) { return new PyFloat(modulo(1.0, coerce(modulo))); + } return new PyFloat(1.0); } if (value == 0.0) { - if (iw < 0.0) - throw Py.ZeroDivisionError("0.0 cannot be raised to a " + - "negative power"); + if (iw < 0.0) { + throw Py.ZeroDivisionError("0.0 cannot be raised to a negative power"); + } return new PyFloat(0); } - if (value < 0 && iw != Math.floor(iw)) + if (value < 0 && iw != Math.floor(iw)) { throw Py.ValueError("negative number cannot be raised to a fractional power"); - + } + double ret = Math.pow(value, iw); - if (modulo == null) { - return new PyFloat(ret); - } else { - return new PyFloat(modulo(ret, coerce(modulo))); - } + return new PyFloat(modulo == null ? ret : modulo(ret, coerce(modulo))); } + @Override public PyObject __neg__() { return float___neg__(); } @@ -554,6 +615,7 @@ return new PyFloat(-value); } + @Override public PyObject __pos__() { return float___pos__(); } @@ -563,10 +625,12 @@ return float___float__(); } + @Override public PyObject __invert__() { throw Py.TypeError("bad operand type for unary ~"); } + @Override public PyObject __abs__() { return float___abs__(); } @@ -579,6 +643,7 @@ return float___float__(); } + @Override public PyObject __int__() { return float___int__(); } @@ -586,11 +651,12 @@ @ExposedMethod(doc = BuiltinDocs.float___int___doc) final PyObject float___int__() { if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE) { - return new PyInteger((int)value); + return new PyInteger((int) value); } return __long__(); } + @Override public PyObject __long__() { return float___long__(); } @@ -600,6 +666,7 @@ return new PyLong(value); } + @Override public PyFloat __float__() { return float___float__(); } @@ -611,6 +678,8 @@ } return Py.newFloat(value); } + + @Override public PyComplex __complex__() { return new PyComplex(value, 0.); } @@ -620,10 +689,12 @@ return new PyTuple(new PyObject[] {new PyFloat(getValue())}); } + @Override public PyTuple __getnewargs__() { return float___getnewargs__(); } + @Override public double asDouble() { return value; } @@ -635,23 +706,26 @@ // standard singleton issues apply here to __getformat__/__setformat__, // but this is what Python demands - public enum Format { - UNKNOWN ("unknown"), - BE ("IEEE, big-endian"), - LE ("IEEE, little-endian"); - + + UNKNOWN("unknown"), + BE("IEEE, big-endian"), + LE("IEEE, little-endian"); + private final String format; + Format(String format) { this.format = format; } - public String format() { return format; } + + public String format() { + return format; + } } - - // subset of IEEE-754, the JVM is big-endian + // subset of IEEE-754, the JVM is big-endian public static volatile Format double_format = Format.BE; public static volatile Format float_format = Format.BE; - + @ExposedClassMethod(doc = BuiltinDocs.float___getformat___doc) public static String float___getformat__(PyType type, String typestr) { if ("double".equals(typestr)) { @@ -662,7 +736,7 @@ throw Py.ValueError("__getformat__() argument 1 must be 'double' or 'float'"); } } - + @ExposedClassMethod(doc = BuiltinDocs.float___setformat___doc) public static void float___setformat__(PyType type, String typestr, String format) { Format new_format = null; @@ -670,13 +744,15 @@ throw Py.ValueError("__setformat__() argument 1 must be 'double' or 'float'"); } if (Format.LE.format().equals(format)) { - throw Py.ValueError(String.format("can only set %s format to 'unknown' or the " + "detected platform value", typestr)); + throw Py.ValueError(String.format("can only set %s format to 'unknown' or the " + + "detected platform value", typestr)); } else if (Format.BE.format().equals(format)) { new_format = Format.BE; } else if (Format.UNKNOWN.format().equals(format)) { new_format = Format.UNKNOWN; } else { - throw Py.ValueError("__setformat__() argument 2 must be 'unknown', " + "'IEEE, little-endian' or 'IEEE, big-endian'"); + throw Py.ValueError("__setformat__() argument 2 must be 'unknown', " + + "'IEEE, little-endian' or 'IEEE, big-endian'"); } if (new_format != null) { if ("double".equals(typestr)) { Modified: trunk/jython/src/org/python/core/PyInteger.java =================================================================== --- trunk/jython/src/org/python/core/PyInteger.java 2010-03-13 17:33:14 UTC (rev 6984) +++ trunk/jython/src/org/python/core/PyInteger.java 2010-03-14 21:39:57 UTC (rev 6985) @@ -1,4 +1,7 @@ -// Copyright (c) Corporation for National Research Initiatives +/* + * Copyright (c) Corporation for National Research Initiatives + * Copyright (c) Jython Developers + */ package org.python.core; import java.io.Serializable; @@ -14,7 +17,7 @@ */ @ExposedType(name = "int", doc = BuiltinDocs.int_doc) public class PyInteger extends PyObject { - + public static final PyType TYPE = PyType.fromClass(PyInteger.class); /** The minimum value of an int represented by a BigInteger */ @@ -23,31 +26,41 @@ /** The maximum value of an int represented by a BigInteger */ public static final BigInteger maxInt = BigInteger.valueOf(Integer.MAX_VALUE); + private int value; + + public PyInteger(PyType subType, int v) { + super(subType); + value = v; + } + + public PyInteger(int v) { + this(TYPE, v); + } + @ExposedNew public static PyObject int_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[] args, String[] keywords) { - ArgParser ap = new ArgParser("int", args, keywords, new String[] { "x", - "base" }, 0); + ArgParser ap = new ArgParser("int", args, keywords, new String[] {"x", "base"}, 0); PyObject x = ap.getPyObject(0, null); int base = ap.getInt(1, -909); if (new_.for_type == subtype) { if (x == null) { return Py.Zero; } - if (base == -909) { - if (x instanceof PyBoolean) { - return (coerce(x) == 0) ? Py.Zero : Py.One; - } - return asPyInteger(x); - } - if (!(x instanceof PyString)) { - throw Py.TypeError("int: can't convert non-string with explicit base"); - } + if (base == -909) { + if (x instanceof PyBoolean) { + return (coerce(x) == 0) ? Py.Zero : Py.One; + } + return asPyInteger(x); + } + if (!(x instanceof PyString)) { + throw Py.TypeError("int: can't convert non-string with explicit base"); + } try { - return Py.newInteger(((PyString)x).atoi(base)); + return Py.newInteger(((PyString) x).atoi(base)); } catch (PyException pye) { if (pye.match(Py.OverflowError)) { - return ((PyString)x).atol(base); + return ((PyString) x).atol(base); } throw pye; } @@ -56,60 +69,51 @@ return new PyIntegerDerived(subtype, 0); } if (base == -909) { - PyObject intOrLong = asPyInteger(x); - if (intOrLong instanceof PyInteger) { - return new PyIntegerDerived(subtype, ((PyInteger) intOrLong).getValue()); - } else { - throw Py.OverflowError("long int too large to convert to int"); - } + PyObject intOrLong = asPyInteger(x); + if (intOrLong instanceof PyInteger) { + return new PyIntegerDerived(subtype, ((PyInteger) intOrLong).getValue()); + } else { + throw Py.OverflowError("long int too large to convert to int"); + } } if (!(x instanceof PyString)) { - throw Py - .TypeError("int: can't convert non-string with explicit base"); + throw Py.TypeError("int: can't convert non-string with explicit base"); } return new PyIntegerDerived(subtype, ((PyString) x).atoi(base)); } } // xxx /** - * @return the result of x.__int__ + * @return the result of x.__int__ * @throws Py.Type error if x.__int__ throws an Py.AttributeError */ - private static PyObject asPyInteger(PyObject x) { - try { - return x.__int__(); - } catch (PyException pye) { - if (!pye.match(Py.AttributeError)) - throw pye; - throw Py.TypeError("int() argument must be a string or a number"); - } - } - - private int value; - - public PyInteger(PyType subType, int v) { - super(subType); - value = v; + private static PyObject asPyInteger(PyObject x) { + try { + return x.__int__(); + } catch (PyException pye) { + if (!pye.match(Py.AttributeError)) { + throw pye; + } + throw Py.TypeError("int() argument must be a string or a number"); + } } - public PyInteger(int v) { - this(TYPE, v); - } - public int getValue() { return value; } + @Override public String toString() { return int_toString(); } - //XXX: need separate __doc__ for __repr__ + // XXX: need separate __doc__ for __repr__ @ExposedMethod(names = {"__str__", "__repr__"}, doc = BuiltinDocs.int___str___doc) final String int_toString() { return Integer.toString(getValue()); } + @Override public int hashCode() { return int_hashCode(); } @@ -119,6 +123,7 @@ return getValue(); } + @Override public boolean __nonzero__() { return int___nonzero__(); } @@ -128,42 +133,50 @@ return getValue() != 0; } + @Override public Object __tojava__(Class<?> c) { - if (c == Integer.TYPE || c == Number.class || - c == Object.class || c == Integer.class || - c == Serializable.class) - { + if (c == Integer.TYPE || c == Number.class || c == Object.class || c == Integer.class + || c == Serializable.class) { return new Integer(getValue()); } - if (c == Boolean.TYPE || c == Boolean.class) + if (c == Boolean.TYPE || c == Boolean.class) { return new Boolean(getValue() != 0); - if (c == Byte.TYPE || c == Byte.class) - return new Byte((byte)getValue()); - if (c == Short.TYPE || c == Short.class) - return new Short((short)getValue()); + } + if (c == Byte.TYPE || c == Byte.class) { + return new Byte((byte) getValue()); + } + if (c == Short.TYPE || c == Short.class) { + return new Short((short) getValue()); + } - if (c == Long.TYPE || c == Long.class) + if (c == Long.TYPE || c == Long.class) { return new Long(getValue()); - if (c == Float.TYPE || c == Float.class) + } + if (c == Float.TYPE || c == Float.class) { return new Float(getValue()); - if (c == Double.TYPE || c == Double.class) + } + if (c == Double.TYPE || c == Double.class) { return new Double(getValue()); + } return super.__tojava__(c); } + @Override public int __cmp__(PyObject other) { return int___cmp__(other); } @ExposedMethod(type = MethodType.CMP, doc = BuiltinDocs.int___cmp___doc) final int int___cmp__(PyObject other) { - if (!canCoerce(other)) - return -2; + if (!canCoerce(other)) { + return -2; + } int v = coerce(other); return getValue() < v ? -1 : getValue() > v ? 1 : 0; } + @Override public Object __coerce_ex__(PyObject other) { return int___coerce_ex__(other); } @@ -173,15 +186,12 @@ return adaptToCoerceTuple(int___coerce_ex__(other)); } - /** + /** * Coercion logic for int. Implemented as a final method to avoid - * invocation of virtual methods from the exposed coerced. - */ + * invocation of virtual methods from the exposed coerced. + */ final Object int___coerce_ex__(PyObject other) { - if (other instanceof PyInteger) - return other; - else - return Py.None; + return other instanceof PyInteger ? other : Py.None; } private static final boolean canCoerce(PyObject other) { @@ -189,30 +199,33 @@ } private static final int coerce(PyObject other) { - if (other instanceof PyInteger) + if (other instanceof PyInteger) { return ((PyInteger) other).getValue(); - else - throw Py.TypeError("xxx"); + } + throw Py.TypeError("xxx"); } - + @Override public PyObject __add__(PyObject right) { return int___add__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___add___doc) final PyObject int___add__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } int rightv = coerce(right); int a = getValue(); int b = rightv; int x = a + b; - if ((x^a) >= 0 || (x^b) >= 0) + if ((x ^ a) >= 0 || (x ^ b) >= 0) { return Py.newInteger(x); - return new PyLong((long) a + (long)b); + } + return new PyLong((long) a + (long) b); } + @Override public PyObject __radd__(PyObject left) { return int___radd__(left); } @@ -224,57 +237,64 @@ private static PyObject _sub(int a, int b) { int x = a - b; - if ((x^a) >= 0 || (x^~b) >= 0) + if ((x ^ a) >= 0 || (x ^ ~b) >= 0) { return Py.newInteger(x); - return new PyLong((long) a - (long)b); + } + return new PyLong((long) a - (long) b); } + @Override public PyObject __sub__(PyObject right) { return int___sub__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___sub___doc) final PyObject int___sub__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } return _sub(getValue(), coerce(right)); } + @Override public PyObject __rsub__(PyObject left) { return int___rsub__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rsub___doc) final PyObject int___rsub__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return _sub(coerce(left), getValue()); } + @Override public PyObject __mul__(PyObject right) { return int___mul__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___mul___doc) final PyObject int___mul__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } int rightv = coerce(right); double x = getValue(); x *= rightv; - //long x = ((long)getValue())*((PyInteger)right).getValue(); - //System.out.println("mul: "+this+" * "+right+" = "+x); - if (x <= Integer.MAX_VALUE && x >= Integer.MIN_VALUE) - return Py.newInteger((int)x); + if (x <= Integer.MAX_VALUE && x >= Integer.MIN_VALUE) { + return Py.newInteger((int) x); + } return __long__().__mul__(right); } + @Override public PyObject __rmul__(PyObject left) { return int___rmul__(left); } - + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rmul___doc) final PyObject int___rmul__(PyObject left) { return __mul__(left); @@ -288,13 +308,11 @@ } long xdivy = x / y; long xmody = x - xdivy * y; - - /* If the signs of x and y differ, and the remainder is non-0, - * C89 doesn't define whether xdivy is now the floor or the - * ceiling of the infinitely precise quotient. We want the floor, - * and we have it iff the remainder's sign matches y's. - */ - + + // If the signs of x and y differ, and the remainder is non-0, C89 doesn't define + // whether xdivy is now the floor or the ceiling of the infinitely precise + // quotient. We want the floor, and we have it iff the remainder's sign matches + // y's. if (xmody != 0 && ((y < 0 && xmody > 0) || (y > 0 && xmody < 0))) { xmody += y; --xdivy; @@ -307,128 +325,148 @@ public PyObject __div__(PyObject right) { return int___div__(right); } - + @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___div___doc) final PyObject int___div__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; - if (Options.divisionWarning > 0) + } + if (Options.divisionWarning > 0) { Py.warning(Py.DeprecationWarning, "classic int division"); + } return Py.newInteger(divide(getValue(), coerce(right))); } + @Override public PyObject __rdiv__(PyObject left) { return int___rdiv__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rdiv___doc) final PyObject int___rdiv__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; - if (Options.divisionWarning > 0) + } + if (Options.divisionWarning > 0) { Py.warning(Py.DeprecationWarning, "classic int division"); + } return Py.newInteger(divide(coerce(left), getValue())); } + @Override public PyObject __floordiv__(PyObject right) { return int___floordiv__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___floordiv___doc) final PyObject int___floordiv__(PyObject right) { - if (!canCoerce(right)) + if (!canCoerce(right)) { return null; + } return Py.newInteger(divide(getValue(), coerce(right))); } + @Override public PyObject __rfloordiv__(PyObject left) { return int___rfloordiv__(left); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___rfloordiv___doc) final PyObject int___rfloordiv__(PyObject left) { - if (!canCoerce(left)) + if (!canCoerce(left)) { return null; + } return Py.newInteger(divide(coerce(left), getValue())); } + @Override public PyObject __truediv__(PyObject right) { return int___truediv__(right); } @ExposedMethod(type = MethodType.BINARY, doc = BuiltinDocs.int___truediv___doc) final PyObject int___truediv__(PyObject right) { - if (right instanceof PyInteger) + if (right instanceof PyInteger) { return __float__().__truediv__(right); - else if(right instanceof PyLong) + } else if (right instanceof PyLong) { return int___long__().__truediv__(right); - ... [truncated message content] |
From: <pj...@us...> - 2010-03-13 17:33:20
|
Revision: 6984 http://jython.svn.sourceforge.net/jython/?rev=6984&view=rev Author: pjenvey Date: 2010-03-13 17:33:14 +0000 (Sat, 13 Mar 2010) Log Message: ----------- fix the cmath module to accept objects implementing __float__ and remove its duplicate implementation of asDouble Modified Paths: -------------- trunk/jython/Lib/test/test_cmath_jy.py trunk/jython/NEWS trunk/jython/src/org/python/modules/cmath.java Modified: trunk/jython/Lib/test/test_cmath_jy.py =================================================================== --- trunk/jython/Lib/test/test_cmath_jy.py 2010-03-13 03:38:40 UTC (rev 6983) +++ trunk/jython/Lib/test/test_cmath_jy.py 2010-03-13 17:33:14 UTC (rev 6984) @@ -99,6 +99,27 @@ self.assertAlmostEqual(complex(1.00071, 0.00490826), cmath.tanh(complex(3, 4))) + def test_faux_float(self): + class Foo: + def __float__(self): + return 1.0 + class Bar(object): + def __float__(self): + return 1.0 + self.assertEqual(cmath.log(Foo()), 0.0) + self.assertEqual(cmath.log(Bar()), 0.0) + + def test_faux_complex(self): + class Foo: + def __complex__(self): + return 1.0j + class Bar(object): + def __complex__(self): + return 1.0j + self.assertEqual(cmath.log(Foo()), cmath.log(1.0j)) + self.assertEqual(cmath.log(Bar()), cmath.log(1.0j)) + + def test_main(): test_support.run_unittest(CmathTestCase) Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2010-03-13 03:38:40 UTC (rev 6983) +++ trunk/jython/NEWS 2010-03-13 17:33:14 UTC (rev 6984) @@ -20,6 +20,7 @@ - Fix runtime issues during exitfuncs triggered via SystemRestart (such as during Django or Pylons development mode reloading) - Fix pickling of collections.defaultdict objects + - Fix the cmath module to accept objects implementing the __float__ method Jython 2.5.1rc3 Bugs Fixed Modified: trunk/jython/src/org/python/modules/cmath.java =================================================================== --- trunk/jython/src/org/python/modules/cmath.java 2010-03-13 03:38:40 UTC (rev 6983) +++ trunk/jython/src/org/python/modules/cmath.java 2010-03-13 17:33:14 UTC (rev 6984) @@ -2,8 +2,8 @@ import org.python.core.Py; import org.python.core.PyComplex; -import org.python.core.PyException; import org.python.core.PyFloat; +import org.python.core.PyInstance; import org.python.core.PyObject; import org.python.modules.math; @@ -24,28 +24,39 @@ return (Math.sqrt(x * x + y * y)); } - private static PyComplex complexFromPyObject(PyObject in) { - try{ - return(in.__complex__()); - } catch(PyException e){ - if(e.type == Py.AttributeError || e.type == Py.ValueError) { - throw Py.TypeError("a float is required"); + private static PyComplex complexFromPyObject(PyObject obj) { + // If op is already of type PyComplex_Type, return its value + if (obj instanceof PyComplex) { + return (PyComplex)obj; + } + + // If not, use op's __complex__ method, if it exists + PyObject newObj = null; + if (obj instanceof PyInstance) { + // this can go away in python 3000 + if (obj.__findattr__("__complex__") != null) { + newObj = obj.invoke("__complex__"); } - throw e; + // else try __float__ + } else { + PyObject complexFunc = obj.getType().lookup("__complex__"); + if (complexFunc != null) { + newObj = complexFunc.__call__(obj); + } } - } - - private static double doubleFromPyObject(PyObject in) { - try{ - return(in.__float__().getValue()); - } catch(PyException e){ - if(e.type == Py.AttributeError || e.type == Py.ValueError) { - throw Py.TypeError("a float is required"); + + if (newObj != null) { + if (!(newObj instanceof PyComplex)) { + throw Py.TypeError("__complex__ should return a complex object"); } - throw e; + return (PyComplex)newObj; } + + // If neither of the above works, interpret op as a float giving the real part of + // the result, and fill in the imaginary part as 0 + return new PyComplex(obj.asDouble(), 0); } - + public static PyObject acos(PyObject in) { PyComplex x = complexFromPyObject(in); return (c_prodi(log(x.__add__(i @@ -146,7 +157,7 @@ } public static PyComplex log(PyObject in, PyObject base) { - return log(complexFromPyObject(in), doubleFromPyObject(base)); + return log(complexFromPyObject(in), base.asDouble()); } public static PyComplex log(PyComplex x, double base) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |