New Type in Extension Module Not Accessing PyNumberMethods???
doug
doug_bartholomew99 at yahoo.com
Wed Aug 8 22:42:25 EDT 2001
im trying to write a python extension type which i am basically
modeling on xxmodule.c that comes with the source. however, for the
life of me, i cannot get the numeric operations to work (just simple
addition and subtraction here) and i cannot see what im doing wrong.
Isnt the following what one has to do to get numeric operations???
***BEGIN CODE SNIPPET***
static PyObject*
MyObject_add(MyObject *Self, PyObject *Arg)
{
long c_long;
MyObject* rv;
if ( !PyInt_Check(Arg) )
{
PyErr_SetString(PyExc_TypeError, "Should add a number to
MyObject");
return NULL;
}
c_long = PyInt_AS_LONG(Arg);
rv = newMyObject(Self->my_num + c_long);
if ( rv == NULL )
return NULL;
return (PyObject *)rv;
}
static PyObject*
MyObject_sub(MyObject *Self, PyObject *Arg)
{
MyObject* rv = NULL;
if ( PyInt_Check(Arg) )
{
long c_long = PyInt_AS_LONG(Arg);
rv = newMyObject(Self->my_num - c_long);
} else if ( MyObject_Check(Arg) )
{
rv = newMyObject(Self->my_num - ((MyObject*)Arg)->my_num);
} else
{
PyErr_SetString(PyExc_TypeError, "Only a number or another
MyObject can be subtracted from a MyObject");
return NULL;
}
if ( rv == NULL )
return NULL;
return (PyObject *)rv;
}
static PyNumberMethods MyObject_as_number = {
(binaryfunc)MyObject_add,
(binaryfunc)MyObject_sub,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(ternaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
(inquiry)0,
(unaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
0,
(unaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
};
static PyTypeObject MyObject_Type = {
PyObject_HEAD_INIT(NULL)
0,
"MyObject",
sizeof(MyObject),
0,
(destructor) MyObject_dealloc,
(printfunc) MyObject_print,
(getattrfunc) MyObject_getattr,
(setattrfunc) MyObject_setattr,
(cmpfunc) MyObject_compare,
(reprfunc) 0,
&MyObject_as_number,
0,
0,
(hashfunc) 0,
(ternaryfunc) 0,
(reprfunc) 0,
};
***END CODE SNIPPET***
And in my python session i get the following error:
C:\test>python
ActivePython 2.1.1, build 212 (ActiveState)
Python 2.1.1 (#20, Jul 26 2001, 11:38:51) [MSC 32 bit (Intel)] on
win32
Type "copyright", "credits" or "license" for more information.
>>> from MyObject_Module import *
>>> foo = MyObject(9)
>>> print foo
9
>>> foo + 8
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unsupported operand types for +
>>>
im posting the full module (MyObject_Module.c) below. Any help is
appreciated greatly.
Thanks very much,
Doug
doug_bartholomew99 at yahoo.com
***********MyObject_Module.c***********
#include "Python.h"
static PyObject *ErrorObject;
typedef struct {
PyObject_HEAD
long my_num;
PyObject *x_attr;
} MyObject;
staticforward PyTypeObject MyObject_Type;
#define MyObject_Check(v) ((v)->ob_type == &MyObject_Type)
static MyObject *
newMyObject(const long arg_int)
{
MyObject *Self;
Self = PyObject_New(MyObject, &MyObject_Type);
if (Self == NULL)
return NULL;
Self->my_num = arg_int;
Self->x_attr = NULL;
return Self;
}
static void
MyObject_dealloc(MyObject *Self)
{
Py_XDECREF(Self->x_attr);
PyObject_Del(Self);
}
static int
MyObject_print(MyObject *Self, FILE *fp, int flags)
/* flags -- not used but required by interface */
{
flags;
fprintf(fp, "%d", Self->my_num);
return 0;
}
static PyObject *
MyObject_demo(MyObject *Self, PyObject *Args)
{
if (!PyArg_ParseTuple(Args, ":demo"))
return NULL;
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef MyObject_methods[] = {
{"demo", (PyCFunction)MyObject_demo, METH_VARARGS},
{NULL, NULL}
};
static PyObject *
MyObject_getattr(MyObject *self, char *name)
{
if (self->x_attr != NULL) {
PyObject *v = PyDict_GetItemString(self->x_attr, name);
if (v != NULL) {
Py_INCREF(v);
return v;
}
}
return Py_FindMethod(MyObject_methods, (PyObject *)self, name);
}
static int
MyObject_setattr(MyObject *self, char *name, PyObject *v)
{
if (self->x_attr == NULL) {
self->x_attr = PyDict_New();
if (self->x_attr == NULL)
return -1;
}
if (v == NULL) {
int rv = PyDict_DelItemString(self->x_attr, name);
if (rv < 0)
PyErr_SetString(PyExc_AttributeError,
"delete non-existing attribute");
return rv;
}
else
return PyDict_SetItemString(self->x_attr, name, v);
}
static int
MyObject_compare(MyObject *Right, MyObject *Left)
{
return ( Right->my_num < Left->my_num ) ? -1 :
(( Right->my_num > Left->my_num ) ? +1 : 0);
}
static PyObject*
MyObject_add(MyObject *Self, PyObject *Arg)
{
long c_long;
MyObject* rv;
if ( !PyInt_Check(Arg) )
{
PyErr_SetString(PyExc_TypeError, "Should add a number to
MyObject");
return NULL;
}
c_long = PyInt_AS_LONG(Arg);
rv = newMyObject(Self->my_num + c_long);
if ( rv == NULL )
return NULL;
return (PyObject *)rv;
}
static PyObject*
MyObject_sub(MyObject *Self, PyObject *Arg)
{
MyObject* rv = NULL;
if ( PyInt_Check(Arg) )
{
long c_long = PyInt_AS_LONG(Arg);
rv = newMyObject(Self->my_num - c_long);
} else if ( MyObject_Check(Arg) )
{
rv = newMyObject(Self->my_num - ((MyObject*)Arg)->my_num);
} else
{
PyErr_SetString(PyExc_TypeError, "Only a number or another
MyObject can be subtracted from a MyObject");
return NULL;
}
if ( rv == NULL )
return NULL;
return (PyObject *)rv;
}
static PyNumberMethods MyObject_as_number = {
(binaryfunc)MyObject_add,
(binaryfunc)MyObject_sub,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(ternaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
(inquiry)0,
(unaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
(binaryfunc)0,
0,
(unaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
(unaryfunc)0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
};
static PyTypeObject MyObject_Type = {
PyObject_HEAD_INIT(NULL)
0,
"MyObject",
sizeof(MyObject),
0,
(destructor) MyObject_dealloc,
(printfunc) MyObject_print,
(getattrfunc) MyObject_getattr,
(setattrfunc) MyObject_setattr,
(cmpfunc) MyObject_compare,
(reprfunc) 0,
&MyObject_as_number,
0,
0,
(hashfunc) 0,
(ternaryfunc) 0,
(reprfunc) 0,
};
static PyObject *
MyObject_Module_new(PyObject *Self, PyObject *Args)
{
MyObject *rv;
long arg_long;
if ( PyArg_ParseTuple(Args, "l:MyObject", &arg_long) )
rv = newMyObject(arg_long);
else if ( PyArg_ParseTuple(Args, ":MyObject") )
{
PyErr_Clear();
rv = newMyObject(0);
}
else
return NULL;
if ( rv == NULL )
return NULL;
return (PyObject *)rv;
}
static PyMethodDef MyObject_Module_methods[] = {
{"MyObject", MyObject_Module_new, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
#ifdef __cplusplus
extern "C"
#endif
__declspec(dllexport)
void initMyObject_Module(void)
{
PyObject *m, *d;
MyObject_Type.ob_type = &PyType_Type;
m = Py_InitModule("MyObject_Module", MyObject_Module_methods);
d = PyModule_GetDict(m);
ErrorObject = PyErr_NewException("MyObject_Module.error", NULL,
NULL);
PyDict_SetItemString(d, "error", ErrorObject);
}
More information about the Python-list
mailing list