From: <fwi...@us...> - 2009-03-10 19:00:06
|
Revision: 6088 http://jython.svn.sourceforge.net/jython/?rev=6088&view=rev Author: fwierzbicki Date: 2009-03-10 18:59:50 +0000 (Tue, 10 Mar 2009) Log Message: ----------- increment version and README for another beta. Modified Paths: -------------- trunk/jython/README.txt trunk/jython/build.xml Modified: trunk/jython/README.txt =================================================================== --- trunk/jython/README.txt 2009-03-10 18:47:33 UTC (rev 6087) +++ trunk/jython/README.txt 2009-03-10 18:59:50 UTC (rev 6088) @@ -1,9 +1,11 @@ -Welcome to Jython 2.5b2 +Welcome to Jython 2.5b3 ======================= -This is the third beta of the 2.5 version of Jython. It -contains all of the new features for the 2.5 release and represents a feature -freeze. +This is the forth beta of the 2.5 version of Jython. It contains a couple of +bug fixes since the 2.5b2 release a couple of days ago. The bug that promted +another release was a corner case on Windows that caused Jython to not start. +This beta contains all of the new features for the eventual 2.5 release and +represents a feature freeze. The release was compiled on Mac OS X with JDK 5 and requires JDK 5 to run. Modified: trunk/jython/build.xml =================================================================== --- trunk/jython/build.xml 2009-03-10 18:47:33 UTC (rev 6087) +++ trunk/jython/build.xml 2009-03-10 18:59:50 UTC (rev 6088) @@ -188,13 +188,13 @@ <property name="PY_RELEASE_LEVEL_SNAPSHOT" value="170"/> <!-- 0xAA --> <!-- The current version info --> - <property name="jython.version" value="2.5b2+"/> - <property name="jython.version.noplus" value="2.5b2"/> + <property name="jython.version" value="2.5b3+"/> + <property name="jython.version.noplus" value="2.5b3"/> <property name="jython.major_version" value="2"/> <property name="jython.minor_version" value="5"/> <property name="jython.micro_version" value="0"/> <property name="jython.release_level" value="${PY_RELEASE_LEVEL_BETA}"/> - <property name="jython.release_serial" value="2"/> + <property name="jython.release_serial" value="3"/> <condition property="do.snapshot.build"> <isset property="snapshot.revision" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-13 02:22:33
|
Revision: 6094 http://jython.svn.sourceforge.net/jython/?rev=6094&view=rev Author: fwierzbicki Date: 2009-03-13 01:33:46 +0000 (Fri, 13 Mar 2009) Log Message: ----------- Fix for http://bugs.jython.org/issue1215: extra spaces in import statement break importing. Modified Paths: -------------- trunk/jython/Lib/test/test_ast_jy.py trunk/jython/NEWS trunk/jython/grammar/Python.g trunk/jython/src/org/python/antlr/GrammarActions.java Modified: trunk/jython/Lib/test/test_ast_jy.py =================================================================== --- trunk/jython/Lib/test/test_ast_jy.py 2009-03-11 17:13:03 UTC (rev 6093) +++ trunk/jython/Lib/test/test_ast_jy.py 2009-03-13 01:33:46 UTC (rev 6094) @@ -11,6 +11,17 @@ node = compile("1/2", '<unknown>', 'exec', PyCF_ONLY_AST) compile(node, "<string>", 'exec') + def test_alias_trim(self): + node = compile("import os. path", '<unknown>', 'exec', PyCF_ONLY_AST) + self.assertEquals(node.body[0].names[0].name, "os.path") + + node = compile("import os .path", '<unknown>', 'exec', PyCF_ONLY_AST) + self.assertEquals(node.body[0].names[0].name, "os.path") + + node = compile("import os . path", '<unknown>', 'exec', PyCF_ONLY_AST) + self.assertEquals(node.body[0].names[0].name, "os.path") + + #============================================================================== def test_main(verbose=None): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-03-11 17:13:03 UTC (rev 6093) +++ trunk/jython/NEWS 2009-03-13 01:33:46 UTC (rev 6094) @@ -1,7 +1,11 @@ Jython NEWS -Jython 2.5 +Jython 2.5.0 rc 1 Bugs fixed (new numbering due to move to Roundup) + - [ 1215 ] extra spaces in import statement break importing + +Jython 2.5.0 a0 - b3 + Bugs fixed (new numbering due to move to Roundup) - [ 1126 ] ImportError raised for Java subpackages import - [ 1111 ] keyword arguments not supported on __import__ - [ 1567212 ] Jython $py.class bytecode doesn't include the .py's mtime Modified: trunk/jython/grammar/Python.g =================================================================== --- trunk/jython/grammar/Python.g 2009-03-11 17:13:03 UTC (rev 6093) +++ trunk/jython/grammar/Python.g 2009-03-13 01:33:46 UTC (rev 6094) @@ -739,13 +739,13 @@ import_from : FROM (d+=DOT* dotted_name | d+=DOT+) IMPORT (STAR - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.text), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), actions.makeStarAlias($STAR), actions.makeLevel($d)]) | i1=import_as_names - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.text), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), actions.makeAliases($i1.atypes), actions.makeLevel($d)]) | LPAREN i2=import_as_names COMMA? RPAREN - -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.text), + -> ^(FROM<ImportFrom>[$FROM, actions.makeFromText($d, $dotted_name.name), actions.makeAliases($i2.atypes), actions.makeLevel($d)]) ) ; @@ -778,7 +778,7 @@ : dotted_name (AS NAME)? { - $atype = new alias($NAME, $dotted_name.text, $NAME.text); + $atype = new alias($NAME, $dotted_name.name, $NAME.text); } ; @@ -791,8 +791,10 @@ ; //dotted_name: NAME ('.' NAME)* -dotted_name - : NAME (DOT attr)* +dotted_name returns [String name] + : NAME (DOT dn+=attr)* { + $name = actions.makeDottedText($NAME, $dn); + } ; //global_stmt: 'global' NAME (',' NAME)* Modified: trunk/jython/src/org/python/antlr/GrammarActions.java =================================================================== --- trunk/jython/src/org/python/antlr/GrammarActions.java 2009-03-11 17:13:03 UTC (rev 6093) +++ trunk/jython/src/org/python/antlr/GrammarActions.java 2009-03-13 01:33:46 UTC (rev 6094) @@ -723,4 +723,17 @@ return s; } + public String makeDottedText(Token name, List<PythonTree> c) { + final String dot = "."; + if (c == null || c.isEmpty()) { + return name.getText(); + } + StringBuilder b = new StringBuilder(name.getText()); + for (PythonTree t : c) { + b.append(dot); + b.append(t.getToken().getText()); + } + return b.toString(); + } + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-14 23:21:51
|
Revision: 6095 http://jython.svn.sourceforge.net/jython/?rev=6095&view=rev Author: pjenvey Date: 2009-03-14 23:21:30 +0000 (Sat, 14 Mar 2009) Log Message: ----------- o gracefully handle a System.getenv SecurityException on startup o grant more permissions needed for test_java_integration's test_nonexistent_import_with_security Modified Paths: -------------- trunk/jython/Lib/test/python_home.policy trunk/jython/src/org/python/core/PySystemState.java Modified: trunk/jython/Lib/test/python_home.policy =================================================================== --- trunk/jython/Lib/test/python_home.policy 2009-03-13 01:33:46 UTC (rev 6094) +++ trunk/jython/Lib/test/python_home.policy 2009-03-14 23:21:30 UTC (rev 6095) @@ -1,5 +1,8 @@ grant codeBase "file:${python.home}/-" { + permission java.io.FilePermission "<<ALL FILES>>", "read,write"; + permission java.lang.RuntimePermission "accessDeclaredMembers"; + permission java.lang.RuntimePermission "createClassLoader"; + permission java.lang.RuntimePermission "getProtectionDomain"; permission java.util.PropertyPermission "*", "read,write"; - permission java.io.FilePermission "<<ALL FILES>>", "read,write"; }; Modified: trunk/jython/src/org/python/core/PySystemState.java =================================================================== --- trunk/jython/src/org/python/core/PySystemState.java 2009-03-13 01:33:46 UTC (rev 6094) +++ trunk/jython/src/org/python/core/PySystemState.java 2009-03-14 23:21:30 UTC (rev 6095) @@ -400,12 +400,18 @@ } /** - * Initialize the environ dict from System.getenv. - * + * Initialize the environ dict from System.getenv. environ may be empty when the + * security policy doesn't grant us access. */ public void initEnviron() { environ = new PyDictionary(); - for (Map.Entry<String, String> entry : System.getenv().entrySet()) { + Map<String, String> env; + try { + env = System.getenv(); + } catch (SecurityException se) { + return; + } + for (Map.Entry<String, String> entry : env.entrySet()) { environ.__setitem__(Py.newString(entry.getKey()), Py.newString(entry.getValue())); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-17 19:00:41
|
Revision: 6099 http://jython.svn.sourceforge.net/jython/?rev=6099&view=rev Author: fwierzbicki Date: 2009-03-17 19:00:26 +0000 (Tue, 17 Mar 2009) Log Message: ----------- Applied patch from http://bugs.jython.org/issue1148 to AstList to fix ClassCastException for slices. Also merged the test included in issue1148 into test_ast_jy.py with some small changes, especially the formatting to fit with pep 8 style. Thanks Geoffrey French (MrMeanie)! Modified Paths: -------------- trunk/jython/Lib/test/test_ast_jy.py trunk/jython/src/org/python/core/AstList.java Modified: trunk/jython/Lib/test/test_ast_jy.py =================================================================== --- trunk/jython/Lib/test/test_ast_jy.py 2009-03-17 02:59:34 UTC (rev 6098) +++ trunk/jython/Lib/test/test_ast_jy.py 2009-03-17 19:00:26 UTC (rev 6099) @@ -2,25 +2,40 @@ future""" import unittest +import ast from test import test_support -from ast import PyCF_ONLY_AST +def srcExprToTree(source, kind='exec'): + return compile(source, '<module>', kind, ast.PyCF_ONLY_AST) + class TestCompile(unittest.TestCase): def test_compile_ast(self): - node = compile("1/2", '<unknown>', 'exec', PyCF_ONLY_AST) + node = srcExprToTree("1/2") compile(node, "<string>", 'exec') def test_alias_trim(self): - node = compile("import os. path", '<unknown>', 'exec', PyCF_ONLY_AST) + node = srcExprToTree("import os. path") self.assertEquals(node.body[0].names[0].name, "os.path") - node = compile("import os .path", '<unknown>', 'exec', PyCF_ONLY_AST) + node = srcExprToTree("import os .path") self.assertEquals(node.body[0].names[0].name, "os.path") - node = compile("import os . path", '<unknown>', 'exec', PyCF_ONLY_AST) + node = srcExprToTree("import os . path") self.assertEquals(node.body[0].names[0].name, "os.path") + def test_cmpop(self): + expr = srcExprToTree('a < b < c', 'eval') + compare = expr.body + self.assert_(isinstance(compare.ops[0], ast.Lt)) + self.assert_(isinstance(compare.comparators[0], ast.Name)) + self.assert_(isinstance(compare.ops[1], ast.Lt)) + self.assert_(isinstance(compare.comparators[1], ast.Name)) + self.assert_(isinstance(compare.ops[1:][0], ast.Lt)) + self.assert_(isinstance(compare.comparators[1:][0], ast.Name)) + z = zip( compare.ops[1:], compare.comparators[1:]) + self.assert_(isinstance(z[0][0], ast.Lt)) + self.assert_(isinstance(z[0][1], ast.Name)) #============================================================================== Modified: trunk/jython/src/org/python/core/AstList.java =================================================================== --- trunk/jython/src/org/python/core/AstList.java 2009-03-17 02:59:34 UTC (rev 6098) +++ trunk/jython/src/org/python/core/AstList.java 2009-03-17 19:00:26 UTC (rev 6099) @@ -376,14 +376,14 @@ List newList = data.subList(start, stop); if(step == 1) { newList = data.subList(start, stop); - return new AstList(newList); + return new AstList(newList, adapter); } int j = 0; for(int i = start; j < n; i += step) { newList.set(j, data.get(i)); j++; } - return new AstList(newList); + return new AstList(newList, adapter); } public void insert(int index, PyObject o) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-03-21 21:23:26
|
Revision: 6103 http://jython.svn.sourceforge.net/jython/?rev=6103&view=rev Author: zyasoft Date: 2009-03-21 21:23:22 +0000 (Sat, 21 Mar 2009) Log Message: ----------- Reinstated PythonInterpreter#setErr(java.io.Writer), #setOut(java.io.Writer) (but deprecating). This uses PyFileWriter which implements a file-like interface sufficient for stdout/stderr usage. Fixes #1266 Modified Paths: -------------- trunk/jython/src/org/python/core/StdoutWrapper.java trunk/jython/src/org/python/util/PythonInterpreter.java Added Paths: ----------- trunk/jython/Lib/test/test_pythoninterpreter_jy.py trunk/jython/src/org/python/core/PyFileWriter.java Added: trunk/jython/Lib/test/test_pythoninterpreter_jy.py =================================================================== --- trunk/jython/Lib/test/test_pythoninterpreter_jy.py (rev 0) +++ trunk/jython/Lib/test/test_pythoninterpreter_jy.py 2009-03-21 21:23:22 UTC (rev 6103) @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +import java.io.StringWriter +import sys +import traceback +import unittest +import test.test_support + + +def exec_code_in_pi(function, out, err, locals=None): + """Runs code in a separate context: (thread, PySystemState, PythonInterpreter)""" + + def function_context(): + from org.python.core import Py + from org.python.util import PythonInterpreter + from org.python.core import PySystemState + + ps = PySystemState() + pi = PythonInterpreter({}, ps) + if locals: + pi.setLocals(locals) + pi.setOut(out) + pi.setErr(err) + try: + pi.exec(function.func_code) + except: + print '-'*60 + traceback.print_exc(file=sys.stdout) + print '-'*60 + + + import threading + context = threading.Thread(target=function_context) + context.start() + context.join() + + +class InterpreterTest(unittest.TestCase): + + # in these tests, note the promotion to unicode by java.io.Writer, + # because these are character-oriented streams. caveat emptor! + + def test_pi_out_unicode(self): + source_text = [ + u'Some text', + 'Plain text', + u'\u1000\u2000\u3000\u4000', + # Some language names from wikipedia + u'Català · Česky · Dansk · Deutsch · English · Español · Esperanto · Français · Bahasa Indonesia · Italiano · Magyar · Nederlands · 日本語 · Norsk (bokmål) · Polski · Português · Русский · Română · Slovenčina · Suomi · Svenska · Türkçe · Українська · Volapük · 中文', + ] + + def f(): + global text + for x in text: + print x + out = java.io.StringWriter() + err = java.io.StringWriter() + exec_code_in_pi(f, out, err, {'text': source_text}) + output_text = out.toString().splitlines() + for source, output in zip(source_text, output_text): + self.assertEquals(source, output) + + def test_pi_out(self): + def f(): + print 42 + out = java.io.StringWriter() + err = java.io.StringWriter() + exec_code_in_pi(f, out, err) + self.assertEquals(u"42\n", out.toString()) + + def test_more_output(self): + def f(): + for i in xrange(42): + print "*" * i + out = java.io.StringWriter() + err = java.io.StringWriter() + exec_code_in_pi(f, out, err) + output = out.toString().splitlines() + for i, line in enumerate(output): + self.assertEquals(line, u'*' * i) + self.assertEquals(42, len(output)) + + + +def test_main(): + test.test_support.run_unittest(InterpreterTest) + +if __name__ == "__main__": + test_main() Added: trunk/jython/src/org/python/core/PyFileWriter.java =================================================================== --- trunk/jython/src/org/python/core/PyFileWriter.java (rev 0) +++ trunk/jython/src/org/python/core/PyFileWriter.java 2009-03-21 21:23:22 UTC (rev 6103) @@ -0,0 +1,83 @@ +// A file-like object for writing to java.io.Writer objects; +// only to be used for stdout, stderr in PythonInterpreter#setOut(Writer), #setErr(Writer) +// (for backwards compatibility) +// +// no attempts to close etc at shutdown are done for this object (unlike PyFile), +// since again just for PythonInterpreter +// nor is this exposed as a type +package org.python.core; + +import java.io.Writer; +import java.io.IOException; + +public class PyFileWriter extends PyObject { + + private final Writer writer; + private boolean closed; + public boolean softspace = false; + + public PyFileWriter(Writer writer) { + this.writer = writer; + closed = false; + } + + public boolean closed() { + return closed; + } + + public void checkClosed() { + if (closed()) { + throw Py.ValueError("I/O operation on closed file"); + } + } + + public synchronized void flush() { + checkClosed(); + try { + writer.flush(); + } catch (IOException e) { + throw Py.IOError(e); + } + } + + public void close() { + try { + writer.close(); + closed = true; + } catch (IOException e) { + throw Py.IOError(e); + } + } + + public void write(PyObject o) { + if (o instanceof PyUnicode) { + write(((PyUnicode) o).string); + } else if (o instanceof PyString) { + write(((PyString) o).string); + } else { + throw Py.TypeError("write requires a string as its argument"); + } + } + + public synchronized void write(String s) { + checkClosed(); + try { + writer.write(s); + } catch (IOException e) { + throw Py.IOError(e); + } + } + + public synchronized void writelines(PyObject a) { + checkClosed(); + PyObject iter = Py.iter(a, "writelines() requires an iterable argument"); + + PyObject item = null; + while ((item = iter.__iternext__()) != null) { + if (!(item instanceof PyString)) { + throw Py.TypeError("writelines() argument must be a sequence of strings"); + } + write(item); + } + } +} Modified: trunk/jython/src/org/python/core/StdoutWrapper.java =================================================================== --- trunk/jython/src/org/python/core/StdoutWrapper.java 2009-03-20 01:16:13 UTC (rev 6102) +++ trunk/jython/src/org/python/core/StdoutWrapper.java 2009-03-21 21:23:22 UTC (rev 6103) @@ -122,6 +122,36 @@ file.softspace = false; } file.flush(); + } else if (obj instanceof PyFileWriter) { + PyFileWriter file = (PyFileWriter)obj; + if (file.softspace) { + file.write(" "); + file.softspace = false; + } + + // since we are outputting directly to a character stream, + // avoid doing an encoding + String s; + if (o instanceof PyString) { + s = ((PyString)o).string; + } else { + s = o.toString(); + } + int len = s.length(); + file.write(s); + if (o instanceof PyString) { + if (len == 0 || !Character.isWhitespace(s.charAt(len - 1)) + || s.charAt(len - 1) == ' ') { + file.softspace = space; + } + } else { + file.softspace = space; + } + if (newline) { + file.write("\n"); + file.softspace = false; + } + file.flush(); } else { PyObject ss = obj.__findattr__("softspace"); if (ss != null && ss.__nonzero__()) { Modified: trunk/jython/src/org/python/util/PythonInterpreter.java =================================================================== --- trunk/jython/src/org/python/util/PythonInterpreter.java 2009-03-20 01:16:13 UTC (rev 6102) +++ trunk/jython/src/org/python/util/PythonInterpreter.java 2009-03-21 21:23:22 UTC (rev 6103) @@ -7,6 +7,7 @@ import org.python.core.PyCode; import org.python.core.PyException; import org.python.core.PyFile; +import org.python.core.PyFileWriter; import org.python.core.PyModule; import org.python.core.PyObject; import org.python.core.PyString; @@ -90,6 +91,11 @@ systemState.stdout = outStream; } + /** @deprecated */ + public void setOut(java.io.Writer outStream) { + setOut(new PyFileWriter(outStream)); + } + /** * Set a java.io.OutputStream to use for the standard output stream * @@ -104,6 +110,11 @@ systemState.stderr = outStream; } + /** @deprecated */ + public void setErr(java.io.Writer outStream) { + setErr(new PyFileWriter(outStream)); + } + public void setErr(java.io.OutputStream outStream) { setErr(new PyFile(outStream)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <zy...@us...> - 2009-03-22 03:00:56
|
Revision: 6106 http://jython.svn.sourceforge.net/jython/?rev=6106&view=rev Author: zyasoft Date: 2009-03-22 03:00:51 +0000 (Sun, 22 Mar 2009) Log Message: ----------- dict() now can be constructed from a Map in user-level code. This fixes bug #1146. Modified Paths: -------------- trunk/jython/Lib/test/test_dict_jy.py trunk/jython/src/org/python/core/PyDictionary.java Modified: trunk/jython/Lib/test/test_dict_jy.py =================================================================== --- trunk/jython/Lib/test/test_dict_jy.py 2009-03-21 22:29:19 UTC (rev 6105) +++ trunk/jython/Lib/test/test_dict_jy.py 2009-03-22 03:00:51 UTC (rev 6106) @@ -1,4 +1,5 @@ from test import test_support +import java import unittest class DictInitTest(unittest.TestCase): @@ -93,9 +94,29 @@ raise CustomKeyError("custom message") self.assertRaises(CustomKeyError, lambda: DerivedDict()['foo']) +class JavaIntegrationTest(unittest.TestCase): + "Tests for instantiating dicts from Java maps and hashtables" + def test_hashmap(self): + x = java.util.HashMap() + x.put('a', 1) + x.put('b', 2) + x.put('c', 3) + x.put((1,2), "xyz") + y = dict(x) + self.assertEqual(set(y.items()), set([('a', 1), ('b', 2), ('c', 3), ((1,2), "xyz")])) + def test_hashtable(self): + x = java.util.Hashtable() + x.put('a', 1) + x.put('b', 2) + x.put('c', 3) + x.put((1,2), "xyz") + y = dict(x) + self.assertEqual(set(y.items()), set([('a', 1), ('b', 2), ('c', 3), ((1,2), "xyz")])) + + def test_main(): - test_support.run_unittest(DictInitTest, DictCmpTest, DerivedDictTest) + test_support.run_unittest(DictInitTest, DictCmpTest, DerivedDictTest, JavaIntegrationTest) if __name__ == '__main__': test_main() Modified: trunk/jython/src/org/python/core/PyDictionary.java =================================================================== --- trunk/jython/src/org/python/core/PyDictionary.java 2009-03-21 22:29:19 UTC (rev 6105) +++ trunk/jython/src/org/python/core/PyDictionary.java 2009-03-22 03:00:51 UTC (rev 6106) @@ -4,6 +4,7 @@ import java.util.AbstractSet; import java.util.ArrayList; import java.util.Collection; +import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -421,7 +422,12 @@ } if (nargs == 1) { PyObject arg = args[0]; - if (arg.__findattr__("keys") != null) { + + Object proxy = arg.getJavaProxy(); + if (proxy instanceof Map) { + merge((Map)proxy); + } + else if (arg.__findattr__("keys") != null) { merge(arg); } else { mergeFromSeq(arg); @@ -432,6 +438,13 @@ } } + private void merge(Map<Object,Object> other) { + for (Entry<Object,Object> entry : other.entrySet()) { + dict___setitem__(Py.java2py(entry.getKey()), Py.java2py(entry.getValue())); + } + } + + /** * Merge another PyObject that supports keys() with this * dict. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-27 19:03:55
|
Revision: 6109 http://jython.svn.sourceforge.net/jython/?rev=6109&view=rev Author: pjenvey Date: 2009-03-27 19:03:30 +0000 (Fri, 27 Mar 2009) Log Message: ----------- have java integration translate faux-floats (objects implementing __float__) to Java floats patch from zyasoft fixes #1198 Modified Paths: -------------- trunk/jython/Lib/test/test_float_jy.py trunk/jython/src/org/python/core/PyObject.java Modified: trunk/jython/Lib/test/test_float_jy.py =================================================================== --- trunk/jython/Lib/test/test_float_jy.py 2009-03-26 16:49:14 UTC (rev 6108) +++ trunk/jython/Lib/test/test_float_jy.py 2009-03-27 19:03:30 UTC (rev 6109) @@ -98,7 +98,13 @@ # regression in 2.5 alphas self.assertEqual(4.0 ** Foo(), 16.0) + def test_faux(self): + class F(object): + def __float__(self): + return 1.6 + self.assertEqual(math.cos(1.6), math.cos(F())) + def test_main(): test_support.run_unittest(FloatTestCase) Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-03-26 16:49:14 UTC (rev 6108) +++ trunk/jython/src/org/python/core/PyObject.java 2009-03-27 19:03:30 UTC (rev 6109) @@ -264,6 +264,20 @@ if (c.isInstance(getJavaProxy())) { return javaProxy; } + + // convert faux floats + // XXX: should also convert faux ints, but that breaks test_java_visibility + // (ReflectedArgs resolution) + if (c == Double.TYPE || c == Double.class || c == Float.TYPE || c == Float.class) { + try { + return __float__().getValue(); + } catch (PyException pye) { + if (!Py.matchException(pye, Py.AttributeError)) { + throw pye; + } + } + } + return Py.NoConversion; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-27 23:22:15
|
Revision: 6112 http://jython.svn.sourceforge.net/jython/?rev=6112&view=rev Author: pjenvey Date: 2009-03-27 23:21:59 +0000 (Fri, 27 Mar 2009) Log Message: ----------- fix type serialization broken by the now fully qualified type names thanks Sergei fixes #1282 Modified Paths: -------------- trunk/jython/Lib/test/test_java_integration.py trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/Lib/test/test_java_integration.py =================================================================== --- trunk/jython/Lib/test/test_java_integration.py 2009-03-27 21:44:57 UTC (rev 6111) +++ trunk/jython/Lib/test/test_java_integration.py 2009-03-27 23:21:59 UTC (rev 6112) @@ -10,8 +10,9 @@ from java.lang import (ClassCastException, ExceptionInInitializerError, String, Runnable, System, Runtime, Math, Byte) from java.math import BigDecimal, BigInteger -from java.io import (File, FileInputStream, FileNotFoundException, FileOutputStream, FileWriter, - OutputStreamWriter, UnsupportedEncodingException) +from java.io import (ByteArrayInputStream, ByteArrayOutputStream, File, FileInputStream, + FileNotFoundException, FileOutputStream, FileWriter, ObjectInputStream, + ObjectOutputStream, OutputStreamWriter, UnsupportedEncodingException) from java.util import ArrayList, Date, HashMap, Hashtable, StringTokenizer, Vector from java.awt import Dimension, Color, Component, Container @@ -425,6 +426,19 @@ self.assertRaises(TypeError, __import__, "org.python.tests.mro.ConfusedOnImport") self.assertRaises(TypeError, GetitemAdder.addPostdefined) +class SerializationTest(unittest.TestCase): + + def test_java_serialization(self): + date_list = [Date(), Date()] + output = ByteArrayOutputStream() + serializer = ObjectOutputStream(output) + serializer.writeObject(date_list) + serializer.close() + + input = ByteArrayInputStream(output.toByteArray()) + unserializer = ObjectInputStream(input) + self.assertEqual(date_list, unserializer.readObject()) + def test_main(): test_support.run_unittest(InstantiationTest, BeanTest, @@ -439,7 +453,8 @@ JavaStringTest, JavaDelegationTest, SecurityManagerTest, - JavaWrapperCustomizationTest) + JavaWrapperCustomizationTest, + SerializationTest) if __name__ == "__main__": test_main() Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-03-27 21:44:57 UTC (rev 6111) +++ trunk/jython/src/org/python/core/PyType.java 2009-03-27 23:21:59 UTC (rev 6112) @@ -1376,7 +1376,7 @@ /** Used when serializing this type. */ protected Object writeReplace() { - return new TypeResolver(underlying_class, getModule().toString(), name); + return new TypeResolver(underlying_class, getModule().toString(), getName()); } private interface OnType { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-03-29 22:11:45
|
Revision: 6115 http://jython.svn.sourceforge.net/jython/?rev=6115&view=rev Author: thobes Date: 2009-03-29 22:11:34 +0000 (Sun, 29 Mar 2009) Log Message: ----------- Patched the compiler paths for type stafety. The kind is now an enum (from builtin.compile and down) The compile methods now return PyCode (from builtin.compile and down) This simplifies the compiler paths, the check for if AST or code should be returned is now in only one place and the parser dispatch is simpler(less code) Modified Paths: -------------- trunk/jython/Lib/codeop.py trunk/jython/src/org/python/Version.java trunk/jython/src/org/python/antlr/BaseParser.java trunk/jython/src/org/python/antlr/ast/AstModule.java trunk/jython/src/org/python/compiler/Future.java trunk/jython/src/org/python/compiler/Module.java trunk/jython/src/org/python/compiler/pbc/Bytecode.java trunk/jython/src/org/python/core/CompilerFlags.java trunk/jython/src/org/python/core/ParserFacade.java trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/PyBaseCode.java trunk/jython/src/org/python/core/PyBytecode.java trunk/jython/src/org/python/core/PyFrame.java trunk/jython/src/org/python/core/PyTableCode.java trunk/jython/src/org/python/core/__builtin__.java trunk/jython/src/org/python/core/imp.java trunk/jython/src/org/python/util/InteractiveInterpreter.java trunk/jython/src/org/python/util/PythonInterpreter.java trunk/jython/src/org/python/util/jython.java trunk/jython/tests/java/org/python/antlr/PythonTreeTester.java Added Paths: ----------- trunk/jython/src/org/python/core/CodeFlag.java trunk/jython/src/org/python/core/CompileMode.java trunk/jython/src/org/python/core/FutureFeature.java trunk/jython/src/org/python/core/Pragma.java trunk/jython/src/org/python/core/PragmaReceiver.java Removed Paths: ------------- trunk/jython/src/org/python/antlr/ExpressionParser.java trunk/jython/src/org/python/antlr/InteractiveParser.java trunk/jython/src/org/python/antlr/ModuleParser.java Modified: trunk/jython/Lib/codeop.py =================================================================== --- trunk/jython/Lib/codeop.py 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/Lib/codeop.py 2009-03-29 22:11:34 UTC (rev 6115) @@ -57,8 +57,8 @@ """ # import internals, not guaranteed interface -from org.python.core import Py,CompilerFlags -from org.python.core.PyTableCode import PyCF_DONT_IMPLY_DEDENT +from org.python.core import Py,CompilerFlags,CompileMode +from org.python.core.CompilerFlags import PyCF_DONT_IMPLY_DEDENT # public interface @@ -84,6 +84,7 @@ """ if symbol not in ['single','eval']: raise ValueError,"symbol arg must be either single or eval" + symbol = CompileMode.getMode(symbol) return Py.compile_command_flags(source,filename,symbol,Py.getCompilerFlags(),0) class Compile: @@ -95,6 +96,7 @@ self._cflags = CompilerFlags() def __call__(self, source, filename, symbol): + symbol = CompileMode.getMode(symbol) return Py.compile_flags(source, filename, symbol, self._cflags) class CommandCompiler: @@ -128,5 +130,6 @@ """ if symbol not in ['single','eval']: raise ValueError,"symbol arg must be either single or eval" + symbol = CompileMode.getMode(symbol) return Py.compile_command_flags(source,filename,symbol,self._cflags,0) Modified: trunk/jython/src/org/python/Version.java =================================================================== --- trunk/jython/src/org/python/Version.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/Version.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -3,8 +3,14 @@ import java.io.InputStream; import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.EnumSet; import java.util.Properties; +import java.util.Set; +import org.python.core.CodeFlag; + /** * Jython version information. * @@ -36,6 +42,10 @@ /** Short version of branch, e.g. asm. */ public static String SHORT_BRANCH; + /** The flags that are set by default in a code object. */ + private static final Collection<CodeFlag> defaultCodeFlags = Arrays.asList( + CodeFlag.CO_NESTED, CodeFlag.CO_GENERATOR_ALLOWED); + private static final String headURL = "$HeadURL$"; @@ -144,4 +154,8 @@ public static String getVersion() { return String.format("%.80s (%.80s) %.80s", PY_VERSION, getBuildInfo(), getVM()); } + + public static Set<CodeFlag> getDefaultCodeFlags() { + return EnumSet.copyOf(defaultCodeFlags); + } } Modified: trunk/jython/src/org/python/antlr/BaseParser.java =================================================================== --- trunk/jython/src/org/python/antlr/BaseParser.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/BaseParser.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,15 +1,31 @@ package org.python.antlr; import org.antlr.runtime.CharStream; +import org.antlr.runtime.CommonTokenStream; +import org.antlr.runtime.RecognitionException; import org.antlr.runtime.Token; +import org.python.antlr.base.mod; public class BaseParser { - protected CharStream charStream; - protected boolean partial; - protected String filename; - protected String encoding; + protected final CharStream charStream; + @Deprecated + protected final boolean partial; + protected final String filename; + protected final String encoding; protected ErrorHandler errorHandler = new FailFastHandler(); + + public BaseParser(CharStream stream, String filename, String encoding) { + this(stream, filename, encoding, false); + } + + @Deprecated + public BaseParser(CharStream stream, String filename, String encoding, boolean partial) { + this.charStream = stream; + this.filename = filename; + this.encoding = encoding; + this.partial = partial; + } public void setAntlrErrorHandler(ErrorHandler eh) { this.errorHandler = eh; @@ -25,4 +41,60 @@ return super.nextToken(); } } + + private CharStream charStream(boolean single) { + return charStream; + } + + private PythonParser setupParser(boolean single) { + PythonLexer lexer = new PyLexer(this.charStream(single)); + lexer.setErrorHandler(errorHandler); + CommonTokenStream tokens = new CommonTokenStream(lexer); + PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename, single); + tokens = new CommonTokenStream(indentedSource); + PythonParser parser = new PythonParser(tokens, encoding); + parser.setErrorHandler(errorHandler); + parser.setTreeAdaptor(new PythonTreeAdaptor()); + return parser; + } + + public mod parseExpression() { + mod tree = null; + PythonParser parser = setupParser(false); + try { + PythonParser.eval_input_return r = parser.eval_input(); + tree = (mod)r.tree; + } catch (RecognitionException e) { + //XXX: this can't happen. Need to strip the throws from antlr + // generated code. + } + return tree; + } + + public mod parseInteractive() { + mod tree = null; + PythonParser parser = setupParser(true); + try { + PythonParser.single_input_return r = parser.single_input(); + tree = (mod)r.tree; + } catch (RecognitionException e) { + //I am only throwing ParseExceptions, but "throws RecognitionException" still gets + //into the generated code. + System.err.println("FIXME: pretty sure this can't happen -- but needs to be checked"); + } + return tree; + } + + public mod parseModule() { + mod tree = null; + PythonParser parser = setupParser(false); + try { + PythonParser.file_input_return r = parser.file_input(); + tree = (mod)r.tree; + } catch (RecognitionException e) { + //XXX: this can't happen. Need to strip the throws from antlr + // generated code. + } + return tree; + } } Deleted: trunk/jython/src/org/python/antlr/ExpressionParser.java =================================================================== --- trunk/jython/src/org/python/antlr/ExpressionParser.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/ExpressionParser.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,36 +0,0 @@ -package org.python.antlr; - -import org.antlr.runtime.CharStream; -import org.antlr.runtime.CommonTokenStream; -import org.antlr.runtime.RecognitionException; -import org.python.antlr.base.mod; - -public class ExpressionParser extends BaseParser { - - public ExpressionParser(CharStream cs, String filename, String encoding) { - this.charStream = cs; - this.filename = filename; - this.encoding = encoding; - } - - public mod parse() { - mod tree = null; - PythonLexer lexer = new PyLexer(this.charStream); - lexer.setErrorHandler(errorHandler); - CommonTokenStream tokens = new CommonTokenStream(lexer); - PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename); - tokens = new CommonTokenStream(indentedSource); - PythonParser parser = new PythonParser(tokens, encoding); - parser.setErrorHandler(errorHandler); - parser.setTreeAdaptor(new PythonTreeAdaptor()); - - try { - PythonParser.eval_input_return r = parser.eval_input(); - tree = (mod)r.tree; - } catch (RecognitionException e) { - //XXX: this can't happen. Need to strip the throws from antlr - // generated code. - } - return tree; - } -} Deleted: trunk/jython/src/org/python/antlr/InteractiveParser.java =================================================================== --- trunk/jython/src/org/python/antlr/InteractiveParser.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/InteractiveParser.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,41 +0,0 @@ -package org.python.antlr; - -import java.io.BufferedReader; -import java.io.IOException; - -import org.antlr.runtime.CommonTokenStream; -import org.antlr.runtime.RecognitionException; -import org.python.antlr.base.mod; - -public class InteractiveParser extends BaseParser { - - private BufferedReader bufreader; - - public InteractiveParser(BufferedReader br, String filename, String encoding) { - this.bufreader = br; - this.filename = filename; - this.encoding = encoding; - } - - public mod parse() throws IOException { - mod tree = null; - PythonLexer lexer = new PyLexer(new NoCloseReaderStream(bufreader)); - lexer.setErrorHandler(errorHandler); - CommonTokenStream tokens = new CommonTokenStream(lexer); - PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename, true); - tokens = new CommonTokenStream(indentedSource); - PythonParser parser = new PythonParser(tokens, encoding); - parser.setErrorHandler(errorHandler); - parser.setTreeAdaptor(new PythonTreeAdaptor()); - - try { - PythonParser.single_input_return r = parser.single_input(); - tree = (mod)r.tree; - } catch (RecognitionException e) { - //I am only throwing ParseExceptions, but "throws RecognitionException" still gets - //into the generated code. - System.err.println("FIXME: pretty sure this can't happen -- but needs to be checked"); - } - return tree; - } -} Deleted: trunk/jython/src/org/python/antlr/ModuleParser.java =================================================================== --- trunk/jython/src/org/python/antlr/ModuleParser.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/ModuleParser.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,39 +0,0 @@ -package org.python.antlr; - -import org.antlr.runtime.CharStream; -import org.antlr.runtime.CommonTokenStream; -import org.antlr.runtime.RecognitionException; -import org.python.antlr.base.mod; - -public class ModuleParser extends BaseParser { - public ModuleParser(CharStream cs, String filename, String encoding) { - this(cs, filename, encoding, false); - } - - public ModuleParser(CharStream cs, String filename, String encoding, boolean partial) { - this.charStream = cs; - this.filename = filename; - this.encoding = encoding; - this.partial = partial; - } - - public mod file_input() { - mod tree = null; - PythonLexer lexer = new PyLexer(this.charStream); - lexer.setErrorHandler(errorHandler); - CommonTokenStream tokens = new CommonTokenStream(lexer); - PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename); - tokens = new CommonTokenStream(indentedSource); - PythonParser parser = new PythonParser(tokens, encoding); - parser.setErrorHandler(errorHandler); - parser.setTreeAdaptor(new PythonTreeAdaptor()); - try { - PythonParser.file_input_return r = parser.file_input(); - tree = (mod)r.tree; - } catch (RecognitionException e) { - //XXX: this can't happen. Need to strip the throws from antlr - // generated code. - } - return tree; - } -} Modified: trunk/jython/src/org/python/antlr/ast/AstModule.java =================================================================== --- trunk/jython/src/org/python/antlr/ast/AstModule.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/antlr/ast/AstModule.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -8,12 +8,12 @@ import org.python.antlr.op.*; import org.python.core.AstList; import org.python.core.ClassDictInit; +import org.python.core.CompilerFlags; import org.python.core.imp; import org.python.core.Py; import org.python.core.PyInteger; import org.python.core.PyObject; import org.python.core.PyString; -import org.python.core.PyTableCode; import org.python.core.PyType; import org.python.antlr.AST; @@ -27,7 +27,7 @@ dict.__setitem__("__doc__", Py.None); dict.__setitem__("__name__", new PyString("_ast")); dict.__setitem__("__version__", new PyString("62047")); - dict.__setitem__("PyCF_ONLY_AST", new PyInteger(PyTableCode.PyCF_ONLY_AST)); + dict.__setitem__("PyCF_ONLY_AST", new PyInteger(CompilerFlags.PyCF_ONLY_AST)); dict.__setitem__("astlist", AstList.TYPE); Modified: trunk/jython/src/org/python/compiler/Future.java =================================================================== --- trunk/jython/src/org/python/compiler/Future.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/compiler/Future.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -8,73 +8,65 @@ import org.python.antlr.ast.Interactive; import org.python.antlr.ast.Module; import org.python.antlr.ast.Str; +import org.python.antlr.ast.alias; import org.python.antlr.base.mod; import org.python.antlr.base.stmt; +import org.python.core.CodeFlag; +import org.python.core.FutureFeature; +import org.python.core.Pragma; +import org.python.core.PragmaReceiver; +import java.util.EnumSet; import java.util.List; +import java.util.Set; public class Future { + Set<FutureFeature> featureSet = EnumSet.noneOf(FutureFeature.class); + private final PragmaReceiver features = new PragmaReceiver() { - private boolean division = false; - private boolean with_statement = false; - private boolean absolute_import = false; + public void add(Pragma pragma) { + if (pragma instanceof FutureFeature) { + FutureFeature feature = (FutureFeature) pragma; + featureSet.add(feature); + } + } - private static final String FUTURE = "__future__"; + }; private boolean check(ImportFrom cand) throws Exception { - if (!cand.getInternalModule().equals(FUTURE)) + if (!cand.getInternalModule().equals(FutureFeature.MODULE_NAME)) return false; - int n = cand.getInternalNames().size(); - if (n == 0) { - throw new ParseException("future statement does not support import *", cand); + if (cand.getInternalNames().isEmpty()) { + throw new ParseException( + "future statement does not support import *", cand); } - for (int i = 0; i < n; i++) { - String feature = cand.getInternalNames().get(i).getInternalName(); - // *known* features - if (feature.equals("nested_scopes")) { - continue; + try { + for (alias feature : cand.getInternalNames()) { + // *known* features + FutureFeature.addFeature(feature.getInternalName(), features); } - if (feature.equals("division")) { - division = true; - continue; - } - if (feature.equals("generators")) { - continue; - } - if (feature.equals("with_statement")) { - with_statement = true; - continue; - } - if (feature.equals("absolute_import")) { - absolute_import = true; - continue; - } - if (feature.equals("braces")) { - throw new ParseException("not a chance", cand); - } - if (feature.equals("GIL") || feature.equals("global_interpreter_lock")) { - throw new ParseException("Never going to happen!", cand); - } - throw new ParseException("future feature " + feature + " is not defined", cand); + } catch (ParseException pe) { + throw new ParseException(pe.getMessage(), cand); } return true; } - public void preprocessFutures(mod node, - org.python.core.CompilerFlags cflags) - throws Exception - { + public void preprocessFutures(mod node, org.python.core.CompilerFlags cflags) + throws Exception { if (cflags != null) { - division = cflags.division; - with_statement = cflags.with_statement; - absolute_import = cflags.absolute_import; + if (cflags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) + FutureFeature.division.addTo(features); + if (cflags.isFlagSet(CodeFlag.CO_FUTURE_WITH_STATEMENT)) + FutureFeature.with_statement.addTo(features); + if (cflags.isFlagSet(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT)) + FutureFeature.absolute_import.addTo(features); } int beg = 0; List<stmt> suite = null; if (node instanceof Module) { suite = ((Module) node).getInternalBody(); - if (suite.size() > 0 && suite.get(0) instanceof Expr && - ((Expr) suite.get(0)).getInternalValue() instanceof Str) { + if (suite.size() > 0 && suite.get(0) instanceof Expr + && ((Expr) suite.get(0)).getInternalValue() instanceof Str) { beg++; } } else if (node instanceof Interactive) { @@ -85,45 +77,36 @@ for (int i = beg; i < suite.size(); i++) { stmt s = suite.get(i); - if (!(s instanceof ImportFrom)) - break; + if (!(s instanceof ImportFrom)) break; s.from_future_checked = true; - if (!check((ImportFrom)s)) - break; + if (!check((ImportFrom) s)) break; } if (cflags != null) { - cflags.division = cflags.division || division; + for (FutureFeature feature : featureSet) { + feature.setFlag(cflags); + } } - if (cflags != null) { - cflags.with_statement = cflags.with_statement || with_statement; - } - if (cflags != null) { - cflags.absolute_import = cflags.absolute_import || absolute_import; - } } - public static void checkFromFuture(ImportFrom node) throws Exception { - if (node.from_future_checked) - return; - if (node.getInternalModule().equals(FUTURE)) { - throw new ParseException("from __future__ imports must occur " + - "at the beginning of the file",node); + if (node.from_future_checked) return; + if (node.getInternalModule().equals(FutureFeature.MODULE_NAME)) { + throw new ParseException("from __future__ imports must occur " + + "at the beginning of the file", node); } node.from_future_checked = true; } public boolean areDivisionOn() { - return division; + return featureSet.contains(FutureFeature.division); } public boolean withStatementSupported() { - return with_statement; + return featureSet.contains(FutureFeature.with_statement); } public boolean isAbsoluteImportOn() { - return absolute_import; + return featureSet.contains(FutureFeature.absolute_import); } - } Modified: trunk/jython/src/org/python/compiler/Module.java =================================================================== --- trunk/jython/src/org/python/compiler/Module.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/compiler/Module.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -12,6 +12,7 @@ import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; +import org.python.core.CodeFlag; import org.python.core.CompilerFlags; import org.python.core.Py; import org.python.core.PyException; @@ -506,17 +507,17 @@ code.jy_npurecell = scope.jy_npurecell; if (compiler.optimizeGlobals) { - code.moreflags |= org.python.core.PyTableCode.CO_OPTIMIZED; + code.moreflags |= org.python.core.CodeFlag.CO_OPTIMIZED.flag; } if (compiler.my_scope.generator) { - code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR; + code.moreflags |= org.python.core.CodeFlag.CO_GENERATOR.flag; } if (cflags != null) { - if (cflags.generator_allowed) { - code.moreflags |= org.python.core.PyTableCode.CO_GENERATOR_ALLOWED; + if (cflags.isFlagSet(CodeFlag.CO_GENERATOR_ALLOWED)) { + code.moreflags |= org.python.core.CodeFlag.CO_GENERATOR_ALLOWED.flag; } - if (cflags.division) { - code.moreflags |= org.python.core.PyTableCode.CO_FUTUREDIVISION; + if (cflags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) { + code.moreflags |= org.python.core.CodeFlag.CO_FUTURE_DIVISION.flag; } } Modified: trunk/jython/src/org/python/compiler/pbc/Bytecode.java =================================================================== --- trunk/jython/src/org/python/compiler/pbc/Bytecode.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/compiler/pbc/Bytecode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -14,6 +14,8 @@ import java.util.List; import java.util.Map; import java.util.Set; + +import org.python.core.CodeFlag; import org.python.core.Py; import org.python.core.Opcode; import org.python.core.PyBaseCode; @@ -25,7 +27,7 @@ private int co_argcount = 0; private int co_stacksize = 0; - private int co_flags = PyBaseCode.CO_OPTIMIZED | PyBaseCode.CO_NEWLOCALS; // typical usage + private int co_flags = CodeFlag.CO_OPTIMIZED.flag | CodeFlag.CO_NEWLOCALS.flag; // typical usage // co_filename = '<generated code>' // co_name = '<lambda>' // co_firstlineno = 0 @@ -135,7 +137,7 @@ public void YIELD_VALUE() { stackchange(1, 1); - co_flags |= PyBaseCode.CO_GENERATOR; + co_flags |= CodeFlag.CO_GENERATOR.flag; emit(Opcode.YIELD_VALUE); } Added: trunk/jython/src/org/python/core/CodeFlag.java =================================================================== --- trunk/jython/src/org/python/core/CodeFlag.java (rev 0) +++ trunk/jython/src/org/python/core/CodeFlag.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,106 @@ +package org.python.core; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; + +/** + * Represents flags that can be set on code objects. + * + * @author Tobias Ivarsson + */ +public enum CodeFlag { + /** + * Denotes that the code block uses fast locals. + */ + CO_OPTIMIZED(0x0001), + /** + * Denotes that a new dictionary should be created for the code block. + */ + CO_NEWLOCALS(0x0002), + /** + * The compiled code block has a varargs argument. + */ + CO_VARARGS(0x0004), + /** + * The compiled code block has a varkeyword argument. + */ + CO_VARKEYWORDS(0x0008), + /** + * The compiled code block is a generator code block. + */ + CO_GENERATOR(0x0020), + /** + * Denotes that nested scopes are enabled in the code block. + */ + CO_NESTED(0x0010), + /** + * Denotes that generators are enabled in the code block. + */ + CO_GENERATOR_ALLOWED(0x1000), + /** + * Standard division of integers returns float, truncating division needs to + * be enforced. + */ + CO_FUTURE_DIVISION(0x2000), + /** + * Absolute import. + */ + CO_FUTURE_ABSOLUTE_IMPORT(0x4000), + /** + * With statement. + */ + CO_FUTURE_WITH_STATEMENT(0x8000); + + public final int flag; + private static Iterable<CodeFlag> allFlags = Collections.unmodifiableList(Arrays.asList(values())); + + private CodeFlag(int flag) { + this.flag = flag; + } + + public boolean isFlagBitSetIn(int flags) { + return (flags & flag) != 0; + } + + static Iterable<CodeFlag> parse(final int flags) { + return new Iterable<CodeFlag>() { + + public Iterator<CodeFlag> iterator() { + return new Iterator<CodeFlag>() { + Iterator<CodeFlag> all = allFlags.iterator(); + CodeFlag next = null; + + public boolean hasNext() { + if (next != null) { + return true; + } + while (all.hasNext()) { + CodeFlag flag = all.next(); + if (flag.isFlagBitSetIn(flags)) { + next = flag; + return true; + } + } + return false; + } + + public CodeFlag next() { + if (hasNext()) try { + return next; + } finally { + next = null; + } + throw new IllegalStateException(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + }; + } + + }; + } +} Added: trunk/jython/src/org/python/core/CompileMode.java =================================================================== --- trunk/jython/src/org/python/core/CompileMode.java (rev 0) +++ trunk/jython/src/org/python/core/CompileMode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,33 @@ +package org.python.core; + +import org.python.antlr.BaseParser; +import org.python.antlr.base.mod; + +public enum CompileMode { + eval { + @Override + mod dispatch(BaseParser parser) { + return parser.parseExpression(); + } + }, + single { + @Override + mod dispatch(BaseParser parser) { + return parser.parseInteractive(); + } + }, + exec { + @Override + mod dispatch(BaseParser parser) { + return parser.parseModule(); + } + }; + abstract mod dispatch(BaseParser parser); + + public static CompileMode getMode(String mode) { + if (!mode.equals("exec") && !mode.equals("eval") && !mode.equals("single")) { + throw Py.ValueError("compile() arg 3 must be 'exec' or 'eval' or 'single'"); + } + return valueOf(mode); + } +} Modified: trunk/jython/src/org/python/core/CompilerFlags.java =================================================================== --- trunk/jython/src/org/python/core/CompilerFlags.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/CompilerFlags.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1,79 +1,104 @@ -// At some future point this will also be extended - in conjunction with Py#compileFlags - to add -// support for a compiler factory that user code can choose in place of the normal compiler. +// At some future point this will also be extended - in conjunction with +// Py#compileFlags - to add +// support for a compiler factory that user code can choose in place of the +// normal compiler. // (Perhaps a better name might have been "CompilerOptions".) package org.python.core; -public class CompilerFlags { +import java.util.Set; - private int co_flags; +import org.python.Version; - public boolean optimized; - public boolean newlocals; - public boolean varargs; - public boolean varkeywords; - public boolean generator; - - public boolean nested_scopes = true; - public boolean division; - public boolean generator_allowed = true; - public boolean with_statement; - public boolean absolute_import; - +public class CompilerFlags { + // These flags don't mean anything to the code, only to the compiler + public static final int PyCF_SOURCE_IS_UTF8 = 0x0100; + public static final int PyCF_DONT_IMPLY_DEDENT = 0x0200; + public static final int PyCF_ONLY_AST = 0x0400; public boolean only_ast; public boolean dont_imply_dedent; public boolean source_is_utf8; public String encoding; + private final Set<CodeFlag> flags = Version.getDefaultCodeFlags(); - public CompilerFlags() {} + public CompilerFlags() { + } public CompilerFlags(int co_flags) { - this.co_flags = co_flags; - optimized = isEnabled(PyBaseCode.CO_OPTIMIZED); - newlocals = isEnabled(PyBaseCode.CO_NEWLOCALS); - varargs = isEnabled(PyBaseCode.CO_VARARGS); - varkeywords = isEnabled(PyBaseCode.CO_VARKEYWORDS); - generator = isEnabled(PyBaseCode.CO_GENERATOR); - nested_scopes = isEnabled(PyBaseCode.CO_NESTED); - division = isEnabled(PyBaseCode.CO_FUTUREDIVISION); - generator_allowed = isEnabled(PyBaseCode.CO_GENERATOR_ALLOWED); - absolute_import = isEnabled(PyBaseCode.CO_FUTURE_ABSOLUTE_IMPORT); - with_statement = isEnabled(PyBaseCode.CO_WITH_STATEMENT); - only_ast = isEnabled(PyBaseCode.PyCF_ONLY_AST); - dont_imply_dedent = isEnabled(PyBaseCode.PyCF_DONT_IMPLY_DEDENT); - source_is_utf8 = isEnabled(PyBaseCode.PyCF_SOURCE_IS_UTF8); + for (CodeFlag flag : CodeFlag.parse(co_flags)) { + setFlag(flag); + } + only_ast = isEnabled(co_flags, PyCF_ONLY_AST); + dont_imply_dedent = isEnabled(co_flags, PyCF_DONT_IMPLY_DEDENT); + source_is_utf8 = isEnabled(co_flags, PyCF_SOURCE_IS_UTF8); } - private boolean isEnabled(int codeConstant) { + private boolean isEnabled(int co_flags, int codeConstant) { return (co_flags & codeConstant) != 0; } + public int toBits() { + int bits = (only_ast ? PyCF_ONLY_AST : 0) + | (dont_imply_dedent ? PyCF_DONT_IMPLY_DEDENT : 0) + | (source_is_utf8 ? PyCF_SOURCE_IS_UTF8 : 0); + for (CodeFlag flag : flags) { + bits |= flag.flag; + } + return bits; + } + + public void setFlag(CodeFlag flag) { + flags.add(flag); + } + + public boolean isFlagSet(CodeFlag flag) { + return flags.contains(flag); + } + @Override public String toString() { - return String.format("CompilerFlags[division=%s nested_scopes=%s generators=%s " - + "with_statement=%s absolute_import=%s only_ast=%s " - + "dont_imply_dedent=%s source_is_utf8=%s]", division, nested_scopes, - generator_allowed, with_statement, absolute_import, only_ast, - dont_imply_dedent, source_is_utf8); + return String.format( + "CompilerFlags[division=%s nested_scopes=%s generators=%s " + + "with_statement=%s absolute_import=%s only_ast=%s " + + "dont_imply_dedent=%s source_is_utf8=%s]", + isFlagSet(CodeFlag.CO_FUTURE_DIVISION), + isFlagSet(CodeFlag.CO_NESTED), + isFlagSet(CodeFlag.CO_GENERATOR_ALLOWED), + isFlagSet(CodeFlag.CO_FUTURE_WITH_STATEMENT), + isFlagSet(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT), only_ast, + dont_imply_dedent, source_is_utf8); } - public int toBits() { - return (optimized ? PyBaseCode.CO_OPTIMIZED : 0) | - (newlocals ? PyBaseCode.CO_NEWLOCALS : 0) | - (varargs ? PyBaseCode.CO_VARARGS : 0) | - (varkeywords ? PyBaseCode.CO_VARKEYWORDS : 0) | - (generator ? PyBaseCode.CO_GENERATOR : 0) | - (nested_scopes ? PyBaseCode.CO_NESTED : 0) | - (division ? PyBaseCode.CO_FUTUREDIVISION : 0) | - (generator_allowed ? PyBaseCode.CO_GENERATOR_ALLOWED : 0) | - (absolute_import ? PyBaseCode.CO_FUTURE_ABSOLUTE_IMPORT : 0) | - (with_statement ? PyBaseCode.CO_WITH_STATEMENT : 0) | - (only_ast ? PyBaseCode.PyCF_ONLY_AST : 0) | - (dont_imply_dedent ? PyBaseCode.PyCF_DONT_IMPLY_DEDENT : 0) | - (source_is_utf8 ? PyBaseCode.PyCF_SOURCE_IS_UTF8 : 0); + public static CompilerFlags getCompilerFlags() { + return getCompilerFlags(0, null); } + private static final int CO_ALL_FEATURES = CompilerFlags.PyCF_DONT_IMPLY_DEDENT + | CompilerFlags.PyCF_ONLY_AST + | CompilerFlags.PyCF_SOURCE_IS_UTF8 + | CodeFlag.CO_NESTED.flag + | CodeFlag.CO_GENERATOR_ALLOWED.flag + | CodeFlag.CO_FUTURE_DIVISION.flag + | CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT.flag + | CodeFlag.CO_FUTURE_WITH_STATEMENT.flag; + + public static CompilerFlags getCompilerFlags(int flags, PyFrame frame) { + if ((flags & ~CO_ALL_FEATURES) != 0) { + throw Py.ValueError("compile(): unrecognised flags"); + } + return getCompilerFlags(new CompilerFlags(flags), frame); + } + + public static CompilerFlags getCompilerFlags(CompilerFlags flags, + PyFrame frame) { + if (frame != null && frame.f_code != null) { + return frame.f_code.co_flags.combine(flags); + } else { + return flags; + } + } + // this will not strictly be an OR once we have other options, like a compiler factory // in that case, we would assume public CompilerFlags combine(CompilerFlags flags) { Added: trunk/jython/src/org/python/core/FutureFeature.java =================================================================== --- trunk/jython/src/org/python/core/FutureFeature.java (rev 0) +++ trunk/jython/src/org/python/core/FutureFeature.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,101 @@ +package org.python.core; + +import org.python.antlr.ParseException; + +public enum FutureFeature implements Pragma { + /** + * Enables nested scopes. + */ + nested_scopes(CodeFlag.CO_NESTED), + /** + * Makes integer / integer division return float. + */ + division(CodeFlag.CO_FUTURE_DIVISION), + /** + * Enables generators. + */ + generators(CodeFlag.CO_GENERATOR_ALLOWED), + /** + * Enables absolute imports. + */ + absolute_import(CodeFlag.CO_FUTURE_ABSOLUTE_IMPORT), + /** + * Enables the with statement. + */ + with_statement(CodeFlag.CO_FUTURE_WITH_STATEMENT), + /** + * Use braces for block delimiters instead of indentation. + */ + braces { + @Override + public void addTo(PragmaReceiver features) { + throw new ParseException("not a chance"); + } + }, + /** + * Enable the Global Interpreter Lock in Jython. + */ + GIL { + @Override + public void addTo(PragmaReceiver features) { + throw new ParseException("Never going to happen!"); + } + }, + /** + * Enable the Global Interpreter Lock in Jython. + */ + global_interpreter_lock { + @Override + public void addTo(PragmaReceiver features) { + GIL.addTo(features); + } + }; + + public static final String MODULE_NAME = "__future__"; + public static final PragmaModule PRAGMA_MODULE = new PragmaModule( + MODULE_NAME) { + + @Override + public Pragma getPragma(String name) { + return getFeature(name); + } + + @Override + public Pragma getStarPragma() { + throw new ParseException("future feature * is not defined"); + } + }; + private final CodeFlag flag; + + private FutureFeature(CodeFlag flag) { + this.flag = flag; + } + + private FutureFeature() { + this(null); + } + + public void addTo(PragmaReceiver features) { + features.add(this); + } + + public static void addFeature(String featureName, PragmaReceiver features) { + getFeature(featureName).addTo(features); + } + + private static FutureFeature getFeature(String featureName) { + try { + return valueOf(featureName); + } catch (IllegalArgumentException ex) { + throw new ParseException("future feature " + featureName + + " is not defined"); + } + } + + public void setFlag(CompilerFlags cflags) { + if (flag != null) { + cflags.setFlag(flag); + } + } + +} Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/ParserFacade.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -23,10 +23,7 @@ import org.antlr.runtime.CommonTokenStream; import org.python.antlr.BaseParser; -import org.python.antlr.ExpressionParser; -import org.python.antlr.InteractiveParser; import org.python.antlr.ParseException; -import org.python.antlr.ModuleParser; import org.python.antlr.NoCloseReaderStream; import org.python.antlr.PythonTree; import org.python.antlr.PythonLexer; @@ -111,30 +108,23 @@ * PyIndentationErrors. */ private static mod parse(ExpectedEncodingBufferedReader reader, - String kind, + CompileMode kind, String filename, CompilerFlags cflags) throws Throwable { reader.mark(MARK_LIMIT); // We need the ability to move back on the // reader, for the benefit of fixParseError and // validPartialSentence - if (kind.equals("eval")) { + if (kind != null) { CharStream cs = new NoCloseReaderStream(reader); - ExpressionParser e = new ExpressionParser(cs, filename, cflags.encoding); - return e.parse(); - } else if (kind.equals("single")) { - InteractiveParser i = new InteractiveParser(reader, filename, cflags.encoding); - return i.parse(); - } else if (kind.equals("exec")) { - CharStream cs = new NoCloseReaderStream(reader); - ModuleParser g = new ModuleParser(cs, filename, cflags.encoding); - return g.file_input(); + BaseParser parser = new BaseParser(cs, filename, cflags.encoding); + return kind.dispatch(parser); } else { throw Py.ValueError("parse kind must be eval, exec, or single"); } } public static mod parse(InputStream stream, - String kind, + CompileMode kind, String filename, CompilerFlags cflags) { ExpectedEncodingBufferedReader bufReader = null; @@ -151,7 +141,7 @@ } public static mod parse(String string, - String kind, + CompileMode kind, String filename, CompilerFlags cflags) { ExpectedEncodingBufferedReader bufReader = null; @@ -166,7 +156,7 @@ } public static mod partialParse(String string, - String kind, + CompileMode kind, String filename, CompilerFlags cflags, boolean stdprompt) { @@ -186,7 +176,7 @@ } } - private static boolean validPartialSentence(BufferedReader bufreader, String kind, String filename) { + private static boolean validPartialSentence(BufferedReader bufreader, CompileMode kind, String filename) { PythonLexer lexer = null; try { bufreader.reset(); @@ -197,14 +187,16 @@ PythonTokenSource indentedSource = new PythonTokenSource(tokens, filename); tokens = new CommonTokenStream(indentedSource); PythonPartial parser = new PythonPartial(tokens); - if (kind.equals("single")) { + switch (kind) { + case single: parser.single_input(); - } else if (kind.equals("eval")) { + break; + case eval: parser.eval_input(); - } else { + break; + default: return false; } - } catch (Exception e) { return lexer.eofWhileNested; } Added: trunk/jython/src/org/python/core/Pragma.java =================================================================== --- trunk/jython/src/org/python/core/Pragma.java (rev 0) +++ trunk/jython/src/org/python/core/Pragma.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,46 @@ +package org.python.core; + +import org.python.antlr.ParseException; + +public interface Pragma { + void addTo(PragmaReceiver receiver); + + public abstract class PragmaModule { + public final String name; + + protected PragmaModule(String name) { + this.name = name; + } + + public abstract Pragma getPragma(String name); + + public abstract Pragma getStarPragma(); + } + + public final class ForbiddenPragmaModule extends PragmaModule { + private final String message; + + public ForbiddenPragmaModule(String name) { + this(name, "pragma " + name + " is not allowed in this context."); + } + + public ForbiddenPragmaModule(String name, String message) { + super(name); + this.message = message; + } + + @Override + public Pragma getPragma(String name) { + throw new ParseException(message); + } + + @Override + public Pragma getStarPragma() { + throw new ParseException(message); + } + + public void addTo(PragmaReceiver receiver) { + throw new ParseException(message); + } + } +} Added: trunk/jython/src/org/python/core/PragmaReceiver.java =================================================================== --- trunk/jython/src/org/python/core/PragmaReceiver.java (rev 0) +++ trunk/jython/src/org/python/core/PragmaReceiver.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -0,0 +1,5 @@ +package org.python.core; + +public interface PragmaReceiver { + void add(Pragma pragma); +} Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/Py.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -1218,7 +1218,7 @@ String contents = null; if (o instanceof PyString) { if (o instanceof PyUnicode) { - flags |= PyBaseCode.PyCF_SOURCE_IS_UTF8; + flags |= CompilerFlags.PyCF_SOURCE_IS_UTF8; } contents = o.toString(); } else if (o instanceof PyFile) { @@ -1231,7 +1231,7 @@ throw Py.TypeError( "exec: argument 1 must be string, code or file object"); } - code = (PyCode)Py.compile_flags(contents, "<string>", "exec", + code = (PyCode)Py.compile_flags(contents, "<string>", CompileMode.exec, getCompilerFlags(flags, false)); } Py.runCode(code, locals, globals); @@ -1603,41 +1603,31 @@ } public static CompilerFlags getCompilerFlags() { - return getCompilerFlags(0, false); + return CompilerFlags.getCompilerFlags(); } public static CompilerFlags getCompilerFlags(int flags, boolean dont_inherit) { - CompilerFlags cflags = null; + final PyFrame frame; if (dont_inherit) { - cflags = new CompilerFlags(flags); + frame = null; } else { - PyFrame frame = Py.getFrame(); - if (frame != null && frame.f_code != null) { - cflags = frame.f_code.co_flags.combine(flags); - } else { - cflags = new CompilerFlags(flags); - } + frame = Py.getFrame(); } - return cflags; + return CompilerFlags.getCompilerFlags(flags, frame); } public static CompilerFlags getCompilerFlags(CompilerFlags flags, boolean dont_inherit) { - CompilerFlags cflags = null; + final PyFrame frame; if (dont_inherit) { - cflags = flags; + frame = null; } else { - PyFrame frame = Py.getFrame(); - if (frame != null && frame.f_code != null) { - cflags = frame.f_code.co_flags.combine(flags); - } else { - cflags = flags; - } + frame = Py.getFrame(); } - return cflags; + return CompilerFlags.getCompilerFlags(flags, frame); } // w/o compiler-flags - public static PyObject compile(InputStream istream, String filename, String kind) { + public static PyCode compile(InputStream istream, String filename, CompileMode kind) { return compile_flags(istream, filename, kind, new CompilerFlags()); } @@ -1655,13 +1645,10 @@ * @param cflags Compiler flags * @return Code object for the compiled module */ - public static PyObject compile_flags(mod node, String name, String filename, + public static PyCode compile_flags(mod node, String name, String filename, boolean linenumbers, boolean printResults, CompilerFlags cflags) { try { - if (cflags != null && cflags.only_ast) { - return Py.java2py(node); - } ByteArrayOutputStream ostream = new ByteArrayOutputStream(); Module.compile(node, ostream, name, filename, linenumbers, printResults, cflags); @@ -1673,17 +1660,17 @@ } } - public static PyObject compile_flags(mod node, String filename, - String kind, CompilerFlags cflags) { + public static PyCode compile_flags(mod node, String filename, + CompileMode kind, CompilerFlags cflags) { return Py.compile_flags(node, getName(), filename, true, - kind.equals("single"), cflags); + kind == CompileMode.single, cflags); } /** * Compiles python source code coming from a file or another external stream */ - public static PyObject compile_flags(InputStream istream, String filename, - String kind, CompilerFlags cflags) { + public static PyCode compile_flags(InputStream istream, String filename, + CompileMode kind, CompilerFlags cflags) { mod node = ParserFacade.parse(istream, kind, filename, cflags); return Py.compile_flags(node, filename, kind, cflags); } @@ -1694,8 +1681,8 @@ * DO NOT use this for PyString input. Use * {@link #compile_flags(byte[], String, String, CompilerFlags)} instead. */ - public static PyObject compile_flags(String data, String filename, - String kind, CompilerFlags cflags) { + public static PyCode compile_flags(String data, String filename, + CompileMode kind, CompilerFlags cflags) { if (data.contains("\0")) { throw Py.TypeError("compile() expected string without null bytes"); } @@ -1709,7 +1696,7 @@ } public static PyObject compile_command_flags(String string, String filename, - String kind, CompilerFlags cflags, boolean stdprompt) { + CompileMode kind, CompilerFlags cflags, boolean stdprompt) { mod node = ParserFacade.partialParse(string + "\n", kind, filename, cflags, stdprompt); if (node == null) { Modified: trunk/jython/src/org/python/core/PyBaseCode.java =================================================================== --- trunk/jython/src/org/python/core/PyBaseCode.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/PyBaseCode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -17,30 +17,7 @@ public int co_nlocals; public boolean varargs, varkwargs; - final public static int CO_OPTIMIZED = 0x0001; - final public static int CO_NEWLOCALS = 0x0002; - final public static int CO_VARARGS = 0x0004; - final public static int CO_VARKEYWORDS = 0x0008; - final public static int CO_GENERATOR = 0x0020; - // these are defined in __future__.py - final public static int CO_NESTED = 0x0010; - final public static int CO_GENERATOR_ALLOWED = 0x0; - final public static int CO_FUTUREDIVISION = 0x2000; - final public static int CO_FUTURE_ABSOLUTE_IMPORT = 0x4000; - final public static int CO_WITH_STATEMENT = 0x8000; - - //XXX: I'm not positive that this is the right place for these constants. - final public static int PyCF_SOURCE_IS_UTF8 = 0x0100; - final public static int PyCF_DONT_IMPLY_DEDENT = 0x0200; - final public static int PyCF_ONLY_AST = 0x0400; - - final public static int CO_ALL_FEATURES = PyCF_DONT_IMPLY_DEDENT|PyCF_ONLY_AST| - PyCF_SOURCE_IS_UTF8|CO_NESTED| - CO_GENERATOR_ALLOWED| CO_FUTUREDIVISION| - CO_FUTURE_ABSOLUTE_IMPORT|CO_WITH_STATEMENT; - - public boolean hasFreevars() { return co_freevars != null && co_freevars.length > 0; } @@ -135,7 +112,7 @@ return call(Py.EmptyObjects, Py.NoKeywords, globals, defaults, closure); PyFrame frame = new PyFrame(this, globals); - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); @@ -149,7 +126,7 @@ Py.NoKeywords, globals, defaults, closure); PyFrame frame = new PyFrame(this, globals); frame.f_fastlocals[0] = arg1; - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); @@ -164,7 +141,7 @@ PyFrame frame = new PyFrame(this, globals); frame.f_fastlocals[0] = arg1; frame.f_fastlocals[1] = arg2; - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); @@ -181,7 +158,7 @@ frame.f_fastlocals[0] = arg1; frame.f_fastlocals[1] = arg2; frame.f_fastlocals[2] = arg3; - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); @@ -297,7 +274,7 @@ co_name, argcount)); } - if (co_flags.generator) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR)) { return new PyGenerator(frame, closure); } return call(frame, closure); Modified: trunk/jython/src/org/python/core/PyBytecode.java =================================================================== --- trunk/jython/src/org/python/core/PyBytecode.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/PyBytecode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -75,8 +75,8 @@ co_freevars = freevars; co_name = name; co_flags = new CompilerFlags(flags); - varargs = co_flags.varargs; - varkwargs = co_flags.varkeywords; + varargs = co_flags.isFlagSet(CodeFlag.CO_VARARGS); + varkwargs = co_flags.isFlagSet(CodeFlag.CO_VARKEYWORDS); co_stacksize = stacksize; co_consts = constants; @@ -420,7 +420,7 @@ PyObject b = stack.pop(); PyObject a = stack.pop(); - if (!co_flags.division) { + if (!co_flags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) { stack.push(a._div(b)); } else { stack.push(a._truediv(b)); @@ -530,7 +530,7 @@ case Opcode.INPLACE_DIVIDE: { PyObject b = stack.pop(); PyObject a = stack.pop(); - if (!co_flags.division) { + if (!co_flags.isFlagSet(CodeFlag.CO_FUTURE_DIVISION)) { stack.push(a._idiv(b)); } else { stack.push(a._itruediv(b)); @@ -1248,7 +1248,7 @@ throw ts.exception; } - if (co_flags.generator && why == Why.RETURN && retval == Py.None) { + if (co_flags.isFlagSet(CodeFlag.CO_GENERATOR) && why == Why.RETURN && retval == Py.None) { f.f_lasti = -1; } Modified: trunk/jython/src/org/python/core/PyFrame.java =================================================================== --- trunk/jython/src/org/python/core/PyFrame.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/PyFrame.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -62,7 +62,7 @@ // This needs work to be efficient with multiple interpreter states if (locals == null && code != null) { // ! f_fastlocals needed for arg passing too - if (code.co_flags.optimized || code.nargs > 0) { + if (code.co_flags.isFlagSet(CodeFlag.CO_OPTIMIZED) || code.nargs > 0) { if (code.co_nlocals > 0) { // internal: may change f_fastlocals = new PyObject[code.co_nlocals - code.jy_npurecell]; @@ -191,7 +191,7 @@ PyObject o = f_fastlocals[i]; if (o != null) f_locals.__setitem__(f_code.co_varnames[i], o); } - if (!f_code.co_flags.optimized) { + if (!f_code.co_flags.isFlagSet(CodeFlag.CO_OPTIMIZED)) { f_fastlocals = null; } } Modified: trunk/jython/src/org/python/core/PyTableCode.java =================================================================== --- trunk/jython/src/org/python/core/PyTableCode.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/PyTableCode.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -45,12 +45,12 @@ co_name = name; if (varargs) { co_argcount -= 1; - co_flags.varargs = true; + co_flags.setFlag(CodeFlag.CO_VARARGS); } this.varkwargs = varkwargs; if (varkwargs) { co_argcount -= 1; - co_flags.varkeywords = true; + co_flags.setFlag(CodeFlag.CO_VARKEYWORDS); } co_flags = new CompilerFlags(co_flags.toBits() | moreflags); this.funcs = funcs; Modified: trunk/jython/src/org/python/core/__builtin__.java =================================================================== --- trunk/jython/src/org/python/core/__builtin__.java 2009-03-29 20:07:31 UTC (rev 6114) +++ trunk/jython/src/org/python/core/__builtin__.java 2009-03-29 22:11:34 UTC (rev 6115) @@ -527,7 +527,7 @@ PyCode code; try { - code = (PyCode)Py.compile_flags(file, name, "exec", cflags); + code = (PyCode)Py.compile_flags(file, name, CompileMode.exec, cflags); } finally { try { file.close(); @@ -1526,45 +1526,41 @@ public static PyObject compile(PyObject source, String filename, String mode, int flags, boolean dont_inherit) { - if ((flags & ~PyBaseCode.CO_ALL_FEATURES) != 0) { - throw Py.ValueError("compile(): unrecognised flags"); - } - if (!mode.equals("exec") && !mode.equals("eval") && !mode.equals("single")) { - throw Py.ValueError("compile() arg 3 must be 'exec' or 'eval' or 'single'"); - } + CompilerFlags cflags = Py.getCompilerFlags(flags, dont_inherit); + CompileMode kind = CompileMode.getMode(mode); - mod ast = py2node(source); - if (ast != null) { - return Py.compile_flags(ast, filename, mode, Py.getCompilerFlags(flags, dont_inherit)); - } - - if (!(source instanceof PyString)) { - throw Py.TypeError("expected a readable buffer object"); - } - if (source instanceof PyUnicode) { - flags |= PyBaseCode.PyCF_SOURCE_IS_UTF8; - } - return Py.compile_flags(((PyString)source).toString(), filename, mode, - Py.getCompilerFlags(flags, dont_inherit)); + return compile(source, filename, kind, cflags, dont_inherit); } - public static PyObject compile(PyObject source, String filename, String mode, CompilerFlags flags, + public static PyObject compile(PyObject source, String filename, CompileMode kind, CompilerFlags cflags, boolean dont_inherit) { - if (!mode.equals("exec") && !mode.equals("eval") && !mode.equals("single")) { - throw Py.ValueError("compile() arg 3 must be 'exec' or 'eval' or 'single'"); - } - + cflags = Py.getCompilerFlags(cflags, dont_inherit); + mod ast = py2node(source); - if (ast != null) { - return Py.compile_flags(ast, filename, mode, Py.getCompilerFlags(flags, dont_inherit)); + if (ast == null) { + if (!(source instanceof PyString)) { + ... [truncated message content] |
From: <pj...@us...> - 2009-03-30 17:12:52
|
Revision: 6124 http://jython.svn.sourceforge.net/jython/?rev=6124&view=rev Author: pjenvey Date: 2009-03-30 17:12:32 +0000 (Mon, 30 Mar 2009) Log Message: ----------- revert r2556, so == doesn't swallow AttributeErrors thanks Michele Cella fixes #1209 Modified Paths: -------------- trunk/jython/Lib/test/test_descr_jy.py trunk/jython/src/org/python/core/PyObject.java Modified: trunk/jython/Lib/test/test_descr_jy.py =================================================================== --- trunk/jython/Lib/test/test_descr_jy.py 2009-03-30 16:26:41 UTC (rev 6123) +++ trunk/jython/Lib/test/test_descr_jy.py 2009-03-30 17:12:32 UTC (rev 6124) @@ -331,6 +331,13 @@ self.assertRaises(AttributeError, func, old) self.assertRaises(TypeError, func, new) + def test_eq(self): + class A(object): + def __eq__(self, other): + return self.value == other.value + self.assertRaises(AttributeError, lambda: A() == A()) + + class GetAttrTestCase(unittest.TestCase): def test_raising_custom_attribute_error(self): # Very similar to Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-03-30 16:26:41 UTC (rev 6123) +++ trunk/jython/src/org/python/core/PyObject.java 2009-03-30 17:12:32 UTC (rev 6124) @@ -1410,11 +1410,6 @@ if (res != null) return res; return _cmpeq_unsafe(o) == 0 ? Py.True : Py.False; - } catch (PyException e) { - if (Py.matchException(e, Py.AttributeError)) { - return Py.False; - } - throw e; } finally { delete_token(ts, token); ts.compareStateNesting--; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-30 19:15:52
|
Revision: 6125 http://jython.svn.sourceforge.net/jython/?rev=6125&view=rev Author: pjenvey Date: 2009-03-30 19:15:47 +0000 (Mon, 30 Mar 2009) Log Message: ----------- handle the case where a module that failed to import was already deleted from sys.modules thanks Thijs Triemstra fixes #1246 Modified Paths: -------------- trunk/jython/Lib/test/test_import_jy.py trunk/jython/src/org/python/core/imp.java Added Paths: ----------- trunk/jython/Lib/test/module_deleter.py Added: trunk/jython/Lib/test/module_deleter.py =================================================================== --- trunk/jython/Lib/test/module_deleter.py (rev 0) +++ trunk/jython/Lib/test/module_deleter.py 2009-03-30 19:15:47 UTC (rev 6125) @@ -0,0 +1,3 @@ +import sys +del sys.modules[__name__] +1 / 0 Modified: trunk/jython/Lib/test/test_import_jy.py =================================================================== --- trunk/jython/Lib/test/test_import_jy.py 2009-03-30 17:12:32 UTC (rev 6124) +++ trunk/jython/Lib/test/test_import_jy.py 2009-03-30 19:15:47 UTC (rev 6125) @@ -159,6 +159,9 @@ self.assertEquals(Metis, Zeus.Athena.__bases__[0]) self.assertEquals(Zeus, Metis.__bases__[0]) + def test_sys_modules_deletion(self): + self.assertRaises(ZeroDivisionError, __import__, 'test.module_deleter') + def test_main(): test_support.run_unittest(MislabeledImportTestCase, OverrideBuiltinsImportTestCase, Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2009-03-30 17:12:32 UTC (rev 6124) +++ trunk/jython/src/org/python/core/imp.java 2009-03-30 19:15:47 UTC (rev 6125) @@ -66,6 +66,26 @@ return module; } + /** + * Remove name form sys.modules if it's there. + * + * @param name the module name + */ + private static void removeModule(String name) { + name = name.intern(); + PyObject modules = Py.getSystemState().modules; + if (modules.__finditem__(name) != null) { + try { + modules.__delitem__(name); + } catch (PyException pye) { + // another thread may have deleted it + if (!Py.matchException(pye, Py.KeyError)) { + throw pye; + } + } + } + } + private static byte[] readBytes(InputStream fp) { try { return FileUtil.readBytes(fp); @@ -295,7 +315,7 @@ PyFrame f = new PyFrame(code, module.__dict__, module.__dict__, null); code.call(f); } catch (RuntimeException t) { - Py.getSystemState().modules.__delitem__(name.intern()); + removeModule(name); throw t; } return module; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-30 22:02:10
|
Revision: 6129 http://jython.svn.sourceforge.net/jython/?rev=6129&view=rev Author: pjenvey Date: 2009-03-30 22:02:06 +0000 (Mon, 30 Mar 2009) Log Message: ----------- only modify __module__ in classDict after it's been copied thanks Mike Bayer Modified Paths: -------------- trunk/jython/Lib/test/test_class_jy.py trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/Lib/test/test_class_jy.py =================================================================== --- trunk/jython/Lib/test/test_class_jy.py 2009-03-30 21:40:00 UTC (rev 6128) +++ trunk/jython/Lib/test/test_class_jy.py 2009-03-30 22:02:06 UTC (rev 6129) @@ -330,6 +330,11 @@ class Bar(object): self.assertEqual(__module__, module_name) + def test_dundermodule_in_class_dict_copy(self): + class_dict = {'a': 'this is a', 'b': 'this is b'} + Foo = type.__new__(type, 'Foo', (object,), class_dict) + Foo.keys = class_dict.keys + assert sorted(Foo().keys()) == sorted(['a', 'b']), sorted(Foo().keys()) class ClassMetaclassRepr(unittest.TestCase): """Verifies #1131 is fixed""" Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-03-30 21:40:00 UTC (rev 6128) +++ trunk/jython/src/org/python/core/PyType.java 2009-03-30 22:02:06 UTC (rev 6129) @@ -166,19 +166,6 @@ } } - if (dict.__finditem__("__module__") == null) { - PyFrame frame = Py.getFrame(); - if (frame != null) { - PyObject globals = frame.f_globals; - PyObject modname; - if ((modname = globals.__finditem__("__name__")) != null) { - dict.__setitem__("__module__", modname); - } - } - } - // XXX also __doc__ __module__ - - Class<?> proxyClass = null; if (baseClass != null || interfaces.size() != 0) { String proxyName = name; @@ -227,6 +214,19 @@ } else { dict = ((PyDictionary)dict).copy(); } + + if (dict.__finditem__("__module__") == null) { + PyFrame frame = Py.getFrame(); + if (frame != null) { + PyObject globals = frame.f_globals; + PyObject modname; + if ((modname = globals.__finditem__("__name__")) != null) { + dict.__setitem__("__module__", modname); + } + } + } + // XXX also __doc__ __module__ + newtype.dict = dict; newtype.name = name; newtype.base = best_base(bases_list); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-03-31 16:31:10
|
Revision: 6137 http://jython.svn.sourceforge.net/jython/?rev=6137&view=rev Author: fwierzbicki Date: 2009-03-31 16:31:06 +0000 (Tue, 31 Mar 2009) Log Message: ----------- Fix for http://bugs.jython.org/issue1295 Setting a write-only bean property causes a NPE. Modified Paths: -------------- trunk/jython/NEWS trunk/jython/src/org/python/core/PyJavaType.java Added Paths: ----------- trunk/jython/tests/java/org/python/tests/props/ trunk/jython/tests/java/org/python/tests/props/Readonly.java trunk/jython/tests/java/org/python/tests/props/ReadonlyTest.java Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-03-31 15:14:19 UTC (rev 6136) +++ trunk/jython/NEWS 2009-03-31 16:31:06 UTC (rev 6137) @@ -2,6 +2,7 @@ Jython 2.5.0 rc 1 Bugs fixed (new numbering due to move to Roundup) + - [ 1295 ] Setting a write-only bean property causes a NPE - [ 1272 ] ASTList ClassCastException - [ 1261 ] jython -c "import sys; sys.exit(1)" not giving correct exit code. - [ 1215 ] extra spaces in import statement break importing Modified: trunk/jython/src/org/python/core/PyJavaType.java =================================================================== --- trunk/jython/src/org/python/core/PyJavaType.java 2009-03-31 15:14:19 UTC (rev 6136) +++ trunk/jython/src/org/python/core/PyJavaType.java 2009-03-31 16:31:06 UTC (rev 6137) @@ -304,6 +304,17 @@ prop.myType = meth.getReturnType(); } else { prop.setMethod = meth; + // Needed for readonly properties. Getter will be used instead + // if there is one. Only works if setX method has exactly one + // param, which is the only reasonable case. + // XXX: should we issue a warning if setX and getX have different + // types? + if (prop.myType == null) { + Class[] params = meth.getParameterTypes(); + if (params.length == 1) { + prop.myType = params[0]; + } + } } } } Added: trunk/jython/tests/java/org/python/tests/props/Readonly.java =================================================================== --- trunk/jython/tests/java/org/python/tests/props/Readonly.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/props/Readonly.java 2009-03-31 16:31:06 UTC (rev 6137) @@ -0,0 +1,8 @@ +package org.python.tests.props; + +public class Readonly { + private String a; + public void setA(String a) { this.a = a; } + //public String getA() { return a; } +} + Added: trunk/jython/tests/java/org/python/tests/props/ReadonlyTest.java =================================================================== --- trunk/jython/tests/java/org/python/tests/props/ReadonlyTest.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/props/ReadonlyTest.java 2009-03-31 16:31:06 UTC (rev 6137) @@ -0,0 +1,21 @@ +package org.python.tests.props; + +import junit.framework.TestCase; + +import org.python.core.PyStringMap; +import org.python.core.PySystemState; +import org.python.util.PythonInterpreter; + +public class ReadonlyTest extends TestCase { + + private PythonInterpreter interp; + + @Override + protected void setUp() throws Exception { + interp = new PythonInterpreter(new PyStringMap(), new PySystemState()); + } + + public void testReadonly() { + interp.exec("from org.python.tests.props import Readonly;Readonly().a = 'test'"); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-03-31 19:05:02
|
Revision: 6139 http://jython.svn.sourceforge.net/jython/?rev=6139&view=rev Author: pjenvey Date: 2009-03-31 19:04:48 +0000 (Tue, 31 Mar 2009) Log Message: ----------- o don't use custom __hash__'s for internal weakref identity as weakrefs are unique per referent o avoid calling custom __hash__'s until it's necessary incase they're in an indeterminate state pointed out by Mike Bayer o make the internal ref map thread safe Modified Paths: -------------- trunk/jython/src/org/python/modules/_weakref/AbstractReference.java trunk/jython/src/org/python/modules/_weakref/GlobalRef.java Added Paths: ----------- trunk/jython/Lib/test/test_weakref_jy.py Added: trunk/jython/Lib/test/test_weakref_jy.py =================================================================== --- trunk/jython/Lib/test/test_weakref_jy.py (rev 0) +++ trunk/jython/Lib/test/test_weakref_jy.py 2009-03-31 19:04:48 UTC (rev 6139) @@ -0,0 +1,46 @@ +"""Misc weakref tests + +Made for Jython. +""" +import unittest +import weakref +from test import test_support + +class ReferencesTestCase(unittest.TestCase): + + def test___eq__(self): + class Foo(object): + def __eq__(self, other): + return True + def __hash__(self): + return hash('foo') + foo1, foo2 = Foo(), Foo() + ref1, ref2 = weakref.ref(foo1), weakref.ref(foo2) + self.assertTrue(ref1() is foo1) + self.assertTrue(ref2() is foo2) + + def test___hash__call(self): + hash_called = [] + class Bar(object): + def __hash__(self): + hash = object.__hash__(self) + hash_called.append(hash) + return hash + bar = Bar() + ref = weakref.ref(bar) + self.assertFalse(hash_called) + + hash(ref) + self.assertEqual(len(hash_called), 1) + hash(ref) + self.assertEqual(len(hash_called), 1) + self.assertEqual(hash(bar), hash(ref)) + self.assertEqual(len(hash_called), 2) + + +def test_main(): + test_support.run_unittest(ReferencesTestCase) + + +if __name__ == '__main__': + test_main() Modified: trunk/jython/src/org/python/modules/_weakref/AbstractReference.java =================================================================== --- trunk/jython/src/org/python/modules/_weakref/AbstractReference.java 2009-03-31 16:35:51 UTC (rev 6138) +++ trunk/jython/src/org/python/modules/_weakref/AbstractReference.java 2009-03-31 19:04:48 UTC (rev 6139) @@ -42,10 +42,7 @@ } public int hashCode() { - if (gref.realHash) { - return gref.hash; - } - throw Py.TypeError("unhashable instance"); + return gref.pythonHashCode(); } public PyObject __eq__(PyObject other) { Modified: trunk/jython/src/org/python/modules/_weakref/GlobalRef.java =================================================================== --- trunk/jython/src/org/python/modules/_weakref/GlobalRef.java 2009-03-31 16:35:51 UTC (rev 6138) +++ trunk/jython/src/org/python/modules/_weakref/GlobalRef.java 2009-03-31 19:04:48 UTC (rev 6139) @@ -5,29 +5,38 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.ArrayList; -import java.util.Map; import java.util.List; +import java.util.concurrent.ConcurrentMap; import org.python.core.Py; -import org.python.core.PyException; import org.python.core.PyList; import org.python.core.PyObject; import org.python.util.Generic; public class GlobalRef extends WeakReference { - int hash; + /** + * This reference's hashCode: the System.identityHashCode of the referent. Only used + * internally. + */ + private int hashCode; - /** Whether the hash value was calculated by the underlying object. */ - boolean realHash; + /** + * The public hashCode for the Python AbstractReference wrapper. Derived from the + * referent's hashCode. + */ + private int pythonHashCode; + /** Whether pythonHashCode was already determined. */ + private boolean havePythonHashCode; + private List references = new ArrayList(); private static ReferenceQueue referenceQueue = new ReferenceQueue(); private static RefReaperThread reaperThread; - private static Map<GlobalRef, GlobalRef> objects = Generic.map(); + private static ConcurrentMap<GlobalRef, GlobalRef> objects = Generic.concurrentMap(); static { initReaperThread(); @@ -35,29 +44,9 @@ public GlobalRef(PyObject object) { super(object, referenceQueue); - calcHash(object); + hashCode = System.identityHashCode(object); } - /** - * Calculate a hash code to use for this object. If the PyObject we're - * referencing implements hashCode, we use that value. If not, we use - * System.identityHashCode(refedObject). This allows this object to be - * used in a Map while allowing Python ref objects to tell if the - * hashCode is actually valid for the object. - */ - private void calcHash(PyObject object) { - try { - hash = object.hashCode(); - realHash = true; - } catch (PyException pye) { - if (Py.matchException(pye, Py.TypeError)) { - hash = System.identityHashCode(object); - } else { - throw pye; - } - } - } - public synchronized void add(AbstractReference ref) { Reference r = new WeakReference(ref); references.add(r); @@ -148,16 +137,37 @@ if (t == u) { return true; } - return t.equals(u); + // Don't consult the objects' equals (__eq__) method, it can't be trusted + return false; } /** - * Allow GlobalRef's to be used as hashtable keys. + * Allows GlobalRef to be used as hashtable keys. + * + * @return a hashCode int value */ public int hashCode() { - return hash; + return hashCode; } + /** + * The publicly used hashCode, for the AbstractReference wrapper. + * + * @return a hashCode int value + */ + public int pythonHashCode() { + if (havePythonHashCode) { + return pythonHashCode; + } + Object referent = get(); + if (referent == null) { + throw Py.TypeError("weak object has gone away"); + } + pythonHashCode = referent.hashCode(); + havePythonHashCode = true; + return pythonHashCode; + } + private static void initReaperThread() { reaperThread = new RefReaperThread(); reaperThread.setDaemon(true); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2009-03-31 23:54:02
|
Revision: 6142 http://jython.svn.sourceforge.net/jython/?rev=6142&view=rev Author: thobes Date: 2009-03-31 23:53:50 +0000 (Tue, 31 Mar 2009) Log Message: ----------- Fixed a problem with functions being bound to a name before decorators are applied. Also added a test case that checks for it. Modified Paths: -------------- trunk/jython/src/org/python/compiler/CodeCompiler.java Added Paths: ----------- trunk/jython/Lib/test/test_decorators_jy.py Added: trunk/jython/Lib/test/test_decorators_jy.py =================================================================== --- trunk/jython/Lib/test/test_decorators_jy.py (rev 0) +++ trunk/jython/Lib/test/test_decorators_jy.py 2009-03-31 23:53:50 UTC (rev 6142) @@ -0,0 +1,24 @@ +"""Misc decorator related tests + +Made for Jython. +""" +from test import test_support +import unittest + +class TestDecorators(unittest.TestCase): + + def test_lookup_order(self): + class Foo(object): + foo = 'bar' + @property + def property(self): + return self.foo + self.assertEqual(Foo().property, 'bar') + + +def test_main(): + test_support.run_unittest(TestDecorators) + + +if __name__ == '__main__': + test_main() Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-03-31 23:30:57 UTC (rev 6141) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-03-31 23:53:50 UTC (rev 6142) @@ -420,22 +420,29 @@ } else { code.invokespecial( "org/python/core/PyFunction", "<init>", "(" + $pyObj + $pyObjArr + $pyCode + $pyObj + $pyObjArr + ")V"); } + + applyDecorators(node.getInternalDecorator_list()); set(new Name(node,node.getInternalName(), expr_contextType.Store)); - doDecorators(node,node.getInternalDecorator_list(), node.getInternalName()); + //doDecorators(node,node.getInternalDecorator_list(), node.getInternalName()); return null; } - private void doDecorators(stmt node, java.util.List<expr> decs, String name) throws Exception { - if (decs.size() > 0) { - expr currentExpr = new Name(node, name, expr_contextType.Load); - for (int i=decs.size() - 1;i > -1;i--) { - java.util.List args = new ArrayList(); - args.add(currentExpr); - currentExpr = new Call(node, decs.get(i), args, new ArrayList<keyword>(), null, null); + private void applyDecorators(java.util.List<expr> decorators) throws Exception { + if (decorators != null && !decorators.isEmpty()) { + int res = storeTop(); + for (expr decorator : decorators) { + visit(decorator); stackProduce(); } - visit(currentExpr); - set(new Name(node, name, expr_contextType.Store)); + for (int i = decorators.size(); i > 0; i--) { + stackConsume(); + loadThreadState(); + code.aload(res); + code.invokevirtual("org/python/core/PyObject", "__call__", "(" + $threadState + $pyObj + ")" + $pyObj); + code.astore(res); + } + code.aload(res); + code.freeLocal(res); } } @@ -2023,10 +2030,12 @@ } else { code.invokestatic("org/python/core/Py", "makeClass", "(" + $str + $pyObjArr + $pyCode + $pyObj + $pyObjArr + ")" + $pyObj); } + + applyDecorators(node.getInternalDecorator_list()); //Assign this new class to the given name set(new Name(node,node.getInternalName(), expr_contextType.Store)); - doDecorators(node,node.getInternalDecorator_list(), node.getInternalName()); + //doDecorators(node,node.getInternalDecorator_list(), node.getInternalName()); return null; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-04-04 04:11:19
|
Revision: 6157 http://jython.svn.sourceforge.net/jython/?rev=6157&view=rev Author: pjenvey Date: 2009-04-04 04:11:13 +0000 (Sat, 04 Apr 2009) Log Message: ----------- fix unicode format mappings to use unicode keys Modified Paths: -------------- trunk/jython/Lib/test/test_unicode_jy.py trunk/jython/src/org/python/core/PyString.java Modified: trunk/jython/Lib/test/test_unicode_jy.py =================================================================== --- trunk/jython/Lib/test/test_unicode_jy.py 2009-04-04 01:16:56 UTC (rev 6156) +++ trunk/jython/Lib/test/test_unicode_jy.py 2009-04-04 04:11:13 UTC (rev 6157) @@ -109,8 +109,21 @@ self.assertEquals('\xe2\x82\xac', encoded_euro) self.assertEquals(EURO_SIGN, encoded_euro.decode('utf-8')) + +class UnicodeFormatTestCase(unittest.TestCase): + + def test_unicode_mapping(self): + assertTrue = self.assertTrue + class EnsureUnicode(dict): + def __missing__(self, key): + assertTrue(isinstance(key, unicode)) + return key + u'%(foo)s' % EnsureUnicode() + + def test_main(): - test_support.run_unittest(UnicodeTestCase) + test_support.run_unittest(UnicodeTestCase, + UnicodeFormatTestCase) if __name__ == "__main__": Modified: trunk/jython/src/org/python/core/PyString.java =================================================================== --- trunk/jython/src/org/python/core/PyString.java 2009-04-04 01:16:56 UTC (rev 6156) +++ trunk/jython/src/org/python/core/PyString.java 2009-04-04 04:11:13 UTC (rev 6157) @@ -2852,7 +2852,7 @@ parens++; } String tmp = format.substring(keyStart, index-1); - this.args = dict.__getitem__(new PyString(tmp)); + this.args = dict.__getitem__(needUnicode ? new PyUnicode(tmp) : new PyString(tmp)); } else { push(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-04-05 01:53:37
|
Revision: 6161 http://jython.svn.sourceforge.net/jython/?rev=6161&view=rev Author: pjenvey Date: 2009-04-05 01:53:25 +0000 (Sun, 05 Apr 2009) Log Message: ----------- convert PyClass to exposed annotations Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/src/org/python/core/Py.java trunk/jython/src/org/python/core/PyClass.java trunk/jython/src/org/python/modules/_newmodule.java Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2009-04-05 01:15:45 UTC (rev 6160) +++ trunk/jython/CoreExposed.includes 2009-04-05 01:53:25 UTC (rev 6161) @@ -6,6 +6,7 @@ org/python/core/PyBoolean.class org/python/core/PyBuiltinCallable.class org/python/core/PyCell.class +org/python/core/PyClass.class org/python/core/PyClassMethod.class org/python/core/PyClassMethodDescr.class org/python/core/PyComplex.class Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-04-05 01:15:45 UTC (rev 6160) +++ trunk/jython/src/org/python/core/Py.java 2009-04-05 01:53:25 UTC (rev 6161) @@ -1532,8 +1532,6 @@ String.class, PyTuple.class, PyObject.class, Class.class }; - static private final PyType CLASS_TYPE = PyType.fromClass(PyClass.class); - // XXX: The following two makeClass overrides are *only* for the // old compiler, they should be removed when the newcompiler hits public static PyObject makeClass(String name, PyObject[] bases, @@ -1590,21 +1588,10 @@ if (globals != null) { metaclass = globals.__finditem__("__metaclass__"); } - } - } - - if (metaclass == null || metaclass == CLASS_TYPE) { - boolean moreGeneral = false; - for (PyObject base : bases) { - if (!(base instanceof PyClass)) { - metaclass = base.getType(); - moreGeneral = true; - break; + if (metaclass == null) { + metaclass = PyClass.TYPE; } } - if (!moreGeneral) { - return new PyClass(name, new PyTuple(bases), dict); - } } try { Modified: trunk/jython/src/org/python/core/PyClass.java =================================================================== --- trunk/jython/src/org/python/core/PyClass.java 2009-04-05 01:15:45 UTC (rev 6160) +++ trunk/jython/src/org/python/core/PyClass.java 2009-04-05 01:53:25 UTC (rev 6161) @@ -1,56 +1,91 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; +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 class. + * The classic Python class. */ +@ExposedType(name = "classobj", isBaseType = false) public class PyClass extends PyObject { - /** - * Holds the namespace for this class - */ + + public static final PyType TYPE = PyType.fromClass(PyClass.class); + + /** Holds the namespace for this class */ + @ExposedGet public PyObject __dict__; - /** - * The base classes of this class - */ + /** The base classes of this class */ + @ExposedGet public PyTuple __bases__; - /** - * The name of this class - */ + /** The name of this class */ + @ExposedGet + @ExposedSet public String __name__; - // Store these methods for performance optimization - // These are only used by PyInstance - PyObject __getattr__, __setattr__, __delattr__, __tojava__, __del__, - __contains__; + // Store these methods for performance optimization. These are only used by PyInstance + PyObject __getattr__, __setattr__, __delattr__, __tojava__, __del__, __contains__; - protected PyClass() { - super(); - } - /** - * Create a python class. - * - * @param name name of the class. - * @param bases A list of base classes. - * @param dict The class dict. Normally this dict is returned by the class - * code object. - * - * @see org.python.core.Py#makeClass(String, PyObject[], PyCode, PyObject) + * Create a new instance of a Python classic class. */ - public PyClass(String name, PyTuple bases, PyObject dict) { - __name__ = name; - __bases__ = bases; - __dict__ = dict; + private PyClass() { + super(TYPE); + } - findModule(dict); + @ExposedNew + public static PyObject classobj___new__(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { + ArgParser ap = new ArgParser("function", args, keywords, "name", "bases", "dict"); + PyObject name = ap.getPyObject(0); + PyObject bases = ap.getPyObject(1); + PyObject dict = ap.getPyObject(2); + return classobj___new__(name, bases, dict); + } + public static PyObject classobj___new__(PyObject name, PyObject bases, PyObject dict) { + if (!name.getType().isSubType(PyString.TYPE)) { + throw Py.TypeError("PyClass_New: name must be a string"); + } + if (!(dict instanceof PyStringMap || dict instanceof PyDictionary)) { + throw Py.TypeError("PyClass_New: dict must be a dictionary"); + } if (dict.__finditem__("__doc__") == null) { dict.__setitem__("__doc__", Py.None); } + findModule(dict); - // Setup cached references to methods where performance really counts + if (!(bases instanceof PyTuple)) { + throw Py.TypeError("PyClass_New: bases must be a tuple"); + } + PyTuple basesTuple = (PyTuple)bases; + for (PyObject base : basesTuple.getArray()) { + if (!(base instanceof PyClass)) { + if (base.getType().isCallable()) { + return base.getType().__call__(name, bases, dict); + } else { + throw Py.TypeError("PyClass_New: base must be a class"); + } + } + } + + PyClass klass = new PyClass(); + klass.__name__ = name.toString(); + klass.__bases__ = basesTuple; + klass.__dict__ = dict; + klass.cacheDescriptors(); + return klass; + } + + /** + * Setup cached references to methods where performance really counts + */ + private void cacheDescriptors() { __getattr__ = lookup("__getattr__", false); __setattr__ = lookup("__setattr__", false); __delattr__ = lookup("__delattr__", false); @@ -59,7 +94,7 @@ __contains__ = lookup("__contains__", false); } - protected void findModule(PyObject dict) { + private static void findModule(PyObject dict) { PyObject module = dict.__finditem__("__module__"); if (module == null || module == Py.None) { PyFrame f = Py.getFrame(); @@ -89,68 +124,27 @@ return new PyObject[] { result, resolvedClass }; } - public PyObject fastGetDict() { - return __dict__; - } - PyObject lookup(String name, boolean stop_at_java) { PyObject[] result = lookupGivingClass(name, stop_at_java); return result[0]; } + @Override + public PyObject fastGetDict() { + return __dict__; + } + + @Override public PyObject __findattr_ex__(String name) { - if (name == "__dict__") { - return __dict__; - } - if (name == "__name__") { - return new PyString(__name__); - } - if (name == "__bases__") { - return __bases__; - } - if (name == "__class__") { - return null; - } - PyObject[] result = lookupGivingClass(name, false); - if (result[0] == null) { return super.__findattr_ex__(name); } - // xxx do we need to use result[1] (wherefound) for java cases for backw - // comp? + // XXX: do we need to use result[1] (wherefound) for java cases for backw comp? return result[0].__get__(null, this); } - public void __setattr__(String name, PyObject value) { - if (name == "__dict__") { - if (!value.isMappingType()) - throw Py.TypeError("__dict__ must be a dictionary object"); - __dict__ = value; - return; - } - if (name == "__name__") { - if (!(value instanceof PyString)) { - throw Py.TypeError("__name__ must be a string object"); - } - __name__ = value.toString(); - return; - } - if (name == "__bases__") { - if (!(value instanceof PyTuple)) { - throw Py.TypeError("__bases__ must be a tuple object"); - } - __bases__ = (PyTuple) value; - return; - } - - __dict__.__setitem__(name, value); - } - - public void __delattr__(String name) { - __dict__.__delitem__(name); - } - + @Override public void __rawdir__(PyDictionary accum) { mergeClassDict(accum, this); } @@ -158,25 +152,28 @@ /** * Customized AttributeError for class objects. */ + @Override public void noAttributeError(String name) { throw Py.AttributeError(String.format("class %.50s has no attribute '%.400s'", __name__, name)); } + @Override + @ExposedMethod public PyObject __call__(PyObject[] args, String[] keywords) { PyInstance inst; if (__del__ == null) { inst = new PyInstance(this); } else { - // the class defined an __del__ method + // the class defined a __del__ method inst = new PyFinalizableInstance(this); } inst.__init__(args, keywords); - return inst; } /* PyClass's are compared based on __name__ */ + @Override public int __cmp__(PyObject other) { if (!(other instanceof PyClass)) { return -2; @@ -185,6 +182,7 @@ return c < 0 ? -1 : c > 0 ? 1 : 0; } + @Override public PyString __str__() { // Current CPython standard is that str(class) prints as // module.class. If the class has no module, then just the class @@ -200,6 +198,7 @@ return new PyString(smod + "." + __name__); } + @Override public String toString() { PyObject mod = __dict__.__finditem__("__module__"); String smod; @@ -215,17 +214,35 @@ if (this == superclass) { return true; } - if (this.__bases__ == null || superclass.__bases__ == null) { + if (__bases__ == null || superclass.__bases__ == null) { return false; } - PyObject[] bases = this.__bases__.getArray(); - int n = bases.length; - for (int i = 0; i < n; i++) { - PyClass c = (PyClass) bases[i]; - if (c.isSubClass(superclass)) { + for (PyObject base: __bases__.getArray()) { + if (((PyClass)base).isSubClass(superclass)) { return true; } } return false; } + + @ExposedSet(name = "__dict__") + public void setDict(PyObject value) { + if (!(value instanceof PyStringMap || value instanceof PyDictionary)) { + throw Py.TypeError("__dict__ must be a dictionary object"); + } + __dict__ = value; + } + + @ExposedSet(name = "__bases__") + public void setBases(PyTuple value) { + for (PyObject base : value.getArray()) { + if (!(base instanceof PyClass)) { + throw Py.TypeError("__bases__ items must be classes"); + } + if (((PyClass)base).isSubClass(this)) { + throw Py.TypeError("a __bases__ item causes an inheritance cycle"); + } + } + __bases__ = value; + } } Modified: trunk/jython/src/org/python/modules/_newmodule.java =================================================================== --- trunk/jython/src/org/python/modules/_newmodule.java 2009-04-05 01:15:45 UTC (rev 6160) +++ trunk/jython/src/org/python/modules/_newmodule.java 2009-04-05 01:53:25 UTC (rev 6161) @@ -33,6 +33,6 @@ return base.getType().__call__(Py.newString(name), bases, dict); } } - return new PyClass(name, bases, dict); + return Py.makeClass(name, bases.getArray(), dict); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-04-05 02:33:04
|
Revision: 6162 http://jython.svn.sourceforge.net/jython/?rev=6162&view=rev Author: pjenvey Date: 2009-04-05 02:32:50 +0000 (Sun, 05 Apr 2009) Log Message: ----------- remove the _new.classobj hack now that PyClass __new__ does the right thing Modified Paths: -------------- trunk/jython/Lib/new.py trunk/jython/src/org/python/modules/Setup.java Removed Paths: ------------- trunk/jython/src/org/python/modules/_newmodule.java Modified: trunk/jython/Lib/new.py =================================================================== --- trunk/jython/Lib/new.py 2009-04-05 01:53:25 UTC (rev 6161) +++ trunk/jython/Lib/new.py 2009-04-05 02:32:50 UTC (rev 6162) @@ -4,10 +4,7 @@ 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 ClassType as classobj from types import FunctionType as function from types import InstanceType as instance from types import MethodType as instancemethod Modified: trunk/jython/src/org/python/modules/Setup.java =================================================================== --- trunk/jython/src/org/python/modules/Setup.java 2009-04-05 01:53:25 UTC (rev 6161) +++ trunk/jython/src/org/python/modules/Setup.java 2009-04-05 02:32:50 UTC (rev 6162) @@ -41,7 +41,6 @@ "_codecs", "imp", "ucnhash", - "_new:org.python.modules._newmodule", "_weakref:org.python.modules._weakref.WeakrefModule", "errno", "array:org.python.modules.ArrayModule", Deleted: trunk/jython/src/org/python/modules/_newmodule.java =================================================================== --- trunk/jython/src/org/python/modules/_newmodule.java 2009-04-05 01:53:25 UTC (rev 6161) +++ trunk/jython/src/org/python/modules/_newmodule.java 2009-04-05 02:32:50 UTC (rev 6162) @@ -1,38 +0,0 @@ -/* Copyright (c) 2001, 2003 Finn Bock, Samuele Pedroni */ -package org.python.modules; - -import org.python.core.ClassDictInit; -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 implements ClassDictInit { - - public static void classDictInit(PyObject dict) - { - dict.__setitem__("__name__", Py.newString("_new")); - } - - 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 Py.makeClass(name, bases.getArray(), dict); - } -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fwi...@us...> - 2009-04-05 18:30:08
|
Revision: 6165 http://jython.svn.sourceforge.net/jython/?rev=6165&view=rev Author: fwierzbicki Date: 2009-04-05 18:29:58 +0000 (Sun, 05 Apr 2009) Log Message: ----------- Fix for http://bugs.jython.org/issue1264 'is not' test exhibits incorrect behaviour when wrapping Java objects Included is a reshuffling of the patch test so that a regression test can pick it up. It isn't perfect since I had to use raw "assert" statements in the python, but it is run by the Java unit test IdentityTest. Thanks to Geoffrey French for the patch. Modified Paths: -------------- trunk/jython/ACKNOWLEDGMENTS trunk/jython/NEWS trunk/jython/src/org/python/core/PyObject.java Added Paths: ----------- trunk/jython/tests/java/org/python/tests/identity/ trunk/jython/tests/java/org/python/tests/identity/IdentityObject.java trunk/jython/tests/java/org/python/tests/identity/IdentityTest.java trunk/jython/tests/python/ trunk/jython/tests/python/identity_test.py Modified: trunk/jython/ACKNOWLEDGMENTS =================================================================== --- trunk/jython/ACKNOWLEDGMENTS 2009-04-05 17:22:40 UTC (rev 6164) +++ trunk/jython/ACKNOWLEDGMENTS 2009-04-05 18:29:58 UTC (rev 6165) @@ -66,6 +66,7 @@ Nathan Franzen Aleks Totic Randolph Brown + Geoffrey French Local Variables: mode: indented-text Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-04-05 17:22:40 UTC (rev 6164) +++ trunk/jython/NEWS 2009-04-05 18:29:58 UTC (rev 6165) @@ -2,6 +2,7 @@ Jython 2.5.0 rc 1 Bugs fixed (new numbering due to move to Roundup) + - [ 1264 ] 'is not' test exhibits incorrect behaviour when wrapping Java objects - [ 1295 ] Setting a write-only bean property causes a NPE - [ 1272 ] ASTList ClassCastException - [ 1261 ] jython -c "import sys; sys.exit(1)" not giving correct exit code. Modified: trunk/jython/src/org/python/core/PyObject.java =================================================================== --- trunk/jython/src/org/python/core/PyObject.java 2009-04-05 17:22:40 UTC (rev 6164) +++ trunk/jython/src/org/python/core/PyObject.java 2009-04-05 18:29:58 UTC (rev 6165) @@ -1633,7 +1633,7 @@ public PyObject _isnot(PyObject o) { // Access javaProxy directly here as is is for object identity, and at best getJavaProxy // will initialize a new object with a different identity - return this != o || javaProxy != o.javaProxy ? Py.True : Py.False; + return this != o && (javaProxy == null || javaProxy != o.javaProxy) ? Py.True : Py.False; } /** Added: trunk/jython/tests/java/org/python/tests/identity/IdentityObject.java =================================================================== --- trunk/jython/tests/java/org/python/tests/identity/IdentityObject.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/identity/IdentityObject.java 2009-04-05 18:29:58 UTC (rev 6165) @@ -0,0 +1,12 @@ +package org.python.tests.identity; + +public class IdentityObject { + + public IdentityObject() { + } + + public IdentityObject getThis() { + return this; + } + +} Added: trunk/jython/tests/java/org/python/tests/identity/IdentityTest.java =================================================================== --- trunk/jython/tests/java/org/python/tests/identity/IdentityTest.java (rev 0) +++ trunk/jython/tests/java/org/python/tests/identity/IdentityTest.java 2009-04-05 18:29:58 UTC (rev 6165) @@ -0,0 +1,28 @@ +package org.python.tests.identity; + +import junit.framework.TestCase; + +import org.python.core.PyString; +import org.python.core.PyStringMap; +import org.python.core.PySystemState; +import org.python.util.PythonInterpreter; + +public class IdentityTest extends TestCase { + + private PythonInterpreter interp; + + @Override + protected void setUp() throws Exception { + PySystemState sys = new PySystemState(); + sys.path.append(new PyString("dist/Lib")); + sys.path.append(new PyString("dist/javalib/constantine.jar")); + sys.path.append(new PyString("dist/javalib/jna.jar")); + sys.path.append(new PyString("dist/javalib/jna-posix.jar")); + interp = new PythonInterpreter(new PyStringMap(), sys); + } + + public void testReadonly() { + //This used to cause an NPE see http://bugs.jython.org/issue1295 + interp.execfile("tests/python/identity_test.py"); + } +} Added: trunk/jython/tests/python/identity_test.py =================================================================== --- trunk/jython/tests/python/identity_test.py (rev 0) +++ trunk/jython/tests/python/identity_test.py 2009-04-05 18:29:58 UTC (rev 6165) @@ -0,0 +1,18 @@ +from org.python.tests.identity import IdentityObject + +class PyIdentityObject (IdentityObject): + pass + +x = IdentityObject() +y = x.getThis() + +a = PyIdentityObject() +b = a.getThis() + +assert x is y +assert not(x is not y) +assert (x is y) != (x is not y) +assert a is b +assert not(a is not b) +assert (a is b) != (a is not b) + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-04-05 22:13:46
|
Revision: 6169 http://jython.svn.sourceforge.net/jython/?rev=6169&view=rev Author: pjenvey Date: 2009-04-05 22:13:33 +0000 (Sun, 05 Apr 2009) Log Message: ----------- fix dictproxy equality checks Modified Paths: -------------- trunk/jython/Lib/test/test_dictproxy_jy.py trunk/jython/src/org/python/core/PyDictProxy.java Modified: trunk/jython/Lib/test/test_dictproxy_jy.py =================================================================== --- trunk/jython/Lib/test/test_dictproxy_jy.py 2009-04-05 19:27:20 UTC (rev 6168) +++ trunk/jython/Lib/test/test_dictproxy_jy.py 2009-04-05 22:13:33 UTC (rev 6169) @@ -31,8 +31,18 @@ self.assert_(proxy is not copy) self.assertEqual(len(proxy), len(copy)) + def test_dictproxy_equality(self): + self.assertEqual(type.__dict__, type.__dict__) + self.assertEqual(type.__dict__, type.__dict__.copy()) + self.assertEqual(type.__dict__, dict(type.__dict__)) + self.assertEqual(cmp(type.__dict__, type.__dict__), 0) + self.assertEqual(cmp(type.__dict__, type.__dict__.copy()), 0) + self.assertEqual(cmp(type.__dict__, dict(type.__dict__)), 0) + + def test_main(): test_support.run_unittest(DictproxyTestCase) + if __name__ == '__main__': test_main() Modified: trunk/jython/src/org/python/core/PyDictProxy.java =================================================================== --- trunk/jython/src/org/python/core/PyDictProxy.java 2009-04-05 19:27:20 UTC (rev 6168) +++ trunk/jython/src/org/python/core/PyDictProxy.java 2009-04-05 22:13:33 UTC (rev 6169) @@ -93,7 +93,7 @@ @ExposedMethod(type = MethodType.CMP) public int dictproxy___cmp__(PyObject other) { - return dict.__cmp__(other); + return dict._cmp(other); } @ExposedMethod(type = MethodType.BINARY) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-04-05 23:22:05
|
Revision: 6170 http://jython.svn.sourceforge.net/jython/?rev=6170&view=rev Author: pjenvey Date: 2009-04-05 23:21:56 +0000 (Sun, 05 Apr 2009) Log Message: ----------- type shouldn't actually have a __str__ Modified Paths: -------------- trunk/jython/Lib/test/test_class_jy.py trunk/jython/src/org/python/core/PyType.java Modified: trunk/jython/Lib/test/test_class_jy.py =================================================================== --- trunk/jython/Lib/test/test_class_jy.py 2009-04-05 22:13:33 UTC (rev 6169) +++ trunk/jython/Lib/test/test_class_jy.py 2009-04-05 23:21:56 UTC (rev 6170) @@ -336,9 +336,11 @@ Foo.keys = class_dict.keys assert sorted(Foo().keys()) == sorted(['a', 'b']), sorted(Foo().keys()) + class ClassMetaclassRepr(unittest.TestCase): - """Verifies #1131 is fixed""" + def test_repr_with_metaclass(self): + # http://bugs.jython.org/issue1131 class FooMetaclass(type): def __new__(cls, name, bases, attrs): return super(FooMetaclass, cls).__new__(cls, name, bases, attrs) @@ -347,7 +349,17 @@ __metaclass__ = FooMetaclass self.assertEqual("<class '%s.Foo'>" % __name__, repr(Foo)) + def test_metaclass_str(self): + class Foo(type): + def __repr__(cls): + return 'foo' + class Bar(object): + __metaclass__ = Foo + self.assertEqual(repr(Bar), 'foo') + # type.__str__ previously broke this + self.assertEqual(str(Bar), 'foo') + def test_main(): test_support.run_unittest(ClassGeneralTestCase, ClassNamelessModuleTestCase, Modified: trunk/jython/src/org/python/core/PyType.java =================================================================== --- trunk/jython/src/org/python/core/PyType.java 2009-04-05 22:13:33 UTC (rev 6169) +++ trunk/jython/src/org/python/core/PyType.java 2009-04-05 23:21:56 UTC (rev 6170) @@ -1312,7 +1312,7 @@ return numSlots; } - @ExposedMethod(names = {"__repr__", "__str__"}, doc = BuiltinDocs.type___str___doc) + @ExposedMethod(names = "__repr__", doc = BuiltinDocs.type___repr___doc) public String type_toString() { String kind; if (!builtin) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-04-06 02:22:25
|
Revision: 6172 http://jython.svn.sourceforge.net/jython/?rev=6172&view=rev Author: pjenvey Date: 2009-04-06 01:38:32 +0000 (Mon, 06 Apr 2009) Log Message: ----------- convert PyInstance to exposed annotations. fixes its binop rule problems (#1197) Modified Paths: -------------- trunk/jython/CoreExposed.includes trunk/jython/Lib/test/test_descr_jy.py trunk/jython/Misc/make_binops.py trunk/jython/src/org/python/core/PyInstance.java Modified: trunk/jython/CoreExposed.includes =================================================================== --- trunk/jython/CoreExposed.includes 2009-04-06 01:03:47 UTC (rev 6171) +++ trunk/jython/CoreExposed.includes 2009-04-06 01:38:32 UTC (rev 6172) @@ -20,6 +20,7 @@ org/python/core/PyFrozenSet.class org/python/core/PyFunction.class org/python/core/PyGenerator.class +org/python/core/PyInstance.class org/python/core/PyInteger.class org/python/core/PyList.class org/python/core/PyLong.class Modified: trunk/jython/Lib/test/test_descr_jy.py =================================================================== --- trunk/jython/Lib/test/test_descr_jy.py 2009-04-06 01:03:47 UTC (rev 6171) +++ trunk/jython/Lib/test/test_descr_jy.py 2009-04-06 01:38:32 UTC (rev 6172) @@ -96,6 +96,7 @@ except AttributeError, e: self.assertEquals("Custom message", str(e)) + class SubclassDescrTestCase(unittest.TestCase): def test_subclass_cmp_right_op(self): @@ -223,7 +224,15 @@ pass self.assertEquals(DoublerBase(2) * AnotherDoubler(3), 12) + def test_oldstyle_binop_notimplemented(self): + class Foo: + pass + class Bar(object): + def __radd__(self, other): + return 3 + self.assertEqual(Foo() + Bar(), 3) + class InPlaceTestCase(unittest.TestCase): def test_iadd(self): Modified: trunk/jython/Misc/make_binops.py =================================================================== --- trunk/jython/Misc/make_binops.py 2009-04-06 01:03:47 UTC (rev 6171) +++ trunk/jython/Misc/make_binops.py 2009-04-06 01:38:32 UTC (rev 6172) @@ -97,8 +97,15 @@ **/ """ -template1 = comment + """\ +template1 = """\ + @Override public %(ret)s __%(name)s__() { + return instance___%(name)s__(); + } + +""" + comment + """\ + @ExposedMethod + final %(ret)s instance___%(name)s__() { PyObject ret = invoke("__%(name)s__"); if (%(checks)s) return %(cast)sret; @@ -106,8 +113,16 @@ } """ -template2 = comment + """\ + +template2 = """\ + @Override public PyObject __%(name)s__() { + return instance___%(name)s__(); + } + +""" + comment + """\ + @ExposedMethod + public PyObject instance___%(name)s__() { return invoke("__%(name)s__"); } @@ -145,8 +160,15 @@ -template = comment + """\ +template = """\ + @Override public PyObject __%(name)s__(PyObject o) { + return instance___%(name)s__(o); + } + +""" + comment + """\ + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___%(name)s__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__%(name)s__", o); @@ -173,8 +195,15 @@ """ -template2 = comment + """\ +template2 = """\ + @Override public PyObject __%(name)s__(PyObject o) { + return instance___%(name)s__(o); + } + +""" + comment + """\ + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___%(name)s__(PyObject o) { PyObject ret = invoke_ex("__%(name)s__", o); if (ret != null) return ret; Modified: trunk/jython/src/org/python/core/PyInstance.java =================================================================== --- trunk/jython/src/org/python/core/PyInstance.java 2009-04-06 01:03:47 UTC (rev 6171) +++ trunk/jython/src/org/python/core/PyInstance.java 2009-04-06 01:38:32 UTC (rev 6172) @@ -1,25 +1,60 @@ // Copyright (c) Corporation for National Research Initiatives package org.python.core; +import org.python.expose.ExposedMethod; +import org.python.expose.ExposedNew; +import org.python.expose.ExposedType; +import org.python.expose.MethodType; + /** - * A python class instance. + * An instance of a classic Python class. */ +@ExposedType(name = "instance", isBaseType = false) +public class PyInstance extends PyObject { -public class PyInstance extends PyObject -{ + public static final PyType TYPE = PyType.fromClass(PyInstance.class); + // xxx doc, final name public transient PyClass instclass; - // xxx + /** The namespace of this instance. Contains all instance attributes. */ + public PyObject __dict__; + + public PyInstance() { + super(TYPE); + } + + public PyInstance(PyClass iclass, PyObject dict) { + super(TYPE); + instclass = iclass; + if (dict == null) { + dict = new PyStringMap(); + } + __dict__ = dict; + } + + public PyInstance(PyClass iclass) { + this(iclass, null); + } + + @ExposedNew + public static PyObject instance___new__(PyNewWrapper new_, boolean init, PyType subtype, + PyObject[] args, String[] keywords) { + ArgParser ap = new ArgParser("instance", args, keywords, "name", "bases", "dict"); + PyClass klass = (PyClass)ap.getPyObjectByType(0, PyClass.TYPE); + PyObject dict = ap.getPyObject(1, Py.None); + if (dict == Py.None) { + dict = null; + } else if (!(dict instanceof PyStringMap || dict instanceof PyDictionary)) { + throw Py.TypeError("instance() second arg must be dictionary or None"); + } + return new PyInstance(klass, dict); + } + public PyObject fastGetClass() { return instclass; } - /** - The namespace of this instance. Contains all instance attributes. - **/ - public PyObject __dict__; - /* Override serialization behavior */ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException @@ -56,25 +91,7 @@ out.writeUTF(name.toString()); } - - /** - Returns a new - **/ - - public PyInstance(PyClass iclass, PyObject dict) { - instclass = iclass; - if (dict == Py.None) { - dict = new PyStringMap(); - } - __dict__ = dict; - } - - public PyInstance(PyClass iclass) { - this(iclass, new PyStringMap()); - } - - public PyInstance() {} - + @Override public Object __tojava__(Class c) { if (c.isInstance(this)) return this; @@ -117,6 +134,7 @@ } } + @Override public PyObject __findattr_ex__(String name) { PyObject result = ifindlocal(name); if (result != null) { @@ -150,6 +168,7 @@ return getter.__call__(this, new PyString(name)); } + @Override public boolean isCallable() { return __findattr__("__call__") != null; } @@ -159,6 +178,7 @@ return __findattr__("__index__") != null; } + @Override public PyObject invoke(String name) { PyObject f = ifindlocal(name); if (f == null) { @@ -176,6 +196,7 @@ return f.__call__(); } + @Override public PyObject invoke(String name, PyObject arg1) { PyObject f = ifindlocal(name); if (f == null) { @@ -193,6 +214,7 @@ return f.__call__(arg1); } + @Override public PyObject invoke(String name, PyObject arg1, PyObject arg2) { PyObject f = ifindlocal(name); if (f == null) { @@ -210,13 +232,20 @@ return f.__call__(arg1, arg2); } + @Override public void noAttributeError(String name) { throw Py.AttributeError(String.format("%.50s instance has no attribute '%.400s'", instclass.__name__, name)); } + @Override public void __setattr__(String name, PyObject value) { + instance___setattr__(name, value); + } + + @ExposedMethod + final void instance___setattr__(String name, PyObject value) { if (name == "__class__") { if (value instanceof PyClass) { instclass = (PyClass)value; @@ -245,7 +274,13 @@ __dict__.__setitem__(name, value); } + @Override public void __delattr__(String name) { + instance___delattr__(name); + } + + @ExposedMethod + final void instance___delattr__(String name) { PyObject deller = instclass.__delattr__; if (deller != null) { deller.__call__(this, new PyString(name)); @@ -287,7 +322,13 @@ return meth.__call__(arg1, arg2); } + @Override public PyObject __call__(PyObject args[], String keywords[]) { + return instance___call__(args, keywords); + } + + @ExposedMethod + final PyObject instance___call__(PyObject args[], String keywords[]) { ThreadState ts = Py.getThreadState(); if (ts.recursion_depth++ > ts.systemState.getrecursionlimit()) throw Py.RuntimeError("maximum __call__ recursion depth exceeded"); @@ -298,7 +339,18 @@ } } + @Override + public String toString() { + return __repr__().toString(); + } + + @Override public PyString __repr__() { + return instance___repr__(); + } + + @ExposedMethod + final PyString instance___repr__() { PyObject ret = invoke_ex("__repr__"); if (ret == null) { return makeDefaultRepr(); @@ -328,7 +380,13 @@ Py.idstr(this) + ">"); } + @Override public PyString __str__() { + return instance___str__(); + } + + @ExposedMethod + final PyString instance___str__() { PyObject ret = invoke_ex("__str__"); if (ret == null) return __repr__(); @@ -337,7 +395,13 @@ return (PyString)ret; } + @Override public PyUnicode __unicode__() { + return instance___unicode__(); + } + + @ExposedMethod + final PyUnicode instance___unicode__() { PyObject ret = invoke_ex("__unicode__"); if(ret == null) { return super.__unicode__(); @@ -350,6 +414,7 @@ } } + @Override public int hashCode() { PyObject ret; ret = invoke_ex("__hash__"); @@ -368,8 +433,14 @@ throw Py.TypeError("__hash__() must really return int" + ret.getType() ); } + @Override + public int __cmp__(PyObject other) { + return instance___cmp__(other); + } + // special case: does all the work - public int __cmp__(PyObject other) { + @ExposedMethod + final int instance___cmp__(PyObject other) { PyObject[] coerced = this._coerce(other); PyObject v; PyObject w; @@ -415,31 +486,73 @@ return ret; } + @Override public PyObject __lt__(PyObject o) { + return instance___lt__(o); + } + + @ExposedMethod + final PyObject instance___lt__(PyObject o) { return invoke_ex_richcmp("__lt__", o); } + @Override public PyObject __le__(PyObject o) { + return instance___le__(o); + } + + @ExposedMethod + final PyObject instance___le__(PyObject o) { return invoke_ex_richcmp("__le__", o); } + @Override public PyObject __gt__(PyObject o) { + return instance___gt__(o); + } + + @ExposedMethod + final PyObject instance___gt__(PyObject o) { return invoke_ex_richcmp("__gt__", o); } + @Override public PyObject __ge__(PyObject o) { + return instance___ge__(o); + } + + @ExposedMethod + final PyObject instance___ge__(PyObject o) { return invoke_ex_richcmp("__ge__", o); } + @Override public PyObject __eq__(PyObject o) { + return instance___eq__(o); + } + + @ExposedMethod + final PyObject instance___eq__(PyObject o) { return invoke_ex_richcmp("__eq__", o); } + @Override public PyObject __ne__(PyObject o) { + return instance___ne__(o); + } + + @ExposedMethod + final PyObject instance___ne__(PyObject o) { return invoke_ex_richcmp("__ne__", o); } + @Override public boolean __nonzero__() { + return instance___nonzero__(); + } + + @ExposedMethod + final boolean instance___nonzero__() { PyObject meth = null; try { meth = __findattr__("__nonzero__"); @@ -458,13 +571,20 @@ return ret.__nonzero__(); } + @Override public int __len__() { + return instance___len__(); + } + + @ExposedMethod + final int instance___len__() { PyObject ret = invoke("__len__"); if (ret instanceof PyInteger) return ((PyInteger)ret).getValue(); throw Py.TypeError("__len__() should return an int"); } + @Override public PyObject __finditem__(int key) { return __finditem__(new PyInteger(key)); } @@ -490,6 +610,7 @@ } } + @Override public PyObject __finditem__(PyObject key) { try { return invoke("__getitem__", key); @@ -502,19 +623,43 @@ } } + @Override public PyObject __getitem__(PyObject key) { + return instance___getitem__(key); + } + + @ExposedMethod + final PyObject instance___getitem__(PyObject key) { return invoke("__getitem__", key); } + @Override public void __setitem__(PyObject key, PyObject value) { + instance___setitem__(key, value); + } + + @ExposedMethod + final void instance___setitem__(PyObject key, PyObject value) { invoke("__setitem__", key, value); } + @Override public void __delitem__(PyObject key) { + instance___delitem__(key); + } + + @ExposedMethod + final void instance___delitem__(PyObject key) { invoke("__delitem__", key); } + @Override public PyObject __getslice__(PyObject start, PyObject stop, PyObject step) { + return instance___getslice__(start, stop, step); + } + + @ExposedMethod + final PyObject instance___getslice__(PyObject start, PyObject stop, PyObject step) { if (step != null) { return __getitem__(new PySlice(start, stop, step)); } @@ -525,7 +670,13 @@ return super.__getslice__(start, stop, step); } + @Override public void __setslice__(PyObject start, PyObject stop, PyObject step, PyObject value) { + instance___setslice__(start, stop, step, value); + } + + @ExposedMethod + final void instance___setslice__(PyObject start, PyObject stop, PyObject step, PyObject value) { if (step != null) { __setitem__(new PySlice(start, stop, step), value); } else if (trySlice("__setslice__", start, stop, value) == null) { @@ -533,7 +684,13 @@ } } + @Override public void __delslice__(PyObject start, PyObject stop, PyObject step) { + instance___delslice__(start, stop, step); + } + + @ExposedMethod + final void instance___delslice__(PyObject start, PyObject stop, PyObject step) { if (step != null) { __delitem__(new PySlice(start, stop, step)); } else if (trySlice("__delslice__", start, stop) == null) { @@ -541,7 +698,13 @@ } } + @Override public PyObject __iter__() { + return instance___iter__(); + } + + @ExposedMethod + final PyObject instance___iter__() { PyObject func = __findattr__("__iter__"); if (func != null) return func.__call__(); @@ -552,6 +715,7 @@ return new PySequenceIter(this); } + @Override public PyObject __iternext__() { PyObject func = __findattr__("next"); if (func != null) { @@ -566,7 +730,13 @@ throw Py.TypeError("instance has no next() method"); } + @Override public boolean __contains__(PyObject o) { + return instance___contains__(o); + } + + @ExposedMethod + final boolean instance___contains__(PyObject o) { PyObject func = __findattr__("__contains__"); if (func == null) return super.__contains__(o); @@ -574,7 +744,7 @@ return ret.__nonzero__(); } - //Begin the numeric methods here + @Override public Object __coerce_ex__(PyObject o) { PyObject ret = invoke_ex("__coerce__", o); if (ret == null || ret == Py.None) @@ -584,11 +754,17 @@ return ((PyTuple)ret).getArray(); } + @Override + public PyObject __index__() { + return instance___index__(); + } + /** * Implements the __index__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __index__() { + @ExposedMethod + final PyObject instance___index__() { PyObject ret; try { ret = invoke("__index__"); @@ -605,116 +781,181 @@ ret.getType().fastGetName())); } - // Generated by make_binops.py // Unary ops + @Override + public PyString __hex__() { + return instance___hex__(); + } + /** * Implements the __hex__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyString __hex__() { + @ExposedMethod + final PyString instance___hex__() { PyObject ret = invoke("__hex__"); if (ret instanceof PyString) return (PyString)ret; throw Py.TypeError("__hex__() should return a string"); } + @Override + public PyString __oct__() { + return instance___oct__(); + } + /** * Implements the __oct__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyString __oct__() { + @ExposedMethod + final PyString instance___oct__() { PyObject ret = invoke("__oct__"); if (ret instanceof PyString) return (PyString)ret; throw Py.TypeError("__oct__() should return a string"); } + @Override + public PyObject __int__() { + return instance___int__(); + } + /** * Implements the __int__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __int__() { + @ExposedMethod + final PyObject instance___int__() { PyObject ret = invoke("__int__"); if (ret instanceof PyLong || ret instanceof PyInteger) return ret; throw Py.TypeError("__int__() should return a int"); } + @Override + public PyFloat __float__() { + return instance___float__(); + } + /** * Implements the __float__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyFloat __float__() { + @ExposedMethod + final PyFloat instance___float__() { PyObject ret = invoke("__float__"); if (ret instanceof PyFloat) return (PyFloat)ret; throw Py.TypeError("__float__() should return a float"); } + @Override + public PyObject __long__() { + return instance___long__(); + } + /** * Implements the __long__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __long__() { + @ExposedMethod + final PyObject instance___long__() { PyObject ret = invoke("__long__"); if (ret instanceof PyLong || ret instanceof PyInteger) return ret; throw Py.TypeError("__long__() should return a long"); } + @Override + public PyComplex __complex__() { + return instance___complex__(); + } + /** * Implements the __complex__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyComplex __complex__() { + @ExposedMethod + final PyComplex instance___complex__() { PyObject ret = invoke("__complex__"); if (ret instanceof PyComplex) return (PyComplex)ret; throw Py.TypeError("__complex__() should return a complex"); } + @Override + public PyObject __pos__() { + return instance___pos__(); + } + /** * Implements the __pos__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __pos__() { + @ExposedMethod + public PyObject instance___pos__() { return invoke("__pos__"); } + @Override + public PyObject __neg__() { + return instance___neg__(); + } + /** * Implements the __neg__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __neg__() { + @ExposedMethod + public PyObject instance___neg__() { return invoke("__neg__"); } + @Override + public PyObject __abs__() { + return instance___abs__(); + } + /** * Implements the __abs__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __abs__() { + @ExposedMethod + public PyObject instance___abs__() { return invoke("__abs__"); } + @Override + public PyObject __invert__() { + return instance___invert__(); + } + /** * Implements the __invert__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __invert__() { + @ExposedMethod + public PyObject instance___invert__() { return invoke("__invert__"); } // Binary ops + @Override + public PyObject __add__(PyObject o) { + return instance___add__(o); + } + /** * Implements the __add__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __add__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___add__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__add__", o); @@ -738,11 +979,17 @@ } } + @Override + public PyObject __radd__(PyObject o) { + return instance___radd__(o); + } + /** * Implements the __radd__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __radd__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___radd__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__radd__", o); @@ -766,22 +1013,34 @@ } } + @Override + public PyObject __iadd__(PyObject o) { + return instance___iadd__(o); + } + /** * Implements the __iadd__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __iadd__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___iadd__(PyObject o) { PyObject ret = invoke_ex("__iadd__", o); if (ret != null) return ret; return super.__iadd__(o); } + @Override + public PyObject __sub__(PyObject o) { + return instance___sub__(o); + } + /** * Implements the __sub__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __sub__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___sub__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__sub__", o); @@ -805,11 +1064,17 @@ } } + @Override + public PyObject __rsub__(PyObject o) { + return instance___rsub__(o); + } + /** * Implements the __rsub__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rsub__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rsub__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rsub__", o); @@ -833,22 +1098,34 @@ } } + @Override + public PyObject __isub__(PyObject o) { + return instance___isub__(o); + } + /** * Implements the __isub__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __isub__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___isub__(PyObject o) { PyObject ret = invoke_ex("__isub__", o); if (ret != null) return ret; return super.__isub__(o); } + @Override + public PyObject __mul__(PyObject o) { + return instance___mul__(o); + } + /** * Implements the __mul__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __mul__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___mul__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__mul__", o); @@ -872,11 +1149,17 @@ } } + @Override + public PyObject __rmul__(PyObject o) { + return instance___rmul__(o); + } + /** * Implements the __rmul__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rmul__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rmul__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rmul__", o); @@ -900,22 +1183,34 @@ } } + @Override + public PyObject __imul__(PyObject o) { + return instance___imul__(o); + } + /** * Implements the __imul__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __imul__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___imul__(PyObject o) { PyObject ret = invoke_ex("__imul__", o); if (ret != null) return ret; return super.__imul__(o); } + @Override + public PyObject __div__(PyObject o) { + return instance___div__(o); + } + /** * Implements the __div__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __div__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___div__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__div__", o); @@ -939,11 +1234,17 @@ } } + @Override + public PyObject __rdiv__(PyObject o) { + return instance___rdiv__(o); + } + /** * Implements the __rdiv__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rdiv__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rdiv__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rdiv__", o); @@ -967,22 +1268,34 @@ } } + @Override + public PyObject __idiv__(PyObject o) { + return instance___idiv__(o); + } + /** * Implements the __idiv__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __idiv__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___idiv__(PyObject o) { PyObject ret = invoke_ex("__idiv__", o); if (ret != null) return ret; return super.__idiv__(o); } + @Override + public PyObject __floordiv__(PyObject o) { + return instance___floordiv__(o); + } + /** * Implements the __floordiv__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __floordiv__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___floordiv__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__floordiv__", o); @@ -1006,11 +1319,17 @@ } } + @Override + public PyObject __rfloordiv__(PyObject o) { + return instance___rfloordiv__(o); + } + /** * Implements the __rfloordiv__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rfloordiv__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rfloordiv__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rfloordiv__", o); @@ -1034,22 +1353,34 @@ } } + @Override + public PyObject __ifloordiv__(PyObject o) { + return instance___ifloordiv__(o); + } + /** * Implements the __ifloordiv__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __ifloordiv__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___ifloordiv__(PyObject o) { PyObject ret = invoke_ex("__ifloordiv__", o); if (ret != null) return ret; return super.__ifloordiv__(o); } + @Override + public PyObject __truediv__(PyObject o) { + return instance___truediv__(o); + } + /** * Implements the __truediv__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __truediv__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___truediv__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__truediv__", o); @@ -1073,11 +1404,17 @@ } } + @Override + public PyObject __rtruediv__(PyObject o) { + return instance___rtruediv__(o); + } + /** * Implements the __rtruediv__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rtruediv__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rtruediv__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rtruediv__", o); @@ -1101,22 +1438,34 @@ } } + @Override + public PyObject __itruediv__(PyObject o) { + return instance___itruediv__(o); + } + /** * Implements the __itruediv__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __itruediv__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___itruediv__(PyObject o) { PyObject ret = invoke_ex("__itruediv__", o); if (ret != null) return ret; return super.__itruediv__(o); } + @Override + public PyObject __mod__(PyObject o) { + return instance___mod__(o); + } + /** * Implements the __mod__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __mod__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___mod__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__mod__", o); @@ -1140,11 +1489,17 @@ } } + @Override + public PyObject __rmod__(PyObject o) { + return instance___rmod__(o); + } + /** * Implements the __rmod__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rmod__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rmod__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rmod__", o); @@ -1168,22 +1523,34 @@ } } + @Override + public PyObject __imod__(PyObject o) { + return instance___imod__(o); + } + /** * Implements the __imod__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __imod__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___imod__(PyObject o) { PyObject ret = invoke_ex("__imod__", o); if (ret != null) return ret; return super.__imod__(o); } + @Override + public PyObject __divmod__(PyObject o) { + return instance___divmod__(o); + } + /** * Implements the __divmod__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __divmod__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___divmod__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__divmod__", o); @@ -1207,11 +1574,17 @@ } } + @Override + public PyObject __rdivmod__(PyObject o) { + return instance___rdivmod__(o); + } + /** * Implements the __rdivmod__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rdivmod__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rdivmod__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rdivmod__", o); @@ -1235,11 +1608,17 @@ } } + @Override + public PyObject __pow__(PyObject o) { + return instance___pow__(o); + } + /** * Implements the __pow__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __pow__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___pow__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__pow__", o); @@ -1263,11 +1642,17 @@ } } + @Override + public PyObject __rpow__(PyObject o) { + return instance___rpow__(o); + } + /** * Implements the __rpow__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rpow__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rpow__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rpow__", o); @@ -1291,22 +1676,34 @@ } } + @Override + public PyObject __ipow__(PyObject o) { + return instance___ipow__(o); + } + /** * Implements the __ipow__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __ipow__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___ipow__(PyObject o) { PyObject ret = invoke_ex("__ipow__", o); if (ret != null) return ret; return super.__ipow__(o); } + @Override + public PyObject __lshift__(PyObject o) { + return instance___lshift__(o); + } + /** * Implements the __lshift__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __lshift__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___lshift__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__lshift__", o); @@ -1330,11 +1727,17 @@ } } + @Override + public PyObject __rlshift__(PyObject o) { + return instance___rlshift__(o); + } + /** * Implements the __rlshift__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rlshift__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rlshift__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rlshift__", o); @@ -1358,22 +1761,34 @@ } } + @Override + public PyObject __ilshift__(PyObject o) { + return instance___ilshift__(o); + } + /** * Implements the __ilshift__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __ilshift__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___ilshift__(PyObject o) { PyObject ret = invoke_ex("__ilshift__", o); if (ret != null) return ret; return super.__ilshift__(o); } + @Override + public PyObject __rshift__(PyObject o) { + return instance___rshift__(o); + } + /** * Implements the __rshift__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rshift__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rshift__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rshift__", o); @@ -1397,11 +1812,17 @@ } } + @Override + public PyObject __rrshift__(PyObject o) { + return instance___rrshift__(o); + } + /** * Implements the __rrshift__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rrshift__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rrshift__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rrshift__", o); @@ -1425,22 +1846,34 @@ } } + @Override + public PyObject __irshift__(PyObject o) { + return instance___irshift__(o); + } + /** * Implements the __irshift__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __irshift__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___irshift__(PyObject o) { PyObject ret = invoke_ex("__irshift__", o); if (ret != null) return ret; return super.__irshift__(o); } + @Override + public PyObject __and__(PyObject o) { + return instance___and__(o); + } + /** * Implements the __and__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __and__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___and__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__and__", o); @@ -1464,11 +1897,17 @@ } } + @Override + public PyObject __rand__(PyObject o) { + return instance___rand__(o); + } + /** * Implements the __rand__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rand__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rand__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rand__", o); @@ -1492,22 +1931,34 @@ } } + @Override + public PyObject __iand__(PyObject o) { + return instance___iand__(o); + } + /** * Implements the __iand__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __iand__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___iand__(PyObject o) { PyObject ret = invoke_ex("__iand__", o); if (ret != null) return ret; return super.__iand__(o); } + @Override + public PyObject __or__(PyObject o) { + return instance___or__(o); + } + /** * Implements the __or__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __or__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___or__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__or__", o); @@ -1531,11 +1982,17 @@ } } + @Override + public PyObject __ror__(PyObject o) { + return instance___ror__(o); + } + /** * Implements the __ror__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __ror__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___ror__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__ror__", o); @@ -1559,22 +2016,34 @@ } } + @Override + public PyObject __ior__(PyObject o) { + return instance___ior__(o); + } + /** * Implements the __ior__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __ior__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___ior__(PyObject o) { PyObject ret = invoke_ex("__ior__", o); if (ret != null) return ret; return super.__ior__(o); } + @Override + public PyObject __xor__(PyObject o) { + return instance___xor__(o); + } + /** * Implements the __xor__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __xor__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___xor__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__xor__", o); @@ -1598,11 +2067,17 @@ } } + @Override + public PyObject __rxor__(PyObject o) { + return instance___rxor__(o); + } + /** * Implements the __rxor__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __rxor__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___rxor__(PyObject o) { Object ctmp = __coerce_ex__(o); if (ctmp == null || ctmp == Py.None) return invoke_ex("__rxor__", o); @@ -1626,11 +2101,17 @@ } } + @Override + public PyObject __ixor__(PyObject o) { + return instance___ixor__(o); + } + /** * Implements the __ixor__ method by looking it up * in the instance's dictionary and calling it if it is found. **/ - public PyObject __ixor__(PyObject o) { + @ExposedMethod(type = MethodType.BINARY) + public PyObject instance___ixor__(PyObject o) { PyObject ret = invoke_ex("__ixor__", o); if (ret != null) return ret; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-04-06 02:35:32
|
Revision: 6173 http://jython.svn.sourceforge.net/jython/?rev=6173&view=rev Author: pjenvey Date: 2009-04-06 02:35:31 +0000 (Mon, 06 Apr 2009) Log Message: ----------- allow comparison of builtin methods, fixes test_descr.methodwrapper minus its implementation detail Modified Paths: -------------- trunk/jython/Lib/test/test_descr.py trunk/jython/src/org/python/core/PyBuiltinMethod.java Modified: trunk/jython/Lib/test/test_descr.py =================================================================== --- trunk/jython/Lib/test/test_descr.py 2009-04-06 01:38:32 UTC (rev 6172) +++ trunk/jython/Lib/test/test_descr.py 2009-04-06 02:35:31 UTC (rev 6173) @@ -4199,7 +4199,10 @@ verify(l.__add__ != l.__mul__) verify(l.__add__.__name__ == '__add__') verify(l.__add__.__self__ is l) - verify(l.__add__.__objclass__ is list) + if not is_jython: + # XXX: method-wrapper implementation detail, not all builtin + # instance methods have __objclass__ (e.g. l.append) + verify(l.__add__.__objclass__ is list) vereq(l.__add__.__doc__, list.__add__.__doc__) try: hash(l.__add__) @@ -4419,10 +4422,6 @@ # Lack __basicsize__: http://bugs.jython.org/issue1017 slotmultipleinheritance, - # Jython lacks CPython method-wrappers (though maybe this - # should pass anyway?) - methodwrapper, - # derived classes don't support coerce: # http://bugs.jython.org/issue1060 notimplemented Modified: trunk/jython/src/org/python/core/PyBuiltinMethod.java =================================================================== --- trunk/jython/src/org/python/core/PyBuiltinMethod.java 2009-04-06 01:38:32 UTC (rev 6172) +++ trunk/jython/src/org/python/core/PyBuiltinMethod.java 2009-04-06 02:35:31 UTC (rev 6173) @@ -50,4 +50,25 @@ int hashCode = self == null ? 0 : self.hashCode(); return hashCode ^ getClass().hashCode(); } + + @Override + public int __cmp__(PyObject other) { + if (!(other instanceof PyBuiltinMethod)) { + return -2; + } + PyBuiltinMethod otherMethod = (PyBuiltinMethod)other; + if (self != otherMethod.self) { + if (self == null) { + return -1; + } else if (otherMethod.self == null) { + return 1; + } + return self._cmp(otherMethod.self); + } + if (getClass() == otherMethod.getClass()) { + return 0; + } + int compareTo = info.getName().compareTo(otherMethod.info.getName()); + return compareTo < 0 ? -1 : compareTo > 0 ? 1 : 0; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-04-06 03:19:42
|
Revision: 6175 http://jython.svn.sourceforge.net/jython/?rev=6175&view=rev Author: pjenvey Date: 2009-04-06 03:19:30 +0000 (Mon, 06 Apr 2009) Log Message: ----------- fix complex.__nonzero__ Modified Paths: -------------- trunk/jython/Lib/test/test_complex_jy.py trunk/jython/src/org/python/core/PyComplex.java Modified: trunk/jython/Lib/test/test_complex_jy.py =================================================================== --- trunk/jython/Lib/test/test_complex_jy.py 2009-04-06 03:12:07 UTC (rev 6174) +++ trunk/jython/Lib/test/test_complex_jy.py 2009-04-06 03:19:30 UTC (rev 6175) @@ -18,7 +18,11 @@ # regression in 2.5 alphas self.assertEqual((4+0j) ** Foo(), (16+0j)) + def test___nonzero__(self): + self.assertTrue(0.25+0j) + self.assertTrue(25j) + def test_main(): test_support.run_unittest(ComplexTest) Modified: trunk/jython/src/org/python/core/PyComplex.java =================================================================== --- trunk/jython/src/org/python/core/PyComplex.java 2009-04-06 03:12:07 UTC (rev 6174) +++ trunk/jython/src/org/python/core/PyComplex.java 2009-04-06 03:19:30 UTC (rev 6175) @@ -164,7 +164,7 @@ @ExposedMethod(doc = BuiltinDocs.complex___nonzero___doc) final boolean complex___nonzero__() { - return real != 0 && imag != 0; + return real != 0 || imag != 0; } /*public Object __tojava__(Class c) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <pj...@us...> - 2009-04-07 05:49:03
|
Revision: 6185 http://jython.svn.sourceforge.net/jython/?rev=6185&view=rev Author: pjenvey Date: 2009-04-07 05:48:59 +0000 (Tue, 07 Apr 2009) Log Message: ----------- parser string input shouldn't go through universal newlines mode Modified Paths: -------------- trunk/jython/Lib/test/test_builtin_jy.py trunk/jython/Lib/test/test_codeop_jy.py trunk/jython/src/org/python/core/ParserFacade.java Modified: trunk/jython/Lib/test/test_builtin_jy.py =================================================================== --- trunk/jython/Lib/test/test_builtin_jy.py 2009-04-07 02:44:38 UTC (rev 6184) +++ trunk/jython/Lib/test/test_builtin_jy.py 2009-04-07 05:48:59 UTC (rev 6185) @@ -141,23 +141,29 @@ def test_parse_str_eval(self): foo = 'föö' - for code in ("'%s'" % foo.decode('utf-8'), - "# coding: utf-8\n'%s'" % foo, - "%s'%s'" % (BOM_UTF8, foo)): - mod = compile(code, 'foo.py', 'eval') - bar = eval(mod) - self.assertEqual(foo, bar) - bar = eval(code) - self.assertEqual(foo, bar) + for code, expected in ( + ("'%s'" % foo.decode('utf-8'), foo), + ("# coding: utf-8\n'%s'" % foo, foo), + ("%s'%s'" % (BOM_UTF8, foo), foo), + ("'\rfoo\r'", '\rfoo\r') + ): + mod = compile(code, 'test.py', 'eval') + result = eval(mod) + self.assertEqual(result, expected) + result = eval(code) + self.assertEqual(result, expected) def test_parse_str_exec(self): foo = 'föö' - for code in ("a = '%s'" % foo.decode('utf-8'), - "# coding: utf-8\na = '%s'" % foo, - "%sa = '%s'" % (BOM_UTF8, foo)): + for code, expected in ( + ("bar = '%s'" % foo.decode('utf-8'), foo), + ("# coding: utf-8\nbar = '%s'" % foo, foo), + ("%sbar = '%s'" % (BOM_UTF8, foo), foo), + ("bar = '\rfoo\r'", '\rfoo\r') + ): ns = {} exec code in ns - self.assertEqual(foo, ns['a']) + self.assertEqual(ns['bar'], expected) def test_general_eval(self): # Tests that general mappings can be used for the locals argument Modified: trunk/jython/Lib/test/test_codeop_jy.py =================================================================== --- trunk/jython/Lib/test/test_codeop_jy.py 2009-04-07 02:44:38 UTC (rev 6184) +++ trunk/jython/Lib/test/test_codeop_jy.py 2009-04-07 05:48:59 UTC (rev 6185) @@ -1,6 +1,7 @@ """ test compile. derived from test_codeop """ +import codeop import unittest from test import test_support from test.test_support import run_unittest @@ -183,8 +184,17 @@ compile("a = 1\n", "def", 'single').co_filename) +class CodeopTests(unittest.TestCase): + + def test_no_universal_newlines(self): + # previously \r was translated due to universal newlines + code = codeop.compile_command("'\rfoo\r'", symbol='eval') + self.assertEqual(eval(code), '\rfoo\r') + + def test_main(): - run_unittest(CompileTests) + run_unittest(CompileTests, + CodeopTests) if __name__ == "__main__": Modified: trunk/jython/src/org/python/core/ParserFacade.java =================================================================== --- trunk/jython/src/org/python/core/ParserFacade.java 2009-04-07 02:44:38 UTC (rev 6184) +++ trunk/jython/src/org/python/core/ParserFacade.java 2009-04-07 05:48:59 UTC (rev 6185) @@ -220,6 +220,15 @@ CompilerFlags cflags, String filename, boolean fromString) + throws IOException { + return prepBufReader(input, cflags, filename, fromString, true); + } + + private static ExpectedEncodingBufferedReader prepBufReader(InputStream input, + CompilerFlags cflags, + String filename, + boolean fromString, + boolean universalNewlines) throws IOException { input = new BufferedInputStream(input); boolean bom = adjustForBOM(input); @@ -240,12 +249,14 @@ } cflags.encoding = encoding; - // Enable universal newlines mode on the input - StreamIO rawIO = new StreamIO(input, true); - org.python.core.io.BufferedReader bufferedIO = - new org.python.core.io.BufferedReader(rawIO, 0); - UniversalIOWrapper textIO = new UniversalIOWrapper(bufferedIO); - input = new TextIOInputStream(textIO); + if (universalNewlines) { + // Enable universal newlines mode on the input + StreamIO rawIO = new StreamIO(input, true); + org.python.core.io.BufferedReader bufferedIO = + new org.python.core.io.BufferedReader(rawIO, 0); + UniversalIOWrapper textIO = new UniversalIOWrapper(bufferedIO); + input = new TextIOInputStream(textIO); + } Charset cs; try { @@ -270,7 +281,8 @@ private static ExpectedEncodingBufferedReader prepBufReader(String string, CompilerFlags cflags, - String filename) throws IOException { + String filename) + throws IOException { byte[] stringBytes; if (cflags.source_is_utf8) { // Passed unicode, re-encode the String to raw bytes @@ -285,7 +297,7 @@ } else { stringBytes = StringUtil.toBytes(string); } - return prepBufReader(new ByteArrayInputStream(stringBytes), cflags, filename, true); + return prepBufReader(new ByteArrayInputStream(stringBytes), cflags, filename, true, false); } /** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |