From: <fwi...@us...> - 2008-05-14 19:44:53
|
Revision: 4402 http://jython.svn.sourceforge.net/jython/?rev=4402&view=rev Author: fwierzbicki Date: 2008-05-14 12:44:50 -0700 (Wed, 14 May 2008) Log Message: ----------- Merged revisions 4391,4393-4401 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4391 | pjenvey | 2008-05-13 15:28:35 -0400 (Tue, 13 May 2008) | 1 line whitespace ........ r4393 | pjenvey | 2008-05-13 17:15:18 -0400 (Tue, 13 May 2008) | 3 lines update test_funcattrs to the latest 2.5 version, from: http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_funcattrs.py@59171 ........ r4394 | pjenvey | 2008-05-13 17:34:49 -0400 (Tue, 13 May 2008) | 8 lines o cleanup PyFunction, use exposed annotations o copy the new.function arg checking code into PyFunction __new__, so types.FunctionType supports the same args. add test_func_jy with jek's test cases o add cell.cell_contents and an appropriate repr. use exposed annotations fixes #1034 thanks Jason Kirtland ........ r4395 | pjenvey | 2008-05-13 18:18:05 -0400 (Tue, 13 May 2008) | 1 line unused import ........ r4396 | pjenvey | 2008-05-13 18:30:47 -0400 (Tue, 13 May 2008) | 3 lines new.py from: http://svn.python.org/projects/python/branches/release25-maint/Lib/new.py@27241 ........ r4397 | fwierzbicki | 2008-05-13 19:30:08 -0400 (Tue, 13 May 2008) | 3 lines Extracted from astlib.py -- simple pretty printer that works for both jython and python. ........ r4398 | fwierzbicki | 2008-05-13 19:31:56 -0400 (Tue, 13 May 2008) | 2 lines change def name. ........ r4399 | pjenvey | 2008-05-13 21:13:52 -0400 (Tue, 13 May 2008) | 1 line make types.InstanceType() handle None as second arg ........ r4400 | pjenvey | 2008-05-13 21:14:20 -0400 (Tue, 13 May 2008) | 6 lines o match types.MethodType() (new PyMethod()) args to CPython's: (func, self, type) instead of (self, func, type) o kill most of newmodule for the simpler pure python version. we can't dump it completely until a better workaround for the new.classobj hack is done; in the meantime, keep it around at _new.classobj ........ r4401 | pjenvey | 2008-05-13 21:34:54 -0400 (Tue, 13 May 2008) | 1 line ensure new.classobj can create new style classes ........ Modified Paths: -------------- branches/asm/CoreExposed.includes branches/asm/Lib/test/test_class_jy.py branches/asm/Lib/test/test_funcattrs.py branches/asm/src/org/python/core/Py.java branches/asm/src/org/python/core/PyCell.java branches/asm/src/org/python/core/PyClassMethod.java branches/asm/src/org/python/core/PyFile.java branches/asm/src/org/python/core/PyFunction.java branches/asm/src/org/python/core/PyInstance.java branches/asm/src/org/python/core/PyMethod.java branches/asm/src/org/python/core/PyReflectedFunction.java branches/asm/src/org/python/modules/Setup.java branches/asm/src/org/python/modules/cPickle.java branches/asm/src/org/python/modules/synchronize.java Added Paths: ----------- branches/asm/Lib/new.py branches/asm/Lib/test/test_func_jy.py branches/asm/ast/astview.py branches/asm/src/org/python/modules/_newmodule.java Removed Paths: ------------- branches/asm/src/org/python/modules/newmodule.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4383 + /trunk/jython:1-4401 Modified: branches/asm/CoreExposed.includes =================================================================== --- branches/asm/CoreExposed.includes 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/CoreExposed.includes 2008-05-14 19:44:50 UTC (rev 4402) @@ -2,6 +2,7 @@ org/python/core/PyBaseString.class org/python/core/PyBoolean.class org/python/core/PyBuiltinFunction.class +org/python/core/PyCell.class org/python/core/PyClassMethod.class org/python/core/PyComplex.class org/python/core/PyDataDescr.class @@ -10,6 +11,7 @@ org/python/core/PyEnumerate.class org/python/core/PyFile.class org/python/core/PyFloat.class +org/python/core/PyFunction.class org/python/core/PyInteger.class org/python/core/PyList.class org/python/core/PyLong.class Copied: branches/asm/Lib/new.py (from rev 4401, trunk/jython/Lib/new.py) =================================================================== --- branches/asm/Lib/new.py (rev 0) +++ branches/asm/Lib/new.py 2008-05-14 19:44:50 UTC (rev 4402) @@ -0,0 +1,22 @@ +"""Create new objects of various types. Deprecated. + +This module is no longer required except for backward compatibility. +Objects of most types can now be created by calling the type object. +""" + +# XXX: Hack for types.ClassType not supporting creation of new style +# classes; see org.python.modules._newmodule.classobj for more info +#from types import ClassType as classobj +from _new import classobj +from types import FunctionType as function +from types import InstanceType as instance +from types import MethodType as instancemethod +from types import ModuleType as module + +# XXX: Jython can't really create a code object like CPython does +# (according to test.test_new) +## CodeType is not accessible in restricted execution mode +#try: +# from types import CodeType as code +#except ImportError: +# pass Modified: branches/asm/Lib/test/test_class_jy.py =================================================================== --- branches/asm/Lib/test/test_class_jy.py 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/Lib/test/test_class_jy.py 2008-05-14 19:44:50 UTC (rev 4402) @@ -4,6 +4,7 @@ Made for Jython """ import __builtin__ +import new import unittest from test import test_support @@ -108,7 +109,19 @@ self.assert_(False, 'delattr Foo.%s expected a TypeError' % attr) + def test_newstyle_new_classobj(self): + # Ensure new.classobj can create new style classes + class Foo(object): + pass + def hello(self): + return 'hello' + Bar = new.classobj('Bar', (Foo,), dict(hello=hello)) + self.assert_(type(Bar), type) + self.assert_(issubclass(Bar, Foo)) + self.assert_(hasattr(Bar, 'hello')) + self.assertEquals(Bar().hello(), 'hello') + class ClassNamelessModuleTestCase(unittest.TestCase): def setUp(self): Copied: branches/asm/Lib/test/test_func_jy.py (from rev 4401, trunk/jython/Lib/test/test_func_jy.py) =================================================================== --- branches/asm/Lib/test/test_func_jy.py (rev 0) +++ branches/asm/Lib/test/test_func_jy.py 2008-05-14 19:44:50 UTC (rev 4402) @@ -0,0 +1,37 @@ +"""Misc func tests. + +Made for Jython. +""" +import types +import unittest +from test import test_support + +xyz = 123 + +def abc(): + return xyz + +class FunctionTypeTestCase(unittest.TestCase): + + def test_func(self): + self.assertEquals(abc(), 123) + + def test_functiontype(self): + new_abc = types.FunctionType(abc.func_code, {'xyz': 456}, + abc.func_name, abc.func_defaults, + abc.func_closure) + self.assertEquals(new_abc(), 456) + + def test_functiontype_from_globals(self): + sm = type(globals())() + sm.update({'xyz': 789}) + sm_abc = types.FunctionType(abc.func_code, sm, abc.func_name, + abc.func_defaults, abc.func_closure) + self.assertEquals(sm_abc(), 789) + + +def test_main(): + test_support.run_unittest(FunctionTypeTestCase) + +if __name__ == '__main__': + test_main() Modified: branches/asm/Lib/test/test_funcattrs.py =================================================================== --- branches/asm/Lib/test/test_funcattrs.py 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/Lib/test/test_funcattrs.py 2008-05-14 19:44:50 UTC (rev 4402) @@ -218,11 +218,11 @@ # Test all predefined function attributes systematically -def cantset(obj, name, value): +def cantset(obj, name, value, exception=(AttributeError, TypeError)): verify(hasattr(obj, name)) # Otherwise it's probably a typo try: setattr(obj, name, value) - except (AttributeError, TypeError): + except exception: pass else: raise TestFailed, "shouldn't be able to set %s to %r" % (name, value) @@ -242,6 +242,17 @@ verify(c[0].__class__.__name__ == "cell") # don't have a type object handy cantset(f, "func_closure", c) +def test_empty_cell(): + def f(): print a + try: + f.func_closure[0].cell_contents + except ValueError: + pass + else: + raise TestFailed, "shouldn't be able to read an empty cell" + + a = 12 + def test_func_doc(): def f(): pass verify(f.__doc__ is None) @@ -268,17 +279,34 @@ def f(): pass verify(f.__name__ == "f") verify(f.func_name == "f") - cantset(f, "func_name", "f") - cantset(f, "__name__", "f") + f.__name__ = "g" + verify(f.__name__ == "g") + verify(f.func_name == "g") + f.func_name = "h" + verify(f.__name__ == "h") + verify(f.func_name == "h") + cantset(f, "func_globals", 1) + cantset(f, "__name__", 1) + # test that you can access func.__name__ in restricted mode + s = """def f(): pass\nf.__name__""" + exec s in {'__builtins__':{}} + def test_func_code(): + a = b = 24 def f(): pass def g(): print 12 - # XXX: changed to isinstance for jython - #verify(type(f.func_code) is types.CodeType) - verify(isinstance(f.func_code, types.CodeType)) + def f1(): print a + def g1(): print b + def f2(): print a, b + verify(type(f.func_code) is types.CodeType) f.func_code = g.func_code cantset(f, "func_code", None) + # can't change the number of free vars + cantset(f, "func_code", f1.func_code, exception=ValueError) + cantset(f1, "func_code", f.func_code, exception=ValueError) + cantset(f1, "func_code", f2.func_code, exception=ValueError) + f1.func_code = g1.func_code def test_func_defaults(): def f(a, b): return (a, b) @@ -368,6 +396,7 @@ def testmore(): test_func_closure() + test_empty_cell() test_func_doc() test_func_globals() test_func_name() Copied: branches/asm/ast/astview.py (from rev 4401, trunk/jython/ast/astview.py) =================================================================== --- branches/asm/ast/astview.py (rev 0) +++ branches/asm/ast/astview.py 2008-05-14 19:44:50 UTC (rev 4402) @@ -0,0 +1,78 @@ +#!/usr/bin/env python +"""lispify_ast - returns a tuple representation of the AST + +Uses 2.5's _ast, not other AST implementations in CPython, since these +are not used by the compilation phase. And that's what we're +interested in. + +Since this is a tuple, we can directly compare, and this is going to +be handy when comparing Jython's implementation vs CPython. + +""" + +import _ast +import sys + +if sys.platform.startswith('java'): + + get_symbol_key = lambda op: op + + def get_class_name(t): + result = t.__class__.__name__ + if result in ("org.python.antlr.ast.expr_contextType", + "org.python.antlr.ast.boolopType", + "org.python.antlr.ast.unaryopType", + "org.python.antlr.ast.cmpopType", + "org.python.antlr.ast.operatorType"): + result = str(t) + else: + result = result.split(".")[-1] + if result.endswith("Type"): + result = result[:-4] + if result == "Unicode": + result = "Str" + return result + +else: + get_symbol_key = type + get_class_name = lambda node: node.__class__.__name__ + +def lispify_ast(node): + return tuple(lispify_ast2(node)) + +def lispify_ast2(node): + yield get_class_name(node) + try: + for field in node._fields: + yield tuple(lispify_field(field, getattr(node, field))) + except: + pass + +def lispify_field(field, child): + yield field + if not hasattr(child, '__iter__'): + children = [child] + else: + children = child + + for node in children: + if isinstance(node, _ast.AST): + yield lispify_ast(node) + else: + if isinstance(node, float): + #XXX: stringify floats so they match Java's float representation better + #This may mask problems for very small numbers. + if .0001 < node < 10000: + yield "%5.5f" % node + else: + yield "%.5e" % node + else: + yield node + +def tree(pyfile): + ast = compile(open(pyfile).read(), pyfile, "exec", _ast.PyCF_ONLY_AST) + return lispify_ast(ast) + +if __name__ == '__main__': + import pprint + pprint.pprint(tree(sys.argv[1])) Modified: branches/asm/src/org/python/core/Py.java =================================================================== --- branches/asm/src/org/python/core/Py.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/core/Py.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -1968,7 +1968,7 @@ public PyObject _doget(PyObject container, PyObject wherefound) { if (container == null) return this; - return new PyMethod(container, this, wherefound); + return new PyMethod(this, container, wherefound); } public boolean _doset(PyObject container) { Modified: branches/asm/src/org/python/core/PyCell.java =================================================================== --- branches/asm/src/org/python/core/PyCell.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/core/PyCell.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -1,8 +1,35 @@ - +/* Copyright (c) Jython Developers */ package org.python.core; -public class PyCell extends PyObject { // ?? pending repr? +import org.python.expose.ExposedGet; +import org.python.expose.ExposedType; - public PyObject ob_ref; +/** + * The Python cell type. + * + * Cells are used to implement variables referenced by multiple + * scopes. + */ +@ExposedType(name = "cell") +public class PyCell extends PyObject { + /** The underlying content of the cell, or null. */ + public PyObject ob_ref; + + @ExposedGet(name = "cell_contents") + public PyObject getCellContents() { + if (ob_ref == null) { + throw Py.ValueError("Cell is empty"); + } + return ob_ref; + } + + @Override + public String toString() { + if (ob_ref == null) { + return String.format("<cell at %s: empty>", Py.idstr(this)); + } + return String.format("<cell at %s: %.80s object at %s>", Py.idstr(this), + ob_ref.getType().getName(), Py.idstr(ob_ref)); + } } Modified: branches/asm/src/org/python/core/PyClassMethod.java =================================================================== --- branches/asm/src/org/python/core/PyClassMethod.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/core/PyClassMethod.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -31,7 +31,7 @@ if(type == null) { type = obj.getType(); } - return new PyMethod(type, callable, type.getType()); + return new PyMethod(callable, type, type.getType()); } @ExposedNew Modified: branches/asm/src/org/python/core/PyFile.java =================================================================== --- branches/asm/src/org/python/core/PyFile.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/core/PyFile.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -157,8 +157,8 @@ } @ExposedNew - static final PyObject file_new(PyNewWrapper new_, boolean init, PyType subtype, PyObject[]args, - String[]keywords) { + static final PyObject file_new(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { PyFile newFile; if (new_.for_type == subtype) { if (init) { Modified: branches/asm/src/org/python/core/PyFunction.java =================================================================== --- branches/asm/src/org/python/core/PyFunction.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/core/PyFunction.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -1,219 +1,341 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; +import org.python.expose.ExposedDelete; +import org.python.expose.ExposedGet; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedSet; +import org.python.expose.ExposedType; + /** - * A python function. + * A Python function. */ +@ExposedType(name = "function") +public class PyFunction extends PyObject { -public class PyFunction extends PyObject -{ + public static final PyType TYPE = PyType.fromClass(PyFunction.class); + + /** The writable name, also available via func_name. */ + @ExposedGet + @ExposedSet public String __name__; + + /** The writable doc string, also available via func_doc. */ + @ExposedGet + @ExposedSet public PyObject __doc__; + + /** The read only namespace; a dict (PyStringMap). */ + @ExposedGet public PyObject func_globals; + + /** + * Default argument values for associated kwargs. Exposed as a + * tuple to Python. Writable. + */ public PyObject[] func_defaults; + + /** The actual funtion's code, writable. */ + @ExposedGet public PyCode func_code; + + /** + * A function's lazily created __dict__; allows arbitrary + * attributes to be tacked on. Read only. + */ public PyObject __dict__; - public PyObject func_closure; // nested scopes: closure - public PyObject __module__ = Py.None; - public PyFunction(PyObject globals, PyObject[] defaults, PyCode code, - PyObject doc,PyObject[] closure_cells) - { + /** A read only closure tuple for nested scopes. */ + @ExposedGet + public PyObject func_closure; + + /** Writable object describing what module this function belongs to. */ + @ExposedGet + @ExposedSet + public PyObject __module__; + + public PyFunction(PyObject globals, PyObject[] defaults, PyCode code, PyObject doc, + PyObject[] closure_cells) { func_globals = globals; __name__ = code.co_name; - if (doc == null) - __doc__ = Py.None; - else - __doc__ = doc; - func_defaults = defaults; + __doc__ = doc != null ? doc : Py.None; + func_defaults = defaults != null ? defaults : Py.EmptyObjects; func_code = code; - if (closure_cells != null) { - func_closure = new PyTuple(closure_cells); - } else { - func_closure = null; - } + func_closure = closure_cells != null ? new PyTuple(closure_cells) : Py.EmptyTuple; PyObject name = globals.__finditem__("__name__"); - if(name != null) { - __module__ = name; - } + __module__ = name != null ? name : Py.None; } - public PyFunction(PyObject globals, PyObject[] defaults, PyCode code, - PyObject doc) { - this(globals,defaults,code,doc,null); + public PyFunction(PyObject globals, PyObject[] defaults, PyCode code, PyObject doc) { + this(globals, defaults, code, doc, null); } public PyFunction(PyObject globals, PyObject[] defaults, PyCode code) { - this(globals, defaults, code, null,null); + this(globals, defaults, code, null, null); } public PyFunction(PyObject globals, PyObject[] defaults, PyCode code, - PyObject[] closure_cells) - { - this(globals, defaults, code, null,closure_cells); + PyObject[] closure_cells) { + this(globals, defaults, code, null, closure_cells); } + @ExposedNew + static final PyObject file_new(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { + ArgParser ap = new ArgParser("function", args, keywords, + new String[] {"code", "globals", "name", "argdefs", + "closure"}, + 0); + PyObject code = ap.getPyObject(0); + PyObject globals = ap.getPyObject(1); + PyObject name = ap.getPyObject(2, Py.None); + PyObject defaults = ap.getPyObject(3, Py.None); + PyObject closure = ap.getPyObject(4, Py.None); - private static final String[] __members__ = {"__doc__", - "func_doc", - "__name__", - "func_name", - "__dict__", - "__module__", - "func_globals", - "func_defaults", - "func_code", - "func_closure"}; + if (!(code instanceof PyTableCode)) { + throw Py.TypeError("function() argument 1 must be code, not str"); + } + if (name != Py.None && !Py.isInstance(name, PyString.TYPE)) { + throw Py.TypeError("arg 3 (name) must be None or string"); + } + if (defaults != Py.None && !(defaults instanceof PyTuple)) { + throw Py.TypeError("arg 4 (defaults) must be None or tuple"); + } - public PyObject __dir__() { - PyString members[] = new PyString[__members__.length]; - for (int i = 0; i < __members__.length; i++) - members[i] = new PyString(__members__[i]); - PyList ret = new PyList(members); - PyDictionary accum = new PyDictionary(); - addKeys(accum, "__dict__"); - ret.extend(accum.keys()); - ret.sort(); - return ret; - } + PyTableCode tcode = (PyTableCode)code; + int nfree = tcode.co_freevars == null ? 0 : tcode.co_freevars.length; + if (!(closure instanceof PyTuple)) { + if (nfree > 0 && closure == Py.None) { + throw Py.TypeError("arg 5 (closure) must be tuple"); + } else if (closure != Py.None) { + throw Py.TypeError("arg 5 (closure) must be None or tuple"); + } + } - private void throwReadonly(String name) { - for (int i = 0; i < __members__.length; i++) - if (__members__[i] == name) - throw Py.TypeError("readonly attribute"); - throw Py.AttributeError(name); - } - - public void __setattr__(String name, PyObject value) { - if (name == "func_doc" || name == "__doc__") - __doc__ = value; - else if (name == "func_closure") { - throwReadonly(name); + int nclosure = closure == Py.None ? 0 : closure.__len__(); + if (nfree != nclosure) { + throw Py.ValueError(String.format("%s requires closure of length %d, not %d", + tcode.co_name, nfree, nclosure)); } - else if (name == "__name__") - throwReadonly(name); - else if (name == "func_name") - throwReadonly(name); - else if (name == "func_defaults") { - if (value == Py.None) { - func_defaults = Py.EmptyObjects; - } else if (value instanceof PyTuple) { - func_defaults = ((PyTuple)value).getArray(); - } else { - throw Py.TypeError("func_defaults must be set to a tuple object"); + if (nclosure > 0) { + for (PyObject o : ((PyTuple)closure).asIterable()) { + if (!(o instanceof PyCell)) { + throw Py.TypeError(String.format("arg 5 (closure) expected cell, found %s", + o.getType().fastGetName())); + } } } - else if (name == "func_globals") - throwReadonly(name); - else if (name == "func_code") { - if (value instanceof PyCode) - func_code = (PyCode) value; - else - throw Py.TypeError("func_code must be set to a code object"); - } else if (name == "__dict__" || name == "func_dict") { - if (value instanceof PyDictionary || value instanceof PyStringMap) - __dict__ = value; - else - throw Py.TypeError("setting function's dictionary " + - "to a non-dict"); - } else if(name == "__module__") { - __module__ = value; - } else { - if (__dict__ == null) - __dict__ = new PyStringMap(); - __dict__.__setitem__(name, value); + + PyFunction function = new PyFunction(globals, + defaults == Py.None + ? Py.EmptyObjects : ((PyTuple)defaults).getArray(), + tcode, null, + closure == Py.None + ? null : ((PyTuple)closure).getArray()); + if (name != Py.None) { + function.__name__ = name.toString(); } + return function; } - public void __delattr__(String name) { - if (name == "__dict__" || name == "func_dict") { - throw Py.TypeError("function's dictionary may not be deleted"); - } else if (name == "func_defaults") { - func_defaults = Py.EmptyObjects; - return; - } else if (name == "func_doc" || name == "__doc__") { - __doc__ = Py.None; - return; - } else if(name == "__module__") { - __module__ = Py.None; - return; - } - if (__dict__ == null) - throw Py.AttributeError(name); - __dict__.__delitem__(name); + @ExposedGet(name = "func_name") + public String getFuncName() { + return __name__; } - public boolean isMappingType() { return false; } - public boolean isNumberType() { return false; } - public boolean isSequenceType() { return false; } + @ExposedSet(name = "func_name") + public void setFuncName(String func_name) { + __name__ = func_name; + } - public PyObject __findattr__(String name) { - // these are special, everything else is findable by reflection - if (name == "func_doc") - return __doc__; - if (name == "func_name") - return new PyString(__name__); - if (name == "func_closure") { - if (func_closure != null) return func_closure; + @ExposedGet(name = "func_doc") + public PyObject getFuncDoc() { + return __doc__; + } + + @ExposedSet(name = "func_doc") + public void setFuncDoc(PyObject func_doc) { + __doc__ = func_doc; + } + + @ExposedDelete(name = "func_doc") + public void delFuncDoc() { + delDoc(); + } + + @ExposedDelete(name = "__doc__") + public void delDoc() { + __doc__ = Py.None; + } + + @ExposedGet(name = "func_defaults") + public PyObject getFuncDefaults() { + if (func_defaults.length == 0) { return Py.None; } - if (name == "func_defaults") { - if (func_defaults.length == 0) - return Py.None; - return new PyTuple(func_defaults); + return new PyTuple(func_defaults); + } + + @ExposedSet(name = "func_defaults") + public void setFuncDefaults(PyObject func_defaults) { + if (func_defaults != Py.None && !(func_defaults instanceof PyTuple)) { + throw Py.TypeError("func_defaults must be set to a tuple object"); } - if (name == "__dict__" || name == "func_dict") { - if (__dict__ == null) - __dict__ = new PyStringMap(); - return __dict__; + this.func_defaults = func_defaults == Py.None + ? Py.EmptyObjects : ((PyTuple)func_defaults).getArray(); + } + + @ExposedDelete(name = "func_defaults") + public void delFuncDefaults() { + func_defaults = Py.EmptyObjects; + } + + @ExposedSet(name = "func_code") + public void setFuncCode(PyCode code) { + if (func_code == null || !(code instanceof PyTableCode)) { + throw Py.TypeError("func_code must be set to a code object"); } - if (__dict__ != null) { - PyObject ret = __dict__.__finditem__(name); - if (ret != null) - return ret; + PyTableCode tcode = (PyTableCode)code; + int nfree = tcode.co_freevars == null ? 0 : tcode.co_freevars.length; + int nclosure = func_closure.__len__(); + if (nclosure != nfree) { + throw Py.ValueError(String.format("%s() requires a code object with %d free vars," + + " not %d", __name__, nclosure, nfree)); } - return super.__findattr__(name); + this.func_code = code; } + @ExposedDelete(name = "__module__") + public void delModule() { + __module__ = Py.None; + } + + @Override + public PyObject fastGetDict() { + return __dict__; + } + + @ExposedGet(name = "__dict__") + public PyObject getDict() { + ensureDict(); + return __dict__; + } + + @ExposedSet(name = "__dict__") + public void setDict(PyObject value) { + if (!(value instanceof PyDictionary) && !(value instanceof PyStringMap)) { + throw Py.TypeError("setting function's dictionary to a non-dict"); + } + __dict__ = value; + } + + @ExposedDelete(name = "__dict__") + public void delDict() { + throw Py.TypeError("function's dictionary may not be deleted"); + } + + @ExposedGet(name = "func_dict") + public PyObject getFuncDict() { + return getDict(); + } + + @ExposedSet(name = "func_dict") + public void setFuncDict(PyObject value) { + setDict(value); + } + + @ExposedDelete(name = "func_dict") + public void delFuncDict() { + delDict(); + } + + @ExposedSet(name = "func_globals") + public void setFuncGlobals(PyObject value) { + // __setattr__ would set __dict__['func_globals'] = value + // without this method + throw Py.TypeError("readonly attribute"); + } + + @ExposedSet(name = "func_closure") + public void setFuncClosure(PyObject value) { + // same idea as setFuncGlobals + throw Py.TypeError("readonly attribute"); + } + + private void ensureDict() { + if (__dict__ == null) { + __dict__ = new PyStringMap(); + } + } + + @Override + public void __setattr__(String name, PyObject value) { + function___setattr__(name, value); + } + + @ExposedMethod + final void function___setattr__(String name, PyObject value) { + ensureDict(); + super.__setattr__(name, value); + } + + @Override public PyObject getDoc() { return __doc__; } - public PyObject _doget(PyObject container) { - return _doget(container, null); + @Override + public PyObject __get__(PyObject obj, PyObject type) { + return function___get__(obj, type); } - public PyObject _doget(PyObject container, PyObject wherefound) { - return new PyMethod(container, this, wherefound); + @ExposedMethod + final PyObject function___get__(PyObject obj, PyObject type) { + return new PyMethod(this, obj, type); } public PyObject __call__() { return func_code.call(func_globals, func_defaults, func_closure); } + public PyObject __call__(PyObject arg) { return func_code.call(arg, func_globals, func_defaults, func_closure); } + public PyObject __call__(PyObject arg1, PyObject arg2) { - return func_code.call(arg1, arg2, func_globals, func_defaults, - func_closure); + return func_code.call(arg1, arg2, func_globals, func_defaults, func_closure); } + public PyObject __call__(PyObject arg1, PyObject arg2, PyObject arg3) { return func_code.call(arg1, arg2, arg3, func_globals, func_defaults, func_closure); } public PyObject __call__(PyObject[] args, String[] keywords) { - return func_code.call(args, keywords, func_globals, func_defaults, - func_closure); + return function___call__(args, keywords); } - public PyObject __call__(PyObject arg1, PyObject[] args, - String[] keywords) - { - return func_code.call(arg1, args, keywords, func_globals, - func_defaults, func_closure); + + @ExposedMethod + final PyObject function___call__(PyObject[] args, String[] keywords) { + return func_code.call(args, keywords, func_globals, func_defaults, func_closure); } + public PyObject __call__(PyObject arg1, PyObject[] args, String[] keywords) { + return func_code.call(arg1, args, keywords, func_globals, func_defaults, func_closure); + } + + @Override public String toString() { return String.format("<function %s at %s>", __name__, Py.idstr(this)); } + + @Override + public boolean isMappingType() { return false; } + + @Override + public boolean isNumberType() { return false; } + + @Override + public boolean isSequenceType() { return false; } } Modified: branches/asm/src/org/python/core/PyInstance.java =================================================================== --- branches/asm/src/org/python/core/PyInstance.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/core/PyInstance.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -71,6 +71,9 @@ public PyInstance(PyClass iclass, PyObject dict) { instclass = iclass; + if (dict == Py.None) { + dict = new PyStringMap(); + } __dict__ = dict; } Modified: branches/asm/src/org/python/core/PyMethod.java =================================================================== --- branches/asm/src/org/python/core/PyMethod.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/core/PyMethod.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -11,24 +11,15 @@ public PyObject im_func; public PyObject im_class; - public PyMethod(PyObject self, PyObject f, PyObject wherefound) { - if(self == Py.None){ + public PyMethod(PyObject function, PyObject self, PyObject type) { + if (self == Py.None){ self = null; } - im_func = f; + im_func = function; im_self = self; - im_class = wherefound; + im_class = type; } - public PyMethod(PyObject self, PyFunction f, PyObject wherefound) { - this(self, (PyObject)f, wherefound); - } - - public PyMethod(PyObject self, PyReflectedFunction f, PyObject wherefound) - { - this(self, (PyObject)f, wherefound); - } - private static final String[] __members__ = { "im_self", "im_func", "im_class", "__doc__", "__dict__", @@ -77,18 +68,10 @@ public PyObject _doget(PyObject container, PyObject wherefound) { /* Only if classes are compatible */ - if(container == null || im_self != null) { + if (container == null || im_self != null) { return this; - } else if(__builtin__.issubclass(container.fastGetClass(), im_class)) { - if(im_func instanceof PyFunction) { - return new PyMethod(container, (PyFunction)im_func, im_class); - } else if(im_func instanceof PyReflectedFunction) { - return new PyMethod(container, - (PyReflectedFunction)im_func, - im_class); - } else { - return new PyMethod(container, im_func, im_class); - } + } else if (__builtin__.issubclass(container.fastGetClass(), im_class)) { + return new PyMethod(im_func, container, im_class); } else { return this; } Modified: branches/asm/src/org/python/core/PyReflectedFunction.java =================================================================== --- branches/asm/src/org/python/core/PyReflectedFunction.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/core/PyReflectedFunction.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -32,7 +32,7 @@ public PyObject _doget(PyObject container, PyObject wherefound) { if (container == null) return this; - return new PyMethod(container, this, wherefound); + return new PyMethod(this, container, wherefound); } public boolean _doset(PyObject container) { Modified: branches/asm/src/org/python/modules/Setup.java =================================================================== --- branches/asm/src/org/python/modules/Setup.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/modules/Setup.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -45,7 +45,7 @@ "sha", "ucnhash", "_jython", - "new:org.python.modules.newmodule", + "_new:org.python.modules._newmodule", "_weakref", "xreadlines", "errno", Copied: branches/asm/src/org/python/modules/_newmodule.java (from rev 4401, trunk/jython/src/org/python/modules/_newmodule.java) =================================================================== --- branches/asm/src/org/python/modules/_newmodule.java (rev 0) +++ branches/asm/src/org/python/modules/_newmodule.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -0,0 +1,32 @@ +/* Copyright (c) 2001, 2003 Finn Bock, Samuele Pedroni */ +package org.python.modules; + +import org.python.core.Py; +import org.python.core.PyClass; +import org.python.core.PyObject; +import org.python.core.PyTuple; +import org.python.core.PyType; + +/** + * The internal new module; just provides a hack for new.classobj. + * + */ +public class _newmodule { + + public static PyObject classobj(String name, PyTuple bases, PyObject dict) { + // XXX: Hack to return new style classes (originally from + // r4225). types.ClassType (PyClass) should be doing this + // instead, but it needs to be new style so it can return new + // style classes via __new__. When that happens we can use the + // pure python new.py completely + // XXX: This workaround can't be done in new.py (pure python) + // because the caller's stack frame would be wrong (which is + // used to determine the new class's __module__) + for (PyObject base : bases.getArray()) { + if (base instanceof PyType) { + return base.getType().__call__(Py.newString(name), bases, dict); + } + } + return new PyClass(name, bases, dict); + } +} Modified: branches/asm/src/org/python/modules/cPickle.java =================================================================== --- branches/asm/src/org/python/modules/cPickle.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/modules/cPickle.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -31,7 +31,6 @@ import org.python.core.PyJavaInstance; import org.python.core.PyList; import org.python.core.PyLong; -import org.python.core.PyMethod; import org.python.core.PyModule; import org.python.core.PyNone; import org.python.core.PyObject; Deleted: branches/asm/src/org/python/modules/newmodule.java =================================================================== --- branches/asm/src/org/python/modules/newmodule.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/modules/newmodule.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -1,101 +0,0 @@ -/* Copyright (c) 2001, 2003 Finn Bock, Samuele Pedroni */ -package org.python.modules; - -import org.python.core.Py; -import org.python.core.PyCell; -import org.python.core.PyClass; -import org.python.core.PyCode; -import org.python.core.PyFunction; -import org.python.core.PyInstance; -import org.python.core.PyMethod; -import org.python.core.PyModule; -import org.python.core.PyObject; -import org.python.core.PyTableCode; -import org.python.core.PyTuple; -import org.python.core.PyType; - -/** - * The new module. - * - * An interface to the interpreter object creation functions. - * - */ -public class newmodule { - - public static PyInstance instance(PyClass cls) { - return new PyInstance(cls); - } - - public static PyInstance instance(PyClass cls, PyObject dict) { - if (dict == Py.None) { - return new PyInstance(cls); - } else { - return new PyInstance(cls, dict); - } - } - - public static PyMethod instancemethod(PyObject func, PyObject instance, PyObject cls) { - return new PyMethod(instance, func, cls); - } - - public static PyFunction function(PyCode code, PyObject globals) { - return function(code, globals, null, Py.EmptyObjects, Py.None); - } - - public static PyFunction function(PyCode code, PyObject globals, String name) { - return function(code, globals, name, Py.EmptyObjects, Py.None); - } - - public static PyFunction function(PyCode code, PyObject globals, String name, - PyObject[] defaults) { - return function(code, globals, name, defaults, Py.None); - } - - public static PyFunction function(PyCode code, PyObject globals, String name, - PyObject[] defaults, PyObject closure) { - PyTableCode tcode = (PyTableCode)code; - int nfree = tcode.co_freevars == null ? 0 : tcode.co_freevars.length; - - if (!(closure instanceof PyTuple)) { - if (nfree > 0 && closure == Py.None) { - throw Py.TypeError("arg 5 (closure) must be tuple"); - } else if (closure != Py.None) { - throw Py.TypeError("arg 5 (closure) must be None or tuple"); - } - } - - int nclosure = closure == Py.None ? 0 : closure.__len__(); - if (nfree != nclosure) { - throw Py.ValueError(String.format("%s requires closure of length %d, not %d", - tcode.co_name, nfree, nclosure)); - } - if (nclosure > 0) { - for (PyObject o : ((PyTuple)closure).asIterable()) { - if (!(o instanceof PyCell)) { - throw Py.TypeError(String.format("arg 5 (closure) expected cell, found %s", - o.getType().fastGetName())); - } - } - } - - PyFunction f = new PyFunction(globals, defaults, code, null, - closure == Py.None ? null : ((PyTuple)closure).getArray()); - if (name != null) { - f.__name__ = name; - } - return f; - } - - public static PyModule module(String name) { - return new PyModule(name, null); - } - - public static PyObject classobj(String name, PyTuple bases, PyObject dict) { - for (int i = 0; i < bases.size(); i++) { - if (bases.pyget(i) instanceof PyType) { - return bases.pyget(i).__call__(Py.java2py(name), bases, dict); - } - } - return new PyClass(name, bases, dict); - } -} Modified: branches/asm/src/org/python/modules/synchronize.java =================================================================== --- branches/asm/src/org/python/modules/synchronize.java 2008-05-14 01:34:54 UTC (rev 4401) +++ branches/asm/src/org/python/modules/synchronize.java 2008-05-14 19:44:50 UTC (rev 4402) @@ -12,7 +12,7 @@ public PyObject _doget(PyObject container) { // TBD: third arg == null? Hmm... - return new PyMethod(container, this, null); + return new PyMethod(this, container, null); } public PyObject __call__() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-15 16:39:39
|
Revision: 4403 http://jython.svn.sourceforge.net/jython/?rev=4403&view=rev Author: fwierzbicki Date: 2008-05-15 09:39:30 -0700 (Thu, 15 May 2008) Log Message: ----------- Enough compiler and parser tweaking to keep site.py from exploding. Modified Paths: -------------- branches/asm/grammar/PythonWalker.g branches/asm/src/org/python/compiler/CodeCompiler.java branches/asm/src/org/python/core/Py.java Modified: branches/asm/grammar/PythonWalker.g =================================================================== --- branches/asm/grammar/PythonWalker.g 2008-05-14 19:44:50 UTC (rev 4402) +++ branches/asm/grammar/PythonWalker.g 2008-05-15 16:39:30 UTC (rev 4403) @@ -511,7 +511,7 @@ debug("matched expr_stmt:test " + $test.etype); $stmts::statements.add(new Expr($test.begin, $test.etype)); } - | ^(augassign targ=test[expr_contextType.Store] value=test[expr_contextType.Load]) { + | ^(augassign targ=test[expr_contextType.AugStore] value=test[expr_contextType.Load]) { AugAssign a = new AugAssign($targ.begin, $targ.etype, $augassign.op, $value.etype); $stmts::statements.add(a); } Modified: branches/asm/src/org/python/compiler/CodeCompiler.java =================================================================== --- branches/asm/src/org/python/compiler/CodeCompiler.java 2008-05-14 19:44:50 UTC (rev 4402) +++ branches/asm/src/org/python/compiler/CodeCompiler.java 2008-05-15 16:39:30 UTC (rev 4403) @@ -419,7 +419,7 @@ if (print_results) { code.invokestatic("org/python/core/Py", "printResult", "(" + $pyObj + ")V"); - } else { + } else if (!(node.value instanceof Yield)) { code.pop(); } return null; @@ -1475,6 +1475,7 @@ case Load: code.invokevirtual("org/python/core/PyObject", "__getslice__", "(" + $pyObj + $pyObj + $pyObj + ")" + $pyObj); return null; + case Param: case Store: code.aload(temporary); code.invokevirtual("org/python/core/PyObject", "__setslice__", "(" + $pyObj + $pyObj + $pyObj + $pyObj + ")V"); @@ -1511,6 +1512,7 @@ case Load: code.invokevirtual("org/python/core/PyObject", "__getitem__", "(" + $pyObj + ")" + $pyObj); return null; + case Param: case Store: code.aload(temporary); code.invokevirtual("org/python/core/PyObject", "__setitem__", "(" + $pyObj + $pyObj + ")V"); @@ -1556,6 +1558,7 @@ case Load: code.invokevirtual("org/python/core/PyObject", "__getattr__", "(" + $str + ")" + $pyObj); return null; + case Param: case Store: code.aload(temporary); code.invokevirtual("org/python/core/PyObject", "__setattr__", "(" + $str + $pyObj + ")V"); @@ -1644,9 +1647,9 @@ for (int i = node.generators.length - 1; i >= 0; i--) { comprehensionType lc = node.generators[i]; for (int j = lc.ifs.length - 1; j >= 0; j--) { - n = new If(lc.ifs[j], lc.ifs[j], new stmtType[] { n }, null); + n = new If(lc.ifs[j], lc.ifs[j], new stmtType[] { n }, new stmtType[0]); } - n = new For(lc, lc.target, lc.iter, new stmtType[] { n }, null); + n = new For(lc, lc.target, lc.iter, new stmtType[] { n }, new stmtType[0]); } visit(n); visit(new Delete(n, new exprType[] { new Name(n, tmp_append, expr_contextType.Del) })); @@ -1846,6 +1849,7 @@ code.invokevirtual("org/python/core/PyFrame", "getname", "(" + $str + ")" + $pyObj); return null; + case Param: case Store: loadFrame(); if (syminf != null && (syminf.flags&ScopeInfo.GLOBAL) != 0) { Modified: branches/asm/src/org/python/core/Py.java =================================================================== --- branches/asm/src/org/python/core/Py.java 2008-05-14 19:44:50 UTC (rev 4402) +++ branches/asm/src/org/python/core/Py.java 2008-05-15 16:39:30 UTC (rev 4403) @@ -1612,15 +1612,15 @@ public static PyObject compile_flags(InputStream istream, String filename, String type,CompilerFlags cflags) { + modType node = antlr.parse(istream, type, filename, cflags); if (cflags != null && cflags.only_ast) { - modType node = antlr.parse(istream, type, filename, cflags); return Py.java2py(node); } - modType node = antlr.parse(istream, type, filename, cflags); boolean printResults = false; - if (type.equals("single")) + if (type.equals("single")) { printResults = true; + } return Py.compile_flags(node, getName(), filename, true, printResults, cflags); } @@ -1968,7 +1968,7 @@ public PyObject _doget(PyObject container, PyObject wherefound) { if (container == null) return this; - return new PyMethod(this, container, wherefound); + return new PyMethod(container, this, wherefound); } public boolean _doset(PyObject container) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-15 22:11:20
|
Revision: 4407 http://jython.svn.sourceforge.net/jython/?rev=4407&view=rev Author: fwierzbicki Date: 2008-05-15 15:11:12 -0700 (Thu, 15 May 2008) Log Message: ----------- Merged revisions 4404 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4404 | fwierzbicki | 2008-05-15 15:13:41 -0400 (Thu, 15 May 2008) | 3 lines Finally found the fix for empty modules. Empty Lexer output causes a null tree to return. I've fixed by creating an empty Module node by hand for empty inuput. ........ Modified Paths: -------------- branches/asm/src/org/python/antlr/PythonGrammar.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4401 + /trunk/jython:1-4405 Modified: branches/asm/src/org/python/antlr/PythonGrammar.java =================================================================== --- branches/asm/src/org/python/antlr/PythonGrammar.java 2008-05-15 20:42:23 UTC (rev 4406) +++ branches/asm/src/org/python/antlr/PythonGrammar.java 2008-05-15 22:11:12 UTC (rev 4407) @@ -1,6 +1,7 @@ package org.python.antlr; import org.antlr.runtime.CharStream; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.RecognitionException; import org.antlr.runtime.Token; @@ -10,6 +11,8 @@ import org.antlr.runtime.tree.Tree; import org.antlr.runtime.tree.TreeAdaptor; import org.python.antlr.ast.modType; +import org.python.antlr.ast.Module; +import org.python.antlr.ast.stmtType; public class PythonGrammar { public static class PyLexer extends PythonLexer { @@ -77,12 +80,15 @@ try { Object rx = parser.file_input(); PythonParser.file_input_return r = (PythonParser.file_input_return)rx; - //System.out.println("tree: " + ((Tree) r.tree).toStringTree()); - //System.out.println("-----------------------------------"); CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); nodes.setTokenStream(tokens); PythonWalker walker = new PythonWalker(nodes); tree = walker.module(); + if (tree == null) { + //XXX: seems like I should be able to get antlr to give me an empty Module instead + // of null so I wouldn't need to build an empty Moduel by hand here... + return new Module(new PythonTree(new CommonToken(PyLexer.Module)), new stmtType[0]); + } } catch (RecognitionException e) { // FIXME: System.err.println("FIXME: don't eat exceptions:" + e); @@ -104,8 +110,6 @@ try { Object rx = parser.eval_input(); PythonParser.eval_input_return r = (PythonParser.eval_input_return)rx; - //System.out.println("tree: " + ((Tree) r.tree).toStringTree()); - //System.out.println("-----------------------------------"); CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); nodes.setTokenStream(tokens); PythonWalker walker = new PythonWalker(nodes); @@ -130,8 +134,6 @@ try { Object rx = parser.single_input(); PythonParser.single_input_return r = (PythonParser.single_input_return)rx; - //System.out.println("tree: " + ((Tree) r.tree).toStringTree()); - //System.out.println("-----------------------------------"); CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); nodes.setTokenStream(tokens); PythonWalker walker = new PythonWalker(nodes); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-17 16:18:37
|
Revision: 4417 http://jython.svn.sourceforge.net/jython/?rev=4417&view=rev Author: fwierzbicki Date: 2008-05-17 09:18:34 -0700 (Sat, 17 May 2008) Log Message: ----------- Merged revisions 4406,4409-4415 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4406 | pjenvey | 2008-05-15 16:42:23 -0400 (Thu, 15 May 2008) | 3 lines maintain func_defaults and func_closure as null instead of Py.EmptyObjects/EmptyTuple, to more closely resemble CPython ........ r4409 | pjenvey | 2008-05-15 19:52:01 -0400 (Thu, 15 May 2008) | 4 lines let null return values pass thru PyDataDescr get as None instead of triggering AttributeErrors. usually what we want anyway and makes @ExposedGet implementations easier ........ r4410 | pjenvey | 2008-05-15 22:03:31 -0400 (Thu, 15 May 2008) | 3 lines fix isinstance(newstyle_obj, oldstyle_class) always failing when it can be True via multiple inheritance. make isInstance more closely resemble CPython's ........ r4411 | pjenvey | 2008-05-16 13:55:45 -0400 (Fri, 16 May 2008) | 5 lines fix sets incorrectly raising a TypeError when asked for superset/subset on non-set iterables. also fixes a few other tests from 2.5 test_set fixes #1035 patch from Jonathan Ellis ........ r4412 | pjenvey | 2008-05-16 16:27:52 -0400 (Fri, 16 May 2008) | 1 line more ExposedGet now translating null for us ........ r4413 | pjenvey | 2008-05-16 17:19:03 -0400 (Fri, 16 May 2008) | 2 lines cleanup PyMethod, use exposed annotations ........ r4414 | pjenvey | 2008-05-16 19:30:52 -0400 (Fri, 16 May 2008) | 1 line more appropriate method name ........ r4415 | pjenvey | 2008-05-16 20:07:22 -0400 (Fri, 16 May 2008) | 7 lines use our Java set implementation only for the builtin sets, and use CPythonLib's sets module. so we can be more compatible with both versions compared to CPython, as there's a few differences between the two. moves modules.sets into core, PyImmutableSet -> PyFrozenSet, and causes test___all__ and CPythonLib's test_sets to now pass patch from Jonathan Ellis ........ Modified Paths: -------------- branches/asm/CPythonLib.includes branches/asm/CoreExposed.includes branches/asm/Lib/test/regrtest.py branches/asm/Lib/test/test_class_jy.py branches/asm/src/org/python/core/Py.java branches/asm/src/org/python/core/PyDataDescr.java branches/asm/src/org/python/core/PyFunction.java branches/asm/src/org/python/core/PyMethod.java branches/asm/src/org/python/core/PyModule.java branches/asm/src/org/python/core/PyTableCode.java branches/asm/src/org/python/core/PyType.java branches/asm/src/org/python/core/__builtin__.java branches/asm/src/org/python/modules/Setup.java branches/asm/src/templates/mappings Added Paths: ----------- branches/asm/src/org/python/core/BaseSet.java branches/asm/src/org/python/core/PyFrozenSet.java branches/asm/src/org/python/core/PyFrozenSetDerived.java branches/asm/src/org/python/core/PySet.java branches/asm/src/org/python/core/PySetDerived.java branches/asm/src/org/python/core/PySetIterator.java branches/asm/src/templates/frozenset.derived Removed Paths: ------------- branches/asm/Lib/test/test_sets.py branches/asm/src/org/python/modules/sets/ branches/asm/src/templates/immutableset.derived Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4405 + /trunk/jython:1-4416 Modified: branches/asm/CPythonLib.includes =================================================================== --- branches/asm/CPythonLib.includes 2008-05-17 02:23:25 UTC (rev 4416) +++ branches/asm/CPythonLib.includes 2008-05-17 16:18:34 UTC (rev 4417) @@ -105,6 +105,7 @@ rfc822.py rlcompleter.py sched.py +sets.py sgmllib.py shelve.py shlex.py Modified: branches/asm/CoreExposed.includes =================================================================== --- branches/asm/CoreExposed.includes 2008-05-17 02:23:25 UTC (rev 4416) +++ branches/asm/CoreExposed.includes 2008-05-17 16:18:34 UTC (rev 4417) @@ -11,15 +11,18 @@ org/python/core/PyEnumerate.class org/python/core/PyFile.class org/python/core/PyFloat.class +org/python/core/PyFrozenSet.class org/python/core/PyFunction.class org/python/core/PyInteger.class org/python/core/PyList.class org/python/core/PyLong.class +org/python/core/PyMethod.class org/python/core/PyMethodDescr.class org/python/core/PyModule.class org/python/core/PyNone.class org/python/core/PyObject.class org/python/core/PyProperty.class +org/python/core/PySet.class org/python/core/PySlice.class org/python/core/PySlot.class org/python/core/PyStaticMethod.class @@ -32,8 +35,6 @@ org/python/modules/collections/PyDefaultDict.class org/python/modules/collections/PyDeque.class org/python/modules/random/PyRandom.class -org/python/modules/sets/PyImmutableSet.class -org/python/modules/sets/PySet.class org/python/modules/time/PyTimeTuple.class org/python/modules/zipimport/zipimporter.class org/python/modules/PyTeeIterator.class Modified: branches/asm/Lib/test/regrtest.py =================================================================== --- branches/asm/Lib/test/regrtest.py 2008-05-17 02:23:25 UTC (rev 4416) +++ branches/asm/Lib/test/regrtest.py 2008-05-17 16:18:34 UTC (rev 4417) @@ -1018,7 +1018,6 @@ _failures = { 'java': ''' - test___all__ test_class test_copy test_dis Modified: branches/asm/Lib/test/test_class_jy.py =================================================================== --- branches/asm/Lib/test/test_class_jy.py 2008-05-17 02:23:25 UTC (rev 4416) +++ branches/asm/Lib/test/test_class_jy.py 2008-05-17 16:18:34 UTC (rev 4417) @@ -226,11 +226,28 @@ 'JYTHON', 'SOMECLASS']) +class IsDescendentTestCase(unittest.TestCase): + + def test_newstyle_descendent_of_oldstyle(self): + class NewStyle(object): + pass + class OldStyle: + pass + class Retro(NewStyle, OldStyle): + pass + self.assert_(issubclass(Retro, NewStyle)) + self.assert_(issubclass(Retro, OldStyle)) + retro = Retro() + self.assert_(isinstance(retro, NewStyle)) + self.assert_(isinstance(retro, OldStyle)) + + def test_main(): test_support.run_unittest(ClassGeneralTestCase, ClassNamelessModuleTestCase, BrokenNameTestCase, - ClassLocalsTestCase) + ClassLocalsTestCase, + IsDescendentTestCase) if __name__ == "__main__": Deleted: branches/asm/Lib/test/test_sets.py =================================================================== --- branches/asm/Lib/test/test_sets.py 2008-05-17 02:23:25 UTC (rev 4416) +++ branches/asm/Lib/test/test_sets.py 2008-05-17 16:18:34 UTC (rev 4417) @@ -1,793 +0,0 @@ -#!/usr/bin/env python - -from __future__ import generators - -import unittest, operator, copy, pickle -from sets import Set, ImmutableSet -from test import test_support - -empty_set = Set() - -#============================================================================== - -class TestBasicOps(unittest.TestCase): - - def test_repr(self): - if self.repr is not None: - self.assertEqual(`self.set`, self.repr) - - def test_length(self): - self.assertEqual(len(self.set), self.length) - - def test_self_equality(self): - self.assertEqual(self.set, self.set) - - def test_equivalent_equality(self): - self.assertEqual(self.set, self.dup) - - def test_copy(self): - self.assertEqual(self.set.copy(), self.dup) - - def test_self_union(self): - result = self.set | self.set - self.assertEqual(result, self.dup) - - def test_empty_union(self): - result = self.set | empty_set - self.assertEqual(result, self.dup) - - def test_union_empty(self): - result = empty_set | self.set - self.assertEqual(result, self.dup) - - def test_self_intersection(self): - result = self.set & self.set - self.assertEqual(result, self.dup) - - def test_empty_intersection(self): - result = self.set & empty_set - self.assertEqual(result, empty_set) - - def test_intersection_empty(self): - result = empty_set & self.set - self.assertEqual(result, empty_set) - - def test_self_symmetric_difference(self): - result = self.set ^ self.set - self.assertEqual(result, empty_set) - - def checkempty_symmetric_difference(self): - result = self.set ^ empty_set - self.assertEqual(result, self.set) - - def test_self_difference(self): - result = self.set - self.set - self.assertEqual(result, empty_set) - - def test_empty_difference(self): - result = self.set - empty_set - self.assertEqual(result, self.dup) - - def test_empty_difference_rev(self): - result = empty_set - self.set - self.assertEqual(result, empty_set) - - def test_iteration(self): - for v in self.set: - self.assert_(v in self.values) - - def _test_pickling(self): - p = pickle.dumps(self.set) - copy = pickle.loads(p) - self.assertEqual(self.set, copy, - "%s != %s" % (self.set, copy)) - -#------------------------------------------------------------------------------ - -class TestBasicOpsEmpty(TestBasicOps): - def setUp(self): - self.case = "empty set" - self.values = [] - self.set = Set(self.values) - self.dup = Set(self.values) - self.length = 0 - self.repr = "Set([])" - -#------------------------------------------------------------------------------ - -class TestBasicOpsSingleton(TestBasicOps): - def setUp(self): - self.case = "unit set (number)" - self.values = [3] - self.set = Set(self.values) - self.dup = Set(self.values) - self.length = 1 - self.repr = "Set([3])" - - def test_in(self): - self.failUnless(3 in self.set) - - def test_not_in(self): - self.failUnless(2 not in self.set) - -#------------------------------------------------------------------------------ - -class TestBasicOpsTuple(TestBasicOps): - def setUp(self): - self.case = "unit set (tuple)" - self.values = [(0, "zero")] - self.set = Set(self.values) - self.dup = Set(self.values) - self.length = 1 - self.repr = "Set([(0, 'zero')])" - - def test_in(self): - self.failUnless((0, "zero") in self.set) - - def test_not_in(self): - self.failUnless(9 not in self.set) - -#------------------------------------------------------------------------------ - -class TestBasicOpsTriple(TestBasicOps): - def setUp(self): - self.case = "triple set" - self.values = [0, "zero", operator.add] - self.set = Set(self.values) - self.dup = Set(self.values) - self.length = 3 - self.repr = None - -#============================================================================== - -def baditer(): - raise TypeError - yield True - -def gooditer(): - yield True - -class TestExceptionPropagation(unittest.TestCase): - """SF 628246: Set constructor should not trap iterator TypeErrors""" - - def test_instanceWithException(self): - self.assertRaises(TypeError, Set, baditer()) - - def test_instancesWithoutException(self): - # All of these iterables should load without exception. - Set([1,2,3]) - Set((1,2,3)) - Set({'one':1, 'two':2, 'three':3}) - Set(xrange(3)) - Set('abc') - Set(gooditer()) - -#============================================================================== - -class TestSetOfSets(unittest.TestCase): - def test_constructor(self): - inner = Set([1]) - outer = Set([inner]) - element = outer.pop() - self.assertEqual(type(element), ImmutableSet) - outer.add(inner) # Rebuild set of sets with .add method - outer.remove(inner) - self.assertEqual(outer, Set()) # Verify that remove worked - outer.discard(inner) # Absence of KeyError indicates working fine - -#============================================================================== - -class TestBinaryOps(unittest.TestCase): - def setUp(self): - self.set = Set((2, 4, 6)) - - def test_eq(self): # SF bug 643115 - self.assertEqual(self.set, Set({2:1,4:3,6:5})) - - def test_union_subset(self): - result = self.set | Set([2]) - self.assertEqual(result, Set((2, 4, 6))) - - def test_union_superset(self): - result = self.set | Set([2, 4, 6, 8]) - self.assertEqual(result, Set([2, 4, 6, 8])) - - def test_union_overlap(self): - result = self.set | Set([3, 4, 5]) - self.assertEqual(result, Set([2, 3, 4, 5, 6])) - - def test_union_non_overlap(self): - result = self.set | Set([8]) - self.assertEqual(result, Set([2, 4, 6, 8])) - - def test_intersection_subset(self): - result = self.set & Set((2, 4)) - self.assertEqual(result, Set((2, 4))) - - def test_intersection_superset(self): - result = self.set & Set([2, 4, 6, 8]) - self.assertEqual(result, Set([2, 4, 6])) - - def test_intersection_overlap(self): - result = self.set & Set([3, 4, 5]) - self.assertEqual(result, Set([4])) - - def test_intersection_non_overlap(self): - result = self.set & Set([8]) - self.assertEqual(result, empty_set) - - def test_sym_difference_subset(self): - result = self.set ^ Set((2, 4)) - self.assertEqual(result, Set([6])) - - def test_sym_difference_superset(self): - result = self.set ^ Set((2, 4, 6, 8)) - self.assertEqual(result, Set([8])) - - def test_sym_difference_overlap(self): - result = self.set ^ Set((3, 4, 5)) - self.assertEqual(result, Set([2, 3, 5, 6])) - - def test_sym_difference_non_overlap(self): - result = self.set ^ Set([8]) - self.assertEqual(result, Set([2, 4, 6, 8])) - - def _test_cmp(self): - a, b = Set('a'), Set('b') - self.assertRaises(TypeError, cmp, a, b) - - # You can view this as a buglet: cmp(a, a) does not raise TypeError, - # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True, - # which Python thinks is good enough to synthesize a cmp() result - # without calling __cmp__. - self.assertEqual(cmp(a, a), 0) - - self.assertRaises(TypeError, cmp, a, 12) - self.assertRaises(TypeError, cmp, "abc", a) - -#============================================================================== - -class TestUpdateOps(unittest.TestCase): - def setUp(self): - self.set = Set((2, 4, 6)) - - def test_union_subset(self): - self.set |= Set([2]) - self.assertEqual(self.set, Set((2, 4, 6))) - - def test_union_superset(self): - self.set |= Set([2, 4, 6, 8]) - self.assertEqual(self.set, Set([2, 4, 6, 8])) - - def test_union_overlap(self): - self.set |= Set([3, 4, 5]) - self.assertEqual(self.set, Set([2, 3, 4, 5, 6])) - - def test_union_non_overlap(self): - self.set |= Set([8]) - self.assertEqual(self.set, Set([2, 4, 6, 8])) - - def test_union_method_call(self): - self.set.union_update(Set([3, 4, 5])) - self.assertEqual(self.set, Set([2, 3, 4, 5, 6])) - - def test_intersection_subset(self): - self.set &= Set((2, 4)) - self.assertEqual(self.set, Set((2, 4))) - - def test_intersection_superset(self): - self.set &= Set([2, 4, 6, 8]) - self.assertEqual(self.set, Set([2, 4, 6])) - - def test_intersection_overlap(self): - self.set &= Set([3, 4, 5]) - self.assertEqual(self.set, Set([4])) - - def test_intersection_non_overlap(self): - self.set &= Set([8]) - self.assertEqual(self.set, empty_set) - - def test_intersection_method_call(self): - self.set.intersection_update(Set([3, 4, 5])) - self.assertEqual(self.set, Set([4])) - - def test_sym_difference_subset(self): - self.set ^= Set((2, 4)) - self.assertEqual(self.set, Set([6])) - - def test_sym_difference_superset(self): - self.set ^= Set((2, 4, 6, 8)) - self.assertEqual(self.set, Set([8])) - - def test_sym_difference_overlap(self): - self.set ^= Set((3, 4, 5)) - self.assertEqual(self.set, Set([2, 3, 5, 6])) - - def test_sym_difference_non_overlap(self): - self.set ^= Set([8]) - self.assertEqual(self.set, Set([2, 4, 6, 8])) - - def test_sym_difference_method_call(self): - self.set.symmetric_difference_update(Set([3, 4, 5])) - self.assertEqual(self.set, Set([2, 3, 5, 6])) - - def test_difference_subset(self): - self.set -= Set((2, 4)) - self.assertEqual(self.set, Set([6])) - - def test_difference_superset(self): - self.set -= Set((2, 4, 6, 8)) - self.assertEqual(self.set, Set([])) - - def test_difference_overlap(self): - self.set -= Set((3, 4, 5)) - self.assertEqual(self.set, Set([2, 6])) - - def test_difference_non_overlap(self): - self.set -= Set([8]) - self.assertEqual(self.set, Set([2, 4, 6])) - - def test_difference_method_call(self): - self.set.difference_update(Set([3, 4, 5])) - self.assertEqual(self.set, Set([2, 6])) - -#============================================================================== - -class TestMutate(unittest.TestCase): - def setUp(self): - self.values = ["a", "b", "c"] - self.set = Set(self.values) - - def test_add_present(self): - self.set.add("c") - self.assertEqual(self.set, Set("abc")) - - def test_add_absent(self): - self.set.add("d") - self.assertEqual(self.set, Set("abcd")) - - def test_add_until_full(self): - tmp = Set() - expected_len = 0 - for v in self.values: - tmp.add(v) - expected_len += 1 - self.assertEqual(len(tmp), expected_len) - self.assertEqual(tmp, self.set) - - def test_remove_present(self): - self.set.remove("b") - self.assertEqual(self.set, Set("ac")) - - def test_remove_absent(self): - try: - self.set.remove("d") - self.fail("Removing missing element should have raised LookupError") - except LookupError: - pass - - def test_remove_until_empty(self): - expected_len = len(self.set) - for v in self.values: - self.set.remove(v) - expected_len -= 1 - self.assertEqual(len(self.set), expected_len) - - def test_discard_present(self): - self.set.discard("c") - self.assertEqual(self.set, Set("ab")) - - def test_discard_absent(self): - self.set.discard("d") - self.assertEqual(self.set, Set("abc")) - - def test_clear(self): - self.set.clear() - self.assertEqual(len(self.set), 0) - - def test_pop(self): - popped = {} - while self.set: - popped[self.set.pop()] = None - self.assertEqual(len(popped), len(self.values)) - for v in self.values: - self.failUnless(v in popped) - - def test_update_empty_tuple(self): - self.set.union_update(()) - self.assertEqual(self.set, Set(self.values)) - - def test_update_unit_tuple_overlap(self): - self.set.union_update(("a",)) - self.assertEqual(self.set, Set(self.values)) - - def test_update_unit_tuple_non_overlap(self): - self.set.union_update(("a", "z")) - self.assertEqual(self.set, Set(self.values + ["z"])) - -#============================================================================== - -class TestSubsets(unittest.TestCase): - - case2method = {"<=": "issubset", - ">=": "issuperset", - } - - reverse = {"==": "==", - "!=": "!=", - "<": ">", - ">": "<", - "<=": ">=", - ">=": "<=", - } - - def test_issubset(self): - x = self.left - y = self.right - for case in "!=", "==", "<", "<=", ">", ">=": - expected = case in self.cases - # Test the binary infix spelling. - result = eval("x" + case + "y", locals()) - self.assertEqual(result, expected) - # Test the "friendly" method-name spelling, if one exists. - if case in TestSubsets.case2method: - method = getattr(x, TestSubsets.case2method[case]) - result = method(y) - self.assertEqual(result, expected) - - # Now do the same for the operands reversed. - rcase = TestSubsets.reverse[case] - result = eval("y" + rcase + "x", locals()) - self.assertEqual(result, expected) - if rcase in TestSubsets.case2method: - method = getattr(y, TestSubsets.case2method[rcase]) - result = method(x) - self.assertEqual(result, expected) -#------------------------------------------------------------------------------ - -class TestSubsetEqualEmpty(TestSubsets): - left = Set() - right = Set() - name = "both empty" - cases = "==", "<=", ">=" - -#------------------------------------------------------------------------------ - -class TestSubsetEqualNonEmpty(TestSubsets): - left = Set([1, 2]) - right = Set([1, 2]) - name = "equal pair" - cases = "==", "<=", ">=" - -#------------------------------------------------------------------------------ - -class TestSubsetEmptyNonEmpty(TestSubsets): - left = Set() - right = Set([1, 2]) - name = "one empty, one non-empty" - cases = "!=", "<", "<=" - -#------------------------------------------------------------------------------ - -class TestSubsetPartial(TestSubsets): - left = Set([1]) - right = Set([1, 2]) - name = "one a non-empty proper subset of other" - cases = "!=", "<", "<=" - -#------------------------------------------------------------------------------ - -class TestSubsetNonOverlap(TestSubsets): - left = Set([1]) - right = Set([2]) - name = "neither empty, neither contains" - cases = "!=" - -#============================================================================== - -class TestOnlySetsInBinaryOps(unittest.TestCase): - - def test_eq_ne(self): - # Unlike the others, this is testing that == and != *are* allowed. - self.assertEqual(self.other == self.set, False) - self.assertEqual(self.set == self.other, False) - self.assertEqual(self.other != self.set, True) - self.assertEqual(self.set != self.other, True) - - def test_ge_gt_le_lt(self): - self.assertRaises(TypeError, lambda: self.set < self.other) - self.assertRaises(TypeError, lambda: self.set <= self.other) - self.assertRaises(TypeError, lambda: self.set > self.other) - self.assertRaises(TypeError, lambda: self.set >= self.other) - - self.assertRaises(TypeError, lambda: self.other < self.set) - self.assertRaises(TypeError, lambda: self.other <= self.set) - self.assertRaises(TypeError, lambda: self.other > self.set) - self.assertRaises(TypeError, lambda: self.other >= self.set) - - def test_union_update_operator(self): - try: - self.set |= self.other - except TypeError: - pass - else: - self.fail("expected TypeError") - - def test_union_update(self): - if self.otherIsIterable: - self.set.union_update(self.other) - else: - self.assertRaises(TypeError, self.set.union_update, self.other) - - def test_union(self): - self.assertRaises(TypeError, lambda: self.set | self.other) - self.assertRaises(TypeError, lambda: self.other | self.set) - if self.otherIsIterable: - self.set.union(self.other) - else: - self.assertRaises(TypeError, self.set.union, self.other) - - def test_intersection_update_operator(self): - try: - self.set &= self.other - except TypeError: - pass - else: - self.fail("expected TypeError") - - def test_intersection_update(self): - if self.otherIsIterable: - self.set.intersection_update(self.other) - else: - self.assertRaises(TypeError, - self.set.intersection_update, - self.other) - - def test_intersection(self): - self.assertRaises(TypeError, lambda: self.set & self.other) - self.assertRaises(TypeError, lambda: self.other & self.set) - if self.otherIsIterable: - self.set.intersection(self.other) - else: - self.assertRaises(TypeError, self.set.intersection, self.other) - - def test_sym_difference_update_operator(self): - try: - self.set ^= self.other - except TypeError: - pass - else: - self.fail("expected TypeError") - - def test_sym_difference_update(self): - if self.otherIsIterable: - self.set.symmetric_difference_update(self.other) - else: - self.assertRaises(TypeError, - self.set.symmetric_difference_update, - self.other) - - def test_sym_difference(self): - self.assertRaises(TypeError, lambda: self.set ^ self.other) - self.assertRaises(TypeError, lambda: self.other ^ self.set) - if self.otherIsIterable: - self.set.symmetric_difference(self.other) - else: - self.assertRaises(TypeError, self.set.symmetric_difference, self.other) - - def test_difference_update_operator(self): - try: - self.set -= self.other - except TypeError: - pass - else: - self.fail("expected TypeError") - - def test_difference_update(self): - if self.otherIsIterable: - self.set.difference_update(self.other) - else: - self.assertRaises(TypeError, - self.set.difference_update, - self.other) - - def test_difference(self): - self.assertRaises(TypeError, lambda: self.set - self.other) - self.assertRaises(TypeError, lambda: self.other - self.set) - if self.otherIsIterable: - self.set.difference(self.other) - else: - self.assertRaises(TypeError, self.set.difference, self.other) -#------------------------------------------------------------------------------ - -class TestOnlySetsNumeric(TestOnlySetsInBinaryOps): - def setUp(self): - self.set = Set((1, 2, 3)) - self.other = 19 - self.otherIsIterable = False - -#------------------------------------------------------------------------------ - -class TestOnlySetsDict(TestOnlySetsInBinaryOps): - def setUp(self): - self.set = Set((1, 2, 3)) - self.other = {1:2, 3:4} - self.otherIsIterable = True - -#------------------------------------------------------------------------------ - -class TestOnlySetsOperator(TestOnlySetsInBinaryOps): - def setUp(self): - self.set = Set((1, 2, 3)) - self.other = operator.add - self.otherIsIterable = False - -#------------------------------------------------------------------------------ - -class TestOnlySetsTuple(TestOnlySetsInBinaryOps): - def setUp(self): - self.set = Set((1, 2, 3)) - self.other = (2, 4, 6) - self.otherIsIterable = True - -#------------------------------------------------------------------------------ - -class TestOnlySetsString(TestOnlySetsInBinaryOps): - def setUp(self): - self.set = Set((1, 2, 3)) - self.other = 'abc' - self.otherIsIterable = True - -#------------------------------------------------------------------------------ - -class TestOnlySetsGenerator(TestOnlySetsInBinaryOps): - def setUp(self): - def gen(): - for i in xrange(0, 10, 2): - yield i - self.set = Set((1, 2, 3)) - self.other = gen() - self.otherIsIterable = True - -#============================================================================== - -class TestCopying(unittest.TestCase): - - def test_copy(self): - dup = self.set.copy() - dup_list = list(dup); dup_list.sort() - set_list = list(self.set); set_list.sort() - self.assertEqual(len(dup_list), len(set_list)) - for i in range(len(dup_list)): - self.failUnless(dup_list[i] is set_list[i]) - - def test_deep_copy(self): - dup = copy.deepcopy(self.set) - ##print type(dup), `dup` - dup_list = list(dup); dup_list.sort() - set_list = list(self.set); set_list.sort() - self.assertEqual(len(dup_list), len(set_list)) - for i in range(len(dup_list)): - self.assertEqual(dup_list[i], set_list[i]) - -#------------------------------------------------------------------------------ - -class TestCopyingEmpty(TestCopying): - def setUp(self): - self.set = Set() - -#------------------------------------------------------------------------------ - -class TestCopyingSingleton(TestCopying): - def setUp(self): - self.set = Set(["hello"]) - -#------------------------------------------------------------------------------ - -class TestCopyingTriple(TestCopying): - def setUp(self): - self.set = Set(["zero", 0, None]) - -#------------------------------------------------------------------------------ - -class TestCopyingTuple(TestCopying): - def setUp(self): - self.set = Set([(1, 2)]) - -#------------------------------------------------------------------------------ - -class TestCopyingNested(TestCopying): - def setUp(self): - self.set = Set([((1, 2), (3, 4))]) - -#============================================================================== - -class TestIdentities(unittest.TestCase): - def setUp(self): - self.a = Set('abracadabra') - self.b = Set('alacazam') - - def test_binopsVsSubsets(self): - a, b = self.a, self.b - self.assert_(a - b < a) - self.assert_(b - a < b) - self.assert_(a & b < a) - self.assert_(a & b < b) - self.assert_(a | b > a) - self.assert_(a | b > b) - self.assert_(a ^ b < a | b) - - def test_commutativity(self): - a, b = self.a, self.b - self.assertEqual(a&b, b&a) - self.assertEqual(a|b, b|a) - self.assertEqual(a^b, b^a) - if a != b: - self.assertNotEqual(a-b, b-a) - - def test_summations(self): - # check that sums of parts equal the whole - a, b = self.a, self.b - self.assertEqual((a-b)|(a&b)|(b-a), a|b) - self.assertEqual((a&b)|(a^b), a|b) - self.assertEqual(a|(b-a), a|b) - self.assertEqual((a-b)|b, a|b) - self.assertEqual((a-b)|(a&b), a) - self.assertEqual((b-a)|(a&b), b) - self.assertEqual((a-b)|(b-a), a^b) - - def test_exclusion(self): - # check that inverse operations show non-overlap - a, b, zero = self.a, self.b, Set() - self.assertEqual((a-b)&b, zero) - self.assertEqual((b-a)&a, zero) - self.assertEqual((a&b)&(a^b), zero) - -#============================================================================== - -def test_main(verbose=False): - - test_suite = unittest.TestSuite() - test_loader = unittest.TestLoader() - def suite_add(case): - test_suite.addTest(test_loader.loadTestsFromTestCase(case)) - for t in [ - TestSetOfSets, - TestExceptionPropagation, - TestBasicOpsEmpty, - TestBasicOpsSingleton, - TestBasicOpsTuple, - TestBasicOpsTriple, - TestBinaryOps, - TestUpdateOps, - TestMutate, - TestSubsetEqualEmpty, - TestSubsetEqualNonEmpty, - TestSubsetEmptyNonEmpty, - TestSubsetPartial, - TestSubsetNonOverlap, - TestOnlySetsNumeric, - TestOnlySetsDict, - TestOnlySetsOperator, - TestOnlySetsTuple, - TestOnlySetsString, - TestOnlySetsGenerator, - TestCopyingEmpty, - TestCopyingSingleton, - TestCopyingTriple, - TestCopyingTuple, - TestCopyingNested, - TestIdentities, - ]: - suite_add(t) - - _verbose = test_support.verbose - try: - test_support.verbose = verbose - test_support.run_suite(test_suite) - finally: - test_support.verbose = _verbose - -if __name__ == "__main__": - test_main(verbose=False) - Copied: branches/asm/src/org/python/core/BaseSet.java (from rev 4415, trunk/jython/src/org/python/core/BaseSet.java) =================================================================== --- branches/asm/src/org/python/core/BaseSet.java (rev 0) +++ branches/asm/src/org/python/core/BaseSet.java 2008-05-17 16:18:34 UTC (rev 4417) @@ -0,0 +1,497 @@ +package org.python.core; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +public abstract class BaseSet extends PyObject /*implements Set*/ { + + /** + * The underlying container. HashSet is used rather than Set because + * clone is protected on Object and I didn't want to cast. + */ + protected HashSet _set; + + /** + * Create a new, empty set instance. + */ + public BaseSet() { + super(); + this._set = new HashSet(); + } + + /** + * Create a new set instance from the values of the iterable object. + * + * @param data An iterable instance. + */ + public BaseSet(PyObject data) { + super(); + this._set = new HashSet(); + this._update(data); + } + + public BaseSet(PyType type) { + super(type); + this._set = new HashSet(); + } + + /** + * Update the underlying set with the contents of the iterable. + * + * @param data An iterable instance. + * @throws PyIgnoreMethodTag Ignore. + */ + protected void _update(PyObject data) throws PyIgnoreMethodTag { + if(data instanceof BaseSet) { + // Skip the iteration if both are sets + this._set.addAll(((BaseSet)data)._set); + return; + } + for (PyObject item : data.asIterable()) { + try { + this._set.add(item); + } catch (PyException e) { + this._set.add(asImmutable(e, item)); + } + } + } + + /** + * The union of <code>this</code> with <code>other</code>. <p/> <br/> (I.e. all elements + * that are in either set) + * + * @param other + * A <code>BaseSet</code> instance. + * @return The union of the two sets as a new set. + */ + public PyObject __or__(PyObject other) { + return baseset___or__(other); + } + + final PyObject baseset___or__(PyObject other) { + if (!(other instanceof BaseSet)) { + throw Py.TypeError("Not Implemented"); + } + return baseset_union(other); + } + + /** + * The intersection of the <code>this</code> with <code>other</code>. + * <p/> + * <br/> + * (I.e. all elements that are in both sets) + * + * @param other A <code>BaseSet</code> instance. + * @return The intersection of the two sets as a new set. + */ + public PyObject __and__(PyObject other) { + return baseset___and__(other); + } + + final PyObject baseset___and__(PyObject other) { + if (!(other instanceof BaseSet)) { + throw Py.TypeError("Not Implemented"); + } + return baseset_intersection(other); + } + + /** + * The difference of the <code>this</code> with <code>other</code>. + * <p/> + * <br/> + * (I.e. all elements that are in this set and not in the other) + * + * @param other A <code>BaseSet</code> instance. + * @return The difference of the two sets as a new set. + */ + public PyObject __sub__(PyObject other) { + return baseset___sub__(other); + } + + final PyObject baseset___sub__(PyObject other) { + if (!(other instanceof BaseSet)) { + throw Py.TypeError("Not Implemented"); + } + return difference(other); + } + + public PyObject difference(PyObject other) { + return baseset_difference(other); + } + + final PyObject baseset_difference(PyObject other) { + BaseSet bs = (other instanceof BaseSet) ? (BaseSet) other : new PySet(other); + Set set = bs._set; + BaseSet o = (BaseSet) this.getType().__call__(); + for (Object p : this._set) { + if (!set.contains(p)) { + o._set.add(p); + } + } + + return o; + } + + /** + * The symmetric difference of the <code>this</code> with <code>other</code>. + * <p/> + * <br/> + * (I.e. all elements that are in exactly one of the sets) + * + * @param other A <code>BaseSet</code> instance. + * @return The symmetric difference of the two sets as a new set. + */ + public PyObject __xor__(PyObject other) { + return baseset___xor__(other); + } + + final PyObject baseset___xor__(PyObject other) { + if (!(other instanceof BaseSet)) { + throw Py.TypeError("Not Implemented"); + } + return symmetric_difference(other); + } + + public PyObject symmetric_difference(PyObject other) { + return baseset_symmetric_difference(other); + } + + public PyObject baseset_symmetric_difference(PyObject other) { + BaseSet bs = (other instanceof BaseSet) ? (BaseSet) other : new PySet(other); + BaseSet o = (BaseSet) this.getType().__call__(); + for (Object p : this._set) { + if (!bs._set.contains(p)) { + o._set.add(p); + } + } + for (Object p : bs._set) { + if (!this._set.contains(p)) { + o._set.add(p); + } + } + return o; + } + + /** + * The hashCode of the set. Only immutable instances can be hashed. + * + * @return The hashCode of the set. + */ + public abstract int hashCode(); + + /** + * The length of the set. + * + * @return The length of the set. + */ + public int __len__() { + return baseset___len__(); + } + + final int baseset___len__() { + return this._set.size(); + } + + /** + * Determines if the instance is considered <code>true</code> by Python. + * This implementation returns true if the set is not empty. + * + * @return <code>true</code> if the set is not empty, <code>false</code> otherwise + */ + public boolean __nonzero__() { + return baseset___nonzero__(); + } + + final boolean baseset___nonzero__() { + return !this._set.isEmpty(); + } + + /** + * Produce an iterable object. + * + * @return An iteration of the set. + */ + public PyObject __iter__() { + return baseset___iter__(); + } + + final PyObject baseset___iter__() { + return new PySetIterator(this._set); + } + + public boolean __contains__(PyObject other) { + return baseset___contains__(other); + } + + final boolean baseset___contains__(PyObject other) { + return this._set.contains(other); + } + + public int __cmp__(PyObject other) { + return baseset___cmp__(other); + } + + final int baseset___cmp__(PyObject other) { + throw Py.TypeError("cannot compare sets using cmp()"); + } + + public PyObject __eq__(PyObject other) { + return baseset___eq__(other); + } + + final PyObject baseset___eq__(PyObject other) { + if (other instanceof BaseSet) { + return Py.newBoolean(this._set.equals(((BaseSet)other)._set)); + } + return Py.False; + } + + public PyObject __ne__(PyObject other) { + return baseset___ne__(other); + } + + final PyObject baseset___ne__(PyObject other) { + if(other instanceof BaseSet) { + return Py.newBoolean(!this._set.equals(((BaseSet)other)._set)); + } + return Py.True; + } + + public PyObject __le__(PyObject other) { + return baseset___le__(other); + } + + final PyObject baseset___le__(PyObject other) { + BaseSet bs = this._binary_sanity_check(other); + return this.baseset_issubset(other); + } + + public PyObject __ge__(PyObject other) { + return baseset___ge__(other); + } + + final PyObject baseset___ge__(PyObject other) { + BaseSet bs = this._binary_sanity_check(other); + return this.baseset_issuperset(other); + } + + public PyObject __lt__(PyObject other) { + return baseset___lt__(other); + } + + final PyObject baseset___lt__(PyObject other) { + BaseSet bs = this._binary_sanity_check(other); + return Py.newBoolean(this.__len__() < bs.__len__() + && this.baseset_issubset(other).__nonzero__()); + } + + public PyObject __gt__(PyObject other) { + return baseset___gt__(other); + } + + public PyObject baseset___gt__(PyObject other) { + BaseSet bs = this._binary_sanity_check(other); + return Py.newBoolean(this.__len__() > bs.__len__() + && this.baseset_issuperset(other).__nonzero__()); + } + + /** + * Used for pickling. Uses the module <code>setsfactory</sets> to + * export safe constructors. + * + * @return a tuple of (constructor, (elements)) + */ + public PyObject __reduce__() { + return baseset___reduce__(); + } + + final PyObject baseset___reduce__(){ + String name = getType().fastGetName(); + PyObject factory = __builtin__.__import__("setsfactory"); + PyObject func = factory.__getattr__(name); + return new PyTuple(func, new PyTuple(new PyList(this))); + } + + public PyObject __deepcopy__(PyObject memo) { + return baseset___deepcopy__(memo); + } + + final PyObject baseset___deepcopy__(PyObject memo) { + PyObject copy = __builtin__.__import__("copy"); + PyObject deepcopy = copy.__getattr__("deepcopy"); + BaseSet result = (BaseSet) this.getType().__call__(); + memo.__setitem__(Py.newInteger(Py.id(this)), result); + for (Object p : this._set) { + result._set.add(deepcopy.__call__(Py.java2py(p), memo)); + } + return result; + } + + /** + * Return this instance as a Java object. Only coerces to Collection and subinterfaces. + * + * @param c The Class to coerce to. + * @return the underlying HashSet (not a copy) + */ + public Object __tojava__(Class c) { + if (Collection.class.isAssignableFrom(c)) { + return Collections.unmodifiableSet(this._set); + } + return super.__tojava__(c); + } + + public PyObject baseset_union(PyObject other) { + BaseSet result = (BaseSet) this.getType().__call__(this); + result._update(other); + return result; + } + + public PyObject baseset_intersection(PyObject other) { + + PyObject little, big; + if(!(other instanceof BaseSet)) { + other = new PySet(other); + } + + if (this.__len__() <= __builtin__.len(other)) { + little = this; + big = other; + } else { + little = other; + big = this; + } + + PyObject common = __builtin__.filter(big.__getattr__("__contains__"), little); + return other.getType().__call__(common); + } + + public PyObject baseset_copy() { + BaseSet copy = (BaseSet) this.getType().__call__(); + copy._set = (HashSet) this._set.clone(); + return copy; + } + + public PyObject baseset_issubset(PyObject other) { + BaseSet bs = (other instanceof BaseSet) ? (BaseSet) other : new PySet(other); + if (this.__len__() > bs.__len__()) { + return Py.False; + } + for (Object p : this._set) { + if (!bs._set.contains(p)) { + return Py.False; + } + } + return Py.True; + } + + public PyObject baseset_issuperset(PyObject other) { + BaseSet bs = (other instanceof BaseSet) ? (BaseSet) other : new PySet(other); + if (this.__len__() < bs.__len__()) { + return Py.False; + } + for (Object p : bs._set) { + if (!this._set.contains(p)) { + return Py.False; + } + } + return Py.True; + } + + final String baseset_toString() { + return toString(); + } + + public String toString() { + String name = getType().fastGetName(); + StringBuffer buf = new StringBuffer(name).append("(["); + for (Iterator i = this._set.iterator(); i.hasNext();) { + buf.append(((PyObject) i.next()).__repr__().toString()); + if (i.hasNext()) { + buf.append(", "); + } + } + buf.append("])"); + return buf.toString(); + } + + protected final BaseSet _binary_sanity_check(PyObject other) throws PyIgnoreMethodTag { + try { + return (BaseSet) other; + } catch (ClassCastException e) { + throw Py.TypeError("Binary operation only permitted between sets"); + } + } + + /** + * If the exception <code>e</code> is a <code>TypeError</code>, attempt to convert + * the object <code>value</code> into an ImmutableSet. + * + * @param e The exception thrown from a hashable operation. + * @param value The object which was unhashable. + * @return An ImmutableSet if available, a <code>TypeError</code> is thrown otherwise. + */ + protected final PyObject asImmutable(PyException e, PyObject value) { + if (Py.matchException(e, Py.TypeError)) { + PyObject transform = value.__findattr__("_as_immutable"); + if (transform != null) { + return transform.__call__(); + } + } + throw e; + } + +// public int size() { +// return this._set.size(); +// } +// +// public void clear() { +// this._set.clear(); +// } +// +// public boolean isEmpty() { +// return this._set.isEmpty(); +// } +// +// public Object[] toArray() { +// return this._set.toArray(); +// } +// +// public boolean add(Object o) { +// return this._set.add(o); +// } +// +// public boolean contains(Object o) { +// return this._set.contains(o); +// } +// +// public boolean remove(Object o) { +// return this._set.remove(o); +// } +// +// public boolean addAll(Collection c) { +// return this._set.addAll(c); +// } +// +// public boolean containsAll(Collection c) { +// return this._set.containsAll(c); +// } +// +// public boolean removeAll(Collection c) { +// return this._set.removeAll(c); +// } +// +// public boolean retainAll(Collection c) { +// return this._set.retainAll(c); +// } +// +// public Iterator iterator() { +// return this._set.iterator(); +// } +// +// public Object[] toArray(Object a[]) { +// return this._set.toArray(a); +// } +} Modified: branches/asm/src/org/python/core/Py.java =================================================================== --- branches/asm/src/org/python/core/Py.java 2008-05-17 02:23:25 UTC (rev 4416) +++ branches/asm/src/org/python/core/Py.java 2008-05-17 16:18:34 UTC (rev 4417) @@ -1774,42 +1774,52 @@ return false; } - public static boolean isInstance(PyObject obj, PyObject cls) { - return isInstance(obj, cls, 0); + public static boolean isInstance(PyObject inst, PyObject cls) { + return recursiveIsInstance(inst, cls, 0); } - - private static boolean isInstance(PyObject obj, PyObject cls, int recursionDepth){ - if (cls instanceof PyType) { - PyType objtype = obj.getType(); - if (objtype == cls) + + private static boolean recursiveIsInstance(PyObject inst, PyObject cls, int recursionDepth) { + if (cls instanceof PyClass && inst instanceof PyInstance) { + PyClass inClass = (PyClass)inst.fastGetClass(); + return inClass.isSubClass((PyClass)cls); + } else if (cls instanceof PyType) { + PyType instType = inst.getType(); + PyType type = (PyType)cls; + + // equiv. to PyObject_TypeCheck + if (instType == type || instType.isSubType(type)) { return true; - return objtype.isSubType((PyType) cls); - } else if (cls instanceof PyClass) { - if (!(obj instanceof PyInstance)) - return false; - return ((PyClass) obj.fastGetClass()).isSubClass((PyClass) cls); - } else if (cls.getClass() == PyTuple.class) { - if(recursionDepth > Py.getSystemState().getrecursionlimit()) { + } + + PyObject c = inst.__findattr__("__class__"); + if (c != null && c != instType && c instanceof PyType) { + return ((PyType)c).isSubType(type); + } + return false; + } else if (cls instanceof PyTuple) { + if (recursionDepth > Py.getSystemState().getrecursionlimit()) { throw Py.RuntimeError("nest level of tuple too deep"); } - for (int i = 0; i < cls.__len__(); i++) { - if (isInstance(obj, cls.__getitem__(i), recursionDepth + 1)) { + + for (PyObject tupleItem : ((PyTuple)cls).getArray()) { + if (recursiveIsInstance(inst, tupleItem, recursionDepth + 1)) { return true; } } return false; } else { - if (cls.__findattr__("__bases__") == null) - throw Py.TypeError( - "isinstance() arg 2 must be a class, type," - + " or tuple of classes and types"); - PyObject ocls = obj.__findattr__("__class__"); - if (ocls == null) + if (cls.__findattr__("__bases__") == null) { + throw Py.TypeError("isinstance() arg 2 must be a class, type, or tuple of " + + "classes and types"); + } + + PyObject icls = inst.__findattr__("__class__"); + if (icls == null) { return false; - return abstract_issubclass(ocls, cls); + } + return abstract_issubclass(icls, cls); } } - public static boolean isSubClass(PyObject derived,PyObject cls) { return isSubClass(derived, cls, 0); Modified: branches/asm/src/org/python/core/PyDataDescr.java =================================================================== --- branches/asm/src/org/python/core/PyDataDescr.java 2008-05-17 02:23:25 UTC (rev 4416) +++ branches/asm/src/org/python/core/PyDataDescr.java 2008-05-17 16:18:34 UTC (rev 4417) @@ -60,11 +60,7 @@ public PyObject getset_descriptor___get__(PyObject obj, PyObject type) { if(obj != null) { checkGetterType(obj.getType()); - Object v = invokeGet(obj); - if(v == null) { - obj.noAttributeError(name); - } - return Py.java2py(v); + return Py.java2py(invokeGet(obj)); } return this; } Copied: branches/asm/src/org/python/core/PyFrozenSet.java (from rev 4415, trunk/jython/src/org/python/core/PyFrozenSet.java) =================================================================== --- branches/asm/src/org/python/core/PyFrozenSet.java (rev 0) +++ branches/asm/src/org/python/core/PyFrozenSet.java 2008-05-17 16:18:34 UTC (rev 4417) @@ -0,0 +1,172 @@ +package org.python.core; + +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedType; +import org.python.expose.MethodType; + +@ExposedType(name = "frozenset", base = PyObject.class) +public class PyFrozenSet extends BaseSet { + + public static final PyType TYPE = PyType.fromClass(PyFrozenSet.class); + + public PyFrozenSet() { + super(); + } + + public PyFrozenSet(PyType type) { + super(type); + } + + public PyFrozenSet(PyObject data) { + super(data); + } + + @ExposedNew + @ExposedMethod + final void frozenset___init__(PyObject[] args, String[] kwds) { + int nargs = args.length - kwds.length; + if (nargs > 1) { + throw PyBuiltinFunction.DefaultInfo.unexpectedCall(nargs, false, "FrozenSet", 0, 1); + } + if (nargs == 0) { + return; + } + + PyObject o = args[0]; + _update(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___cmp__(PyObject o) { + return new PyInteger(baseset___cmp__(o)); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___ne__(PyObject o) { + return baseset___ne__(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___eq__(PyObject o) { + return baseset___eq__(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___or__(PyObject o) { + return baseset___or__(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___xor__(PyObject o) { + return baseset___xor__(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___sub__(PyObject o) { + return baseset___sub__(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___and__(PyObject o) { + return baseset___and__(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___lt__(PyObject o) { + return baseset___lt__(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___gt__(PyObject o) { + return baseset___gt__(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___ge__(PyObject o) { + return baseset___ge__(o); + } + + @ExposedMethod(type = MethodType.BINARY) + final PyObject frozenset___le__(PyObject o) { + return baseset___le__(o); + } + + @ExposedMethod + final PyObject frozenset___iter__() { + return baseset___iter__(); + } + + @ExposedMethod + final boolean frozenset___contains__(PyObject item) { + return baseset___contains__(item); + } + + @ExposedMethod + final PyObject frozenset___deepcopy__(PyObject memo) { + return baseset___deepcopy__(memo); + } + + @ExposedMethod + final boolean frozenset___nonzero__() { + return baseset___nonzero__(); + } + + @ExposedMethod + final PyObject frozenset_copy() { + return baseset_copy(); + } + + @ExposedMethod + final PyObject frozenset_union(PyObject set) { + return baseset_union(set); + } + + @ExposedMethod + final PyObject frozenset_difference(PyObject set) { + return baseset_difference(set); + } + + @ExposedMethod + final PyObject frozenset_symmetric_difference(PyObject set) { + return baseset_symmetric_difference(set); + } + + @ExposedMethod + final PyObject frozenset_intersection(PyObject set) { + return baseset_intersection(set); + } + + @ExposedMethod + final PyObject frozenset_issubset(PyObject set) { + return baseset_issubset(set); + } + + @ExposedMethod + final PyObject frozenset_issuperset(PyObject set) { + return baseset_issuperset(set); + } + + @ExposedMethod + final int frozenset___len__() { + return baseset___len__(); + } + + @ExposedMethod + final PyObject frozenset___reduce__() { + return baseset___reduce__(); + } + + @ExposedMethod + final int frozenset___hash__() { + return hashCode(); + } + + public int hashCode() { + return this._set.hashCode(); + } + + public PyObject _as_immutable() { + return this; + } +} Copied: branches/asm/src/org/python/core/PyFrozenSetDerived.java (from rev 4415, trunk/jython/src/org/python/core/PyFrozenSetDerived.java) =================================================================== --- branches/asm/src/org/python/core/PyFrozenSetDerived.java (rev 0) +++ branches/asm/src/org/python/core/PyFrozenSetDerived.java 2008-05-17 16:18:34 UTC (rev 4417) @@ -0,0 +1,954 @@ +package org.python.core; + +public class PyFrozenSetDerived extends PyFrozenSet implements Slotted { + + public PyObject getSlot(int index) { + return slots[index]; + } + + public void setSlot(int index,PyObject value) { + slots[index]=value; + } + + private PyObject[]slots; + + private PyObject dict; + + public PyObject fastGetDict() { + return dict; + } + + public PyObject getDict() { + return dict; + } + + public void setDict(PyObject newDict) { + if (newDict instanceof PyStringMap||newDict instanceof PyDictionary) { + dict=newDict; + } else { + throw Py.TypeError("__dict__ must be set to a Dictionary "+newDict.getClass().getName()); + } + } + + public void delDict() { + // deleting an object's instance dict makes it grow a new one + dict=new PyStringMap(); + } + + public PyFrozenSetDerived(PyType subtype) { + super(subtype); + slots=new PyObject[subtype.getNumSlots()]; + dict=subtype.instDict(); + } + + public PyString __str__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__str__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyString) + return(PyString)res; + throw Py.TypeError("__str__"+" should return a "+"string"); + } + return super.__str__(); + } + + public PyString __repr__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__repr__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyString) + return(PyString)res; + throw Py.TypeError("__repr__"+" should return a "+"string"); + } + return super.__repr__(); + } + + public PyString __hex__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__hex__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyString) + return(PyString)res; + throw Py.TypeError("__hex__"+" should return a "+"string"); + } + return super.__hex__(); + } + + public PyString __oct__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__oct__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyString) + return(PyString)res; + throw Py.TypeError("__oct__"+" should return a "+"string"); + } + return super.__oct__(); + } + + public PyFloat __float__() { + PyType self_type=getType(); + PyObject impl=self_type.lookup("__float__"); + if (impl!=null) { + PyObject res=impl.__get__(this,self_type).__call__(); + if (res instanceof PyFloat) + return(PyFloat)res; + throw Py.TypeError("__float__"+" should return a "+"float"); + } + return super.__float__(); + } + + public PyLong __long__() { + PyType self_ty... [truncated message content] |
From: <fwi...@us...> - 2008-05-19 18:12:23
|
Revision: 4423 http://jython.svn.sourceforge.net/jython/?rev=4423&view=rev Author: fwierzbicki Date: 2008-05-19 11:12:21 -0700 (Mon, 19 May 2008) Log Message: ----------- Merged revisions 4419-4422 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4419 | pjenvey | 2008-05-17 19:09:27 -0400 (Sat, 17 May 2008) | 1 line match CPython's error message ........ r4420 | pjenvey | 2008-05-18 17:54:16 -0400 (Sun, 18 May 2008) | 1 line use String.format ........ r4421 | pjenvey | 2008-05-18 18:51:09 -0400 (Sun, 18 May 2008) | 1 line move the thread module into its own package ........ r4422 | pjenvey | 2008-05-18 19:00:22 -0400 (Sun, 18 May 2008) | 1 line small cleanup ........ Modified Paths: -------------- branches/asm/CoreExposed.includes branches/asm/src/org/python/core/PyModule.java branches/asm/src/org/python/core/PySet.java branches/asm/src/org/python/modules/Setup.java Added Paths: ----------- branches/asm/src/org/python/modules/thread/ branches/asm/src/org/python/modules/thread/PyLocal.java branches/asm/src/org/python/modules/thread/PyLocalDerived.java branches/asm/src/org/python/modules/thread/PyLock.java branches/asm/src/org/python/modules/thread/thread.java Removed Paths: ------------- branches/asm/src/org/python/modules/PyLocal.java branches/asm/src/org/python/modules/PyLocalDerived.java branches/asm/src/org/python/modules/PyLock.java branches/asm/src/org/python/modules/thread/PyLocal.java branches/asm/src/org/python/modules/thread/PyLocalDerived.java branches/asm/src/org/python/modules/thread/PyLock.java branches/asm/src/org/python/modules/thread/thread.java branches/asm/src/org/python/modules/thread.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4416 + /trunk/jython:1-4422 Modified: branches/asm/CoreExposed.includes =================================================================== --- branches/asm/CoreExposed.includes 2008-05-18 23:00:22 UTC (rev 4422) +++ branches/asm/CoreExposed.includes 2008-05-19 18:12:21 UTC (rev 4423) @@ -31,10 +31,10 @@ org/python/core/PyTuple.class org/python/core/PyType.class org/python/core/PyUnicode.class -org/python/modules/PyLocal.class org/python/modules/collections/PyDefaultDict.class org/python/modules/collections/PyDeque.class org/python/modules/random/PyRandom.class +org/python/modules/thread/PyLocal.class org/python/modules/time/PyTimeTuple.class org/python/modules/zipimport/zipimporter.class org/python/modules/PyTeeIterator.class Modified: branches/asm/src/org/python/core/PyModule.java =================================================================== --- branches/asm/src/org/python/core/PyModule.java 2008-05-18 23:00:22 UTC (rev 4422) +++ branches/asm/src/org/python/core/PyModule.java 2008-05-19 18:12:21 UTC (rev 4423) @@ -177,11 +177,9 @@ name = new PyString("?"); } if (filename == null) { - filename = new PyString("(built-in)"); - } else { - filename = new PyString("from '" + filename + "'"); + return String.format("<module '%s' (built-in)>", name); } - return "<module '" + name + "' " + filename + ">"; + return String.format("<module '%s' from '%s'>", name, filename); } public PyObject __dir__() { Modified: branches/asm/src/org/python/core/PySet.java =================================================================== --- branches/asm/src/org/python/core/PySet.java 2008-05-18 23:00:22 UTC (rev 4422) +++ branches/asm/src/org/python/core/PySet.java 2008-05-19 18:12:21 UTC (rev 4423) @@ -208,7 +208,7 @@ @ExposedMethod final int set___hash__() { - throw Py.TypeError("Can't hash a Set, only an FrozenSet."); + throw Py.TypeError("set objects are unhashable"); } @ExposedMethod Deleted: branches/asm/src/org/python/modules/PyLocal.java =================================================================== --- branches/asm/src/org/python/modules/PyLocal.java 2008-05-18 23:00:22 UTC (rev 4422) +++ branches/asm/src/org/python/modules/PyLocal.java 2008-05-19 18:12:21 UTC (rev 4423) @@ -1,88 +0,0 @@ -package org.python.modules; - -import org.python.core.Py; -import org.python.core.PyDictionary; -import org.python.core.PyNewWrapper; -import org.python.core.PyObject; -import org.python.core.PyType; -import org.python.expose.ExposedGet; -import org.python.expose.ExposedMethod; -import org.python.expose.ExposedNew; -import org.python.expose.ExposedSet; -import org.python.expose.ExposedType; - -@ExposedType(name = "thread._local") -public class PyLocal extends PyObject { - - public static final PyType TYPE = PyType.fromClass(PyLocal.class); - - private ThreadLocal<PyDictionary> tdict = new ThreadLocal<PyDictionary>(); - - private PyObject args[]; - - private String keywords[]; - - public PyLocal() { - this(TYPE); - } - - public PyLocal(PyType subType) { - super(subType); - // Because the instantiation of a type instance in PyType.invoke_new_ - // calls dispatch__init__, we call tdict.set here so dispatch__init__ - // doesn't get called a second time for a thread in fastGetDict - tdict.set(new PyDictionary()); - } - - @ExposedNew - final static PyObject _local___new__(PyNewWrapper new_, - boolean init, - PyType subtype, - PyObject[] args, - String[] keywords) { - PyLocal newobj; - if (new_.getWrappedType() == subtype) { - newobj = new PyLocal(); - } else { - newobj = new PyLocalDerived(subtype); - } - if (init) { - newobj._local___init__(args, keywords); - } - return newobj; - } - - @ExposedMethod - final void _local___init__(PyObject[] args, String[] keywords) { - PyObject[] where = new PyObject[1]; - getType().lookup_where("__init__", where); - if (where[0] == TYPE && args.length > 0) { - throw Py.TypeError("Initialization arguments are not supported"); - } - this.args = args; - this.keywords = keywords; - } - - @Override - @ExposedGet(name = "__dict__") - public PyObject getDict() { - return fastGetDict(); - } - - @Override - @ExposedSet(name = "__dict__") - public void setDict(PyObject dict) { - setDict(dict); - } - - @Override - public synchronized PyObject fastGetDict() { - PyDictionary ldict = tdict.get(); - if (ldict == null) { - ldict = new PyDictionary(); - tdict.set(ldict); - dispatch__init__(getType(), args, keywords); - } - return ldict; - } -} Deleted: branches/asm/src/org/python/modules/PyLocalDerived.java =================================================================== --- branches/asm/src/org/python/modules/PyLocalDerived.java 2008-05-18 23:00:22 UTC (rev 4422) +++ branches/asm/src/org/python/modules/PyLocalDerived.java 2008-05-19 18:12:21 UTC (rev 4423) @@ -1,932 +0,0 @@ -package org.python.modules; - -import org.python.core.*; - -public class PyLocalDerived extends PyLocal implements Slotted { - - public PyObject getSlot(int index) { - return slots[index]; - } - - public void setSlot(int index,PyObject value) { - slots[index]=value; - } - - private PyObject[]slots; - - public PyLocalDerived(PyType subtype) { - super(subtype); - slots=new PyObject[subtype.getNumSlots()]; - } - - public PyString __str__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__str__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__str__"+" should return a "+"string"); - } - return super.__str__(); - } - - public PyString __repr__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__repr__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__repr__"+" should return a "+"string"); - } - return super.__repr__(); - } - - public PyString __hex__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__hex__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__hex__"+" should return a "+"string"); - } - return super.__hex__(); - } - - public PyString __oct__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__oct__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__oct__"+" should return a "+"string"); - } - return super.__oct__(); - } - - public PyFloat __float__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__float__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyFloat) - return(PyFloat)res; - throw Py.TypeError("__float__"+" should return a "+"float"); - } - return super.__float__(); - } - - public PyLong __long__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__long__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyLong) - return(PyLong)res; - throw Py.TypeError("__long__"+" should return a "+"long"); - } - return super.__long__(); - } - - public PyComplex __complex__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__complex__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyComplex) - return(PyComplex)res; - throw Py.TypeError("__complex__"+" should return a "+"complex"); - } - return super.__complex__(); - } - - public PyObject __pos__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__pos__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__pos__(); - } - - public PyObject __neg__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__neg__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__neg__(); - } - - public PyObject __abs__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__abs__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__abs__(); - } - - public PyObject __invert__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__invert__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__invert__(); - } - - public PyObject __reduce__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__reduce__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__reduce__(); - } - - public PyObject __add__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__add__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__add__(other); - } - - public PyObject __radd__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__radd__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__radd__(other); - } - - public PyObject __sub__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__sub__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__sub__(other); - } - - public PyObject __rsub__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rsub__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rsub__(other); - } - - public PyObject __mul__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__mul__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__mul__(other); - } - - public PyObject __rmul__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rmul__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rmul__(other); - } - - public PyObject __div__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__div__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__div__(other); - } - - public PyObject __rdiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rdiv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rdiv__(other); - } - - public PyObject __floordiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__floordiv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__floordiv__(other); - } - - public PyObject __rfloordiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rfloordiv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rfloordiv__(other); - } - - public PyObject __truediv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__truediv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__truediv__(other); - } - - public PyObject __rtruediv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rtruediv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rtruediv__(other); - } - - public PyObject __mod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__mod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__mod__(other); - } - - public PyObject __rmod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rmod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rmod__(other); - } - - public PyObject __divmod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__divmod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__divmod__(other); - } - - public PyObject __rdivmod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rdivmod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rdivmod__(other); - } - - public PyObject __pow__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__pow__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__pow__(other); - } - - public PyObject __rpow__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rpow__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rpow__(other); - } - - public PyObject __lshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__lshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__lshift__(other); - } - - public PyObject __rlshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rlshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rlshift__(other); - } - - public PyObject __rshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rshift__(other); - } - - public PyObject __rrshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rrshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rrshift__(other); - } - - public PyObject __and__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__and__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__and__(other); - } - - public PyObject __rand__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rand__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rand__(other); - } - - public PyObject __or__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__or__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__or__(other); - } - - public PyObject __ror__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ror__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__ror__(other); - } - - public PyObject __xor__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__xor__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__xor__(other); - } - - public PyObject __rxor__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rxor__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rxor__(other); - } - - public PyObject __lt__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__lt__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__lt__(other); - } - - public PyObject __le__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__le__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__le__(other); - } - - public PyObject __gt__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__gt__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__gt__(other); - } - - public PyObject __ge__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ge__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__ge__(other); - } - - public PyObject __eq__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__eq__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__eq__(other); - } - - public PyObject __ne__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ne__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__ne__(other); - } - - public PyObject __iadd__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__iadd__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__iadd__(other); - } - - public PyObject __isub__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__isub__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__isub__(other); - } - - public PyObject __imul__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__imul__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__imul__(other); - } - - public PyObject __idiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__idiv__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__idiv__(other); - } - - public PyObject __ifloordiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ifloordiv__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__ifloordiv__(other); - } - - public PyObject __itruediv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__itruediv__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__itruediv__(other); - } - - public PyObject __imod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__imod__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__imod__(other); - } - - public PyObject __ipow__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ipow__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__ipow__(other); - } - - public PyObject __ilshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ilshift__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__ilshift__(other); - } - - public PyObject __irshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__irshift__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__irshift__(other); - } - - public PyObject __iand__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__iand__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__iand__(other); - } - - public PyObject __ior__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ior__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__ior__(other); - } - - public PyObject __ixor__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__ixor__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(other); - return super.__ixor__(other); - } - - public PyObject __int__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__int__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyInteger||res instanceof PyLong) - return(PyObject)res; - throw Py.TypeError("__int__"+" should return an integer"); - } - return super.__int__(); - } - - public String toString() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__repr__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (!(res instanceof PyString)) - throw Py.TypeError("__repr__ should return a string"); - return((PyString)res).toString(); - } - return super.toString(); - } - - public int hashCode() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__hash__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyInteger) - return((PyInteger)res).getValue(); - throw Py.TypeError("__hash__ should return a int"); - } - if (self_type.lookup("__eq__")!=null||self_type.lookup("__cmp__")!=null) - throw Py.TypeError("unhashable type"); - return super.hashCode(); - } - - public PyUnicode __unicode__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__unicode__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyUnicode) - return(PyUnicode)res; - if (res instanceof PyString) - return new PyUnicode((PyString)res); - throw Py.TypeError("__unicode__"+" should return a "+"unicode"); - } - return super.__unicode__(); - } - - public int __cmp__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__cmp__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res instanceof PyInteger) { - int v=((PyInteger)res).getValue(); - return v<0?-1:v>0?1:0; - } - throw Py.TypeError("__cmp__ should return a int"); - } - return super.__cmp__(other); - } - - public boolean __nonzero__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__nonzero__"); - if (impl==null) { - impl=self_type.lookup("__len__"); - if (impl==null) - return super.__nonzero__(); - } - return impl.__get__(this,self_type).__call__().__nonzero__(); - } - - public boolean __contains__(PyObject o) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__contains__"); - if (impl==null) - return super.__contains__(o); - return impl.__get__(this,self_type).__call__(o).__nonzero__(); - } - - public int __len__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__len__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyInteger) - return((PyInteger)res).getValue(); - throw Py.TypeError("__len__ should return a int"); - } - return super.__len__(); - } - - public PyObject __iter__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__iter__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - impl=self_type.lookup("__getitem__"); - if (impl==null) - return super.__iter__(); - return new PySequenceIter(this); - } - - public PyObject __iternext__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("next"); - if (impl!=null) { - try { - return impl.__get__(this,self_type).__call__(); - } catch (PyException exc) { - if (Py.matchException(exc,Py.StopIteration)) - return null; - throw exc; - } - } - return super.__iternext__(); // ??? - } - - public PyObject __finditem__(PyObject key) { // ??? - PyType self_type=getType(); - PyObject impl=self_type.lookup("__getitem__"); - if (impl!=null) - try { - return impl.__get__(this,self_type).__call__(key); - } catch (PyException exc) { - if (Py.matchException(exc,Py.LookupError)) - return null; - throw exc; - } - return super.__finditem__(key); - } - - public void __setitem__(PyObject key,PyObject value) { // ??? - PyType self_type=getType(); - PyObject impl=self_type.lookup("__setitem__"); - if (impl!=null) { - impl.__get__(this,self_type).__call__(key,value); - return; - } - super.__setitem__(key,value); - } - - public PyObject __getslice__(PyObject start,PyObject stop,PyObject step) { // ??? - PyType self_type=getType(); - PyObject impl=self_type.lookup("__getslice__"); - if (impl!=null) - try { - return impl.__get__(this,self_type).__call__(start,stop); - } catch (PyException exc) { - if (Py.matchException(exc,Py.LookupError)) - return null; - throw exc; - } - return super.__getslice__(start,stop,step); - } - - public void __delitem__(PyObject key) { // ??? - PyType self_type=getType(); - PyObject impl=self_type.lookup("__delitem__"); - if (impl!=null) { - impl.__get__(this,self_type).__call__(key); - return; - } - super.__delitem__(key); - } - - public PyObject __call__(PyObject args[],String keywords[]) { - ThreadState ts=Py.getThreadState(); - if (ts.recursion_depth++>ts.systemState.getrecursionlimit()) - throw Py.RuntimeError("maximum __call__ recursion depth exceeded"); - try { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__call__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(args,keywords); - return super.__call__(args,keywords); - } finally { - --ts.recursion_depth; - } - } - - public PyObject __findattr__(String name) { - PyType self_type=getType(); - PyObject getattribute=self_type.lookup("__getattribute__"); - PyString py_name=null; - try { - if (getattribute!=null) { - return getattribute.__get__(this,self_type).__call__(py_name=new PyString(name)); - } else { - return super.__findattr__(name); - } - } catch (PyException e) { - if (Py.matchException(e,Py.AttributeError)) { - PyObject getattr=self_type.lookup("__getattr__"); - if (getattr!=null) - try { - return getattr.__get__(this,self_type).__call__(py_name!=null?py_name:new PyString(name)); - } catch (PyException e1) { - if (!Py.matchException(e1,Py.AttributeError)) - throw e1; - } - return null; - } - throw e; - } - } - - public void __setattr__(String name,PyObject value) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__setattr__"); - if (impl!=null) { - impl.__get__(this,self_type).__call__(new PyString(name),value); - return; - } - super.__setattr__(name,value); - } - - public void __delattr__(String name) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__delattr__"); - if (impl!=null) { - impl.__get__(this,self_type).__call__(new PyString(name)); - return; - } - super.__delattr__(name); - } - - public PyObject __get__(PyObject obj,PyObject type) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__get__"); - if (impl!=null) { - if (obj==null) - obj=Py.None; - if (type==null) - type=Py.None; - return impl.__get__(this,self_type).__call__(obj,type); - } - return super.__get__(obj,type); - } - - public void __set__(PyObject obj,PyObject value) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__set__"); - if (impl!=null) { - impl.__get__(this,self_type).__call__(obj,value); - return; - } - super.__set__(obj,value); - } - - public void __delete__(PyObject obj) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__delete__"); - if (impl!=null) { - impl.__get__(this,self_type).__call__(obj); - return; - } - super.__delete__(obj); - } - - public void dispatch__init__(PyType type,PyObject[]args,String[]keywords) { - PyType self_type=getType(); - if (self_type.isSubType(type)) { - PyObject impl=self_type.lookup("__init__"); - if (impl!=null) - impl.__get__(this,self_type).__call__(args,keywords); - } - } - -} Deleted: branches/asm/src/org/python/modules/PyLock.java =================================================================== --- branches/asm/src/org/python/modules/PyLock.java 2008-05-18 23:00:22 UTC (rev 4422) +++ branches/asm/src/org/python/modules/PyLock.java 2008-05-19 18:12:21 UTC (rev 4423) @@ -1,46 +0,0 @@ -// Copyright (c) Corporation for National Research Initiatives -package org.python.modules; - -import org.python.core.*; - -public class PyLock extends PyObject { - private boolean locked=false; - //private Object lock = new Object(); - - public boolean acquire() { - return acquire(true); - } - - public synchronized boolean acquire(boolean waitflag) { - if (waitflag) { - while (locked) { - try { - wait(); - } catch (InterruptedException e) { - System.err.println("Interrupted thread"); - } - } - locked = true; - return true; - } else { - if (locked) { - return false; - } else { - locked = true; - return true; - } - } - } - - public synchronized void release() { - if (locked) { - locked = false; notifyAll(); - } else { - throw Py.ValueError("lock not acquired"); - } - } - - public boolean locked() { - return locked; - } -} Modified: branches/asm/src/org/python/modules/Setup.java =================================================================== --- branches/asm/src/org/python/modules/Setup.java 2008-05-18 23:00:22 UTC (rev 4422) +++ branches/asm/src/org/python/modules/Setup.java 2008-05-19 18:12:21 UTC (rev 4423) @@ -27,7 +27,7 @@ public static String[] builtinModules = { "jarray", "math", - "thread", + "thread:org.python.modules.thread.thread", "operator", "time:org.python.modules.time.Time", "_py_compile", Copied: branches/asm/src/org/python/modules/thread (from rev 4422, trunk/jython/src/org/python/modules/thread) Deleted: branches/asm/src/org/python/modules/thread/PyLocal.java =================================================================== --- trunk/jython/src/org/python/modules/thread/PyLocal.java 2008-05-18 23:00:22 UTC (rev 4422) +++ branches/asm/src/org/python/modules/thread/PyLocal.java 2008-05-19 18:12:21 UTC (rev 4423) @@ -1,88 +0,0 @@ -package org.python.modules.thread; - -import org.python.core.Py; -import org.python.core.PyDictionary; -import org.python.core.PyNewWrapper; -import org.python.core.PyObject; -import org.python.core.PyType; -import org.python.expose.ExposedGet; -import org.python.expose.ExposedMethod; -import org.python.expose.ExposedNew; -import org.python.expose.ExposedSet; -import org.python.expose.ExposedType; - -@ExposedType(name = "thread._local") -public class PyLocal extends PyObject { - - public static final PyType TYPE = PyType.fromClass(PyLocal.class); - - private ThreadLocal<PyDictionary> tdict = new ThreadLocal<PyDictionary>(); - - private PyObject args[]; - - private String keywords[]; - - public PyLocal() { - this(TYPE); - } - - public PyLocal(PyType subType) { - super(subType); - // Because the instantiation of a type instance in PyType.invoke_new_ - // calls dispatch__init__, we call tdict.set here so dispatch__init__ - // doesn't get called a second time for a thread in fastGetDict - tdict.set(new PyDictionary()); - } - - @ExposedNew - final static PyObject _local___new__(PyNewWrapper new_, - boolean init, - PyType subtype, - PyObject[] args, - String[] keywords) { - PyLocal newobj; - if (new_.getWrappedType() == subtype) { - newobj = new PyLocal(); - } else { - newobj = new PyLocalDerived(subtype); - } - if (init) { - newobj._local___init__(args, keywords); - } - return newobj; - } - - @ExposedMethod - final void _local___init__(PyObject[] args, String[] keywords) { - PyObject[] where = new PyObject[1]; - getType().lookup_where("__init__", where); - if (where[0] == TYPE && args.length > 0) { - throw Py.TypeError("Initialization arguments are not supported"); - } - this.args = args; - this.keywords = keywords; - } - - @Override - @ExposedGet(name = "__dict__") - public PyObject getDict() { - return fastGetDict(); - } - - @Override - @ExposedSet(name = "__dict__") - public void setDict(PyObject dict) { - setDict(dict); - } - - @Override - public synchronized PyObject fastGetDict() { - PyDictionary ldict = tdict.get(); - if (ldict == null) { - ldict = new PyDictionary(); - tdict.set(ldict); - dispatch__init__(getType(), args, keywords); - } - return ldict; - } -} Copied: branches/asm/src/org/python/modules/thread/PyLocal.java (from rev 4422, trunk/jython/src/org/python/modules/thread/PyLocal.java) =================================================================== --- branches/asm/src/org/python/modules/thread/PyLocal.java (rev 0) +++ branches/asm/src/org/python/modules/thread/PyLocal.java 2008-05-19 18:12:21 UTC (rev 4423) @@ -0,0 +1,88 @@ +package org.python.modules.thread; + +import org.python.core.Py; +import org.python.core.PyDictionary; +import org.python.core.PyNewWrapper; +import org.python.core.PyObject; +import org.python.core.PyType; +import org.python.expose.ExposedGet; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedSet; +import org.python.expose.ExposedType; + +@ExposedType(name = "thread._local") +public class PyLocal extends PyObject { + + public static final PyType TYPE = PyType.fromClass(PyLocal.class); + + private ThreadLocal<PyDictionary> tdict = new ThreadLocal<PyDictionary>(); + + private PyObject args[]; + + private String keywords[]; + + public PyLocal() { + this(TYPE); + } + + public PyLocal(PyType subType) { + super(subType); + // Because the instantiation of a type instance in PyType.invoke_new_ + // calls dispatch__init__, we call tdict.set here so dispatch__init__ + // doesn't get called a second time for a thread in fastGetDict + tdict.set(new PyDictionary()); + } + + @ExposedNew + final static PyObject _local___new__(PyNewWrapper new_, + boolean init, + PyType subtype, + PyObject[] args, + String[] keywords) { + PyLocal newobj; + if (new_.getWrappedType() == subtype) { + newobj = new PyLocal(); + } else { + newobj = new PyLocalDerived(subtype); + } + if (init) { + newobj._local___init__(args, keywords); + } + return newobj; + } + + @ExposedMethod + final void _local___init__(PyObject[] args, String[] keywords) { + PyObject[] where = new PyObject[1]; + getType().lookup_where("__init__", where); + if (where[0] == TYPE && args.length > 0) { + throw Py.TypeError("Initialization arguments are not supported"); + } + this.args = args; + this.keywords = keywords; + } + + @Override + @ExposedGet(name = "__dict__") + public PyObject getDict() { + return fastGetDict(); + } + + @Override + @ExposedSet(name = "__dict__") + public void setDict(PyObject dict) { + setDict(dict); + } + + @Override + public synchronized PyObject fastGetDict() { + PyDictionary ldict = tdict.get(); + if (ldict == null) { + ldict = new PyDictionary(); + tdict.set(ldict); + dispatch__init__(getType(), args, keywords); + } + return ldict; + } +} Deleted: branches/asm/src/org/python/modules/thread/PyLocalDerived.java =================================================================== --- trunk/jython/src/org/python/modules/thread/PyLocalDerived.java 2008-05-18 23:00:22 UTC (rev 4422) +++ branches/asm/src/org/python/modules/thread/PyLocalDerived.java 2008-05-19 18:12:21 UTC (rev 4423) @@ -1,932 +0,0 @@ -package org.python.modules.thread; - -import org.python.core.*; - -public class PyLocalDerived extends PyLocal implements Slotted { - - public PyObject getSlot(int index) { - return slots[index]; - } - - public void setSlot(int index,PyObject value) { - slots[index]=value; - } - - private PyObject[]slots; - - public PyLocalDerived(PyType subtype) { - super(subtype); - slots=new PyObject[subtype.getNumSlots()]; - } - - public PyString __str__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__str__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__str__"+" should return a "+"string"); - } - return super.__str__(); - } - - public PyString __repr__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__repr__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__repr__"+" should return a "+"string"); - } - return super.__repr__(); - } - - public PyString __hex__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__hex__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__hex__"+" should return a "+"string"); - } - return super.__hex__(); - } - - public PyString __oct__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__oct__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyString) - return(PyString)res; - throw Py.TypeError("__oct__"+" should return a "+"string"); - } - return super.__oct__(); - } - - public PyFloat __float__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__float__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyFloat) - return(PyFloat)res; - throw Py.TypeError("__float__"+" should return a "+"float"); - } - return super.__float__(); - } - - public PyLong __long__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__long__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyLong) - return(PyLong)res; - throw Py.TypeError("__long__"+" should return a "+"long"); - } - return super.__long__(); - } - - public PyComplex __complex__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__complex__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(); - if (res instanceof PyComplex) - return(PyComplex)res; - throw Py.TypeError("__complex__"+" should return a "+"complex"); - } - return super.__complex__(); - } - - public PyObject __pos__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__pos__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__pos__(); - } - - public PyObject __neg__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__neg__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__neg__(); - } - - public PyObject __abs__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__abs__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__abs__(); - } - - public PyObject __invert__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__invert__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__invert__(); - } - - public PyObject __reduce__() { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__reduce__"); - if (impl!=null) - return impl.__get__(this,self_type).__call__(); - return super.__reduce__(); - } - - public PyObject __add__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__add__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__add__(other); - } - - public PyObject __radd__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__radd__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__radd__(other); - } - - public PyObject __sub__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__sub__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__sub__(other); - } - - public PyObject __rsub__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rsub__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rsub__(other); - } - - public PyObject __mul__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__mul__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__mul__(other); - } - - public PyObject __rmul__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rmul__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rmul__(other); - } - - public PyObject __div__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__div__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__div__(other); - } - - public PyObject __rdiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rdiv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rdiv__(other); - } - - public PyObject __floordiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__floordiv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__floordiv__(other); - } - - public PyObject __rfloordiv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rfloordiv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rfloordiv__(other); - } - - public PyObject __truediv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__truediv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__truediv__(other); - } - - public PyObject __rtruediv__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rtruediv__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rtruediv__(other); - } - - public PyObject __mod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__mod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__mod__(other); - } - - public PyObject __rmod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rmod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rmod__(other); - } - - public PyObject __divmod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__divmod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__divmod__(other); - } - - public PyObject __rdivmod__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rdivmod__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rdivmod__(other); - } - - public PyObject __pow__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__pow__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__pow__(other); - } - - public PyObject __rpow__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rpow__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rpow__(other); - } - - public PyObject __lshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__lshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__lshift__(other); - } - - public PyObject __rlshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rlshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rlshift__(other); - } - - public PyObject __rshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(other); - if (res==Py.NotImplemented) - return null; - return res; - } - return super.__rshift__(other); - } - - public PyObject __rrshift__(PyObject other) { - PyType self_type=getType(); - PyObject impl=self_type.lookup("__rrshift__"); - if (impl!=null) { - PyObject res=impl.__get__(this,self_type).__call__(othe... [truncated message content] |
From: <fwi...@us...> - 2008-05-20 17:39:39
|
Revision: 4424 http://jython.svn.sourceforge.net/jython/?rev=4424&view=rev Author: fwierzbicki Date: 2008-05-20 10:39:32 -0700 (Tue, 20 May 2008) Log Message: ----------- Added a shell script to run Jython. This was adapted from a script from the JRuby project. I also included the same suport for The Java Interactive Profiler (JIP) that JRuby includes. See http://jiprof.sourceforge.net/ Modified Paths: -------------- branches/asm/build.xml Added Paths: ----------- branches/asm/extlibs/profile.jar branches/asm/extlibs/profile.properties branches/asm/src/shell/ branches/asm/src/shell/jython Modified: branches/asm/build.xml =================================================================== --- branches/asm/build.xml 2008-05-19 18:12:21 UTC (rev 4423) +++ branches/asm/build.xml 2008-05-20 17:39:32 UTC (rev 4424) @@ -604,6 +604,22 @@ <present present="srconly" targetdir="${jython.base.dir}/Lib"/> </fileset> </copy> + + <copy todir="${dist.dir}/bin"> + <fileset dir="${source.dir}/shell"/> + </copy> + + <chmod perm="ugo+rx"> + <fileset dir="${dist.dir}/bin" /> + </chmod> + + <copy todir="${dist.dir}/javalib"> + <fileset dir="${jython.base.dir}/extlibs"/> + <fileset dir="${jython.base.dir}/build"> + <include name="*.jar"/> + <include name="*.properties"/> + </fileset> + </copy> </target> <!-- wrap the build into the installer --> Added: branches/asm/extlibs/profile.jar =================================================================== (Binary files differ) Property changes on: branches/asm/extlibs/profile.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: branches/asm/extlibs/profile.properties =================================================================== --- branches/asm/extlibs/profile.properties (rev 0) +++ branches/asm/extlibs/profile.properties 2008-05-20 17:39:32 UTC (rev 4424) @@ -0,0 +1,69 @@ +# +# Is the profiler on or off when the app starts? +# (on | off) +# default = on +# +profiler=on +# +# Can the profiler be controlled remotely ? +# (on | off) +# default = off +# +remote=off +# +# TCP listen port for remote control +# default =15599 +# +port=15599 +# +# +#ClassLoaderFilter.1=com.mentorgen.tools.profile.instrument.clfilter.StandardClassLoaderFilter +# +# What is the maximum depth for thread dumps +# (-1 means no limit) +# default = -1 +# (you may also use 'compact') +# +thread-depth=compact +# +# When compacting thread dumps, what in the minimum total time you want +# to show +# default = 10 (ms) +# +thread.compact.threshold.ms=1 +# +# What is the maximum number of methods to show in the method dump +# (-1 means no limit) +# default = -1 +# (you may also use 'compact') +# +max-method-count=10 +# +# defaults to 10 +# +method.compact.threshold.ms=1 +# +# What is the default file name for the profile information +# default=./profile.txt +# +file=profile.txt +# +# What packages are excluded from the display +# (comma separated) +# Note: com.mentorgen.tools.profile is always excluded +# +include=ruby +# +# Track Object Allocation (very expensive) +# values: on, off +# default = off +# +#track.object.alloc=on +# +output=text +#output-method-signatures=yes +#profiler-class=net.sourceforge.jiprof.timeline.TimeLineProfiler +#clock-resolution=ms + +output-summary-only=yes +accept-class-loaders=org.jruby.util.JRubyClassLoader Added: branches/asm/src/shell/jython =================================================================== --- branches/asm/src/shell/jython (rev 0) +++ branches/asm/src/shell/jython 2008-05-20 17:39:32 UTC (rev 4424) @@ -0,0 +1,161 @@ +#!/bin/bash +# ----------------------------------------------------------------------------- +# jython.sh - Start Script for the Jython +# +# Adapted from jruby.sh +# +# Environment Variable Prequisites +# +# JYTHON_OPTS (Optional) Default Jython command line args +# +# JAVA_HOME Must point at your Java Development Kit installation. +# +# ----------------------------------------------------------------------------- + +cygwin=false + +# ----- Identify OS we are running under -------------------------------------- +case "`uname`" in +CYGWIN*) cygwin=true +esac + +# ----- Verify and Set Required Environment Variables ------------------------- + +## resolve links - $0 may be a link to home +PRG=$0 +progname=`basename "$0"` + +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '.*/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname $PRG`/$link" + fi +done + +JYTHON_HOME_1=`dirname "$PRG"` # the ./bin dir +JYTHON_HOME=`dirname "$JYTHON_HOME_1"` # the . dir + +if [ -z "$JYTHON_OPTS" ] ; then + JYTHON_OPTS="" +fi + +if [ -z "$JAVA_HOME" ] ; then + JAVA_CMD='java' +else + if $cygwin; then + JAVA_HOME=`cygpath -u "$JAVA_HOME"` + fi + JAVA_CMD="$JAVA_HOME/bin/java" +fi + +CP_DELIMETER=":" + +CP=$JYTHON_HOME/jython.jar + +# add necessary jars for command-line execution +for j in "$JYTHON_HOME"/javalib/*.jar; do + if [ "$CP" ]; then + CP="$CP$CP_DELIMETER$j" + else + CP="$j" + fi +done + +if $cygwin; then + CP=`cygpath -p -w "$CP"` +fi + +# ----- Execute The Requested Command ----------------------------------------- + +JAVA_MEM=-Xmx378m +JAVA_STACK=-Xss1024k + +# Split out any -J argument for passing to the JVM. +# Scanning for args is aborted by '--'. +declare -a java_args +declare -a python_args + while [ $# -gt 0 ] +do + case "$1" in + # Stuff after '-J' in this argument goes to JVM + -J*) + val=${1:2} + if [ "${val:0:4}" = "-Xmx" ]; then + JAVA_MEM=$val + elif [ "${val:0:4}" = "-Xss" ]; then + JAVA_STACK=$val + else + java_args=("${java_args[@]}" "${1:2}") + fi + ;; + # Match switches that take an argument + -c|-D|-C|-jar|-Q|-W) python_args=("${python_args[@]}" "$1" "$2"); shift ;; + # Match -Dprop=val type args + -D*) python_args=("${python_args[@]}" "$1" ) ;; + # Run with the instrumented profiler: http://jiprof.sourceforge.net/ + --profile) PROFILE_ARGS="-javaagent:$JYTHON_HOME/javalib/profile.jar -Dprofile.properties=$JYTHON_HOME/javalib/profile.properties" ;; + # Run under JDB + --jdb) + if [ -z "$JAVA_HOME" ] ; then + JAVA_CMD='jdb' + else + if $cygwin; then + JAVA_HOME=`cygpath -u "$JAVA_HOME"` + fi + JAVA_CMD="$JAVA_HOME/bin/jdb" + fi ;; + --help) python_args=("${python_args[@]}" "$1") ;; + # Abort processing on the double dash + --) break ;; + # Other opts go to python + -*) python_args=("${python_args[@]}" "$1") ;; + # Abort processing on first non-opt arg + *) break ;; + esac + shift +done + +# Append the rest of the arguments +python_args=("${python_args[@]}" "$@") + +# Put the python_args back into the position arguments $1, $2 etc +set -- "${python_args[@]}" + +JAVA_OPTS="$JAVA_OPTS $JAVA_MEM $JAVA_STACK" + +if $cygwin; then + JAVA_HOME=`cygpath --mixed "$JAVA_HOME"` + JYTHON_HOME=`cygpath --mixed "$JYTHON_HOME"` + + if [[ ( "${1:0:1}" = "/" ) && ( ( -f "$1" ) || ( -d "$1" )) ]]; then + win_arg=`cygpath -w "$1"` + shift + win_args=("$win_arg" "$@") + set -- "${win_args[@]}" + fi +fi + +if [ "$PROFILE_ARGS" != "" ]; then + echo "Running with instrumented profiler" + + $JAVA_CMD $PROFILE_ARGS $JAVA_OPTS "${java_args[@]}" -classpath "$CP$CP_SEPARATOR$CLASSPATH" \ + "-Dpython.home=$JYTHON_HOME" \ + org.python.util.jython $JYTHON_OPTS "$@" + + echo "Profiling results:" + + cat profile.txt + +else + echo "$JAVA_CMD" $JAVA_OPTS "${java_args[@]}" -Xbootclasspath/a:"$CP" -classpath "$CLASSPATH" \ + "-Dpython.home=$JYTHON_HOME" \ + org.python.util.jython $JYTHON_OPTS "$@" + + exec "$JAVA_CMD" $JAVA_OPTS "${java_args[@]}" -Xbootclasspath/a:"$CP" -classpath "$CLASSPATH" \ + "-Dpython.home=$JYTHON_HOME" \ + org.python.util.jython $JYTHON_OPTS "$@" + +fi Property changes on: branches/asm/src/shell/jython ___________________________________________________________________ Name: svn:executable + * This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-05-20 20:47:59
|
Revision: 4433 http://jython.svn.sourceforge.net/jython/?rev=4433&view=rev Author: pjenvey Date: 2008-05-20 13:47:58 -0700 (Tue, 20 May 2008) Log Message: ----------- Merged revisions 4423-4432 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4426 | pjenvey | 2008-05-20 11:24:57 -0700 (Tue, 20 May 2008) | 2 lines test_set.py from: http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_set.py@54954 ........ r4427 | pjenvey | 2008-05-20 11:52:29 -0700 (Tue, 20 May 2008) | 4 lines number of set fixes to get most of 2.5's test_set passing fixes #1036 patch from Jonathan Ellis ........ r4428 | pjenvey | 2008-05-20 12:00:21 -0700 (Tue, 20 May 2008) | 1 line make all baseset_ methods final, whitespace ........ r4429 | pjenvey | 2008-05-20 12:01:14 -0700 (Tue, 20 May 2008) | 2 lines fix set pickling. we no longer need setsfactory ........ r4430 | pjenvey | 2008-05-20 12:14:37 -0700 (Tue, 20 May 2008) | 2 lines special case symmetric_difference_update on yourself; just clear avoids ConcurrentModificationExceptions ........ r4431 | fwierzbicki | 2008-05-20 12:19:52 -0700 (Tue, 20 May 2008) | 5 lines Added a shell script to run Jython -- tested this in the asm branch a bit, but I think this can safely go into trunk. This was adapted from a script from the JRuby project. I also included the same support for The Java Interactive Profiler (JIP) that JRuby includes. See http://jiprof.sourceforge.net/ ........ r4432 | pjenvey | 2008-05-20 13:39:12 -0700 (Tue, 20 May 2008) | 2 lines need to track line numbers for inplace ops ........ Modified Paths: -------------- branches/asm/grammar/PythonWalker.g branches/asm/src/org/python/compiler/CodeCompiler.java branches/asm/src/org/python/core/BaseSet.java branches/asm/src/org/python/core/Py.java branches/asm/src/org/python/core/PyFrozenSet.java branches/asm/src/org/python/core/PySet.java branches/asm/src/org/python/core/PySystemState.java Added Paths: ----------- branches/asm/Lib/test/test_set.py Removed Paths: ------------- branches/asm/Lib/setsfactory.py Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4422 + /trunk/jython:1-4432 Deleted: branches/asm/Lib/setsfactory.py =================================================================== --- branches/asm/Lib/setsfactory.py 2008-05-20 20:39:12 UTC (rev 4432) +++ branches/asm/Lib/setsfactory.py 2008-05-20 20:47:58 UTC (rev 4433) @@ -1,10 +0,0 @@ -from copy_reg import pickle, constructor -from sets import Set as _Set, ImmutableSet as _ImmutableSet - -def Set(*args): - return _Set(*args) -def ImmutableSet(*args): - return _ImmutableSet(*args) - -constructor(Set) -constructor(ImmutableSet) Copied: branches/asm/Lib/test/test_set.py (from rev 4432, trunk/jython/Lib/test/test_set.py) =================================================================== --- branches/asm/Lib/test/test_set.py (rev 0) +++ branches/asm/Lib/test/test_set.py 2008-05-20 20:47:58 UTC (rev 4433) @@ -0,0 +1,1540 @@ +import unittest +from test import test_support +from weakref import proxy +import operator +import copy +import pickle +import os +from random import randrange, shuffle +import sys + +class PassThru(Exception): + pass + +def check_pass_thru(): + raise PassThru + yield 1 + +class BadCmp: + def __hash__(self): + return 1 + def __cmp__(self, other): + raise RuntimeError + +class ReprWrapper: + 'Used to test self-referential repr() calls' + def __repr__(self): + return repr(self.value) + +class HashCountingInt(int): + 'int-like object that counts the number of times __hash__ is called' + def __init__(self, *args): + self.hash_count = 0 + def __hash__(self): + self.hash_count += 1 + return int.__hash__(self) + +class TestJointOps(unittest.TestCase): + # Tests common to both set and frozenset + + def setUp(self): + self.word = word = 'simsalabim' + self.otherword = 'madagascar' + self.letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + self.s = self.thetype(word) + self.d = dict.fromkeys(word) + + def test_new_or_init(self): + self.assertRaises(TypeError, self.thetype, [], 2) + + def test_uniquification(self): + actual = sorted(self.s) + expected = sorted(self.d) + self.assertEqual(actual, expected) + self.assertRaises(PassThru, self.thetype, check_pass_thru()) + self.assertRaises(TypeError, self.thetype, [[]]) + + def test_len(self): + self.assertEqual(len(self.s), len(self.d)) + + def test_contains(self): + for c in self.letters: + self.assertEqual(c in self.s, c in self.d) + self.assertRaises(TypeError, self.s.__contains__, [[]]) + s = self.thetype([frozenset(self.letters)]) + self.assert_(self.thetype(self.letters) in s) + + def test_union(self): + u = self.s.union(self.otherword) + for c in self.letters: + self.assertEqual(c in u, c in self.d or c in self.otherword) + self.assertEqual(self.s, self.thetype(self.word)) + self.assertEqual(type(u), self.thetype) + self.assertRaises(PassThru, self.s.union, check_pass_thru()) + self.assertRaises(TypeError, self.s.union, [[]]) + for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: + self.assertEqual(self.thetype('abcba').union(C('cdc')), set('abcd')) + self.assertEqual(self.thetype('abcba').union(C('efgfe')), set('abcefg')) + self.assertEqual(self.thetype('abcba').union(C('ccb')), set('abc')) + self.assertEqual(self.thetype('abcba').union(C('ef')), set('abcef')) + + def test_or(self): + i = self.s.union(self.otherword) + self.assertEqual(self.s | set(self.otherword), i) + self.assertEqual(self.s | frozenset(self.otherword), i) + try: + self.s | self.otherword + except TypeError: + pass + else: + self.fail("s|t did not screen-out general iterables") + + def test_intersection(self): + i = self.s.intersection(self.otherword) + for c in self.letters: + self.assertEqual(c in i, c in self.d and c in self.otherword) + self.assertEqual(self.s, self.thetype(self.word)) + self.assertEqual(type(i), self.thetype) + self.assertRaises(PassThru, self.s.intersection, check_pass_thru()) + for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: + self.assertEqual(self.thetype('abcba').intersection(C('cdc')), set('cc')) + self.assertEqual(self.thetype('abcba').intersection(C('efgfe')), set('')) + self.assertEqual(self.thetype('abcba').intersection(C('ccb')), set('bc')) + self.assertEqual(self.thetype('abcba').intersection(C('ef')), set('')) + + def test_and(self): + i = self.s.intersection(self.otherword) + self.assertEqual(self.s & set(self.otherword), i) + self.assertEqual(self.s & frozenset(self.otherword), i) + try: + self.s & self.otherword + except TypeError: + pass + else: + self.fail("s&t did not screen-out general iterables") + + def test_difference(self): + i = self.s.difference(self.otherword) + for c in self.letters: + self.assertEqual(c in i, c in self.d and c not in self.otherword) + self.assertEqual(self.s, self.thetype(self.word)) + self.assertEqual(type(i), self.thetype) + self.assertRaises(PassThru, self.s.difference, check_pass_thru()) + self.assertRaises(TypeError, self.s.difference, [[]]) + for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: + self.assertEqual(self.thetype('abcba').difference(C('cdc')), set('ab')) + self.assertEqual(self.thetype('abcba').difference(C('efgfe')), set('abc')) + self.assertEqual(self.thetype('abcba').difference(C('ccb')), set('a')) + self.assertEqual(self.thetype('abcba').difference(C('ef')), set('abc')) + + def test_sub(self): + i = self.s.difference(self.otherword) + self.assertEqual(self.s - set(self.otherword), i) + self.assertEqual(self.s - frozenset(self.otherword), i) + try: + self.s - self.otherword + except TypeError: + pass + else: + self.fail("s-t did not screen-out general iterables") + + def test_symmetric_difference(self): + i = self.s.symmetric_difference(self.otherword) + for c in self.letters: + self.assertEqual(c in i, (c in self.d) ^ (c in self.otherword)) + self.assertEqual(self.s, self.thetype(self.word)) + self.assertEqual(type(i), self.thetype) + self.assertRaises(PassThru, self.s.symmetric_difference, check_pass_thru()) + self.assertRaises(TypeError, self.s.symmetric_difference, [[]]) + for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: + self.assertEqual(self.thetype('abcba').symmetric_difference(C('cdc')), set('abd')) + self.assertEqual(self.thetype('abcba').symmetric_difference(C('efgfe')), set('abcefg')) + self.assertEqual(self.thetype('abcba').symmetric_difference(C('ccb')), set('a')) + self.assertEqual(self.thetype('abcba').symmetric_difference(C('ef')), set('abcef')) + + def test_xor(self): + i = self.s.symmetric_difference(self.otherword) + self.assertEqual(self.s ^ set(self.otherword), i) + self.assertEqual(self.s ^ frozenset(self.otherword), i) + try: + self.s ^ self.otherword + except TypeError: + pass + else: + self.fail("s^t did not screen-out general iterables") + + def test_equality(self): + self.assertEqual(self.s, set(self.word)) + self.assertEqual(self.s, frozenset(self.word)) + self.assertEqual(self.s == self.word, False) + self.assertNotEqual(self.s, set(self.otherword)) + self.assertNotEqual(self.s, frozenset(self.otherword)) + self.assertEqual(self.s != self.word, True) + + def test_setOfFrozensets(self): + t = map(frozenset, ['abcdef', 'bcd', 'bdcb', 'fed', 'fedccba']) + s = self.thetype(t) + self.assertEqual(len(s), 3) + + def test_compare(self): + self.assertRaises(TypeError, self.s.__cmp__, self.s) + + def test_sub_and_super(self): + p, q, r = map(self.thetype, ['ab', 'abcde', 'def']) + self.assert_(p < q) + self.assert_(p <= q) + self.assert_(q <= q) + self.assert_(q > p) + self.assert_(q >= p) + self.failIf(q < r) + self.failIf(q <= r) + self.failIf(q > r) + self.failIf(q >= r) + self.assert_(set('a').issubset('abc')) + self.assert_(set('abc').issuperset('a')) + self.failIf(set('a').issubset('cbs')) + self.failIf(set('cbs').issuperset('a')) + + def test_pickling(self): + for i in (0, 1, 2): + p = pickle.dumps(self.s, i) + dup = pickle.loads(p) + self.assertEqual(self.s, dup, "%s != %s" % (self.s, dup)) + if type(self.s) not in (set, frozenset): + self.s.x = 10 + p = pickle.dumps(self.s) + dup = pickle.loads(p) + self.assertEqual(self.s.x, dup.x) + + def test_deepcopy(self): + class Tracer: + def __init__(self, value): + self.value = value + def __hash__(self): + return self.value + def __deepcopy__(self, memo=None): + return Tracer(self.value + 1) + t = Tracer(10) + s = self.thetype([t]) + dup = copy.deepcopy(s) + self.assertNotEqual(id(s), id(dup)) + for elem in dup: + newt = elem + self.assertNotEqual(id(t), id(newt)) + self.assertEqual(t.value + 1, newt.value) + + def test_gc(self): + # Create a nest of cycles to exercise overall ref count check + class A: + pass + s = set([A() for i in xrange(1000)]) + for elem in s: + elem.cycle = s + elem.sub = elem + elem.set = set([elem]) + + def test_subclass_with_custom_hash(self): + # Bug #1257731 + class H(self.thetype): + def __hash__(self): + return int(id(self) & 0x7fffffff) + s=H() + f=set() + f.add(s) + self.assert_(s in f) + f.remove(s) + f.add(s) + f.discard(s) + + def test_badcmp(self): + s = self.thetype([BadCmp()]) + # Detect comparison errors during insertion and lookup + self.assertRaises(RuntimeError, self.thetype, [BadCmp(), BadCmp()]) + self.assertRaises(RuntimeError, s.__contains__, BadCmp()) + # Detect errors during mutating operations + if hasattr(s, 'add'): + self.assertRaises(RuntimeError, s.add, BadCmp()) + self.assertRaises(RuntimeError, s.discard, BadCmp()) + self.assertRaises(RuntimeError, s.remove, BadCmp()) + +# XXX: todo not sure why these fail +# def test_cyclical_repr(self): +# w = ReprWrapper() +# s = self.thetype([w]) +# w.value = s +# name = repr(s).partition('(')[0] # strip class name from repr string +# self.assertEqual(repr(s), '%s([%s(...)])' % (name, name)) +# +# def test_cyclical_print(self): +# w = ReprWrapper() +# s = self.thetype([w]) +# w.value = s +# try: +# fo = open(test_support.TESTFN, "wb") +# print >> fo, s, +# fo.close() +# fo = open(test_support.TESTFN, "rb") +# self.assertEqual(fo.read(), repr(s)) +# finally: +# fo.close() +# os.remove(test_support.TESTFN) + +# XXX: tests cpython internals (caches key hashes) +# def test_do_not_rehash_dict_keys(self): +# n = 10 +# d = dict.fromkeys(map(HashCountingInt, xrange(n))) +# self.assertEqual(sum([elem.hash_count for elem in d]), n) +# s = self.thetype(d) +# self.assertEqual(sum([elem.hash_count for elem in d]), n) +# s.difference(d) +# self.assertEqual(sum([elem.hash_count for elem in d]), n) +# if hasattr(s, 'symmetric_difference_update'): +# s.symmetric_difference_update(d) +# self.assertEqual(sum([elem.hash_count for elem in d]), n) +# d2 = dict.fromkeys(set(d)) +# self.assertEqual(sum([elem.hash_count for elem in d]), n) +# d3 = dict.fromkeys(frozenset(d)) +# self.assertEqual(sum([elem.hash_count for elem in d]), n) +# d3 = dict.fromkeys(frozenset(d), 123) +# self.assertEqual(sum([elem.hash_count for elem in d]), n) +# self.assertEqual(d3, dict.fromkeys(d, 123)) + +class TestSet(TestJointOps): + thetype = set + + def test_init(self): + s = self.thetype() + s.__init__(self.word) + self.assertEqual(s, set(self.word)) + s.__init__(self.otherword) + self.assertEqual(s, set(self.otherword)) + self.assertRaises(TypeError, s.__init__, s, 2); + self.assertRaises(TypeError, s.__init__, 1); + + def test_constructor_identity(self): + s = self.thetype(range(3)) + t = self.thetype(s) + self.assertNotEqual(id(s), id(t)) + + def test_hash(self): + self.assertRaises(TypeError, hash, self.s) + + def test_clear(self): + self.s.clear() + self.assertEqual(self.s, set()) + self.assertEqual(len(self.s), 0) + + def test_copy(self): + dup = self.s.copy() + self.assertEqual(self.s, dup) + self.assertNotEqual(id(self.s), id(dup)) + + def test_add(self): + self.s.add('Q') + self.assert_('Q' in self.s) + dup = self.s.copy() + self.s.add('Q') + self.assertEqual(self.s, dup) + self.assertRaises(TypeError, self.s.add, []) + + def test_remove(self): + self.s.remove('a') + self.assert_('a' not in self.s) + self.assertRaises(KeyError, self.s.remove, 'Q') + self.assertRaises(TypeError, self.s.remove, []) + s = self.thetype([frozenset(self.word)]) + self.assert_(self.thetype(self.word) in s) + s.remove(self.thetype(self.word)) + self.assert_(self.thetype(self.word) not in s) + self.assertRaises(KeyError, self.s.remove, self.thetype(self.word)) + + def test_remove_keyerror_unpacking(self): + # bug: www.python.org/sf/1576657 + for v1 in ['Q', (1,)]: + try: + self.s.remove(v1) + except KeyError, e: + v2 = e.args[0] + self.assertEqual(v1, v2) + else: + self.fail() + + def test_discard(self): + self.s.discard('a') + self.assert_('a' not in self.s) + self.s.discard('Q') + self.assertRaises(TypeError, self.s.discard, []) + s = self.thetype([frozenset(self.word)]) + self.assert_(self.thetype(self.word) in s) + s.discard(self.thetype(self.word)) + self.assert_(self.thetype(self.word) not in s) + s.discard(self.thetype(self.word)) + + def test_pop(self): + for i in xrange(len(self.s)): + elem = self.s.pop() + self.assert_(elem not in self.s) + self.assertRaises(KeyError, self.s.pop) + + def test_update(self): + retval = self.s.update(self.otherword) + self.assertEqual(retval, None) + for c in (self.word + self.otherword): + self.assert_(c in self.s) + self.assertRaises(PassThru, self.s.update, check_pass_thru()) + self.assertRaises(TypeError, self.s.update, [[]]) + for p, q in (('cdc', 'abcd'), ('efgfe', 'abcefg'), ('ccb', 'abc'), ('ef', 'abcef')): + for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: + s = self.thetype('abcba') + self.assertEqual(s.update(C(p)), None) + self.assertEqual(s, set(q)) + + def test_ior(self): + self.s |= set(self.otherword) + for c in (self.word + self.otherword): + self.assert_(c in self.s) + + def test_intersection_update(self): + retval = self.s.intersection_update(self.otherword) + self.assertEqual(retval, None) + for c in (self.word + self.otherword): + if c in self.otherword and c in self.word: + self.assert_(c in self.s) + else: + self.assert_(c not in self.s) + self.assertRaises(PassThru, self.s.intersection_update, check_pass_thru()) + self.assertRaises(TypeError, self.s.intersection_update, [[]]) + for p, q in (('cdc', 'c'), ('efgfe', ''), ('ccb', 'bc'), ('ef', '')): + for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: + s = self.thetype('abcba') + self.assertEqual(s.intersection_update(C(p)), None) + self.assertEqual(s, set(q)) + + def test_iand(self): + self.s &= set(self.otherword) + for c in (self.word + self.otherword): + if c in self.otherword and c in self.word: + self.assert_(c in self.s) + else: + self.assert_(c not in self.s) + + def test_difference_update(self): + retval = self.s.difference_update(self.otherword) + self.assertEqual(retval, None) + for c in (self.word + self.otherword): + if c in self.word and c not in self.otherword: + self.assert_(c in self.s) + else: + self.assert_(c not in self.s) + self.assertRaises(PassThru, self.s.difference_update, check_pass_thru()) + self.assertRaises(TypeError, self.s.difference_update, [[]]) + self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]]) + for p, q in (('cdc', 'ab'), ('efgfe', 'abc'), ('ccb', 'a'), ('ef', 'abc')): + for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: + s = self.thetype('abcba') + self.assertEqual(s.difference_update(C(p)), None) + self.assertEqual(s, set(q)) + + def test_isub(self): + self.s -= set(self.otherword) + for c in (self.word + self.otherword): + if c in self.word and c not in self.otherword: + self.assert_(c in self.s) + else: + self.assert_(c not in self.s) + + def test_symmetric_difference_update(self): + retval = self.s.symmetric_difference_update(self.otherword) + self.assertEqual(retval, None) + for c in (self.word + self.otherword): + if (c in self.word) ^ (c in self.otherword): + self.assert_(c in self.s) + else: + self.assert_(c not in self.s) + self.assertRaises(PassThru, self.s.symmetric_difference_update, check_pass_thru()) + self.assertRaises(TypeError, self.s.symmetric_difference_update, [[]]) + for p, q in (('cdc', 'abd'), ('efgfe', 'abcefg'), ('ccb', 'a'), ('ef', 'abcef')): + for C in set, frozenset, dict.fromkeys, str, unicode, list, tuple: + s = self.thetype('abcba') + self.assertEqual(s.symmetric_difference_update(C(p)), None) + self.assertEqual(s, set(q)) + + def test_ixor(self): + self.s ^= set(self.otherword) + for c in (self.word + self.otherword): + if (c in self.word) ^ (c in self.otherword): + self.assert_(c in self.s) + else: + self.assert_(c not in self.s) + + def test_inplace_on_self(self): + t = self.s.copy() + t |= t + self.assertEqual(t, self.s) + t &= t + self.assertEqual(t, self.s) + t -= t + self.assertEqual(t, self.thetype()) + t = self.s.copy() + t ^= t + self.assertEqual(t, self.thetype()) + +# XXX: CPython gc-specific +# def test_weakref(self): +# s = self.thetype('gallahad') +# p = proxy(s) +# self.assertEqual(str(p), str(s)) +# s = None +# self.assertRaises(ReferenceError, str, p) + + # C API test only available in a debug build + if hasattr(set, "test_c_api"): + def test_c_api(self): + self.assertEqual(set('abc').test_c_api(), True) + +class SetSubclass(set): + pass + +class TestSetSubclass(TestSet): + thetype = SetSubclass + +class SetSubclassWithKeywordArgs(set): + def __init__(self, iterable=[], newarg=None): + set.__init__(self, iterable) + +class TestSetSubclassWithKeywordArgs(TestSet): + + def test_keywords_in_subclass(self): + 'SF bug #1486663 -- this used to erroneously raise a TypeError' + SetSubclassWithKeywordArgs(newarg=1) + +class TestFrozenSet(TestJointOps): + thetype = frozenset + + def test_init(self): + s = self.thetype(self.word) + s.__init__(self.otherword) + self.assertEqual(s, set(self.word)) + + def test_singleton_empty_frozenset(self): + f = frozenset() + efs = [frozenset(), frozenset([]), frozenset(()), frozenset(''), + frozenset(), frozenset([]), frozenset(()), frozenset(''), + frozenset(xrange(0)), frozenset(frozenset()), + frozenset(f), f] + # All of the empty frozensets should have just one id() + self.assertEqual(len(set(map(id, efs))), 1) + + def test_constructor_identity(self): + s = self.thetype(range(3)) + t = self.thetype(s) + self.assertEqual(id(s), id(t)) + + def test_hash(self): + self.assertEqual(hash(self.thetype('abcdeb')), + hash(self.thetype('ebecda'))) + + # make sure that all permutations give the same hash value + n = 100 + seq = [randrange(n) for i in xrange(n)] + results = set() + for i in xrange(200): + shuffle(seq) + results.add(hash(self.thetype(seq))) + self.assertEqual(len(results), 1) + + def test_copy(self): + dup = self.s.copy() + self.assertEqual(id(self.s), id(dup)) + + def test_frozen_as_dictkey(self): + seq = range(10) + list('abcdefg') + ['apple'] + key1 = self.thetype(seq) + key2 = self.thetype(reversed(seq)) + self.assertEqual(key1, key2) + self.assertNotEqual(id(key1), id(key2)) + d = {} + d[key1] = 42 + self.assertEqual(d[key2], 42) + + def test_hash_caching(self): + f = self.thetype('abcdcda') + self.assertEqual(hash(f), hash(f)) + +# XXX: tied to cpython's hash implementation +# def test_hash_effectiveness(self): +# n = 13 +# hashvalues = set() +# addhashvalue = hashvalues.add +# elemmasks = [(i+1, 1<<i) for i in range(n)] +# for i in xrange(2**n): +# addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i]))) +# self.assertEqual(len(hashvalues), 2**n) + +class FrozenSetSubclass(frozenset): + pass + +class TestFrozenSetSubclass(TestFrozenSet): + thetype = FrozenSetSubclass + + def test_constructor_identity(self): + s = self.thetype(range(3)) + t = self.thetype(s) + self.assertNotEqual(id(s), id(t)) + + def test_copy(self): + dup = self.s.copy() + self.assertNotEqual(id(self.s), id(dup)) + + def test_nested_empty_constructor(self): + s = self.thetype() + t = self.thetype(s) + self.assertEqual(s, t) + + def test_singleton_empty_frozenset(self): + Frozenset = self.thetype + f = frozenset() + F = Frozenset() + efs = [Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''), + Frozenset(), Frozenset([]), Frozenset(()), Frozenset(''), + Frozenset(xrange(0)), Frozenset(Frozenset()), + Frozenset(frozenset()), f, F, Frozenset(f), Frozenset(F)] + # All empty frozenset subclass instances should have different ids + self.assertEqual(len(set(map(id, efs))), len(efs)) + +# Tests taken from test_sets.py ============================================= + +empty_set = set() + +#============================================================================== + +class TestBasicOps(unittest.TestCase): + + def test_repr(self): + if self.repr is not None: + self.assertEqual(repr(self.set), self.repr) + + def test_print(self): + try: + fo = open(test_support.TESTFN, "wb") + print >> fo, self.set, + fo.close() + fo = open(test_support.TESTFN, "rb") + self.assertEqual(fo.read(), repr(self.set)) + finally: + fo.close() + os.remove(test_support.TESTFN) + + def test_length(self): + self.assertEqual(len(self.set), self.length) + + def test_self_equality(self): + self.assertEqual(self.set, self.set) + + def test_equivalent_equality(self): + self.assertEqual(self.set, self.dup) + + def test_copy(self): + self.assertEqual(self.set.copy(), self.dup) + + def test_self_union(self): + result = self.set | self.set + self.assertEqual(result, self.dup) + + def test_empty_union(self): + result = self.set | empty_set + self.assertEqual(result, self.dup) + + def test_union_empty(self): + result = empty_set | self.set + self.assertEqual(result, self.dup) + + def test_self_intersection(self): + result = self.set & self.set + self.assertEqual(result, self.dup) + + def test_empty_intersection(self): + result = self.set & empty_set + self.assertEqual(result, empty_set) + + def test_intersection_empty(self): + result = empty_set & self.set + self.assertEqual(result, empty_set) + + def test_self_symmetric_difference(self): + result = self.set ^ self.set + self.assertEqual(result, empty_set) + + def checkempty_symmetric_difference(self): + result = self.set ^ empty_set + self.assertEqual(result, self.set) + + def test_self_difference(self): + result = self.set - self.set + self.assertEqual(result, empty_set) + + def test_empty_difference(self): + result = self.set - empty_set + self.assertEqual(result, self.dup) + + def test_empty_difference_rev(self): + result = empty_set - self.set + self.assertEqual(result, empty_set) + + def test_iteration(self): + for v in self.set: + self.assert_(v in self.values) +# XXX: jython does not use length_hint +# setiter = iter(self.set) +# # note: __length_hint__ is an internal undocumented API, +# # don't rely on it in your own programs +# self.assertEqual(setiter.__length_hint__(), len(self.set)) + + def test_pickling(self): + p = pickle.dumps(self.set) + copy = pickle.loads(p) + self.assertEqual(self.set, copy, + "%s != %s" % (self.set, copy)) + +#------------------------------------------------------------------------------ + +class TestBasicOpsEmpty(TestBasicOps): + def setUp(self): + self.case = "empty set" + self.values = [] + self.set = set(self.values) + self.dup = set(self.values) + self.length = 0 + self.repr = "set([])" + +#------------------------------------------------------------------------------ + +class TestBasicOpsSingleton(TestBasicOps): + def setUp(self): + self.case = "unit set (number)" + self.values = [3] + self.set = set(self.values) + self.dup = set(self.values) + self.length = 1 + self.repr = "set([3])" + + def test_in(self): + self.failUnless(3 in self.set) + + def test_not_in(self): + self.failUnless(2 not in self.set) + +#------------------------------------------------------------------------------ + +class TestBasicOpsTuple(TestBasicOps): + def setUp(self): + self.case = "unit set (tuple)" + self.values = [(0, "zero")] + self.set = set(self.values) + self.dup = set(self.values) + self.length = 1 + self.repr = "set([(0, 'zero')])" + + def test_in(self): + self.failUnless((0, "zero") in self.set) + + def test_not_in(self): + self.failUnless(9 not in self.set) + +#------------------------------------------------------------------------------ + +class TestBasicOpsTriple(TestBasicOps): + def setUp(self): + self.case = "triple set" + self.values = [0, "zero", operator.add] + self.set = set(self.values) + self.dup = set(self.values) + self.length = 3 + self.repr = None + +#============================================================================== + +def baditer(): + raise TypeError + yield True + +def gooditer(): + yield True + +class TestExceptionPropagation(unittest.TestCase): + """SF 628246: Set constructor should not trap iterator TypeErrors""" + + def test_instanceWithException(self): + self.assertRaises(TypeError, set, baditer()) + + def test_instancesWithoutException(self): + # All of these iterables should load without exception. + set([1,2,3]) + set((1,2,3)) + set({'one':1, 'two':2, 'three':3}) + set(xrange(3)) + set('abc') + set(gooditer()) + + def test_changingSizeWhileIterating(self): + s = set([1,2,3]) + try: + for i in s: + s.update([4]) + except RuntimeError: + pass + else: + self.fail("no exception when changing size during iteration") + +#============================================================================== + +class TestSetOfSets(unittest.TestCase): + def test_constructor(self): + inner = frozenset([1]) + outer = set([inner]) + element = outer.pop() + self.assertEqual(type(element), frozenset) + outer.add(inner) # Rebuild set of sets with .add method + outer.remove(inner) + self.assertEqual(outer, set()) # Verify that remove worked + outer.discard(inner) # Absence of KeyError indicates working fine + +#============================================================================== + +class TestBinaryOps(unittest.TestCase): + def setUp(self): + self.set = set((2, 4, 6)) + + def test_eq(self): # SF bug 643115 + self.assertEqual(self.set, set({2:1,4:3,6:5})) + + def test_union_subset(self): + result = self.set | set([2]) + self.assertEqual(result, set((2, 4, 6))) + + def test_union_superset(self): + result = self.set | set([2, 4, 6, 8]) + self.assertEqual(result, set([2, 4, 6, 8])) + + def test_union_overlap(self): + result = self.set | set([3, 4, 5]) + self.assertEqual(result, set([2, 3, 4, 5, 6])) + + def test_union_non_overlap(self): + result = self.set | set([8]) + self.assertEqual(result, set([2, 4, 6, 8])) + + def test_intersection_subset(self): + result = self.set & set((2, 4)) + self.assertEqual(result, set((2, 4))) + + def test_intersection_superset(self): + result = self.set & set([2, 4, 6, 8]) + self.assertEqual(result, set([2, 4, 6])) + + def test_intersection_overlap(self): + result = self.set & set([3, 4, 5]) + self.assertEqual(result, set([4])) + + def test_intersection_non_overlap(self): + result = self.set & set([8]) + self.assertEqual(result, empty_set) + + def test_sym_difference_subset(self): + result = self.set ^ set((2, 4)) + self.assertEqual(result, set([6])) + + def test_sym_difference_superset(self): + result = self.set ^ set((2, 4, 6, 8)) + self.assertEqual(result, set([8])) + + def test_sym_difference_overlap(self): + result = self.set ^ set((3, 4, 5)) + self.assertEqual(result, set([2, 3, 5, 6])) + + def test_sym_difference_non_overlap(self): + result = self.set ^ set([8]) + self.assertEqual(result, set([2, 4, 6, 8])) + + def test_cmp(self): + a, b = set('a'), set('b') + self.assertRaises(TypeError, cmp, a, b) + + # You can view this as a buglet: cmp(a, a) does not raise TypeError, + # because __eq__ is tried before __cmp__, and a.__eq__(a) returns True, + # which Python thinks is good enough to synthesize a cmp() result + # without calling __cmp__. + self.assertEqual(cmp(a, a), 0) + + self.assertRaises(TypeError, cmp, a, 12) + self.assertRaises(TypeError, cmp, "abc", a) + +#============================================================================== + +class TestUpdateOps(unittest.TestCase): + def setUp(self): + self.set = set((2, 4, 6)) + + def test_union_subset(self): + self.set |= set([2]) + self.assertEqual(self.set, set((2, 4, 6))) + + def test_union_superset(self): + self.set |= set([2, 4, 6, 8]) + self.assertEqual(self.set, set([2, 4, 6, 8])) + + def test_union_overlap(self): + self.set |= set([3, 4, 5]) + self.assertEqual(self.set, set([2, 3, 4, 5, 6])) + + def test_union_non_overlap(self): + self.set |= set([8]) + self.assertEqual(self.set, set([2, 4, 6, 8])) + + def test_union_method_call(self): + self.set.update(set([3, 4, 5])) + self.assertEqual(self.set, set([2, 3, 4, 5, 6])) + + def test_intersection_subset(self): + self.set &= set((2, 4)) + self.assertEqual(self.set, set((2, 4))) + + def test_intersection_superset(self): + self.set &= set([2, 4, 6, 8]) + self.assertEqual(self.set, set([2, 4, 6])) + + def test_intersection_overlap(self): + self.set &= set([3, 4, 5]) + self.assertEqual(self.set, set([4])) + + def test_intersection_non_overlap(self): + self.set &= set([8]) + self.assertEqual(self.set, empty_set) + + def test_intersection_method_call(self): + self.set.intersection_update(set([3, 4, 5])) + self.assertEqual(self.set, set([4])) + + def test_sym_difference_subset(self): + self.set ^= set((2, 4)) + self.assertEqual(self.set, set([6])) + + def test_sym_difference_superset(self): + self.set ^= set((2, 4, 6, 8)) + self.assertEqual(self.set, set([8])) + + def test_sym_difference_overlap(self): + self.set ^= set((3, 4, 5)) + self.assertEqual(self.set, set([2, 3, 5, 6])) + + def test_sym_difference_non_overlap(self): + self.set ^= set([8]) + self.assertEqual(self.set, set([2, 4, 6, 8])) + + def test_sym_difference_method_call(self): + self.set.symmetric_difference_update(set([3, 4, 5])) + self.assertEqual(self.set, set([2, 3, 5, 6])) + + def test_difference_subset(self): + self.set -= set((2, 4)) + self.assertEqual(self.set, set([6])) + + def test_difference_superset(self): + self.set -= set((2, 4, 6, 8)) + self.assertEqual(self.set, set([])) + + def test_difference_overlap(self): + self.set -= set((3, 4, 5)) + self.assertEqual(self.set, set([2, 6])) + + def test_difference_non_overlap(self): + self.set -= set([8]) + self.assertEqual(self.set, set([2, 4, 6])) + + def test_difference_method_call(self): + self.set.difference_update(set([3, 4, 5])) + self.assertEqual(self.set, set([2, 6])) + +#============================================================================== + +class TestMutate(unittest.TestCase): + def setUp(self): + self.values = ["a", "b", "c"] + self.set = set(self.values) + + def test_add_present(self): + self.set.add("c") + self.assertEqual(self.set, set("abc")) + + def test_add_absent(self): + self.set.add("d") + self.assertEqual(self.set, set("abcd")) + + def test_add_until_full(self): + tmp = set() + expected_len = 0 + for v in self.values: + tmp.add(v) + expected_len += 1 + self.assertEqual(len(tmp), expected_len) + self.assertEqual(tmp, self.set) + + def test_remove_present(self): + self.set.remove("b") + self.assertEqual(self.set, set("ac")) + + def test_remove_absent(self): + try: + self.set.remove("d") + self.fail("Removing missing element should have raised LookupError") + except LookupError: + pass + + def test_remove_until_empty(self): + expected_len = len(self.set) + for v in self.values: + self.set.remove(v) + expected_len -= 1 + self.assertEqual(len(self.set), expected_len) + + def test_discard_present(self): + self.set.discard("c") + self.assertEqual(self.set, set("ab")) + + def test_discard_absent(self): + self.set.discard("d") + self.assertEqual(self.set, set("abc")) + + def test_clear(self): + self.set.clear() + self.assertEqual(len(self.set), 0) + + def test_pop(self): + popped = {} + while self.set: + popped[self.set.pop()] = None + self.assertEqual(len(popped), len(self.values)) + for v in self.values: + self.failUnless(v in popped) + + def test_update_empty_tuple(self): + self.set.update(()) + self.assertEqual(self.set, set(self.values)) + + def test_update_unit_tuple_overlap(self): + self.set.update(("a",)) + self.assertEqual(self.set, set(self.values)) + + def test_update_unit_tuple_non_overlap(self): + self.set.update(("a", "z")) + self.assertEqual(self.set, set(self.values + ["z"])) + +#============================================================================== + +class TestSubsets(unittest.TestCase): + + case2method = {"<=": "issubset", + ">=": "issuperset", + } + + reverse = {"==": "==", + "!=": "!=", + "<": ">", + ">": "<", + "<=": ">=", + ">=": "<=", + } + + def test_issubset(self): + x = self.left + y = self.right + for case in "!=", "==", "<", "<=", ">", ">=": + expected = case in self.cases + # Test the binary infix spelling. + result = eval("x" + case + "y", locals()) + self.assertEqual(result, expected) + # Test the "friendly" method-name spelling, if one exists. + if case in TestSubsets.case2method: + method = getattr(x, TestSubsets.case2method[case]) + result = method(y) + self.assertEqual(result, expected) + + # Now do the same for the operands reversed. + rcase = TestSubsets.reverse[case] + result = eval("y" + rcase + "x", locals()) + self.assertEqual(result, expected) + if rcase in TestSubsets.case2method: + method = getattr(y, TestSubsets.case2method[rcase]) + result = method(x) + self.assertEqual(result, expected) +#------------------------------------------------------------------------------ + +class TestSubsetEqualEmpty(TestSubsets): + left = set() + right = set() + name = "both empty" + cases = "==", "<=", ">=" + +#------------------------------------------------------------------------------ + +class TestSubsetEqualNonEmpty(TestSubsets): + left = set([1, 2]) + right = set([1, 2]) + name = "equal pair" + cases = "==", "<=", ">=" + +#------------------------------------------------------------------------------ + +class TestSubsetEmptyNonEmpty(TestSubsets): + left = set() + right = set([1, 2]) + name = "one empty, one non-empty" + cases = "!=", "<", "<=" + +#------------------------------------------------------------------------------ + +class TestSubsetPartial(TestSubsets): + left = set([1]) + right = set([1, 2]) + name = "one a non-empty proper subset of other" + cases = "!=", "<", "<=" + +#------------------------------------------------------------------------------ + +class TestSubsetNonOverlap(TestSubsets): + left = set([1]) + right = set([2]) + name = "neither empty, neither contains" + cases = "!=" + +#============================================================================== + +class TestOnlySetsInBinaryOps(unittest.TestCase): + + def test_eq_ne(self): + # Unlike the others, this is testing that == and != *are* allowed. + self.assertEqual(self.other == self.set, False) + self.assertEqual(self.set == self.other, False) + self.assertEqual(self.other != self.set, True) + self.assertEqual(self.set != self.other, True) + + def test_ge_gt_le_lt(self): + self.assertRaises(TypeError, lambda: self.set < self.other) + self.assertRaises(TypeError, lambda: self.set <= self.other) + self.assertRaises(TypeError, lambda: self.set > self.other) + self.assertRaises(TypeError, lambda: self.set >= self.other) + + self.assertRaises(TypeError, lambda: self.other < self.set) + self.assertRaises(TypeError, lambda: self.other <= self.set) + self.assertRaises(TypeError, lambda: self.other > self.set) + self.assertRaises(TypeError, lambda: self.other >= self.set) + + def test_update_operator(self): + try: + self.set |= self.other + except TypeError: + pass + else: + self.fail("expected TypeError") + + def test_update(self): + if self.otherIsIterable: + self.set.update(self.other) + else: + self.assertRaises(TypeError, self.set.update, self.other) + + def test_union(self): + self.assertRaises(TypeError, lambda: self.set | self.other) + self.assertRaises(TypeError, lambda: self.other | self.set) + if self.otherIsIterable: + self.set.union(self.other) + else: + self.assertRaises(TypeError, self.set.union, self.other) + + def test_intersection_update_operator(self): + try: + self.set &= self.other + except TypeError: + pass + else: + self.fail("expected TypeError") + + def test_intersection_update(self): + if self.otherIsIterable: + self.set.intersection_update(self.other) + else: + self.assertRaises(TypeError, + self.set.intersection_update, + self.other) + + def test_intersection(self): + self.assertRaises(TypeError, lambda: self.set & self.other) + self.assertRaises(TypeError, lambda: self.other & self.set) + if self.otherIsIterable: + self.set.intersection(self.other) + else: + self.assertRaises(TypeError, self.set.intersection, self.other) + + def test_sym_difference_update_operator(self): + try: + self.set ^= self.other + except TypeError: + pass + else: + self.fail("expected TypeError") + + def test_sym_difference_update(self): + if self.otherIsIterable: + self.set.symmetric_difference_update(self.other) + else: + self.assertRaises(TypeError, + self.set.symmetric_difference_update, + self.other) + + def test_sym_difference(self): + self.assertRaises(TypeError, lambda: self.set ^ self.other) + self.assertRaises(TypeError, lambda: self.other ^ self.set) + if self.otherIsIterable: + self.set.symmetric_difference(self.other) + else: + self.assertRaises(TypeError, self.set.symmetric_difference, self.other) + + def test_difference_update_operator(self): + try: + self.set -= self.other + except TypeError: + pass + else: + self.fail("expected TypeError") + + def test_difference_update(self): + if self.otherIsIterable: + self.set.difference_update(self.other) + else: + self.assertRaises(TypeError, + self.set.difference_update, + self.other) + + def test_difference(self): + self.assertRaises(TypeError, lambda: self.set - self.other) + self.assertRaises(TypeError, lambda: self.other - self.set) + if self.otherIsIterable: + self.set.difference(self.other) + else: + self.assertRaises(TypeError, self.set.difference, self.other) + +#------------------------------------------------------------------------------ + +class TestOnlySetsNumeric(TestOnlySetsInBinaryOps): + def setUp(self): + self.set = set((1, 2, 3)) + self.other = 19 + self.otherIsIterable = False + +#------------------------------------------------------------------------------ + +class TestOnlySetsDict(TestOnlySetsInBinaryOps): + def setUp(self): + self.set = set((1, 2, 3)) + self.other = {1:2, 3:4} + self.otherIsIterable = True + +#------------------------------------------------------------------------------ + +class TestOnlySetsOperator(TestOnlySetsInBinaryOps): + def setUp(self): + self.set = set((1, 2, 3)) + self.other = operator.add + self.otherIsIterable = False + +#------------------------------------------------------------------------------ + +class TestOnlySetsTuple(TestOnlySetsInBinaryOps): + def setUp(self): + self.set = set((1, 2, 3)) + self.other = (2, 4, 6) + self.otherIsIterable = True + +#------------------------------------------------------------------------------ + +class TestOnlySetsString(TestOnlySetsInBinaryOps): + def setUp(self): + self.set = set((1, 2, 3)) + self.other = 'abc' + self.otherIsIterable = True + +#------------------------------------------------------------------------------ + +class TestOnlySetsGenerator(TestOnlySetsInBinaryOps): + def setUp(self): + def gen(): + for i in xrange(0, 10, 2): + yield i + self.set = set((1, 2, 3)) + self.other = gen() + self.otherIsIterable = True + +#============================================================================== + +class TestCopying(unittest.TestCase): + + def test_copy(self): + dup = self.set.copy() + dup_list = list(dup); dup_list.sort() + set_list = list(self.set); set_list.sort() + self.assertEqual(len(dup_list), len(set_list)) + for i in range(len(dup_list)): + self.failUnless(dup_list[i] is set_list[i]) + + def test_deep_copy(self): + dup = copy.deepcopy(self.set) + ##print type(dup), repr(dup) + dup_list = list(dup); dup_list.sort() + set_list = list(self.set); set_list.sort() + self.assertEqual(len(dup_list), len(set_list)) + for i in range(len(dup_list)): + self.assertEqual(dup_list[i], set_list[i]) + +#------------------------------------------------------------------------------ + +class TestCopyingEmpty(TestCopying): + def setUp(self): + self.set = set() + +#------------------------------------------------------------------------------ + +class TestCopyingSingleton(TestCopying): + def setUp(self): + self.set = set(["hello"]) + +#------------------------------------------------------------------------------ + +class TestCopyingTriple(TestCopying): + def setUp(self): + self.set = set(["zero", 0, None]) + +#------------------------------------------------------------------------------ + +class TestCopyingTuple(TestCopying): + def setUp(self): + self.set = set([(1, 2)]) + +#------------------------------------------------------------------------------ + +class TestCopyingNested(TestCopying): + def setUp(self): + self.set = set([((1, 2), (3, 4))]) + +#============================================================================== + +class TestIdentities(unittest.TestCase): + def setUp(self): + self.a = set('abracadabra') + self.b = set('alacazam') + + def test_binopsVsSubsets(self): + a, b = self.a, self.b + self.assert_(a - b < a) + self.assert_(b - a < b) + self.assert_(a & b < a) + self.assert_(a & b < b) + self.assert_(a | b > a) + self.assert_(a | b > b) + self.assert_(a ^ b < a | b) + + def test_commutativity(self): + a, b = self.a, self.b + self.assertEqual(a&b, b&a) + self.assertEqual(a|b, b|a) + self.assertEqual(a^b, b^a) + if a != b: + self.assertNotEqual(a-b, b-a) + + def test_summations(self): + # check that sums of parts equal the whole + a, b = self.a, self.b + self.assertEqual((a-b)|(a&b)|(b-a), a|b) + self.assertEqual((a&b)|(a^b), a|b) + self.assertEqual(a|(b-a), a|b) + self.assertEqual((a-b)|b, a|b) + self.assertEqual((a-b)|(a&b), a) + self.assertEqual((b-a)|(a&b), b) + self.assertEqual((a-b)|(b-a), a^b) + + def test_exclusion(self): + # check that inverse operations show non-overlap + a, b, zero = self.a, self.b, set() + self.assertEqual((a-b)&b, zero) + self.assertEqual((b-a)&a, zero) + self.assertEqual((a&b)&(a^b), zero) + +# Tests derived from test_itertools.py ======================================= + +def R(seqn): + 'Regular generator' + for i in seqn: + yield i + +class G: + 'Sequence using __getitem__' + def __init__(self, seqn): + self.seqn = seqn + def __getitem__(self, i): + return self.seqn[i] + +class I: + 'Sequence using iterator protocol' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + return self + def next(self): + if self.i >= len(self.seqn): raise StopIteration + v = self.seqn[self.i] + self.i += 1 + return v + +class Ig: + 'Sequence using iterator protocol defined with a generator' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + for val in self.seqn: + yield val + +class X: + 'Missing __getitem__ and __iter__' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def next(self): + if self.i >= len(self.seqn): raise StopIteration + v = self.seqn[self.i] + self.i += 1 + return v + +class N: + 'Iterator missing next()' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + return self + +class E: + 'Test propagation of exceptions' + def __init__(self, seqn): + self.seqn = seqn + self.i = 0 + def __iter__(self): + return self + def next(self): + 3 // 0 + +class S: + 'Test immediate stop' + def __init__(self, seqn): + pass + def __iter__(self): + return self + def next(self): + raise StopIteration + +from itertools import chain, imap +def L(seqn): + 'Test multiple tiers of iterators' + return chain(imap(lambda x:x, R(Ig(G(seqn))))) + +class TestVariousIteratorArgs(unittest.TestCase): + + def test_constructor(self): + for cons in (set, frozenset): + for s in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5)): + for g in (G, I, Ig, S, L, R): + self.assertEqual(sorted(cons(g(s))), sorted(g(s))) + self.assertRaises(TypeError, cons , X(s)) + self.assertRaises(TypeError, cons , N(s)) + self.assertRaises(ZeroDivisionError, cons , E(s)) + + def test_inline_methods(self): + s = set('november') + for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'): + for meth in (s.union, s.intersection, s.difference, s.symmetric_difference): + for g in (G, I, Ig, L, R): + expected = meth(data) + actual = meth(G(data)) + self.assertEqual(sorted(actual), sorted(expected)) + self.assertRaises(TypeError, meth, X(s)) + self.assertRaises(TypeError, meth, N(s)) + self.assertRaises(ZeroDivisionError, meth, E(s)) + + def test_inplace_methods(self): + for data in ("123", "", range(1000), ('do', 1.2), xrange(2000,2200,5), 'december'): + for methname in ('update', 'intersection_update', + 'difference_update', 'symmetric_difference_update'): + for g in (G, I, Ig, S, L, R): + s = set('january') + t = s.copy() + getattr(s, methname)(list(g(data))) + getattr(t, methname)(g(data)) + self.assertEqual(sorted(s), sorted(t)) + + self.assertRaises(TypeError, getattr(set('january'), methname), X(data)) + self.assertRaises(TypeError, getattr(set('january'), methname), N(data)) + self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data)) + +#============================================================================== + +def test_main(verbose=None): + from test import test_sets + test_classes = ( + TestSet, + TestSetSubclass, + TestSetSubclassWithKeywordArgs, + TestFrozenSet, + TestFrozenSetSubclass, + TestSetOfSets, + TestExceptionPropagation, + TestBasicOpsEmpty, + TestBasicOpsSingleton, + TestBasicOpsTuple, + TestBasicOpsTriple, + TestBinaryOps, + TestUpdateOps, + TestMutate, + TestSubsetEqualEmpty, + TestSubsetEqualNonEmpty, + TestSubsetEmptyNonEmpty, + TestSubsetPartial, + TestSubsetNonOverlap, + TestOnlySetsNumeric, + TestOnlySetsDict, + TestOnlySetsOperator, + TestOnlySetsTuple, + TestOnlySetsString, + TestOnlySetsGenerator, + TestCopyingEmpty, + TestCopyingSingleton, + TestCopyingTriple, + TestCopyingTuple, + TestCopyingNested, + TestIdentities, + TestVariousIteratorArgs, + ) + + test_support.run_unittest(*test_classes) + + # verify reference counting + if verbose and hasattr(sys, "gettotalrefcount"): + import gc + counts = [None] * 5 + for i in xrange(len(counts)): + test_support.run_unittest(*test_classes) + gc.collect() + counts[i] = sys.gettotalrefcount() + print counts + +if __name__ == "__main__": + test_main(verbose=True) Modified: branches/asm/grammar/PythonWalker.g =================================================================== --- branches/asm/grammar/PythonWalker.g 2008-05-20 20:39:12 UTC (rev 4432) +++ branches/asm/grammar/PythonWalker.g 2008-05-20 20:47:58 UTC (rev 4433) @@ -933,7 +933,6 @@ } ; -//FIXME: lots of placeholders test[expr_contextType ctype] returns [exprType etype, PythonTree begin, boolean parens] : ^(AND left=test[ctype] right=test[ctype]) { List values = new ArrayList(); Modified: branches/asm/src/org/python/compiler/CodeCompiler.java =================================================================== --- branches/asm/src/org/python/compiler/CodeCompiler.java 2008-05-20 20:39:12 UTC (rev 4432) +++ branches/asm/src/org/python/compiler/CodeCompiler.java 2008-05-20 20:47:58 UTC (rev 4433) @@ -1280,6 +1280,8 @@ } public Object visitAugAssign(AugAssign node) throws Exception { + setline(node); + visit(node.value); int tmp = storeTop(); Modified: branches/asm/src/org/python/core/BaseSet.java =================================================================== --- branches/asm/src/org/python/core/BaseSet.java 2008-05-20 20:39:12 UTC (rev 4432) +++ branches/asm/src/org/python/core/BaseSet.java 2008-05-20 20:47:58 UTC (rev 4433) @@ -45,17 +45,13 @@ * @throws PyIgnoreMethodTag Ignore. */ protected void _update(PyObject data) throws PyIgnoreMethodTag { - if(data instanceof BaseSet) { + if (data instanceof BaseSet) { // Skip the iteration if both are sets this._set.addAll(((BaseSet)data)._set); return; } for (PyObject item : data.asIterable()) { - try { - this._set.add(item); - } catch (PyException e) { - this._set.add(asImmutable(e, item)); - } + this._set.add(item); } } @@ -123,9 +119,9 @@ } final PyObject baseset_difference(PyObject other) { - BaseSet bs = (other instanceof BaseSet) ? (BaseSet) other : new PySet(other); + BaseSet bs = (other instanceof BaseSet) ? (BaseSet)other : new PySet(other); Set set = bs._set; - BaseSet o = (BaseSet) this.getType().__call__(); + BaseSet o = BaseSet.makeNewSet(getType()); for (Object p : this._set) { if (!set.contains(p)) { o._set.add(p); @@ -159,9 +155,9 @@ return baseset_symmetric_difference(other); } - public PyObject baseset_symmetric_difference(PyObject other) { - BaseSet bs = (other instanceof BaseSet) ? (BaseSet) other : new PySet(other); - BaseSet o = (BaseSet) this.getType().__call__(); + final PyObject baseset_symmetric_difference(PyObject other) { + BaseSet bs = (other instanceof BaseSet) ? (BaseSet)other : new PySet(other); + BaseSet o = BaseSet.makeNewSet(getType()); for (Object p : this._set) { if (!bs._set.contains(p)) { o._set.add(p); @@ -227,7 +223,12 @@ } final boolean baseset___contains__(PyObject other) { - return this._set.contains(other); + try { + return this._set.contains(other); + } catch... [truncated message content] |
From: <fwi...@us...> - 2008-05-22 20:10:09
|
Revision: 4440 http://jython.svn.sourceforge.net/jython/?rev=4440&view=rev Author: fwierzbicki Date: 2008-05-22 13:10:01 -0700 (Thu, 22 May 2008) Log Message: ----------- Merged revisions 4435-4439 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4435 | pjenvey | 2008-05-20 19:20:43 -0400 (Tue, 20 May 2008) | 4 lines o kill as_immutable, leftover from the sets module implementation. cleanup asImmutable as a result (now asFrozen) o fix cyclical repr problems via thread.enterRepr, and repr on set subclasses ........ r4436 | pjenvey | 2008-05-20 19:37:48 -0400 (Tue, 20 May 2008) | 1 line remove unnecessary this., small cleanup ........ r4437 | pjenvey | 2008-05-20 19:39:54 -0400 (Tue, 20 May 2008) | 1 line don't need deepcopy since our copy module is already from 2.5 and supports builtin sets ........ r4438 | pjenvey | 2008-05-20 19:54:02 -0400 (Tue, 20 May 2008) | 1 line we also don't need union_update, nor does __nonzero__ need to be exposed ........ r4439 | fwierzbicki | 2008-05-21 20:10:14 -0400 (Wed, 21 May 2008) | 4 lines Allow 'as' and 'exec' to be non-keywords for Java integration (These are Python keywords and not Java keywords, so Java may use them as method names etc). Commented out start to the complete list of these keywords in Python.g. ........ Modified Paths: -------------- branches/asm/Lib/test/test_set.py branches/asm/grammar/Python.g branches/asm/grammar/PythonWalker.g branches/asm/src/org/python/core/BaseSet.java branches/asm/src/org/python/core/PyFrozenSet.java branches/asm/src/org/python/core/PySet.java Added Paths: ----------- branches/asm/Lib/test/test_grammar_jy.py Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4432 + /trunk/jython:1-4439 Copied: branches/asm/Lib/test/test_grammar_jy.py (from rev 4439, trunk/jython/Lib/test/test_grammar_jy.py) =================================================================== --- branches/asm/Lib/test/test_grammar_jy.py (rev 0) +++ branches/asm/Lib/test/test_grammar_jy.py 2008-05-22 20:10:01 UTC (rev 4440) @@ -0,0 +1,36 @@ +"""Tests whether Python keywords that are *not* Java keywords can be used + as method names (needed for Java integration -- for example, if a Java + method is named "print" and we want to use it from Jython). + +Made for Jython. +""" + +import test_support +import unittest + +class Keywords(object): + def exec(self): + exec "2+2" + return "success" + + def as(self): + import unittest as eggs + return "success" + +class GrammarTest(unittest.TestCase): + def testKeywords(self): + kws = Keywords() + self.assertEquals("success", kws.exec()) + self.assertEquals("success", kws.as()) + + def testStringPrefixes(self): + self.assertEquals(u"spam",U"spam") + self.assertEquals(r"spam", R"spam") + self.assertEquals(uR"spam", Ur"spam") + self.assertEquals(ur"spam", UR"spam") + +def test_main(): + test_support.run_unittest(GrammarTest) + +if __name__ == '__main__': + test_main() Modified: branches/asm/Lib/test/test_set.py =================================================================== --- branches/asm/Lib/test/test_set.py 2008-05-22 00:10:14 UTC (rev 4439) +++ branches/asm/Lib/test/test_set.py 2008-05-22 20:10:01 UTC (rev 4440) @@ -257,28 +257,30 @@ self.assertRaises(RuntimeError, s.discard, BadCmp()) self.assertRaises(RuntimeError, s.remove, BadCmp()) -# XXX: todo not sure why these fail -# def test_cyclical_repr(self): -# w = ReprWrapper() -# s = self.thetype([w]) -# w.value = s -# name = repr(s).partition('(')[0] # strip class name from repr string -# self.assertEqual(repr(s), '%s([%s(...)])' % (name, name)) -# -# def test_cyclical_print(self): -# w = ReprWrapper() -# s = self.thetype([w]) -# w.value = s -# try: -# fo = open(test_support.TESTFN, "wb") -# print >> fo, s, -# fo.close() -# fo = open(test_support.TESTFN, "rb") -# self.assertEqual(fo.read(), repr(s)) -# finally: -# fo.close() -# os.remove(test_support.TESTFN) + def test_cyclical_repr(self): + w = ReprWrapper() + s = self.thetype([w]) + w.value = s + # XXX: Jython doesn't have str.partition yet + #name = repr(s).partition('(')[0] # strip class name from repr string + srepr = repr(s) + name = srepr[0:srepr.find('(')] + self.assertEqual(repr(s), '%s([%s(...)])' % (name, name)) + def test_cyclical_print(self): + w = ReprWrapper() + s = self.thetype([w]) + w.value = s + try: + fo = open(test_support.TESTFN, "wb") + print >> fo, s, + fo.close() + fo = open(test_support.TESTFN, "rb") + self.assertEqual(fo.read(), repr(s)) + finally: + fo.close() + os.remove(test_support.TESTFN) + # XXX: tests cpython internals (caches key hashes) # def test_do_not_rehash_dict_keys(self): # n = 10 Modified: branches/asm/grammar/Python.g =================================================================== --- branches/asm/grammar/Python.g 2008-05-22 00:10:14 UTC (rev 4439) +++ branches/asm/grammar/Python.g 2008-05-22 20:10:01 UTC (rev 4440) @@ -481,13 +481,16 @@ ; //import_as_name: NAME [('as' | NAME) NAME] -import_as_name : name=NAME ('as' asname=NAME)? +import_as_name : name=NAME (keyAS asname=NAME)? -> ^(Alias $name ^(Asname $asname)?) ; -//XXX: when does Grammar match "dotted_name NAME NAME"? +//XXX: when does Grammar match "dotted_name NAME NAME"? This may be a big +// problem because of the keyAS rule, which matches NAME (needed to allow +// 'as' to be a method name for Java integration). + //dotted_as_name: dotted_name [('as' | NAME) NAME] -dotted_as_name : dotted_name ('as' asname=NAME)? +dotted_as_name : dotted_name (keyAS asname=NAME)? -> ^(Alias dotted_name ^(Asname NAME)?) ; @@ -504,8 +507,8 @@ ; //exec_stmt: 'exec' expr ['in' test [',' test]] -exec_stmt : 'exec' expr ('in' t1=test (COMMA t2=test)?)? - -> ^(Exec 'exec' expr ^(Globals $t1)? ^(Locals $t2)?) +exec_stmt : keyEXEC expr ('in' t1=test (COMMA t2=test)?)? + -> ^(Exec keyEXEC expr ^(Globals $t1)? ^(Locals $t2)?) ; //assert_stmt: 'assert' test [',' test] @@ -562,7 +565,7 @@ ; //with_var: ('as' | NAME) expr -with_var: ('as' | NAME) expr +with_var: (keyAS | NAME) expr ; //except_clause: 'except' [test [',' test]] @@ -813,7 +816,32 @@ //XXX: //testlist1: test (',' test)* +//These are all Python keywords that are not Java keywords +//This means that Jython needs to support these as NAMEs +//unlike CPython. For now I have only done this for 'as' +//and 'exec'. +//keyAND : {input.LT(1).getText().equals("and")}? NAME ; +keyAS : {input.LT(1).getText().equals("as")}? NAME ; +//keyDEF : {input.LT(1).getText().equals("def")}? NAME ; +//keyDEL : {input.LT(1).getText().equals("del")}? NAME ; +//keyELIF : {input.LT(1).getText().equals("elif")}? NAME ; +//keyEXCEPT : {input.LT(1).getText().equals("except")}? NAME ; +keyEXEC : {input.LT(1).getText().equals("exec")}? NAME ; +//keyFROM : {input.LT(1).getText().equals("from")}? NAME ; +//keyGLOBAL : {input.LT(1).getText().equals("global")}? NAME ; +//keyIN : {input.LT(1).getText().equals("in")}? NAME ; +//keyIS : {input.LT(1).getText().equals("is")}? NAME ; +//keyLAMBDA : {input.LT(1).getText().equals("lambda")}? NAME ; +//keyNOT : {input.LT(1).getText().equals("not")}? NAME ; +//keyOR : {input.LT(1).getText().equals("or")}? NAME ; +//keyPASS : {input.LT(1).getText().equals("pass")}? NAME ; +//keyPRINT : {input.LT(1).getText().equals("print")}? NAME ; +//keyRAISE : {input.LT(1).getText().equals("raise")}? NAME ; +//keyWITH : {input.LT(1).getText().equals("with")}? NAME ; +//keyYIELD : {input.LT(1).getText().equals("yield")}? NAME ; + + LPAREN : '(' {implicitLineJoiningLevel++;} ; RPAREN : ')' {implicitLineJoiningLevel--;} ; @@ -948,7 +976,7 @@ * should make us exit loop not continue. */ STRING - : ('r'|'u'|'ur')? + : ('r'|'u'|'ur'|'R'|'U'|'UR'|'uR'|'Ur')? ( '\'\'\'' (options {greedy=false;}:TRIAPOS)* '\'\'\'' | '"""' (options {greedy=false;}:TRIQUOTE)* '"""' | '"' (ESC|~('\\'|'\n'|'"'))* '"' Modified: branches/asm/grammar/PythonWalker.g =================================================================== --- branches/asm/grammar/PythonWalker.g 2008-05-22 00:10:14 UTC (rev 4439) +++ branches/asm/grammar/PythonWalker.g 2008-05-22 20:10:01 UTC (rev 4440) @@ -798,8 +798,9 @@ } ; +//Using tok=NAME instead of tok='exec' for Java integration exec_stmt - : ^(Exec tok='exec' exec=test[expr_contextType.Load] (^(Globals globals=test[expr_contextType.Load]))? (^(Locals locals=test[expr_contextType.Load]))?) { + : ^(Exec tok=NAME exec=test[expr_contextType.Load] (^(Globals globals=test[expr_contextType.Load]))? (^(Locals locals=test[expr_contextType.Load]))?) { exprType g = null; if ($Globals != null) { g = $globals.etype; @@ -925,10 +926,9 @@ } ; -//FIXME: how would NAME be used? I can't find any examples of this usage, but this is what -// CPython's Grammar/Grammar file specifies... +//using NAME because of Java integration for 'as' with_var returns [exprType etype] - : ('as' | NAME) test[expr_contextType.Store] { + : NAME test[expr_contextType.Store] { $etype = $test.etype; } ; Modified: branches/asm/src/org/python/core/BaseSet.java =================================================================== --- branches/asm/src/org/python/core/BaseSet.java 2008-05-22 00:10:14 UTC (rev 4439) +++ branches/asm/src/org/python/core/BaseSet.java 2008-05-22 20:10:01 UTC (rev 4440) @@ -19,7 +19,7 @@ */ public BaseSet() { super(); - this._set = new HashSet(); + _set = new HashSet(); } /** @@ -29,13 +29,13 @@ */ public BaseSet(PyObject data) { super(); - this._set = new HashSet(); - this._update(data); + _set = new HashSet(); + _update(data); } public BaseSet(PyType type) { super(type); - this._set = new HashSet(); + _set = new HashSet(); } /** @@ -47,11 +47,11 @@ protected void _update(PyObject data) throws PyIgnoreMethodTag { if (data instanceof BaseSet) { // Skip the iteration if both are sets - this._set.addAll(((BaseSet)data)._set); + _set.addAll(((BaseSet)data)._set); return; } for (PyObject item : data.asIterable()) { - this._set.add(item); + _set.add(item); } } @@ -122,7 +122,7 @@ BaseSet bs = (other instanceof BaseSet) ? (BaseSet)other : new PySet(other); Set set = bs._set; BaseSet o = BaseSet.makeNewSet(getType()); - for (Object p : this._set) { + for (Object p : _set) { if (!set.contains(p)) { o._set.add(p); } @@ -158,13 +158,13 @@ final PyObject baseset_symmetric_difference(PyObject other) { BaseSet bs = (other instanceof BaseSet) ? (BaseSet)other : new PySet(other); BaseSet o = BaseSet.makeNewSet(getType()); - for (Object p : this._set) { + for (Object p : _set) { if (!bs._set.contains(p)) { o._set.add(p); } } for (Object p : bs._set) { - if (!this._set.contains(p)) { + if (!_set.contains(p)) { o._set.add(p); } } @@ -188,7 +188,7 @@ } final int baseset___len__() { - return this._set.size(); + return _set.size(); } /** @@ -198,13 +198,9 @@ * @return <code>true</code> if the set is not empty, <code>false</code> otherwise */ public boolean __nonzero__() { - return baseset___nonzero__(); + return !_set.isEmpty(); } - final boolean baseset___nonzero__() { - return !this._set.isEmpty(); - } - /** * Produce an iterable object. * @@ -215,7 +211,7 @@ } final PyObject baseset___iter__() { - return new PySetIterator(this._set); + return new PySetIterator(_set); } public boolean __contains__(PyObject other) { @@ -224,10 +220,10 @@ final boolean baseset___contains__(PyObject other) { try { - return this._set.contains(other); - } catch (PyException e) { - PyObject immutable = this.asImmutable(e, other); - return this._set.contains(immutable); + return _set.contains(other); + } catch (PyException pye) { + PyFrozenSet frozen = asFrozen(pye, other); + return _set.contains(frozen); } } @@ -245,7 +241,7 @@ final PyObject baseset___eq__(PyObject other) { if (other instanceof BaseSet) { - return Py.newBoolean(this._set.equals(((BaseSet)other)._set)); + return Py.newBoolean(_set.equals(((BaseSet)other)._set)); } return Py.False; } @@ -256,7 +252,7 @@ final PyObject baseset___ne__(PyObject other) { if(other instanceof BaseSet) { - return Py.newBoolean(!this._set.equals(((BaseSet)other)._set)); + return Py.newBoolean(!_set.equals(((BaseSet)other)._set)); } return Py.True; } @@ -266,8 +262,8 @@ } final PyObject baseset___le__(PyObject other) { - BaseSet bs = this._binary_sanity_check(other); - return this.baseset_issubset(other); + BaseSet bs = _binary_sanity_check(other); + return baseset_issubset(other); } public PyObject __ge__(PyObject other) { @@ -275,8 +271,8 @@ } final PyObject baseset___ge__(PyObject other) { - BaseSet bs = this._binary_sanity_check(other); - return this.baseset_issuperset(other); + BaseSet bs = _binary_sanity_check(other); + return baseset_issuperset(other); } public PyObject __lt__(PyObject other) { @@ -284,9 +280,9 @@ } final PyObject baseset___lt__(PyObject other) { - BaseSet bs = this._binary_sanity_check(other); - return Py.newBoolean(this.__len__() < bs.__len__() - && this.baseset_issubset(other).__nonzero__()); + BaseSet bs = _binary_sanity_check(other); + return Py.newBoolean(__len__() < bs.__len__() + && baseset_issubset(other).__nonzero__()); } public PyObject __gt__(PyObject other) { @@ -294,9 +290,9 @@ } final PyObject baseset___gt__(PyObject other) { - BaseSet bs = this._binary_sanity_check(other); - return Py.newBoolean(this.__len__() > bs.__len__() - && this.baseset_issuperset(other).__nonzero__()); + BaseSet bs = _binary_sanity_check(other); + return Py.newBoolean(__len__() > bs.__len__() + && baseset_issuperset(other).__nonzero__()); } /** @@ -318,21 +314,6 @@ return new PyTuple(getType(), args, dict); } - public PyObject __deepcopy__(PyObject memo) { - return baseset___deepcopy__(memo); - } - - final PyObject baseset___deepcopy__(PyObject memo) { - PyObject copy = __builtin__.__import__("copy"); - PyObject deepcopy = copy.__getattr__("deepcopy"); - BaseSet result = BaseSet.makeNewSet(getType()); - memo.__setitem__(Py.newInteger(Py.id(this)), result); - for (Object p : this._set) { - result._set.add(deepcopy.__call__(Py.java2py(p), memo)); - } - return result; - } - /** * Return this instance as a Java object. Only coerces to Collection and subinterfaces. * @@ -341,7 +322,7 @@ */ public Object __tojava__(Class c) { if (Collection.class.isAssignableFrom(c)) { - return Collections.unmodifiableSet(this._set); + return Collections.unmodifiableSet(_set); } return super.__tojava__(c); } @@ -358,7 +339,7 @@ other = new PySet(other); } - if (this.__len__() <= __builtin__.len(other)) { + if (__len__() <= __builtin__.len(other)) { little = this; big = other; } else { @@ -377,10 +358,10 @@ final PyObject baseset_issubset(PyObject other) { BaseSet bs = (other instanceof BaseSet) ? (BaseSet)other : new PySet(other); - if (this.__len__() > bs.__len__()) { + if (__len__() > bs.__len__()) { return Py.False; } - for (Object p : this._set) { + for (Object p : _set) { if (!bs._set.contains(p)) { return Py.False; } @@ -390,31 +371,36 @@ final PyObject baseset_issuperset(PyObject other) { BaseSet bs = (other instanceof BaseSet) ? (BaseSet)other : new PySet(other); - if (this.__len__() < bs.__len__()) { + if (__len__() < bs.__len__()) { return Py.False; } for (Object p : bs._set) { - if (!this._set.contains(p)) { + if (!_set.contains(p)) { return Py.False; } } return Py.True; } - final String baseset_toString() { - return toString(); + public String toString() { + return baseset_toString(); } - public String toString() { + final String baseset_toString() { String name = getType().fastGetName(); + ThreadState ts = Py.getThreadState(); + if (!ts.enterRepr(this)) { + return name + "(...)"; + } StringBuffer buf = new StringBuffer(name).append("(["); - for (Iterator i = this._set.iterator(); i.hasNext();) { + for (Iterator i = _set.iterator(); i.hasNext();) { buf.append(((PyObject)i.next()).__repr__().toString()); if (i.hasNext()) { buf.append(", "); } } buf.append("])"); + ts.exitRepr(this); return buf.toString(); } @@ -427,25 +413,29 @@ } /** - * If the exception <code>e</code> is a <code>TypeError</code>, attempt to convert - * the object <code>value</code> into an ImmutableSet. + * Return a PyFrozenSet whose contents are shared with value when + * value is a BaseSet and pye is a TypeError. + * + * WARNING: The PyFrozenSet returned is only intended to be used + * temporarily (and internally); since its contents are shared + * with value, it could be mutated! * - * This is better than special-casing behavior based on isinstance, because a Python - * subclass can override, say, __hash__ and all of a sudden you can't assume that - * a non-PyFrozenSet is unhashable anymore. + * This is better than special-casing behavior based on + * isinstance, because a Python subclass can override, say, + * __hash__ and all of a sudden you can't assume that a + * non-PyFrozenSet is unhashable anymore. * - * @param e The exception thrown from a hashable operation. + * @param pye The exception thrown from a hashable operation. * @param value The object which was unhashable. - * @return An ImmutableSet if available, a <code>TypeError</code> is thrown otherwise. + * @return A PyFrozenSet if appropriate, otherwise the pye is rethrown */ - protected final PyObject asImmutable(PyException e, PyObject value) { - if (Py.matchException(e, Py.TypeError)) { - PyObject transform = value.__findattr__("_as_immutable"); - if (transform != null) { - return transform.__call__(); - } + protected final PyFrozenSet asFrozen(PyException pye, PyObject value) { + if (!(value instanceof BaseSet) || !Py.matchException(pye, Py.TypeError)) { + throw pye; } - throw e; + PyFrozenSet tmp = new PyFrozenSet(); + tmp._set = ((BaseSet)value)._set; + return tmp; } /** @@ -483,54 +473,54 @@ } // public int size() { -// return this._set.size(); +// return _set.size(); // } // // public void clear() { -// this._set.clear(); +// _set.clear(); // } // // public boolean isEmpty() { -// return this._set.isEmpty(); +// return _set.isEmpty(); // } // // public Object[] toArray() { -// return this._set.toArray(); +// return _set.toArray(); // } // // public boolean add(Object o) { -// return this._set.add(o); +// return _set.add(o); // } // // public boolean contains(Object o) { -// return this._set.contains(o); +// return _set.contains(o); // } // // public boolean remove(Object o) { -// return this._set.remove(o); +// return _set.remove(o); // } // // public boolean addAll(Collection c) { -// return this._set.addAll(c); +// return _set.addAll(c); // } // // public boolean containsAll(Collection c) { -// return this._set.containsAll(c); +// return _set.containsAll(c); // } // // public boolean removeAll(Collection c) { -// return this._set.removeAll(c); +// return _set.removeAll(c); // } // // public boolean retainAll(Collection c) { -// return this._set.retainAll(c); +// return _set.retainAll(c); // } // // public Iterator iterator() { -// return this._set.iterator(); +// return _set.iterator(); // } // // public Object[] toArray(Object a[]) { -// return this._set.toArray(a); +// return _set.toArray(a); // } } Modified: branches/asm/src/org/python/core/PyFrozenSet.java =================================================================== --- branches/asm/src/org/python/core/PyFrozenSet.java 2008-05-22 00:10:14 UTC (rev 4439) +++ branches/asm/src/org/python/core/PyFrozenSet.java 2008-05-22 20:10:01 UTC (rev 4440) @@ -116,16 +116,6 @@ } @ExposedMethod - final PyObject frozenset___deepcopy__(PyObject memo) { - return baseset___deepcopy__(memo); - } - - @ExposedMethod - final boolean frozenset___nonzero__() { - return baseset___nonzero__(); - } - - @ExposedMethod final PyObject frozenset_copy() { if (getClass() == PyFrozenSet.class) { return this; @@ -176,14 +166,15 @@ @ExposedMethod final int frozenset___hash__() { - return this._set.hashCode(); + return _set.hashCode(); } + @ExposedMethod(names = "__repr__") + final String frozenset_toString() { + return baseset_toString(); + } + public int hashCode() { return frozenset___hash__(); } - - public PyObject _as_immutable() { - return this; - } } Modified: branches/asm/src/org/python/core/PySet.java =================================================================== --- branches/asm/src/org/python/core/PySet.java 2008-05-22 00:10:14 UTC (rev 4439) +++ branches/asm/src/org/python/core/PySet.java 2008-05-22 20:10:01 UTC (rev 4440) @@ -36,7 +36,7 @@ return; } - this._set.clear(); + _set.clear(); PyObject o = args[0]; _update(o); } @@ -107,16 +107,6 @@ } @ExposedMethod - final PyObject set___deepcopy__(PyObject memo) { - return baseset___deepcopy__(memo); - } - - @ExposedMethod - final boolean set___nonzero__() { - return baseset___nonzero__(); - } - - @ExposedMethod final PyObject set_copy() { return baseset_copy(); } @@ -166,8 +156,8 @@ } final PyObject set___ior__(PyObject other) { - BaseSet bs = this._binary_sanity_check(other); - this._set.addAll(bs._set); + BaseSet bs = _binary_sanity_check(other); + _set.addAll(bs._set); return this; } @@ -177,7 +167,7 @@ @ExposedMethod(type = MethodType.BINARY) final PyObject set___ixor__(PyObject other) { - this._binary_sanity_check(other); + _binary_sanity_check(other); set_symmetric_difference_update(other); return this; } @@ -188,8 +178,8 @@ @ExposedMethod(type = MethodType.BINARY) final PyObject set___iand__(PyObject other) { - BaseSet bs = this._binary_sanity_check(other); - this._set = ((BaseSet) this.__and__(bs))._set; + BaseSet bs = _binary_sanity_check(other); + _set = ((BaseSet)__and__(bs))._set; return this; } @@ -199,8 +189,8 @@ @ExposedMethod(type = MethodType.BINARY) final PyObject set___isub__(PyObject other) { - BaseSet bs = this._binary_sanity_check(other); - this._set.removeAll(bs._set); + BaseSet bs = _binary_sanity_check(other); + _set.removeAll(bs._set); return this; } @@ -215,17 +205,17 @@ @ExposedMethod final void set_add(PyObject o) { - this._set.add(o); + _set.add(o); } @ExposedMethod final void set_remove(PyObject o) { boolean b = false; try { - b = this._set.remove(o); + b = _set.remove(o); } catch (PyException e) { - PyObject immutable = this.asImmutable(e, o); - b = this._set.remove(immutable); + PyObject frozen = asFrozen(e, o); + b = _set.remove(frozen); } if (!b) { throw new PyException(Py.KeyError, o); @@ -235,19 +225,19 @@ @ExposedMethod final void set_discard(PyObject o) { try { - this._set.remove(o); + _set.remove(o); } catch (PyException e) { - PyObject immutable = this.asImmutable(e, o); - this._set.remove(immutable); + PyObject frozen = asFrozen(e, o); + _set.remove(frozen); } } @ExposedMethod final PyObject set_pop() { - Iterator iterator = this._set.iterator(); + Iterator iterator = _set.iterator(); try { Object first = iterator.next(); - this._set.remove(first); + _set.remove(first); return (PyObject) first; } catch (NoSuchElementException e) { throw new PyException(Py.KeyError, "pop from an empty set"); @@ -256,26 +246,21 @@ @ExposedMethod final void set_clear() { - this._set.clear(); + _set.clear(); } @ExposedMethod final void set_update(PyObject data) { - this._update(data); + _update(data); } @ExposedMethod - final void set_union_update(PyObject other) { - this._update(other); - } - - @ExposedMethod final void set_intersection_update(PyObject other) { if (other instanceof BaseSet) { - this.__iand__(other); + __iand__(other); } else { - BaseSet set = (BaseSet) baseset_intersection(other); - this._set = set._set; + BaseSet set = (BaseSet)baseset_intersection(other); + _set = set._set; } } @@ -286,13 +271,13 @@ return; } - BaseSet bs = (other instanceof BaseSet) ? (BaseSet) other : new PySet(other); + BaseSet bs = (other instanceof BaseSet) ? (BaseSet)other : new PySet(other); for (Iterator iterator = bs._set.iterator(); iterator.hasNext();) { Object o = iterator.next(); - if (this._set.contains(o)) { - this._set.remove(o); + if (_set.contains(o)) { + _set.remove(o); } else { - this._set.add(o); + _set.add(o); } } } @@ -300,18 +285,18 @@ @ExposedMethod final void set_difference_update(PyObject other) { if (other instanceof BaseSet) { - this.__isub__(other); + __isub__(other); return; } for (PyObject o : other.asIterable()) { - if (this.__contains__(o)) { - this._set.remove(o); + if (__contains__(o)) { + _set.remove(o); } } } - @ExposedMethod - final PyObject set__as_immutable() { - return new PyFrozenSet(this); + @ExposedMethod(names = "__repr__") + final String set_toString() { + return baseset_toString(); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-25 03:28:59
|
Revision: 4444 http://jython.svn.sourceforge.net/jython/?rev=4444&view=rev Author: fwierzbicki Date: 2008-05-24 20:28:56 -0700 (Sat, 24 May 2008) Log Message: ----------- Merged revisions 4442-4443 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4442 | fwierzbicki | 2008-05-24 10:56:35 -0400 (Sat, 24 May 2008) | 4 lines Broke out antlr parsing of Expressions (aka: evals). Start of a fix for evals with leading spaces. Extended PythonTreeWalker so eval and interactive parsing is supported. ........ r4443 | pjenvey | 2008-05-24 19:46:09 -0400 (Sat, 24 May 2008) | 3 lines fix function, method and slot descriptors always requiring 2 args pointed out by lsoto ........ Modified Paths: -------------- branches/asm/Lib/test/test_descr_jy.py branches/asm/src/org/python/antlr/PythonGrammar.java branches/asm/src/org/python/antlr/PythonTreeWalker.java branches/asm/src/org/python/core/PyFunction.java branches/asm/src/org/python/core/PyMethod.java branches/asm/src/org/python/core/PySlot.java branches/asm/src/org/python/core/antlr.java Added Paths: ----------- branches/asm/src/org/python/antlr/ExpressionParser.java branches/asm/src/org/python/antlr/LeadingSpaceSkippingStream.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4439 + /trunk/jython:1-4443 Modified: branches/asm/Lib/test/test_descr_jy.py =================================================================== --- branches/asm/Lib/test/test_descr_jy.py 2008-05-24 23:46:09 UTC (rev 4443) +++ branches/asm/Lib/test/test_descr_jy.py 2008-05-25 03:28:56 UTC (rev 4444) @@ -3,6 +3,7 @@ Made for Jython. """ import test_support +import types import unittest class TestDescrTestCase(unittest.TestCase): @@ -19,7 +20,33 @@ class Foo(object): __metaclass__ = FooMeta + def test_descr___get__(self): + class Foo(object): + __slots__ = 'bar' + def hello(self): + pass + def hi(self): + pass + hi = staticmethod(hi) + foo = Foo() + foo.bar = 'baz' + self.assertEqual(Foo.bar.__get__(foo), 'baz') + self.assertEqual(Foo.bar.__get__(None, Foo), Foo.bar) + + bound = Foo.hello.__get__(foo) + self.assert_(isinstance(bound, types.MethodType)) + self.assert_(bound.im_self is foo) + self.assertEqual(Foo.hello.__get__(None, Foo), Foo.hello) + + bound = Foo.hi.__get__(foo) + self.assert_(isinstance(bound, types.MethodType)) + self.assert_(bound.im_self is foo) + unbound = Foo.hi.__get__(None, foo) + self.assert_(isinstance(unbound, types.MethodType)) + self.assert_(unbound.im_self is None) + + def test_main(): test_support.run_unittest(TestDescrTestCase) Copied: branches/asm/src/org/python/antlr/ExpressionParser.java (from rev 4443, trunk/jython/src/org/python/antlr/ExpressionParser.java) =================================================================== --- branches/asm/src/org/python/antlr/ExpressionParser.java (rev 0) +++ branches/asm/src/org/python/antlr/ExpressionParser.java 2008-05-25 03:28:56 UTC (rev 4444) @@ -0,0 +1,73 @@ +package org.python.antlr; + +import org.antlr.runtime.CharStream; +import org.antlr.runtime.CommonToken; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.Token; +import org.antlr.runtime.tree.CommonTree; +import org.antlr.runtime.tree.CommonTreeAdaptor; +import org.antlr.runtime.tree.CommonTreeNodeStream; +import org.antlr.runtime.tree.Tree; +import org.antlr.runtime.tree.TreeAdaptor; +import org.python.antlr.ast.modType; +import org.python.antlr.ast.Module; +import org.python.antlr.ast.stmtType; + +public class ExpressionParser { + + private CharStream charStream; + + //Extract superclass from this and the other XParsers. + public static class PyLexer extends PythonLexer { + public PyLexer(CharStream lexer) { + super(lexer); + } + + public Token nextToken() { + startPos = getCharPositionInLine(); + return super.nextToken(); + } + } + + public static TreeAdaptor pyadaptor = new CommonTreeAdaptor() { + public Object create(Token token) { + return new PythonTree(token); + } + + public Object dupNode(Object t) { + if (t == null) { + return null; + } + return create(((PythonTree) t).token); + } + }; + + public ExpressionParser(CharStream cs) { + this.charStream = cs; + } + + public modType parse() { + modType tree = null; + PythonLexer lexer = new PyLexer(this.charStream); + CommonTokenStream tokens = new CommonTokenStream(lexer); + tokens.discardOffChannelTokens(true); + PythonTokenSource indentedSource = new PythonTokenSource(tokens); + tokens = new CommonTokenStream(indentedSource); + PythonParser parser = new PythonParser(tokens); + parser.setTreeAdaptor(pyadaptor); + + try { + Object rx = parser.eval_input(); + PythonParser.eval_input_return r = (PythonParser.eval_input_return)rx; + CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); + nodes.setTokenStream(tokens); + PythonWalker walker = new PythonWalker(nodes); + tree = walker.expression(); + } catch (RecognitionException e) { + // FIXME: + System.err.println("FIXME: don't eat exceptions:" + e); + } + return tree; + } +} Copied: branches/asm/src/org/python/antlr/LeadingSpaceSkippingStream.java (from rev 4443, trunk/jython/src/org/python/antlr/LeadingSpaceSkippingStream.java) =================================================================== --- branches/asm/src/org/python/antlr/LeadingSpaceSkippingStream.java (rev 0) +++ branches/asm/src/org/python/antlr/LeadingSpaceSkippingStream.java 2008-05-25 03:28:56 UTC (rev 4444) @@ -0,0 +1,26 @@ +package org.python.antlr; + +import java.io.InputStream; +import java.io.IOException; + +public class LeadingSpaceSkippingStream extends InputStream { + + private InputStream inputStream; + private boolean maybeLeadingSpaces = true; + + public LeadingSpaceSkippingStream(InputStream is) { + inputStream = is; + } + + public int read() throws IOException { + int i = inputStream.read(); + while (maybeLeadingSpaces) { + if (i != ' ') { + maybeLeadingSpaces = false; + } else { + i = inputStream.read(); + } + } + return i; + } +} Modified: branches/asm/src/org/python/antlr/PythonGrammar.java =================================================================== --- branches/asm/src/org/python/antlr/PythonGrammar.java 2008-05-24 23:46:09 UTC (rev 4443) +++ branches/asm/src/org/python/antlr/PythonGrammar.java 2008-05-25 03:28:56 UTC (rev 4444) @@ -86,7 +86,7 @@ tree = walker.module(); if (tree == null) { //XXX: seems like I should be able to get antlr to give me an empty Module instead - // of null so I wouldn't need to build an empty Moduel by hand here... + // of null so I wouldn't need to build an empty Module by hand here... return new Module(new PythonTree(new CommonToken(PyLexer.Module)), new stmtType[0]); } } catch (RecognitionException e) { @@ -97,31 +97,6 @@ } //XXX: factor out common code. - public modType eval_input() { - modType tree = null; - PythonLexer lexer = new PyLexer(this.charStream); - CommonTokenStream tokens = new CommonTokenStream(lexer); - tokens.discardOffChannelTokens(true); - PythonTokenSource indentedSource = new PythonTokenSource(tokens); - tokens = new CommonTokenStream(indentedSource); - PythonParser parser = new PythonParser(tokens); - parser.setTreeAdaptor(pyadaptor); - - try { - Object rx = parser.eval_input(); - PythonParser.eval_input_return r = (PythonParser.eval_input_return)rx; - CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); - nodes.setTokenStream(tokens); - PythonWalker walker = new PythonWalker(nodes); - tree = walker.expression(); - } catch (RecognitionException e) { - // FIXME: - System.err.println("FIXME: don't eat exceptions:" + e); - } - return tree; - } - - //XXX: factor out common code. public modType single_input() { modType tree = null; PythonLexer lexer = new PyLexer(this.charStream); Modified: branches/asm/src/org/python/antlr/PythonTreeWalker.java =================================================================== --- branches/asm/src/org/python/antlr/PythonTreeWalker.java 2008-05-24 23:46:09 UTC (rev 4443) +++ branches/asm/src/org/python/antlr/PythonTreeWalker.java 2008-05-25 03:28:56 UTC (rev 4444) @@ -15,12 +15,16 @@ */ public class PythonTreeWalker { + public enum Block { MODULE, INTERACTIVE, EXPRESSION }; + private boolean _parseOnly; private boolean _tolerant; + private Block _block; public PythonTreeWalker() { setParseOnly(false); setTolerant(true); + setBlock(Block.MODULE); } public PythonTree parse(String[] args) throws Exception { @@ -31,11 +35,22 @@ tokens.discardOffChannelTokens(true); PythonTokenSource indentedSource = new PythonTokenSource(tokens); tokens = new CommonTokenStream(indentedSource); - // System.out.println("tokens="+tokens.getTokens()); PythonParser parser = new PythonParser(tokens); parser.setTreeAdaptor(PythonGrammar.pyadaptor); try { - PythonParser.file_input_return r = parser.file_input(); + Tree r = null; + switch (_block) { + case MODULE : + r = (Tree)parser.file_input().tree; + break; + case INTERACTIVE : + r = (Tree)parser.single_input().tree; + break; + case EXPRESSION : + r = (Tree)parser.eval_input().tree; + break; + } + //Tree r = (Tree)parser.file_input().tree; if (parser.hasErrors()) { // handle errors swallowed by antlr recovery String errors = parser.getErrors().toString(); @@ -46,13 +61,24 @@ } } if (args.length > 1) { - System.out.println(((Tree) r.tree).toStringTree()); + System.out.println((r).toStringTree()); } if (!isParseOnly()) { - CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree) r.tree); + CommonTreeNodeStream nodes = new CommonTreeNodeStream(r); nodes.setTokenStream(tokens); PythonWalker walker = new PythonWalker(nodes); - result = walker.module(); + switch (_block) { + case MODULE : + result = walker.module(); + break; + case INTERACTIVE : + result = walker.interactive(); + break; + case EXPRESSION : + result = walker.expression(); + break; + } + if (args.length > 1) { System.out.println(result.toStringTree()); } @@ -95,4 +121,12 @@ return _tolerant; } + public void setBlock(Block block) { + _block = block; + } + + public Block getBlock() { + return _block; + } + } Modified: branches/asm/src/org/python/core/PyFunction.java =================================================================== --- branches/asm/src/org/python/core/PyFunction.java 2008-05-24 23:46:09 UTC (rev 4443) +++ branches/asm/src/org/python/core/PyFunction.java 2008-05-25 03:28:56 UTC (rev 4444) @@ -292,7 +292,7 @@ return function___get__(obj, type); } - @ExposedMethod + @ExposedMethod(defaults = "null") final PyObject function___get__(PyObject obj, PyObject type) { return new PyMethod(this, obj, type); } Modified: branches/asm/src/org/python/core/PyMethod.java =================================================================== --- branches/asm/src/org/python/core/PyMethod.java 2008-05-24 23:46:09 UTC (rev 4443) +++ branches/asm/src/org/python/core/PyMethod.java 2008-05-25 03:28:56 UTC (rev 4444) @@ -65,7 +65,7 @@ return instancemethod___get__(obj, type); } - @ExposedMethod + @ExposedMethod(defaults = "null") final PyObject instancemethod___get__(PyObject obj, PyObject type) { // Only if classes are compatible if (obj == null || im_self != null) { Modified: branches/asm/src/org/python/core/PySlot.java =================================================================== --- branches/asm/src/org/python/core/PySlot.java 2008-05-24 23:46:09 UTC (rev 4443) +++ branches/asm/src/org/python/core/PySlot.java 2008-05-25 03:28:56 UTC (rev 4444) @@ -30,9 +30,9 @@ return member_descriptor___get__(obj, type); } - @ExposedMethod + @ExposedMethod(defaults = "null") public PyObject member_descriptor___get__(PyObject obj, PyObject type) { - if(obj != null) { + if (obj != null && obj != Py.None) { checkGetterType(obj.getType()); return ((Slotted)obj).getSlot(index); } Modified: branches/asm/src/org/python/core/antlr.java =================================================================== --- branches/asm/src/org/python/core/antlr.java 2008-05-24 23:46:09 UTC (rev 4443) +++ branches/asm/src/org/python/core/antlr.java 2008-05-25 03:28:56 UTC (rev 4444) @@ -12,6 +12,8 @@ import org.antlr.runtime.ANTLRReaderStream; import org.antlr.runtime.CharStream; import org.antlr.runtime.RecognitionException; +import org.python.antlr.ExpressionParser; +import org.python.antlr.LeadingSpaceSkippingStream; import org.python.antlr.PythonGrammar; import org.python.core.util.StringUtil; import org.python.antlr.IParserHost; @@ -92,22 +94,23 @@ public static modType parse(InputStream istream, String kind, String filename, CompilerFlags cflags) { - BufferedReader bufreader = prepBufreader(istream, cflags); - /* FJW FJW - PythonGrammar g = new PythonGrammar(new ReaderCharStream(bufreader), - literalMkrForParser); - */ CharStream cs = null; - try { - cs = new ANTLRReaderStream(bufreader); - } catch (IOException io){ - //FIXME: - System.err.println("FIXME: Don't eat exceptions."); - } - PythonGrammar g = new PythonGrammar(cs);//FJW, literalMkrForParser); + //FIXME: definite NPE potential here -- do we even need prepBufreader + // now? + BufferedReader bufreader = null; modType node = null; try { - node = doparse(kind, cflags, g); + if (kind.equals("eval")) { + bufreader = prepBufreader(new LeadingSpaceSkippingStream(istream), cflags); + cs = new ANTLRReaderStream(bufreader); + ExpressionParser e = new ExpressionParser(cs); + node = e.parse(); + } else { + bufreader = prepBufreader(istream, cflags); + cs = new ANTLRReaderStream(bufreader); + PythonGrammar g = new PythonGrammar(cs);//FJW, literalMkrForParser); + node = doparse(kind, cflags, g); + } } catch (Throwable t) { throw fixParseError(bufreader, t, filename); @@ -162,10 +165,7 @@ //FJW if (cflags != null) //FJW g.token_source.generator_allowed = cflags.generator_allowed; - if (kind.equals("eval")) { - node = g.eval_input(); - } - else if (kind.equals("exec")) { + if (kind.equals("exec")) { node = g.file_input(); } else if (kind.equals("single")) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-26 02:27:12
|
Revision: 4452 http://jython.svn.sourceforge.net/jython/?rev=4452&view=rev Author: fwierzbicki Date: 2008-05-25 19:27:07 -0700 (Sun, 25 May 2008) Log Message: ----------- Merged revisions 4445 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4445 | fwierzbicki | 2008-05-25 08:47:37 -0400 (Sun, 25 May 2008) | 3 lines Fail on first syntax error. Use antlr's RecognitionException to handle syntax errors. ........ Modified Paths: -------------- branches/asm/ast/astview.py branches/asm/grammar/Python.g branches/asm/grammar/PythonWalker.g branches/asm/src/org/python/antlr/PythonGrammar.java branches/asm/src/org/python/core/antlr.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4443 + /trunk/jython:1-4445 Modified: branches/asm/ast/astview.py =================================================================== --- branches/asm/ast/astview.py 2008-05-25 23:28:57 UTC (rev 4451) +++ branches/asm/ast/astview.py 2008-05-26 02:27:07 UTC (rev 4452) @@ -70,7 +70,10 @@ yield node def tree(pyfile): - ast = compile(open(pyfile).read(), pyfile, "exec", _ast.PyCF_ONLY_AST) + try: + ast = compile(open(pyfile).read(), pyfile, "exec", _ast.PyCF_ONLY_AST) + except SyntaxError: + return "SyntaxError", return lispify_ast(ast) if __name__ == '__main__': Modified: branches/asm/grammar/Python.g =================================================================== --- branches/asm/grammar/Python.g 2008-05-25 23:28:57 UTC (rev 4451) +++ branches/asm/grammar/Python.g 2008-05-26 02:27:07 UTC (rev 4452) @@ -199,6 +199,14 @@ } } + protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException { + throw new MismatchedTokenException(ttype, input); + } + + protected void mismatch(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException { + throw e; + } + /** * A list holding the error message(s) encountered during parse. */ @@ -229,8 +237,15 @@ super.emitErrorMessage(msg); getErrors().add(msg); } + } +@rulecatch { +catch (RecognitionException e) { + throw e; +} +} + @lexer::header { package org.python.antlr; } @@ -392,7 +407,7 @@ ( t1=printlist -> {$t1.newline}? ^(Print 'print' ^(Values $t1) ^(Newline)) -> ^(Print 'print' ^(Values $t1)) | RIGHTSHIFT t2=printlist -> {$t2.newline}? ^(Print 'print' ^(Dest RIGHTSHIFT) ^(Values $t2) ^(Newline)) - -> ^(Print 'print' ^(Dest RIGHTSHIFT) ^(Values $t2)) + -> ^(Print 'print' ^(Dest RIGHTSHIFT) ^(Values $t2)) | -> ^(Print 'print' ^(Newline)) ) ; Modified: branches/asm/grammar/PythonWalker.g =================================================================== --- branches/asm/grammar/PythonWalker.g 2008-05-25 23:28:57 UTC (rev 4451) +++ branches/asm/grammar/PythonWalker.g 2008-05-26 02:27:07 UTC (rev 4452) @@ -553,8 +553,8 @@ ; target[List etypes] - : ^(Target test[expr_contextType.Store]) { - etypes.add($test.etype); + : ^(Target atom[expr_contextType.Store]) { + etypes.add($atom.etype); } ; Modified: branches/asm/src/org/python/antlr/PythonGrammar.java =================================================================== --- branches/asm/src/org/python/antlr/PythonGrammar.java 2008-05-25 23:28:57 UTC (rev 4451) +++ branches/asm/src/org/python/antlr/PythonGrammar.java 2008-05-26 02:27:07 UTC (rev 4452) @@ -67,7 +67,7 @@ } //XXX: factor out common code. - public modType file_input() { + public modType file_input() throws RecognitionException { modType tree = null; PythonLexer lexer = new PyLexer(this.charStream); CommonTokenStream tokens = new CommonTokenStream(lexer); @@ -77,27 +77,22 @@ PythonParser parser = new PythonParser(tokens); parser.setTreeAdaptor(pyadaptor); - try { - Object rx = parser.file_input(); - PythonParser.file_input_return r = (PythonParser.file_input_return)rx; - CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); - nodes.setTokenStream(tokens); - PythonWalker walker = new PythonWalker(nodes); - tree = walker.module(); - if (tree == null) { - //XXX: seems like I should be able to get antlr to give me an empty Module instead - // of null so I wouldn't need to build an empty Module by hand here... - return new Module(new PythonTree(new CommonToken(PyLexer.Module)), new stmtType[0]); - } - } catch (RecognitionException e) { - // FIXME: - System.err.println("FIXME: don't eat exceptions:" + e); + Object rx = parser.file_input(); + PythonParser.file_input_return r = (PythonParser.file_input_return)rx; + CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); + nodes.setTokenStream(tokens); + PythonWalker walker = new PythonWalker(nodes); + tree = walker.module(); + if (tree == null) { + //XXX: seems like I should be able to get antlr to give me an empty Module instead + // of null so I wouldn't need to build an empty Module by hand here... + return new Module(new PythonTree(new CommonToken(PyLexer.Module)), new stmtType[0]); } return tree; } //XXX: factor out common code. - public modType single_input() { + public modType single_input() throws RecognitionException { modType tree = null; PythonLexer lexer = new PyLexer(this.charStream); CommonTokenStream tokens = new CommonTokenStream(lexer); @@ -106,18 +101,12 @@ tokens = new CommonTokenStream(indentedSource); PythonParser parser = new PythonParser(tokens); parser.setTreeAdaptor(pyadaptor); - try { - Object rx = parser.single_input(); - PythonParser.single_input_return r = (PythonParser.single_input_return)rx; - CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); - nodes.setTokenStream(tokens); - PythonWalker walker = new PythonWalker(nodes); - tree = walker.interactive(); - } catch (RecognitionException e) { - // FIXME: - System.err.println("FIXME: don't eat exceptions:" + e); - } + Object rx = parser.single_input(); + PythonParser.single_input_return r = (PythonParser.single_input_return)rx; + CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); + nodes.setTokenStream(tokens); + PythonWalker walker = new PythonWalker(nodes); + tree = walker.interactive(); return tree; } - } Modified: branches/asm/src/org/python/core/antlr.java =================================================================== --- branches/asm/src/org/python/core/antlr.java 2008-05-25 23:28:57 UTC (rev 4451) +++ branches/asm/src/org/python/core/antlr.java 2008-05-26 02:27:07 UTC (rev 4452) @@ -12,9 +12,11 @@ import org.antlr.runtime.ANTLRReaderStream; import org.antlr.runtime.CharStream; import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.*; import org.python.antlr.ExpressionParser; import org.python.antlr.LeadingSpaceSkippingStream; import org.python.antlr.PythonGrammar; +import org.python.antlr.PythonParser; import org.python.core.util.StringUtil; import org.python.antlr.IParserHost; import org.python.antlr.PythonTree; @@ -58,34 +60,96 @@ if (t instanceof RecognitionException) { RecognitionException e = (RecognitionException)t; - //FJW Token tok = e.currentToken; - int col=0; - int line=0; - //FJW if (tok != null && tok.next != null) { - //FJW col = tok.next.beginColumn; - //FJW line = tok.next.beginLine; - //FJW } - String text=getLine(reader, line); - return new PySyntaxError(e.getMessage(), line, col, + String msg = e.getMessage(); + String tokenNames[] = PythonParser.tokenNames; + /* XXX: think the first two are new in antlr 3.1 + if ( e instanceof UnwantedTokenException ) { + UnwantedTokenException ute = (UnwantedTokenException)e; + String tokenName="<unknown>"; + if ( ute.expecting== Token.EOF ) { + tokenName = "EOF"; + } + else { + tokenName = tokenNames[ute.expecting]; + } + msg = "extraneous input "+getTokenErrorDisplay(ute.getUnexpectedToken())+ + " expecting "+tokenName; + } + else if ( e instanceof MissingTokenException ) { + MissingTokenException mte = (MissingTokenException)e; + String tokenName="<unknown>"; + if ( mte.expecting== Token.EOF ) { + tokenName = "EOF"; + } + else { + tokenName = tokenNames[mte.expecting]; + } + msg = "missing "+tokenName+" at "+getTokenErrorDisplay(e.token); + } + */ + if ( e instanceof MismatchedTokenException ) { + MismatchedTokenException mte = (MismatchedTokenException)e; + String tokenName="<unknown>"; + if ( mte.expecting== Token.EOF ) { + tokenName = "EOF"; + } + else { + tokenName = tokenNames[mte.expecting]; + } + msg = "mismatched input "+getTokenErrorDisplay(e.token)+ + " expecting "+tokenName; + } + else if ( e instanceof MismatchedTreeNodeException ) { + MismatchedTreeNodeException mtne = (MismatchedTreeNodeException)e; + String tokenName="<unknown>"; + if ( mtne.expecting==Token.EOF ) { + tokenName = "EOF"; + } + else { + tokenName = tokenNames[mtne.expecting]; + } + msg = "mismatched tree node: "+mtne.node+ + " expecting "+tokenName; + } + else if ( e instanceof NoViableAltException ) { + NoViableAltException nvae = (NoViableAltException)e; + // for development, can add "decision=<<"+nvae.grammarDecisionDescription+">>" + // and "(decision="+nvae.decisionNumber+") and + // "state "+nvae.stateNumber + msg = "no viable alternative at input "+getTokenErrorDisplay(e.token); + } + else if ( e instanceof EarlyExitException ) { + EarlyExitException eee = (EarlyExitException)e; + // for development, can add "(decision="+eee.decisionNumber+")" + msg = "required (...)+ loop did not match anything at input "+ + getTokenErrorDisplay(e.token); + } + else if ( e instanceof MismatchedSetException ) { + MismatchedSetException mse = (MismatchedSetException)e; + msg = "mismatched input "+getTokenErrorDisplay(e.token)+ + " expecting set "+mse.expecting; + } + else if ( e instanceof MismatchedNotSetException ) { + MismatchedNotSetException mse = (MismatchedNotSetException)e; + msg = "mismatched input "+getTokenErrorDisplay(e.token)+ + " expecting set "+mse.expecting; + } + else if ( e instanceof FailedPredicateException ) { + FailedPredicateException fpe = (FailedPredicateException)e; + msg = "rule "+fpe.ruleName+" failed predicate: {"+ + fpe.predicateText+"}?"; + } + String text=getLine(reader, e.line); + return new PySyntaxError(msg, e.line, e.charPositionInLine, text, filename); } - /* FJW FJW FJW - if (t instanceof TokenMgrError) { - TokenMgrError e = (TokenMgrError)t; - boolean eofSeen = e.EOFSeen; - - int col = e.errorColumn; - int line = e.errorLine; - String text = getLine(reader, line); - if (eofSeen) - col -= 1; - return new PySyntaxError(e.getMessage(), line, col, - text, filename); - } - */ else return Py.JavaError(t); } + private static String getTokenErrorDisplay(Token t) { + return t.getText(); + } + public static PythonTree parse(String string, String kind) { return parse(new ByteArrayInputStream(StringUtil.toBytes(string)), kind, "<string>", null); @@ -158,7 +222,7 @@ } private static modType doparse(String kind, CompilerFlags cflags, - PythonGrammar g) throws /*Parse*/Exception //FJW + PythonGrammar g) throws RecognitionException { modType node = null; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-26 13:57:56
|
Revision: 4455 http://jython.svn.sourceforge.net/jython/?rev=4455&view=rev Author: fwierzbicki Date: 2008-05-26 06:57:54 -0700 (Mon, 26 May 2008) Log Message: ----------- Merged revisions 4447,4449,4453-4454 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4447 | cgroves | 2008-05-25 16:38:53 -0400 (Sun, 25 May 2008) | 10 lines Add a basic project for Eclipse. It requires that ant be run first to make gensrc and jarjar, though that could probably be fixed by some intrepid work with the External Builder. It also requires an ANT_HOME variable to be defined as the directory where ant is installed. It excludes the Informix and Oracle classes from the build since they aren't included by default in extlibs, but they'll still be built by ant if you have the jars. ........ r4449 | pjenvey | 2008-05-25 19:21:36 -0400 (Sun, 25 May 2008) | 2 lines add CPython 2.3's special case for KeyError__str__ patch from lsoto, fixes #1040 ........ r4453 | pjenvey | 2008-05-26 01:37:52 -0400 (Mon, 26 May 2008) | 1 line r4449 synced us with 2.3 test_exceptions' output ........ r4454 | fwierzbicki | 2008-05-26 09:41:36 -0400 (Mon, 26 May 2008) | 2 lines Tighten grammar around "print <<" statements. "print << a ," not allowed. ........ Modified Paths: -------------- branches/asm/grammar/Python.g branches/asm/src/org/python/core/exceptions.java Added Paths: ----------- branches/asm/.classpath branches/asm/.externalToolBuilders/ branches/asm/.externalToolBuilders/Expose and jar.launch branches/asm/.project branches/asm/Lib/test/test_exceptions_jy.py Removed Paths: ------------- branches/asm/.externalToolBuilders/Expose and jar.launch branches/asm/Lib/test/output/test_exceptions Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4445 + /trunk/jython:1-4454 Copied: branches/asm/.classpath (from rev 4454, trunk/jython/.classpath) =================================================================== --- branches/asm/.classpath (rev 0) +++ branches/asm/.classpath 2008-05-26 13:57:54 UTC (rev 4455) @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="lib" path="build/exposed"/> + <classpathentry excluding="com/ziclix/python/sql/handler/InformixDataHandler.java|com/ziclix/python/sql/handler/OracleDataHandler.java" kind="src" output="build/classes" path="src"/> + <classpathentry kind="src" output="build/classes" path="build/gensrc"/> + <classpathentry kind="src" output="build/classes" path="tests/java"/> + <classpathentry kind="src" path="bugtests/classes"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3"/> + <classpathentry kind="lib" path="extlibs/jline-0.9.94.jar"/> + <classpathentry kind="lib" path="extlibs/junit-3.8.2.jar"/> + <classpathentry kind="lib" path="extlibs/libreadline-java-0.8.jar"/> + <classpathentry kind="lib" path="extlibs/mysql-connector-java-5.1.6.jar"/> + <classpathentry kind="lib" path="extlibs/postgresql-8.3-603.jdbc4.jar"/> + <classpathentry kind="lib" path="extlibs/servlet-api-2.5.jar"/> + <classpathentry kind="lib" path="build/jarjar"/> + <classpathentry kind="lib" path="extlibs/antlr-3.0.1.jar"/> + <classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/> + <classpathentry kind="output" path="bugtests/classes"/> +</classpath> Copied: branches/asm/.externalToolBuilders (from rev 4454, trunk/jython/.externalToolBuilders) Deleted: branches/asm/.externalToolBuilders/Expose and jar.launch =================================================================== --- trunk/jython/.externalToolBuilders/Expose and jar.launch 2008-05-26 13:41:36 UTC (rev 4454) +++ branches/asm/.externalToolBuilders/Expose and jar.launch 2008-05-26 13:57:54 UTC (rev 4455) @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> -<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AUTO_TARGETS" value="expose,jar,"/> -<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/> -<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> -<listEntry value="/jython-trunk/build.xml"/> -</listAttribute> -<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> -<listEntry value="1"/> -</listAttribute> -<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> -<booleanAttribute key="org.eclipse.debug.core.capture_output" value="false"/> -<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="false"/> -<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> -<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> -<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/> -<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="jython-trunk"/> -<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/jython-trunk/build.xml}"/> -<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="auto,"/> -<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> -</launchConfiguration> Copied: branches/asm/.externalToolBuilders/Expose and jar.launch (from rev 4454, trunk/jython/.externalToolBuilders/Expose and jar.launch) =================================================================== --- branches/asm/.externalToolBuilders/Expose and jar.launch (rev 0) +++ branches/asm/.externalToolBuilders/Expose and jar.launch 2008-05-26 13:57:54 UTC (rev 4455) @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> +<stringAttribute key="org.eclipse.ant.ui.ATTR_ANT_AUTO_TARGETS" value="expose,jar,"/> +<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/> +<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> +<listEntry value="/jython-trunk/build.xml"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> +<listEntry value="1"/> +</listAttribute> +<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/> +<booleanAttribute key="org.eclipse.debug.core.capture_output" value="false"/> +<booleanAttribute key="org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON" value="false"/> +<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> +<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> +<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="jython-trunk"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/jython-trunk/build.xml}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="auto,"/> +<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> +</launchConfiguration> Copied: branches/asm/.project (from rev 4454, trunk/jython/.project) =================================================================== --- branches/asm/.project (rev 0) +++ branches/asm/.project 2008-05-26 13:57:54 UTC (rev 4455) @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>jython-trunk</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.ui.externaltools.ExternalToolBuilder</name> + <triggers>auto,</triggers> + <arguments> + <dictionary> + <key>LaunchConfigHandle</key> + <value><project>/.externalToolBuilders/Expose and jar.launch</value> + </dictionary> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> Deleted: branches/asm/Lib/test/output/test_exceptions =================================================================== --- branches/asm/Lib/test/output/test_exceptions 2008-05-26 13:41:36 UTC (rev 4454) +++ branches/asm/Lib/test/output/test_exceptions 2008-05-26 13:57:54 UTC (rev 4455) @@ -1,52 +0,0 @@ -test_exceptions -5. Built-in exceptions -spam -AttributeError -spam -EOFError -spam -IOError -spam -ImportError -spam -IndexError -spam -KeyError -spam -KeyboardInterrupt -(not testable in a script) -spam -MemoryError -(not safe to test) -spam -NameError -spam -OverflowError -spam -RuntimeError -(not used any more?) -spam -SyntaxError -'continue' not supported inside 'finally' clause -ok -'continue' not properly in loop -ok -'continue' not properly in loop -ok -spam -IndentationError -spam -TabError -spam -SystemError -(hard to reproduce) -spam -SystemExit -spam -TypeError -spam -ValueError -spam -ZeroDivisionError -spam -Exception Copied: branches/asm/Lib/test/test_exceptions_jy.py (from rev 4454, trunk/jython/Lib/test/test_exceptions_jy.py) =================================================================== --- branches/asm/Lib/test/test_exceptions_jy.py (rev 0) +++ branches/asm/Lib/test/test_exceptions_jy.py 2008-05-26 13:57:54 UTC (rev 4455) @@ -0,0 +1,21 @@ +"""Misc. exception related tests + +Made for Jython. +""" +import test_support +import unittest + +class ExceptionsTestCase(unittest.TestCase): + + def test_keyerror_str(self): + self.assertEquals(str(KeyError()), '') + # Is actually repr(args[0]) + self.assertEquals(str(KeyError('')), "''") + self.assertEquals(str(KeyError('', '')), "('', '')") + + +def test_main(): + test_support.run_unittest(ExceptionsTestCase) + +if __name__ == '__main__': + test_main() Modified: branches/asm/grammar/Python.g =================================================================== --- branches/asm/grammar/Python.g 2008-05-26 13:41:36 UTC (rev 4454) +++ branches/asm/grammar/Python.g 2008-05-26 13:57:54 UTC (rev 4455) @@ -406,7 +406,7 @@ print_stmt : 'print' ( t1=printlist -> {$t1.newline}? ^(Print 'print' ^(Values $t1) ^(Newline)) -> ^(Print 'print' ^(Values $t1)) - | RIGHTSHIFT t2=printlist -> {$t2.newline}? ^(Print 'print' ^(Dest RIGHTSHIFT) ^(Values $t2) ^(Newline)) + | RIGHTSHIFT t2=printlist2 -> {$t2.newline}? ^(Print 'print' ^(Dest RIGHTSHIFT) ^(Values $t2) ^(Newline)) -> ^(Print 'print' ^(Dest RIGHTSHIFT) ^(Values $t2)) | -> ^(Print 'print' ^(Newline)) ) @@ -426,7 +426,21 @@ -> ^(Elts test) ; +//not in CPython's Grammar file +printlist2 returns [boolean newline] + : (test COMMA test) => test (options {k=2;}: COMMA test)* (trailcomma=COMMA)? + { if ($trailcomma == null) { + $newline = true; + } else { + $newline = false; + } + } + -> ^(Elts test+) + | test {$newline = true;} + -> ^(Elts test) + ; + //del_stmt: 'del' exprlist del_stmt : 'del' exprlist2 -> ^(Delete 'del' exprlist2) Modified: branches/asm/src/org/python/core/exceptions.java =================================================================== --- branches/asm/src/org/python/core/exceptions.java 2008-05-26 13:41:36 UTC (rev 4454) +++ branches/asm/src/org/python/core/exceptions.java 2008-05-26 13:57:54 UTC (rev 4455) @@ -199,7 +199,7 @@ buildClass(dict, "IndexError", "LookupError", "empty__init__", "Sequence index out of range."); - buildClass(dict, "KeyError", "LookupError", "empty__init__", + buildClass(dict, "KeyError", "LookupError", "KeyError", "Mapping key not found."); buildClass(dict, "AttributeError", "StandardError", "empty__init__", @@ -613,6 +613,32 @@ return dict; } + public static PyObject KeyError__str__(PyObject[] arg, String[] kws) { + ArgParser ap = new ArgParser("__str__", arg, kws, "self"); + PyObject self = ap.getPyObject(0); + + PyObject args = self.__getattr__("args"); + // If args is a tuple of exactly one item, apply repr to args[0]. + // This is done so that e.g. the exception raised by {}[''] prints + // KeyError: '' + // rather than the confusing + // KeyError + // alone. The downside is that if KeyError is raised with an explanatory + // string, that string will be displayed in quotes. Too bad. + if (args.__len__() == 1) { + return args.__getitem__(0).__repr__(); + } else { + return Exception__str__(arg, kws); + } + } + + public static PyObject KeyError(PyObject[] arg, String[] kws) { + PyObject dict = empty__init__(arg, kws); + dict.__setitem__("__str__", getJavaFunc("KeyError__str__")); + return dict; + + } + private static PyObject getJavaFunc(String name) { return Py.newJavaFunc(exceptions.class, name); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-26 17:32:57
|
Revision: 4457 http://jython.svn.sourceforge.net/jython/?rev=4457&view=rev Author: fwierzbicki Date: 2008-05-26 10:32:53 -0700 (Mon, 26 May 2008) Log Message: ----------- Merged revisions 4456 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4456 | fwierzbicki | 2008-05-26 13:26:16 -0400 (Mon, 26 May 2008) | 3 lines Better exception handling in antlr parser (fail fast in PythonWalker, and new class antlr/ParseException. ........ Modified Paths: -------------- branches/asm/grammar/PythonWalker.g branches/asm/src/org/python/antlr/ParseException.java branches/asm/src/org/python/core/antlr.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4454 + /trunk/jython:1-4456 Modified: branches/asm/grammar/PythonWalker.g =================================================================== --- branches/asm/grammar/PythonWalker.g 2008-05-26 17:26:16 UTC (rev 4456) +++ branches/asm/grammar/PythonWalker.g 2008-05-26 17:32:53 UTC (rev 4457) @@ -93,6 +93,15 @@ } } + protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException { + throw new MismatchedTokenException(ttype, input); + } + + protected void mismatch(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException { + throw e; + } + + String name = "Test"; //XXX: Not sure I need any below... @@ -350,6 +359,13 @@ } } +@rulecatch { +catch (RecognitionException e) { + throw e; +} +} + + expression returns [modType mod] : ^(Expression test[expr_contextType.Load]) { $mod = makeExpression($Expression, $test.etype); } ; Modified: branches/asm/src/org/python/antlr/ParseException.java =================================================================== --- branches/asm/src/org/python/antlr/ParseException.java 2008-05-26 17:26:16 UTC (rev 4456) +++ branches/asm/src/org/python/antlr/ParseException.java 2008-05-26 17:32:53 UTC (rev 4457) @@ -1,17 +1,21 @@ package org.python.antlr; +import org.python.antlr.PythonTree; + public class ParseException extends Exception { - public ParseException() { - super(); - } + public PythonTree currentToken = null; - public ParseException(String message) { - super(message); - } + public ParseException() { + super(); + } - public ParseException(String message, PythonTree node) { - super(message); - } + public ParseException(String message) { + super(message); + } + public ParseException(String message, PythonTree node) { + super(message); + this.currentToken = node; + } } Modified: branches/asm/src/org/python/core/antlr.java =================================================================== --- branches/asm/src/org/python/core/antlr.java 2008-05-26 17:26:16 UTC (rev 4456) +++ branches/asm/src/org/python/core/antlr.java 2008-05-26 17:32:53 UTC (rev 4457) @@ -15,8 +15,10 @@ import org.antlr.runtime.*; import org.python.antlr.ExpressionParser; import org.python.antlr.LeadingSpaceSkippingStream; +import org.python.antlr.ParseException; import org.python.antlr.PythonGrammar; import org.python.antlr.PythonParser; +import org.python.antlr.PythonTree; import org.python.core.util.StringUtil; import org.python.antlr.IParserHost; import org.python.antlr.PythonTree; @@ -58,7 +60,20 @@ } } - if (t instanceof RecognitionException) { + if (t instanceof ParseException) { + ParseException e = (ParseException)t; + PythonTree tok = e.currentToken; + int line=0; + int col=0; + if (tok != null) { + line = tok.getLine(); + col = tok.getCharPositionInLine(); + } + String text=getLine(reader, line); + return new PySyntaxError(e.getMessage(), line, col, + text, filename); + } + else if (t instanceof RecognitionException) { RecognitionException e = (RecognitionException)t; String msg = e.getMessage(); String tokenNames[] = PythonParser.tokenNames; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-27 15:56:28
|
Revision: 4459 http://jython.svn.sourceforge.net/jython/?rev=4459&view=rev Author: fwierzbicki Date: 2008-05-27 08:56:25 -0700 (Tue, 27 May 2008) Log Message: ----------- Merged revisions 4458 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4458 | fwierzbicki | 2008-05-27 08:08:02 -0400 (Tue, 27 May 2008) | 2 lines Throw ParseException for non-default arg after default arg. ........ Modified Paths: -------------- branches/asm/grammar/PythonWalker.g branches/asm/src/org/python/antlr/ParseException.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4456 + /trunk/jython:1-4458 Modified: branches/asm/grammar/PythonWalker.g =================================================================== --- branches/asm/grammar/PythonWalker.g 2008-05-27 12:08:02 UTC (rev 4458) +++ branches/asm/grammar/PythonWalker.g 2008-05-27 15:56:25 UTC (rev 4459) @@ -11,6 +11,7 @@ import org.python.core.Py; import org.python.core.PyObject; import org.python.core.PyString; +import org.python.antlr.ParseException; import org.python.antlr.ast.aliasType; import org.python.antlr.ast.argumentsType; import org.python.antlr.ast.boolopType; @@ -409,6 +410,10 @@ params.add($fpdef.etype); if ($ASSIGN != null) { defaults.add($test.etype); + } else if (!defaults.isEmpty()) { + throw new ParseException( + "non-default argument follows default argument", + $fpdef.start); } } ; Modified: branches/asm/src/org/python/antlr/ParseException.java =================================================================== --- branches/asm/src/org/python/antlr/ParseException.java 2008-05-27 12:08:02 UTC (rev 4458) +++ branches/asm/src/org/python/antlr/ParseException.java 2008-05-27 15:56:25 UTC (rev 4459) @@ -2,7 +2,7 @@ import org.python.antlr.PythonTree; -public class ParseException extends Exception { +public class ParseException extends RuntimeException { public PythonTree currentToken = null; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-27 17:05:21
|
Revision: 4461 http://jython.svn.sourceforge.net/jython/?rev=4461&view=rev Author: fwierzbicki Date: 2008-05-27 10:05:17 -0700 (Tue, 27 May 2008) Log Message: ----------- Merged revisions 4460 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4460 | fwierzbicki | 2008-05-27 12:56:34 -0400 (Tue, 27 May 2008) | 4 lines Fail fast on lexer errors. Also correct lexing of imaginary numbers (can start with zero, are never octal or hex). ........ Modified Paths: -------------- branches/asm/grammar/Python.g Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4458 + /trunk/jython:1-4460 Modified: branches/asm/grammar/Python.g =================================================================== --- branches/asm/grammar/Python.g 2008-05-27 16:56:34 UTC (rev 4460) +++ branches/asm/grammar/Python.g 2008-05-27 17:05:17 UTC (rev 4461) @@ -187,6 +187,7 @@ @header { package org.python.antlr; +import org.python.antlr.ParseException; import org.python.antlr.PythonTree; } @@ -258,6 +259,33 @@ */ int implicitLineJoiningLevel = 0; int startPos=-1; + + public Token nextToken() { + while (true) { + token = null; + channel = Token.DEFAULT_CHANNEL; + tokenStartCharIndex = input.index(); + tokenStartCharPositionInLine = input.getCharPositionInLine(); + tokenStartLine = input.getLine(); + text = null; + if ( input.LA(1)==CharStream.EOF ) { + return Token.EOF_TOKEN; + } + try { + mTokens(); + if ( token==null ) { + emit(); + } + else if ( token==Token.SKIP_TOKEN ) { + continue; + } + return token; + } + catch (RecognitionException re) { + throw new ParseException(getErrorMessage(re, this.getTokenNames())); + } + } + } } //single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE @@ -985,12 +1013,12 @@ INT : // Hex '0' ('x' | 'X') ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' )+ | // Octal - '0' DIGITS* + '0' ( '0' .. '7' )* | '1'..'9' DIGITS* ; COMPLEX - : INT ('j'|'J') + : DIGITS+ ('j'|'J') | FLOAT ('j'|'J') ; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-27 18:57:00
|
Revision: 4463 http://jython.svn.sourceforge.net/jython/?rev=4463&view=rev Author: fwierzbicki Date: 2008-05-27 11:56:58 -0700 (Tue, 27 May 2008) Log Message: ----------- Merged revisions 4462 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4462 | fwierzbicki | 2008-05-27 14:48:24 -0400 (Tue, 27 May 2008) | 2 lines Some cleanup of the parser driving classes. ........ Modified Paths: -------------- branches/asm/src/org/python/antlr/ExpressionParser.java branches/asm/src/org/python/antlr/PythonGrammar.java branches/asm/src/org/python/core/antlr.java Added Paths: ----------- branches/asm/src/org/python/antlr/InteractiveParser.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4460 + /trunk/jython:1-4462 Modified: branches/asm/src/org/python/antlr/ExpressionParser.java =================================================================== --- branches/asm/src/org/python/antlr/ExpressionParser.java 2008-05-27 18:48:24 UTC (rev 4462) +++ branches/asm/src/org/python/antlr/ExpressionParser.java 2008-05-27 18:56:58 UTC (rev 4463) @@ -47,7 +47,7 @@ this.charStream = cs; } - public modType parse() { + public modType parse() throws RecognitionException { modType tree = null; PythonLexer lexer = new PyLexer(this.charStream); CommonTokenStream tokens = new CommonTokenStream(lexer); @@ -57,17 +57,12 @@ PythonParser parser = new PythonParser(tokens); parser.setTreeAdaptor(pyadaptor); - try { - Object rx = parser.eval_input(); - PythonParser.eval_input_return r = (PythonParser.eval_input_return)rx; - CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); - nodes.setTokenStream(tokens); - PythonWalker walker = new PythonWalker(nodes); - tree = walker.expression(); - } catch (RecognitionException e) { - // FIXME: - System.err.println("FIXME: don't eat exceptions:" + e); - } + Object rx = parser.eval_input(); + PythonParser.eval_input_return r = (PythonParser.eval_input_return)rx; + CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); + nodes.setTokenStream(tokens); + PythonWalker walker = new PythonWalker(nodes); + tree = walker.expression(); return tree; - } + } } Copied: branches/asm/src/org/python/antlr/InteractiveParser.java (from rev 4462, trunk/jython/src/org/python/antlr/InteractiveParser.java) =================================================================== --- branches/asm/src/org/python/antlr/InteractiveParser.java (rev 0) +++ branches/asm/src/org/python/antlr/InteractiveParser.java 2008-05-27 18:56:58 UTC (rev 4463) @@ -0,0 +1,68 @@ +package org.python.antlr; + +import org.antlr.runtime.CharStream; +import org.antlr.runtime.CommonToken; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.Token; +import org.antlr.runtime.tree.CommonTree; +import org.antlr.runtime.tree.CommonTreeAdaptor; +import org.antlr.runtime.tree.CommonTreeNodeStream; +import org.antlr.runtime.tree.Tree; +import org.antlr.runtime.tree.TreeAdaptor; +import org.python.antlr.ast.modType; +import org.python.antlr.ast.Module; +import org.python.antlr.ast.stmtType; + +public class InteractiveParser { + + private CharStream charStream; + + //Extract superclass from this and the other XParsers. + public static class PyLexer extends PythonLexer { + public PyLexer(CharStream lexer) { + super(lexer); + } + + public Token nextToken() { + startPos = getCharPositionInLine(); + return super.nextToken(); + } + } + + public static TreeAdaptor pyadaptor = new CommonTreeAdaptor() { + public Object create(Token token) { + return new PythonTree(token); + } + + public Object dupNode(Object t) { + if (t == null) { + return null; + } + return create(((PythonTree) t).token); + } + }; + + public InteractiveParser(CharStream cs) { + this.charStream = cs; + } + + public modType parse() throws RecognitionException { + modType tree = null; + PythonLexer lexer = new PyLexer(this.charStream); + CommonTokenStream tokens = new CommonTokenStream(lexer); + tokens.discardOffChannelTokens(true); + PythonTokenSource indentedSource = new PythonTokenSource(tokens); + tokens = new CommonTokenStream(indentedSource); + PythonParser parser = new PythonParser(tokens); + parser.setTreeAdaptor(pyadaptor); + + Object rx = parser.single_input(); + PythonParser.single_input_return r = (PythonParser.single_input_return)rx; + CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); + nodes.setTokenStream(tokens); + PythonWalker walker = new PythonWalker(nodes); + tree = walker.interactive(); + return tree; + } +} Modified: branches/asm/src/org/python/antlr/PythonGrammar.java =================================================================== --- branches/asm/src/org/python/antlr/PythonGrammar.java 2008-05-27 18:48:24 UTC (rev 4462) +++ branches/asm/src/org/python/antlr/PythonGrammar.java 2008-05-27 18:56:58 UTC (rev 4463) @@ -52,21 +52,6 @@ this.charStream = cs; } - public void printTree(CommonTree t, int indent) { - if (t != null) { - System.out.println("XXX: " + t.toString() + t.getType()); - StringBuffer sb = new StringBuffer(indent); - for (int i = 0; i < indent; i++) { - sb = sb.append(" "); - } - for (int i = 0; i < t.getChildCount(); i++) { - System.out.println(sb.toString() + t.getChild(i).toString() + ":" + t.getChild(i).getType()); - printTree((CommonTree) t.getChild(i), indent + 1); - } - } - } - - //XXX: factor out common code. public modType file_input() throws RecognitionException { modType tree = null; PythonLexer lexer = new PyLexer(this.charStream); @@ -90,23 +75,4 @@ } return tree; } - - //XXX: factor out common code. - public modType single_input() throws RecognitionException { - modType tree = null; - PythonLexer lexer = new PyLexer(this.charStream); - CommonTokenStream tokens = new CommonTokenStream(lexer); - tokens.discardOffChannelTokens(true); - PythonTokenSource indentedSource = new PythonTokenSource(tokens); - tokens = new CommonTokenStream(indentedSource); - PythonParser parser = new PythonParser(tokens); - parser.setTreeAdaptor(pyadaptor); - Object rx = parser.single_input(); - PythonParser.single_input_return r = (PythonParser.single_input_return)rx; - CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree); - nodes.setTokenStream(tokens); - PythonWalker walker = new PythonWalker(nodes); - tree = walker.interactive(); - return tree; - } } Modified: branches/asm/src/org/python/core/antlr.java =================================================================== --- branches/asm/src/org/python/core/antlr.java 2008-05-27 18:48:24 UTC (rev 4462) +++ branches/asm/src/org/python/core/antlr.java 2008-05-27 18:56:58 UTC (rev 4463) @@ -14,6 +14,7 @@ import org.antlr.runtime.RecognitionException; import org.antlr.runtime.*; import org.python.antlr.ExpressionParser; +import org.python.antlr.InteractiveParser; import org.python.antlr.LeadingSpaceSkippingStream; import org.python.antlr.ParseException; import org.python.antlr.PythonGrammar; @@ -184,10 +185,15 @@ cs = new ANTLRReaderStream(bufreader); ExpressionParser e = new ExpressionParser(cs); node = e.parse(); + } else if (kind.equals("single")) { + bufreader = prepBufreader(istream, cflags); + cs = new ANTLRReaderStream(bufreader); + InteractiveParser i = new InteractiveParser(cs); + node = i.parse(); } else { bufreader = prepBufreader(istream, cflags); cs = new ANTLRReaderStream(bufreader); - PythonGrammar g = new PythonGrammar(cs);//FJW, literalMkrForParser); + PythonGrammar g = new PythonGrammar(cs); node = doparse(kind, cflags, g); } } @@ -200,40 +206,44 @@ public static modType partialParse(String string, String kind, String filename, CompilerFlags cflags,boolean stdprompt) { - modType node = null; - BufferedReader bufreader = prepBufreader(new ByteArrayInputStream(StringUtil.toBytes(string)), - cflags); - - CharStream cs = null; - try { - cs = new ANTLRReaderStream(bufreader); - } catch (IOException io){ - //FIXME: - System.err.println("FIXME: Don't eat exceptions."); - } - PythonGrammar g = new PythonGrammar(cs, true); - //FJW g.token_source.partial = true; - //FJW g.token_source.stdprompt = stdprompt; - - try { - node = doparse(kind, cflags, g); - } - catch (Throwable t) { - /* - CPython codeop exploits that with CPython parser adding newlines - to a partial valid sentence move the reported error position, - this is not true for our parser, so we need a different approach: - we check whether all sentence tokens have been consumed or - the remaining ones fullfill lookahead expectations. See: - PythonGrammar.partial_valid_sentence (def in python.jjt) - */ - - //FJW if (g.partial_valid_sentence(t)) { - //FJW return null; - //FJW } - throw fixParseError(bufreader, t, filename); - } - return node; +//FIXME: FJW -- just doing "parse" for now until I come up with a partial parse +// strategy for antlr. 3.1 is supposed to have some kind of direct +// support for incremental parsing -- hopefully that can be used. + return parse(new ByteArrayInputStream(StringUtil.toBytes(string)), kind, filename, cflags); +// modType node = null; +// BufferedReader bufreader = prepBufreader(new ByteArrayInputStream(StringUtil.toBytes(string)), +// cflags); +// +// CharStream cs = null; +// try { +// cs = new ANTLRReaderStream(bufreader); +// } catch (IOException io){ +// //FIXME: +// System.err.println("FIXME: Don't eat exceptions."); +// } +// PythonGrammar g = new PythonGrammar(cs, true); +// //FJW g.token_source.partial = true; +// //FJW g.token_source.stdprompt = stdprompt; +// +// try { +// node = doparse(kind, cflags, g); +// } +// catch (Throwable t) { +// /* +// CPython codeop exploits that with CPython parser adding newlines +// to a partial valid sentence move the reported error position, +// this is not true for our parser, so we need a different approach: +// we check whether all sentence tokens have been consumed or +// the remaining ones fullfill lookahead expectations. See: +// PythonGrammar.partial_valid_sentence (def in python.jjt) +// */ +// +// //FJW if (g.partial_valid_sentence(t)) { +// //FJW return null; +// //FJW } +// throw fixParseError(bufreader, t, filename); +// } +// return node; } private static modType doparse(String kind, CompilerFlags cflags, @@ -247,9 +257,6 @@ if (kind.equals("exec")) { node = g.file_input(); } - else if (kind.equals("single")) { - node = g.single_input(); - } else { throw Py.ValueError("parse kind must be eval, exec, " + "or single"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-27 23:37:55
|
Revision: 4465 http://jython.svn.sourceforge.net/jython/?rev=4465&view=rev Author: fwierzbicki Date: 2008-05-27 16:37:54 -0700 (Tue, 27 May 2008) Log Message: ----------- Merged revisions 4464 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4464 | fwierzbicki | 2008-05-27 19:31:15 -0400 (Tue, 27 May 2008) | 4 lines Very naive partial parsing in antlr grammar for interactive code and doctests. Also renamed symbol->kind in InteractiveInterpreter to be consistent with usage in parser code. ........ Modified Paths: -------------- branches/asm/grammar/Python.g branches/asm/src/org/python/antlr/InteractiveParser.java branches/asm/src/org/python/core/antlr.java branches/asm/src/org/python/util/InteractiveInterpreter.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4462 + /trunk/jython:1-4464 Modified: branches/asm/grammar/Python.g =================================================================== --- branches/asm/grammar/Python.g 2008-05-27 23:31:15 UTC (rev 4464) +++ branches/asm/grammar/Python.g 2008-05-27 23:37:54 UTC (rev 4465) @@ -289,9 +289,12 @@ } //single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE +//XXX: I don't know why, but in "compound_stmt NEWLINE" +// Jython chokes on the NEWLINE every time -- so I made +// it optional for now. single_input : NEWLINE | simple_stmt -> ^(Interactive simple_stmt) - | compound_stmt NEWLINE -> ^(Interactive compound_stmt) + | compound_stmt NEWLINE? -> ^(Interactive compound_stmt) ; //file_input: (NEWLINE | stmt)* ENDMARKER Modified: branches/asm/src/org/python/antlr/InteractiveParser.java =================================================================== --- branches/asm/src/org/python/antlr/InteractiveParser.java 2008-05-27 23:31:15 UTC (rev 4464) +++ branches/asm/src/org/python/antlr/InteractiveParser.java 2008-05-27 23:37:54 UTC (rev 4465) @@ -47,6 +47,27 @@ this.charStream = cs; } + public modType partialParse() { + /* + CPython codeop exploits that with CPython parser adding newlines + to a partial valid sentence move the reported error position, + this is not true for our parser, so we need a different approach: + we check whether all sentence tokens have been consumed or + the remaining ones fullfill lookahead expectations. See: + PythonGrammar.partial_valid_sentence (def in python.jjt) + + FJW: the above comment needs to be changed when the current partial + parse strategy gels. + */ + try { + return parse(); + } catch (RecognitionException e) { + //FIXME: This needs plenty of tuning, this just calls all errors + //partial matches. + return null; + } + } + public modType parse() throws RecognitionException { modType tree = null; PythonLexer lexer = new PyLexer(this.charStream); Modified: branches/asm/src/org/python/core/antlr.java =================================================================== --- branches/asm/src/org/python/core/antlr.java 2008-05-27 23:31:15 UTC (rev 4464) +++ branches/asm/src/org/python/core/antlr.java 2008-05-27 23:37:54 UTC (rev 4465) @@ -171,9 +171,10 @@ kind, "<string>", null); } - public static modType parse(InputStream istream, String kind, - String filename, CompilerFlags cflags) - { + public static modType parse(InputStream istream, + String kind, + String filename, + CompilerFlags cflags) { CharStream cs = null; //FIXME: definite NPE potential here -- do we even need prepBufreader // now? @@ -189,61 +190,46 @@ bufreader = prepBufreader(istream, cflags); cs = new ANTLRReaderStream(bufreader); InteractiveParser i = new InteractiveParser(cs); - node = i.parse(); - } else { + node = i.partialParse(); + } else if (kind.equals("exec")) { bufreader = prepBufreader(istream, cflags); cs = new ANTLRReaderStream(bufreader); PythonGrammar g = new PythonGrammar(cs); - node = doparse(kind, cflags, g); + node = g.file_input(); + } else { + throw Py.ValueError("parse kind must be eval, exec, " + "or single"); } - } - catch (Throwable t) { + } catch (Throwable t) { throw fixParseError(bufreader, t, filename); } return node; } - public static modType partialParse(String string, String kind, - String filename, CompilerFlags cflags,boolean stdprompt) - { -//FIXME: FJW -- just doing "parse" for now until I come up with a partial parse -// strategy for antlr. 3.1 is supposed to have some kind of direct -// support for incremental parsing -- hopefully that can be used. - return parse(new ByteArrayInputStream(StringUtil.toBytes(string)), kind, filename, cflags); -// modType node = null; -// BufferedReader bufreader = prepBufreader(new ByteArrayInputStream(StringUtil.toBytes(string)), -// cflags); -// -// CharStream cs = null; -// try { -// cs = new ANTLRReaderStream(bufreader); -// } catch (IOException io){ -// //FIXME: -// System.err.println("FIXME: Don't eat exceptions."); -// } -// PythonGrammar g = new PythonGrammar(cs, true); -// //FJW g.token_source.partial = true; -// //FJW g.token_source.stdprompt = stdprompt; -// -// try { -// node = doparse(kind, cflags, g); -// } -// catch (Throwable t) { -// /* -// CPython codeop exploits that with CPython parser adding newlines -// to a partial valid sentence move the reported error position, -// this is not true for our parser, so we need a different approach: -// we check whether all sentence tokens have been consumed or -// the remaining ones fullfill lookahead expectations. See: -// PythonGrammar.partial_valid_sentence (def in python.jjt) -// */ -// -// //FJW if (g.partial_valid_sentence(t)) { -// //FJW return null; -// //FJW } -// throw fixParseError(bufreader, t, filename); -// } -// return node; + public static modType partialParse(String string, + String kind, + String filename, + CompilerFlags cflags, + boolean stdprompt) { + CharStream cs = null; + //FIXME: definite NPE potential here -- do we even need prepBufreader + // now? + BufferedReader bufreader = null; + modType node = null; + if (kind.equals("single")) { + ByteArrayInputStream bi = new ByteArrayInputStream( + StringUtil.toBytes(string)); + bufreader = prepBufreader(bi, cflags); + try { + cs = new ANTLRReaderStream(bufreader); + } catch (IOException io) { + //FIXME: + } + InteractiveParser i = new InteractiveParser(cs); + node = i.partialParse(); + } else { + throw Py.ValueError("parse kind must be eval, exec, " + "or single"); + } + return node; } private static modType doparse(String kind, CompilerFlags cflags, @@ -254,13 +240,6 @@ //FJW if (cflags != null) //FJW g.token_source.generator_allowed = cflags.generator_allowed; - if (kind.equals("exec")) { - node = g.file_input(); - } - else { - throw Py.ValueError("parse kind must be eval, exec, " + - "or single"); - } return node; } Modified: branches/asm/src/org/python/util/InteractiveInterpreter.java =================================================================== --- branches/asm/src/org/python/util/InteractiveInterpreter.java 2008-05-27 23:31:15 UTC (rev 4464) +++ branches/asm/src/org/python/util/InteractiveInterpreter.java 2008-05-27 23:37:54 UTC (rev 4465) @@ -47,10 +47,10 @@ return runsource(source, filename, "single"); } - public boolean runsource(String source, String filename, String symbol) { + public boolean runsource(String source, String filename, String kind) { PyObject code; try { - code = Py.compile_command_flags(source, filename, symbol, cflags, true); + code = Py.compile_command_flags(source, filename, kind, cflags, true); } catch (PyException exc) { if (Py.matchException(exc, Py.SyntaxError)) { // Case 1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-28 02:05:20
|
Revision: 4466 http://jython.svn.sourceforge.net/jython/?rev=4466&view=rev Author: fwierzbicki Date: 2008-05-27 19:05:18 -0700 (Tue, 27 May 2008) Log Message: ----------- Now that things are close to working, time to completely destroy things again. Switched to pulling in 2.5 Python libraries. Took first baby step by attempting to support def f(): yield which is not valid 2.3 syntax. (This is actually what motivated this -- I was about to "fix" the grammar to disallow this when I accidentally noticed that it was valid 2.5 syntax. Modified Paths: -------------- branches/asm/src/org/python/compiler/CodeCompiler.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svn:externals - CPythonLib http://svn.python.org/projects/python/branches/release23-maint/Lib/ + CPythonLib http://svn.python.org/projects/python/branches/release25-maint/Lib/ Modified: branches/asm/src/org/python/compiler/CodeCompiler.java =================================================================== --- branches/asm/src/org/python/compiler/CodeCompiler.java 2008-05-27 23:37:54 UTC (rev 4465) +++ branches/asm/src/org/python/compiler/CodeCompiler.java 2008-05-28 02:05:18 UTC (rev 4466) @@ -40,8 +40,10 @@ import org.python.antlr.ast.ExtSlice; 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; @@ -66,7 +68,10 @@ import org.python.antlr.ast.UnaryOp; import org.python.antlr.ast.Unicode; import org.python.antlr.ast.While; +import org.python.antlr.ast.With; import org.python.antlr.ast.Yield; +import org.python.antlr.ast.aliasType; +import org.python.antlr.ast.argumentsType; import org.python.antlr.ast.cmpopType; import org.python.antlr.ast.comprehensionType; import org.python.antlr.ast.excepthandlerType; @@ -75,7 +80,9 @@ import org.python.antlr.ast.keywordType; import org.python.antlr.ast.modType; import org.python.antlr.ast.operatorType; +import org.python.antlr.ast.sliceType; import org.python.antlr.ast.stmtType; +import org.python.antlr.ast.unaryopType; public class CodeCompiler extends Visitor implements Opcodes, ClassConstants //, PythonGrammarTreeConstants { @@ -533,7 +540,11 @@ } saveLocals(); - visit(node.value); + if (node.value != null) { + visit(node.value); + } else { + getNone(); + } setLastI(++yield_count); code.areturn(); @@ -1926,6 +1937,11 @@ return null; } + public Object visitGeneratorExp(GeneratorExp node) { + //FIXME + return null; + } + protected Object unhandled_node(PythonTree node) throws Exception { throw new Exception("Unhandled node " + node); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-29 17:20:20
|
Revision: 4472 http://jython.svn.sourceforge.net/jython/?rev=4472&view=rev Author: fwierzbicki Date: 2008-05-29 10:20:16 -0700 (Thu, 29 May 2008) Log Message: ----------- Merged revisions 4467-4471 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4467 | pjenvey | 2008-05-28 18:40:27 -0400 (Wed, 28 May 2008) | 1 line small cleanup ........ r4468 | pjenvey | 2008-05-28 23:54:32 -0400 (Wed, 28 May 2008) | 6 lines fix test_socket's testConnectWithLocalBind locking up on subsequent test runs: Not even SO_REUSEADDR allows reuse of an exact socket 4-tuple (localhost, PORT - 1, localhost, PORT) stuck in TIME_WAIT (which happens after the first test run), so catch the EADDRINUSE raised in that situation, decrement the local PORT and try again ........ r4469 | pjenvey | 2008-05-29 01:29:20 -0400 (Thu, 29 May 2008) | 6 lines o revert _map_exception back to creating new socket.errors every time. they're mutable and unsafe as singletons o map java exceptions to python in socket.shutdown o handle all unmapped exceptions in one place and include the Java exception's message in the translated socket.error's msg ........ r4470 | pjenvey | 2008-05-29 02:16:26 -0400 (Thu, 29 May 2008) | 5 lines fix intermittent failures in testShutdown: the server occasionally tearsDown before the client finishes, causing a socket not connected error during client shutdown(). so block server tearDowns until clients are ready to tearDown ........ r4471 | fwierzbicki | 2008-05-29 13:16:32 -0400 (Thu, 29 May 2008) | 2 lines null checks for arrays in ast code. ........ Modified Paths: -------------- branches/asm/Lib/socket.py branches/asm/Lib/test/test_socket.py branches/asm/ast/asdl_antlr.py branches/asm/src/org/python/antlr/ast/Assign.java branches/asm/src/org/python/antlr/ast/BoolOp.java branches/asm/src/org/python/antlr/ast/Call.java branches/asm/src/org/python/antlr/ast/ClassDef.java branches/asm/src/org/python/antlr/ast/Compare.java branches/asm/src/org/python/antlr/ast/Delete.java branches/asm/src/org/python/antlr/ast/Dict.java branches/asm/src/org/python/antlr/ast/ExtSlice.java branches/asm/src/org/python/antlr/ast/For.java branches/asm/src/org/python/antlr/ast/FunctionDef.java branches/asm/src/org/python/antlr/ast/GeneratorExp.java branches/asm/src/org/python/antlr/ast/If.java branches/asm/src/org/python/antlr/ast/Import.java branches/asm/src/org/python/antlr/ast/ImportFrom.java branches/asm/src/org/python/antlr/ast/Interactive.java branches/asm/src/org/python/antlr/ast/List.java branches/asm/src/org/python/antlr/ast/ListComp.java branches/asm/src/org/python/antlr/ast/Module.java branches/asm/src/org/python/antlr/ast/Print.java branches/asm/src/org/python/antlr/ast/Suite.java branches/asm/src/org/python/antlr/ast/TryExcept.java branches/asm/src/org/python/antlr/ast/TryFinally.java branches/asm/src/org/python/antlr/ast/Tuple.java branches/asm/src/org/python/antlr/ast/While.java branches/asm/src/org/python/antlr/ast/With.java branches/asm/src/org/python/antlr/ast/argumentsType.java branches/asm/src/org/python/antlr/ast/comprehensionType.java branches/asm/src/org/python/antlr/ast/excepthandlerType.java branches/asm/src/org/python/core/PyClassMethod.java branches/asm/src/org/python/core/PyStaticMethod.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4464 + /trunk/jython:1-4471 Modified: branches/asm/Lib/socket.py =================================================================== --- branches/asm/Lib/socket.py 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/Lib/socket.py 2008-05-29 17:20:16 UTC (rev 4472) @@ -89,36 +89,36 @@ _exception_map = { -# (<javaexception>, <circumstance>) : lambda: <code that raises the python equivalent> +# (<javaexception>, <circumstance>) : lambda: <code that raises the python equivalent>, or None to stub out as unmapped -(java.io.IOException, ALL) : error(errno.ECONNRESET, 'Software caused connection abort'), -(java.io.InterruptedIOException, ALL) : timeout('timed out'), +(java.io.IOException, ALL) : lambda: error(errno.ECONNRESET, 'Software caused connection abort'), +(java.io.InterruptedIOException, ALL) : lambda: timeout('timed out'), -(java.net.BindException, ALL) : error(errno.EADDRINUSE, 'Address already in use'), -(java.net.ConnectException, ALL) : error(errno.ECONNREFUSED, 'Connection refused'), -(java.net.NoRouteToHostException, ALL) : error(-1, 'Unmapped exception: java.net.NoRouteToHostException'), -(java.net.PortUnreachableException, ALL) : error(-1, 'Unmapped exception: java.net.PortUnreachableException'), -(java.net.ProtocolException, ALL) : error(-1, 'Unmapped exception: java.net.ProtocolException'), -(java.net.SocketException, ALL) : error(-1, 'Unmapped exception: java.net.SocketException'), -(java.net.SocketTimeoutException, ALL) : timeout('timed out'), -(java.net.UnknownHostException, ALL) : gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'), +(java.net.BindException, ALL) : lambda: error(errno.EADDRINUSE, 'Address already in use'), +(java.net.ConnectException, ALL) : lambda: error(errno.ECONNREFUSED, 'Connection refused'), +(java.net.NoRouteToHostException, ALL) : None, +(java.net.PortUnreachableException, ALL) : None, +(java.net.ProtocolException, ALL) : None, +(java.net.SocketException, ALL) : None, +(java.net.SocketTimeoutException, ALL) : lambda: timeout('timed out'), +(java.net.UnknownHostException, ALL) : lambda: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'), -(java.nio.channels.AlreadyConnectedException, ALL) : error(errno.EISCONN, 'Socket is already connected'), -(java.nio.channels.AsynchronousCloseException, ALL) : error(-1, 'Unmapped exception: java.nio.AsynchronousCloseException'), -(java.nio.channels.CancelledKeyException, ALL) : error(-1, 'Unmapped exception: java.nio.CancelledKeyException'), -(java.nio.channels.ClosedByInterruptException, ALL) : error(-1, 'Unmapped exception: java.nio.ClosedByInterruptException'), -(java.nio.channels.ClosedChannelException, ALL) : error(errno.EPIPE, 'Socket closed'), -(java.nio.channels.ClosedSelectorException, ALL) : error(-1, 'Unmapped exception: java.nio.ClosedSelectorException'), -(java.nio.channels.ConnectionPendingException, ALL) : error(-1, 'Unmapped exception: java.nio.ConnectionPendingException'), -(java.nio.channels.IllegalBlockingModeException, ALL) : error(-1, 'Unmapped exception: java.nio.IllegalBlockingModeException'), -(java.nio.channels.IllegalSelectorException, ALL) : error(-1, 'Unmapped exception: java.nio.IllegalSelectorException'), -(java.nio.channels.NoConnectionPendingException, ALL) : error(-1, 'Unmapped exception: java.nio.NoConnectionPendingException'), -(java.nio.channels.NonReadableChannelException, ALL) : error(-1, 'Unmapped exception: java.nio.NonReadableChannelException'), -(java.nio.channels.NonWritableChannelException, ALL) : error(-1, 'Unmapped exception: java.nio.NonWritableChannelException'), -(java.nio.channels.NotYetBoundException, ALL) : error(-1, 'Unmapped exception: java.nio.NotYetBoundException'), -(java.nio.channels.NotYetConnectedException, ALL) : error(-1, 'Unmapped exception: java.nio.NotYetConnectedException'), -(java.nio.channels.UnresolvedAddressException, ALL) : gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'), -(java.nio.channels.UnsupportedAddressTypeException, ALL) : error(-1, 'Unmapped exception: java.nio.UnsupportedAddressTypeException'), +(java.nio.channels.AlreadyConnectedException, ALL) : lambda: error(errno.EISCONN, 'Socket is already connected'), +(java.nio.channels.AsynchronousCloseException, ALL) : None, +(java.nio.channels.CancelledKeyException, ALL) : None, +(java.nio.channels.ClosedByInterruptException, ALL) : None, +(java.nio.channels.ClosedChannelException, ALL) : lambda: error(errno.EPIPE, 'Socket closed'), +(java.nio.channels.ClosedSelectorException, ALL) : None, +(java.nio.channels.ConnectionPendingException, ALL) : None, +(java.nio.channels.IllegalBlockingModeException, ALL) : None, +(java.nio.channels.IllegalSelectorException, ALL) : None, +(java.nio.channels.NoConnectionPendingException, ALL) : None, +(java.nio.channels.NonReadableChannelException, ALL) : None, +(java.nio.channels.NonWritableChannelException, ALL) : None, +(java.nio.channels.NotYetBoundException, ALL) : None, +(java.nio.channels.NotYetConnectedException, ALL) : None, +(java.nio.channels.UnresolvedAddressException, ALL) : lambda: gaierror(errno.EGETADDRINFOFAILED, 'getaddrinfo failed'), +(java.nio.channels.UnsupportedAddressTypeException, ALL) : None, } @@ -127,12 +127,13 @@ def _map_exception(exc, circumstance=ALL): # print "Mapping exception: %s" % exc - try: - mapped_exception = _exception_map[(exc.__class__, circumstance)] - mapped_exception.java_exception = exc - return mapped_exception - except KeyError: - return error(-1, 'Unmapped java exception: <%s:%s>' % (exc.toString(), circumstance)) + mapped_exception = _exception_map.get((exc.__class__, circumstance)) + if mapped_exception: + exception = mapped_exception() + else: + exception = error(-1, 'Unmapped exception: %s' % exc) + exception.java_exception = exc + return exception MODE_BLOCKING = 'block' MODE_NONBLOCKING = 'nonblock' @@ -202,10 +203,16 @@ # close = close4 def shutdownInput(self): - self.jsocket.shutdownInput() + try: + self.jsocket.shutdownInput() + except java.lang.Exception, jlx: + raise _map_exception(jlx) def shutdownOutput(self): - self.jsocket.shutdownOutput() + try: + self.jsocket.shutdownOutput() + except java.lang.Exception, jlx: + raise _map_exception(jlx) def getchannel(self): return self.jchannel Modified: branches/asm/Lib/test/test_socket.py =================================================================== --- branches/asm/Lib/test/test_socket.py 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/Lib/test/test_socket.py 2008-05-29 17:20:16 UTC (rev 4472) @@ -123,8 +123,8 @@ self.client_ready.wait() def _tearDown(self): + self.done.wait() self.__tearDown() - self.done.wait() if not self.queue.empty(): msg = self.queue.get() @@ -766,11 +766,27 @@ def _testConnectWithLocalBind(self): # Testing blocking connect with local bind - self.cli.settimeout(1) - self.cli.bind( (HOST, PORT-1) ) - self.cli.connect((HOST, PORT)) + cli_port = PORT - 1 + while True: + # Keep trying until a local port is available + self.cli.settimeout(1) + self.cli.bind( (HOST, cli_port) ) + try: + self.cli.connect((HOST, PORT)) + break + except socket.error, se: + # cli_port is in use (maybe in TIME_WAIT state from a + # previous test run). reset the client socket and try + # again + self.failUnlessEqual(se[0], errno.EADDRINUSE) + try: + self.cli.close() + except socket.error: + pass + self.clientSetUp() + cli_port -= 1 bound_host, bound_port = self.cli.getsockname() - self.failUnlessEqual(bound_port, PORT-1) + self.failUnlessEqual(bound_port, cli_port) def testRecvData(self): # Testing non-blocking recv Modified: branches/asm/ast/asdl_antlr.py =================================================================== --- branches/asm/ast/asdl_antlr.py 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/ast/asdl_antlr.py 2008-05-29 17:20:16 UTC (rev 4472) @@ -247,8 +247,10 @@ not_simple = False #For now ignoring String -- will want to revisit if f.seq and not_simple and not fparg.startswith("String"): - self.emit("for(int i%(name)s=0;i%(name)s<%(name)s.length;i%(name)s++) {" % {"name":f.name}, depth+1) - self.emit("addChild(%s[i%s]);" % (f.name, f.name), depth+2) + self.emit("if (%s != null) {" % f.name, depth+1); + self.emit("for(int i%(name)s=0;i%(name)s<%(name)s.length;i%(name)s++) {" % {"name":f.name}, depth+2) + self.emit("addChild(%s[i%s]);" % (f.name, f.name), depth+3) + self.emit("}", depth+2) self.emit("}", depth+1) def javaMethods(self, type, clsname, ctorname, fields, depth): Modified: branches/asm/src/org/python/antlr/ast/Assign.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Assign.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Assign.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -14,8 +14,10 @@ public Assign(PythonTree tree, exprType[] targets, exprType value) { super(tree); this.targets = targets; - for(int itargets=0;itargets<targets.length;itargets++) { - addChild(targets[itargets]); + if (targets != null) { + for(int itargets=0;itargets<targets.length;itargets++) { + addChild(targets[itargets]); + } } this.value = value; } Modified: branches/asm/src/org/python/antlr/ast/BoolOp.java =================================================================== --- branches/asm/src/org/python/antlr/ast/BoolOp.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/BoolOp.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -15,8 +15,10 @@ super(tree); this.op = op; this.values = values; - for(int ivalues=0;ivalues<values.length;ivalues++) { - addChild(values[ivalues]); + if (values != null) { + for(int ivalues=0;ivalues<values.length;ivalues++) { + addChild(values[ivalues]); + } } } Modified: branches/asm/src/org/python/antlr/ast/Call.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Call.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Call.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -20,12 +20,16 @@ super(tree); this.func = func; this.args = args; - for(int iargs=0;iargs<args.length;iargs++) { - addChild(args[iargs]); + if (args != null) { + for(int iargs=0;iargs<args.length;iargs++) { + addChild(args[iargs]); + } } this.keywords = keywords; - for(int ikeywords=0;ikeywords<keywords.length;ikeywords++) { - addChild(keywords[ikeywords]); + if (keywords != null) { + for(int ikeywords=0;ikeywords<keywords.length;ikeywords++) { + addChild(keywords[ikeywords]); + } } this.starargs = starargs; this.kwargs = kwargs; Modified: branches/asm/src/org/python/antlr/ast/ClassDef.java =================================================================== --- branches/asm/src/org/python/antlr/ast/ClassDef.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/ClassDef.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -17,12 +17,16 @@ super(tree); this.name = name; this.bases = bases; - for(int ibases=0;ibases<bases.length;ibases++) { - addChild(bases[ibases]); + if (bases != null) { + for(int ibases=0;ibases<bases.length;ibases++) { + addChild(bases[ibases]); + } } this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } } Modified: branches/asm/src/org/python/antlr/ast/Compare.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Compare.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Compare.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -19,8 +19,11 @@ this.left = left; this.ops = ops; this.comparators = comparators; - for(int icomparators=0;icomparators<comparators.length;icomparators++) { - addChild(comparators[icomparators]); + if (comparators != null) { + for(int + icomparators=0;icomparators<comparators.length;icomparators++) { + addChild(comparators[icomparators]); + } } } Modified: branches/asm/src/org/python/antlr/ast/Delete.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Delete.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Delete.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -13,8 +13,10 @@ public Delete(PythonTree tree, exprType[] targets) { super(tree); this.targets = targets; - for(int itargets=0;itargets<targets.length;itargets++) { - addChild(targets[itargets]); + if (targets != null) { + for(int itargets=0;itargets<targets.length;itargets++) { + addChild(targets[itargets]); + } } } Modified: branches/asm/src/org/python/antlr/ast/Dict.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Dict.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Dict.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -14,12 +14,16 @@ public Dict(PythonTree tree, exprType[] keys, exprType[] values) { super(tree); this.keys = keys; - for(int ikeys=0;ikeys<keys.length;ikeys++) { - addChild(keys[ikeys]); + if (keys != null) { + for(int ikeys=0;ikeys<keys.length;ikeys++) { + addChild(keys[ikeys]); + } } this.values = values; - for(int ivalues=0;ivalues<values.length;ivalues++) { - addChild(values[ivalues]); + if (values != null) { + for(int ivalues=0;ivalues<values.length;ivalues++) { + addChild(values[ivalues]); + } } } Modified: branches/asm/src/org/python/antlr/ast/ExtSlice.java =================================================================== --- branches/asm/src/org/python/antlr/ast/ExtSlice.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/ExtSlice.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -13,8 +13,10 @@ public ExtSlice(PythonTree tree, sliceType[] dims) { super(tree); this.dims = dims; - for(int idims=0;idims<dims.length;idims++) { - addChild(dims[idims]); + if (dims != null) { + for(int idims=0;idims<dims.length;idims++) { + addChild(dims[idims]); + } } } Modified: branches/asm/src/org/python/antlr/ast/For.java =================================================================== --- branches/asm/src/org/python/antlr/ast/For.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/For.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -20,12 +20,16 @@ this.target = target; this.iter = iter; this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } this.orelse = orelse; - for(int iorelse=0;iorelse<orelse.length;iorelse++) { - addChild(orelse[iorelse]); + if (orelse != null) { + for(int iorelse=0;iorelse<orelse.length;iorelse++) { + addChild(orelse[iorelse]); + } } } Modified: branches/asm/src/org/python/antlr/ast/FunctionDef.java =================================================================== --- branches/asm/src/org/python/antlr/ast/FunctionDef.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/FunctionDef.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -11,8 +11,6 @@ public stmtType[] body; public exprType[] decorators; - public String __name__ = "BAH"; - public static final String[] _fields = new String[] {"name","args","body","decorators"}; @@ -22,12 +20,16 @@ this.name = name; this.args = args; this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } this.decorators = decorators; - for(int idecorators=0;idecorators<decorators.length;idecorators++) { - addChild(decorators[idecorators]); + if (decorators != null) { + for(int idecorators=0;idecorators<decorators.length;idecorators++) { + addChild(decorators[idecorators]); + } } } Modified: branches/asm/src/org/python/antlr/ast/GeneratorExp.java =================================================================== --- branches/asm/src/org/python/antlr/ast/GeneratorExp.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/GeneratorExp.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -16,8 +16,10 @@ super(tree); this.elt = elt; this.generators = generators; - for(int igenerators=0;igenerators<generators.length;igenerators++) { - addChild(generators[igenerators]); + if (generators != null) { + for(int igenerators=0;igenerators<generators.length;igenerators++) { + addChild(generators[igenerators]); + } } } Modified: branches/asm/src/org/python/antlr/ast/If.java =================================================================== --- branches/asm/src/org/python/antlr/ast/If.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/If.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -18,12 +18,16 @@ super(tree); this.test = test; this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } this.orelse = orelse; - for(int iorelse=0;iorelse<orelse.length;iorelse++) { - addChild(orelse[iorelse]); + if (orelse != null) { + for(int iorelse=0;iorelse<orelse.length;iorelse++) { + addChild(orelse[iorelse]); + } } } Modified: branches/asm/src/org/python/antlr/ast/Import.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Import.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Import.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -13,8 +13,10 @@ public Import(PythonTree tree, aliasType[] names) { super(tree); this.names = names; - for(int inames=0;inames<names.length;inames++) { - addChild(names[inames]); + if (names != null) { + for(int inames=0;inames<names.length;inames++) { + addChild(names[inames]); + } } } Modified: branches/asm/src/org/python/antlr/ast/ImportFrom.java =================================================================== --- branches/asm/src/org/python/antlr/ast/ImportFrom.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/ImportFrom.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -18,8 +18,10 @@ super(tree); this.module = module; this.names = names; - for(int inames=0;inames<names.length;inames++) { - addChild(names[inames]); + if (names != null) { + for(int inames=0;inames<names.length;inames++) { + addChild(names[inames]); + } } this.level = level; } Modified: branches/asm/src/org/python/antlr/ast/Interactive.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Interactive.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Interactive.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -13,8 +13,10 @@ public Interactive(PythonTree tree, stmtType[] body) { super(tree); this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } } Modified: branches/asm/src/org/python/antlr/ast/List.java =================================================================== --- branches/asm/src/org/python/antlr/ast/List.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/List.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -14,8 +14,10 @@ public List(PythonTree tree, exprType[] elts, expr_contextType ctx) { super(tree); this.elts = elts; - for(int ielts=0;ielts<elts.length;ielts++) { - addChild(elts[ielts]); + if (elts != null) { + for(int ielts=0;ielts<elts.length;ielts++) { + addChild(elts[ielts]); + } } this.ctx = ctx; } Modified: branches/asm/src/org/python/antlr/ast/ListComp.java =================================================================== --- branches/asm/src/org/python/antlr/ast/ListComp.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/ListComp.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -16,8 +16,10 @@ super(tree); this.elt = elt; this.generators = generators; - for(int igenerators=0;igenerators<generators.length;igenerators++) { - addChild(generators[igenerators]); + if (generators != null) { + for(int igenerators=0;igenerators<generators.length;igenerators++) { + addChild(generators[igenerators]); + } } } Modified: branches/asm/src/org/python/antlr/ast/Module.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Module.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Module.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -13,8 +13,10 @@ public Module(PythonTree tree, stmtType[] body) { super(tree); this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } } Modified: branches/asm/src/org/python/antlr/ast/Print.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Print.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Print.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -17,8 +17,10 @@ super(tree); this.dest = dest; this.values = values; - for(int ivalues=0;ivalues<values.length;ivalues++) { - addChild(values[ivalues]); + if (values != null) { + for(int ivalues=0;ivalues<values.length;ivalues++) { + addChild(values[ivalues]); + } } this.nl = nl; } Modified: branches/asm/src/org/python/antlr/ast/Suite.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Suite.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Suite.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -13,8 +13,10 @@ public Suite(PythonTree tree, stmtType[] body) { super(tree); this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } } Modified: branches/asm/src/org/python/antlr/ast/TryExcept.java =================================================================== --- branches/asm/src/org/python/antlr/ast/TryExcept.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/TryExcept.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -17,16 +17,22 @@ handlers, stmtType[] orelse) { super(tree); this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } this.handlers = handlers; - for(int ihandlers=0;ihandlers<handlers.length;ihandlers++) { - addChild(handlers[ihandlers]); + if (handlers != null) { + for(int ihandlers=0;ihandlers<handlers.length;ihandlers++) { + addChild(handlers[ihandlers]); + } } this.orelse = orelse; - for(int iorelse=0;iorelse<orelse.length;iorelse++) { - addChild(orelse[iorelse]); + if (orelse != null) { + for(int iorelse=0;iorelse<orelse.length;iorelse++) { + addChild(orelse[iorelse]); + } } } Modified: branches/asm/src/org/python/antlr/ast/TryFinally.java =================================================================== --- branches/asm/src/org/python/antlr/ast/TryFinally.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/TryFinally.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -14,12 +14,16 @@ public TryFinally(PythonTree tree, stmtType[] body, stmtType[] finalbody) { super(tree); this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } this.finalbody = finalbody; - for(int ifinalbody=0;ifinalbody<finalbody.length;ifinalbody++) { - addChild(finalbody[ifinalbody]); + if (finalbody != null) { + for(int ifinalbody=0;ifinalbody<finalbody.length;ifinalbody++) { + addChild(finalbody[ifinalbody]); + } } } Modified: branches/asm/src/org/python/antlr/ast/Tuple.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Tuple.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/Tuple.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -14,8 +14,10 @@ public Tuple(PythonTree tree, exprType[] elts, expr_contextType ctx) { super(tree); this.elts = elts; - for(int ielts=0;ielts<elts.length;ielts++) { - addChild(elts[ielts]); + if (elts != null) { + for(int ielts=0;ielts<elts.length;ielts++) { + addChild(elts[ielts]); + } } this.ctx = ctx; } Modified: branches/asm/src/org/python/antlr/ast/While.java =================================================================== --- branches/asm/src/org/python/antlr/ast/While.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/While.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -18,12 +18,16 @@ super(tree); this.test = test; this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } this.orelse = orelse; - for(int iorelse=0;iorelse<orelse.length;iorelse++) { - addChild(orelse[iorelse]); + if (orelse != null) { + for(int iorelse=0;iorelse<orelse.length;iorelse++) { + addChild(orelse[iorelse]); + } } } Modified: branches/asm/src/org/python/antlr/ast/With.java =================================================================== --- branches/asm/src/org/python/antlr/ast/With.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/With.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -19,8 +19,10 @@ this.context_expr = context_expr; this.optional_vars = optional_vars; this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } } Modified: branches/asm/src/org/python/antlr/ast/argumentsType.java =================================================================== --- branches/asm/src/org/python/antlr/ast/argumentsType.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/argumentsType.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -18,14 +18,18 @@ String kwarg, exprType[] defaults) { super(tree); this.args = args; - for(int iargs=0;iargs<args.length;iargs++) { - addChild(args[iargs]); + if (args != null) { + for(int iargs=0;iargs<args.length;iargs++) { + addChild(args[iargs]); + } } this.vararg = vararg; this.kwarg = kwarg; this.defaults = defaults; - for(int idefaults=0;idefaults<defaults.length;idefaults++) { - addChild(defaults[idefaults]); + if (defaults != null) { + for(int idefaults=0;idefaults<defaults.length;idefaults++) { + addChild(defaults[idefaults]); + } } } Modified: branches/asm/src/org/python/antlr/ast/comprehensionType.java =================================================================== --- branches/asm/src/org/python/antlr/ast/comprehensionType.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/comprehensionType.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -18,8 +18,10 @@ this.target = target; this.iter = iter; this.ifs = ifs; - for(int iifs=0;iifs<ifs.length;iifs++) { - addChild(ifs[iifs]); + if (ifs != null) { + for(int iifs=0;iifs<ifs.length;iifs++) { + addChild(ifs[iifs]); + } } } Modified: branches/asm/src/org/python/antlr/ast/excepthandlerType.java =================================================================== --- branches/asm/src/org/python/antlr/ast/excepthandlerType.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/antlr/ast/excepthandlerType.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -21,8 +21,10 @@ this.type = type; this.name = name; this.body = body; - for(int ibody=0;ibody<body.length;ibody++) { - addChild(body[ibody]); + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } } this.lineno = lineno; this.col_offset = col_offset; Modified: branches/asm/src/org/python/core/PyClassMethod.java =================================================================== --- branches/asm/src/org/python/core/PyClassMethod.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/core/PyClassMethod.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -4,20 +4,35 @@ import org.python.expose.ExposedNew; import org.python.expose.ExposedType; +/** + * The classmethod descriptor. + */ @ExposedType(name = "classmethod") public class PyClassMethod extends PyObject { - + public static final PyType TYPE = PyType.fromClass(PyClassMethod.class); protected PyObject callable; - + public PyClassMethod(PyObject callable) { - if (!callable.isCallable()) { + if (!callable.isCallable()) { throw Py.TypeError("'" + callable.getType().fastGetName() + "' object is not callable"); } this.callable = callable; } + @ExposedNew + final static PyObject classmethod_new(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { + if (keywords.length != 0) { + throw Py.TypeError("classmethod does not accept keyword arguments"); + } + if (args.length != 1) { + throw Py.TypeError("classmethod expected 1 argument, got " + args.length); + } + return new PyClassMethod(args[0]); + } + public PyObject __get__(PyObject obj) { return classmethod___get__(obj, null); } @@ -25,7 +40,7 @@ public PyObject __get__(PyObject obj, PyObject type) { return classmethod___get__(obj, type); } - + @ExposedMethod(defaults = "null") final PyObject classmethod___get__(PyObject obj, PyObject type) { if(type == null) { @@ -33,19 +48,4 @@ } return new PyMethod(callable, type, type.getType()); } - - @ExposedNew - final static PyObject classmethod_new(PyNewWrapper new_, - boolean init, - PyType subtype, - PyObject[] args, - String[] keywords) { - if (keywords.length != 0) { - throw Py.TypeError("classmethod does not accept keyword arguments"); - } - if (args.length != 1) { - throw Py.TypeError("classmethod expected 1 argument, got " + args.length); - } - return new PyClassMethod(args[0]); - } } Modified: branches/asm/src/org/python/core/PyStaticMethod.java =================================================================== --- branches/asm/src/org/python/core/PyStaticMethod.java 2008-05-29 17:16:32 UTC (rev 4471) +++ branches/asm/src/org/python/core/PyStaticMethod.java 2008-05-29 17:20:16 UTC (rev 4472) @@ -4,17 +4,23 @@ import org.python.expose.ExposedNew; import org.python.expose.ExposedType; +/** + * The staticmethod descriptor. + */ @ExposedType(name = "staticmethod") public class PyStaticMethod extends PyObject { public static final PyType TYPE = PyType.fromClass(PyStaticMethod.class); + protected PyObject callable; + + public PyStaticMethod(PyObject callable) { + this.callable = callable; + } + @ExposedNew - final static PyObject staticmethod_new(PyNewWrapper new_, - boolean init, - PyType subtype, - PyObject[] args, - String[] keywords) { + final static PyObject staticmethod_new(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { if (keywords.length != 0) { throw Py.TypeError("staticmethod does not accept keyword arguments"); } @@ -24,18 +30,12 @@ return new PyStaticMethod(args[0]); } + public PyObject __get__(PyObject obj, PyObject type) { + return staticmethod___get__(obj, type); + } + @ExposedMethod(defaults = "null") final PyObject staticmethod___get__(PyObject obj, PyObject type) { return callable; } - - protected PyObject callable; - - public PyStaticMethod(PyObject callable) { - this.callable = callable; - } - - public PyObject __get__(PyObject obj, PyObject type) { - return staticmethod___get__(obj, type); - } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-30 03:28:43
|
Revision: 4487 http://jython.svn.sourceforge.net/jython/?rev=4487&view=rev Author: fwierzbicki Date: 2008-05-29 20:28:32 -0700 (Thu, 29 May 2008) Log Message: ----------- Merged revisions 4473,4475-4486 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4473 | pjenvey | 2008-05-29 15:24:41 -0400 (Thu, 29 May 2008) | 1 line don't consider tests skipped due to ResourceDenied as unexpected ........ r4475 | pjenvey | 2008-05-29 17:37:07 -0400 (Thu, 29 May 2008) | 6 lines fix intermittent failures in test_select_new: o allow socket.connect_ex to be called multiple times o since we're using connect_ex for an asynchronous connects, don't assume it's immediately ready in finish_connect o same idea for server accept: don't assume it's immediately acceptable ........ r4476 | pjenvey | 2008-05-29 18:39:00 -0400 (Thu, 29 May 2008) | 1 line revert part of r4409: Java 6 disallows the exposed method access to the private base ........ r4477 | pjenvey | 2008-05-29 18:51:31 -0400 (Thu, 29 May 2008) | 1 line use String.format ........ r4478 | pjenvey | 2008-05-29 18:52:21 -0400 (Thu, 29 May 2008) | 1 line be more efficient with memory in the generic readall ........ r4479 | pjenvey | 2008-05-29 18:56:22 -0400 (Thu, 29 May 2008) | 1 line expect test_ast to fail for now, until we actually include antlr-runtime ........ r4480 | pjenvey | 2008-05-29 20:34:42 -0400 (Thu, 29 May 2008) | 3 lines UserString.py from http://svn.python.org/projects/python/branches/release25-maint/Lib/UserString.py@46876 ........ r4481 | pjenvey | 2008-05-29 20:35:40 -0400 (Thu, 29 May 2008) | 4 lines add str/unicode partition/rpartition fixes #1796272, 1797751 thanks ukeshav ........ r4482 | nriley | 2008-05-29 22:47:57 -0400 (Thu, 29 May 2008) | 1 line clean up start script, add test script, tested on Mac OS X/Linux/Solaris/Cygwin ........ r4483 | nriley | 2008-05-29 22:52:24 -0400 (Thu, 29 May 2008) | 1 line remove debugging, interferes with help ........ r4484 | nriley | 2008-05-29 22:56:23 -0400 (Thu, 29 May 2008) | 1 line fix help sort order ........ r4485 | fwierzbicki | 2008-05-29 23:13:31 -0400 (Thu, 29 May 2008) | 2 lines Added line numbers and column to ast display. ........ r4486 | fwierzbicki | 2008-05-29 23:21:14 -0400 (Thu, 29 May 2008) | 2 lines Fix lineno/col for yield. ........ Modified Paths: -------------- branches/asm/Lib/socket.py branches/asm/Lib/test/regrtest.py branches/asm/Lib/test/string_tests.py branches/asm/Lib/test/test_select_new.py branches/asm/Lib/test/test_set.py branches/asm/ast/astview.py branches/asm/grammar/Python.g branches/asm/grammar/PythonWalker.g branches/asm/src/org/python/core/PyString.java branches/asm/src/org/python/core/PyType.java branches/asm/src/org/python/core/PyUnicode.java branches/asm/src/org/python/core/io/IOBase.java branches/asm/src/org/python/core/io/RawIOBase.java branches/asm/src/shell/jython Added Paths: ----------- branches/asm/Lib/UserString.py branches/asm/tests/shell/ branches/asm/tests/shell/test-jython.sh Removed Paths: ------------- branches/asm/tests/shell/test-jython.sh Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4471 + /trunk/jython:1-4486 Copied: branches/asm/Lib/UserString.py (from rev 4486, trunk/jython/Lib/UserString.py) =================================================================== --- branches/asm/Lib/UserString.py (rev 0) +++ branches/asm/Lib/UserString.py 2008-05-30 03:28:32 UTC (rev 4487) @@ -0,0 +1,194 @@ +#!/usr/bin/env python +## vim:ts=4:et:nowrap +"""A user-defined wrapper around string objects + +Note: string objects have grown methods in Python 1.6 +This module requires Python 1.6 or later. +""" +import sys + +__all__ = ["UserString","MutableString"] + +class UserString: + def __init__(self, seq): + if isinstance(seq, basestring): + self.data = seq + elif isinstance(seq, UserString): + self.data = seq.data[:] + else: + self.data = str(seq) + def __str__(self): return str(self.data) + def __repr__(self): return repr(self.data) + def __int__(self): return int(self.data) + def __long__(self): return long(self.data) + def __float__(self): return float(self.data) + def __complex__(self): return complex(self.data) + def __hash__(self): return hash(self.data) + + def __cmp__(self, string): + if isinstance(string, UserString): + return cmp(self.data, string.data) + else: + return cmp(self.data, string) + def __contains__(self, char): + return char in self.data + + def __len__(self): return len(self.data) + def __getitem__(self, index): return self.__class__(self.data[index]) + def __getslice__(self, start, end): + start = max(start, 0); end = max(end, 0) + return self.__class__(self.data[start:end]) + + def __add__(self, other): + if isinstance(other, UserString): + return self.__class__(self.data + other.data) + elif isinstance(other, basestring): + return self.__class__(self.data + other) + else: + return self.__class__(self.data + str(other)) + def __radd__(self, other): + if isinstance(other, basestring): + return self.__class__(other + self.data) + else: + return self.__class__(str(other) + self.data) + def __mul__(self, n): + return self.__class__(self.data*n) + __rmul__ = __mul__ + def __mod__(self, args): + return self.__class__(self.data % args) + + # the following methods are defined in alphabetical order: + def capitalize(self): return self.__class__(self.data.capitalize()) + def center(self, width, *args): + return self.__class__(self.data.center(width, *args)) + def count(self, sub, start=0, end=sys.maxint): + return self.data.count(sub, start, end) + def decode(self, encoding=None, errors=None): # XXX improve this? + if encoding: + if errors: + return self.__class__(self.data.decode(encoding, errors)) + else: + return self.__class__(self.data.decode(encoding)) + else: + return self.__class__(self.data.decode()) + def encode(self, encoding=None, errors=None): # XXX improve this? + if encoding: + if errors: + return self.__class__(self.data.encode(encoding, errors)) + else: + return self.__class__(self.data.encode(encoding)) + else: + return self.__class__(self.data.encode()) + def endswith(self, suffix, start=0, end=sys.maxint): + return self.data.endswith(suffix, start, end) + def expandtabs(self, tabsize=8): + return self.__class__(self.data.expandtabs(tabsize)) + def find(self, sub, start=0, end=sys.maxint): + return self.data.find(sub, start, end) + def index(self, sub, start=0, end=sys.maxint): + return self.data.index(sub, start, end) + def isalpha(self): return self.data.isalpha() + def isalnum(self): return self.data.isalnum() + def isdecimal(self): return self.data.isdecimal() + def isdigit(self): return self.data.isdigit() + def islower(self): return self.data.islower() + def isnumeric(self): return self.data.isnumeric() + def isspace(self): return self.data.isspace() + def istitle(self): return self.data.istitle() + def isupper(self): return self.data.isupper() + def join(self, seq): return self.data.join(seq) + def ljust(self, width, *args): + return self.__class__(self.data.ljust(width, *args)) + def lower(self): return self.__class__(self.data.lower()) + def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars)) + def partition(self, sep): + return self.data.partition(sep) + def replace(self, old, new, maxsplit=-1): + return self.__class__(self.data.replace(old, new, maxsplit)) + def rfind(self, sub, start=0, end=sys.maxint): + return self.data.rfind(sub, start, end) + def rindex(self, sub, start=0, end=sys.maxint): + return self.data.rindex(sub, start, end) + def rjust(self, width, *args): + return self.__class__(self.data.rjust(width, *args)) + def rpartition(self, sep): + return self.data.rpartition(sep) + def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars)) + def split(self, sep=None, maxsplit=-1): + return self.data.split(sep, maxsplit) + def rsplit(self, sep=None, maxsplit=-1): + return self.data.rsplit(sep, maxsplit) + def splitlines(self, keepends=0): return self.data.splitlines(keepends) + def startswith(self, prefix, start=0, end=sys.maxint): + return self.data.startswith(prefix, start, end) + def strip(self, chars=None): return self.__class__(self.data.strip(chars)) + def swapcase(self): return self.__class__(self.data.swapcase()) + def title(self): return self.__class__(self.data.title()) + def translate(self, *args): + return self.__class__(self.data.translate(*args)) + def upper(self): return self.__class__(self.data.upper()) + def zfill(self, width): return self.__class__(self.data.zfill(width)) + +class MutableString(UserString): + """mutable string objects + + Python strings are immutable objects. This has the advantage, that + strings may be used as dictionary keys. If this property isn't needed + and you insist on changing string values in place instead, you may cheat + and use MutableString. + + But the purpose of this class is an educational one: to prevent + people from inventing their own mutable string class derived + from UserString and than forget thereby to remove (override) the + __hash__ method inherited from UserString. This would lead to + errors that would be very hard to track down. + + A faster and better solution is to rewrite your program using lists.""" + def __init__(self, string=""): + self.data = string + def __hash__(self): + raise TypeError, "unhashable type (it is mutable)" + def __setitem__(self, index, sub): + if index < 0: + index += len(self.data) + if index < 0 or index >= len(self.data): raise IndexError + self.data = self.data[:index] + sub + self.data[index+1:] + def __delitem__(self, index): + if index < 0: + index += len(self.data) + if index < 0 or index >= len(self.data): raise IndexError + self.data = self.data[:index] + self.data[index+1:] + def __setslice__(self, start, end, sub): + start = max(start, 0); end = max(end, 0) + if isinstance(sub, UserString): + self.data = self.data[:start]+sub.data+self.data[end:] + elif isinstance(sub, basestring): + self.data = self.data[:start]+sub+self.data[end:] + else: + self.data = self.data[:start]+str(sub)+self.data[end:] + def __delslice__(self, start, end): + start = max(start, 0); end = max(end, 0) + self.data = self.data[:start] + self.data[end:] + def immutable(self): + return UserString(self.data) + def __iadd__(self, other): + if isinstance(other, UserString): + self.data += other.data + elif isinstance(other, basestring): + self.data += other + else: + self.data += str(other) + return self + def __imul__(self, n): + self.data *= n + return self + +if __name__ == "__main__": + # execute the regression test to stdout, if called as a script: + import os + called_in_dir, called_as = os.path.split(sys.argv[0]) + called_as, py = os.path.splitext(called_as) + if '-q' in sys.argv: + from test import test_support + test_support.verbose = 0 + __import__('test.test_' + called_as.lower()) Modified: branches/asm/Lib/socket.py =================================================================== --- branches/asm/Lib/socket.py 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/Lib/socket.py 2008-05-30 03:28:32 UTC (rev 4487) @@ -624,7 +624,8 @@ def connect_ex(self, addr): "This signifies a client socket" - self._do_connect(addr) + if not self.sock_impl: + self._do_connect(addr) if self.sock_impl.finish_connect(): self._setup() return 0 Modified: branches/asm/Lib/test/regrtest.py =================================================================== --- branches/asm/Lib/test/regrtest.py 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/Lib/test/regrtest.py 2008-05-30 03:28:32 UTC (rev 4487) @@ -293,6 +293,7 @@ good = [] bad = [] skipped = [] + resource_denieds = [] if findleaks: try: @@ -367,6 +368,8 @@ bad.append(test) else: skipped.append(test) + if ok == -2: + resource_denieds.append(test) if findleaks: gc.collect() if gc.garbage: @@ -397,10 +400,10 @@ surprises = 0 if skipped and not quiet: print count(len(skipped), "test"), "skipped:" - surprises += countsurprises(skips, skipped, 'skip', 'ran', allran) + surprises += countsurprises(skips, skipped, 'skip', 'ran', allran, resource_denieds) if bad: print count(len(bad), "test"), "failed:" - surprises += countsurprises(failures, bad, 'fail', 'passed', allran) + surprises += countsurprises(failures, bad, 'fail', 'passed', allran, resource_denieds) if memo: savememo(memo,good,bad,skipped) @@ -472,6 +475,11 @@ indirect_test() finally: sys.stdout = save_stdout + except test_support.ResourceDenied, msg: + if not quiet: + print test, "skipped --", msg + sys.stdout.flush() + return -2 except (ImportError, test_support.TestSkipped), msg: if not quiet: print test, "skipped --", msg @@ -604,7 +612,7 @@ if len(line) > indent: print line -def countsurprises(expected, actual, action, antiaction, allran): +def countsurprises(expected, actual, action, antiaction, allran, resource_denieds): """returns the number of items in actual that aren't in expected.""" printlist(actual) if not expected.isvalid(): @@ -615,7 +623,7 @@ if allran and good_surprise: print count(len(good_surprise), 'test'), antiaction, 'unexpectedly:' printlist(good_surprise) - bad_surprise = set(actual) - expected.getexpected() + bad_surprise = set(actual) - expected.getexpected() - set(resource_denieds) if bad_surprise: print count(len(bad_surprise), action), "unexpected:" printlist(bad_surprise) @@ -1018,6 +1026,7 @@ _failures = { 'java': ''' + test_ast test_class test_copy test_dis Modified: branches/asm/Lib/test/string_tests.py =================================================================== --- branches/asm/Lib/test/string_tests.py 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/Lib/test/string_tests.py 2008-05-30 03:28:32 UTC (rev 4487) @@ -590,6 +590,34 @@ else: self.checkcall(format, "__mod__", value) + def test_partition(self): + self.checkequal(('this is the par', 'ti', 'tion method'), + 'this is the partition method', 'partition', 'ti') + + # from raymond's original specification + S = 'http://www.python.org' + self.checkequal(('http', '://', 'www.python.org'), S, 'partition', '://') + self.checkequal(('http://www.python.org', '', ''), S, 'partition', '?') + self.checkequal(('', 'http://', 'www.python.org'), S, 'partition', 'http://') + self.checkequal(('http://www.python.', 'org', ''), S, 'partition', 'org') + + self.checkraises(ValueError, S, 'partition', '') + self.checkraises(TypeError, S, 'partition', None) + + def test_rpartition(self): + self.checkequal(('this is the rparti', 'ti', 'on method'), + 'this is the rpartition method', 'rpartition', 'ti') + + # from raymond's original specification + S = 'http://www.python.org' + self.checkequal(('http', '://', 'www.python.org'), S, 'rpartition', '://') + self.checkequal(('', '', 'http://www.python.org'), S, 'rpartition', '?') + self.checkequal(('', 'http://', 'www.python.org'), S, 'rpartition', 'http://') + self.checkequal(('http://www.python.', 'org', ''), S, 'rpartition', 'org') + + self.checkraises(ValueError, S, 'rpartition', '') + self.checkraises(TypeError, S, 'rpartition', None) + class MixinStrStringUserStringTest: # Additional tests for 8bit strings, i.e. str, UserString and # the string module Modified: branches/asm/Lib/test/test_select_new.py =================================================================== --- branches/asm/Lib/test/test_select_new.py 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/Lib/test/test_select_new.py 2008-05-30 03:28:32 UTC (rev 4487) @@ -2,6 +2,7 @@ AMAK: 20050515: This module is a brand new test_select module, which gives much wider coverage. """ +import errno import time import test_support import unittest @@ -46,7 +47,13 @@ return select.select([self.server_socket], [self.server_socket], [], SELECT_TIMEOUT)[0] def verify_acceptable(self): - assert self.select_acceptable(), "Server socket should be acceptable" + start = time.time() + while True: + if self.select_acceptable(): + return + elif (time.time() - start) > READ_TIMEOUT: + raise Exception('Server socket did not accept in time') + time.sleep(0.1) def verify_not_acceptable(self): assert not self.select_acceptable(), "Server socket should not be acceptable" @@ -143,10 +150,21 @@ result = self.socket.connect_ex(SERVER_ADDRESS) if result == 0: self.connected = 1 + else: + assert result == errno.EINPROGRESS def finish_connect(self): if self.connected: return + start = time.time() + while True: + self.start_connect() + if self.connected: + break + elif (time.time() - start) > READ_TIMEOUT: + raise Exception('Client socket incomplete connect') + time.sleep(0.1) + rfds, wfds, xfds = select.select([], [self.socket], [], SELECT_TIMEOUT) assert self.socket in wfds, "Client socket incomplete connect" Modified: branches/asm/Lib/test/test_set.py =================================================================== --- branches/asm/Lib/test/test_set.py 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/Lib/test/test_set.py 2008-05-30 03:28:32 UTC (rev 4487) @@ -261,10 +261,7 @@ w = ReprWrapper() s = self.thetype([w]) w.value = s - # XXX: Jython doesn't have str.partition yet - #name = repr(s).partition('(')[0] # strip class name from repr string - srepr = repr(s) - name = srepr[0:srepr.find('(')] + name = repr(s).partition('(')[0] # strip class name from repr string self.assertEqual(repr(s), '%s([%s(...)])' % (name, name)) def test_cyclical_print(self): Modified: branches/asm/ast/astview.py =================================================================== --- branches/asm/ast/astview.py 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/ast/astview.py 2008-05-30 03:28:32 UTC (rev 4487) @@ -37,11 +37,16 @@ get_symbol_key = type get_class_name = lambda node: node.__class__.__name__ +get_lines_and_cols = True + def lispify_ast(node): return tuple(lispify_ast2(node)) def lispify_ast2(node): - yield get_class_name(node) + result = get_class_name(node) + if get_lines_and_cols and hasattr(node, 'lineno') and hasattr(node, 'col_offset'): + result = "%s (%s,%s)" % (result, node.lineno, node.col_offset) + yield result#get_class_name(node)#result try: for field in node._fields: yield tuple(lispify_field(field, getattr(node, field))) Modified: branches/asm/grammar/Python.g =================================================================== --- branches/asm/grammar/Python.g 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/grammar/Python.g 2008-05-30 03:28:32 UTC (rev 4487) @@ -870,7 +870,7 @@ //yield_expr: 'yield' [testlist] yield_expr : 'yield' testlist? - -> ^(Yield ^(Value testlist)?) + -> ^(Yield 'yield' ^(Value testlist)?) ; //XXX: Modified: branches/asm/grammar/PythonWalker.g =================================================================== --- branches/asm/grammar/PythonWalker.g 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/grammar/PythonWalker.g 2008-05-30 03:28:32 UTC (rev 4487) @@ -686,12 +686,12 @@ ; yield_expr returns [exprType etype] - : ^(Yield (^(Value test[expr_contextType.Load]))?) { + : ^(Yield tok='yield' (^(Value test[expr_contextType.Load]))?) { exprType v = null; if ($Value != null) { v = $test.etype; } - $etype = new Yield($Yield, v); + $etype = new Yield($tok, v); } ; Modified: branches/asm/src/org/python/core/PyString.java =================================================================== --- branches/asm/src/org/python/core/PyString.java 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/src/org/python/core/PyString.java 2008-05-30 03:28:32 UTC (rev 4487) @@ -1063,6 +1063,108 @@ return list; } + public PyTuple partition(PyObject sepObj) { + return str_partition(sepObj); + } + + @ExposedMethod + final PyTuple str_partition(PyObject sepObj) { + String sep; + + if (sepObj instanceof PyUnicode) { + return unicodePartition(sepObj); + } else if (sepObj instanceof PyString) { + sep = ((PyString)sepObj).string; + } else { + throw Py.TypeError("expected a character buffer object"); + } + + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + + int index = string.indexOf(sep); + if (index != -1) { + return new PyTuple(fromSubstring(0, index), sepObj, + fromSubstring(index + sep.length(), string.length())); + } else { + return new PyTuple(this, Py.EmptyString, Py.EmptyString); + } + } + + final PyTuple unicodePartition(PyObject sepObj) { + PyUnicode strObj = __unicode__(); + String str = strObj.string; + + // Will throw a TypeError if not a basestring + String sep = sepObj.asString(); + sepObj = sepObj.__unicode__(); + + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + + int index = str.indexOf(sep); + if (index != -1) { + return new PyTuple(strObj.fromSubstring(0, index), sepObj, + strObj.fromSubstring(index + sep.length(), str.length())); + } else { + PyUnicode emptyUnicode = Py.newUnicode(""); + return new PyTuple(this, emptyUnicode, emptyUnicode); + } + } + + public PyTuple rpartition(PyObject sepObj) { + return str_rpartition(sepObj); + } + + @ExposedMethod + final PyTuple str_rpartition(PyObject sepObj) { + String sep; + + if (sepObj instanceof PyUnicode) { + return unicodePartition(sepObj); + } else if (sepObj instanceof PyString) { + sep = ((PyString)sepObj).string; + } else { + throw Py.TypeError("expected a character buffer object"); + } + + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + + int index = string.lastIndexOf(sep); + if (index != -1) { + return new PyTuple(fromSubstring(0, index), sepObj, + fromSubstring(index + sep.length(), string.length())); + } else { + return new PyTuple(Py.EmptyString, Py.EmptyString, this); + } + } + + final PyTuple unicodeRpartition(PyObject sepObj) { + PyUnicode strObj = __unicode__(); + String str = strObj.string; + + // Will throw a TypeError if not a basestring + String sep = sepObj.asString(); + sepObj = sepObj.__unicode__(); + + if (sep.length() == 0) { + throw Py.ValueError("empty separator"); + } + + int index = str.lastIndexOf(sep); + if (index != -1) { + return new PyTuple(strObj.fromSubstring(0, index), sepObj, + strObj.fromSubstring(index + sep.length(), str.length())); + } else { + PyUnicode emptyUnicode = Py.newUnicode(""); + return new PyTuple(emptyUnicode, emptyUnicode, this); + } + } + private PyList splitfields(String sep, int maxsplit) { PyList list = new PyList(); Modified: branches/asm/src/org/python/core/PyType.java =================================================================== --- branches/asm/src/org/python/core/PyType.java 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/src/org/python/core/PyType.java 2008-05-30 03:28:32 UTC (rev 4487) @@ -38,7 +38,6 @@ private String name; /** __base__, the direct base type or null. */ - @ExposedGet(name = "__base__") private PyType base; /** __bases__, the base classes. */ @@ -478,6 +477,13 @@ return base.getLayout(); } + @ExposedGet(name = "__base__") + public PyObject getBase() { + if (base == null) + return Py.None; + return base; + } + @ExposedGet(name = "__bases__") public PyObject getBases() { return new PyTuple(bases); Modified: branches/asm/src/org/python/core/PyUnicode.java =================================================================== --- branches/asm/src/org/python/core/PyUnicode.java 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/src/org/python/core/PyUnicode.java 2008-05-30 03:28:32 UTC (rev 4487) @@ -206,7 +206,16 @@ return new PyUnicode(str_rstrip(sep)); } + @ExposedMethod + final PyTuple unicode_partition(PyObject sep) { + return unicodePartition(sep); + } + @ExposedMethod + final PyTuple unicode_rpartition(PyObject sep) { + return unicodeRpartition(sep); + } + @ExposedMethod(defaults = {"null", "-1"}) final PyList unicode_split(String sep, int maxsplit) { return str_split(sep, maxsplit); Modified: branches/asm/src/org/python/core/io/IOBase.java =================================================================== --- branches/asm/src/org/python/core/io/IOBase.java 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/src/org/python/core/io/IOBase.java 2008-05-30 03:28:32 UTC (rev 4487) @@ -8,8 +8,8 @@ /** * Base class for all I/O classes. * - * IOBase and its descendents in org.python.core.io are loosely based - * off of Python 3000's new io module (PEP 3116). + * IOBase and its descendents in org.python.core.io are based off + * Python 3's new io module (PEP 3116). * * This does not define read(), readinto() and write(), nor readline() * and friends, since their signatures vary per layer. @@ -210,6 +210,6 @@ protected void unsupported(String methodName) { String qualifiedName = getClass().getName(); String className = qualifiedName.substring(qualifiedName.lastIndexOf('.') + 1); - throw Py.TypeError(className + "." + methodName + "() not supported"); + throw Py.TypeError(String.format("%s.%s() not supported", className, methodName)); } } Modified: branches/asm/src/org/python/core/io/RawIOBase.java =================================================================== --- branches/asm/src/org/python/core/io/RawIOBase.java 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/src/org/python/core/io/RawIOBase.java 2008-05-30 03:28:32 UTC (rev 4487) @@ -3,9 +3,6 @@ import java.nio.ByteBuffer; import java.nio.channels.Channel; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; import org.python.core.Py; @@ -58,27 +55,28 @@ * @return a ByteBuffer containing the bytes read */ public ByteBuffer readall() { - long count = 0; - List<ByteBuffer> chunks = new ArrayList<ByteBuffer>(); - while (true) { - ByteBuffer chunk = read(DEFAULT_BUFFER_SIZE); - int chunkSize = chunk.remaining(); - if (chunkSize == 0) { - break; + long allCount = 0; + int readCount = 0; + ByteBuffer all = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE); + ByteBuffer readBuffer = ByteBuffer.allocate(DEFAULT_BUFFER_SIZE); + while ((readCount = readinto(readBuffer)) > 0) { + if (all.remaining() < readCount) { + ByteBuffer old = all; + all = ByteBuffer.allocate(Math.max(old.capacity() * 2, + old.position() + readCount)); + old.flip(); + all.put(old); } - chunks.add(chunk); - count += chunkSize; + readBuffer.flip(); + all.put(readBuffer); + readBuffer.clear(); } - if (count > Integer.MAX_VALUE) { + if (allCount > Integer.MAX_VALUE) { throw Py.OverflowError("requested number of bytes is more than a Python string can " + "hold"); } - ByteBuffer all = ByteBuffer.allocate((int)count); - for (ByteBuffer chunk : chunks) { - all.put(chunk); - } all.flip(); return all; } Modified: branches/asm/src/shell/jython =================================================================== --- branches/asm/src/shell/jython 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/src/shell/jython 2008-05-30 03:28:32 UTC (rev 4487) @@ -1,14 +1,14 @@ -#!/bin/bash +#!/bin/sh # ----------------------------------------------------------------------------- -# jython.sh - Start Script for the Jython +# jython.sh - start script for Jython (adapted from jruby.sh) # -# Adapted from jruby.sh +# Environment variables (optional) # -# Environment Variable Prequisites +# JAVA_HOME Java installation directory # -# JYTHON_OPTS (Optional) Default Jython command line args +# JYTHON_HOME Jython installation directory # -# JAVA_HOME Must point at your Java Development Kit installation. +# JYTHON_OPTS Default Jython command line arguments # # ----------------------------------------------------------------------------- @@ -16,27 +16,28 @@ # ----- Identify OS we are running under -------------------------------------- case "`uname`" in -CYGWIN*) cygwin=true + CYGWIN*) cygwin=true esac -# ----- Verify and Set Required Environment Variables ------------------------- +# ----- Verify and set required environment variables ------------------------- -## resolve links - $0 may be a link to home +## resolve links - $0 may be a link to home PRG=$0 -progname=`basename "$0"` while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '.*/.*' > /dev/null; then - PRG="$link" + PRG="$link" else - PRG="`dirname $PRG`/$link" + PRG="`dirname $PRG`/$link" fi done -JYTHON_HOME_1=`dirname "$PRG"` # the ./bin dir -JYTHON_HOME=`dirname "$JYTHON_HOME_1"` # the . dir +if [ -z "$JYTHON_HOME" ] ; then + JYTHON_HOME_1=`dirname "$PRG"` # the ./bin dir + JYTHON_HOME=`dirname "$JYTHON_HOME_1"` # the . dir +fi if [ -z "$JYTHON_OPTS" ] ; then JYTHON_OPTS="" @@ -51,71 +52,99 @@ JAVA_CMD="$JAVA_HOME/bin/java" fi -CP_DELIMETER=":" +CP_DELIMITER=":" CP=$JYTHON_HOME/jython.jar +if [ ! -f "$CP" ]; then + echo "$0: '$CP' does not exist." >&2 + echo "Try running this script from the 'bin' directory of an installed Jython or " >&2 + echo 'setting $JYTHON_HOME.' >&2 + exit 1 +fi + # add necessary jars for command-line execution for j in "$JYTHON_HOME"/javalib/*.jar; do - if [ "$CP" ]; then - CP="$CP$CP_DELIMETER$j" - else - CP="$j" - fi + if [ "$CP" ]; then + CP="$CP$CP_DELIMITER$j" + else + CP="$j" + fi done if $cygwin; then - CP=`cygpath -p -w "$CP"` + CP=`cygpath -wp "$CP"` + PRG=`cygpath -w "$PRG"` fi -# ----- Execute The Requested Command ----------------------------------------- +# ----- Execute the requested command ----------------------------------------- -JAVA_MEM=-Xmx378m -JAVA_STACK=-Xss1024k +JAVA_STACK=-Xss512k # minimum requirement for test_cpickle # Split out any -J argument for passing to the JVM. # Scanning for args is aborted by '--'. -declare -a java_args -declare -a python_args - while [ $# -gt 0 ] -do - case "$1" in +while [ $# -gt 0 ] ; do + case "$1" in # Stuff after '-J' in this argument goes to JVM -J*) - val=${1:2} - if [ "${val:0:4}" = "-Xmx" ]; then - JAVA_MEM=$val - elif [ "${val:0:4}" = "-Xss" ]; then - JAVA_STACK=$val - else - java_args=("${java_args[@]}" "${1:2}") - fi - ;; - # Match switches that take an argument - -c|-D|-C|-jar|-Q|-W) python_args=("${python_args[@]}" "$1" "$2"); shift ;; - # Match -Dprop=val type args - -D*) python_args=("${python_args[@]}" "$1" ) ;; - # Run with the instrumented profiler: http://jiprof.sourceforge.net/ - --profile) PROFILE_ARGS="-javaagent:$JYTHON_HOME/javalib/profile.jar -Dprofile.properties=$JYTHON_HOME/javalib/profile.properties" ;; - # Run under JDB - --jdb) - if [ -z "$JAVA_HOME" ] ; then - JAVA_CMD='jdb' - else - if $cygwin; then - JAVA_HOME=`cygpath -u "$JAVA_HOME"` - fi - JAVA_CMD="$JAVA_HOME/bin/jdb" - fi ;; - --help) python_args=("${python_args[@]}" "$1") ;; - # Abort processing on the double dash - --) break ;; - # Other opts go to python - -*) python_args=("${python_args[@]}" "$1") ;; - # Abort processing on first non-opt arg - *) break ;; - esac - shift + val=${1:2} + if [ "${val:0:4}" = "-Xss" ] ; then + JAVA_STACK=$val + else + java_args=("${java_args[@]}" "${1:2}") + fi + ;; + # Match switches that take an argument + -c|-C|-jar|-Q|-W) + python_args=("${python_args[@]}" "$1" "$2") + shift + ;; + # Match -Dprop=val type args + -D*) + python_args=("${python_args[@]}" "$1") + ;; + # Run with the instrumented profiler: http://jiprof.sourceforge.net/ + --profile) + rm -f profile.txt # XXX do this? + profile_requested=true + agent_path="$JYTHON_HOME/javalib/profile.jar" + props_path="$JYTHON_HOME/javalib/profile.properties" + if $cygwin; then + agent_path=`cygpath -w "$agent_path"` + props_path=`cygpath -w "$props_path"` + fi + java_args=("${java_args[@]}" -javaagent:"$agent_path" + -Dprofile.properties="$props_path") + ;; + # Run under JDB + --jdb) + if [ -z "$JAVA_HOME" ] ; then + JAVA_CMD='jdb' + else + if $cygwin; then + JAVA_HOME=`cygpath -u "$JAVA_HOME"` + fi + JAVA_CMD="$JAVA_HOME/bin/jdb" + fi + ;; + -h|--help) + help_requested=true + python_args=("${python_args[@]}" "$1") + ;; + # Abort processing on a double dash + --) + break + ;; + # Other opts go to Jython + -*) + python_args=("${python_args[@]}" "$1") + ;; + # Abort processing on first non-opt arg + *) + break + ;; + esac + shift done # Append the rest of the arguments @@ -124,7 +153,7 @@ # Put the python_args back into the position arguments $1, $2 etc set -- "${python_args[@]}" -JAVA_OPTS="$JAVA_OPTS $JAVA_MEM $JAVA_STACK" +JAVA_OPTS="$JAVA_OPTS $JAVA_STACK" if $cygwin; then JAVA_HOME=`cygpath --mixed "$JAVA_HOME"` @@ -138,24 +167,33 @@ fi fi -if [ "$PROFILE_ARGS" != "" ]; then +if [ -n "$profile_requested" ] ; then echo "Running with instrumented profiler" + alias runjava="$JAVA_CMD" + java_args=("${java_args[@]}" -classpath "$CP$CP_SEPARATOR$CLASSPATH") +else + if [ -z $help_requested ] ; then + alias runjava="exec $JAVA_CMD" + else + alias runjava="$JAVA_CMD" + fi + java_args=("${java_args[@]}" -Xbootclasspath/a:"$CP" -classpath "$CLASSPATH") +fi - $JAVA_CMD $PROFILE_ARGS $JAVA_OPTS "${java_args[@]}" -classpath "$CP$CP_SEPARATOR$CLASSPATH" \ - "-Dpython.home=$JYTHON_HOME" \ - org.python.util.jython $JYTHON_OPTS "$@" +runjava $JAVA_OPTS "${java_args[@]}" -Dpython.home="$JYTHON_HOME" \ + -Dpython.executable="$PRG" org.python.util.jython $JYTHON_OPTS "$@" +if [ -n "$profile_requested" ] ; then echo "Profiling results:" - cat profile.txt - -else - echo "$JAVA_CMD" $JAVA_OPTS "${java_args[@]}" -Xbootclasspath/a:"$CP" -classpath "$CLASSPATH" \ - "-Dpython.home=$JYTHON_HOME" \ - org.python.util.jython $JYTHON_OPTS "$@" - - exec "$JAVA_CMD" $JAVA_OPTS "${java_args[@]}" -Xbootclasspath/a:"$CP" -classpath "$CLASSPATH" \ - "-Dpython.home=$JYTHON_HOME" \ - org.python.util.jython $JYTHON_OPTS "$@" - +elif [ -n "$help_requested" ] ; then + echo "Jython launcher options:" >&2 + echo "-Jarg : pass argument through to Java VM (e.g. -J-Xmx512m)" >&2 + echo "--jdb : run under JDB" >&2 + echo "--profile: run with the Java Interactive Profiler (http://jiprof.sf.net)" >&2 + echo "-- : pass remaining arguments through to Jython" >&2 + echo "Jython launcher environment variables:" >&2 + echo "JAVA_HOME : Java installation directory" >&2 + echo "JYTHON_HOME: Jython installation directory" >&2 + echo "JYTHON_OPTS: default command line arguments" >&2 fi Copied: branches/asm/tests/shell (from rev 4486, trunk/jython/tests/shell) Deleted: branches/asm/tests/shell/test-jython.sh =================================================================== --- trunk/jython/tests/shell/test-jython.sh 2008-05-30 03:21:14 UTC (rev 4486) +++ branches/asm/tests/shell/test-jython.sh 2008-05-30 03:28:32 UTC (rev 4487) @@ -1,57 +0,0 @@ -#!/bin/sh - -# test script for bin/jython - -if [ -z "$1" ] ; then - echo "$0: usage: test-jython.sh <Jython home>" >&2 - exit 99 -fi - -TEST_DIR="`mktemp -dt test-jython.XXXXXX`" -SPACE_DIR="$TEST_DIR/directory with spaces" - -cp -Rp "$1" "$SPACE_DIR" - -for JYTHON_HOME in "$SPACE_DIR" "$1" ; do - JYTHON="$JYTHON_HOME/bin/jython" - export JYTHON_HOME - set -ex - - # -J passthrough - "$JYTHON" -J-version 2>&1 | [ `egrep -c "^java version "` == 1 ] - - # Jython reports version - "$JYTHON" --version 2>&1 | [ `egrep -c "^Jython "` == 1 ] - - # $JYTHON_OPTS - JYTHON_OPTS="--version" "$JYTHON" 2>&1 | [ `egrep -c "^Jython "` == 1 ] - - # Jython help - "$JYTHON" --help 2>&1 | [ `egrep -c "^usage: "` == 1 ] - - # Jython launcher help - "$JYTHON" --help 2>&1 | [ `egrep -c "^Jython launcher options:"` == 1 ] - - # Jython exit status - set +e - "$JYTHON" -c 'import sys; sys.exit(5)' - [ $? == 5 ] || exit 1 - set -e - - # Jython executable (don't include newline in case it's \r\n) - [ `"$JYTHON" -c 'import sys; print sys.executable is not None,'` == True ] - - # JDB - echo run | "$JYTHON" --jdb -c "print '\ntest'" | [ `egrep -c "^test"` == 1 ] - - # Jython profiling - "$JYTHON" --profile -c pass 2>&1 | \ - [ `egrep -c "^\| Thread depth limit:"` == 1 ] - [ -f profile.txt ] && rm profile.txt - - set +ex -done - -rm -rf "$TEST_DIR" - -echo "Test successful." Copied: branches/asm/tests/shell/test-jython.sh (from rev 4486, trunk/jython/tests/shell/test-jython.sh) =================================================================== --- branches/asm/tests/shell/test-jython.sh (rev 0) +++ branches/asm/tests/shell/test-jython.sh 2008-05-30 03:28:32 UTC (rev 4487) @@ -0,0 +1,57 @@ +#!/bin/sh + +# test script for bin/jython + +if [ -z "$1" ] ; then + echo "$0: usage: test-jython.sh <Jython home>" >&2 + exit 99 +fi + +TEST_DIR="`mktemp -dt test-jython.XXXXXX`" +SPACE_DIR="$TEST_DIR/directory with spaces" + +cp -Rp "$1" "$SPACE_DIR" + +for JYTHON_HOME in "$SPACE_DIR" "$1" ; do + JYTHON="$JYTHON_HOME/bin/jython" + export JYTHON_HOME + set -ex + + # -J passthrough + "$JYTHON" -J-version 2>&1 | [ `egrep -c "^java version "` == 1 ] + + # Jython reports version + "$JYTHON" --version 2>&1 | [ `egrep -c "^Jython "` == 1 ] + + # $JYTHON_OPTS + JYTHON_OPTS="--version" "$JYTHON" 2>&1 | [ `egrep -c "^Jython "` == 1 ] + + # Jython help + "$JYTHON" --help 2>&1 | [ `egrep -c "^usage: "` == 1 ] + + # Jython launcher help + "$JYTHON" --help 2>&1 | [ `egrep -c "^Jython launcher options:"` == 1 ] + + # Jython exit status + set +e + "$JYTHON" -c 'import sys; sys.exit(5)' + [ $? == 5 ] || exit 1 + set -e + + # Jython executable (don't include newline in case it's \r\n) + [ `"$JYTHON" -c 'import sys; print sys.executable is not None,'` == True ] + + # JDB + echo run | "$JYTHON" --jdb -c "print '\ntest'" | [ `egrep -c "^test"` == 1 ] + + # Jython profiling + "$JYTHON" --profile -c pass 2>&1 | \ + [ `egrep -c "^\| Thread depth limit:"` == 1 ] + [ -f profile.txt ] && rm profile.txt + + set +ex +done + +rm -rf "$TEST_DIR" + +echo "Test successful." This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-05-30 15:19:44
|
Revision: 4490 http://jython.svn.sourceforge.net/jython/?rev=4490&view=rev Author: fwierzbicki Date: 2008-05-30 08:19:42 -0700 (Fri, 30 May 2008) Log Message: ----------- Begin experimenting with a partial parser -- that is a recognizer that will be able to tell if a string of code from an interactive session is a true syntax error, or if it is part of a potentially valid string of code. For example, in the interactive session: >>> s = """ ... hello Is the start of a valid string, and should be recognized as a valid partial parse. On the other hand >>> print , Is still a syntax error. Modified Paths: -------------- branches/asm/build.xml Added Paths: ----------- branches/asm/grammar/PythonPartial.g branches/asm/src/org/python/antlr/PythonPartialTester.java Modified: branches/asm/build.xml =================================================================== --- branches/asm/build.xml 2008-05-30 05:54:28 UTC (rev 4489) +++ branches/asm/build.xml 2008-05-30 15:19:42 UTC (rev 4490) @@ -398,6 +398,7 @@ <arg path="build/gensrc/org/python/antlr"/> <arg file="grammar/Python.g"/> <arg file="grammar/PythonWalker.g"/> + <arg file="grammar/PythonPartial.g"/> <classpath refid="main.classpath"/> </java> Added: branches/asm/grammar/PythonPartial.g =================================================================== --- branches/asm/grammar/PythonPartial.g (rev 0) +++ branches/asm/grammar/PythonPartial.g 2008-05-30 15:19:42 UTC (rev 4490) @@ -0,0 +1,742 @@ +/* + [The 'BSD licence'] + Copyright (c) 2004 Terence Parr and Loring Craymer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** Python 2.3.3 Grammar + * + * Terence Parr and Loring Craymer + * February 2004 + * + * Converted to ANTLR v3 November 2005 by Terence Parr. + * + * This grammar was derived automatically from the Python 2.3.3 + * parser grammar to get a syntactically correct ANTLR grammar + * for Python. Then Terence hand tweaked it to be semantically + * correct; i.e., removed lookahead issues etc... It is LL(1) + * except for the (sometimes optional) trailing commas and semi-colons. + * It needs two symbols of lookahead in this case. + * + * Starting with Loring's preliminary lexer for Python, I modified it + * to do my version of the whole nasty INDENT/DEDENT issue just so I + * could understand the problem better. This grammar requires + * PythonTokenStream.java to work. Also I used some rules from the + * semi-formal grammar on the web for Python (automatically + * translated to ANTLR format by an ANTLR grammar, naturally <grin>). + * The lexical rules for python are particularly nasty and it took me + * a long time to get it 'right'; i.e., think about it in the proper + * way. Resist changing the lexer unless you've used ANTLR a lot. ;) + * + * I (Terence) tested this by running it on the jython-2.1/Lib + * directory of 40k lines of Python. + * + * Updated to Python 2.5 by Frank Wierzbicki. + * + * This particular version has some changes to allow "partial" parsing + * So that an interactive session can tell if it should wait for more + * input or not. For example, this grammar will allow a String that + * starts with """ but has no ending """ and will allow a Suite to have + * an indent but no dedent. + */ + +grammar PythonPartial; + +tokens { + INDENT; + DEDENT; +} + +@header { +package org.python.antlr; +} + +@members { + protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException { + throw new MismatchedTokenException(ttype, input); + } + + protected void mismatch(IntStream input, RecognitionException e, BitSet follow) throws RecognitionException { + throw e; + } +} + +@rulecatch { +catch (RecognitionException e) { + throw e; +} +} + + +@lexer::header { +package org.python.antlr; +} + +@lexer::members { +/** Handles context-sensitive lexing of implicit line joining such as + * the case where newline is ignored in cases like this: + * a = [3, + * 4] + */ +int implicitLineJoiningLevel = 0; +int startPos=-1; + + public Token nextToken() { + while (true) { + token = null; + channel = Token.DEFAULT_CHANNEL; + tokenStartCharIndex = input.index(); + tokenStartCharPositionInLine = input.getCharPositionInLine(); + tokenStartLine = input.getLine(); + text = null; + if ( input.LA(1)==CharStream.EOF ) { + return Token.EOF_TOKEN; + } + try { + mTokens(); + if ( token==null ) { + emit(); + } + else if ( token==Token.SKIP_TOKEN ) { + continue; + } + return token; + } + catch (RecognitionException re) { + throw new ParseException(getErrorMessage(re, this.getTokenNames())); + } + } + } + +} + +single_input : NEWLINE + | simple_stmt + | compound_stmt NEWLINE? + ; + +file_input : (NEWLINE | stmt)* + ; + +eval_input : (NEWLINE)* testlist (NEWLINE)* + ; + +decorators: decorator+ + ; + +decorator: AT dotted_attr (LPAREN arglist? RPAREN)? NEWLINE + ; + +dotted_attr + : NAME (DOT NAME)* + ; + +funcdef : decorators? 'def' NAME parameters COLON suite + ; + +parameters : LPAREN (varargslist)? RPAREN + ; + +varargslist : defparameter (options {greedy=true;}:COMMA defparameter)* + (COMMA + ( STAR NAME (COMMA DOUBLESTAR NAME)? + | DOUBLESTAR NAME + )? + )? + | STAR NAME (COMMA DOUBLESTAR NAME)? + | DOUBLESTAR NAME + ; + +defparameter : fpdef (ASSIGN test)? + ; + +fpdef : NAME + | LPAREN fplist RPAREN + ; + +fplist : fpdef (options {greedy=true;}:COMMA fpdef)* (COMMA)? + ; + +stmt : simple_stmt + | compound_stmt + ; + +simple_stmt : small_stmt (options {greedy=true;}:SEMI small_stmt)* (SEMI)? NEWLINE + ; + +small_stmt : expr_stmt + | print_stmt + | del_stmt + | pass_stmt + | flow_stmt + | import_stmt + | global_stmt + | exec_stmt + | assert_stmt + ; + +expr_stmt : testlist + ( augassign yield_expr + | augassign testlist + | assigns + )? + ; + +assigns + : assign_testlist+ + | assign_yield+ + ; + +assign_testlist + : ASSIGN testlist + ; + +assign_yield + : ASSIGN yield_expr + ; + +augassign : PLUSEQUAL + | MINUSEQUAL + | STAREQUAL + | SLASHEQUAL + | PERCENTEQUAL + | AMPEREQUAL + | VBAREQUAL + | CIRCUMFLEXEQUAL + | LEFTSHIFTEQUAL + | RIGHTSHIFTEQUAL + | DOUBLESTAREQUAL + | DOUBLESLASHEQUAL + ; + +print_stmt : 'print' (printlist | RIGHTSHIFT printlist)? + ; + +printlist returns [boolean newline] + : test (options {k=2;}: COMMA test)* (COMMA)? + ; + + +del_stmt : 'del' exprlist + ; + +pass_stmt : 'pass' + ; + +flow_stmt : break_stmt + | continue_stmt + | return_stmt + | raise_stmt + | yield_stmt + ; + +break_stmt : 'break' + ; + +continue_stmt : 'continue' + ; + +return_stmt : 'return' (testlist)? + ; + +yield_stmt : yield_expr + ; + +raise_stmt: 'raise' (test (COMMA test (COMMA test)?)?)? + ; + +import_stmt : import_name + | import_from + ; + +import_name : 'import' dotted_as_names + ; + +import_from: 'from' (DOT* dotted_name | DOT+) 'import' + (STAR + | import_as_names + | LPAREN import_as_names RPAREN + ) + ; + +import_as_names : import_as_name (COMMA import_as_name)* (COMMA)? + ; + +import_as_name : NAME ('as' NAME)? + ; + +dotted_as_name : dotted_name ('as' NAME)? + ; + +dotted_as_names : dotted_as_name (COMMA dotted_as_name)* + ; +dotted_name : NAME (DOT NAME)* + ; + +global_stmt : 'global' NAME (COMMA NAME)* + ; + +exec_stmt : 'exec' expr ('in' test (COMMA test)?)? + ; + +assert_stmt : 'assert' test (COMMA test)? + ; + +compound_stmt : if_stmt + | while_stmt + | for_stmt + | try_stmt + | with_stmt + | funcdef + | classdef + ; + +if_stmt: 'if' test COLON suite elif_clause* ('else' COLON suite)? + ; + +elif_clause : 'elif' test COLON suite + ; + +while_stmt : 'while' test COLON suite ('else' COLON suite)? + ; + +for_stmt : 'for' exprlist 'in' testlist COLON suite ('else' COLON suite)? + ; + +try_stmt : 'try' COLON suite + ( except_clause+ ('else' COLON suite)? ('finally' COLON suite)? + | 'finally' COLON suite + ) + ; + +with_stmt: 'with' test (with_var)? COLON suite + ; + +with_var: ('as' | NAME) expr + ; + +except_clause : 'except' (test (COMMA test)?)? COLON suite + ; + +suite : simple_stmt + | NEWLINE INDENT (stmt)+ DEDENT + ; + +test: or_test + ( ('if' or_test 'else') => 'if' or_test 'else' test)? + | lambdef + ; + +or_test : and_test (OR and_test)* + ; + +and_test : not_test (AND not_test)* + ; + +not_test : NOT not_test + | comparison + ; + +comparison: expr (comp_op expr)* + ; + +comp_op : LESS + | GREATER + | EQUAL + | GREATEREQUAL + | LESSEQUAL + | ALT_NOTEQUAL + | NOTEQUAL + | 'in' + | NOT 'in' + | 'is' + | 'is' NOT + ; + +expr : xor_expr (VBAR xor_expr)* + ; + +xor_expr : and_expr (CIRCUMFLEX and_expr)* + ; + +and_expr : shift_expr (AMPER shift_expr)* + ; + +shift_expr : arith_expr ((LEFTSHIFT|RIGHTSHIFT) arith_expr)* + ; + +arith_expr: term ((PLUS|MINUS) term)* + ; + +term : factor ((STAR | SLASH | PERCENT | DOUBLESLASH ) factor)* + ; + +factor : PLUS factor + | MINUS factor + | TILDE factor + | power + ; + +power : atom (trailer)* (options {greedy=true;}:DOUBLESTAR factor)? + ; + +atom : LPAREN + ( yield_expr + | testlist_gexp + )? + RPAREN + | LBRACK (listmaker)? RBRACK + | LCURLY (dictmaker)? RCURLY + | BACKQUOTE testlist BACKQUOTE + | NAME + | INT + | LONGINT + | FLOAT + | COMPLEX + | (STRING)+ + ; + +listmaker : test + ( list_for + | (options {greedy=true;}:COMMA test)* + ) (COMMA)? + ; + +testlist_gexp + : test ( (options {k=2;}: COMMA test)* (COMMA)? + | gen_for + ) + + ; + +lambdef: 'lambda' (varargslist)? COLON test + ; + +trailer : LPAREN (arglist)? RPAREN + | LBRACK subscriptlist RBRACK + | DOT NAME + ; + +subscriptlist : subscript (options {greedy=true;}:COMMA subscript)* (COMMA)? + ; + +subscript : DOT DOT DOT + | test (COLON (test)? (sliceop)?)? + | COLON (test)? (sliceop)? + ; + +sliceop : COLON (test)? + ; + +exprlist : expr (options {k=2;}: COMMA expr)* (COMMA)? + ; + +testlist + : test (options {k=2;}: COMMA test)* (COMMA)? + ; + +dictmaker : test COLON test (options {k=2;}:COMMA test COLON test)* (COMMA)? + ; + +classdef: 'class' NAME (LPAREN testlist? RPAREN)? COLON suite + ; + +arglist : argument (COMMA argument)* + ( COMMA + ( STAR test (COMMA DOUBLESTAR test)? + | DOUBLESTAR test + )? + )? + | STAR test (COMMA DOUBLESTAR test)? + | DOUBLESTAR test + ; + +argument : test ( (ASSIGN test) | gen_for)? + ; + +list_iter : list_for + | list_if + ; + +list_for : 'for' exprlist 'in' testlist (list_iter)? + ; + +list_if : 'if' test (list_iter)? + ; + +gen_iter: gen_for + | gen_if + ; + +gen_for: 'for' exprlist 'in' or_test gen_iter? + ; + +gen_if: 'if' test gen_iter? + ; + +yield_expr : 'yield' testlist? + ; + +LPAREN : '(' {implicitLineJoiningLevel++;} ; + +RPAREN : ')' {implicitLineJoiningLevel--;} ; + +LBRACK : '[' {implicitLineJoiningLevel++;} ; + +RBRACK : ']' {implicitLineJoiningLevel--;} ; + +COLON : ':' ; + +COMMA : ',' ; + +SEMI : ';' ; + +PLUS : '+' ; + +MINUS : '-' ; + +STAR : '*' ; + +SLASH : '/' ; + +VBAR : '|' ; + +AMPER : '&' ; + +LESS : '<' ; + +GREATER : '>' ; + +ASSIGN : '=' ; + +PERCENT : '%' ; + +BACKQUOTE : '`' ; + +LCURLY : '{' {implicitLineJoiningLevel++;} ; + +RCURLY : '}' {implicitLineJoiningLevel--;} ; + +CIRCUMFLEX : '^' ; + +TILDE : '~' ; + +EQUAL : '==' ; + +NOTEQUAL : '!=' ; + +ALT_NOTEQUAL: '<>' ; + +LESSEQUAL : '<=' ; + +LEFTSHIFT : '<<' ; + +GREATEREQUAL : '>=' ; + +RIGHTSHIFT : '>>' ; + +PLUSEQUAL : '+=' ; + +MINUSEQUAL : '-=' ; + +DOUBLESTAR : '**' ; + +STAREQUAL : '*=' ; + +DOUBLESLASH : '//' ; + +SLASHEQUAL : '/=' ; + +VBAREQUAL : '|=' ; + +PERCENTEQUAL : '%=' ; + +AMPEREQUAL : '&=' ; + +CIRCUMFLEXEQUAL : '^=' ; + +LEFTSHIFTEQUAL : '<<=' ; + +RIGHTSHIFTEQUAL : '>>=' ; + +DOUBLESTAREQUAL : '**=' ; + +DOUBLESLASHEQUAL : '//=' ; + +DOT : '.' ; + +AT : '@' ; + +AND : 'and' ; + +OR : 'or' ; + +NOT : 'not' ; + +FLOAT + : '.' DIGITS (Exponent)? + | DIGITS '.' Exponent + | DIGITS ('.' (DIGITS (Exponent)?)? | Exponent) + ; + +LONGINT + : INT ('l'|'L') + ; + +fragment +Exponent + : ('e' | 'E') ( '+' | '-' )? DIGITS + ; + +INT : // Hex + '0' ('x' | 'X') ( '0' .. '9' | 'a' .. 'f' | 'A' .. 'F' )+ + | // Octal + '0' ( '0' .. '7' )* + | '1'..'9' DIGITS* + ; + +COMPLEX + : DIGITS+ ('j'|'J') + | FLOAT ('j'|'J') + ; + +fragment +DIGITS : ( '0' .. '9' )+ ; + +NAME: ( 'a' .. 'z' | 'A' .. 'Z' | '_') + ( 'a' .. 'z' | 'A' .. 'Z' | '_' | '0' .. '9' )* + ; + +/** Match various string types. Note that greedy=false implies ''' + * should make us exit loop not continue. + */ +STRING + : ('r'|'u'|'ur')? + ( '\'\'\'' (options {greedy=false;}:TRIAPOS)* '\'\'\'' + | '"""' (options {greedy=false;}:TRIQUOTE)* '"""' + | '"' (ESC|~('\\'|'\n'|'"'))* '"' + | '\'' (ESC|~('\\'|'\n'|'\''))* '\'' + ) + ; + +/** the two '"'? cause a warning -- is there a way to avoid that? */ +fragment +TRIQUOTE + : '"'? '"'? (ESC|~('\\'|'"'))+ + ; + +/** the two '\''? cause a warning -- is there a way to avoid that? */ +fragment +TRIAPOS + : '\''? '\''? (ESC|~('\\'|'\''))+ + ; + +fragment +ESC + : '\\' . + ; + +/** Consume a newline and any whitespace at start of next line + * unless the next line contains only white space, in that case + * emit a newline. + */ +CONTINUED_LINE + : '\\' ('\r')? '\n' (' '|'\t')* { $channel=HIDDEN; } + ( nl=NEWLINE {emit(new ClassicToken(NEWLINE,nl.getText()));} + | + ) + ; + +/** Treat a sequence of blank lines as a single blank line. If + * nested within a (..), {..}, or [..], then ignore newlines. + * If the first newline starts in column one, they are to be ignored. + * + * Frank Wierzbicki added: Also ignore FORMFEEDS (\u000C). + */ +NEWLINE + : (('\u000C')?('\r')? '\n' )+ + {if ( startPos==0 || implicitLineJoiningLevel>0 ) + $channel=HIDDEN; + } + ; + +WS : {startPos>0}?=> (' '|'\t'|'\u000C')+ {$channel=HIDDEN;} + ; + +/** Grab everything before a real symbol. Then if newline, kill it + * as this is a blank line. If whitespace followed by comment, kill it + * as it's a comment on a line by itself. + * + * Ignore leading whitespace when nested in [..], (..), {..}. + */ +LEADING_WS +@init { + int spaces = 0; +} + : {startPos==0}?=> + ( {implicitLineJoiningLevel>0}? ( ' ' | '\t' )+ {$channel=HIDDEN;} + | ( ' ' { spaces++; } + | '\t' { spaces += 8; spaces -= (spaces \% 8); } + )+ + { + // make a string of n spaces where n is column number - 1 + char[] indentation = new char[spaces]; + for (int i=0; i<spaces; i++) { + indentation[i] = ' '; + } + String s = new String(indentation); + emit(new ClassicToken(LEADING_WS,new String(indentation))); + } + // kill trailing newline if present and then ignore + ( ('\r')? '\n' {if (token!=null) token.setChannel(HIDDEN); else $channel=HIDDEN;})* + // {token.setChannel(99); } + ) + ; + +/** Comments not on line by themselves are turned into newlines. + + b = a # end of line comment + + or + + a = [1, # weird + 2] + + This rule is invoked directly by nextToken when the comment is in + first column or when comment is on end of nonwhitespace line. + + Only match \n here if we didn't start on left edge; let NEWLINE return that. + Kill if newlines if we live on a line by ourselves + + Consume any leading whitespace if it starts on left edge. + */ +COMMENT +@init { + $channel=HIDDEN; +} + : {startPos==0}?=> (' '|'\t')* '#' (~'\n')* '\n'+ + | {startPos>0}?=> '#' (~'\n')* // let NEWLINE handle \n unless char pos==0 for '#' + ; + Added: branches/asm/src/org/python/antlr/PythonPartialTester.java =================================================================== --- branches/asm/src/org/python/antlr/PythonPartialTester.java (rev 0) +++ branches/asm/src/org/python/antlr/PythonPartialTester.java 2008-05-30 15:19:42 UTC (rev 4490) @@ -0,0 +1,61 @@ +package org.python.antlr; + +import org.antlr.runtime.ANTLRFileStream; +import org.antlr.runtime.CharStream; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; +import org.antlr.runtime.Token; + +/** + * A walker producing a <code>PythonTree</code> AST. + */ +public class PythonPartialTester { + + public static class PPLexer extends PythonPartialLexer { + public PPLexer(CharStream lexer) { + super(lexer); + } + + public Token nextToken() { + startPos = getCharPositionInLine(); + return super.nextToken(); + } + } + + public enum Block { MODULE, INTERACTIVE, EXPRESSION }; + + private Block _block = Block.INTERACTIVE; + + public void parse(String[] args) throws Exception { + try { + PythonTree result = null; + CharStream input = new ANTLRFileStream(args[0]); + PythonPartialLexer lexer = new PPLexer(input); + CommonTokenStream tokens = new CommonTokenStream(lexer); + tokens.discardOffChannelTokens(true); + PythonTokenSource indentedSource = new PythonTokenSource(tokens); + tokens = new CommonTokenStream(indentedSource); + PythonPartialParser parser = new PythonPartialParser(tokens); + switch (_block) { + case MODULE : + parser.file_input(); + break; + case INTERACTIVE : + parser.single_input(); + break; + case EXPRESSION : + parser.eval_input(); + break; + } + System.out.println("SUCCEED"); + } catch (RecognitionException e) { + System.out.println("FAIL"); + } + } + + public static void main(String[] args) throws Exception { + PythonPartialTester p = new PythonPartialTester(); + p.parse(args); + } + +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-06-02 01:03:11
|
Revision: 4499 http://jython.svn.sourceforge.net/jython/?rev=4499&view=rev Author: fwierzbicki Date: 2008-06-01 18:03:08 -0700 (Sun, 01 Jun 2008) Log Message: ----------- Switched to 2.4 CPython lib. Modified Paths: -------------- branches/asm/src/org/python/modules/sre/SRE_STATE.java Added Paths: ----------- branches/asm/Lib/random.py Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svn:externals - CPythonLib http://svn.python.org/projects/python/branches/release25-maint/Lib/ + CPythonLib http://svn.python.org/projects/python/branches/release24-maint/Lib/ Added: branches/asm/Lib/random.py =================================================================== --- branches/asm/Lib/random.py (rev 0) +++ branches/asm/Lib/random.py 2008-06-02 01:03:08 UTC (rev 4499) @@ -0,0 +1,843 @@ +"""Random variable generators. + + integers + -------- + uniform within range + + sequences + --------- + pick random element + pick random sample + generate random permutation + + distributions on the real line: + ------------------------------ + uniform + normal (Gaussian) + lognormal + negative exponential + gamma + beta + pareto + Weibull + + distributions on the circle (angles 0 to 2pi) + --------------------------------------------- + circular uniform + von Mises + +General notes on the underlying Mersenne Twister core generator: + +* The period is 2**19937-1. +* It is one of the most extensively tested generators in existence +* Without a direct way to compute N steps forward, the + semantics of jumpahead(n) are weakened to simply jump + to another distant state and rely on the large period + to avoid overlapping sequences. +* The random() method is implemented in C, executes in + a single Python step, and is, therefore, threadsafe. + +""" +from types import BuiltinMethodType as _BuiltinMethodType +from math import log as _log, exp as _exp, pi as _pi, e as _e +from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin +from math import floor as _floor + +__all__ = ["Random","seed","random","uniform","randint","choice","sample", + "randrange","shuffle","normalvariate","lognormvariate", + "cunifvariate","expovariate","vonmisesvariate","gammavariate", + "stdgamma","gauss","betavariate","paretovariate","weibullvariate", + "getstate","setstate","jumpahead", "WichmannHill"] + +NV_MAGICCONST = 4 * _exp(-0.5)/_sqrt(2.0) +TWOPI = 2.0*_pi +LOG4 = _log(4.0) +SG_MAGICCONST = 1.0 + _log(4.5) +BPF = 53 # Number of bits in a float + +# Translated by Guido van Rossum from C source provided by +# Adrian Baddeley. Adapted by Raymond Hettinger for use with +# the Mersenne Twister core generator. + +import _random + +class Random(_random.Random): + """Random number generator base class used by bound module functions. + + Used to instantiate instances of Random to get generators that don't + share state. Especially useful for multi-threaded programs, creating + a different instance of Random for each thread, and using the jumpahead() + method to ensure that the generated sequences seen by each thread don't + overlap. + + Class Random can also be subclassed if you want to use a different basic + generator of your own devising: in that case, override the following + methods: random(), seed(), getstate(), setstate() and jumpahead(). + + """ + + VERSION = 2 # used by getstate/setstate + + def __init__(self, x=None): + """Initialize an instance. + + Optional argument x controls seeding, as for Random.seed(). + """ + + self.seed(x) + self.gauss_next = None + + def seed(self, a=None): + """Initialize internal state from hashable object. + + None or no argument seeds from current time. + + If a is not None or an int or long, hash(a) is used instead. + """ + + if a is None: + import time + a = long(time.time() * 256) # use fractional seconds + super(Random, self).seed(a) + self.gauss_next = None + + def getstate(self): + """Return internal state; can be passed to setstate() later.""" + return self.VERSION, super(Random, self).getstate(), self.gauss_next + + def setstate(self, state): + """Restore internal state from object returned by getstate().""" + version = state[0] + if version == 2: + version, internalstate, self.gauss_next = state + super(Random, self).setstate(internalstate) + else: + raise ValueError("state with version %s passed to " + "Random.setstate() of version %s" % + (version, self.VERSION)) + +## ---- Methods below this point do not need to be overridden when +## ---- subclassing for the purpose of using a different core generator. + +## -------------------- pickle support ------------------- + + def __getstate__(self): # for pickle + return self.getstate() + + def __setstate__(self, state): # for pickle + self.setstate(state) + + def __reduce__(self): + return self.__class__, (), self.getstate() + +## -------------------- integer methods ------------------- + + def randrange(self, start, stop=None, step=1, int=int, default=None, + maxwidth=1L<<BPF, _BuiltinMethod=_BuiltinMethodType): + """Choose a random item from range(start, stop[, step]). + + This fixes the problem with randint() which includes the + endpoint; in Python this is usually not what you want. + Do not supply the 'int', 'default', and 'maxwidth' arguments. + """ + + # This code is a bit messy to make it fast for the + # common case while still doing adequate error checking. + istart = int(start) + if istart != start: + raise ValueError, "non-integer arg 1 for randrange()" + if stop is default: + if istart > 0: + if istart >= maxwidth and type(self.random) is _BuiltinMethod: + return self._randbelow(istart) + return int(self.random() * istart) + raise ValueError, "empty range for randrange()" + + # stop argument supplied. + istop = int(stop) + if istop != stop: + raise ValueError, "non-integer stop for randrange()" + width = istop - istart + if step == 1 and width > 0: + # Note that + # int(istart + self.random()*(istop - istart)) + # instead would be incorrect. For example, consider istart + # = -2 and istop = 0. Then the guts would be in + # -2.0 to 0.0 exclusive on both ends (ignoring that random() + # might return 0.0), and because int() truncates toward 0, the + # final result would be -1 or 0 (instead of -2 or -1). + # istart + int(self.random()*(istop - istart)) + # would also be incorrect, for a subtler reason: the RHS + # can return a long, and then randrange() would also return + # a long, but we're supposed to return an int (for backward + # compatibility). + if width >= maxwidth and type(self.random) is _BuiltinMethod: + return int(istart + self._randbelow(width)) + return int(istart + int(self.random()*width)) + if step == 1: + raise ValueError, "empty range for randrange()" + + # Non-unit step argument supplied. + istep = int(step) + if istep != step: + raise ValueError, "non-integer step for randrange()" + if istep > 0: + n = (width + istep - 1) / istep + elif istep < 0: + n = (width + istep + 1) / istep + else: + raise ValueError, "zero step for randrange()" + + if n <= 0: + raise ValueError, "empty range for randrange()" + + if n >= maxwidth and type(self.random) is _BuiltinMethod: + return istart + self._randbelow(n) + return istart + istep*int(self.random() * n) + + def randint(self, a, b): + """Return random integer in range [a, b], including both end points. + """ + + return self.randrange(a, b+1) + + def _randbelow(self, n, bpf=BPF, maxwidth=1L<<BPF, + long=long, _log=_log, int=int): + """Return a random int in the range [0,n) + + Handles the case where n has more bits than returned + by a single call to the underlying generator. + """ + + # k is a sometimes over but never under estimate of the bits in n + k = int(1.00001 + _log(n-1, 2)) # 2**k > n-1 >= 2**(k-2) + + random = self.random + r = n + while r >= n: + # In Py2.4, this section becomes: r = self.getrandbits(k) + r = long(random() * maxwidth) + bits = bpf + while bits < k: + r = (r << bpf) | (long(random() * maxwidth)) + bits += bpf + r >>= (bits - k) + return r + +## -------------------- sequence methods ------------------- + + def choice(self, seq): + """Choose a random element from a non-empty sequence.""" + return seq[int(self.random() * len(seq))] + + def shuffle(self, x, random=None, int=int): + """x, random=random.random -> shuffle list x in place; return None. + + Optional arg random is a 0-argument function returning a random + float in [0.0, 1.0); by default, the standard random.random. + + Note that for even rather small len(x), the total number of + permutations of x is larger than the period of most random number + generators; this implies that "most" permutations of a long + sequence can never be generated. + """ + + if random is None: + random = self.random + for i in xrange(len(x)-1, 0, -1): + # pick an element in x[:i+1] with which to exchange x[i] + j = int(random() * (i+1)) + x[i], x[j] = x[j], x[i] + + def sample(self, population, k): + """Chooses k unique random elements from a population sequence. + + Returns a new list containing elements from the population while + leaving the original population unchanged. The resulting list is + in selection order so that all sub-slices will also be valid random + samples. This allows raffle winners (the sample) to be partitioned + into grand prize and second place winners (the subslices). + + Members of the population need not be hashable or unique. If the + population contains repeats, then each occurrence is a possible + selection in the sample. + + To choose a sample in a range of integers, use xrange as an argument. + This is especially fast and space efficient for sampling from a + large population: sample(xrange(10000000), 60) + """ + + # Sampling without replacement entails tracking either potential + # selections (the pool) in a list or previous selections in a + # dictionary. + + # When the number of selections is small compared to the population, + # then tracking selections is efficient, requiring only a small + # dictionary and an occasional reselection. For a larger number of + # selections, the pool tracking method is preferred since the list takes + # less space than the dictionary and it doesn't suffer from frequent + # reselections. + + n = len(population) + if not 0 <= k <= n: + raise ValueError, "sample larger than population" + random = self.random + _int = int + result = [None] * k + if n < 6 * k: # if n len list takes less space than a k len dict + pool = list(population) + for i in xrange(k): # invariant: non-selected at [0,n-i) + j = _int(random() * (n-i)) + result[i] = pool[j] + pool[j] = pool[n-i-1] # move non-selected item into vacancy + else: + try: + n > 0 and (population[0], population[n//2], population[n-1]) + except (TypeError, KeyError): # handle sets and dictionaries + population = tuple(population) + selected = {} + for i in xrange(k): + j = _int(random() * n) + while j in selected: + j = _int(random() * n) + result[i] = selected[j] = population[j] + return result + +## -------------------- real-valued distributions ------------------- + +## -------------------- uniform distribution ------------------- + + def uniform(self, a, b): + """Get a random number in the range [a, b).""" + return a + (b-a) * self.random() + +## -------------------- normal distribution -------------------- + + def normalvariate(self, mu, sigma): + """Normal distribution. + + mu is the mean, and sigma is the standard deviation. + + """ + # mu = mean, sigma = standard deviation + + # Uses Kinderman and Monahan method. Reference: Kinderman, + # A.J. and Monahan, J.F., "Computer generation of random + # variables using the ratio of uniform deviates", ACM Trans + # Math Software, 3, (1977), pp257-260. + + random = self.random + while True: + u1 = random() + u2 = 1.0 - random() + z = NV_MAGICCONST*(u1-0.5)/u2 + zz = z*z/4.0 + if zz <= -_log(u2): + break + return mu + z*sigma + +## -------------------- lognormal distribution -------------------- + + def lognormvariate(self, mu, sigma): + """Log normal distribution. + + If you take the natural logarithm of this distribution, you'll get a + normal distribution with mean mu and standard deviation sigma. + mu can have any value, and sigma must be greater than zero. + + """ + return _exp(self.normalvariate(mu, sigma)) + +## -------------------- circular uniform -------------------- + + def cunifvariate(self, mean, arc): + """Circular uniform distribution. + + mean is the mean angle, and arc is the range of the distribution, + centered around the mean angle. Both values must be expressed in + radians. Returned values range between mean - arc/2 and + mean + arc/2 and are normalized to between 0 and pi. + + Deprecated in version 2.3. Use: + (mean + arc * (Random.random() - 0.5)) % Math.pi + + """ + # mean: mean angle (in radians between 0 and pi) + # arc: range of distribution (in radians between 0 and pi) + import warnings + warnings.warn("The cunifvariate function is deprecated; Use (mean " + "+ arc * (Random.random() - 0.5)) % Math.pi instead.", + DeprecationWarning, 2) + + return (mean + arc * (self.random() - 0.5)) % _pi + +## -------------------- exponential distribution -------------------- + + def expovariate(self, lambd): + """Exponential distribution. + + lambd is 1.0 divided by the desired mean. (The parameter would be + called "lambda", but that is a reserved word in Python.) Returned + values range from 0 to positive infinity. + + """ + # lambd: rate lambd = 1/mean + # ('lambda' is a Python reserved word) + + random = self.random + u = random() + while u <= 1e-7: + u = random() + return -_log(u)/lambd + +## -------------------- von Mises distribution -------------------- + + def vonmisesvariate(self, mu, kappa): + """Circular data distribution. + + mu is the mean angle, expressed in radians between 0 and 2*pi, and + kappa is the concentration parameter, which must be greater than or + equal to zero. If kappa is equal to zero, this distribution reduces + to a uniform random angle over the range 0 to 2*pi. + + """ + # mu: mean angle (in radians between 0 and 2*pi) + # kappa: concentration parameter kappa (>= 0) + # if kappa = 0 generate uniform random angle + + # Based upon an algorithm published in: Fisher, N.I., + # "Statistical Analysis of Circular Data", Cambridge + # University Press, 1993. + + # Thanks to Magnus Kessler for a correction to the + # implementation of step 4. + + random = self.random + if kappa <= 1e-6: + return TWOPI * random() + + a = 1.0 + _sqrt(1.0 + 4.0 * kappa * kappa) + b = (a - _sqrt(2.0 * a))/(2.0 * kappa) + r = (1.0 + b * b)/(2.0 * b) + + while True: + u1 = random() + + z = _cos(_pi * u1) + f = (1.0 + r * z)/(r + z) + c = kappa * (r - f) + + u2 = random() + + if not (u2 >= c * (2.0 - c) and u2 > c * _exp(1.0 - c)): + break + + u3 = random() + if u3 > 0.5: + theta = (mu % TWOPI) + _acos(f) + else: + theta = (mu % TWOPI) - _acos(f) + + return theta + +## -------------------- gamma distribution -------------------- + + def gammavariate(self, alpha, beta): + """Gamma distribution. Not the gamma function! + + Conditions on the parameters are alpha > 0 and beta > 0. + + """ + + # alpha > 0, beta > 0, mean is alpha*beta, variance is alpha*beta**2 + + # Warning: a few older sources define the gamma distribution in terms + # of alpha > -1.0 + if alpha <= 0.0 or beta <= 0.0: + raise ValueError, 'gammavariate: alpha and beta must be > 0.0' + + random = self.random + if alpha > 1.0: + + # Uses R.C.H. Cheng, "The generation of Gamma + # variables with non-integral shape parameters", + # Applied Statistics, (1977), 26, No. 1, p71-74 + + ainv = _sqrt(2.0 * alpha - 1.0) + bbb = alpha - LOG4 + ccc = alpha + ainv + + while True: + u1 = random() + if not 1e-7 < u1 < .9999999: + continue + u2 = 1.0 - random() + v = _log(u1/(1.0-u1))/ainv + x = alpha*_exp(v) + z = u1*u1*u2 + r = bbb+ccc*v-x + if r + SG_MAGICCONST - 4.5*z >= 0.0 or r >= _log(z): + return x * beta + + elif alpha == 1.0: + # expovariate(1) + u = random() + while u <= 1e-7: + u = random() + return -_log(u) * beta + + else: # alpha is between 0 and 1 (exclusive) + + # Uses ALGORITHM GS of Statistical Computing - Kennedy & Gentle + + while True: + u = random() + b = (_e + alpha)/_e + p = b*u + if p <= 1.0: + x = pow(p, 1.0/alpha) + else: + # p > 1 + x = -_log((b-p)/alpha) + u1 = random() + if not (((p <= 1.0) and (u1 > _exp(-x))) or + ((p > 1) and (u1 > pow(x, alpha - 1.0)))): + break + return x * beta + + + def stdgamma(self, alpha, ainv, bbb, ccc): + # This method was (and shall remain) undocumented. + # This method is deprecated + # for the following reasons: + # 1. Returns same as .gammavariate(alpha, 1.0) + # 2. Requires caller to provide 3 extra arguments + # that are functions of alpha anyway + # 3. Can't be used for alpha < 0.5 + + # ainv = sqrt(2 * alpha - 1) + # bbb = alpha - log(4) + # ccc = alpha + ainv + import warnings + warnings.warn("The stdgamma function is deprecated; " + "use gammavariate() instead.", + DeprecationWarning, 2) + return self.gammavariate(alpha, 1.0) + + + +## -------------------- Gauss (faster alternative) -------------------- + + def gauss(self, mu, sigma): + """Gaussian distribution. + + mu is the mean, and sigma is the standard deviation. This is + slightly faster than the normalvariate() function. + + Not thread-safe without a lock around calls. + + """ + + # When x and y are two variables from [0, 1), uniformly + # distributed, then + # + # cos(2*pi*x)*sqrt(-2*log(1-y)) + # sin(2*pi*x)*sqrt(-2*log(1-y)) + # + # are two *independent* variables with normal distribution + # (mu = 0, sigma = 1). + # (Lambert Meertens) + # (corrected version; bug discovered by Mike Miller, fixed by LM) + + # Multithreading note: When two threads call this function + # simultaneously, it is possible that they will receive the + # same return value. The window is very small though. To + # avoid this, you have to use a lock around all calls. (I + # didn't want to slow this down in the serial case by using a + # lock here.) + + random = self.random + z = self.gauss_next + self.gauss_next = None + if z is None: + x2pi = random() * TWOPI + g2rad = _sqrt(-2.0 * _log(1.0 - random())) + z = _cos(x2pi) * g2rad + self.gauss_next = _sin(x2pi) * g2rad + + return mu + z*sigma + +## -------------------- beta -------------------- +## See +## http://sourceforge.net/bugs/?func=detailbug&bug_id=130030&group_id=5470 +## for Ivan Frohne's insightful analysis of why the original implementation: +## +## def betavariate(self, alpha, beta): +## # Discrete Event Simulation in C, pp 87-88. +## +## y = self.expovariate(alpha) +## z = self.expovariate(1.0/beta) +## return z/(y+z) +## +## was dead wrong, and how it probably got that way. + + def betavariate(self, alpha, beta): + """Beta distribution. + + Conditions on the parameters are alpha > -1 and beta} > -1. + Returned values range between 0 and 1. + + """ + + # This version due to Janne Sinkkonen, and matches all the std + # texts (e.g., Knuth Vol 2 Ed 3 pg 134 "the beta distribution"). + y = self.gammavariate(alpha, 1.) + if y == 0: + return 0.0 + else: + return y / (y + self.gammavariate(beta, 1.)) + +## -------------------- Pareto -------------------- + + def paretovariate(self, alpha): + """Pareto distribution. alpha is the shape parameter.""" + # Jain, pg. 495 + + u = 1.0 - self.random() + return 1.0 / pow(u, 1.0/alpha) + +## -------------------- Weibull -------------------- + + def weibullvariate(self, alpha, beta): + """Weibull distribution. + + alpha is the scale parameter and beta is the shape parameter. + + """ + # Jain, pg. 499; bug fix courtesy Bill Arms + + u = 1.0 - self.random() + return alpha * pow(-_log(u), 1.0/beta) + +## -------------------- Wichmann-Hill ------------------- + +class WichmannHill(Random): + + VERSION = 1 # used by getstate/setstate + + def seed(self, a=None): + """Initialize internal state from hashable object. + + None or no argument seeds from current time. + + If a is not None or an int or long, hash(a) is used instead. + + If a is an int or long, a is used directly. Distinct values between + 0 and 27814431486575L inclusive are guaranteed to yield distinct + internal states (this guarantee is specific to the default + Wichmann-Hill generator). + """ + + if a is None: + # Initialize from current time + import time + a = long(time.time() * 256) + + if not isinstance(a, (int, long)): + a = hash(a) + + a, x = divmod(a, 30268) + a, y = divmod(a, 30306) + a, z = divmod(a, 30322) + self._seed = int(x)+1, int(y)+1, int(z)+1 + + self.gauss_next = None + + def random(self): + """Get the next random number in the range [0.0, 1.0).""" + + # Wichman-Hill random number generator. + # + # Wichmann, B. A. & Hill, I. D. (1982) + # Algorithm AS 183: + # An efficient and portable pseudo-random number generator + # Applied Statistics 31 (1982) 188-190 + # + # see also: + # Correction to Algorithm AS 183 + # Applied Statistics 33 (1984) 123 + # + # McLeod, A. I. (1985) + # A remark on Algorithm AS 183 + # Applied Statistics 34 (1985),198-200 + + # This part is thread-unsafe: + # BEGIN CRITICAL SECTION + x, y, z = self._seed + x = (171 * x) % 30269 + y = (172 * y) % 30307 + z = (170 * z) % 30323 + self._seed = x, y, z + # END CRITICAL SECTION + + # Note: on a platform using IEEE-754 double arithmetic, this can + # never return 0.0 (asserted by Tim; proof too long for a comment). + return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0 + + def getstate(self): + """Return internal state; can be passed to setstate() later.""" + return self.VERSION, self._seed, self.gauss_next + + def setstate(self, state): + """Restore internal state from object returned by getstate().""" + version = state[0] + if version == 1: + version, self._seed, self.gauss_next = state + else: + raise ValueError("state with version %s passed to " + "Random.setstate() of version %s" % + (version, self.VERSION)) + + def jumpahead(self, n): + """Act as if n calls to random() were made, but quickly. + + n is an int, greater than or equal to 0. + + Example use: If you have 2 threads and know that each will + consume no more than a million random numbers, create two Random + objects r1 and r2, then do + r2.setstate(r1.getstate()) + r2.jumpahead(1000000) + Then r1 and r2 will use guaranteed-disjoint segments of the full + period. + """ + + if not n >= 0: + raise ValueError("n must be >= 0") + x, y, z = self._seed + x = int(x * pow(171, n, 30269)) % 30269 + y = int(y * pow(172, n, 30307)) % 30307 + z = int(z * pow(170, n, 30323)) % 30323 + self._seed = x, y, z + + def __whseed(self, x=0, y=0, z=0): + """Set the Wichmann-Hill seed from (x, y, z). + + These must be integers in the range [0, 256). + """ + + if not type(x) == type(y) == type(z) == int: + raise TypeError('seeds must be integers') + if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256): + raise ValueError('seeds must be in range(0, 256)') + if 0 == x == y == z: + # Initialize from current time + import time + t = long(time.time() * 256) + t = int((t&0xffffff) ^ (t>>24)) + t, x = divmod(t, 256) + t, y = divmod(t, 256) + t, z = divmod(t, 256) + # Zero is a poor seed, so substitute 1 + self._seed = (x or 1, y or 1, z or 1) + + self.gauss_next = None + + def whseed(self, a=None): + """Seed from hashable object's hash code. + + None or no argument seeds from current time. It is not guaranteed + that objects with distinct hash codes lead to distinct internal + states. + + This is obsolete, provided for compatibility with the seed routine + used prior to Python 2.1. Use the .seed() method instead. + """ + + if a is None: + self.__whseed() + return + a = hash(a) + a, x = divmod(a, 256) + a, y = divmod(a, 256) + a, z = divmod(a, 256) + x = (x + a) % 256 or 1 + y = (y + a) % 256 or 1 + z = (z + a) % 256 or 1 + self.__whseed(x, y, z) + +## -------------------- test program -------------------- + +def _test_generator(n, funccall): + import time + print n, 'times', funccall + code = compile(funccall, funccall, 'eval') + total = 0.0 + sqsum = 0.0 + smallest = 1e10 + largest = -1e10 + t0 = time.time() + for i in range(n): + x = eval(code) + total += x + sqsum = sqsum + x*x + smallest = min(x, smallest) + largest = max(x, largest) + t1 = time.time() + print round(t1-t0, 3), 'sec,', + avg = total/n + stddev = _sqrt(sqsum/n - avg*avg) + print 'avg %g, stddev %g, min %g, max %g' % \ + (avg, stddev, smallest, largest) + + +def _test(N=2000): + _test_generator(N, 'random()') + _test_generator(N, 'normalvariate(0.0, 1.0)') + _test_generator(N, 'lognormvariate(0.0, 1.0)') + _test_generator(N, 'cunifvariate(0.0, 1.0)') + _test_generator(N, 'vonmisesvariate(0.0, 1.0)') + _test_generator(N, 'gammavariate(0.01, 1.0)') + _test_generator(N, 'gammavariate(0.1, 1.0)') + _test_generator(N, 'gammavariate(0.1, 2.0)') + _test_generator(N, 'gammavariate(0.5, 1.0)') + _test_generator(N, 'gammavariate(0.9, 1.0)') + _test_generator(N, 'gammavariate(1.0, 1.0)') + _test_generator(N, 'gammavariate(2.0, 1.0)') + _test_generator(N, 'gammavariate(20.0, 1.0)') + _test_generator(N, 'gammavariate(200.0, 1.0)') + _test_generator(N, 'gauss(0.0, 1.0)') + _test_generator(N, 'betavariate(3.0, 3.0)') + +# Create one instance, seeded from current time, and export its methods +# as module-level functions. The functions share state across all uses +#(both in the user's code and in the Python libraries), but that's fine +# for most programs and is easier for the casual user than making them +# instantiate their own Random() instance. + +_inst = Random() +seed = _inst.seed +random = _inst.random +uniform = _inst.uniform +randint = _inst.randint +choice = _inst.choice +randrange = _inst.randrange +sample = _inst.sample +shuffle = _inst.shuffle +normalvariate = _inst.normalvariate +lognormvariate = _inst.lognormvariate +cunifvariate = _inst.cunifvariate +expovariate = _inst.expovariate +vonmisesvariate = _inst.vonmisesvariate +gammavariate = _inst.gammavariate +stdgamma = _inst.stdgamma +gauss = _inst.gauss +betavariate = _inst.betavariate +paretovariate = _inst.paretovariate +weibullvariate = _inst.weibullvariate +getstate = _inst.getstate +setstate = _inst.setstate +jumpahead = _inst.jumpahead + +if __name__ == '__main__': + _test() Modified: branches/asm/src/org/python/modules/sre/SRE_STATE.java =================================================================== --- branches/asm/src/org/python/modules/sre/SRE_STATE.java 2008-06-02 00:25:36 UTC (rev 4498) +++ branches/asm/src/org/python/modules/sre/SRE_STATE.java 2008-06-02 01:03:08 UTC (rev 4499) @@ -31,7 +31,7 @@ print '%s = %s;' % (' '.join(segs[:-1]), segs[-1]) */ //BEGIN generated code - public static final int SRE_MAGIC = 20030419; + public static final int SRE_MAGIC = 20031017; public static final int SRE_OP_FAILURE = 0; public static final int SRE_OP_SUCCESS = 1; public static final int SRE_OP_ANY = 2; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-06-02 19:46:26
|
Revision: 4511 http://jython.svn.sourceforge.net/jython/?rev=4511&view=rev Author: fwierzbicki Date: 2008-06-02 12:46:25 -0700 (Mon, 02 Jun 2008) Log Message: ----------- Merged revisions 4488-4489,4491-4492,4495,4497,4502-4503,4505-4509 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4488 | pjenvey | 2008-05-30 01:50:34 -0400 (Fri, 30 May 2008) | 1 line invoke regrtest via the new dist/bin/jython script ........ r4489 | pjenvey | 2008-05-30 01:54:28 -0400 (Fri, 30 May 2008) | 3 lines add a subprocess resource that's skipped by default (test_subprocess and a few tests in test_chdir), because they take a long time ........ r4491 | pjenvey | 2008-05-30 14:31:03 -0400 (Fri, 30 May 2008) | 2 lines merge r4441 from branches/Release_2_2maint/jython ........ r4492 | pjenvey | 2008-05-30 14:34:13 -0400 (Fri, 30 May 2008) | 3 lines still not pure bourne shell compatible: we die on line 90 during substring extraction. so use bash and fix aliases not being expanded in bash ........ r4495 | amak | 2008-06-01 20:02:17 -0400 (Sun, 01 Jun 2008) | 1 line Merging changes from Release 2.2 branch, including new option support and some test refactoring. ........ r4497 | amak | 2008-06-01 20:12:57 -0400 (Sun, 01 Jun 2008) | 1 line Submitted in an incomplete merge in the last checkin; fixing this now. ........ r4502 | pjenvey | 2008-06-01 23:18:56 -0400 (Sun, 01 Jun 2008) | 2 lines add unicode __getitem/slice__ to fix a couple test_unicode failures, make str's versions final ........ r4503 | pjenvey | 2008-06-01 23:20:23 -0400 (Sun, 01 Jun 2008) | 1 line re-enable tests broken by #1758276 which was a while ago ........ r4505 | fwierzbicki | 2008-06-02 13:37:04 -0400 (Mon, 02 Jun 2008) | 2 lines Fix start position for (Expr (Call)) ........ r4506 | fwierzbicki | 2008-06-02 13:54:29 -0400 (Mon, 02 Jun 2008) | 2 lines Improved Line/Col info for parens. ........ r4507 | fwierzbicki | 2008-06-02 14:03:33 -0400 (Mon, 02 Jun 2008) | 2 lines Adjust line/col info for elif. ........ r4508 | fwierzbicki | 2008-06-02 14:26:07 -0400 (Mon, 02 Jun 2008) | 2 lines Adjust line/col info for unary ops. ........ r4509 | fwierzbicki | 2008-06-02 14:40:37 -0400 (Mon, 02 Jun 2008) | 2 lines dump astview output for a directory tree. ........ Modified Paths: -------------- branches/asm/Lib/socket.py branches/asm/Lib/test/regrtest.py branches/asm/Lib/test/test_bool.py branches/asm/Lib/test/test_chdir.py branches/asm/Lib/test/test_richcmp.py branches/asm/Lib/test/test_socket.py branches/asm/Lib/test/test_subprocess.py branches/asm/Lib/test/test_zlib.py branches/asm/Lib/zlib.py branches/asm/build.xml branches/asm/grammar/Python.g branches/asm/grammar/PythonWalker.g branches/asm/src/org/python/core/PyString.java branches/asm/src/org/python/core/PyUnicode.java branches/asm/src/shell/jython Added Paths: ----------- branches/asm/ast/astdump.py Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4486 + /trunk/jython:1-4509 Modified: branches/asm/Lib/socket.py =================================================================== --- branches/asm/Lib/socket.py 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/Lib/socket.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -12,6 +12,7 @@ AMAK: 20050527: added socket timeouts AMAK: 20070515: Added non-blocking (asynchronous) support AMAK: 20070515: Added client-side SSL support +AMAK: 20080513: Added support for options """ _defaulttimeout = None @@ -19,6 +20,7 @@ import errno import jarray import string +import struct import sys import threading import time @@ -145,6 +147,38 @@ SHUT_WR = 1 SHUT_RDWR = 2 +__all__ = [ 'AF_INET', 'SOCK_DGRAM', 'SOCK_RAW', + 'SOCK_RDM', 'SOCK_SEQPACKET', 'SOCK_STREAM', 'SOL_SOCKET', + 'SO_BROADCAST', 'SO_KEEPALIVE', 'SO_LINGER', 'SO_OOBINLINE', + 'SO_RCVBUF', 'SO_REUSEADDR', 'SO_SNDBUF', 'SO_TIMEOUT', 'TCP_NODELAY' + 'SocketType', 'error', 'herror', 'gaierror', 'timeout', + 'getfqdn', 'gethostbyaddr', 'gethostbyname', 'gethostname', + 'socket', 'getaddrinfo', 'getdefaulttimeout', 'setdefaulttimeout', + 'has_ipv6', 'htons', 'htonl', 'ntohs', 'ntohl', + 'SHUT_RD', 'SHUT_WR', 'SHUT_RDWR', + ] + +AF_INET = 2 + +SOCK_DGRAM = 1 +SOCK_STREAM = 2 +SOCK_RAW = 3 # not supported +SOCK_RDM = 4 # not supported +SOCK_SEQPACKET = 5 # not supported + +SOL_SOCKET = 0xFFFF + +SO_BROADCAST = 1 +SO_KEEPALIVE = 2 +SO_LINGER = 4 +SO_OOBINLINE = 8 +SO_RCVBUF = 16 +SO_REUSEADDR = 32 +SO_SNDBUF = 64 +SO_TIMEOUT = 128 + +TCP_NODELAY = 256 + class _nio_impl: timeout = None @@ -160,12 +194,6 @@ count = self.jchannel.write(bytebuf) return count - def _setreuseaddress(self, flag): - self.jsocket.setReuseAddress(flag) - - def _getreuseaddress(self, flag): - return self.jsocket.getReuseAddress() - def getpeername(self): return (self.jsocket.getInetAddress().getHostAddress(), self.jsocket.getPort() ) @@ -179,29 +207,32 @@ self._timeout_millis = int(timeout*1000) self.jsocket.setSoTimeout(self._timeout_millis) - def close1(self): - self.jsocket.close() + def getsockopt(self, option): + if self.options.has_key(option): + result = getattr(self.jsocket, "get%s" % self.options[option])() + if option == SO_LINGER: + if result == -1: + enabled, linger_time = 0, 0 + else: + enabled, linger_time = 1, result + return struct.pack('ii', enabled, linger_time) + return result + else: + raise error(errno.ENOPROTOOPT, "Option not supported on socket(%s): %d" % (str(self.jsocket), option)) - def close2(self): - self.jchannel.close() + def setsockopt(self, option, value): + if self.options.has_key(option): + if option == SO_LINGER: + values = struct.unpack('ii', value) + self.jsocket.setSoLinger(*values) + else: + getattr(self.jsocket, "set%s" % self.options[option])(value) + else: + raise error(errno.ENOPROTOOPT, "Option not supported on socket(%s): %d" % (str(self.jsocket), option)) - def close3(self): - if not self.jsocket.isClosed(): - self.jsocket.close() + def close(self): + self.jsocket.close() - def close4(self): - if not self.jsocket.isClosed(): - if hasattr(self.jsocket, 'shutdownInput') and not self.jsocket.isInputShutdown(): - self.jsocket.shutdownInput() - if hasattr(self.jsocket, 'shutdownOutput') and not self.jsocket.isOutputShutdown(): - self.jsocket.shutdownOutput() - self.jsocket.close() - - close = close1 -# close = close2 -# close = close3 -# close = close4 - def shutdownInput(self): try: self.jsocket.shutdownInput() @@ -222,6 +253,17 @@ class _client_socket_impl(_nio_impl): + options = { + SO_KEEPALIVE: 'KeepAlive', + SO_LINGER: 'SoLinger', + SO_OOBINLINE: 'OOBInline', + SO_RCVBUF: 'ReceiveBufferSize', + SO_REUSEADDR: 'ReuseAddress', + SO_SNDBUF: 'SendBufferSize', + SO_TIMEOUT: 'SoTimeout', + TCP_NODELAY: 'TcpNoDelay', + } + def __init__(self, socket=None): if socket: self.jchannel = socket.getChannel() @@ -234,7 +276,8 @@ self.jsocket = self.jchannel.socket() self.socketio = org.python.core.io.SocketIO(self.jchannel, 'rw') - def bind(self, host, port): + def bind(self, host, port, reuse_addr): + self.jsocket.setReuseAddress(reuse_addr) self.jsocket.bind(java.net.InetSocketAddress(host, port)) def connect(self, host, port): @@ -250,6 +293,12 @@ class _server_socket_impl(_nio_impl): + options = { + SO_RCVBUF: 'ReceiveBufferSize', + SO_REUSEADDR: 'ReuseAddress', + SO_TIMEOUT: 'SoTimeout', + } + def __init__(self, host, port, backlog, reuse_addr): self.jchannel = java.nio.channels.ServerSocketChannel.open() self.jsocket = self.jchannel.socket() @@ -257,7 +306,7 @@ bindaddr = java.net.InetSocketAddress(host, port) else: bindaddr = java.net.InetSocketAddress(port) - self._setreuseaddress(reuse_addr) + self.jsocket.setReuseAddress(reuse_addr) self.jsocket.bind(bindaddr, backlog) self.socketio = org.python.core.io.ServerSocketIO(self.jchannel, 'rw') @@ -275,6 +324,14 @@ class _datagram_socket_impl(_nio_impl): + options = { + SO_BROADCAST: 'Broadcast', + SO_RCVBUF: 'ReceiveBufferSize', + SO_REUSEADDR: 'ReuseAddress', + SO_SNDBUF: 'SendBufferSize', + SO_TIMEOUT: 'SoTimeout', + } + def __init__(self, port=None, address=None, reuse_addr=0): self.jchannel = java.nio.channels.DatagramChannel.open() self.jsocket = self.jchannel.socket() @@ -283,8 +340,8 @@ local_address = java.net.InetSocketAddress(address, port) else: local_address = java.net.InetSocketAddress(port) + self.jsocket.setReuseAddress(reuse_addr) self.jsocket.bind(local_address) - self._setreuseaddress(reuse_addr) self.socketio = org.python.core.io.DatagramSocketIO(self.jchannel, 'rw') def connect(self, host, port): @@ -350,9 +407,9 @@ byte_array = jarray.zeros(num_bytes, 'b') byte_buf = java.nio.ByteBuffer.wrap(byte_array) source_address = self.jchannel.receive(byte_buf) - byte_buf.flip() ; bytes_read = byte_buf.remaining() if source_address is None and not self.jchannel.isBlocking(): raise would_block_error() + byte_buf.flip() ; bytes_read = byte_buf.remaining() if bytes_read < num_bytes: byte_array = byte_array[:bytes_read] return_data = byte_array.tostring() @@ -373,25 +430,6 @@ else: return self._do_receive_nio(0, num_bytes, flags) -__all__ = [ 'AF_INET', 'SO_REUSEADDR', 'SOCK_DGRAM', 'SOCK_RAW', - 'SOCK_RDM', 'SOCK_SEQPACKET', 'SOCK_STREAM', 'SOL_SOCKET', - 'SocketType', 'error', 'herror', 'gaierror', 'timeout', - 'getfqdn', 'gethostbyaddr', 'gethostbyname', 'gethostname', - 'socket', 'getaddrinfo', 'getdefaulttimeout', 'setdefaulttimeout', - 'has_ipv6', 'htons', 'htonl', 'ntohs', 'ntohl', - 'SHUT_RD', 'SHUT_WR', 'SHUT_RDWR', - ] - -AF_INET = 2 - -SOCK_DGRAM = 1 -SOCK_STREAM = 2 -SOCK_RAW = 3 # not supported -SOCK_RDM = 4 # not supported -SOCK_SEQPACKET = 5 # not supported -SOL_SOCKET = 0xFFFF -SO_REUSEADDR = 4 - def _gethostbyaddr(name): # This is as close as I can get; at least the types are correct... addresses = java.net.InetAddress.getAllByName(gethostbyname(name)) @@ -500,6 +538,11 @@ reference_count = 0 close_lock = threading.Lock() + def __init__(self): + self.pending_options = { + SO_REUSEADDR: 0, + } + def gettimeout(self): return self.timeout @@ -525,9 +568,33 @@ def getblocking(self): return self.mode == MODE_BLOCKING + def setsockopt(self, level, optname, value): + if level != SOL_SOCKET: return + try: + if self.sock_impl: + self.sock_impl.setsockopt(optname, value) + else: + self.pending_options[optname] = value + except java.lang.Exception, jlx: + raise _map_exception(jlx) + + def getsockopt(self, level, optname): + if level != SOL_SOCKET: return + try: + if self.sock_impl: + return self.sock_impl.getsockopt(optname) + else: + return self.pending_options.get(optname, None) + except java.lang.Exception, jlx: + raise _map_exception(jlx) + def _config(self): assert self.mode in _permitted_modes - if self.sock_impl: self.sock_impl.config(self.mode, self.timeout) + if self.sock_impl: + self.sock_impl.config(self.mode, self.timeout) + for k in self.pending_options.keys(): + if k != SO_REUSEADDR: + self.sock_impl.setsockopt(k, self.pending_options[k]) def getchannel(self): if not self.sock_impl: @@ -557,8 +624,10 @@ ostream = None local_addr = None server = 0 - reuse_addr = 0 + def __init__(self): + _nonblocking_api_mixin.__init__(self) + def bind(self, addr): assert not self.sock_impl assert not self.local_addr @@ -575,7 +644,7 @@ host, port = self.local_addr else: host, port = "", 0 - self.sock_impl = _server_socket_impl(host, port, backlog, self.reuse_addr) + self.sock_impl = _server_socket_impl(host, port, backlog, self.pending_options[SO_REUSEADDR]) self._config() except java.lang.Exception, jlx: raise _map_exception(jlx) @@ -590,7 +659,7 @@ if not new_sock: raise would_block_error() cliconn = _tcpsocket() - cliconn.reuse_addr = new_sock.jsocket.getReuseAddress() + cliconn.pending_options[SO_REUSEADDR] = new_sock.jsocket.getReuseAddress() cliconn.sock_impl = new_sock cliconn._setup() return cliconn, new_sock.getpeername() @@ -608,10 +677,9 @@ assert not self.sock_impl host, port = self._get_host_port(addr) self.sock_impl = _client_socket_impl() - self.sock_impl._setreuseaddress(self.reuse_addr) if self.local_addr: # Has the socket been bound to a local address? bind_host, bind_port = self.local_addr - self.sock_impl.bind(bind_host, bind_port) + self.sock_impl.bind(bind_host, bind_port, self.pending_options[SO_REUSEADDR]) self._config() # Configure timeouts, etc, now that the socket exists self.sock_impl.connect(host, port) except java.lang.Exception, jlx: @@ -694,15 +762,7 @@ return (host, port) except java.lang.Exception, jlx: raise _map_exception(jlx) - - def setsockopt(self, level, optname, value): - if optname == SO_REUSEADDR: - self.reuse_addr = value - def getsockopt(self, level, optname): - if optname == SO_REUSEADDR: - return self.reuse_addr - def shutdown(self, how): assert how in (SHUT_RD, SHUT_WR, SHUT_RDWR) assert self.sock_impl @@ -725,17 +785,18 @@ class _udpsocket(_nonblocking_api_mixin): + sock_impl = None + addr = None + def __init__(self): - self.sock_impl = None - self.addr = None - self.reuse_addr = 0 + _nonblocking_api_mixin.__init__(self) def bind(self, addr): try: assert not self.sock_impl host, port = _unpack_address_tuple(addr) host_address = java.net.InetAddress.getByName(host) - self.sock_impl = _datagram_socket_impl(port, host_address, reuse_addr = self.reuse_addr) + self.sock_impl = _datagram_socket_impl(port, host_address, self.pending_options[SO_REUSEADDR]) self._config() except java.lang.Exception, jlx: raise _map_exception(jlx) @@ -803,6 +864,7 @@ raise _map_exception(jlx) def recv(self, num_bytes, flags=None): + if not self.sock_impl: raise error(errno.ENOTCONN, "Socket is not connected") try: return self.sock_impl.recv(num_bytes, flags) except java.lang.Exception, jlx: @@ -836,23 +898,6 @@ except java.lang.Exception, jlx: raise _map_exception(jlx) - def setsockopt(self, level, optname, value): - try: - if optname == SO_REUSEADDR: - self.reuse_addr = value -# self.sock._setreuseaddress(value) - except java.lang.Exception, jlx: - raise _map_exception(jlx) - - def getsockopt(self, level, optname): - try: - if optname == SO_REUSEADDR: - return self.sock_impl._getreuseaddress() - else: - return None - except java.lang.Exception, jlx: - raise _map_exception(jlx) - _socketmethods = ( 'bind', 'connect', 'connect_ex', 'fileno', 'listen', 'getpeername', 'getsockname', 'getsockopt', 'setsockopt', Modified: branches/asm/Lib/test/regrtest.py =================================================================== --- branches/asm/Lib/test/regrtest.py 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/Lib/test/regrtest.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -44,6 +44,9 @@ network - It is okay to run tests that use external network resource, e.g. testing SSL support for sockets. + subprocess Run tests that invoke subprocesses, in particular + test_subprocess. + To enable all resources except one, use '-uall,-<resource>'. For example, to run all the tests except for the network tests, give the option '-uall,-network'. @@ -179,7 +182,7 @@ -RESOURCE_NAMES = ['curses', 'largefile', 'network'] +RESOURCE_NAMES = ['curses', 'largefile', 'network', 'subprocess'] def usage(code, msg=''): Modified: branches/asm/Lib/test/test_bool.py =================================================================== --- branches/asm/Lib/test/test_bool.py 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/Lib/test/test_bool.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -340,10 +340,6 @@ return self check(Baz()) -# Jython transition 2.3 -# boolean attribute returns int not bool -# http://jython.org/bugs/1758276 -del BoolTest.test_fileclosed # StackOverflow if __nonzero__ returns self # http://jython.org/bugs/1758318 del BoolTest.test_convert_to_bool Modified: branches/asm/Lib/test/test_chdir.py =================================================================== --- branches/asm/Lib/test/test_chdir.py 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/Lib/test/test_chdir.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -685,7 +685,6 @@ ImportPackageTestCase, ZipimportTestCase, PyCompileTestCase, - SubprocessTestCase, ExecfileTestCase, ExecfileTracebackTestCase, ListdirTestCase, @@ -694,6 +693,8 @@ if sys.platform.startswith('java'): tests.extend((ImportJavaClassTestCase, ImportJarTestCase)) + if test_support.is_resource_enabled('subprocess'): + tests.append(SubprocessTestCase) if WINDOWS: tests.append(WindowsChdirTestCase) test_support.run_unittest(*tests) Modified: branches/asm/Lib/test/test_richcmp.py =================================================================== --- branches/asm/Lib/test/test_richcmp.py 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/Lib/test/test_richcmp.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -351,11 +351,6 @@ for op in opmap["lt"]: self.assertIs(op(x, y), True) -# Jython transition 2.3 -# x = [42] -# x < x returns 0 but it should return False -# http://jython.org/bugs/1758276 -del ListTest.test_coverage # A circular implementation of __eq__ returns False instead of True # http://jython.org/bugs/1758280 del MiscTest.test_recursion2 Modified: branches/asm/Lib/test/test_socket.py =================================================================== --- branches/asm/Lib/test/test_socket.py 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/Lib/test/test_socket.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -8,12 +8,13 @@ import test_support import errno +import Queue +import select import socket -import select +import struct +import sys import time import thread, threading -import Queue -import sys from weakref import proxy from StringIO import StringIO @@ -493,6 +494,148 @@ sock.close() self.assertRaises(socket.error, sock.send, "spam") +class TestSocketOptions(unittest.TestCase): + + def setUp(self): + self.test_udp = self.test_tcp_client = self.test_tcp_server = 0 + + def _testSetAndGetOption(self, sock, option, values): + for expected_value in values: + sock.setsockopt(socket.SOL_SOCKET, option, expected_value) + retrieved_value = sock.getsockopt(socket.SOL_SOCKET, option) + self.failUnlessEqual(retrieved_value, expected_value, \ + "Retrieved option(%s) value %s != %s(value set)" % (option, retrieved_value, expected_value)) + + def _testUDPOption(self, option, values): + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self._testSetAndGetOption(sock, option, values) + # now bind the socket i.e. cause the implementation socket to be created + sock.bind( (HOST, PORT) ) + self.failUnlessEqual(sock.getsockopt(socket.SOL_SOCKET, option), values[-1], \ + "Option value '%s'='%s' did not propagate to implementation socket" % (option, values[-1]) ) + self._testSetAndGetOption(sock, option, values) + finally: + sock.close() + + def _testTCPClientOption(self, option, values): + try: + # First listen on a server socket, so that the connection won't be refused. + server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_sock.bind( (HOST, PORT) ) + server_sock.listen() + # Now do the tests + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._testSetAndGetOption(sock, option, values) + # now connect the socket i.e. cause the implementation socket to be created + # First bind, so that the SO_REUSEADDR setting propagates + sock.bind( (HOST, PORT+1) ) + sock.connect( (HOST, PORT) ) + self.failUnlessEqual(sock.getsockopt(socket.SOL_SOCKET, option), values[-1], \ + "Option value '%s'='%s' did not propagate to implementation socket" % (option, values[-1])) + self._testSetAndGetOption(sock, option, values) + finally: + server_sock.close() + sock.close() + + def _testTCPServerOption(self, option, values): + try: + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._testSetAndGetOption(sock, option, values) + # now bind and listen on the socket i.e. cause the implementation socket to be created + sock.bind( (HOST, PORT) ) + sock.listen() + self.failUnlessEqual(sock.getsockopt(socket.SOL_SOCKET, option), values[-1], \ + "Option value '%s'='%s' did not propagate to implementation socket" % (option, values[-1])) + self._testSetAndGetOption(sock, option, values) + finally: + sock.close() + + def _testOption(self, option, values): + for flag, func in [ + (self.test_udp, self._testUDPOption), + (self.test_tcp_server, self._testTCPServerOption), + (self.test_tcp_client, self._testTCPClientOption), + ]: + if flag: + func(option, values) + else: + try: + func(option, values) + except socket.error, se: + self.failUnlessEqual(se[0], errno.ENOPROTOOPT, "Wrong errno from unsupported option exception: %d" % se[0]) + except Exception, x: + self.fail("Wrong exception raised from unsupported option: %s" % str(x)) + else: + self.fail("Setting unsupported option should have raised an exception") + + def testSO_BROADCAST(self): + self.test_udp = 1 ; + self._testOption(socket.SO_BROADCAST, [0, 1]) + + def testSO_KEEPALIVE(self): + self.test_tcp_client = 1 + self._testOption(socket.SO_KEEPALIVE, [0, 1]) + + def testSO_LINGER(self): + self.test_tcp_client = 1 + off = struct.pack('ii', 0, 0) + on_2_seconds = struct.pack('ii', 1, 2) + self._testOption(socket.SO_LINGER, [off, on_2_seconds]) + + def testSO_OOBINLINE(self): + self.test_tcp_client = 1 + self._testOption(socket.SO_OOBINLINE, [0, 1]) + + def testSO_RCVBUF(self): + self.test_udp = 1 + self.test_tcp_client = 1 + self.test_tcp_server = 1 + self._testOption(socket.SO_RCVBUF, [1024, 4096, 16384]) + + def testSO_REUSEADDR(self): + self.test_udp = 1 + self.test_tcp_client = 1 + self.test_tcp_server = 1 + self._testOption(socket.SO_REUSEADDR, [0, 1]) + + def testSO_SNDBUF(self): + self.test_udp = 1 + self.test_tcp_client = 1 + self._testOption(socket.SO_SNDBUF, [1024, 4096, 16384]) + + def testSO_TIMEOUT(self): + self.test_udp = 1 + self.test_tcp_client = 1 + self.test_tcp_server = 1 + self._testOption(socket.SO_TIMEOUT, [0, 1, 1000]) + + def testTCP_NODELAY(self): + self.test_tcp_client = 1 + self._testOption(socket.TCP_NODELAY, [0, 1]) + +class AsYetUnsupportedOptions: + + def testSO_ACCEPTCONN(self): pass + def testSO_DEBUG(self): pass + def testSO_DONTROUTE(self): pass + def testSO_ERROR(self): pass + def testSO_EXCLUSIVEADDRUSE(self): + # this is an MS specific option that will not be appearing on java + # http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6421091 + # http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6402335 + pass + def testSO_RCVLOWAT(self): pass + def testSO_RCVTIMEO(self): pass + def testSO_REUSEPORT(self): + # not yet supported on java + # http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6432031 + pass + def testSO_SNDLOWAT(self): pass + def testSO_SNDTIMEO(self): pass + def testSO_TYPE(self): pass + def testSO_USELOOPBACK(self): pass + class BasicTCPTest(SocketConnectedTest): def __init__(self, methodName='runTest'): @@ -678,6 +821,7 @@ self.assertEqual(msg, MSG) class NonBlockingTCPServerTests(SocketTCPTest): + def testSetBlocking(self): # Testing whether set blocking works self.serv.setblocking(0) @@ -705,7 +849,6 @@ pass else: self.fail("Error trying to do non-blocking accept.") - class NonBlockingTCPTests(ThreadedTCPSocketTest): @@ -1071,6 +1214,7 @@ self.fail("accept() returned success when we did not expect it") class TCPClientTimeoutTest(unittest.TestCase): + def testClientTimeout(self): cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) cli.settimeout(0.1) @@ -1124,10 +1268,7 @@ self.assert_(issubclass(socket.gaierror, socket.error)) self.assert_(issubclass(socket.timeout, socket.error)) -class TestJythonExceptions(unittest.TestCase): - def setUp(self): - self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +class TestJythonExceptionsShared: def tearDown(self): self.s.close() @@ -1141,33 +1282,6 @@ except Exception, x: self.fail("Get host name for non-existent host raised wrong exception: %s" % x) - def testConnectionRefused(self): - try: - # This port should not be open at this time - self.s.connect( (HOST, PORT) ) - except socket.error, se: - self.failUnlessEqual(se[0], errno.ECONNREFUSED) - except Exception, x: - self.fail("Connection to non-existent host/port raised wrong exception: %s" % x) - else: - self.fail("Socket (%s,%s) should not have been listening at this time" % (HOST, PORT)) - - def testBindException(self): - # First bind to the target port - self.s.bind( (HOST, PORT) ) - self.s.listen() - try: - # And then try to bind again - t = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - t.bind( (HOST, PORT) ) - t.listen() - except socket.error, se: - self.failUnlessEqual(se[0], errno.EADDRINUSE) - except Exception, x: - self.fail("Binding to already bound host/port raised wrong exception: %s" % x) - else: - self.fail("Binding to already bound host/port should have raised exception") - def testUnresolvedAddress(self): try: self.s.connect( ('non.existent.server', PORT) ) @@ -1187,14 +1301,16 @@ self.fail("Send on unconnected socket raised wrong exception: %s" % x) else: self.fail("Send on unconnected socket raised exception") + + def testSocketNotBound(self): try: result = self.s.recv(1024) except socket.error, se: self.failUnlessEqual(se[0], errno.ENOTCONN) except Exception, x: - self.fail("Receive on unconnected socket raised wrong exception: %s" % x) + self.fail("Receive on unbound socket raised wrong exception: %s" % x) else: - self.fail("Receive on unconnected socket raised exception") + self.fail("Receive on unbound socket raised exception") def testClosedSocket(self): self.s.close() @@ -1216,6 +1332,59 @@ except socket.error, se: self.failUnlessEqual(se[0], errno.EBADF) +class TestJythonTCPExceptions(TestJythonExceptionsShared, unittest.TestCase): + + def setUp(self): + self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + def testConnectionRefused(self): + try: + # This port should not be open at this time + self.s.connect( (HOST, PORT) ) + except socket.error, se: + self.failUnlessEqual(se[0], errno.ECONNREFUSED) + except Exception, x: + self.fail("Connection to non-existent host/port raised wrong exception: %s" % x) + else: + self.fail("Socket (%s,%s) should not have been listening at this time" % (HOST, PORT)) + + def testBindException(self): + # First bind to the target port + self.s.bind( (HOST, PORT) ) + self.s.listen() + try: + # And then try to bind again + t = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + t.bind( (HOST, PORT) ) + t.listen() + except socket.error, se: + self.failUnlessEqual(se[0], errno.EADDRINUSE) + except Exception, x: + self.fail("Binding to already bound host/port raised wrong exception: %s" % x) + else: + self.fail("Binding to already bound host/port should have raised exception") + +class TestJythonUDPExceptions(TestJythonExceptionsShared, unittest.TestCase): + + def setUp(self): + self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + def testBindException(self): + # First bind to the target port + self.s.bind( (HOST, PORT) ) + try: + # And then try to bind again + t = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + t.bind( (HOST, PORT) ) + except socket.error, se: + self.failUnlessEqual(se[0], errno.EADDRINUSE) + except Exception, x: + self.fail("Binding to already bound host/port raised wrong exception: %s" % x) + else: + self.fail("Binding to already bound host/port should have raised exception") + class TestAddressParameters: def testBindNonTupleEndpointRaisesTypeError(self): @@ -1255,6 +1424,7 @@ def test_main(): tests = [ GeneralModuleTests, + TestSocketOptions, BasicTCPTest, TCPTimeoutTest, TCPClientTimeoutTest, @@ -1277,7 +1447,8 @@ if hasattr(socket, "socketpair"): tests.append(BasicSocketPairTest) if sys.platform[:4] == 'java': - tests.append(TestJythonExceptions) + tests.append(TestJythonTCPExceptions) + tests.append(TestJythonUDPExceptions) suites = [unittest.makeSuite(klass, 'test') for klass in tests] test_support.run_suite(unittest.TestSuite(suites)) Modified: branches/asm/Lib/test/test_subprocess.py =================================================================== --- branches/asm/Lib/test/test_subprocess.py 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/Lib/test/test_subprocess.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -410,14 +410,12 @@ def test_no_leaking(self): # Make sure we leak no resources if not hasattr(test_support, "is_resource_enabled") \ - or test_support.is_resource_enabled("subprocess") and \ - not mswindows: - # 1026 is too much for most UNIX systems - max_handles = jython and 65 or 1026 - elif jython: - # Spawning java processes takes a long time - return + or test_support.is_resource_enabled("subprocess") and not mswindows \ + and not jython: + max_handles = 1026 # too much for most UNIX systems else: + # Settle for 65 on jython: spawning jython processes takes a + # long time max_handles = 65 for i in range(max_handles): p = subprocess.Popen([sys.executable, "-c", @@ -702,6 +700,8 @@ def test_main(): + # Spawning many new jython processes takes a long time + test_support.requires('subprocess') test_support.run_unittest(ProcessTestCase) if hasattr(test_support, "reap_children"): test_support.reap_children() Modified: branches/asm/Lib/test/test_zlib.py =================================================================== --- branches/asm/Lib/test/test_zlib.py 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/Lib/test/test_zlib.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -40,6 +40,11 @@ self.assertEqual(zlib.adler32("", 1), 1) ##self.assertEqual(zlib.adler32("", 432), 432) + def test_adler32_non7bit(self): + # Introduced on jython to test non-7-bit strings + self.assertEqual(zlib.adler32("\x80", 1), 8454273) + self.assertEqual(zlib.adler32("\x3b3", 1), 11206767) + def assertEqual32(self, seen, expected): # 32-bit values masked -- checksums on 32- vs 64- bit machines # This is important if bit 31 (0x08000000L) is set. Modified: branches/asm/Lib/zlib.py =================================================================== --- branches/asm/Lib/zlib.py 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/Lib/zlib.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -27,11 +27,11 @@ Z_FINISH = 4 _valid_flush_modes = (Z_FINISH,) -def adler32(string, value=1): +def adler32(s, value=1): if value != 1: raise ValueError, "adler32 only support start value of 1" checksum = Adler32() - checksum.update(String.getBytes(string)) + checksum.update(String.getBytes(s, 'iso-8859-1')) return Long(checksum.getValue()).intValue() def crc32(string, value=0): Copied: branches/asm/ast/astdump.py (from rev 4509, trunk/jython/ast/astdump.py) =================================================================== --- branches/asm/ast/astdump.py (rev 0) +++ branches/asm/ast/astdump.py 2008-06-02 19:46:25 UTC (rev 4511) @@ -0,0 +1,64 @@ +#!/usr/bin/env python +import os +import globwalk +import astview + +def makepath(path): + """ + from ho...@tr... 2002/03/18 + See: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/117243 + """ + + from os import makedirs + from os.path import normpath,dirname,exists,abspath + + dpath = normpath(dirname(path)) + if not exists(dpath): makedirs(dpath) + return normpath(abspath(path)) + +def main(code_path, output_dir, testfile=False): + if os.path.exists(output_dir): + print "%s already exists, exiting" % output_dir + sys.exit(1) + os.mkdir(output_dir) + if testfile: + pyfiles = [f.rstrip() for f in file(code_path)] + elif os.path.isdir(code_path): + pyfiles = globwalk.GlobDirectoryWalker(code_path, "*.py") + else: + pyfiles = [code_path] + + for pyfile in pyfiles: + print "%s to %s" % (pyfile, output_dir) + import pprint + fh = open(makepath(os.path.join(output_dir, pyfile)), 'w') + pprint.pprint(astview.tree(pyfile), fh) + +if __name__ == '__main__': + import sys + import getopt + + usage = """\ +Usage: python %s [-t] code_path output_dir + output_dir must not exist (it will be created) + unless -t is specified, if codepath is a file test it, if codepath is a directory + test all .py files in and below that directory. +""" % sys.argv[0] + + testfile = False + try: + opts, args = getopt.getopt(sys.argv[1:], 'th') + except: + print usage + sys.exit(1) + for o, v in opts: + if o == '-h': + print usage + sys.exit(0) + if o == '-t': + testfile = True + if len(args) < 2 or len(args) > 3: + print usage + sys.exit(1) + + main(args[0], args[1], testfile) Modified: branches/asm/build.xml =================================================================== --- branches/asm/build.xml 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/build.xml 2008-06-02 19:46:25 UTC (rev 4511) @@ -687,13 +687,11 @@ </junit> </target> <target name="regrtest" depends="compile,expose,copy-lib"> - <java classname="org.python.util.jython" fork="true"> - <jvmarg value="-Dpython.home=${dist.dir}"/> - <arg value="${dist.dir}/Lib/test/regrtest.py"/> - <!-- Only run the tests that are expected to work on Jython --> - <arg value="--expected"/> - <classpath refid="test.classpath" /> - </java> + <exec executable="${dist.dir}/bin/jython"> + <arg value="${dist.dir}/Lib/test/regrtest.py"/> + <!-- Only run the tests that are expected to work on Jython --> + <arg value="--expected"/> + </exec> </target> <!-- run bugtests, create a config if necessary --> Modified: branches/asm/grammar/Python.g =================================================================== --- branches/asm/grammar/Python.g 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/grammar/Python.g 2008-06-02 19:46:25 UTC (rev 4511) @@ -705,9 +705,9 @@ ; //factor: ('+'|'-'|'~') factor | power -factor : PLUS factor -> ^(UAdd factor) - | MINUS factor -> ^(USub factor) - | TILDE factor -> ^(Invert factor) +factor : PLUS factor -> ^(UAdd PLUS factor) + | MINUS factor -> ^(USub MINUS factor) + | TILDE factor -> ^(Invert TILDE factor) | power ; @@ -721,8 +721,8 @@ // '`' testlist1 '`' | // NAME | NUMBER | STRING+) atom : LPAREN - ( yield_expr -> ^(Parens yield_expr) - | testlist_gexp {debug("parsed testlist_gexp");} -> ^(Parens testlist_gexp) + ( yield_expr -> ^(Parens LPAREN yield_expr) + | testlist_gexp {debug("parsed testlist_gexp");} -> ^(Parens LPAREN testlist_gexp) | -> ^(Tuple) ) RPAREN Modified: branches/asm/grammar/PythonWalker.g =================================================================== --- branches/asm/grammar/PythonWalker.g 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/grammar/PythonWalker.g 2008-06-02 19:46:25 UTC (rev 4511) @@ -480,14 +480,14 @@ } ; -dotted_attr returns [exprType etype, PythonTree begin] +dotted_attr returns [exprType etype, PythonTree marker] : NAME { $etype = new Name($NAME, $NAME.text, expr_contextType.Load); - $begin = $NAME; + $marker = $NAME; debug("matched NAME in dotted_attr");} | ^(DOT n1=dotted_attr n2=dotted_attr) { - $etype = new Attribute($n1.begin, $n1.etype, $n2.text, expr_contextType.Load); - $begin = $n1.begin; + $etype = new Attribute($n1.marker, $n1.etype, $n2.text, expr_contextType.Load); + $marker = $n1.marker; } ; @@ -530,10 +530,10 @@ expr_stmt : test[expr_contextType.Load] { debug("matched expr_stmt:test " + $test.etype); - $stmts::statements.add(new Expr($test.begin, $test.etype)); + $stmts::statements.add(new Expr($test.marker, $test.etype)); } | ^(augassign targ=test[expr_contextType.AugStore] value=test[expr_contextType.Load]) { - AugAssign a = new AugAssign($targ.begin, $targ.etype, $augassign.op, $value.etype); + AugAssign a = new AugAssign($targ.marker, $targ.etype, $augassign.op, $value.etype); $stmts::statements.add(a); } | ^(Assign targets ^(Value value=test[expr_contextType.Load])) { @@ -548,17 +548,17 @@ } ; -call_expr returns [exprType etype] +call_expr returns [exprType etype, PythonTree marker] : ^(Call (^(Args arglist))? test[expr_contextType.Load]) { Call c; if ($Args == null) { - c = new Call($Call, $test.etype, new exprType[0], new keywordType[0], null, null); + c = new Call($test.marker, $test.etype, new exprType[0], new keywordType[0], null, null); debug("Matched Call site no args"); } else { debug("Matched Call w/ args"); exprType[] args = (exprType[])$arglist.args.toArray(new exprType[$arglist.args.size()]); keywordType[] keywords = (keywordType[])$arglist.keywords.toArray(new keywordType[$arglist.keywords.size()]); - c = new Call($test.begin, $test.etype, args, keywords, $arglist.starargs, $arglist.kwargs); + c = new Call($test.marker, $test.etype, args, keywords, $arglist.starargs, $arglist.kwargs); } $etype = c; } @@ -874,7 +874,7 @@ stmtType[] b = (stmtType[])$stmts.stypes.toArray(new stmtType[$stmts.stypes.size()]); //the stmtType[0] is intended to be replaced in the iterator of the if_stmt rule. //there is probably a better way to do this. - elifs.add(new If($Elif, $test.etype, b, new stmtType[0])); + elifs.add(new If($test.etype, $test.etype, b, new stmtType[0])); } ; @@ -954,7 +954,7 @@ } ; -test[expr_contextType ctype] returns [exprType etype, PythonTree begin, boolean parens] +test[expr_contextType ctype] returns [exprType etype, PythonTree marker, boolean parens] : ^(AND left=test[ctype] right=test[ctype]) { List values = new ArrayList(); boolean leftIsAnd = false; @@ -994,8 +994,8 @@ e[1] = $right.etype; } //XXX: could re-use BoolOps discarded above in many cases. - $etype = new BoolOp($left.begin, boolopType.And, e); - $begin = $left.begin; + $etype = new BoolOp($left.marker, boolopType.And, e); + $marker = $left.marker; } | ^(OR left=test[ctype] right=test[ctype]) { //XXX: AND and OR could be factored into one method. @@ -1037,8 +1037,8 @@ e[1] = $right.etype; } //XXX: could re-use BoolOps discarded above in many cases. - $etype = new BoolOp($left.begin, boolopType.Or, e); - $begin = $left.begin; + $etype = new BoolOp($left.marker, boolopType.Or, e); + $marker = $left.marker; } | ^(comp_op left=test[ctype] targs=test[ctype]) { exprType[] comparators; @@ -1061,8 +1061,8 @@ comparators[0] = $targs.etype; val = $left.etype; } - $etype = new Compare($left.begin, val, ops, comparators); - $begin = $left.begin; + $etype = new Compare($left.marker, val, ops, comparators); + $marker = $left.marker; debug("COMP_OP: " + $comp_op.start + ":::" + $etype + ":::" + $parens); } | atom[ctype] { @@ -1070,28 +1070,30 @@ debug("***" + $atom.etype); $parens = $atom.parens; $etype = $atom.etype; - $begin = $atom.begin; + $marker = $atom.marker; } | ^(binop left=test[ctype] right=test[ctype]) { debug("BinOp matched"); - $etype = new BinOp($left.begin, left.etype, $binop.op, right.etype); - $begin = $left.begin; + //XXX: BinOp's line/col info in CPython is subtle -- sometimes left.marker is correct + // as I have it here, but sometimes $binop.start is more correct. + $etype = new BinOp($left.marker, left.etype, $binop.op, right.etype); + $marker = $left.marker; } | call_expr { $etype = $call_expr.etype; - $begin = $call_expr.start; + $marker = $call_expr.etype; } | lambdef { $etype = $lambdef.etype; - $begin = $lambdef.start; + $marker = $lambdef.start; } | ^(IfExp ^(Test t1=test[ctype]) ^(Body t2=test[ctype]) ^(OrElse t3=test[ctype])) { $etype = new IfExp($IfExp, $t1.etype, $t2.etype, $t3.etype); - $begin = $IfExp; + $marker = $IfExp; } | yield_expr { $etype = $yield_expr.etype; - $begin = $yield_expr.start; + $marker = $yield_expr.start; } ; @@ -1128,7 +1130,7 @@ } ; -atom[expr_contextType ctype] returns [exprType etype, PythonTree begin, boolean parens] +atom[expr_contextType ctype] returns [exprType etype, PythonTree marker, boolean parens] : ^(Tuple (^(Elts elts[ctype]))?) { debug("matched Tuple"); exprType[] e; @@ -1138,11 +1140,11 @@ e = new exprType[0]; } $etype = new Tuple($Tuple, e, ctype); - $begin = $Tuple; + $marker = $Tuple; } | comprehension[ctype] { $etype = $comprehension.etype; - $begin = $comprehension.begin; + $marker = $comprehension.marker; } | ^(Dict LCURLY (^(Elts elts[ctype]))?) { exprType[] keys; @@ -1160,22 +1162,22 @@ values = new exprType[0]; } $etype = new Dict($LCURLY, keys, values); - $begin = $LCURLY; + $marker = $LCURLY; } | ^(Repr BACKQUOTE test[ctype]*) { $etype = new Repr($BACKQUOTE, $test.etype); - $begin = $BACKQUOTE; + $marker = $BACKQUOTE; } | ^(Name NAME) { debug("matched Name " + $NAME.text); $etype = new Name($NAME, $NAME.text, ctype); - $begin = $NAME; + $marker = $NAME; } | ^(DOT NAME test[expr_contextType.Load]) { debug("matched DOT in atom: " + $test.etype + "###" + $NAME.text); - $etype = new Attribute($test.begin, $test.etype, $NAME.text, ctype); - $begin = $test.begin; + $etype = new Attribute($test.marker, $test.etype, $NAME.text, ctype); + $marker = $test.marker; } | ^(SubscriptList subscriptlist test[expr_contextType.Load]) { //XXX: only handling one subscript for now. @@ -1205,62 +1207,62 @@ s = new ExtSlice($SubscriptList, st); } } - $etype = new Subscript($test.begin, $test.etype, s, ctype); - $begin = $test.begin; + $etype = new Subscript($test.marker, $test.etype, s, ctype); + $marker = $test.marker; } | ^(Num INT) { $etype = makeInt($INT); - $begin = $INT; + $marker = $INT; debug("makeInt output: " + $etype); } | ^(Num LONGINT) { $etype = makeInt($LONGINT); - $begin = $LONGINT; + $marker = $LONGINT; } | ^(Num FLOAT) { $etype = makeFloat($FLOAT); debug("float matched" + $etype); - $begin = $FLOAT; + $marker = $FLOAT; } | ^(Num COMPLEX) { $etype = makeComplex($COMPLEX); - $begin = $COMPLEX; + $marker = $COMPLEX; } | stringlist { StringPair sp = extractStrings($stringlist.strings); if (sp.isUnicode()) { - $etype = new Unicode($stringlist.begin, sp.getString()); + $etype = new Unicode($stringlist.marker, sp.getString()); } else { - $etype = new Str($stringlist.begin, sp.getString()); + $etype = new Str($stringlist.marker, sp.getString()); } - $begin = $stringlist.begin; + $marker = $stringlist.marker; } - | ^(USub test[ctype]) { + | ^(USub tok=MINUS test[ctype]) { debug("USub matched " + $test.etype); - $etype = negate($USub, $test.etype); - $begin = $USub; + $etype = negate($tok, $test.etype); + $marker = $tok; } - | ^(UAdd test[ctype]) { - $etype = new UnaryOp($UAdd, unaryopType.UAdd, $test.etype); - $begin = $UAdd; + | ^(UAdd tok=PLUS test[ctype]) { + $etype = new UnaryOp($tok, unaryopType.UAdd, $test.etype); + $marker = $tok; } - | ^(Invert test[ctype]) { - $etype = new UnaryOp($Invert, unaryopType.Invert, $test.etype); - $begin = $Invert; + | ^(Invert tok=TILDE test[ctype]) { + $etype = new UnaryOp($tok, unaryopType.Invert, $test.etype); + $marker = $tok; } | ^(NOT test[ctype]) { $etype = new UnaryOp($NOT, unaryopType.Not, $test.etype); - $begin = $NOT; + $marker = $NOT; } - | ^(Parens test[ctype]) { + | ^(Parens tok=LPAREN test[ctype]) { debug("PARENS! " + $test.etype); $parens = true; $etype = $test.etype; - $begin = $Parens; + $marker = $tok; } ; -comprehension[expr_contextType ctype] returns [exprType etype, PythonTree begin] +comprehension[expr_contextType ctype] returns [exprType etype, PythonTree marker] @init { List gens = new ArrayList(); } @@ -1274,14 +1276,14 @@ e = new exprType[0]; } $etype = new org.python.antlr.ast.List($LBRACK, e, ctype); - $begin = $LBRACK; + $marker = $LBRACK; }) | (^(ListComp test[ctype] list_for[gens]) { debug("matched ListComp"); Collections.reverse(gens); comprehensionType[] c = (comprehensionType[])gens.toArray(new comprehensionType[gens.size()]); - $etype = new ListComp($test.begin, $test.etype, c); - $begin = $LBRACK; + $etype = new ListComp($test.marker, $test.etype, c); + $marker = $LBRACK; } ) ) @@ -1290,16 +1292,16 @@ debug("matched GeneratorExp"); Collections.reverse(gens); comprehensionType[] c = (comprehensionType[])gens.toArray(new comprehensionType[gens.size()]); - $etype = new GeneratorExp($test.begin, $test.etype, c); - $begin = $GeneratorExp; + $etype = new GeneratorExp($test.marker, $test.etype, c); + $marker = $GeneratorExp; } ; -stringlist returns [PythonTree begin, List strings] +stringlist returns [PythonTree marker, List strings] @init { List strs = new ArrayList(); } - : ^(Str string[strs]+) {$strings = strs; $begin = $string.start;} + : ^(Str string[strs]+) {$strings = strs; $marker = $string.start;} ; string[List strs] Modified: branches/asm/src/org/python/core/PyString.java =================================================================== --- branches/asm/src/org/python/core/PyString.java 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/src/org/python/core/PyString.java 2008-06-02 19:46:25 UTC (rev 4511) @@ -461,12 +461,12 @@ } @ExposedMethod - public PyObject str___getitem__(PyObject index) { + final PyObject str___getitem__(PyObject index) { return seq___finditem__(index); } @ExposedMethod(defaults = "null") - public PyObject str___getslice__(PyObject start, PyObject stop, PyObject step) { + final PyObject str___getslice__(PyObject start, PyObject stop, PyObject step) { return seq___getslice__(start, stop, step); } Modified: branches/asm/src/org/python/core/PyUnicode.java =================================================================== --- branches/asm/src/org/python/core/PyUnicode.java 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/src/org/python/core/PyUnicode.java 2008-06-02 19:46:25 UTC (rev 4511) @@ -127,6 +127,16 @@ return new PyString("u" + encode_UnicodeEscape(string, true)); } + @ExposedMethod + final PyObject unicode___getitem__(PyObject index) { + return seq___finditem__(index); + } + + @ExposedMethod(defaults = "null") + final PyObject unicode___getslice__(PyObject start, PyObject stop, PyObject step) { + return seq___getslice__(start, stop, step); + } + @ExposedMethod(type = MethodType.CMP) final int unicode___cmp__(PyObject other) { return str___cmp__(other); Modified: branches/asm/src/shell/jython =================================================================== --- branches/asm/src/shell/jython 2008-06-02 19:46:09 UTC (rev 4510) +++ branches/asm/src/shell/jython 2008-06-02 19:46:25 UTC (rev 4511) @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # ----------------------------------------------------------------------------- # jython.sh - start script for Jython (adapted from jruby.sh) # @@ -169,18 +169,15 @@ if [ -n "$profile_requested" ] ; then echo "Running with instrumented profiler" - alias runjava="$JAVA_CMD" java_args=("${java_args[@]}" -classpath "$CP$CP_SEPARATOR$CLASSPATH") else if [ -z $help_requested ] ; then - alias runjava="exec $JAVA_CMD" - else - alias runjava="$JAVA_CMD" + JAVA_CMD="exec $JAVA_CMD" fi java_args=("${java_args[@]}" -Xbootclasspath/a:"$CP" -classpath "$CLASSPATH") fi -runjava $JAVA_OPTS "${java_args[@]}" -Dpython.home="$JYTHON_HOME" \ +$JAVA_CMD $JAVA_OPTS "${java_args[@]}" -Dpython.home="$JYTHON_HOME" \ -Dpython.executable="$PRG" org.python.util.jython $JYTHON_OPTS "$@" if [ -n "$profile_requested" ] ; then This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2008-06-02 20:00:42
|
Revision: 4512 http://jython.svn.sourceforge.net/jython/?rev=4512&view=rev Author: fwierzbicki Date: 2008-06-02 13:00:41 -0700 (Mon, 02 Jun 2008) Log Message: ----------- Merged revisions 4510 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4510 | fwierzbicki | 2008-06-02 15:46:09 -0400 (Mon, 02 Jun 2008) | 3 lines Switching to antlr 3.1b in prep for moving to automatic AST shaping in PythonWalker.g instead of the current "by hand" approach. ........ Modified Paths: -------------- branches/asm/build.xml branches/asm/grammar/Python.g branches/asm/grammar/PythonPartial.g branches/asm/src/org/python/antlr/PythonTokenSource.java branches/asm/src/org/python/compiler/CodeCompiler.java Added Paths: ----------- branches/asm/extlibs/antlr-3.1b1.jar branches/asm/extlibs/antlr-runtime-3.1b1.jar Removed Paths: ------------- branches/asm/extlibs/antlr-3.0.1.jar branches/asm/extlibs/antlr-runtime-3.0.1.jar Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4509 + /trunk/jython:1-4511 Modified: branches/asm/build.xml =================================================================== --- branches/asm/build.xml 2008-06-02 19:46:25 UTC (rev 4511) +++ branches/asm/build.xml 2008-06-02 20:00:41 UTC (rev 4512) @@ -168,7 +168,10 @@ <pathelement path="${extlibs.dir}/mysql-connector-java-5.1.6.jar" /> <pathelement path="${extlibs.dir}/postgresql-8.3-603.jdbc4.jar" /> <pathelement path="${extlibs.dir}/antlr-2.7.7.jar" /> + <!-- <pathelement path="${extlibs.dir}/antlr-3.0.1.jar" /> + --> + <pathelement path="${extlibs.dir}/antlr-3.1b1.jar" /> <pathelement path="${extlibs.dir}/stringtemplate-3.1b1.jar" /> </path> Deleted: branches/asm/extlibs/antlr-3.0.1.jar =================================================================== (Binary files differ) Copied: branches/asm/extlibs/antlr-3.1b1.jar (from rev 4510, trunk/jython/extlibs/antlr-3.1b1.jar) =================================================================== (Binary files differ) Deleted: branches/asm/extlibs/antlr-runtime-3.0.1.jar =================================================================== (Binary files differ) Copied: branches/asm/extlibs/antlr-runtime-3.1b1.jar (from rev 4510, trunk/jython/extlibs/antlr-runtime-3.1b1.jar) =================================================================== (Binary files differ) Modified: branches/asm/grammar/Python.g =================================================================== --- branches/asm/grammar/Python.g 2008-06-02 19:46:25 UTC (rev 4511) +++ branches/asm/grammar/Python.g 2008-06-02 20:00:41 UTC (rev 4512) @@ -262,24 +262,24 @@ public Token nextToken() { while (true) { - token = null; - channel = Token.DEFAULT_CHANNEL; - tokenStartCharIndex = input.index(); - tokenStartCharPositionInLine = input.getCharPositionInLine(); - tokenStartLine = input.getLine(); - text = null; + state.token = null; + state.channel = Token.DEFAULT_CHANNEL; + state.tokenStartCharIndex = input.index(); + state.tokenStartCharPositionInLine = input.getCharPositionInLine(); + state.tokenStartLine = input.getLine(); + state.text = null; if ( input.LA(1)==CharStream.EOF ) { - return Token.EOF_TOKEN; - } - try { - mTokens(); - if ( token==null ) { + return Token.EOF_TOKEN; + } + try { + mTokens(); + if ( state.token==null ) { emit(); } - else if ( token==Token.SKIP_TOKEN ) { + else if ( state.token==Token.SKIP_TOKEN ) { continue; } - return token; + return state.token; } catch (RecognitionException re) { throw new ParseException(getErrorMessage(re, this.getTokenNames())); @@ -323,12 +323,15 @@ //funcdef: [decorators] 'def' NAME parameters ':' suite funcdef : decorators? 'def' NAME parameters COLON suite - -> ^(FunctionDef 'def' ^(Name NAME) ^(Arguments parameters) ^(Body suite) ^(Decorators decorators?)) + -> ^(FunctionDef 'def' ^(Name NAME) parameters ^(Body suite) ^(Decorators decorators?)) ; //parameters: '(' [varargslist] ')' -parameters : LPAREN (varargslist)? RPAREN - -> (varargslist)? +parameters : LPAREN + (varargslist -> ^(Arguments varargslist) + | -> ^(Arguments) + ) + RPAREN ; //varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME] | '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [','] @@ -1113,8 +1116,8 @@ emit(new ClassicToken(LEADING_WS,new String(indentation))); } // kill trailing newline if present and then ignore - ( ('\r')? '\n' {if (token!=null) token.setChannel(HIDDEN); else $channel=HIDDEN;})* - // {token.setChannel(99); } + ( ('\r')? '\n' {if (state.token!=null) state.token.setChannel(HIDDEN); else $channel=HIDDEN;})* + // {state.token.setChannel(99); } ) ; Modified: branches/asm/grammar/PythonPartial.g =================================================================== --- branches/asm/grammar/PythonPartial.g 2008-06-02 19:46:25 UTC (rev 4511) +++ branches/asm/grammar/PythonPartial.g 2008-06-02 20:00:41 UTC (rev 4512) @@ -105,31 +105,30 @@ public Token nextToken() { while (true) { - token = null; - channel = Token.DEFAULT_CHANNEL; - tokenStartCharIndex = input.index(); - tokenStartCharPositionInLine = input.getCharPositionInLine(); - tokenStartLine = input.getLine(); - text = null; + state.token = null; + state.channel = Token.DEFAULT_CHANNEL; + state.tokenStartCharIndex = input.index(); + state.tokenStartCharPositionInLine = input.getCharPositionInLine(); + state.tokenStartLine = input.getLine(); + state.text = null; if ( input.LA(1)==CharStream.EOF ) { - return Token.EOF_TOKEN; - } - try { - mTokens(); - if ( token==null ) { + return Token.EOF_TOKEN; + } + try { + mTokens(); + if ( state.token==null ) { emit(); } - else if ( token==Token.SKIP_TOKEN ) { + else if ( state.token==Token.SKIP_TOKEN ) { continue; } - return token; + return state.token; } catch (RecognitionException re) { throw new ParseException(getErrorMessage(re, this.getTokenNames())); } } } - } single_input : NEWLINE @@ -710,8 +709,8 @@ emit(new ClassicToken(LEADING_WS,new String(indentation))); } // kill trailing newline if present and then ignore - ( ('\r')? '\n' {if (token!=null) token.setChannel(HIDDEN); else $channel=HIDDEN;})* - // {token.setChannel(99); } + ( ('\r')? '\n' {if (state.token!=null) state.token.setChannel(HIDDEN); else $channel=HIDDEN;})* + // {state.token.setChannel(99); } ) ; Modified: branches/asm/src/org/python/antlr/PythonTokenSource.java =================================================================== --- branches/asm/src/org/python/antlr/PythonTokenSource.java 2008-06-02 19:46:25 UTC (rev 4511) +++ branches/asm/src/org/python/antlr/PythonTokenSource.java 2008-06-02 20:00:41 UTC (rev 4512) @@ -250,6 +250,11 @@ return buf.toString(); } + //FIXME: needed this for the Antlr 3.1b interface change. + public String getSourceName() { + return "XXX-need-real-name.py"; + } + } /* More example input / output pairs with code simplified to single chars Modified: branches/asm/src/org/python/compiler/CodeCompiler.java =================================================================== --- branches/asm/src/org/python/compiler/CodeCompiler.java 2008-06-02 19:46:25 UTC (rev 4511) +++ branches/asm/src/org/python/compiler/CodeCompiler.java 2008-06-02 20:00:41 UTC (rev 4512) @@ -404,7 +404,7 @@ scope.dump(); module.PyCode(new Suite(node, node.body), name, true, className, false, false, - node.startIndex, scope, cflags).get(code); + node.getTokenStartIndex(), scope, cflags).get(code); getDocString(node.body); @@ -1727,7 +1727,7 @@ scope.setup_closure(); scope.dump(); module.PyCode(retSuite, name, true, className, - false, false, node.startIndex, scope, cflags).get(code); + false, false, node.getTokenStartIndex(), scope, cflags).get(code); if (!makeClosure(scope)) { code.invokespecial("org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + ")V"); @@ -1773,7 +1773,7 @@ scope.dump(); //Make code object out of suite module.PyCode(new Suite(node, node.body), name, false, name, - true, false, node.startIndex, scope, cflags).get(code); + true, false, node.getTokenStartIndex(), scope, cflags).get(code); //Get doc string (if there) getDocString(node.body); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2008-06-03 03:35:48
|
Revision: 4521 http://jython.svn.sourceforge.net/jython/?rev=4521&view=rev Author: pjenvey Date: 2008-06-02 20:35:47 -0700 (Mon, 02 Jun 2008) Log Message: ----------- Merged revisions 4512-4520 via svnmerge from https://jython.svn.sourceforge.net/svnroot/jython/trunk/jython ........ r4513 | pjenvey | 2008-06-02 14:57:01 -0700 (Mon, 02 Jun 2008) | 1 line sort all test lists ........ r4514 | pjenvey | 2008-06-02 15:34:09 -0700 (Mon, 02 Jun 2008) | 3 lines o fix __reduce__ for PyDequeDeriveds o re-enable test_deque's usage of gc.collect now that we support it ........ r4515 | pjenvey | 2008-06-02 17:02:19 -0700 (Mon, 02 Jun 2008) | 1 line move _weakref into its own dir ........ r4516 | pjenvey | 2008-06-02 18:56:41 -0700 (Mon, 02 Jun 2008) | 2 lines fix isCallable to handle new style classes ........ r4517 | pjenvey | 2008-06-02 19:50:09 -0700 (Mon, 02 Jun 2008) | 5 lines from 2.5 lib: http://svn.python.org/projects/python/branches/release25-maint/Lib/weakref.py@45853 http://svn.python.org/projects/python/branches/release25-maint/Lib/test/test_weakref.py@53533 http://svn.python.org/projects/python/branches/release25-maint/Lib/test/mapping_tests.py@36025 ........ r4518 | pjenvey | 2008-06-02 20:23:59 -0700 (Mon, 02 Jun 2008) | 1 line make for_type public ........ r4519 | pjenvey | 2008-06-02 20:24:47 -0700 (Mon, 02 Jun 2008) | 6 lines o use the 2.5 weakref module o pull apart the _weakref types into their own class files, exposed with annotations o add more methods to ProxyType o use the builtin ReferenceError instead of _weakref's own ........ r4520 | pjenvey | 2008-06-02 20:33:29 -0700 (Mon, 02 Jun 2008) | 1 line revert mistaken commits in r4519 ........ Modified Paths: -------------- branches/asm/CoreExposed.includes branches/asm/Lib/test/regrtest.py branches/asm/Lib/test/test_deque.py branches/asm/src/org/python/core/PyInstance.java branches/asm/src/org/python/core/PyNewWrapper.java branches/asm/src/org/python/core/PyObject.java branches/asm/src/org/python/core/__builtin__.java branches/asm/src/org/python/modules/Setup.java branches/asm/src/org/python/modules/collections/PyDeque.java branches/asm/src/templates/mappings Added Paths: ----------- branches/asm/Lib/test/mapping_tests.py branches/asm/Lib/test/test_weakref.py branches/asm/Lib/weakref.py branches/asm/src/org/python/modules/_weakref/ branches/asm/src/org/python/modules/_weakref/AbstractReference.java branches/asm/src/org/python/modules/_weakref/CallableProxyType.java branches/asm/src/org/python/modules/_weakref/GlobalRef.java branches/asm/src/org/python/modules/_weakref/ProxyType.java branches/asm/src/org/python/modules/_weakref/ReferenceType.java branches/asm/src/org/python/modules/_weakref/ReferenceTypeDerived.java branches/asm/src/org/python/modules/_weakref/WeakrefModule.java branches/asm/src/templates/weakref.derived Removed Paths: ------------- branches/asm/src/org/python/modules/_weakref/AbstractReference.java branches/asm/src/org/python/modules/_weakref/CallableProxyType.java branches/asm/src/org/python/modules/_weakref/GlobalRef.java branches/asm/src/org/python/modules/_weakref/ProxyType.java branches/asm/src/org/python/modules/_weakref/ReferenceType.java branches/asm/src/org/python/modules/_weakref/ReferenceTypeDerived.java branches/asm/src/org/python/modules/_weakref/WeakrefModule.java branches/asm/src/org/python/modules/_weakref.java Property Changed: ---------------- branches/asm/ Property changes on: branches/asm ___________________________________________________________________ Name: svnmerge-integrated - /trunk/jython:1-4511 + /trunk/jython:1-4520 Modified: branches/asm/CoreExposed.includes =================================================================== --- branches/asm/CoreExposed.includes 2008-06-03 03:33:29 UTC (rev 4520) +++ branches/asm/CoreExposed.includes 2008-06-03 03:35:47 UTC (rev 4521) @@ -31,6 +31,9 @@ org/python/core/PyTuple.class org/python/core/PyType.class org/python/core/PyUnicode.class +org/python/modules/_weakref/CallableProxyType.class +org/python/modules/_weakref/ReferenceType.class +org/python/modules/_weakref/ProxyType.class org/python/modules/collections/PyDefaultDict.class org/python/modules/collections/PyDeque.class org/python/modules/random/PyRandom.class Copied: branches/asm/Lib/test/mapping_tests.py (from rev 4520, trunk/jython/Lib/test/mapping_tests.py) =================================================================== --- branches/asm/Lib/test/mapping_tests.py (rev 0) +++ branches/asm/Lib/test/mapping_tests.py 2008-06-03 03:35:47 UTC (rev 4521) @@ -0,0 +1,672 @@ +# tests common to dict and UserDict +import unittest +import UserDict + + +class BasicTestMappingProtocol(unittest.TestCase): + # This base class can be used to check that an object conforms to the + # mapping protocol + + # Functions that can be useful to override to adapt to dictionary + # semantics + type2test = None # which class is being tested (overwrite in subclasses) + + def _reference(self): + """Return a dictionary of values which are invariant by storage + in the object under test.""" + return {1:2, "key1":"value1", "key2":(1,2,3)} + def _empty_mapping(self): + """Return an empty mapping object""" + return self.type2test() + def _full_mapping(self, data): + """Return a mapping object with the value contained in data + dictionary""" + x = self._empty_mapping() + for key, value in data.items(): + x[key] = value + return x + + def __init__(self, *args, **kw): + unittest.TestCase.__init__(self, *args, **kw) + self.reference = self._reference().copy() + + # A (key, value) pair not in the mapping + key, value = self.reference.popitem() + self.other = {key:value} + + # A (key, value) pair in the mapping + key, value = self.reference.popitem() + self.inmapping = {key:value} + self.reference[key] = value + + def test_read(self): + # Test for read only operations on mapping + p = self._empty_mapping() + p1 = dict(p) #workaround for singleton objects + d = self._full_mapping(self.reference) + if d is p: + p = p1 + #Indexing + for key, value in self.reference.items(): + self.assertEqual(d[key], value) + knownkey = self.other.keys()[0] + self.failUnlessRaises(KeyError, lambda:d[knownkey]) + #len + self.assertEqual(len(p), 0) + self.assertEqual(len(d), len(self.reference)) + #has_key + for k in self.reference: + self.assert_(d.has_key(k)) + self.assert_(k in d) + for k in self.other: + self.failIf(d.has_key(k)) + self.failIf(k in d) + #cmp + self.assertEqual(cmp(p,p), 0) + self.assertEqual(cmp(d,d), 0) + self.assertEqual(cmp(p,d), -1) + self.assertEqual(cmp(d,p), 1) + #__non__zero__ + if p: self.fail("Empty mapping must compare to False") + if not d: self.fail("Full mapping must compare to True") + # keys(), items(), iterkeys() ... + def check_iterandlist(iter, lst, ref): + self.assert_(hasattr(iter, 'next')) + self.assert_(hasattr(iter, '__iter__')) + x = list(iter) + self.assert_(set(x)==set(lst)==set(ref)) + check_iterandlist(d.iterkeys(), d.keys(), self.reference.keys()) + check_iterandlist(iter(d), d.keys(), self.reference.keys()) + check_iterandlist(d.itervalues(), d.values(), self.reference.values()) + check_iterandlist(d.iteritems(), d.items(), self.reference.items()) + #get + key, value = d.iteritems().next() + knownkey, knownvalue = self.other.iteritems().next() + self.assertEqual(d.get(key, knownvalue), value) + self.assertEqual(d.get(knownkey, knownvalue), knownvalue) + self.failIf(knownkey in d) + + def test_write(self): + # Test for write operations on mapping + p = self._empty_mapping() + #Indexing + for key, value in self.reference.items(): + p[key] = value + self.assertEqual(p[key], value) + for key in self.reference.keys(): + del p[key] + self.failUnlessRaises(KeyError, lambda:p[key]) + p = self._empty_mapping() + #update + p.update(self.reference) + self.assertEqual(dict(p), self.reference) + items = p.items() + p = self._empty_mapping() + p.update(items) + self.assertEqual(dict(p), self.reference) + d = self._full_mapping(self.reference) + #setdefault + key, value = d.iteritems().next() + knownkey, knownvalue = self.other.iteritems().next() + self.assertEqual(d.setdefault(key, knownvalue), value) + self.assertEqual(d[key], value) + self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue) + self.assertEqual(d[knownkey], knownvalue) + #pop + self.assertEqual(d.pop(knownkey), knownvalue) + self.failIf(knownkey in d) + self.assertRaises(KeyError, d.pop, knownkey) + default = 909 + d[knownkey] = knownvalue + self.assertEqual(d.pop(knownkey, default), knownvalue) + self.failIf(knownkey in d) + self.assertEqual(d.pop(knownkey, default), default) + #popitem + key, value = d.popitem() + self.failIf(key in d) + self.assertEqual(value, self.reference[key]) + p=self._empty_mapping() + self.assertRaises(KeyError, p.popitem) + + def test_constructor(self): + self.assertEqual(self._empty_mapping(), self._empty_mapping()) + + def test_bool(self): + self.assert_(not self._empty_mapping()) + self.assert_(self.reference) + self.assert_(bool(self._empty_mapping()) is False) + self.assert_(bool(self.reference) is True) + + def test_keys(self): + d = self._empty_mapping() + self.assertEqual(d.keys(), []) + d = self.reference + self.assert_(self.inmapping.keys()[0] in d.keys()) + self.assert_(self.other.keys()[0] not in d.keys()) + self.assertRaises(TypeError, d.keys, None) + + def test_values(self): + d = self._empty_mapping() + self.assertEqual(d.values(), []) + + self.assertRaises(TypeError, d.values, None) + + def test_items(self): + d = self._empty_mapping() + self.assertEqual(d.items(), []) + + self.assertRaises(TypeError, d.items, None) + + def test_len(self): + d = self._empty_mapping() + self.assertEqual(len(d), 0) + + def test_getitem(self): + d = self.reference + self.assertEqual(d[self.inmapping.keys()[0]], self.inmapping.values()[0]) + + self.assertRaises(TypeError, d.__getitem__) + + def test_update(self): + # mapping argument + d = self._empty_mapping() + d.update(self.other) + self.assertEqual(d.items(), self.other.items()) + + # No argument + d = self._empty_mapping() + d.update() + self.assertEqual(d, self._empty_mapping()) + + # item sequence + d = self._empty_mapping() + d.update(self.other.items()) + self.assertEqual(d.items(), self.other.items()) + + # Iterator + d = self._empty_mapping() + d.update(self.other.iteritems()) + self.assertEqual(d.items(), self.other.items()) + + # FIXME: Doesn't work with UserDict + # self.assertRaises((TypeError, AttributeError), d.update, None) + self.assertRaises((TypeError, AttributeError), d.update, 42) + + outerself = self + class SimpleUserDict: + def __init__(self): + self.d = outerself.reference + def keys(self): + return self.d.keys() + def __getitem__(self, i): + return self.d[i] + d.clear() + d.update(SimpleUserDict()) + i1 = d.items() + i2 = self.reference.items() + i1.sort() + i2.sort() + self.assertEqual(i1, i2) + + class Exc(Exception): pass + + d = self._empty_mapping() + class FailingUserDict: + def keys(self): + raise Exc + self.assertRaises(Exc, d.update, FailingUserDict()) + + d.clear() + + class FailingUserDict: + def keys(self): + class BogonIter: + def __init__(self): + self.i = 1 + def __iter__(self): + return self + def next(self): + if self.i: + self.i = 0 + return 'a' + raise Exc + return BogonIter() + def __getitem__(self, key): + return key + self.assertRaises(Exc, d.update, FailingUserDict()) + + class FailingUserDict: + def keys(self): + class BogonIter: + def __init__(self): + self.i = ord('a') + def __iter__(self): + return self + def next(self): + if self.i <= ord('z'): + rtn = chr(self.i) + self.i += 1 + return rtn + raise StopIteration + return BogonIter() + def __getitem__(self, key): + raise Exc + self.assertRaises(Exc, d.update, FailingUserDict()) + + d = self._empty_mapping() + class badseq(object): + def __iter__(self): + return self + def next(self): + raise Exc() + + self.assertRaises(Exc, d.update, badseq()) + + self.assertRaises(ValueError, d.update, [(1, 2, 3)]) + + # no test_fromkeys or test_copy as both os.environ and selves don't support it + + def test_get(self): + d = self._empty_mapping() + self.assert_(d.get(self.other.keys()[0]) is None) + self.assertEqual(d.get(self.other.keys()[0], 3), 3) + d = self.reference + self.assert_(d.get(self.other.keys()[0]) is None) + self.assertEqual(d.get(self.other.keys()[0], 3), 3) + self.assertEqual(d.get(self.inmapping.keys()[0]), self.inmapping.values()[0]) + self.assertEqual(d.get(self.inmapping.keys()[0], 3), self.inmapping.values()[0]) + self.assertRaises(TypeError, d.get) + self.assertRaises(TypeError, d.get, None, None, None) + + def test_setdefault(self): + d = self._empty_mapping() + self.assertRaises(TypeError, d.setdefault) + + def test_popitem(self): + d = self._empty_mapping() + self.assertRaises(KeyError, d.popitem) + self.assertRaises(TypeError, d.popitem, 42) + + def test_pop(self): + d = self._empty_mapping() + k, v = self.inmapping.items()[0] + d[k] = v + self.assertRaises(KeyError, d.pop, self.other.keys()[0]) + + self.assertEqual(d.pop(k), v) + self.assertEqual(len(d), 0) + + self.assertRaises(KeyError, d.pop, k) + + +class TestMappingProtocol(BasicTestMappingProtocol): + def test_constructor(self): + BasicTestMappingProtocol.test_constructor(self) + self.assert_(self._empty_mapping() is not self._empty_mapping()) + self.assertEqual(self.type2test(x=1, y=2), {"x": 1, "y": 2}) + + def test_bool(self): + BasicTestMappingProtocol.test_bool(self) + self.assert_(not self._empty_mapping()) + self.assert_(self._full_mapping({"x": "y"})) + self.assert_(bool(self._empty_mapping()) is False) + self.assert_(bool(self._full_mapping({"x": "y"})) is True) + + def test_keys(self): + BasicTestMappingProtocol.test_keys(self) + d = self._empty_mapping() + self.assertEqual(d.keys(), []) + d = self._full_mapping({'a': 1, 'b': 2}) + k = d.keys() + self.assert_('a' in k) + self.assert_('b' in k) + self.assert_('c' not in k) + + def test_values(self): + BasicTestMappingProtocol.test_values(self) + d = self._full_mapping({1:2}) + self.assertEqual(d.values(), [2]) + + def test_items(self): + BasicTestMappingProtocol.test_items(self) + + d = self._full_mapping({1:2}) + self.assertEqual(d.items(), [(1, 2)]) + + def test_has_key(self): + d = self._empty_mapping() + self.assert_(not d.has_key('a')) + d = self._full_mapping({'a': 1, 'b': 2}) + k = d.keys() + k.sort() + self.assertEqual(k, ['a', 'b']) + + self.assertRaises(TypeError, d.has_key) + + def test_contains(self): + d = self._empty_mapping() + self.assert_(not ('a' in d)) + self.assert_('a' not in d) + d = self._full_mapping({'a': 1, 'b': 2}) + self.assert_('a' in d) + self.assert_('b' in d) + self.assert_('c' not in d) + + self.assertRaises(TypeError, d.__contains__) + + def test_len(self): + BasicTestMappingProtocol.test_len(self) + d = self._full_mapping({'a': 1, 'b': 2}) + self.assertEqual(len(d), 2) + + def test_getitem(self): + BasicTestMappingProtocol.test_getitem(self) + d = self._full_mapping({'a': 1, 'b': 2}) + self.assertEqual(d['a'], 1) + self.assertEqual(d['b'], 2) + d['c'] = 3 + d['a'] = 4 + self.assertEqual(d['c'], 3) + self.assertEqual(d['a'], 4) + del d['b'] + self.assertEqual(d, {'a': 4, 'c': 3}) + + self.assertRaises(TypeError, d.__getitem__) + + def test_clear(self): + d = self._full_mapping({1:1, 2:2, 3:3}) + d.clear() + self.assertEqual(d, {}) + + self.assertRaises(TypeError, d.clear, None) + + def test_update(self): + BasicTestMappingProtocol.test_update(self) + # mapping argument + d = self._empty_mapping() + d.update({1:100}) + d.update({2:20}) + d.update({1:1, 2:2, 3:3}) + self.assertEqual(d, {1:1, 2:2, 3:3}) + + # no argument + d.update() + self.assertEqual(d, {1:1, 2:2, 3:3}) + + # keyword arguments + d = self._empty_mapping() + d.update(x=100) + d.update(y=20) + d.update(x=1, y=2, z=3) + self.assertEqual(d, {"x":1, "y":2, "z":3}) + + # item sequence + d = self._empty_mapping() + d.update([("x", 100), ("y", 20)]) + self.assertEqual(d, {"x":100, "y":20}) + + # Both item sequence and keyword arguments + d = self._empty_mapping() + d.update([("x", 100), ("y", 20)], x=1, y=2) + self.assertEqual(d, {"x":1, "y":2}) + + # iterator + d = self._full_mapping({1:3, 2:4}) + d.update(self._full_mapping({1:2, 3:4, 5:6}).iteritems()) + self.assertEqual(d, {1:2, 2:4, 3:4, 5:6}) + + class SimpleUserDict: + def __init__(self): + self.d = {1:1, 2:2, 3:3} + def keys(self): + return self.d.keys() + def __getitem__(self, i): + return self.d[i] + d.clear() + d.update(SimpleUserDict()) + self.assertEqual(d, {1:1, 2:2, 3:3}) + + def test_fromkeys(self): + self.assertEqual(self.type2test.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) + d = self._empty_mapping() + self.assert_(not(d.fromkeys('abc') is d)) + self.assertEqual(d.fromkeys('abc'), {'a':None, 'b':None, 'c':None}) + self.assertEqual(d.fromkeys((4,5),0), {4:0, 5:0}) + self.assertEqual(d.fromkeys([]), {}) + def g(): + yield 1 + self.assertEqual(d.fromkeys(g()), {1:None}) + self.assertRaises(TypeError, {}.fromkeys, 3) + class dictlike(self.type2test): pass + self.assertEqual(dictlike.fromkeys('a'), {'a':None}) + self.assertEqual(dictlike().fromkeys('a'), {'a':None}) + self.assert_(dictlike.fromkeys('a').__class__ is dictlike) + self.assert_(dictlike().fromkeys('a').__class__ is dictlike) + # FIXME: the following won't work with UserDict, because it's an old style class + # self.assert_(type(dictlike.fromkeys('a')) is dictlike) + class mydict(self.type2test): + def __new__(cls): + return UserDict.UserDict() + ud = mydict.fromkeys('ab') + self.assertEqual(ud, {'a':None, 'b':None}) + # FIXME: the following won't work with UserDict, because it's an old style class + # self.assert_(isinstance(ud, UserDict.UserDict)) + self.assertRaises(TypeError, dict.fromkeys) + + class Exc(Exception): pass + + class baddict1(self.type2test): + def __init__(self): + raise Exc() + + self.assertRaises(Exc, baddict1.fromkeys, [1]) + + class BadSeq(object): + def __iter__(self): + return self + def next(self): + raise Exc() + + self.assertRaises(Exc, self.type2test.fromkeys, BadSeq()) + + class baddict2(self.type2test): + def __setitem__(self, key, value): + raise Exc() + + self.assertRaises(Exc, baddict2.fromkeys, [1]) + + def test_copy(self): + d = self._full_mapping({1:1, 2:2, 3:3}) + self.assertEqual(d.copy(), {1:1, 2:2, 3:3}) + d = self._empty_mapping() + self.assertEqual(d.copy(), d) + self.assert_(isinstance(d.copy(), d.__class__)) + self.assertRaises(TypeError, d.copy, None) + + def test_get(self): + BasicTestMappingProtocol.test_get(self) + d = self._empty_mapping() + self.assert_(d.get('c') is None) + self.assertEqual(d.get('c', 3), 3) + d = self._full_mapping({'a' : 1, 'b' : 2}) + self.assert_(d.get('c') is None) + self.assertEqual(d.get('c', 3), 3) + self.assertEqual(d.get('a'), 1) + self.assertEqual(d.get('a', 3), 1) + + def test_setdefault(self): + BasicTestMappingProtocol.test_setdefault(self) + d = self._empty_mapping() + self.assert_(d.setdefault('key0') is None) + d.setdefault('key0', []) + self.assert_(d.setdefault('key0') is None) + d.setdefault('key', []).append(3) + self.assertEqual(d['key'][0], 3) + d.setdefault('key', []).append(4) + self.assertEqual(len(d['key']), 2) + + def test_popitem(self): + BasicTestMappingProtocol.test_popitem(self) + for copymode in -1, +1: + # -1: b has same structure as a + # +1: b is a.copy() + for log2size in range(12): + size = 2**log2size + a = self._empty_mapping() + b = self._empty_mapping() + for i in range(size): + a[repr(i)] = i + if copymode < 0: + b[repr(i)] = i + if copymode > 0: + b = a.copy() + for i in range(size): + ka, va = ta = a.popitem() + self.assertEqual(va, int(ka)) + kb, vb = tb = b.popitem() + self.assertEqual(vb, int(kb)) + self.assert_(not(copymode < 0 and ta != tb)) + self.assert_(not a) + self.assert_(not b) + + def test_pop(self): + BasicTestMappingProtocol.test_pop(self) + + # Tests for pop with specified key + d = self._empty_mapping() + k, v = 'abc', 'def' + + # verify longs/ints get same value when key > 32 bits (for 64-bit archs) + # see SF bug #689659 + x = 4503599627370496L + y = 4503599627370496 + h = self._full_mapping({x: 'anything', y: 'something else'}) + self.assertEqual(h[x], h[y]) + + self.assertEqual(d.pop(k, v), v) + d[k] = v + self.assertEqual(d.pop(k, 1), v) + + +class TestHashMappingProtocol(TestMappingProtocol): + + def test_getitem(self): + TestMappingProtocol.test_getitem(self) + class Exc(Exception): pass + + class BadEq(object): + def __eq__(self, other): + raise Exc() + + d = self._empty_mapping() + d[BadEq()] = 42 + self.assertRaises(KeyError, d.__getitem__, 23) + + class BadHash(object): + fail = False + def __hash__(self): + if self.fail: + raise Exc() + else: + return 42 + + d = self._empty_mapping() + x = BadHash() + d[x] = 42 + x.fail = True + self.assertRaises(Exc, d.__getitem__, x) + + def test_fromkeys(self): + TestMappingProtocol.test_fromkeys(self) + class mydict(self.type2test): + def __new__(cls): + return UserDict.UserDict() + ud = mydict.fromkeys('ab') + self.assertEqual(ud, {'a':None, 'b':None}) + self.assert_(isinstance(ud, UserDict.UserDict)) + + def test_pop(self): + TestMappingProtocol.test_pop(self) + + class Exc(Exception): pass + + class BadHash(object): + fail = False + def __hash__(self): + if self.fail: + raise Exc() + else: + return 42 + + d = self._empty_mapping() + x = BadHash() + d[x] = 42 + x.fail = True + self.assertRaises(Exc, d.pop, x) + + def test_mutatingiteration(self): + d = self._empty_mapping() + d[1] = 1 + try: + for i in d: + d[i+1] = 1 + except RuntimeError: + pass + else: + self.fail("changing dict size during iteration doesn't raise Error") + + def test_repr(self): + d = self._empty_mapping() + self.assertEqual(repr(d), '{}') + d[1] = 2 + self.assertEqual(repr(d), '{1: 2}') + d = self._empty_mapping() + d[1] = d + self.assertEqual(repr(d), '{1: {...}}') + + class Exc(Exception): pass + + class BadRepr(object): + def __repr__(self): + raise Exc() + + d = self._full_mapping({1: BadRepr()}) + self.assertRaises(Exc, repr, d) + + def test_le(self): + self.assert_(not (self._empty_mapping() < self._empty_mapping())) + self.assert_(not (self._full_mapping({1: 2}) < self._full_mapping({1L: 2L}))) + + class Exc(Exception): pass + + class BadCmp(object): + def __eq__(self, other): + raise Exc() + + d1 = self._full_mapping({BadCmp(): 1}) + d2 = self._full_mapping({1: 1}) + try: + d1 < d2 + except Exc: + pass + else: + self.fail("< didn't raise Exc") + + def test_setdefault(self): + TestMappingProtocol.test_setdefault(self) + + class Exc(Exception): pass + + class BadHash(object): + fail = False + def __hash__(self): + if self.fail: + raise Exc() + else: + return 42 + + d = self._empty_mapping() + x = BadHash() + d[x] = 42 + x.fail = True + self.assertRaises(Exc, d.setdefault, x, []) Modified: branches/asm/Lib/test/regrtest.py =================================================================== --- branches/asm/Lib/test/regrtest.py 2008-06-03 03:33:29 UTC (rev 4520) +++ branches/asm/Lib/test/regrtest.py 2008-06-03 03:35:47 UTC (rev 4521) @@ -600,6 +600,8 @@ """ line = ' ' * indent + x = list(x) + x.sort() for one in map(str, x): w = len(line) + len(one) if line[-1:] == ' ': Modified: branches/asm/Lib/test/test_deque.py =================================================================== --- branches/asm/Lib/test/test_deque.py 2008-06-03 03:33:29 UTC (rev 4520) +++ branches/asm/Lib/test/test_deque.py 2008-06-03 03:35:47 UTC (rev 4521) @@ -613,15 +613,9 @@ ) if test_support.is_jython: - # Py*Derived doesn't pickle its dict if the supertype has __reduce__ - del TestSubclass.test_pickle - # Jython doesn't weakref things immediately del TestSubclass.test_weakref - # Jython doesn't have the gc module - del TestBasic.test_gc_doesnt_blowup - # Needs 2.5 seq_tests del TestVariousIteratorArgs.test_constructor Copied: branches/asm/Lib/test/test_weakref.py (from rev 4520, trunk/jython/Lib/test/test_weakref.py) =================================================================== --- branches/asm/Lib/test/test_weakref.py (rev 0) +++ branches/asm/Lib/test/test_weakref.py 2008-06-03 03:35:47 UTC (rev 4521) @@ -0,0 +1,1161 @@ +import gc +import sys +import unittest +import UserList +import weakref + +from test import test_support + +# Used in ReferencesTestCase.test_ref_created_during_del() . +ref_from_del = None + +class C: + def method(self): + pass + + +class Callable: + bar = None + + def __call__(self, x): + self.bar = x + + +def create_function(): + def f(): pass + return f + +def create_bound_method(): + return C().method + +def create_unbound_method(): + return C.method + + +class TestBase(unittest.TestCase): + + def setUp(self): + self.cbcalled = 0 + + def callback(self, ref): + self.cbcalled += 1 + + +class ReferencesTestCase(TestBase): + + def test_basic_ref(self): + self.check_basic_ref(C) + self.check_basic_ref(create_function) + self.check_basic_ref(create_bound_method) + self.check_basic_ref(create_unbound_method) + + # Just make sure the tp_repr handler doesn't raise an exception. + # Live reference: + o = C() + wr = weakref.ref(o) + `wr` + # Dead reference: + del o + `wr` + + def test_basic_callback(self): + self.check_basic_callback(C) + self.check_basic_callback(create_function) + self.check_basic_callback(create_bound_method) + self.check_basic_callback(create_unbound_method) + + def test_multiple_callbacks(self): + o = C() + ref1 = weakref.ref(o, self.callback) + ref2 = weakref.ref(o, self.callback) + del o + self.assert_(ref1() is None, + "expected reference to be invalidated") + self.assert_(ref2() is None, + "expected reference to be invalidated") + self.assert_(self.cbcalled == 2, + "callback not called the right number of times") + + def test_multiple_selfref_callbacks(self): + # Make sure all references are invalidated before callbacks are called + # + # What's important here is that we're using the first + # reference in the callback invoked on the second reference + # (the most recently created ref is cleaned up first). This + # tests that all references to the object are invalidated + # before any of the callbacks are invoked, so that we only + # have one invocation of _weakref.c:cleanup_helper() active + # for a particular object at a time. + # + def callback(object, self=self): + self.ref() + c = C() + self.ref = weakref.ref(c, callback) + ref1 = weakref.ref(c, callback) + del c + + def test_proxy_ref(self): + o = C() + o.bar = 1 + ref1 = weakref.proxy(o, self.callback) + ref2 = weakref.proxy(o, self.callback) + del o + + def check(proxy): + proxy.bar + + self.assertRaises(weakref.ReferenceError, check, ref1) + self.assertRaises(weakref.ReferenceError, check, ref2) + self.assertRaises(weakref.ReferenceError, bool, weakref.proxy(C())) + self.assert_(self.cbcalled == 2) + + def check_basic_ref(self, factory): + o = factory() + ref = weakref.ref(o) + self.assert_(ref() is not None, + "weak reference to live object should be live") + o2 = ref() + self.assert_(o is o2, + "<ref>() should return original object if live") + + def check_basic_callback(self, factory): + self.cbcalled = 0 + o = factory() + ref = weakref.ref(o, self.callback) + del o + self.assert_(self.cbcalled == 1, + "callback did not properly set 'cbcalled'") + self.assert_(ref() is None, + "ref2 should be dead after deleting object reference") + + def test_ref_reuse(self): + o = C() + ref1 = weakref.ref(o) + # create a proxy to make sure that there's an intervening creation + # between these two; it should make no difference + proxy = weakref.proxy(o) + ref2 = weakref.ref(o) + self.assert_(ref1 is ref2, + "reference object w/out callback should be re-used") + + o = C() + proxy = weakref.proxy(o) + ref1 = weakref.ref(o) + ref2 = weakref.ref(o) + self.assert_(ref1 is ref2, + "reference object w/out callback should be re-used") + self.assert_(weakref.getweakrefcount(o) == 2, + "wrong weak ref count for object") + del proxy + self.assert_(weakref.getweakrefcount(o) == 1, + "wrong weak ref count for object after deleting proxy") + + def test_proxy_reuse(self): + o = C() + proxy1 = weakref.proxy(o) + ref = weakref.ref(o) + proxy2 = weakref.proxy(o) + self.assert_(proxy1 is proxy2, + "proxy object w/out callback should have been re-used") + + def test_basic_proxy(self): + o = C() + self.check_proxy(o, weakref.proxy(o)) + + L = UserList.UserList() + p = weakref.proxy(L) + self.failIf(p, "proxy for empty UserList should be false") + p.append(12) + self.assertEqual(len(L), 1) + self.failUnless(p, "proxy for non-empty UserList should be true") + p[:] = [2, 3] + self.assertEqual(len(L), 2) + self.assertEqual(len(p), 2) + self.failUnless(3 in p, + "proxy didn't support __contains__() properly") + p[1] = 5 + self.assertEqual(L[1], 5) + self.assertEqual(p[1], 5) + L2 = UserList.UserList(L) + p2 = weakref.proxy(L2) + self.assertEqual(p, p2) + ## self.assertEqual(repr(L2), repr(p2)) + L3 = UserList.UserList(range(10)) + p3 = weakref.proxy(L3) + self.assertEqual(L3[:], p3[:]) + self.assertEqual(L3[5:], p3[5:]) + self.assertEqual(L3[:5], p3[:5]) + self.assertEqual(L3[2:5], p3[2:5]) + + # The PyWeakref_* C API is documented as allowing either NULL or + # None as the value for the callback, where either means "no + # callback". The "no callback" ref and proxy objects are supposed + # to be shared so long as they exist by all callers so long as + # they are active. In Python 2.3.3 and earlier, this guaranttee + # was not honored, and was broken in different ways for + # PyWeakref_NewRef() and PyWeakref_NewProxy(). (Two tests.) + + def test_shared_ref_without_callback(self): + self.check_shared_without_callback(weakref.ref) + + def test_shared_proxy_without_callback(self): + self.check_shared_without_callback(weakref.proxy) + + def check_shared_without_callback(self, makeref): + o = Object(1) + p1 = makeref(o, None) + p2 = makeref(o, None) + self.assert_(p1 is p2, "both callbacks were None in the C API") + del p1, p2 + p1 = makeref(o) + p2 = makeref(o, None) + self.assert_(p1 is p2, "callbacks were NULL, None in the C API") + del p1, p2 + p1 = makeref(o) + p2 = makeref(o) + self.assert_(p1 is p2, "both callbacks were NULL in the C API") + del p1, p2 + p1 = makeref(o, None) + p2 = makeref(o) + self.assert_(p1 is p2, "callbacks were None, NULL in the C API") + + def test_callable_proxy(self): + o = Callable() + ref1 = weakref.proxy(o) + + self.check_proxy(o, ref1) + + self.assert_(type(ref1) is weakref.CallableProxyType, + "proxy is not of callable type") + ref1('twinkies!') + self.assert_(o.bar == 'twinkies!', + "call through proxy not passed through to original") + ref1(x='Splat.') + self.assert_(o.bar == 'Splat.', + "call through proxy not passed through to original") + + # expect due to too few args + self.assertRaises(TypeError, ref1) + + # expect due to too many args + self.assertRaises(TypeError, ref1, 1, 2, 3) + + def check_proxy(self, o, proxy): + o.foo = 1 + self.assert_(proxy.foo == 1, + "proxy does not reflect attribute addition") + o.foo = 2 + self.assert_(proxy.foo == 2, + "proxy does not reflect attribute modification") + del o.foo + self.assert_(not hasattr(proxy, 'foo'), + "proxy does not reflect attribute removal") + + proxy.foo = 1 + self.assert_(o.foo == 1, + "object does not reflect attribute addition via proxy") + proxy.foo = 2 + self.assert_( + o.foo == 2, + "object does not reflect attribute modification via proxy") + del proxy.foo + self.assert_(not hasattr(o, 'foo'), + "object does not reflect attribute removal via proxy") + + def test_proxy_deletion(self): + # Test clearing of SF bug #762891 + class Foo: + result = None + def __delitem__(self, accessor): + self.result = accessor + g = Foo() + f = weakref.proxy(g) + del f[0] + self.assertEqual(f.result, 0) + + def test_proxy_bool(self): + # Test clearing of SF bug #1170766 + class List(list): pass + lyst = List() + self.assertEqual(bool(weakref.proxy(lyst)), bool(lyst)) + + def test_getweakrefcount(self): + o = C() + ref1 = weakref.ref(o) + ref2 = weakref.ref(o, self.callback) + self.assert_(weakref.getweakrefcount(o) == 2, + "got wrong number of weak reference objects") + + proxy1 = weakref.proxy(o) + proxy2 = weakref.proxy(o, self.callback) + self.assert_(weakref.getweakrefcount(o) == 4, + "got wrong number of weak reference objects") + + del ref1, ref2, proxy1, proxy2 + self.assert_(weakref.getweakrefcount(o) == 0, + "weak reference objects not unlinked from" + " referent when discarded.") + + # assumes ints do not support weakrefs + self.assert_(weakref.getweakrefcount(1) == 0, + "got wrong number of weak reference objects for int") + + def test_getweakrefs(self): + o = C() + ref1 = weakref.ref(o, self.callback) + ref2 = weakref.ref(o, self.callback) + del ref1 + self.assert_(weakref.getweakrefs(o) == [ref2], + "list of refs does not match") + + o = C() + ref1 = weakref.ref(o, self.callback) + ref2 = weakref.ref(o, self.callback) + del ref2 + self.assert_(weakref.getweakrefs(o) == [ref1], + "list of refs does not match") + + del ref1 + self.assert_(weakref.getweakrefs(o) == [], + "list of refs not cleared") + + # assumes ints do not support weakrefs + self.assert_(weakref.getweakrefs(1) == [], + "list of refs does not match for int") + + def test_newstyle_number_ops(self): + class F(float): + pass + f = F(2.0) + p = weakref.proxy(f) + self.assert_(p + 1.0 == 3.0) + self.assert_(1.0 + p == 3.0) # this used to SEGV + + def test_callbacks_protected(self): + # Callbacks protected from already-set exceptions? + # Regression test for SF bug #478534. + class BogusError(Exception): + pass + data = {} + def remove(k): + del data[k] + def encapsulate(): + f = lambda : () + data[weakref.ref(f, remove)] = None + raise BogusError + try: + encapsulate() + except BogusError: + pass + else: + self.fail("exception not properly restored") + try: + encapsulate() + except BogusError: + pass + else: + self.fail("exception not properly restored") + + def test_sf_bug_840829(self): + # "weakref callbacks and gc corrupt memory" + # subtype_dealloc erroneously exposed a new-style instance + # already in the process of getting deallocated to gc, + # causing double-deallocation if the instance had a weakref + # callback that triggered gc. + # If the bug exists, there probably won't be an obvious symptom + # in a release build. In a debug build, a segfault will occur + # when the second attempt to remove the instance from the "list + # of all objects" occurs. + + import gc + + class C(object): + pass + + c = C() + wr = weakref.ref(c, lambda ignore: gc.collect()) + del c + + # There endeth the first part. It gets worse. + del wr + + c1 = C() + c1.i = C() + wr = weakref.ref(c1.i, lambda ignore: gc.collect()) + + c2 = C() + c2.c1 = c1 + del c1 # still alive because c2 points to it + + # Now when subtype_dealloc gets called on c2, it's not enough just + # that c2 is immune from gc while the weakref callbacks associated + # with c2 execute (there are none in this 2nd half of the test, btw). + # subtype_dealloc goes on to call the base classes' deallocs too, + # so any gc triggered by weakref callbacks associated with anything + # torn down by a base class dealloc can also trigger double + # deallocation of c2. + del c2 + + def test_callback_in_cycle_1(self): + import gc + + class J(object): + pass + + class II(object): + def acallback(self, ignore): + self.J + + I = II() + I.J = J + I.wr = weakref.ref(J, I.acallback) + + # Now J and II are each in a self-cycle (as all new-style class + # objects are, since their __mro__ points back to them). I holds + # both a weak reference (I.wr) and a strong reference (I.J) to class + # J. I is also in a cycle (I.wr points to a weakref that references + # I.acallback). When we del these three, they all become trash, but + # the cycles prevent any of them from getting cleaned up immediately. + # Instead they have to wait for cyclic gc to deduce that they're + # trash. + # + # gc used to call tp_clear on all of them, and the order in which + # it does that is pretty accidental. The exact order in which we + # built up these things manages to provoke gc into running tp_clear + # in just the right order (I last). Calling tp_clear on II leaves + # behind an insane class object (its __mro__ becomes NULL). Calling + # tp_clear on J breaks its self-cycle, but J doesn't get deleted + # just then because of the strong reference from I.J. Calling + # tp_clear on I starts to clear I's __dict__, and just happens to + # clear I.J first -- I.wr is still intact. That removes the last + # reference to J, which triggers the weakref callback. The callback + # tries to do "self.J", and instances of new-style classes look up + # attributes ("J") in the class dict first. The class (II) wants to + # search II.__mro__, but that's NULL. The result was a segfault in + # a release build, and an assert failure in a debug build. + del I, J, II + gc.collect() + + def test_callback_in_cycle_2(self): + import gc + + # This is just like test_callback_in_cycle_1, except that II is an + # old-style class. The symptom is different then: an instance of an + # old-style class looks in its own __dict__ first. 'J' happens to + # get cleared from I.__dict__ before 'wr', and 'J' was never in II's + # __dict__, so the attribute isn't found. The difference is that + # the old-style II doesn't have a NULL __mro__ (it doesn't have any + # __mro__), so no segfault occurs. Instead it got: + # test_callback_in_cycle_2 (__main__.ReferencesTestCase) ... + # Exception exceptions.AttributeError: + # "II instance has no attribute 'J'" in <bound method II.acallback + # of <?.II instance at 0x00B9B4B8>> ignored + + class J(object): + pass + + class II: + def acallback(self, ignore): + self.J + + I = II() + I.J = J + I.wr = weakref.ref(J, I.acallback) + + del I, J, II + gc.collect() + + def test_callback_in_cycle_3(self): + import gc + + # This one broke the first patch that fixed the last two. In this + # case, the objects reachable from the callback aren't also reachable + # from the object (c1) *triggering* the callback: you can get to + # c1 from c2, but not vice-versa. The result was that c2's __dict__ + # got tp_clear'ed by the time the c2.cb callback got invoked. + + class C: + def cb(self, ignore): + self.me + self.c1 + self.wr + + c1, c2 = C(), C() + + c2.me = c2 + c2.c1 = c1 + c2.wr = weakref.ref(c1, c2.cb) + + del c1, c2 + gc.collect() + + def test_callback_in_cycle_4(self): + import gc + + # Like test_callback_in_cycle_3, except c2 and c1 have different + # classes. c2's class (C) isn't reachable from c1 then, so protecting + # objects reachable from the dying object (c1) isn't enough to stop + # c2's class (C) from getting tp_clear'ed before c2.cb is invoked. + # The result was a segfault (C.__mro__ was NULL when the callback + # tried to look up self.me). + + class C(object): + def cb(self, ignore): + self.me + self.c1 + self.wr + + class D: + pass + + c1, c2 = D(), C() + + c2.me = c2 + c2.c1 = c1 + c2.wr = weakref.ref(c1, c2.cb) + + del c1, c2, C, D + gc.collect() + + def test_callback_in_cycle_resurrection(self): + import gc + + # Do something nasty in a weakref callback: resurrect objects + # from dead cycles. For this to be attempted, the weakref and + # its callback must also be part of the cyclic trash (else the + # objects reachable via the callback couldn't be in cyclic trash + # to begin with -- the callback would act like an external root). + # But gc clears trash weakrefs with callbacks early now, which + # disables the callbacks, so the callbacks shouldn't get called + # at all (and so nothing actually gets resurrected). + + alist = [] + class C(object): + def __init__(self, value): + self.attribute = value + + def acallback(self, ignore): + alist.append(self.c) + + c1, c2 = C(1), C(2) + c1.c = c2 + c2.c = c1 + c1.wr = weakref.ref(c2, c1.acallback) + c2.wr = weakref.ref(c1, c2.acallback) + + def C_went_away(ignore): + alist.append("C went away") + wr = weakref.ref(C, C_went_away) + + del c1, c2, C # make them all trash + self.assertEqual(alist, []) # del isn't enough to reclaim anything + + gc.collect() + # c1.wr and c2.wr were part of the cyclic trash, so should have + # been cleared without their callbacks executing. OTOH, the weakref + # to C is bound to a function local (wr), and wasn't trash, so that + # callback should have been invoked when C went away. + self.assertEqual(alist, ["C went away"]) + # The remaining weakref should be dead now (its callback ran). + self.assertEqual(wr(), None) + + del alist[:] + gc.collect() + self.assertEqual(alist, []) + + def test_callbacks_on_callback(self): + import gc + + # Set up weakref callbacks *on* weakref callbacks. + alist = [] + def safe_callback(ignore): + alist.append("safe_callback called") + + class C(object): + def cb(self, ignore): + alist.append("cb called") + + c, d = C(), C() + c.other = d + d.other = c + callback = c.cb + c.wr = weakref.ref(d, callback) # this won't trigger + d.wr = weakref.ref(callback, d.cb) # ditto + external_wr = weakref.ref(callback, safe_callback) # but this will + self.assert_(external_wr() is callback) + + # The weakrefs attached to c and d should get cleared, so that + # C.cb is never called. But external_wr isn't part of the cyclic + # trash, and no cyclic trash is reachable from it, so safe_callback + # should get invoked when the bound method object callback (c.cb) + # -- which is itself a callback, and also part of the cyclic trash -- + # gets reclaimed at the end of gc. + + del callback, c, d, C + self.assertEqual(alist, []) # del isn't enough to clean up cycles + gc.collect() + self.assertEqual(alist, ["safe_callback called"]) + self.assertEqual(external_wr(), None) + + del alist[:] + gc.collect() + self.assertEqual(alist, []) + + def test_gc_during_ref_creation(self): + self.check_gc_during_creation(weakref.ref) + + def test_gc_during_proxy_creation(self): + self.check_gc_during_creation(weakref.proxy) + + def check_gc_during_creation(self, makeref): + # XXX: threshold not applicable to Jython + #thresholds = gc.get_threshold() + #gc.set_threshold(1, 1, 1) + gc.collect() + class A: + pass + + def callback(*args): + pass + + referenced = A() + + a = A() + a.a = a + a.wr = makeref(referenced) + + try: + # now make sure the object and the ref get labeled as + # cyclic trash: + a = A() + weakref.ref(referenced, callback) + + finally: + # XXX: threshold not applicable to Jython + #gc.set_threshold(*thresholds) + pass + + def test_ref_created_during_del(self): + # Bug #1377858 + # A weakref created in an object's __del__() would crash the + # interpreter when the weakref was cleaned up since it would refer to + # non-existent memory. This test should not segfault the interpreter. + class Target(object): + def __del__(self): + global ref_from_del + ref_from_del = weakref.ref(self) + + w = Target() + + +class SubclassableWeakrefTestCase(unittest.TestCase): + + def test_subclass_refs(self): + class MyRef(weakref.ref): + def __init__(self, ob, callback=None, value=42): + self.value = value + super(MyRef, self).__init__(ob, callback) + def __call__(self): + self.called = True + return super(MyRef, self).__call__() + o = Object("foo") + mr = MyRef(o, value=24) + self.assert_(mr() is o) + self.assert_(mr.called) + self.assertEqual(mr.value, 24) + del o + self.assert_(mr() is None) + self.assert_(mr.called) + + def test_subclass_refs_dont_replace_standard_refs(self): + class MyRef(weakref.ref): + pass + o = Object(42) + r1 = MyRef(o) + r2 = weakref.ref(o) + self.assert_(r1 is not r2) + self.assertEqual(weakref.getweakrefs(o), [r2, r1]) + self.assertEqual(weakref.getweakrefcount(o), 2) + r3 = MyRef(o) + self.assertEqual(weakref.getweakrefcount(o), 3) + refs = weakref.getweakrefs(o) + self.assertEqual(len(refs), 3) + self.assert_(r2 is refs[0]) + self.assert_(r1 in refs[1:]) + self.assert_(r3 in refs[1:]) + + def test_subclass_refs_dont_conflate_callbacks(self): + class MyRef(weakref.ref): + pass + o = Object(42) + r1 = MyRef(o, id) + r2 = MyRef(o, str) + self.assert_(r1 is not r2) + refs = weakref.getweakrefs(o) + self.assert_(r1 in refs) + self.assert_(r2 in refs) + + def test_subclass_refs_with_slots(self): + class MyRef(weakref.ref): + __slots__ = "slot1", "slot2" + def __new__(type, ob, callback, slot1, slot2): + return weakref.ref.__new__(type, ob, callback) + def __init__(self, ob, callback, slot1, slot2): + self.slot1 = slot1 + self.slot2 = slot2 + def meth(self): + return self.slot1 + self.slot2 + o = Object(42) + r = MyRef(o, None, "abc", "def") + self.assertEqual(r.slot1, "abc") + self.assertEqual(r.slot2, "def") + self.assertEqual(r.meth(), "abcdef") + self.failIf(hasattr(r, "__dict__")) + + +class Object: + def __init__(self, arg): + self.arg = arg + def __repr__(self): + return "<Object %r>" % self.arg + + +class MappingTestCase(TestBase): + + COUNT = 10 + + def test_weak_values(self): + # + # This exercises d.copy(), d.items(), d[], del d[], len(d). + # + dict, objects = self.make_weak_valued_dict() + for o in objects: + self.assert_(weakref.getweakrefcount(o) == 1, + "wrong number of weak references to %r!" % o) + self.assert_(o is dict[o.arg], + "wrong object returned by weak dict!") + items1 = dict.items() + items2 = dict.copy().items() + items1.sort() + items2.sort() + self.assert_(items1 == items2, + "cloning of weak-valued dictionary did not work!") + del items1, items2 + self.assert_(len(dict) == self.COUNT) + del objects[0] + self.assert_(len(dict) == (self.COUNT - 1), + "deleting object did not cause dictionary update") + del objects, o + self.assert_(len(dict) == 0, + "deleting the values did not clear the dictionary") + # regression on SF bug #447152: + dict = weakref.WeakValueDictionary() + self.assertRaises(KeyError, dict.__getitem__, 1) + dict[2] = C() + self.assertRaises(KeyError, dict.__getitem__, 2) + + def test_weak_keys(self): + # + # This exercises d.copy(), d.items(), d[] = v, d[], del d[], + # len(d), d.has_key(). + # + dict, objects = self.make_weak_keyed_dict() + for o in objects: + self.assert_(weakref.getweakrefcount(o) == 1, + "wrong number of weak references to %r!" % o) + self.assert_(o.arg is dict[o], + "wrong object returned by weak dict!") + items1 = dict.items() + items2 = dict.copy().items() + self.assert_(set(items1) == set(items2), + "cloning of weak-keyed dictionary did not work!") + del items1, items2 + self.assert_(len(dict) == self.COUNT) + del objects[0] + self.assert_(len(dict) == (self.COUNT - 1), + "deleting object did not cause dictionary update") + del objects, o + self.assert_(len(dict) == 0, + "deleting the keys did not clear the dictionary") + o = Object(42) + dict[o] = "What is the meaning of the universe?" + self.assert_(dict.has_key(o)) + self.assert_(not dict.has_key(34)) + + def test_weak_keyed_iters(self): + dict, objects = self.make_weak_keyed_dict() + self.check_iters(dict) + + # Test keyrefs() + refs = dict.keyrefs() + self.assertEqual(len(refs), len(objects)) + objects2 = list(objects) + for wr in refs: + ob = wr() + self.assert_(dict.has_key(ob)) + self.assert_(ob in dict) + self.assertEqual(ob.arg, dict[ob]) + objects2.remove(ob) + self.assertEqual(len(objects2), 0) + + # Test iterkeyrefs() + objects2 = list(objects) + self.assertEqual(len(list(dict.iterkeyrefs())), len(objects)) + for wr in dict.iterkeyrefs(): + ob = wr() + self.assert_(dict.has_key(ob)) + self.assert_(ob in dict) + self.assertEqual(ob.arg, dict[ob]) + objects2.remove(ob) + self.assertEqual(len(objects2), 0) + + def test_weak_valued_iters(self): + dict, objects = self.make_weak_valued_dict() + self.check_iters(dict) + + # Test valuerefs() + refs = dict.valuerefs() + self.assertEqual(len(refs), len(objects)) + objects2 = list(objects) + for wr in refs: + ob = wr() + self.assertEqual(ob, dict[ob.arg]) + self.assertEqual(ob.arg, dict[ob.arg].arg) + objects2.remove(ob) + self.assertEqual(len(objects2), 0) + + # Test itervaluerefs() + objects2 = list(objects) + self.assertEqual(len(list(dict.itervaluerefs())), len(objects)) + for wr in dict.itervaluerefs(): + ob = wr() + self.assertEqual(ob, dict[ob.arg]) + self.assertEqual(ob.arg, dict[ob.arg].arg) + objects2.remove(ob) + self.assertEqual(len(objects2), 0) + + def check_iters(self, dict): + # item iterator: + items = dict.items() + for item in dict.iteritems(): + items.remove(item) + self.assert_(len(items) == 0, "iteritems() did not touch all items") + + # key iterator, via __iter__(): + keys = dict.keys() + for k in dict: + keys.remove(k) + self.assert_(len(keys) == 0, "__iter__() did not touch all keys") + + # key iterator, via iterkeys(): + keys = dict.keys() + for k in dict.iterkeys(): + keys.remove(k) + self.assert_(len(keys) == 0, "iterkeys() did not touch all keys") + + # value iterator: + values = dict.values() + for v in dict.itervalues(): + values.remove(v) + self.assert_(len(values) == 0, + "itervalues() did not touch all values") + + def test_make_weak_keyed_dict_from_dict(self): + o = Object(3) + dict = weakref.WeakKeyDictionary({o:364}) + self.assert_(dict[o] == 364) + + def test_make_weak_keyed_dict_from_weak_keyed_dict(self): + o = Object(3) + dict = weakref.WeakKeyDictionary({o:364}) + dict2 = weakref.WeakKeyDictionary(dict) + self.assert_(dict[o] == 364) + + def make_weak_keyed_dict(self): + dict = weakref.WeakKeyDictionary() + objects = map(Object, range(self.COUNT)) + for o in objects: + dict[o] = o.arg + return dict, objects + + def make_weak_valued_dict(self): + dict = weakref.WeakValueDictionary() + objects = map(Object, range(self.COUNT)) + for o in objects: + dict[o.arg] = o + return dict, objects + + def check_popitem(self, klass, key1, value1, key2, value2): + weakdict = klass() + weakdict[key1] = value1 + weakdict[ke... [truncated message content] |
From: <fwi...@us...> - 2008-06-03 06:39:44
|
Revision: 4523 http://jython.svn.sourceforge.net/jython/?rev=4523&view=rev Author: fwierzbicki Date: 2008-06-02 23:39:41 -0700 (Mon, 02 Jun 2008) Log Message: ----------- Most of this change is generated -- the real code changes are in Python.g, PythonWalker.g, and asdl_antlr.py. Moving to antlr 3.1 style of AST production. Changed the Num processing only so far. Modified Paths: -------------- branches/asm/ast/asdl_antlr.py branches/asm/grammar/Python.g branches/asm/grammar/PythonWalker.g branches/asm/src/org/python/antlr/PythonTree.java branches/asm/src/org/python/antlr/ast/Assert.java branches/asm/src/org/python/antlr/ast/Assign.java branches/asm/src/org/python/antlr/ast/Attribute.java branches/asm/src/org/python/antlr/ast/AugAssign.java branches/asm/src/org/python/antlr/ast/BinOp.java branches/asm/src/org/python/antlr/ast/BoolOp.java branches/asm/src/org/python/antlr/ast/Break.java branches/asm/src/org/python/antlr/ast/Call.java branches/asm/src/org/python/antlr/ast/ClassDef.java branches/asm/src/org/python/antlr/ast/Compare.java branches/asm/src/org/python/antlr/ast/Continue.java branches/asm/src/org/python/antlr/ast/Delete.java branches/asm/src/org/python/antlr/ast/Dict.java branches/asm/src/org/python/antlr/ast/Ellipsis.java branches/asm/src/org/python/antlr/ast/Exec.java branches/asm/src/org/python/antlr/ast/Expr.java branches/asm/src/org/python/antlr/ast/Expression.java branches/asm/src/org/python/antlr/ast/ExtSlice.java branches/asm/src/org/python/antlr/ast/For.java branches/asm/src/org/python/antlr/ast/FunctionDef.java branches/asm/src/org/python/antlr/ast/GeneratorExp.java branches/asm/src/org/python/antlr/ast/Global.java branches/asm/src/org/python/antlr/ast/If.java branches/asm/src/org/python/antlr/ast/IfExp.java branches/asm/src/org/python/antlr/ast/Import.java branches/asm/src/org/python/antlr/ast/ImportFrom.java branches/asm/src/org/python/antlr/ast/Index.java branches/asm/src/org/python/antlr/ast/Interactive.java branches/asm/src/org/python/antlr/ast/Lambda.java branches/asm/src/org/python/antlr/ast/List.java branches/asm/src/org/python/antlr/ast/ListComp.java branches/asm/src/org/python/antlr/ast/Module.java branches/asm/src/org/python/antlr/ast/Name.java branches/asm/src/org/python/antlr/ast/Num.java branches/asm/src/org/python/antlr/ast/Pass.java branches/asm/src/org/python/antlr/ast/Print.java branches/asm/src/org/python/antlr/ast/Raise.java branches/asm/src/org/python/antlr/ast/Repr.java branches/asm/src/org/python/antlr/ast/Return.java branches/asm/src/org/python/antlr/ast/Slice.java branches/asm/src/org/python/antlr/ast/Str.java branches/asm/src/org/python/antlr/ast/Subscript.java branches/asm/src/org/python/antlr/ast/Suite.java branches/asm/src/org/python/antlr/ast/TryExcept.java branches/asm/src/org/python/antlr/ast/TryFinally.java branches/asm/src/org/python/antlr/ast/Tuple.java branches/asm/src/org/python/antlr/ast/UnaryOp.java branches/asm/src/org/python/antlr/ast/Unicode.java branches/asm/src/org/python/antlr/ast/VisitorBase.java branches/asm/src/org/python/antlr/ast/While.java branches/asm/src/org/python/antlr/ast/With.java branches/asm/src/org/python/antlr/ast/Yield.java branches/asm/src/org/python/antlr/ast/aliasType.java branches/asm/src/org/python/antlr/ast/argumentsType.java branches/asm/src/org/python/antlr/ast/comprehensionType.java branches/asm/src/org/python/antlr/ast/excepthandlerType.java branches/asm/src/org/python/antlr/ast/exprType.java branches/asm/src/org/python/antlr/ast/keywordType.java branches/asm/src/org/python/antlr/ast/modType.java branches/asm/src/org/python/antlr/ast/sliceType.java branches/asm/src/org/python/antlr/ast/stmtType.java Modified: branches/asm/ast/asdl_antlr.py =================================================================== --- branches/asm/ast/asdl_antlr.py 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/ast/asdl_antlr.py 2008-06-03 06:39:41 UTC (rev 4523) @@ -57,6 +57,7 @@ print >> self.file, 'package org.python.antlr.ast;' if refersToPythonTree: print >> self.file, 'import org.python.antlr.PythonTree;' + print >> self.file, 'import org.antlr.runtime.CommonToken;' print >> self.file, 'import org.antlr.runtime.Token;' if useDataOutput: print >> self.file, 'import java.io.DataOutputStream;' @@ -158,11 +159,18 @@ self.open("%sType" % name) self.emit("public abstract class %(name)sType extends PythonTree {" % locals(), depth) - #self.emit("public %(name)sType(Token token) {" % locals(), depth+1) - #self.emit("super(token);", depth+2) - #self.emit("}", depth+1) - #self.emit("", 0) + self.emit("", 0) + self.emit("public %(name)sType(int ttype, Token token) {" % locals(), depth+1) + self.emit("super(ttype, token);", depth+2) + self.emit("}", depth+1) + self.emit("", 0) + + self.emit("public %(name)sType(Token token) {" % locals(), depth+1) + self.emit("super(token);", depth+2) + self.emit("}", depth+1) + self.emit("", 0) + self.emit("public %(name)sType(PythonTree node) {" % locals(), depth+1) self.emit("super(node);", depth+2) self.emit("}", depth+1) @@ -255,15 +263,24 @@ def javaMethods(self, type, clsname, ctorname, fields, depth): # The java ctors + token = asdl.Field('Token', 'token') token.typedef = False fpargs = ", ".join([self.fieldDef(f) for f in [token] + fields]) + self.emit("public %s(%s) {" % (ctorname, fpargs), depth) + self.emit("super(token);", depth+1) + self.javaConstructorHelper(fields, depth) + self.emit("}", depth) + self.emit("", 0) - #self.emit("public %s(%s) {" % (ctorname, fpargs), depth) - #self.emit("super(token);", depth+1) - #self.javaConstructorHelper(fields, depth) - #self.emit("}", depth) - #self.emit("", 0) + ttype = asdl.Field('int', 'ttype') + ttype.typedef = False + fpargs = ", ".join([self.fieldDef(f) for f in [ttype, token] + fields]) + self.emit("public %s(%s) {" % (ctorname, fpargs), depth) + self.emit("super(ttype, token);", depth+1) + self.javaConstructorHelper(fields, depth) + self.emit("}", depth) + self.emit("", 0) tree = asdl.Field('PythonTree', 'tree') tree.typedef = False Modified: branches/asm/grammar/Python.g =================================================================== --- branches/asm/grammar/Python.g 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/grammar/Python.g 2008-06-03 06:39:41 UTC (rev 4523) @@ -120,7 +120,7 @@ Return; Yield; Str; - Num; + NumTok; IsNot; In; NotIn; @@ -187,8 +187,14 @@ @header { package org.python.antlr; +import org.antlr.runtime.CommonToken; + import org.python.antlr.ParseException; import org.python.antlr.PythonTree; +import org.python.antlr.ast.Num; +import org.python.core.Py; + +import java.math.BigInteger; } @members { @@ -200,6 +206,46 @@ } } + Object makeFloat(Token t) { + debug("makeFloat matched " + t.getText()); + return Py.newFloat(Double.valueOf(t.getText())); + } + + Object makeComplex(Token t) { + String s = t.getText(); + s = s.substring(0, s.length() - 1); + return Py.newImaginary(Double.valueOf(s)); + } + + Object makeInt(Token t) { + debug("Num matched " + t.getText()); + String s = t.getText(); + int radix = 10; + if (s.startsWith("0x") || s.startsWith("0X")) { + radix = 16; + s = s.substring(2, s.length()); + } else if (s.startsWith("0")) { + radix = 8; + } + if (s.endsWith("L") || s.endsWith("l")) { + s = s.substring(0, s.length()-1); + return Py.newLong(new BigInteger(s, radix)); + } + int ndigits = s.length(); + int i=0; + while (i < ndigits && s.charAt(i) == '0') + i++; + if ((ndigits - i) > 11) { + return Py.newLong(new BigInteger(s, radix)); + } + + long l = Long.valueOf(s, radix).longValue(); + if (l > 0xffffffffl || (radix == 10 && l > Integer.MAX_VALUE)) { + return Py.newLong(new BigInteger(s, radix)); + } + return Py.newInteger((int) l); + } + protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException { throw new MismatchedTokenException(ttype, input); } @@ -737,10 +783,10 @@ | LCURLY (dictmaker)? RCURLY -> ^(Dict LCURLY ^(Elts dictmaker)?) | BACKQUOTE testlist BACKQUOTE -> ^(Repr BACKQUOTE testlist) | NAME {debug("parsed NAME");} -> ^(Name NAME) - | INT -> ^(Num INT) - | LONGINT -> ^(Num LONGINT) - | FLOAT -> ^(Num FLOAT) - | COMPLEX -> ^(Num COMPLEX) + | INT -> ^(NumTok<Num>[$INT, makeInt($INT)]) + | LONGINT -> ^(NumTok<Num>[$LONGINT, makeInt($LONGINT)]) + | FLOAT -> ^(NumTok<Num>[$FLOAT, makeFloat($FLOAT)]) + | COMPLEX -> ^(NumTok<Num>[$COMPLEX, makeComplex($COMPLEX)]) | (STRING)+ -> ^(Str STRING+) ; Modified: branches/asm/grammar/PythonWalker.g =================================================================== --- branches/asm/grammar/PythonWalker.g 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/grammar/PythonWalker.g 2008-06-03 06:39:41 UTC (rev 4523) @@ -242,46 +242,6 @@ } } - Num makeFloat(PythonTree t) { - debug("makeFloat matched " + t.getText()); - return new Num(t, Py.newFloat(Double.valueOf(t.getText()))); - } - - Num makeComplex(PythonTree t) { - String s = t.getText(); - s = s.substring(0, s.length() - 1); - return new Num(t, Py.newImaginary(Double.valueOf(s))); - } - - Num makeInt(PythonTree t) { - debug("Num matched " + t.getText()); - String s = t.getText(); - int radix = 10; - if (s.startsWith("0x") || s.startsWith("0X")) { - radix = 16; - s = s.substring(2, s.length()); - } else if (s.startsWith("0")) { - radix = 8; - } - if (s.endsWith("L") || s.endsWith("l")) { - s = s.substring(0, s.length()-1); - return new Num(t, Py.newLong(new BigInteger(s, radix))); - } - int ndigits = s.length(); - int i=0; - while (i < ndigits && s.charAt(i) == '0') - i++; - if ((ndigits - i) > 11) { - return new Num(t, Py.newLong(new BigInteger(s, radix))); - } - - long l = Long.valueOf(s, radix).longValue(); - if (l > 0xffffffffl || (radix == 10 && l > Integer.MAX_VALUE)) { - return new Num(t, Py.newLong(new BigInteger(s, radix))); - } - return new Num(t, Py.newInteger((int) l)); - } - private stmtType makeTryExcept(PythonTree t, List body, List handlers, List orelse, List finBody) { stmtType[] b = (stmtType[])body.toArray(new stmtType[body.size()]); excepthandlerType[] e = (excepthandlerType[])handlers.toArray(new excepthandlerType[handlers.size()]); @@ -1095,6 +1055,10 @@ $etype = $yield_expr.etype; $marker = $yield_expr.start; } + | NumTok { + $etype = (Num)$NumTok; + $marker = (Num)$NumTok; + } ; comp_op returns [cmpopType op] @@ -1210,24 +1174,6 @@ $etype = new Subscript($test.marker, $test.etype, s, ctype); $marker = $test.marker; } - | ^(Num INT) { - $etype = makeInt($INT); - $marker = $INT; - debug("makeInt output: " + $etype); - } - | ^(Num LONGINT) { - $etype = makeInt($LONGINT); - $marker = $LONGINT; - } - | ^(Num FLOAT) { - $etype = makeFloat($FLOAT); - debug("float matched" + $etype); - $marker = $FLOAT; - } - | ^(Num COMPLEX) { - $etype = makeComplex($COMPLEX); - $marker = $COMPLEX; - } | stringlist { StringPair sp = extractStrings($stringlist.strings); if (sp.isUnicode()) { Modified: branches/asm/src/org/python/antlr/PythonTree.java =================================================================== --- branches/asm/src/org/python/antlr/PythonTree.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/PythonTree.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -2,6 +2,7 @@ import org.antlr.runtime.tree.BaseTree; import org.antlr.runtime.tree.CommonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; @@ -15,6 +16,18 @@ public boolean from_future_checked = false; + public PythonTree(int ttype, Token t) { + super(); + CommonToken c = new CommonToken(ttype, t.getText()); + c.setLine(t.getLine()); + c.setTokenIndex(t.getTokenIndex()); + c.setCharPositionInLine(t.getCharPositionInLine()); + c.setChannel(t.getChannel()); + c.setStartIndex(((CommonToken)t).getStartIndex()); + c.setStopIndex(((CommonToken)t).getStopIndex()); + token = c; + } + public PythonTree(Token token) { super(token); } Modified: branches/asm/src/org/python/antlr/ast/Assert.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Assert.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Assert.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -11,6 +12,18 @@ public static final String[] _fields = new String[] {"test","msg"}; + public Assert(Token token, exprType test, exprType msg) { + super(token); + this.test = test; + this.msg = msg; + } + + public Assert(int ttype, Token token, exprType test, exprType msg) { + super(ttype, token); + this.test = test; + this.msg = msg; + } + public Assert(PythonTree tree, exprType test, exprType msg) { super(tree); this.test = test; Modified: branches/asm/src/org/python/antlr/ast/Assign.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Assign.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Assign.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -11,6 +12,28 @@ public static final String[] _fields = new String[] {"targets","value"}; + public Assign(Token token, exprType[] targets, exprType value) { + super(token); + this.targets = targets; + if (targets != null) { + for(int itargets=0;itargets<targets.length;itargets++) { + addChild(targets[itargets]); + } + } + this.value = value; + } + + public Assign(int ttype, Token token, exprType[] targets, exprType value) { + super(ttype, token); + this.targets = targets; + if (targets != null) { + for(int itargets=0;itargets<targets.length;itargets++) { + addChild(targets[itargets]); + } + } + this.value = value; + } + public Assign(PythonTree tree, exprType[] targets, exprType value) { super(tree); this.targets = targets; Modified: branches/asm/src/org/python/antlr/ast/Attribute.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Attribute.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Attribute.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -12,6 +13,22 @@ public static final String[] _fields = new String[] {"value","attr","ctx"}; + public Attribute(Token token, exprType value, String attr, expr_contextType + ctx) { + super(token); + this.value = value; + this.attr = attr; + this.ctx = ctx; + } + + public Attribute(int ttype, Token token, exprType value, String attr, + expr_contextType ctx) { + super(ttype, token); + this.value = value; + this.attr = attr; + this.ctx = ctx; + } + public Attribute(PythonTree tree, exprType value, String attr, expr_contextType ctx) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/AugAssign.java =================================================================== --- branches/asm/src/org/python/antlr/ast/AugAssign.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/AugAssign.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -12,6 +13,22 @@ public static final String[] _fields = new String[] {"target","op","value"}; + public AugAssign(Token token, exprType target, operatorType op, exprType + value) { + super(token); + this.target = target; + this.op = op; + this.value = value; + } + + public AugAssign(int ttype, Token token, exprType target, operatorType op, + exprType value) { + super(ttype, token); + this.target = target; + this.op = op; + this.value = value; + } + public AugAssign(PythonTree tree, exprType target, operatorType op, exprType value) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/BinOp.java =================================================================== --- branches/asm/src/org/python/antlr/ast/BinOp.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/BinOp.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -12,6 +13,21 @@ public static final String[] _fields = new String[] {"left","op","right"}; + public BinOp(Token token, exprType left, operatorType op, exprType right) { + super(token); + this.left = left; + this.op = op; + this.right = right; + } + + public BinOp(int ttype, Token token, exprType left, operatorType op, + exprType right) { + super(ttype, token); + this.left = left; + this.op = op; + this.right = right; + } + public BinOp(PythonTree tree, exprType left, operatorType op, exprType right) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/BoolOp.java =================================================================== --- branches/asm/src/org/python/antlr/ast/BoolOp.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/BoolOp.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -11,6 +12,28 @@ public static final String[] _fields = new String[] {"op","values"}; + public BoolOp(Token token, boolopType op, exprType[] values) { + super(token); + this.op = op; + this.values = values; + if (values != null) { + for(int ivalues=0;ivalues<values.length;ivalues++) { + addChild(values[ivalues]); + } + } + } + + public BoolOp(int ttype, Token token, boolopType op, exprType[] values) { + super(ttype, token); + this.op = op; + this.values = values; + if (values != null) { + for(int ivalues=0;ivalues<values.length;ivalues++) { + addChild(values[ivalues]); + } + } + } + public BoolOp(PythonTree tree, boolopType op, exprType[] values) { super(tree); this.op = op; Modified: branches/asm/src/org/python/antlr/ast/Break.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Break.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Break.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -9,6 +10,14 @@ public static final String[] _fields = new String[] {}; + public Break(Token token) { + super(token); + } + + public Break(int ttype, Token token) { + super(ttype, token); + } + public Break(PythonTree tree) { super(tree); } Modified: branches/asm/src/org/python/antlr/ast/Call.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Call.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Call.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -15,6 +16,46 @@ public static final String[] _fields = new String[] {"func","args","keywords","starargs","kwargs"}; + public Call(Token token, exprType func, exprType[] args, keywordType[] + keywords, exprType starargs, exprType kwargs) { + super(token); + this.func = func; + this.args = args; + if (args != null) { + for(int iargs=0;iargs<args.length;iargs++) { + addChild(args[iargs]); + } + } + this.keywords = keywords; + if (keywords != null) { + for(int ikeywords=0;ikeywords<keywords.length;ikeywords++) { + addChild(keywords[ikeywords]); + } + } + this.starargs = starargs; + this.kwargs = kwargs; + } + + public Call(int ttype, Token token, exprType func, exprType[] args, + keywordType[] keywords, exprType starargs, exprType kwargs) { + super(ttype, token); + this.func = func; + this.args = args; + if (args != null) { + for(int iargs=0;iargs<args.length;iargs++) { + addChild(args[iargs]); + } + } + this.keywords = keywords; + if (keywords != null) { + for(int ikeywords=0;ikeywords<keywords.length;ikeywords++) { + addChild(keywords[ikeywords]); + } + } + this.starargs = starargs; + this.kwargs = kwargs; + } + public Call(PythonTree tree, exprType func, exprType[] args, keywordType[] keywords, exprType starargs, exprType kwargs) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/ClassDef.java =================================================================== --- branches/asm/src/org/python/antlr/ast/ClassDef.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/ClassDef.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -12,6 +13,42 @@ public static final String[] _fields = new String[] {"name","bases","body"}; + public ClassDef(Token token, String name, exprType[] bases, stmtType[] + body) { + super(token); + this.name = name; + this.bases = bases; + if (bases != null) { + for(int ibases=0;ibases<bases.length;ibases++) { + addChild(bases[ibases]); + } + } + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + } + + public ClassDef(int ttype, Token token, String name, exprType[] bases, + stmtType[] body) { + super(ttype, token); + this.name = name; + this.bases = bases; + if (bases != null) { + for(int ibases=0;ibases<bases.length;ibases++) { + addChild(bases[ibases]); + } + } + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + } + public ClassDef(PythonTree tree, String name, exprType[] bases, stmtType[] body) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/Compare.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Compare.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Compare.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -13,6 +14,34 @@ public static final String[] _fields = new String[] {"left","ops","comparators"}; + public Compare(Token token, exprType left, cmpopType[] ops, exprType[] + comparators) { + super(token); + this.left = left; + this.ops = ops; + this.comparators = comparators; + if (comparators != null) { + for(int + icomparators=0;icomparators<comparators.length;icomparators++) { + addChild(comparators[icomparators]); + } + } + } + + public Compare(int ttype, Token token, exprType left, cmpopType[] ops, + exprType[] comparators) { + super(ttype, token); + this.left = left; + this.ops = ops; + this.comparators = comparators; + if (comparators != null) { + for(int + icomparators=0;icomparators<comparators.length;icomparators++) { + addChild(comparators[icomparators]); + } + } + } + public Compare(PythonTree tree, exprType left, cmpopType[] ops, exprType[] comparators) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/Continue.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Continue.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Continue.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -9,6 +10,14 @@ public static final String[] _fields = new String[] {}; + public Continue(Token token) { + super(token); + } + + public Continue(int ttype, Token token) { + super(ttype, token); + } + public Continue(PythonTree tree) { super(tree); } Modified: branches/asm/src/org/python/antlr/ast/Delete.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Delete.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Delete.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,26 @@ public static final String[] _fields = new String[] {"targets"}; + public Delete(Token token, exprType[] targets) { + super(token); + this.targets = targets; + if (targets != null) { + for(int itargets=0;itargets<targets.length;itargets++) { + addChild(targets[itargets]); + } + } + } + + public Delete(int ttype, Token token, exprType[] targets) { + super(ttype, token); + this.targets = targets; + if (targets != null) { + for(int itargets=0;itargets<targets.length;itargets++) { + addChild(targets[itargets]); + } + } + } + public Delete(PythonTree tree, exprType[] targets) { super(tree); this.targets = targets; Modified: branches/asm/src/org/python/antlr/ast/Dict.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Dict.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Dict.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -11,6 +12,38 @@ public static final String[] _fields = new String[] {"keys","values"}; + public Dict(Token token, exprType[] keys, exprType[] values) { + super(token); + this.keys = keys; + if (keys != null) { + for(int ikeys=0;ikeys<keys.length;ikeys++) { + addChild(keys[ikeys]); + } + } + this.values = values; + if (values != null) { + for(int ivalues=0;ivalues<values.length;ivalues++) { + addChild(values[ivalues]); + } + } + } + + public Dict(int ttype, Token token, exprType[] keys, exprType[] values) { + super(ttype, token); + this.keys = keys; + if (keys != null) { + for(int ikeys=0;ikeys<keys.length;ikeys++) { + addChild(keys[ikeys]); + } + } + this.values = values; + if (values != null) { + for(int ivalues=0;ivalues<values.length;ivalues++) { + addChild(values[ivalues]); + } + } + } + public Dict(PythonTree tree, exprType[] keys, exprType[] values) { super(tree); this.keys = keys; Modified: branches/asm/src/org/python/antlr/ast/Ellipsis.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Ellipsis.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Ellipsis.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -9,6 +10,14 @@ public static final String[] _fields = new String[] {}; + public Ellipsis(Token token) { + super(token); + } + + public Ellipsis(int ttype, Token token) { + super(ttype, token); + } + public Ellipsis(PythonTree tree) { super(tree); } Modified: branches/asm/src/org/python/antlr/ast/Exec.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Exec.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Exec.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -13,6 +14,21 @@ public static final String[] _fields = new String[] {"body","globals","locals"}; + public Exec(Token token, exprType body, exprType globals, exprType locals) { + super(token); + this.body = body; + this.globals = globals; + this.locals = locals; + } + + public Exec(int ttype, Token token, exprType body, exprType globals, + exprType locals) { + super(ttype, token); + this.body = body; + this.globals = globals; + this.locals = locals; + } + public Exec(PythonTree tree, exprType body, exprType globals, exprType locals) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/Expr.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Expr.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Expr.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,16 @@ public static final String[] _fields = new String[] {"value"}; + public Expr(Token token, exprType value) { + super(token); + this.value = value; + } + + public Expr(int ttype, Token token, exprType value) { + super(ttype, token); + this.value = value; + } + public Expr(PythonTree tree, exprType value) { super(tree); this.value = value; Modified: branches/asm/src/org/python/antlr/ast/Expression.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Expression.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Expression.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,16 @@ public static final String[] _fields = new String[] {"body"}; + public Expression(Token token, exprType body) { + super(token); + this.body = body; + } + + public Expression(int ttype, Token token, exprType body) { + super(ttype, token); + this.body = body; + } + public Expression(PythonTree tree, exprType body) { super(tree); this.body = body; Modified: branches/asm/src/org/python/antlr/ast/ExtSlice.java =================================================================== --- branches/asm/src/org/python/antlr/ast/ExtSlice.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/ExtSlice.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,26 @@ public static final String[] _fields = new String[] {"dims"}; + public ExtSlice(Token token, sliceType[] dims) { + super(token); + this.dims = dims; + if (dims != null) { + for(int idims=0;idims<dims.length;idims++) { + addChild(dims[idims]); + } + } + } + + public ExtSlice(int ttype, Token token, sliceType[] dims) { + super(ttype, token); + this.dims = dims; + if (dims != null) { + for(int idims=0;idims<dims.length;idims++) { + addChild(dims[idims]); + } + } + } + public ExtSlice(PythonTree tree, sliceType[] dims) { super(tree); this.dims = dims; Modified: branches/asm/src/org/python/antlr/ast/For.java =================================================================== --- branches/asm/src/org/python/antlr/ast/For.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/For.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -14,6 +15,44 @@ public static final String[] _fields = new String[] {"target","iter","body","orelse"}; + public For(Token token, exprType target, exprType iter, stmtType[] body, + stmtType[] orelse) { + super(token); + this.target = target; + this.iter = iter; + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + this.orelse = orelse; + if (orelse != null) { + for(int iorelse=0;iorelse<orelse.length;iorelse++) { + addChild(orelse[iorelse]); + } + } + } + + public For(int ttype, Token token, exprType target, exprType iter, + stmtType[] body, stmtType[] orelse) { + super(ttype, token); + this.target = target; + this.iter = iter; + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + this.orelse = orelse; + if (orelse != null) { + for(int iorelse=0;iorelse<orelse.length;iorelse++) { + addChild(orelse[iorelse]); + } + } + } + public For(PythonTree tree, exprType target, exprType iter, stmtType[] body, stmtType[] orelse) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/FunctionDef.java =================================================================== --- branches/asm/src/org/python/antlr/ast/FunctionDef.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/FunctionDef.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -14,6 +15,44 @@ public static final String[] _fields = new String[] {"name","args","body","decorators"}; + public FunctionDef(Token token, String name, argumentsType args, stmtType[] + body, exprType[] decorators) { + super(token); + this.name = name; + this.args = args; + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + this.decorators = decorators; + if (decorators != null) { + for(int idecorators=0;idecorators<decorators.length;idecorators++) { + addChild(decorators[idecorators]); + } + } + } + + public FunctionDef(int ttype, Token token, String name, argumentsType args, + stmtType[] body, exprType[] decorators) { + super(ttype, token); + this.name = name; + this.args = args; + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + this.decorators = decorators; + if (decorators != null) { + for(int idecorators=0;idecorators<decorators.length;idecorators++) { + addChild(decorators[idecorators]); + } + } + } + public FunctionDef(PythonTree tree, String name, argumentsType args, stmtType[] body, exprType[] decorators) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/GeneratorExp.java =================================================================== --- branches/asm/src/org/python/antlr/ast/GeneratorExp.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/GeneratorExp.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -11,6 +12,30 @@ public static final String[] _fields = new String[] {"elt","generators"}; + public GeneratorExp(Token token, exprType elt, comprehensionType[] + generators) { + super(token); + this.elt = elt; + this.generators = generators; + if (generators != null) { + for(int igenerators=0;igenerators<generators.length;igenerators++) { + addChild(generators[igenerators]); + } + } + } + + public GeneratorExp(int ttype, Token token, exprType elt, + comprehensionType[] generators) { + super(ttype, token); + this.elt = elt; + this.generators = generators; + if (generators != null) { + for(int igenerators=0;igenerators<generators.length;igenerators++) { + addChild(generators[igenerators]); + } + } + } + public GeneratorExp(PythonTree tree, exprType elt, comprehensionType[] generators) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/Global.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Global.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Global.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,16 @@ public static final String[] _fields = new String[] {"names"}; + public Global(Token token, String[] names) { + super(token); + this.names = names; + } + + public Global(int ttype, Token token, String[] names) { + super(ttype, token); + this.names = names; + } + public Global(PythonTree tree, String[] names) { super(tree); this.names = names; Modified: branches/asm/src/org/python/antlr/ast/If.java =================================================================== --- branches/asm/src/org/python/antlr/ast/If.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/If.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -13,6 +14,41 @@ public static final String[] _fields = new String[] {"test","body","orelse"}; + public If(Token token, exprType test, stmtType[] body, stmtType[] orelse) { + super(token); + this.test = test; + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + this.orelse = orelse; + if (orelse != null) { + for(int iorelse=0;iorelse<orelse.length;iorelse++) { + addChild(orelse[iorelse]); + } + } + } + + public If(int ttype, Token token, exprType test, stmtType[] body, + stmtType[] orelse) { + super(ttype, token); + this.test = test; + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + this.orelse = orelse; + if (orelse != null) { + for(int iorelse=0;iorelse<orelse.length;iorelse++) { + addChild(orelse[iorelse]); + } + } + } + public If(PythonTree tree, exprType test, stmtType[] body, stmtType[] orelse) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/IfExp.java =================================================================== --- branches/asm/src/org/python/antlr/ast/IfExp.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/IfExp.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -13,6 +14,21 @@ public static final String[] _fields = new String[] {"test","body","orelse"}; + public IfExp(Token token, exprType test, exprType body, exprType orelse) { + super(token); + this.test = test; + this.body = body; + this.orelse = orelse; + } + + public IfExp(int ttype, Token token, exprType test, exprType body, exprType + orelse) { + super(ttype, token); + this.test = test; + this.body = body; + this.orelse = orelse; + } + public IfExp(PythonTree tree, exprType test, exprType body, exprType orelse) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/Import.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Import.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Import.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,26 @@ public static final String[] _fields = new String[] {"names"}; + public Import(Token token, aliasType[] names) { + super(token); + this.names = names; + if (names != null) { + for(int inames=0;inames<names.length;inames++) { + addChild(names[inames]); + } + } + } + + public Import(int ttype, Token token, aliasType[] names) { + super(ttype, token); + this.names = names; + if (names != null) { + for(int inames=0;inames<names.length;inames++) { + addChild(names[inames]); + } + } + } + public Import(PythonTree tree, aliasType[] names) { super(tree); this.names = names; Modified: branches/asm/src/org/python/antlr/ast/ImportFrom.java =================================================================== --- branches/asm/src/org/python/antlr/ast/ImportFrom.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/ImportFrom.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -13,6 +14,32 @@ public static final String[] _fields = new String[] {"module","names","level"}; + public ImportFrom(Token token, String module, aliasType[] names, int level) + { + super(token); + this.module = module; + this.names = names; + if (names != null) { + for(int inames=0;inames<names.length;inames++) { + addChild(names[inames]); + } + } + this.level = level; + } + + public ImportFrom(int ttype, Token token, String module, aliasType[] names, + int level) { + super(ttype, token); + this.module = module; + this.names = names; + if (names != null) { + for(int inames=0;inames<names.length;inames++) { + addChild(names[inames]); + } + } + this.level = level; + } + public ImportFrom(PythonTree tree, String module, aliasType[] names, int level) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/Index.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Index.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Index.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,16 @@ public static final String[] _fields = new String[] {"value"}; + public Index(Token token, exprType value) { + super(token); + this.value = value; + } + + public Index(int ttype, Token token, exprType value) { + super(ttype, token); + this.value = value; + } + public Index(PythonTree tree, exprType value) { super(tree); this.value = value; Modified: branches/asm/src/org/python/antlr/ast/Interactive.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Interactive.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Interactive.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,26 @@ public static final String[] _fields = new String[] {"body"}; + public Interactive(Token token, stmtType[] body) { + super(token); + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + } + + public Interactive(int ttype, Token token, stmtType[] body) { + super(ttype, token); + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + } + public Interactive(PythonTree tree, stmtType[] body) { super(tree); this.body = body; Modified: branches/asm/src/org/python/antlr/ast/Lambda.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Lambda.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Lambda.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -11,6 +12,18 @@ public static final String[] _fields = new String[] {"args","body"}; + public Lambda(Token token, argumentsType args, exprType body) { + super(token); + this.args = args; + this.body = body; + } + + public Lambda(int ttype, Token token, argumentsType args, exprType body) { + super(ttype, token); + this.args = args; + this.body = body; + } + public Lambda(PythonTree tree, argumentsType args, exprType body) { super(tree); this.args = args; Modified: branches/asm/src/org/python/antlr/ast/List.java =================================================================== --- branches/asm/src/org/python/antlr/ast/List.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/List.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -11,6 +12,28 @@ public static final String[] _fields = new String[] {"elts","ctx"}; + public List(Token token, exprType[] elts, expr_contextType ctx) { + super(token); + this.elts = elts; + if (elts != null) { + for(int ielts=0;ielts<elts.length;ielts++) { + addChild(elts[ielts]); + } + } + this.ctx = ctx; + } + + public List(int ttype, Token token, exprType[] elts, expr_contextType ctx) { + super(ttype, token); + this.elts = elts; + if (elts != null) { + for(int ielts=0;ielts<elts.length;ielts++) { + addChild(elts[ielts]); + } + } + this.ctx = ctx; + } + public List(PythonTree tree, exprType[] elts, expr_contextType ctx) { super(tree); this.elts = elts; Modified: branches/asm/src/org/python/antlr/ast/ListComp.java =================================================================== --- branches/asm/src/org/python/antlr/ast/ListComp.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/ListComp.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -11,6 +12,29 @@ public static final String[] _fields = new String[] {"elt","generators"}; + public ListComp(Token token, exprType elt, comprehensionType[] generators) { + super(token); + this.elt = elt; + this.generators = generators; + if (generators != null) { + for(int igenerators=0;igenerators<generators.length;igenerators++) { + addChild(generators[igenerators]); + } + } + } + + public ListComp(int ttype, Token token, exprType elt, comprehensionType[] + generators) { + super(ttype, token); + this.elt = elt; + this.generators = generators; + if (generators != null) { + for(int igenerators=0;igenerators<generators.length;igenerators++) { + addChild(generators[igenerators]); + } + } + } + public ListComp(PythonTree tree, exprType elt, comprehensionType[] generators) { super(tree); Modified: branches/asm/src/org/python/antlr/ast/Module.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Module.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Module.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,26 @@ public static final String[] _fields = new String[] {"body"}; + public Module(Token token, stmtType[] body) { + super(token); + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + } + + public Module(int ttype, Token token, stmtType[] body) { + super(ttype, token); + this.body = body; + if (body != null) { + for(int ibody=0;ibody<body.length;ibody++) { + addChild(body[ibody]); + } + } + } + public Module(PythonTree tree, stmtType[] body) { super(tree); this.body = body; Modified: branches/asm/src/org/python/antlr/ast/Name.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Name.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Name.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -11,6 +12,18 @@ public static final String[] _fields = new String[] {"id","ctx"}; + public Name(Token token, String id, expr_contextType ctx) { + super(token); + this.id = id; + this.ctx = ctx; + } + + public Name(int ttype, Token token, String id, expr_contextType ctx) { + super(ttype, token); + this.id = id; + this.ctx = ctx; + } + public Name(PythonTree tree, String id, expr_contextType ctx) { super(tree); this.id = id; Modified: branches/asm/src/org/python/antlr/ast/Num.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Num.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Num.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -10,6 +11,16 @@ public static final String[] _fields = new String[] {"n"}; + public Num(Token token, Object n) { + super(token); + this.n = n; + } + + public Num(int ttype, Token token, Object n) { + super(ttype, token); + this.n = n; + } + public Num(PythonTree tree, Object n) { super(tree); this.n = n; Modified: branches/asm/src/org/python/antlr/ast/Pass.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Pass.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Pass.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -9,6 +10,14 @@ public static final String[] _fields = new String[] {}; + public Pass(Token token) { + super(token); + } + + public Pass(int ttype, Token token) { + super(ttype, token); + } + public Pass(PythonTree tree) { super(tree); } Modified: branches/asm/src/org/python/antlr/ast/Print.java =================================================================== --- branches/asm/src/org/python/antlr/ast/Print.java 2008-06-03 04:36:28 UTC (rev 4522) +++ branches/asm/src/org/python/antlr/ast/Print.java 2008-06-03 06:39:41 UTC (rev 4523) @@ -1,6 +1,7 @@ // Autogenerated AST node package org.python.antlr.ast; import org.python.antlr.PythonTree; +import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import java.io.DataOutputStream; import java.io.IOException; @@ -12,6 +13,31 @@ public static final String[] _fields = new String[] {"dest","values","nl"}; + public Print(Token token, exprType dest, exprType[] values, boolean nl) { + super(token); + this.dest = dest; + this.values = values; + if (values != null) { + ... [truncated message content] |