On Monday, 5 March 2018 13:59:35 UTC, 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() > > > You keep insisting that this is an easy thing. > We keep pointing out > > that it isn't. Now you're proving that you haven't even attempted any > > of this. > > Nonsense. But you have got a result I have never seen in many years > and I would like to get to the bottom of it.
Ahah... I see now you are running it from a shell so the exception is staying in scope. We just need to include normal exception handling in the example to fix this:- 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(): try: c = C() c.dostuff() except: print("Boom!") main() -- https://mail.python.org/mailman/listinfo/python-list