Le Mon, 05 Aug 2013 22:30:29 +0200, Stefan Behnel <stefan...@behnel.de> a écrit : > > Hmm, it's a bit unfortunate that tp_finalize() maps so directly to > __del__(), but I think this can be fixed. In any case, each > tp_finalize() function must only ever be called once, so if a subtype > inherited the tp_finalize() slot from its parent, it mustn't be > called again.
This is already dealt with by a custom bit in the GC header (cf. _PyGC_IS_FINALIZED, IIRC). > >> 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() > > What makes you think it's a good idea to call the parent type's > finaliser before doing the local finalisation, and not the other way > round? What if the subtype needs access to parts of the super type > for its cleanup? I'm not saying it's a good idea. I'm just saying that to reason about the C API, it is a good idea to reason about equivalent pure Python code. Since exceptions aren't implicitly silenced in pure Python code, they probably shouldn't in C code. > In other words, which makes more sense (at the C level): > > try: > super().tp_finalize() > finally: > local_cleanup() > > or > > try: > local_cleanup() > finally: > super().tp_finalize() > > Should that order be part of the protocol or not? (well, not for > __del__() I guess, but maybe for tp_finalize()?) No, it is left to the user's preference. Since tp_finalize() is meant to be equivalent to __del__(), I think it's better if the protocols aren't subtly different (to the extent to which it is possible, of course). > Coming back to the __del__() vs. tp_finalize() story, if tp_finalize() > first recursed into the super types, the top-most one of which then > calls __del__() and returns, we'd get an execution order that runs > Python-level __del__() methods before C-level tp_finalize() > functions, but loose the subtype-before-supertype execution order for > tp_finalize() functions. Well... to get that, you'd have to subclass a pure Python class with a C extension type. Does that ever happen? > That might call for a three-step cleanup: > > 1) run all Python __del__() methods recursively > 2) run all tp_finalize() functions recursively > 3) run tp_dealloc() recursively I don't see any reason why tp_finalize should be distinct from __del__, while e.g. __init__ and tp_init map to the exact same thing. (you might wonder why tp_finalize isn't called tp_del, but that's because there is already something named tp_del - something which is obsoleted by PEP 442, incidently ;-)). 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