Guido van Rossum wrote:
I wouldn't be surprised if this is a genuine bug; the complex type
doesn't get a lot of love from core developers.

Could you come up with a proposed fix, and a unit test showing that it
works (and that the old version doesn't)? (Maybe a good unit test
would require writing a custome C extension; in that case just show
some sample code.)


Attached is a sample module that exposes the problem. The problem goes away by replacing

op = PyType_GenericAlloc(type, 0);

with

op = type->tp_alloc(type, 0);

in the function

complex_subtype_from_c_complex

in the file complexobject.c  (about line #191).



The problem with a unit test is that it might not fail. On my Linux system, it doesn't complain about the problem unless I first use strict pointer checking with

export MALLOC_CHECK_=2

Then the code

import bugtest
a = bugtest.newcomplex(3.0)
del a

Aborts

Valgrind also shows the error when running the simple code. It seems pretty clear to me that the subtype code should be calling the sub-types tp_alloc code instead of the generic one.


Best regards,

-Travis










#include "Python.h"


typedef struct {
	PyObject_HEAD
	double real;
	double imag;
} PyNewComplexObject;


static PyTypeObject PyComplex_SubType = { 
        PyObject_HEAD_INIT(NULL)
        0,				       /*ob_size*/
        "newcomplex",		               /*tp_name*/
        sizeof(PyNewComplexObject),            /*tp_basicsize*/
};

static PyObject *
_complex_alloc(PyTypeObject *type, int nitems)
{
	PyObject *obj;

	obj = (PyObject *)malloc(_PyObject_SIZE(type));
	memset(obj, 0, _PyObject_SIZE(type));
	PyObject_INIT(obj, type);
	return obj;
}

PyMODINIT_FUNC initbugtest(void) {
	PyObject *m, *d;
	m = Py_InitModule("bugtest", NULL);
	d = PyModule_GetDict(m);

	PyComplex_SubType.tp_free = free;
	PyComplex_SubType.tp_alloc = _complex_alloc;
	PyComplex_SubType.tp_base = &PyComplex_Type;	
	PyComplex_SubType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES;

        PyType_Ready(&PyComplex_SubType);
	Py_INCREF(&PyComplex_SubType);
	PyDict_SetItemString(d, "newcomplex", 
			     (PyObject *)&PyComplex_SubType);
	return;
}
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to