[Python-Dev] PEP 442 clarification for type hierarchies
solipsis at pitrou.net
Mon Aug 5 20:56:29 CEST 2013
On Sun, 04 Aug 2013 17:59:57 +0200
Stefan Behnel <stefan_ml at behnel.de> wrote:
> > I continued my implementation and found that calling up the base type
> > hierarchy is essentially the same code as calling up the hierarchy for
> > tp_dealloc(), so that was easy to adapt to in Cython and is also more
> > efficient than a generic loop (because it can usually benefit from
> > inlining). So I'm personally ok with leaving the super type calling code to
> > the user side, even though manual implementers may not be entirely happy.
> > I think it should get explicitly documented how subtypes should deal with a
> > tp_finalize() in (one of the) super types. It's not entirely trivial
> > because the tp_finalize slot is not guaranteed to be filled for a super
> > type IIUC, as opposed to tp_dealloc. I assume the recursive invariant that
> > PyType_Ready() copies it would still hold, though.
Not only it could be NULL (if no upper type has a finalizer), but it
could also not exist at all (if Py_TPFLAGS_HAVE_FINALIZE isn't in
tp_flags). If an API is needed to make this easier then why not. But
I'm not sure anyone else than Cython really has such concerns. Usually,
the class hierarchy for C extension types is known at compile-time and
therefore you know exactly which upper finalizers to call.
> Hmm, it seems to me by now that the only safe way of handling this is to
> let each tp_dealloc() level in the hierarchy call tp_finalize() through
> PyObject_CallFinalizerFromDealloc(), instead of calling up the stack in
> tp_finalize(). Otherwise, it's a bit fragile for arbitrary tp_dealloc()
> functions in base types and subtypes.
I'm not following you. Why is it "a bit fragile" to call the base
tp_finalize from a derived tp_finalize? It should actually be totally
safe, since tp_finalize is a regular function called in a safe
environment (unlike tp_dealloc and tp_del).
More information about the Python-Dev