tp_free and tp_dealloc?

Robert Nikander nikander at mindspring.com
Wed Dec 19 12:33:21 EST 2001


Greetings Pythoners...

I am writing my first extension types and am having a couple problems. One
is that I and am confused about the tp_free vs the tp_dealloc slots in
PyTypeObject.  Examples in the Python documentation say that you should
actually free the object when dealloc is called, using:

PyObject_Del( obj );

But PEP 253 on subtyping builtins says that the tp_dealloc should unref or
delete its members and that *tp_free* is used to delete the object. So:
'tp_free' is opposite 'tp_alloc' and 'tp_new' is opposite 'tp_dealloc'
(BTW: I am on Python 2.2c1)

My little test type ('Dog') and a script that creates a Dog shows that
tp_free is never getting called.

Also a Dog works fine but a Python subclass segfaults when the object is
dealloc'd.

Can someone enlighten me?

Thanks,
Rob

Here is some of my code:

typedef struct {
  PyObject_HEAD
  int weight;
  char * name;
} Dog;

static int
dog_init(PyObject * self, PyObject * args, PyObject * kwargs) {
  int w;
  char * name = NULL;
  Dog * new_dog = (Dog*)self;

  if(!PyArg_ParseTuple(args, "si:Dog __init__", &name, &w)) {
    return -1;
  }
  
  new_dog->weight = w;
  new_dog->name = name;
  return 0;
}


static void dog_dealloc(Dog * dog)
{
  printf("dog_dealloc is running\n");
  printf("   name is %s\n", dog->name); /* This next line causes seg
  fault, not sure how to get rid of name. */ /* PyMem_Free(dog->name);  */
  printf("   deleted the name\n");
  PyObject_Del(dog);
  printf("   deleted object.\n");
}

....
  DogType.tp_free = dog_free;
  DogType.tp_dealloc = (destructor)dog_dealloc;
  DogType.tp_init = dog_init;
  DogType.tp_new = PyType_GenericNew;
  DogType.tp_alloc = PyType_GenericAlloc;
  DogType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;

  PyType_Ready( &DogType );

---- Python test program ---
# Create a Dog and try subclassing Dog 

import robs

d = robs.Dog("Cloe", 72)
print d, d.name

class FatDog(robs.Dog):
    def __init__(self, n, w):
        robs.Dog.__init__(self, n, w+10)

## If I uncomment the next 3 commented lines, # I get a seg fault in the
middle of dealloc for the fat dog

#fd = FatDog("Lester", 85)
#print fd.name, fd.weight

del d
#del fd
print 'done'



More information about the Python-list mailing list