cython-devel

changeset 2054:ddaf43291b55

Fixing up flawed fix for #303
author Dag Sverre Seljebotn <dagss@student.matnat.uio.no>
date Thu May 14 17:28:50 2009 +0200 (2 years ago)
parents b8ba8ad3379d
children ceda186490a1
files Cython/Compiler/Nodes.py Cython/Compiler/ParseTreeTransforms.py tests/run/typedfieldbug_T303.pyx
line diff
1.1 --- a/Cython/Compiler/Nodes.py Thu May 14 17:09:39 2009 +0200 1.2 +++ b/Cython/Compiler/Nodes.py Thu May 14 17:28:50 2009 +0200 1.3 @@ -794,21 +794,25 @@ 1.4 self.dest_scope = dest_scope 1.5 base_type = self.base_type.analyse(env) 1.6 1.7 - # If the field is an external typedef, we cannot be sure about the type, 1.8 - # so do conversion ourself rather than rely on the CPython mechanism (through 1.9 - # a property; made in AnalyseDeclarationsTransform). 1.10 - # Also, if the type is an extension type, then the CPython mechanism does 1.11 - # not do enough type-checking for us. 1.12 - if (dest_scope.is_c_class_scope and 1.13 - ((self.visibility == 'public' 1.14 - and base_type.is_pyobject 1.15 - and (base_type.is_builtin_type or base_type.is_extension_type) 1.16 - or (base_type.is_typedef and base_type.typedef_is_external)))): 1.17 + need_property = False 1.18 + if (dest_scope.is_c_class_scope 1.19 + and self.visibility == 'public' 1.20 + and base_type.is_pyobject 1.21 + and (base_type.is_builtin_type or base_type.is_extension_type)): 1.22 + # If the field is settable and extension type, then the CPython mechanism does 1.23 + # not do enough type-checking for us. 1.24 + need_property = True 1.25 + elif (base_type.is_typedef and base_type.typedef_is_external 1.26 + and (self.visibility in ('public', 'readonly'))): 1.27 + # If the field is an external typedef, we cannot be sure about the type, 1.28 + # so do conversion ourself rather than rely on the CPython mechanism (through 1.29 + # a property; made in AnalyseDeclarationsTransform). 1.30 + need_property = True 1.31 + 1.32 + if need_property: 1.33 + visibility = 'private' 1.34 self.need_properties = [] 1.35 - need_property = True 1.36 - visibility = 'private' 1.37 - else: 1.38 - need_property = False 1.39 + else: 1.40 visibility = self.visibility 1.41 1.42 for declarator in self.declarators:
2.1 --- a/Cython/Compiler/ParseTreeTransforms.py Thu May 14 17:09:39 2009 +0200 2.2 +++ b/Cython/Compiler/ParseTreeTransforms.py Thu May 14 17:28:50 2009 +0200 2.3 @@ -676,6 +676,12 @@ 2.4 ATTR = value 2.5 """, level='c_class') 2.6 2.7 + readonly_property = TreeFragment(u""" 2.8 +property NAME: 2.9 + def __get__(self): 2.10 + return ATTR 2.11 + """, level='c_class') 2.12 + 2.13 def __call__(self, root): 2.14 self.env_stack = [root.scope] 2.15 # needed to determine if a cdef var is declared after it's used. 2.16 @@ -752,7 +758,7 @@ 2.17 # mechanism for them. 2.18 stats = [] 2.19 for entry in node.need_properties: 2.20 - property = self.create_Property(entry) 2.21 + property = self.create_Property(entry, node.visibility == 'readonly') 2.22 property.analyse_declarations(node.dest_scope) 2.23 self.visit(property) 2.24 stats.append(property) 2.25 @@ -760,8 +766,12 @@ 2.26 else: 2.27 return None 2.28 2.29 - def create_Property(self, entry): 2.30 - property = self.basic_property.substitute({ 2.31 + def create_Property(self, entry, readonly): 2.32 + if readonly: 2.33 + template = self.readonly_property 2.34 + else: 2.35 + template = self.basic_property 2.36 + property = template.substitute({ 2.37 u"ATTR": AttributeNode(pos=entry.pos, 2.38 obj=NameNode(pos=entry.pos, name="self"), 2.39 attribute=entry.name),
3.1 --- a/tests/run/typedfieldbug_T303.pyx Thu May 14 17:09:39 2009 +0200 3.2 +++ b/tests/run/typedfieldbug_T303.pyx Thu May 14 17:28:50 2009 +0200 3.3 @@ -1,6 +1,10 @@ 3.4 """ 3.5 >>> f() 3.6 -42.0 42.0 3.7 +42.0 42.0 42.0 3.8 +>>> readonly() 3.9 +Traceback (most recent call last): 3.10 + ... 3.11 +AttributeError: attribute 'var_nf' of 'typedfieldbug_T303.MyClass' objects is not writable 3.12 """ 3.13 3.14 cdef extern from "external_defs.h": 3.15 @@ -10,11 +14,18 @@ 3.16 cdef readonly: 3.17 double var_d 3.18 DoubleTypedef var_nf 3.19 + cdef public: 3.20 + DoubleTypedef mutable 3.21 def __init__(self): 3.22 self.var_d = 42.0 3.23 self.var_nf = 42.0 3.24 + self.mutable = 1 3.25 3.26 def f(): 3.27 c = MyClass() 3.28 - print c.var_d, c.var_nf 3.29 + c.mutable = 42.0 3.30 + print c.var_d, c.var_nf, c.mutable 3.31 3.32 +def readonly(): 3.33 + c = MyClass() 3.34 + c.var_nf = 3