[Pyrex] Possible Pyrex bug

Edward C. Jones edcjones at erols.com
Tue May 20 03:09:09 CEST 2003


A typo in my code crashed Pyrex 0.7.2 doing "pyrexc wrapped.pyx".

----------------------
tiny.h:

typedef struct _Small {
     int i;
     double x;
     int* u;
} Small;

typedef struct _AAA {
     Small sm;
     Small* smp;
} AAA;

----------------------
tiny.c:

#include "tiny.h"

----------------------
wrapped.pyx:

include "tools.pyx"

cdef extern from "tiny.h":

     ctypedef struct Small:
         int iC "i"
         double xC "x"
         int* uC "u"

     ctypedef struct AAA:
         Small smC "sm"
         Small* smpC "smp"

cdef class TemP__Small:
     cdef Small* t

     def __new__(self, object iPY, xPY, uPY):
         self.t = <Small*> PyMem_Malloc(sizeof(Small))
         if self.t == NULL:
             raise MemoryError
         self.t.iC = iPY
         self.t.xC = xPY
         if uPY is None:
             self.t.uC = NULL
         else:
             self.t.uC = <int *> extract_ptr(uPY)

     def __dealloc__(self):
         PyMem_Free(self.t)

     def __getattr__(self, name):
         if name == 'i':
             return self.t.iC
         if name == 'x':
             return self.t.xC
         if name == 'u':
             return wrap_ptr(self.t.uC, 'Small.u')
         return object.__getattribute__(self, name)

     def __setattr__(self, name, valPY):
         if name == 'i':
             self.t.iC = valPY
         if name == 'x':
             self.t.xC = valPY
         if name == 'u':
             self.t.uC = <int *> extract_ptr(valPY)
         else:
             object.__setattr__(self, name, valPY)

     def ToPointer(self):
         return  PyCObject_FromVoidPtrAndDesc(self.t, 'type Small*', NULL)

cdef TemP__Small_toC(object PY, Small* C):
     C.iC = PY.i
     C.xC = PY.x
     C.uC = <int *> extract_ptr(PY.u)

cdef TemP__Small_FromC(Small* smC):
     return TemP__Small(smC.iC, smC.xC, wrap_ptr(smC.uC, 'Small.u'))

cdef class TemP__AAA:
     cdef AAA* t

     def __new__(self, smPY, smpPY):
         self.t = <AAA*> PyMem_Malloc(sizeof(AAA))
         if self.t == NULL:
             raise MemoryError
         cdef int LocaLi
         cdef int LocaLj
         TemP__Small_toC(smPY, &self.t.smC)
         self.t.smpC = <Small*> extract_ptr(smpPY)

     def __dealloc__(self):
         PyMem_Free(self.t)

     def __getattr__(self, name):
         if name == 'sm':
             return TemP__Small_FromC(&self.t.smC)
         if name == 'smp':
             return self.t.smpC.Topointer()
         return object.__getattribute__(self, name)

     def __setattr__(self, name, valPY):
         cdef int LocaLi
         cdef int LocaLj
         if name == 'sm':
             TemP__Small_toC(valPY, &self.t.smC)
         if name == 'smp':
             return wrap_ptr(self.t.smpC, 'AAA.smp')
         else:
             object.__setattr__(self, name, valPY)

     def ToPointer(self):
         return  PyCObject_FromVoidPtrAndDesc(self.t, 'type AAA*', NULL)

cdef TemP__AAA_toC(object PY, AAA* C):
     TemP__Small_toC(PY.sm, &C.smC)

cdef TemP__AAA_FromC(AAA* C):
     smPY = TemP__Small_FromC(&C.smC)
     return TemP__AAA(smPY)

----------------------
Error messages:

/home/edcjones/cvlib/antlr/cgram/mystuff/example4/wrapped.pyx:80:30:
        Object of type 'Small' has no attribute 'Topointer'
Traceback (most recent call last):
   File "/usr/bin/pyrexc", line 7, in ?
     Pyrex.Compiler.Main.main(command_line = 1, c_only = 1)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Main.py",
     line 163, in main
     result = compile(source, options, c_only = c_only)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Main.py",
        line 120, in compile
     tree.process(name, result)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 82, in process
     self.generate_c_code(env, result)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 134, in generate_c_code
     self.body.generate_function_definitions(env, code)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 842, in generate_function_definitions
     stat.generate_function_definitions(env, code)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 1861, in generate_function_definitions
     self.body.generate_function_definitions(
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 842, in generate_function_definitions
     stat.generate_function_definitions(env, code)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 1190, in generate_function_definitions
     self.body.analyse_expressions(lenv)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 837, in analyse_expressions
     stat.analyse_expressions(env)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 2321, in analyse_expressions
     if_clause.analyse_expressions(env)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 2351, in analyse_expressions
     self.body.analyse_expressions(env)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 837, in analyse_expressions
     stat.analyse_expressions(env)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/Nodes.py",
        line 2181, in analyse_expressions
     self.value.allocate_temps(env)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/ExprNodes.py",
        line 285, in allocate_temps
     self.allocate_subexpr_temps(env)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/ExprNodes.py",
        line 299, in allocate_subexpr_temps
     node.allocate_temps(env)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/ExprNodes.py",
        line 286, in allocate_temps
     self.allocate_temp(env, result)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/ExprNodes.py",
        line 326, in allocate_temp
     self.result = self.result_code()
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/ExprNodes.py",
        line 1166, in result_code
     return self.c_call_code(as_extension_type = 0)
   File "/usr/lib/python2.2/site-packages/Pyrex/Compiler/ExprNodes.py",
        line 1174, in c_call_code
     formal_args = self.function.type.args
AttributeError: ErrorType instance has no attribute 'args'

----------------------
tools.pyx:

ctypedef int size_t

cdef extern from "stdlib.h":
     void* malloc(size_t size)
     void free(void* ptr)

cdef extern from "stdio.h":
     int printf(char* format, ...)

cdef extern from "Python.h":
     void* PyMem_Malloc(size_t n)
     void* PyMem_Realloc(void *p, size_t n)
     void PyMem_Free(void *p)

     int PyCObject_Check(object p)
     object PyCObject_FromVoidPtr(void* cobj, void (*destr)(void *))
     object PyCObject_FromVoidPtrAndDesc(void* cobj, void* desc,
             void (*destr)(void *, void *))
     void* PyCObject_AsVoidPtr(object self)
     void* PyCObject_GetDesc(object self)

cdef wrap_ptr(void* p, char* name):
     return PyCObject_FromVoidPtrAndDesc(p, name, NULL)

cdef void* extract_ptr(object P):
     return PyCObject_AsVoidPtr(P)

def CObject_ToPrettyString(object P):
     cdef int i
     cdef void* p
     cdef char* s
     if not PyCObject_Check(P):
         raise TypeError, 'not a CObject'
     p = PyCObject_AsVoidPtr(P)
     s = <char*> PyCObject_GetDesc(P)
     if p == NULL:
         val = "NULL"
     else:
         i = <int> p
         val = '0x%x' % i
     return '<CObject wrapping %s: %s>' % (s, val)





More information about the Pyrex mailing list