Fix error when the first statement of Module/Function/Class is a litteral string
authorQuentin Poirier <qpoirier@itrust.fr>
Thu, 11 Oct 2012 08:38:11 +0000 (10:38 +0200)
committerQuentin Poirier <qpoirier@itrust.fr>
Thu, 11 Oct 2012 08:38:11 +0000 (10:38 +0200)
that does not end by a new line

Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/Parsing.pxd
Cython/Compiler/Parsing.py

index bbb9092..467235d 100644 (file)
@@ -179,10 +179,35 @@ class PostParse(ScopeTrackingTransform):
             '__cythonbufferdefaults__' : self.handle_bufferdefaults
         }
 
+    def _visit_DocString(self, result):
+        if hasattr(result.body, 'stats') and result.body.stats:
+            firstNode = result.body.stats[0]
+            if isinstance(firstNode, Nodes.ExprStatNode) and firstNode.expr.is_string_literal:
+                result.body.stats = result.body.stats[1:]
+                self.doc = firstNode.expr.value
+                result.doc = self.doc
+                return firstNode.expr, result
+        return None, result
+
+    def visit_FuncDefNode(self, node):
+        docNode, result = self._visit_DocString(super(PostParse, self).visit_FuncDefNode(node))
+        return result
+
+    def visit_PyClassDefNode(self, node):
+        docNode, result = self._visit_DocString(super(PostParse, self).visit_PyClassDefNode(node))
+        if docNode:
+            result.classobj.doc = docNode
+        return result
+
+    def visit_CClassDefNode(self, node):
+        docNode, result = self._visit_DocString(super(PostParse, self).visit_CClassDefNode(node))
+        return result
+
     def visit_ModuleNode(self, node):
         self.lambda_counter = 1
         self.genexpr_counter = 1
-        return super(PostParse, self).visit_ModuleNode(node)
+        docNode, result = self._visit_DocString(super(PostParse, self).visit_ModuleNode(node))
+        return result
 
     def visit_LambdaNode(self, node):
         # unpack a lambda expression into the corresponding DefNode
@@ -1646,7 +1671,7 @@ if VALUE is not None:
             return None
         else:
             return self.visit_ClassDefNode(node)
-    
+
     def visit_CStructOrUnionDefNode(self, node):
         # Create a wrapper node if needed.
         # We want to use the struct type information (so it can't happen
index f2aa2db..d0e71f4 100644 (file)
@@ -175,6 +175,5 @@ cdef p_class_statement(PyrexScanner s, decorators)
 cdef p_c_class_definition(PyrexScanner s, pos,  ctx)
 cdef p_c_class_options(PyrexScanner s)
 cdef p_property_decl(PyrexScanner s)
-cdef p_doc_string(PyrexScanner s)
 cdef p_compiler_directive_comments(PyrexScanner s)
 cdef p_cpp_class_definition(PyrexScanner s, pos, ctx)
index 07a2edd..c2abc90 100644 (file)
@@ -1099,10 +1099,7 @@ def p_expression_or_assignment(s):
                 rhs = p_testlist(s)
             return Nodes.InPlaceAssignmentNode(lhs.pos, operator = operator, lhs = lhs, rhs = rhs)
         expr = expr_list[0]
-        if isinstance(expr, (ExprNodes.UnicodeNode, ExprNodes.StringNode, ExprNodes.BytesNode)):
-            return Nodes.PassStatNode(expr.pos)
-        else:
-            return Nodes.ExprStatNode(expr.pos, expr = expr)
+        return Nodes.ExprStatNode(expr.pos, expr = expr)
 
     rhs = expr_list[-1]
     if len(expr_list) == 2:
@@ -1870,8 +1867,6 @@ def p_suite(s, ctx = Ctx(), with_doc = 0, with_pseudo_doc = 0):
     if s.sy == 'NEWLINE':
         s.next()
         s.expect_indent()
-        if with_doc or with_pseudo_doc:
-            doc = p_doc_string(s)
         body = p_statement_list(s, ctx)
         s.expect_dedent()
     else:
@@ -2959,19 +2954,6 @@ def p_property_decl(s):
     doc, body = p_suite(s, Ctx(level = 'property'), with_doc = 1)
     return Nodes.PropertyNode(pos, name = name, doc = doc, body = body)
 
-def p_doc_string(s):
-    if s.sy == 'BEGIN_STRING':
-        pos = s.position()
-        kind, bytes_result, unicode_result = p_cat_string_literal(s)
-        if s.sy != 'EOF':
-            s.expect_newline("Syntax error in doc string")
-        if kind in ('u', ''):
-            return unicode_result
-        warning(pos, "Python 3 requires docstrings to be unicode strings")
-        return bytes_result
-    else:
-        return None
-
 def p_code(s, level=None, ctx=Ctx):
     body = p_statement_list(s, ctx(level = level), first_statement = 1)
     if s.sy != 'EOF':
@@ -3004,7 +2986,7 @@ def p_module(s, pxd, full_module_name, ctx=Ctx):
     if 'language_level' in directive_comments:
         s.context.set_language_level(directive_comments['language_level'])
 
-    doc = p_doc_string(s)
+    doc = None
     if pxd:
         level = 'module_pxd'
     else: