Lifetime of a local reference

Rhodri James rhodri at kynesim.co.uk
Wed Feb 27 09:18:37 EST 2019


On 27/02/2019 06:56, Marko Rauhamaa wrote:
> Alan Bawden <alan at csail.mit.edu>:
>> But I appreciate that that isn't the true question that you wanted to ask!
>> You are wondering if a Python implementation is _permitted_ to treat the
>> code you wrote _as if_ you had written:
>>
>>     def fun():
>>         f = open("lock")
>>         flock.flock(f, fcntl.LOCK_EX)
>>         del f
>>         do_stuff()
>>         sys.exit(0)
>>
>> which deletes the variable f from the local environment at a point where it
>> will never be used again.  (Which could cause the lock to be released
>> before do_stuff is even called.)
>>
>> This is an interesting question, and one that any garbage collected
>> language should probably address somehow.

Interesting indeed.  My gut instinct was "Hell, no!", but as Marko 
points out C optimisers do exactly that, and I don't find it 
particularly surprising in practice.  I don't think that there is 
anything in the docs that says a compliant implementation couldn't 
delete variables early.  The nearest you get is repeated reminders that 
you can't make assumptions about when destructors will be run.

> Then there's the question of a sufficient way to prevent premature
> garbage collection:
> 
>       def fun():
>           f = open("lock")
>           flock.flock(f, fcntl.LOCK_EX)
>           do_stuff()
>           f.close()
>           sys.exit(0)
> 
>       def fun():
>           f = open("lock")
>           flock.flock(f, fcntl.LOCK_EX)
>           do_stuff()
>           f.close
>           sys.exit(0)
> 
>       def fun():
>           f = open("lock")
>           flock.flock(f, fcntl.LOCK_EX)
>           do_stuff()
>           f
>           sys.exit(0)
> 
>       def fun():
>           f = open("lock")
>           flock.flock(f, fcntl.LOCK_EX)
>           do_stuff()
>           sys.exit(0)

I would go with:

     def fun():
         with open("lock") as f:
             flock.flock(f, fcntl.LOCK_EX)
             do_stuff()
         sys.exit(0)

The description of the with statement does explicitly say that the 
context manager's __exit__() method won't be called until the suite has 
been executed, so the reference to the open file must exist for at least 
that long.

-- 
Rhodri James *-* Kynesim Ltd



More information about the Python-list mailing list