How to make a C extension module backwards compatible?

Pete Shinners pete at shinners.org
Wed Sep 18 00:55:56 EDT 2002


Andrew McNamara wrote:
> Is there any community wisdom on how to make a C extension module that
> implements a new-style class (type?) backwards compatible (albeit,
> at the cost of some functionality)?
> 
> Put another way, how *should* I make a class implemented in C behave
> like a new-style class when installed with python 2.2 and above, and
> like an old style class when installed with older pythons?
> 
> Should I just riddle the code with #ifdef's, or is there a more elegant
> way?

i've gone the #ifdef route, and it's a bit of a pain, but manageable. note 
that this was all completely undocumented when i put it together. i mainly 
just copied the builtin types included with python (with my own #ifdef 
stuff going in). here's related excerpts from the code that do what i want. 
basically my object is "RectType", and there is an object named "Rect" to 
construct them. the object is either a function or the actual RectType 
depending on the python version used. unfortunately i believe this is still 
currently undocumented, so good luck.




static PyTypeObject PyRect_Type = {
	...
#if PYTHON_API_VERSION >= 1011
	Py_TPFLAGS_DEFAULT|Py_TPFLAGS_CHECKTYPES|Py_TPFLAGS_BASETYPE,
#else
	0,
#endif
	doc_Rect_MODULE,    /* Documentation string */
#if PYTHON_API_VERSION >= 1011
	...
	rect_new,
#endif
};



#if PYTHON_API_VERSION >= 1011 /*this is the python-2.2 constructor*/
static PyObject* rect_new(PyTypeObject *type, PyObject *args,
		PyObject *kwds)
{
	GAME_Rect *argrect, temp;
	if(!(argrect = GameRect_FromObject(args, &temp)))
		return RAISE(PyExc_TypeError, "badargs");

	return PyRect_New4(argrect->x, argrect->y);
}
#endif



static PyMethodDef rect__builtins__[] =
{
#if PYTHON_API_VERSION < 1011
	{ "Rect", RectInit, 1, doc_Rect },
#endif
	{NULL, NULL}
};



void initrect(void)
{
	PyObject *module, *dict, *apiobj;
	PyType_Init(PyRect_Type);

	module = Py_InitModule3("rect", rect__builtins__, rectangle_doc);
	dict = PyModule_GetDict(module);

	PyDict_SetItemString(dict, "RectType", (PyObject *)&PyRect_Type);
#if PYTHON_API_VERSION >= 1011 /*this is the python-2.2 constructor*/
	PyDict_SetItemString(dict, "Rect", (PyObject *)&PyRect_Type);
#endif
}




More information about the Python-list mailing list