[Guido] > I was looking at the code that invokes __del__, with the intent to > implement a feature from Java: in Java, a finalizer is only called > once per object, even if calling it makes the object live longer. Why? That is, in what way is this an improvement over current behavior? Note that Java is a bit subtle: a finalizer is only called once by magic; explicit calls "don't count". The Java rules add up to quite a confusing mish-mash. Python's rules are *currently* clearer. I deal with possible exceptions in Python constructors the same way I do in C++ and Java: if there's a destructor, don't put anything in __init__ that may raise an uncaught exception. Anything dangerous is moved into a separate .reset() (or .clear() or ...) method. This works well in practice. > To implement this, we need a flag in each instance that means "__del__ > was called". At least <wink>. > I opened the creation code for instances, looking for the right place > to set the flag. I then realized that it might be smart, now that we > have this flag anyway, to set it to "true" during initialization. There > are a number of exits from the initialization where the object is created > but not fully initialized, where the new object is DECREF'ed and NULL is > returned. When such an exit is taken, __del__ is called on an > incompletely initialized object! I agree *that* isn't good. Taken on its own, though, it argues for adding an "instance construction completed" flag that __del__ later checks, as if its body were: if self.__instance_construction_completed: body That is, the problem you've identified here could be addressed directly. > Now I have a choice to make. If the class has an __init__, should I > clear the flag only after __init__ succeeds? This means that if > __init__ raises an exception, __del__ is never called. This is an > incompatibility. It's possible that someone has written code that > relies on __del__ being called even when __init__ fails halfway, and > then their code would break. > > But it is just as likely that calling __del__ on a partially > uninitialized object is a bad mistake, and I am doing all these cases > a favor by not calling __del__ when __init__ failed! > > Any opinions? If nobody speaks up, I'll make the change. I'd be in favor of fixing the actual problem; I don't understand the point to the rest of it, especially as it has the potential to break existing code and I don't see a compensating advantage (surely not compatibility w/ JPython -- JPython doesn't invoke __del__ methods at all by magic, right? or is that changing, and that's what's driving this?). too-much-magic-is-dizzying-ly y'rs - tim
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4