Public extension type properties working from pxd
authorRobert Bradshaw <robertwb@math.washington.edu>
Sun, 3 Aug 2008 02:16:28 +0000 (19:16 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Sun, 3 Aug 2008 02:16:28 +0000 (19:16 -0700)
The issue was that pxd files don't get transformed yet.

--HG--
rename : tests/errors/e_extmember.pyx => tests/run/extmember.pyx

Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py
tests/errors/e_extmember.pyx [deleted file]
tests/run/extmember.pyx [new file with mode: 0644]

index ec07ae86150618dcd1c693a70415f2df125fd542..d06324c9115c6086a2cd8dcf14daf7b0201be973 100644 (file)
@@ -672,6 +672,7 @@ class CVarDefNode(StatNode):
                             cname = cname, visibility = visibility, is_cdef = 1)
                 if need_property:
                     self.need_properties.append(entry)
+                    entry.needs_property = 1
     
 
 class CStructOrUnionDefNode(StatNode):
@@ -979,7 +980,7 @@ class FuncDefNode(StatNode, BlockNode):
         self.put_stararg_decrefs(code)
         if acquire_gil:
             code.putln("PyGILState_Release(_save);")
-        code.putln("/* TODO: decref scope object */")
+        code.putln("/* TODO: decref scope object */")
         # ----- Return
         if not self.return_type.is_void:
             code.putln("return %s;" % Naming.retval_cname)
@@ -2116,6 +2117,15 @@ class CClassDefNode(ClassDefNode):
 
         if self.doc and Options.docstrings:
             scope.doc = embed_position(self.pos, self.doc)
+            
+        if has_body and not self.in_pxd:
+            # transforms not yet run on pxd files
+            from ParseTreeTransforms import AnalyseDeclarationsTransform
+            transform = AnalyseDeclarationsTransform(None)
+            for entry in scope.var_entries:
+                if hasattr(entry, 'needs_property'):
+                    property = transform.create_Property(entry)
+                    self.body.stats.append(property)
 
         if has_body:
             self.body.analyse_declarations(scope)
index c37d2167380ad13f0d95e79c8ba7dcc04683b654..97ff9a82f97cbf03c8ea7ec833d65c8defb5845a 100644 (file)
@@ -339,16 +339,22 @@ property NAME:
             # mechanism for them. 
             stats = []
             for entry in node.need_properties:
-                property = self.basic_property.substitute({
-                    u"ATTR": AttributeNode(pos=entry.pos, obj=NameNode(pos=entry.pos, name="self"), attribute=entry.name),
-                }, pos=entry.pos)
-                property.stats[0].name = entry.name
+                property = self.create_Property(entry)
                 property.analyse_declarations(node.dest_scope)
                 self.visit(property)
                 stats.append(property)
             return StatListNode(pos=node.pos, stats=stats)
         else:
             return None
+            
+    def create_Property(self, entry):
+        property = self.basic_property.substitute({
+                u"ATTR": AttributeNode(pos=entry.pos,
+                                       obj=NameNode(pos=entry.pos, name="self"), 
+                                       attribute=entry.name),
+            }, pos=entry.pos).stats[0]
+        property.name = entry.name
+        return property
 
 class AnalyseExpressionsTransform(CythonTransform):
     def visit_ModuleNode(self, node):
diff --git a/tests/errors/e_extmember.pyx b/tests/errors/e_extmember.pyx
deleted file mode 100644 (file)
index 73b1fdd..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-cdef class Spam:
-       cdef public Spam e
-_ERRORS = u"""
-/Local/Projects/D/Pyrex/Source/Tests/Errors1/e_extmember.pyx:2:18: Non-generic Python attribute cannot be exposed for writing from Python
-"""
diff --git a/tests/run/extmember.pyx b/tests/run/extmember.pyx
new file mode 100644 (file)
index 0000000..86faeed
--- /dev/null
@@ -0,0 +1,13 @@
+__doc__ = """
+    >>> s = Spam()
+    >>> s.e = s
+    >>> s.e = 1
+    Traceback (most recent call last):
+    TypeError: Cannot convert int to extmember.Spam
+    >>> s.e is s
+    True
+    >>> s.e = None
+"""
+
+cdef class Spam:
+       cdef public Spam e