Message8910

Author stefan.richthofer
Recipients ajdavis, fwierzbicki, pjenvey, stefan.richthofer, zyasoft
Date 2014-08-10.15:28:31
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1407684513.22.0.683988217654.issue1057@psf.upfronthosting.co.za>
In-reply-to
Content
I unfortunately discovered that the technique to automatically detect resurrection (used in resurrectOnDemand) only works, if there occurs a gc-run before the resurrected object becomes unreachable again.
I overlooked this behaviour first (sorry for that!), because in my tests I always called System.gc multiple times to assure it ran at least once.
Since in usual cases one does not control when gc runs, it would actually be undefined whether repeated finalization would work or not, wich I consider worse than having it never work. One would have to detect a gc-run and re-run every time, which is unreasonably expensive in best case and maybe even impossible. So I would stick to the suggestion to directly perform Python 3.4 behavior here.

 
Next topic.

I forked Jython to implement and test this. Besides other tests, I explored how CPython behaves if an instance (not the class!) acquires a finalizer.
 
A = SomeClass()
A.__del__ = blah
 
There are issues with binding the method to the instance, but basically a __del__ method is not necessarily required to be bound to its instance.
However it appears that instance-acquired finalizers are supported for old style classes in CPython, but not for new style.

We could emulate this behavior in Jython for old style classes. The technique with FinalizeGuardian/FinalizeTrigger just requires that the Java object holds the single reference to a FinalizeTrigger, which in turn contains the actual finalizer. To support instace-acquired __del__, the PyInstanceClass would need to be enhanched by such a memeber, which would simply be null for all instances without __del__.
If we chose this variant, there would be no more need for the PyFinalizableInstance class any more and it could be removed or deprecated.

But maybe we would not want to increase the memory demand for old style python objects by one reference per object in general.

To avoid this, one could add the FinalizeTrigger to the instance's dictionary instead. This would only increase memory usage for objects that need it, but would somehow mess up their dictionary with an object that is irrelevant from Python view. Additionally one would have to implement FinalizeTrigger as a PyObject, which also increases memory demand. And there would be checks necessary to move the trigger to the new dict if the dict is replaced.

So please let's decide how to proceed. Shall instance-acquired finalizers be supported or not, considering the given costs?
If so, should it be done via a member or via the dictionary?
Or maybe someone has a better idea how to hide a reference to a FinalizeTrigger in the PyInstance I did not consider yet?
History
Date User Action Args
2014-08-10 15:28:33stefan.richthofersetmessageid: <1407684513.22.0.683988217654.issue1057@psf.upfronthosting.co.za>
2014-08-10 15:28:33stefan.richthofersetrecipients: + stefan.richthofer, fwierzbicki, pjenvey, zyasoft, ajdavis
2014-08-10 15:28:33stefan.richthoferlinkissue1057 messages
2014-08-10 15:28:31stefan.richthofercreate