On 6/5/05, "Martin v. Löwis" <[EMAIL PROTECTED]> wrote: > Guido van Rossum wrote: > >> @with_template > >> def closing(obj): > >> try: > >> yield obj > >> finally: > >> obj.close() > >> > > I just realized this has a race condition. The bytecode for the > > expression closing(open("...")) must necessarily contain a bytecode > > that calls open() followed by another bytecode that calls closing(). > > This is not a convincing point. That race condition always existed, > e.g. in the traditional > > f = open(filename) > try: > process(f) > finally: > f.close() > > as you could always get an async exception between open returns and > f is assigned. This isn't much of an issue, since CPython would always > release the file immediately as the stack frame is cleared due to > the exception. > > I think would should explicitly weaken our guarantees for > "asynchronous" exceptions (of which we currently only have > KeyboardInterrupt). The PEP should point out that an async > exception between the beginning of the with statement and > the assignment to the variable may or may not cause __exit__ > to be called (depending on how far you are into __enter__)
That is pretty clear from the translation given in the PEP. What is not so clear is that the cace can be completely avoided *if* the call to __enter__ and the try-finally setup are combined in one opcode, *and* __enter__ is implemented in C, *and* the reversible actions are all done by __enter__. This is also why I don't like giving file objects __enter__ and __exit__ methods. I know all this doesn't matter in most situations, but sometimes it does, and it would be good if there was a solution -- today, there really isn't one except to rely on CPython's reference counting. -- --Guido van Rossum (home page: http://www.python.org/~guido/) _______________________________________________ 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