On 5/2/2010 1:43 PM, Robert Kern wrote:
Perhaps things would be clearer if you could post the C code that you've
written that fails. So far, you've only alluded at what you are doing
using Python-syntax examples.

I'm not sure how much this will help, but here you go. The actual C code probably doesn't matter except for where I set tp_flags, tp_new, and register the type, but I included it for completeness. The full C source is available here if you need it, but be warned that other strangeness abounds in the code: <http://trac.mcs.anl.gov/projects/ITAPS/browser/python/trunk/iMesh_array.inl?rev=3831>.

Obviously, this is kind of a bizarre case, so I'm not entirely sure what the best route is here.

Thanks,
Jim

static PyObject*
iMeshArrObj_new(PyTypeObject *cls,PyObject *args,PyObject *kw)
{
    static char *kwlist[] = {"object","instance",0};

    PyObject *obj;
    iMesh_Object *instance = NULL;
    PyObject *arr = NULL;
    iMeshArr_Object *self;

    if(!PyArg_ParseTupleAndKeywords(args,kw,"O|O!",kwlist,&obj,
                                    &iMesh_Type,&instance))
        return NULL;

    arr = PyArray_FROM_O(obj);
    if(arr == NULL)
        return NULL;

    self = (iMeshArr_Object*)PyObject_CallMethod(arr,"view","O",cls);
    Py_DECREF(arr);
    if(self == NULL)
        return NULL;

    /* some boring stuff to set |instance| */

    return self;
}

static void
iMeshArrObj_dealloc(iMeshArr_Object *self)
{
    Py_XDECREF(self->instance);
    self->array.ob_type->tp_free((PyObject*)self);
}

static PyObject*
iMeshArrObj_finalize(iMeshArr_Object *self,PyObject *args)
{
    iMeshArr_Object *context;
    if(PyArg_ParseTuple(args,"O!",&iMeshArr_Type,&context))
    {
        self->instance = context->instance;
        Py_XINCREF(self->instance);
    }
    PyErr_Clear();
    Py_RETURN_NONE;
}

static PyMethodDef iMeshArrObj_methods[] = {
    { "__array_finalize__", (PyCFunction)iMeshArrObj_finalize,
      METH_VARARGS, ""
    },
    {0}
};

static PyMemberDef iMeshArrObj_members[] = {
    {"instance", T_OBJECT_EX, offsetof(iMeshArr_Object, instance),
     READONLY, "base iMesh instance"},
    {0}
};

static PyTypeObject iMeshArr_Type = {
    PyObject_HEAD_INIT(NULL)
    /* ... */
    (destructor)iMeshArrObj_dealloc,          /* tp_dealloc */
    /* ... */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    "iMesh array objects",                    /* tp_doc */
    /* ... */
    iMeshArrObj_methods,                      /* tp_methods */
    iMeshArrObj_members,                      /* tp_members */
    /* ... */
    iMeshArrObj_new,                          /* tp_new */
};

PyMODINITFUNC initiMesh(void)
{
    PyObject *m;
    m = Py_InitModule("iMesh",module_methods);
    import_array();

    iMeshArr_Type.tp_base = &PyArray_Type;  
    if(PyType_Ready(&iMeshArr_Type) < 0)
        return;
    Py_INCREF(&iMeshArr_Type);
    PyModule_AddObject(m,"Array",(PyObject *)&iMeshArr_Type);
}

/***** End C code *****/

And then in Python:

    A = iMesh.Array(numpy.array([1,2,3,4,5]), instance=mesh)
    numpy.zeros_like(A) # fails here

Inside NumPy, zeros_like looks like this (there's a bit more than this, but it's irrelevant to this problem):

    def zeros_like(a):
        if isinstance(a, ndarray):
            res = ndarray.__new__(type(a), a.shape, a.dtype,
                                  order=a.flags.fnc)
            res.fill(0)
            return res

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to