Fix a bug with automatic conversion of public attributes to properties.
authorCraig Citro <craigcitro@gmail.com>
Wed, 7 Jul 2010 08:11:24 +0000 (01:11 -0700)
committerCraig Citro <craigcitro@gmail.com>
Wed, 7 Jul 2010 08:11:24 +0000 (01:11 -0700)
Cython/Compiler/ExprNodes.py
Cython/Compiler/ParseTreeTransforms.py
tests/errors/e_extweakref.pyx
tests/run/extpropertyref.pyx

index 965a8ec4719dcf015360bdda2e0353dbf1ef1e38..852286f4cdeac810a70e9f09acc38e8df8b090b4 100755 (executable)
@@ -3427,7 +3427,8 @@ class AttributeNode(ExprNode):
     def generate_deletion_code(self, code):
         interned_attr_cname = code.intern_identifier(self.attribute)
         self.obj.generate_evaluation_code(code)
-        if self.is_py_attr:
+        if self.is_py_attr or (isinstance(self.entry.scope, Symtab.PropertyScope)
+                               and self.entry.scope.entries.has_key(u'__del__')):
             code.put_error_if_neg(self.pos,
                 'PyObject_DelAttr(%s, %s)' % (
                     self.obj.py_result(),
index adb41c3c22ab06edaeeaea52acf05b2f43bc9704..a9eab1435f120b2353dca609086921695b3b018f 100644 (file)
@@ -952,6 +952,15 @@ property NAME:
     def __set__(self, value):
         ATTR = value
     """, level='c_class')
+    basic_pyobject_property = TreeFragment(u"""
+property NAME:
+    def __get__(self):
+        return ATTR
+    def __set__(self, value):
+        ATTR = value
+    def __del__(self):
+        ATTR = None
+    """, level='c_class')
     basic_property_ro = TreeFragment(u"""
 property NAME:
     def __get__(self):
@@ -1055,7 +1064,10 @@ property NAME:
             
     def create_Property(self, entry):
         if entry.visibility == 'public':
-            template = self.basic_property
+            if entry.type.is_pyobject:
+                template = self.basic_pyobject_property
+            else:
+                template = self.basic_property
         elif entry.visibility == 'readonly':
             template = self.basic_property_ro
         property = template.substitute({
index 8354dcb5f85bf338e3c77bce4ecb6e306d58c7fa..4b68996960ae0288827bff06b987ba052856fedf 100644 (file)
@@ -15,6 +15,7 @@ cdef void f():
 _ERRORS = u"""
 5:20: Illegal use of special attribute __weakref__
 5:20: Illegal use of special attribute __weakref__
+5:20: Illegal use of special attribute __weakref__
 5:20: Special attribute __weakref__ cannot be exposed to Python
 8:22: Illegal use of special attribute __weakref__
 8:22: Special attribute __weakref__ cannot be exposed to Python
index c015454da692a9f83a75279c99ba7a69616396ca..0feb96311477e89b7739f894d371cbd629be84c2 100644 (file)
@@ -15,7 +15,7 @@ def tomato():
 
     >>> lines = __test__.keys()
     >>> len(lines)
-    2
+    3
     >>> 'Spam.eggs.__get__ (line 5)' in lines
     True
     >>> 'tomato (line 11)' in lines
@@ -26,3 +26,17 @@ def tomato():
     spam = Spam()
     lettuce = spam.eggs
     return lettuce
+
+cdef class Bacon(object):
+    cdef object number_of_slices
+    cdef public object is_a_vegetable
+
+def breakfast():
+    """
+    >>> breakfast()
+    """
+    cdef Bacon myslices = Bacon()
+    myslices.is_a_vegetable = True
+    assert myslices.is_a_vegetable, myslices.is_a_vegetable
+    del myslices.is_a_vegetable
+    assert myslices.is_a_vegetable is None, myslices.is_a_vegetable