From: <pj...@us...> - 2010-01-09 06:39:03
|
Revision: 6959 http://jython.svn.sourceforge.net/jython/?rev=6959&view=rev Author: pjenvey Date: 2010-01-09 06:38:57 +0000 (Sat, 09 Jan 2010) Log Message: ----------- have the compiler setup class __doc__s as local variables fixes #1532 Modified Paths: -------------- trunk/jython/Lib/test/test_class_jy.py trunk/jython/NEWS trunk/jython/src/org/python/compiler/CodeCompiler.java trunk/jython/src/org/python/compiler/Module.java trunk/jython/src/org/python/core/Py.java Modified: trunk/jython/Lib/test/test_class_jy.py =================================================================== --- trunk/jython/Lib/test/test_class_jy.py 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/Lib/test/test_class_jy.py 2010-01-09 06:38:57 UTC (rev 6959) @@ -310,7 +310,13 @@ self.assertEqual(MyFields2.fields, ['FIELDGATHERERMETA', 'JAVA', 'JYTHON', 'SOMECLASS']) + def test___doc__(self): + class Test(object): + """doc""" + test = 'Test %s' % __doc__ + self.assertEqual(Test.test, 'Test doc') + class IsDescendentTestCase(unittest.TestCase): def test_newstyle_descendent_of_oldstyle(self): Modified: trunk/jython/NEWS =================================================================== --- trunk/jython/NEWS 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/NEWS 2010-01-09 06:38:57 UTC (rev 6959) @@ -2,6 +2,7 @@ Jython 2.5.2a1 Bugs Fixed + - [ 1532 ] Cannot use docstring when defining class - [ 1530 ] BoolOp in multiple assign causes VerifyError - [ 1478 ] defaultdict & weakref.WeakKeyDictionary [TypeError: first argument must be callable] - [ 1487 ] Import of module with latin-1 chars fails on utf-8 file encoding Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2010-01-09 06:38:57 UTC (rev 6959) @@ -248,10 +248,8 @@ return fast_locals && !scope.exec && !scope.from_import_star; } - void parse(mod node, Code code, - boolean fast_locals, String className, - boolean classBody, ScopeInfo scope, CompilerFlags cflags) - throws Exception { + void parse(mod node, Code code, boolean fast_locals, String className, Str classDoc, + boolean classBody, ScopeInfo scope, CompilerFlags cflags) throws Exception { this.fast_locals = fast_locals; this.className = className; this.code = code; @@ -262,14 +260,22 @@ //BEGIN preparse if (classBody) { // Set the class's __module__ to __name__. fails when there's no __name__ - code.aload(1); + loadFrame(); code.ldc("__module__"); - code.aload(1); + loadFrame(); code.ldc("__name__"); code.invokevirtual(p(PyFrame.class), "getname", sig(PyObject.class, String.class)); code.invokevirtual(p(PyFrame.class), "setlocal", sig(Void.TYPE, String.class, - PyObject.class)); + PyObject.class)); + + if (classDoc != null) { + loadFrame(); + code.ldc("__doc__"); + visit(classDoc); + code.invokevirtual(p(PyFrame.class), "setlocal", sig(Void.TYPE, String.class, + PyObject.class)); + } } Label genswitch = new Label(); @@ -345,16 +351,14 @@ } @Override - public Object visitModule(org.python.antlr.ast.Module suite) - throws Exception { - if (suite.getInternalBody().size() > 0 && - suite.getInternalBody().get(0) instanceof Expr && - ((Expr) suite.getInternalBody().get(0)).getInternalValue() instanceof Str) { + public Object visitModule(org.python.antlr.ast.Module suite) throws Exception { + Str docStr = getDocStr(suite.getInternalBody()); + if (docStr != null) { loadFrame(); code.ldc("__doc__"); - visit(((Expr) suite.getInternalBody().get(0)).getInternalValue()); + visit(docStr); code.invokevirtual(p(PyFrame.class), "setglobal", sig(Void.TYPE, String.class, - PyObject.class)); + PyObject.class)); } traverse(suite); return null; @@ -409,13 +413,14 @@ code.freeLocal(array); } - public void getDocString(java.util.List<stmt> suite) throws Exception { - if (suite.size() > 0 && suite.get(0) instanceof Expr && - ((Expr) suite.get(0)).getInternalValue() instanceof Str) { - visit(((Expr) suite.get(0)).getInternalValue()); - } else { - code.aconst_null(); + public Str getDocStr(java.util.List<stmt> suite) { + if (suite.size() > 0) { + stmt stmt = suite.get(0); + if (stmt instanceof Expr && ((Expr) stmt).getInternalValue() instanceof Str) { + return (Str) ((Expr) stmt).getInternalValue(); + } } + return null; } public boolean makeClosure(ScopeInfo scope) throws Exception { @@ -476,7 +481,12 @@ className, false, false, node.getLine(), scope, cflags).get(code); - getDocString(node.getInternalBody()); + Str docStr = getDocStr(node.getInternalBody()); + if (docStr != null) { + visit(docStr); + } else { + code.aconst_null(); + } if (!makeClosure(scope)) { code.invokespecial(p(PyFunction.class), "<init>", sig(Void.TYPE, PyObject.class, @@ -2259,19 +2269,18 @@ scope.setup_closure(); scope.dump(); //Make code object out of suite + module.codeConstant(new Suite(node, node.getInternalBody()), name, false, name, - true, false, node.getLine(), scope, cflags).get(code); + getDocStr(node.getInternalBody()), true, false, node.getLine(), scope, + cflags).get(code); - //Get doc string (if there) - getDocString(node.getInternalBody()); - //Make class out of name, bases, and code if (!makeClosure(scope)) { code.invokestatic(p(Py.class), "makeClass", sig(PyObject.class, String.class, - PyObject[].class, PyCode.class, PyObject.class)); + PyObject[].class, PyCode.class)); } else { code.invokestatic(p(Py.class), "makeClass", sig(PyObject.class, String.class, - PyObject[].class, PyCode.class, PyObject.class, PyObject[].class)); + PyObject[].class, PyCode.class, PyObject[].class)); } applyDecorators(node.getInternalDecorator_list()); Modified: trunk/jython/src/org/python/compiler/Module.java =================================================================== --- trunk/jython/src/org/python/compiler/Module.java 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/src/org/python/compiler/Module.java 2010-01-09 06:38:57 UTC (rev 6959) @@ -7,7 +7,6 @@ import java.util.Enumeration; import java.util.Hashtable; import java.util.List; -import java.util.Map; import org.objectweb.asm.Label; import org.objectweb.asm.Opcodes; @@ -33,6 +32,7 @@ import org.objectweb.asm.Type; import org.python.antlr.ParseException; import org.python.antlr.PythonTree; +import org.python.antlr.ast.Str; import org.python.antlr.ast.Suite; import org.python.antlr.base.mod; import static org.python.util.CodegenUtils.*; @@ -485,16 +485,16 @@ } PyCodeConstant codeConstant(mod tree, String name, boolean fast_locals, String className, - boolean classBody, boolean printResults, int firstlineno, ScopeInfo scope) - throws Exception { - return codeConstant(tree, name, fast_locals, className, classBody, - printResults, firstlineno, scope, null); + boolean classBody, boolean printResults, int firstlineno, + ScopeInfo scope, CompilerFlags cflags) throws Exception { + return codeConstant(tree, name, fast_locals, className, null, classBody, printResults, + firstlineno, scope, cflags); } PyCodeConstant codeConstant(mod tree, String name, boolean fast_locals, String className, - boolean classBody, boolean printResults, int firstlineno, ScopeInfo scope, - CompilerFlags cflags) - throws Exception { + Str classDoc, boolean classBody, boolean printResults, + int firstlineno, ScopeInfo scope, CompilerFlags cflags) + throws Exception { PyCodeConstant code = new PyCodeConstant(tree, name, fast_locals, className, classBody, printResults, firstlineno, scope, cflags, this); @@ -507,7 +507,7 @@ sig(PyObject.class, PyFrame.class, ThreadState.class), ACC_PUBLIC); - compiler.parse(tree, c, fast_locals, className, classBody, scope, cflags); + compiler.parse(tree, c, fast_locals, className, classDoc, classBody, scope, cflags); return code; } Modified: trunk/jython/src/org/python/core/Py.java =================================================================== --- trunk/jython/src/org/python/core/Py.java 2009-12-30 15:38:42 UTC (rev 6958) +++ trunk/jython/src/org/python/core/Py.java 2010-01-09 06:38:57 UTC (rev 6959) @@ -1555,20 +1555,15 @@ // XXX: The following two makeClass overrides are *only* for the // old compiler, they should be removed when the newcompiler hits - public static PyObject makeClass(String name, PyObject[] bases, - PyCode code, PyObject doc) { - return makeClass(name, bases, code, doc, null); + public static PyObject makeClass(String name, PyObject[] bases, PyCode code) { + return makeClass(name, bases, code, null); } - public static PyObject makeClass(String name, PyObject[] bases, - PyCode code, PyObject doc, + public static PyObject makeClass(String name, PyObject[] bases, PyCode code, PyObject[] closure_cells) { ThreadState state = getThreadState(); PyObject dict = code.call(state, Py.EmptyObjects, Py.NoKeywords, state.frame.f_globals, Py.EmptyObjects, new PyTuple(closure_cells)); - if (doc != null && dict.__finditem__("__doc__") == null) { - dict.__setitem__("__doc__", doc); - } return makeClass(name, bases, dict); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |