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
