RFC: Proposal: Deterministic Object Destruction

bartc bc at freeuk.com
Mon Mar 5 10:17:01 EST 2018


On 05/03/2018 13:58, Ooomzay wrote:
> On Monday, 5 March 2018 11:24:37 UTC, Chris Angelico  wrote:
>> On Mon, Mar 5, 2018 at 10:09 PM, Ooomzay wrote:
>>> Here is an example of a composite resource using RAII:-
>>>
>>> class RAIIFileAccess():
>>>      def __init__(self, fname):
>>>          print("%s Opened" % fname)
>>>      def __del__(self):
>>>          print("%s Closed" % fname)
>>>
>>> class A():
>>>      def __init__(self):
>>>          self.res = RAIIFileAccess("a")
>>>
>>> class B():
>>>      def __init__(self):
>>>          self.res = RAIIFileAccess("b")
>>>
>>> class C():
>>>      def __init__(self):
>>>          self.a = A()
>>>          self.b = B()
>>>
>>> def main():
>>>      c = C()
>>>
>>> Under this PEP this is all that is needed to guarantee that the files "a"
>>> and "b" are closed on exit from main or after any exception has been handled.
>>
>> Okay. And all your PEP needs is for reference count semantics, right?
>> Okay. I'm going to run this in CPython, with reference semantics. You
>> guarantee that those files will be closed after an exception is
>> handled? Right.
>>
>>>>> def main():
>> ...     c = C()
>> ...     c.do_stuff()
>> ...
>>>>> main()
>> a Opened
>> b Opened
>> Traceback (most recent call last):
>>    File "<stdin>", line 1, in <module>
>>    File "<stdin>", line 3, in main
>> AttributeError: 'C' object has no attribute 'do_stuff'
>>>>>
>>   
>> Uhh.... I'm not seeing any messages about the files getting closed.
> 
> Then that is indeed a challenge. From CPython back in 2.6 days up to Python36-32 what I see is:-
> 
> a Opened
> b Opened
> Traceback (most recent call last):
> ...
> AttributeError: 'C' object has no attribute 'dostuff'
> a Closed
> b Closed
> 
>> Maybe exceptions aren't as easy to handle as you think?
> 
> Well there is a general issue with exceptions owing to the ease
> with which one can create cycles that may catch out newbs. But
> that is not the case here.
> 
>> Or maybe you
>> just haven't tried any of this (which is obvious from the bug in your
>> code
> 
> Or maybe I just made a typo when simplifying my test case and failed to retest?
> 
> Here is my fixed case, if someone else could try it in CPython and report back that would be interesting:-
> 
> class RAIIFileAccess():
>      def __init__(self, fname):
>          print("%s Opened" % fname)
>          self.fname = fname
> 
>      def __del__(self):
>          print("%s Closed" % self.fname)
> 
> class A():
>      def __init__(self):
>          self.res = RAIIFileAccess("a")
> 
> class B():
>      def __init__(self):
>          self.res = RAIIFileAccess("b")
> 
> class C():
>      def __init__(self):
>          self.a = A()
>          self.b = B()
> 
> def main():
>      c = C()
>      c.dostuff()
> 
> main()

I get A and B closed messages when running on CPython 2.7 and 3.6, with 
the code run from a .py file. (I never use interactive mode.)

But not when running on a PyPy version of 2.7 (however that is not CPython).

-- 
bartc



More information about the Python-list mailing list