sometype.__new__ and C subclasses
James Porter
porterj at alum.rit.edu
Sun May 2 16:03:45 EDT 2010
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
More information about the Python-list
mailing list