From: Robert Bradshaw Date: Sun, 3 Aug 2008 02:16:28 +0000 (-0700) Subject: Public extension type properties working from pxd X-Git-Tag: 0.9.8.1~100 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=459f11b4f50a1fa50a9589554d492dd8abbb2538;p=cython.git Public extension type properties working from pxd The issue was that pxd files don't get transformed yet. --HG-- rename : tests/errors/e_extmember.pyx => tests/run/extmember.pyx --- diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index ec07ae86..d06324c9 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -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) diff --git a/Cython/Compiler/ParseTreeTransforms.py b/Cython/Compiler/ParseTreeTransforms.py index c37d2167..97ff9a82 100644 --- a/Cython/Compiler/ParseTreeTransforms.py +++ b/Cython/Compiler/ParseTreeTransforms.py @@ -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 index 73b1fdd8..00000000 --- a/tests/errors/e_extmember.pyx +++ /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 index 00000000..86faeed5 --- /dev/null +++ b/tests/run/extmember.pyx @@ -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