On Mon, 05 Aug 2013 21:03:33 +0200 Stefan Behnel <stefan...@behnel.de> wrote: > I think the main problem I have with the PEP is this part: > > """ > The PEP doesn't change the semantics of: > * C extension types with a custom tp_dealloc function. > """ > > Meaning, it was designed to explicitly ignore this use case.
It doesn't ignore it. It lets you fix your C extension type to use tp_finalize for resource finalization. It also provides the PyObject_CallFinalizerFromDealloc() API function to make it easier to call tp_finalize from your tp_dealloc. What the above sentence means is that, if you don't change your legacy tp_dealloc, your type will not take advantage of the new facilities. (you can take a look at the _io module; it was modified to take advantage of tp_finalize) > * make finalisation run recursively (or iteratively) through all > inheritance levels, in a well defined execution environment (e.g. after > saving away the exception state) __init__ and other methods only let the user recurse explicitly. __del__ would be a weird exception if it recursed implicitly. Also, it would break backwards compatibility for existing uses of __del__. > I think it's a mistake that the current implementation calls the > finalisation from tp_dealloc(). Instead, both the finalisation and the > deallocation should be called externally and independently from the cleanup > mechanism behind Py_DECREF(). (There is no problem in CS that can't be > solved by adding another level of indirection...) Why not, but I'm not sure that would solve anything on your side. If it does, would you like to cook a patch? I wonder if there's some unexpected issue with doing what you're proposing. > An obvious open question is how to deal with exceptions during > finalisation. Any break in the execution chain would mean that a part of > the type wouldn't be finalised. Let's come back to pure Python: class A: def __del__(self): 1/0 class B(A): def __del__(self): super().__del__() self.cleanup_resources() If you want cleanup_resources() to be called always (despite A.__del__() raising), you have to use a try/finally block. There's no magic here. Letting the user call the upper finalizer explicitly lets them choose their preferred form of exception handling. Regards Antoine. _______________________________________________ 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