remove dependency on structmember.h
authorLisandro Dalcin <dalcinl@gmail.com>
Thu, 11 Mar 2010 20:21:13 +0000 (17:21 -0300)
committerLisandro Dalcin <dalcinl@gmail.com>
Thu, 11 Mar 2010 20:21:13 +0000 (17:21 -0300)
12 files changed:
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py
Cython/Compiler/TypeSlots.py
tests/compile/extpymemberdef.pyx
tests/errors/cdef_members_T517.pyx [new file with mode: 0644]
tests/errors/e_extweakref.pyx
tests/run/cdef_members_T517.pyx [new file with mode: 0644]
tests/run/embedsignatures.pyx
tests/run/typedfieldbug_T303.pyx

index ef7e242023fa2c1c8b0ad667cb81b20f3e9fc802..c0010d77679512a1427ee6aa63d13c3e89442931 100644 (file)
@@ -426,6 +426,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
         
         code.put("""
+#include <stddef.h> /* For offsetof */
+#ifndef offsetof
+#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
+#endif
+
 #ifndef PY_LONG_LONG
   #define PY_LONG_LONG LONG_LONG
 #endif
@@ -903,7 +908,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                         self.generate_descr_set_function(scope, code)
                     self.generate_property_accessors(scope, code)
                     self.generate_method_table(scope, code)
-                    self.generate_member_table(scope, code)
                     self.generate_getset_table(scope, code)
                     self.generate_typeobj_definition(full_module_name, entry, code)
     
@@ -1529,34 +1533,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln(
             "};")
     
-    def generate_member_table(self, env, code):
-        #print "ModuleNode.generate_member_table: scope =", env ###
-        if env.public_attr_entries:
-            code.putln("")
-            code.putln(
-                "static struct PyMemberDef %s[] = {" %
-                    env.member_table_cname)
-            type = env.parent_type
-            if type.typedef_flag:
-                objstruct = type.objstruct_cname
-            else:
-                objstruct = "struct %s" % type.objstruct_cname
-            for entry in env.public_attr_entries:
-                type_code = entry.type.pymemberdef_typecode
-                if entry.visibility == 'readonly':
-                    flags = "READONLY"
-                else:
-                    flags = "0"
-                code.putln('{(char *)"%s", %s, %s, %s, 0},' % (
-                    entry.name,
-                    type_code,
-                    "offsetof(%s, %s)" % (objstruct, entry.cname),
-                    flags))
-            code.putln(
-                    "{0, 0, 0, 0, 0}")
-            code.putln(
-                "};")
-    
     def generate_getset_table(self, env, code):
         if env.property_entries:
             code.putln("")
index f5da2453c6b340ebfed49c1b7538ab530d6cdbc4..76418599d8fb27e54eb9630a03f9f3fe871afb9c 100644 (file)
@@ -891,13 +891,13 @@ class CVarDefNode(StatNode):
     #  declarators   [CDeclaratorNode]
     #  in_pxd        boolean
     #  api           boolean
-    #  need_properties [entry]
+    #  properties    [entry]
 
     #  decorators    [cython.locals(...)] or None 
     #  directive_locals { string : NameNode } locals defined by cython.locals(...)
 
     child_attrs = ["base_type", "declarators"]
-    need_properties = ()
+    properties = ()
     
     decorators = None
     directive_locals = {}
@@ -912,15 +912,12 @@ class CVarDefNode(StatNode):
         # so do conversion ourself rather than rely on the CPython mechanism (through
         # a property; made in AnalyseDeclarationsTransform).
         if (dest_scope.is_c_class_scope
-                and self.visibility == 'public' 
-                and base_type.is_pyobject 
-                and (base_type.is_builtin_type or base_type.is_extension_type)):
-            self.need_properties = []
+            and self.visibility in ('public', 'readonly')):
+            self.properties = []
             need_property = True
-            visibility = 'private'
         else:
             need_property = False
-            visibility = self.visibility
+        visibility = self.visibility
             
         for declarator in self.declarators:
             name_declarator, type = declarator.analyse(base_type, env)
@@ -951,8 +948,7 @@ class CVarDefNode(StatNode):
                 entry = dest_scope.declare_var(name, type, declarator.pos,
                             cname = cname, visibility = visibility, is_cdef = 1)
                 if need_property:
-                    self.need_properties.append(entry)
-                    entry.needs_property = 1
+                    self.properties.append(entry)
     
 
 class CStructOrUnionDefNode(StatNode):
index 678260cae092a8489592f9dc30983dd496310a4e..d6cbd5c5ba707a38399c5172eda3f3ad7611cceb 100644 (file)
@@ -952,6 +952,11 @@ property NAME:
     def __set__(self, value):
         ATTR = value
     """, level='c_class')
+    basic_property_ro = TreeFragment(u"""
+property NAME:
+    def __get__(self):
+        return ATTR
+    """, level='c_class')
 
     def __call__(self, root):
         self.env_stack = [root.scope]
@@ -1037,12 +1042,9 @@ property NAME:
         # to ensure all CNameDeclaratorNodes are visited.
         self.visitchildren(node)
 
-        if node.need_properties:
-            # cdef public attributes may need type testing on 
-            # assignment, so we create a property accesss
-            # mechanism for them. 
+        if node.properties:
             stats = []
-            for entry in node.need_properties:
+            for entry in node.properties:
                 property = self.create_Property(entry)
                 property.analyse_declarations(node.dest_scope)
                 self.visit(property)
@@ -1052,13 +1054,34 @@ property NAME:
             return None
             
     def create_Property(self, entry):
-        template = self.basic_property
+        if entry.visibility == 'public':
+            template = self.basic_property
+        elif entry.visibility == 'readonly':
+            template = self.basic_property_ro
         property = template.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
+        # ---------------------------------------
+        # XXX This should go to AutoDocTransforms
+        # ---------------------------------------
+        if self.current_directives['embedsignature']:
+            attr_name = entry.name
+            type_name = entry.type.declaration_code("", for_display=1)
+            default_value = ''
+            if not entry.type.is_pyobject:
+                type_name = "'%s'" % type_name
+            elif entry.type.is_extension_type:
+                type_name = entry.type.module_name + '.' + type_name
+            if entry.init is not None:
+                default_value = ' = ' + entry.init
+            elif entry.init_to_none:
+                default_value = ' = ' + repr(None)
+            docstring = attr_name + ': ' + type_name + default_value
+            property.doc = EncodedString(docstring)
+        # ---------------------------------------
         return property
 
 class AnalyseExpressionsTransform(CythonTransform):
index 3d6a011f0b3db764ebe835b660d31a7ede8d0c02..8e1f7f998ae71c8cdd076f074f31f76a34a40cd4 100755 (executable)
@@ -56,7 +56,6 @@ class PyrexType(BaseType):
     #  is_buffer             boolean     Is buffer access type
     #  has_attributes        boolean     Has C dot-selectable attributes
     #  default_value         string      Initial value
-    #  pymemberdef_typecode  string      Type code for PyMemberDef struct
     #
     #  declaration_code(entity_code, 
     #      for_display = 0, dll_linkage = None, pyrex = 0)
@@ -109,7 +108,6 @@ class PyrexType(BaseType):
     is_buffer = 0
     has_attributes = 0
     default_value = ""
-    pymemberdef_typecode = None
     
     def resolve(self):
         # If a typedef, returns the base type.
@@ -198,18 +196,6 @@ class CTypedefType(BaseType):
         self.typedef_cname = cname
         self.typedef_base_type = base_type
         self.typedef_is_external = is_external
-        # Make typecodes in external typedefs use typesize-neutral macros
-        if is_external:
-            typecode = None
-            if base_type.is_int:
-                if base_type.signed == 0:
-                    typecode = "__Pyx_T_UNSIGNED_INT"
-                else:
-                    typecode = "__Pyx_T_SIGNED_INT"
-            elif base_type.is_float and not rank_to_type_name[base_type.rank] == "long double":
-                typecode = "__Pyx_T_FLOATING"
-            if typecode:
-                self.pymemberdef_typecode = "%s(%s)" % (typecode, cname)
     
     def resolve(self):
         return self.typedef_base_type.resolve()
@@ -349,7 +335,6 @@ class PyObjectType(PyrexType):
     name = "object"
     is_pyobject = 1
     default_value = "0"
-    pymemberdef_typecode = "T_OBJECT"
     buffer_defaults = None
     is_extern = False
     is_subclassed = False
@@ -618,10 +603,9 @@ class CNumericType(CType):
     
     sign_words = ("unsigned ", "", "signed ")
     
-    def __init__(self, rank, signed = 1, pymemberdef_typecode = None):
+    def __init__(self, rank, signed = 1):
         self.rank = rank
         self.signed = signed
-        self.pymemberdef_typecode = pymemberdef_typecode
     
     def sign_and_name(self):
         s = self.sign_words[self.signed]
@@ -787,8 +771,8 @@ class CIntType(CNumericType):
     from_py_function = "__Pyx_PyInt_AsInt"
     exception_value = -1
 
-    def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
-        CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
+    def __init__(self, rank, signed, is_returncode = 0):
+        CNumericType.__init__(self, rank, signed)
         self.is_returncode = is_returncode
         if self.from_py_function == "__Pyx_PyInt_AsInt":
             self.from_py_function = self.get_type_conversion()
@@ -887,8 +871,8 @@ class CFloatType(CNumericType):
 
     exception_value = -1
     
-    def __init__(self, rank, pymemberdef_typecode = None, math_h_modifier = ''):
-        CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
+    def __init__(self, rank, math_h_modifier = ''):
+        CNumericType.__init__(self, rank, 1)
         self.math_h_modifier = math_h_modifier
     
     def assignable_from_resolved_type(self, src_type):
@@ -1988,7 +1972,6 @@ class CStringType(object):
 class CUTF8CharArrayType(CStringType, CArrayType):
     #  C 'char []' type.
     
-    pymemberdef_typecode = "T_STRING_INPLACE"
     is_unicode = 1
     
     to_py_function = "PyUnicode_DecodeUTF8"
@@ -2000,8 +1983,6 @@ class CUTF8CharArrayType(CStringType, CArrayType):
 class CCharArrayType(CStringType, CArrayType):
     #  C 'char []' type.
     
-    pymemberdef_typecode = "T_STRING_INPLACE"
-    
     def __init__(self, size):
         CArrayType.__init__(self, c_char_type, size)
     
@@ -2009,8 +1990,6 @@ class CCharArrayType(CStringType, CArrayType):
 class CCharPtrType(CStringType, CPtrType):
     # C 'char *' type.
     
-    pymemberdef_typecode = "T_STRING"
-    
     def __init__(self):
         CPtrType.__init__(self, c_char_type)
 
@@ -2018,8 +1997,6 @@ class CCharPtrType(CStringType, CPtrType):
 class CUCharPtrType(CStringType, CPtrType):
     # C 'unsigned char *' type.
     
-    pymemberdef_typecode = "T_STRING"
-    
     to_py_function = "__Pyx_PyBytes_FromUString"
     from_py_function = "__Pyx_PyBytes_AsUString"
 
@@ -2085,30 +2062,30 @@ c_void_type =         CVoidType()
 c_void_ptr_type =     CPtrType(c_void_type)
 c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
 
-c_uchar_type =       CIntType(0, 0, "T_UBYTE")
-c_ushort_type =      CIntType(1, 0, "T_USHORT")
-c_uint_type =        CUIntType(2, 0, "T_UINT")
-c_ulong_type =       CULongType(3, 0, "T_ULONG")
-c_ulonglong_type =   CULongLongType(6, 0, "T_ULONGLONG")
-
-c_char_type =        CIntType(0, 1, "T_CHAR")
-c_short_type =       CIntType(1, 1, "T_SHORT")
-c_int_type =         CIntType(2, 1, "T_INT")
-c_long_type =        CLongType(3, 1, "T_LONG")
-c_longlong_type =    CLongLongType(6, 1, "T_LONGLONG")
-c_bint_type =        CBIntType(2, 1, "T_INT")
-
-c_schar_type =       CIntType(0, 2, "T_CHAR")
-c_sshort_type =      CIntType(1, 2, "T_SHORT")
-c_sint_type =        CIntType(2, 2, "T_INT")
-c_slong_type =       CLongType(3, 2, "T_LONG")
-c_slonglong_type =   CLongLongType(6, 2, "T_LONGLONG")
-
-c_py_ssize_t_type =  CPySSizeTType(4, 2, "T_PYSSIZET")
-c_size_t_type =      CSizeTType(5, 0, "T_SIZET")
-
-c_float_type =       CFloatType(7, "T_FLOAT", math_h_modifier='f')
-c_double_type =      CFloatType(8, "T_DOUBLE")
+c_uchar_type =       CIntType(0, 0)
+c_ushort_type =      CIntType(1, 0)
+c_uint_type =        CUIntType(2, 0)
+c_ulong_type =       CULongType(3, 0)
+c_ulonglong_type =   CULongLongType(6, 0)
+
+c_char_type =        CIntType(0, 1)
+c_short_type =       CIntType(1, 1)
+c_int_type =         CIntType(2, 1)
+c_long_type =        CLongType(3, 1)
+c_longlong_type =    CLongLongType(6, 1)
+c_bint_type =        CBIntType(2, 1)
+
+c_schar_type =       CIntType(0, 2)
+c_sshort_type =      CIntType(1, 2)
+c_sint_type =        CIntType(2, 2)
+c_slong_type =       CLongType(3, 2)
+c_slonglong_type =   CLongLongType(6, 2)
+
+c_py_ssize_t_type =  CPySSizeTType(4, 2)
+c_size_t_type =      CSizeTType(5, 0)
+
+c_float_type =       CFloatType(7, math_h_modifier='f')
+c_double_type =      CFloatType(8)
 c_longdouble_type =  CFloatType(9, math_h_modifier='l')
 
 c_double_complex_type = CComplexType(c_double_type)
@@ -2123,7 +2100,7 @@ c_int_ptr_type =      CPtrType(c_int_type)
 c_py_ssize_t_ptr_type =  CPtrType(c_py_ssize_t_type)
 c_size_t_ptr_type =  CPtrType(c_size_t_type)
 
-c_returncode_type =   CIntType(2, 1, "T_INT", is_returncode = 1)
+c_returncode_type =   CIntType(2, 1, is_returncode = 1)
 
 c_anon_enum_type =    CAnonEnumType(-1, 1)
 
@@ -2492,68 +2469,6 @@ type_conversion_predeclarations = """
 static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*);
 static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
 
-#if !defined(T_PYSSIZET)
-#if PY_VERSION_HEX < 0x02050000
-#define T_PYSSIZET T_INT
-#elif !defined(T_LONGLONG)
-#define T_PYSSIZET \\
-        ((sizeof(Py_ssize_t) == sizeof(int))  ? T_INT  : \\
-        ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : -1))
-#else
-#define T_PYSSIZET \\
-        ((sizeof(Py_ssize_t) == sizeof(int))          ? T_INT      : \\
-        ((sizeof(Py_ssize_t) == sizeof(long))         ? T_LONG     : \\
-        ((sizeof(Py_ssize_t) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))
-#endif
-#endif
-
-
-#if !defined(T_ULONGLONG)
-#define __Pyx_T_UNSIGNED_INT(x) \\
-        ((sizeof(x) == sizeof(unsigned char))  ? T_UBYTE : \\
-        ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
-        ((sizeof(x) == sizeof(unsigned int))   ? T_UINT : \\
-        ((sizeof(x) == sizeof(unsigned long))  ? T_ULONG : -1))))
-#else
-#define __Pyx_T_UNSIGNED_INT(x) \\
-        ((sizeof(x) == sizeof(unsigned char))  ? T_UBYTE : \\
-        ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
-        ((sizeof(x) == sizeof(unsigned int))   ? T_UINT : \\
-        ((sizeof(x) == sizeof(unsigned long))  ? T_ULONG : \\
-        ((sizeof(x) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))))
-#endif
-#if !defined(T_LONGLONG)
-#define __Pyx_T_SIGNED_INT(x) \\
-        ((sizeof(x) == sizeof(char))  ? T_BYTE : \\
-        ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
-        ((sizeof(x) == sizeof(int))   ? T_INT : \\
-        ((sizeof(x) == sizeof(long))  ? T_LONG : -1))))
-#else
-#define __Pyx_T_SIGNED_INT(x) \\
-        ((sizeof(x) == sizeof(char))  ? T_BYTE : \\
-        ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
-        ((sizeof(x) == sizeof(int))   ? T_INT : \\
-        ((sizeof(x) == sizeof(long))  ? T_LONG : \\
-        ((sizeof(x) == sizeof(PY_LONG_LONG))   ? T_LONGLONG : -1)))))
-#endif
-
-#define __Pyx_T_FLOATING(x) \\
-        ((sizeof(x) == sizeof(float)) ? T_FLOAT : \\
-        ((sizeof(x) == sizeof(double)) ? T_DOUBLE : -1))
-
-#if !defined(T_SIZET)
-#if !defined(T_ULONGLONG)
-#define T_SIZET \\
-        ((sizeof(size_t) == sizeof(unsigned int))  ? T_UINT  : \\
-        ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : -1))
-#else
-#define T_SIZET \\
-        ((sizeof(size_t) == sizeof(unsigned int))          ? T_UINT      : \\
-        ((sizeof(size_t) == sizeof(unsigned long))         ? T_ULONG     : \\
-        ((sizeof(size_t) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))
-#endif
-#endif
-
 static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
 static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
 static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
index 02f825d1e0cc7e483751424895c0c7f8515703ac..834a20dbc92c71309092c1282f87076ca873e8bc 100644 (file)
@@ -791,7 +791,7 @@ class ModuleScope(Scope):
         self.doc_cname = Naming.moddoc_cname
         self.utility_code_list = []
         self.module_entries = {}
-        self.python_include_files = ["Python.h", "structmember.h"]
+        self.python_include_files = ["Python.h"]
         self.include_files = []
         self.type_names = dict(outer_scope.type_names)
         self.pxd_file_loaded = 0
@@ -1321,10 +1321,8 @@ class CClassScope(ClassScope):
     #  #typeobj_cname        string or None
     #  #objstruct_cname      string
     #  method_table_cname    string
-    #  member_table_cname    string
     #  getset_table_cname    string
     #  has_pyobject_attrs    boolean  Any PyObject attributes?
-    #  public_attr_entries   boolean  public/readonly attrs
     #  property_entries      [Entry]
     #  defined               boolean  Defined in .pxd file
     #  implemented           boolean  Defined in .pyx file
@@ -1336,10 +1334,8 @@ class CClassScope(ClassScope):
         ClassScope.__init__(self, name, outer_scope)
         if visibility != 'extern':
             self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
-            self.member_table_cname = outer_scope.mangle(Naming.memtab_prefix, name)
             self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
         self.has_pyobject_attrs = 0
-        self.public_attr_entries = []
         self.property_entries = []
         self.inherited_var_entries = []
         self.defined = 0
@@ -1380,16 +1376,14 @@ class CClassScope(ClassScope):
                 error(pos,
                     "Attribute of extension type cannot be declared %s" % visibility)
             if visibility in ('public', 'readonly'):
-                if type.pymemberdef_typecode:
-                    self.public_attr_entries.append(entry)
-                    if name == "__weakref__":
-                        error(pos, "Special attribute __weakref__ cannot be exposed to Python")
-                else:
-                    error(pos,
-                        "C attribute of type '%s' cannot be accessed from Python" % type)
-            if visibility == 'public' and type.is_extension_type:
-                error(pos,
-                    "Non-generic Python attribute cannot be exposed for writing from Python")
+                if name == "__weakref__":
+                    error(pos, "Special attribute __weakref__ cannot be exposed to Python")
+                if not type.is_pyobject:
+                    if (not type.create_to_py_utility_code(self) or
+                        (visibility=='public' and not
+                         type.create_from_py_utility_code(self))):
+                        error(pos,
+                              "C attribute of type '%s' cannot be accessed from Python" % type)
             return entry
         else:
             if type is unspecified_type:
index 1399fcf38782fca1cf5bb2ff72beb05bbe0d12a7..232c51d263102949e7bf0275309eb8ff5515d451 100644 (file)
@@ -370,10 +370,7 @@ class MemberTableSlot(SlotDescriptor):
     #  Slot descriptor for the table of Python-accessible attributes.
     
     def slot_code(self, scope):
-        if scope.public_attr_entries:
-            return scope.member_table_cname
-        else:
-            return "0"
+        return "0"
 
 
 class GetSetSlot(SlotDescriptor):
index 58a62a38789d570450732a8beecf6baa21bf9d50..61bf6d1b9a60eb03ce39ef23204c39f3f99fba81 100644 (file)
@@ -8,7 +8,7 @@ cdef class Spam:
     cdef public float f
     cdef public double d
     cdef public char *s
-    cdef public char a[42]
+    cdef readonly char a[42]
     cdef public object o
     cdef readonly int r
     cdef readonly Spam e
diff --git a/tests/errors/cdef_members_T517.pyx b/tests/errors/cdef_members_T517.pyx
new file mode 100644 (file)
index 0000000..ee95a40
--- /dev/null
@@ -0,0 +1,26 @@
+ctypedef void* VoidP
+
+cdef class Spam:
+    cdef          VoidP vp0
+    cdef readonly VoidP vp2
+    cdef public   VoidP vp1
+
+ctypedef struct Foo:
+    int i
+
+cdef class Bar:
+    cdef          Foo foo0
+    cdef readonly Foo foo2
+    cdef public   Foo foo1
+    pass
+
+_ERRORS = u"""
+5:24: C attribute of type 'VoidP' cannot be accessed from Python
+5:24: Cannot convert 'VoidP' to Python object
+6:24: C attribute of type 'VoidP' cannot be accessed from Python
+6:24: Cannot convert 'VoidP' to Python object
+6:24: Cannot convert Python object to 'VoidP'
+14:22: C attribute of type 'Foo' cannot be accessed from Python
+14:22: Cannot convert Python object to 'Foo'
+"""
+
index 6ce4cf3c3cf1e72ce0274a90efd0383e2fef992c..8354dcb5f85bf338e3c77bce4ecb6e306d58c7fa 100644 (file)
@@ -13,7 +13,10 @@ cdef void f():
        x = c.__weakref__
        c.__weakref__ = x
 _ERRORS = u"""
+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
 13:6: Illegal use of special attribute __weakref__
 14:2: Illegal use of special attribute __weakref__
diff --git a/tests/run/cdef_members_T517.pyx b/tests/run/cdef_members_T517.pyx
new file mode 100644 (file)
index 0000000..2299681
--- /dev/null
@@ -0,0 +1,134 @@
+#cython: embedsignature=True
+__doc__ = u"""
+>>> a = A()
+>>> a.h = 7
+>>> a.i = 127
+>>> a.l = 255
+>>> a.q = 255
+>>> a.f = 1.0/2.0
+>>> a.d = 1/2.0 + 1/4.0
+>>> a.g = 1/2.0 + 1/4.0 + 1/8.0
+>>> a.Zf = 1+2j
+>>> a.Zd = 3+4j
+>>> a.Zg = 5+6j
+
+>>> a.h, a.i, a.l
+(7, 127, 255)
+>>> a.ro_h, a.ro_i, a.ro_l
+(7, 127, 255)
+>>> a.f, a.d, a.g
+(0.5, 0.75, 0.875)
+>>> a.ro_f, a.ro_d, a.ro_g
+(0.5, 0.75, 0.875)
+>>> a.Zf, a.Zd, a.Zg
+((1+2j), (3+4j), (5+6j))
+>>> a.ro_Zf, a.ro_Zd, a.ro_Zg
+((1+2j), (3+4j), (5+6j))
+
+>>> b = B()
+>>> b.a0 #doctest: +ELLIPSIS
+Traceback (most recent call last):
+    ...
+AttributeError: ...
+>>> b.b0 #doctest: +ELLIPSIS
+Traceback (most recent call last):
+    ...
+AttributeError: ...
+>>> b.c0 #doctest: +ELLIPSIS
+Traceback (most recent call last):
+    ...
+AttributeError: ...
+
+>>> isinstance(b.a1, type(None))
+True
+>>> isinstance(b.a2, type(None))
+True
+>>> isinstance(b.b1, list)
+True
+>>> isinstance(b.b2, list)
+True
+>>> isinstance(b.c1, A)
+True
+>>> isinstance(b.c2, A)
+True
+
+>>> b.a1 = a
+>>> b.a1 is not b.a2
+True
+
+>>> b.b1 = 1 #doctest: +ELLIPSIS
+Traceback (most recent call last):
+    ...
+TypeError: ...
+>>> b.c1 = 1 #doctest: +ELLIPSIS
+Traceback (most recent call last):
+    ...
+TypeError: ...
+>>> b.a2 = None #doctest: +ELLIPSIS
+Traceback (most recent call last):
+    ...
+AttributeError: ...
+>>> b.b2 = [] #doctest: +ELLIPSIS
+Traceback (most recent call last):
+    ...
+AttributeError: ...
+>>> b.c2 = A() #doctest: +ELLIPSIS
+Traceback (most recent call last):
+    ...
+AttributeError: ...
+"""
+
+cdef class A:
+
+    cdef public short h
+    cdef public int i
+    cdef public long l
+    cdef public long long q
+    cdef public float f
+    cdef public double d
+    cdef public long double g
+    cdef public float complex Zf
+    cdef public double complex Zd
+    cdef public long double complex Zg
+
+    cdef readonly short ro_h
+    cdef readonly int ro_i
+    cdef readonly long ro_l
+    cdef readonly long long ro_q
+    cdef readonly float ro_f
+    cdef readonly double ro_d
+    cdef readonly long double ro_g
+    cdef readonly float complex ro_Zf
+    cdef readonly double complex ro_Zd
+    cdef readonly long double complex ro_Zg
+
+    def __cinit__(self):
+        self.ro_h = 7
+        self.ro_i = 127
+        self.ro_l = 255
+        self.ro_q = 255
+        self.ro_f = 1.0/2.0
+        self.ro_d = 1/2.0 + 1/4.0
+        self.ro_g = 1/2.0 + 1/4.0 + 1/8.0
+        self.ro_Zf = 1+2j
+        self.ro_Zd = 3+4j
+        self.ro_Zg = 5+6j
+
+
+cdef class B:
+
+    cdef object a0
+    cdef public object a1
+    cdef readonly object a2
+
+    cdef list b0
+    cdef public list b1
+    cdef readonly list b2
+
+    cdef A c0
+    cdef public A c1
+    cdef readonly A c2
+
+    def __cinit__(self):
+        self.b0 = self.b1 = self.b2 = []
+        self.c0 = self.c1 = self.c2 = A()
index 3fafdbedadb4692bfd8322b5f0da75294e468cac..0bfcdcadd213067979ab7e95f7f03f9eff8ddc88 100644 (file)
@@ -5,6 +5,15 @@ __doc__ = ur"""
     >>> print (Ext.__doc__)
     Ext(a, b, c=None)
 
+    >>> print (Ext.attr0.__doc__)
+    attr0: 'int'
+    >>> print (Ext.attr1.__doc__)
+    attr1: object
+    >>> print (Ext.attr2.__doc__)
+    attr2: list
+    >>> print (Ext.attr3.__doc__)
+    attr3: embedsignatures.Ext
+
     >>> print (Ext.a.__doc__)
     Ext.a(self)
 
@@ -145,6 +154,11 @@ __doc__ = ur"""
 
 cdef class Ext:
 
+    cdef public int  attr0
+    cdef public      attr1
+    cdef public list attr2
+    cdef public Ext  attr3
+
     def __init__(self, a, b, c=None):
         pass
 
index 82094d4be87dd2a565e1cee4f84e24bb133fbcb9..653fa513a35af322ddf046c05c43464280416d82 100644 (file)
@@ -1,12 +1,12 @@
 __doc__ = """
->>> readonly()
+>>> readonly() #doctest: +ELLIPSIS
 Traceback (most recent call last):
-...
-TypeError: readonly attribute
+    ...
+TypeError: ...
 """
 
 import sys
-if sys.version_info[0] >= 3:
+if sys.version_info[0:2] >= (2,4):
     __doc__ = __doc__.replace(u'TypeError:', u'AttributeError:')
 
 
@@ -51,9 +51,7 @@ def f():
 def longdouble_access():
     """
     >>> longdouble_access()
-    Traceback (most recent call last):
-    ...
-    SystemError: bad memberdescr type
+    42.0
     """
     cdef object c = MyClass()
     print c.float_isreally_longdouble