Why no open(f, "w").write()?

Andreas Kostyrka andreas at kostyrka.priv.at
Sat Jun 1 08:26:12 CEST 2002


Am Donnerstag, 30. Mai 2002 02:47 schrieb Delaney, Timothy:
> I can come up with a perfectly good example where
Well, replacing the semantics of a builtin operation is not a perfectly good
example IMHO. ;)
>
> 	open(FILE, 'w').write(CONTENTS)
>
> will fail to close the file in CPython.
>
> There are no guarantees that the reference to the object returned is the
> *only* reference to that object. Assume the following (perverse)
> implementation of open:
>
> __files = []
>
> def open (path, mode):
>     f = __open(path, mode)
>     __files.append(f)
>     return f
>
> or
>
> class file:
>
>     __files = []
>
>     def __init__(self, path, mode):
>         __files.append(self)
>
> Whilst I know this is not the implementation, there is nothing that
> prevents it from being like this. So you get back an object that has one
> more reference count than expected. It never gets collected.
Well, then the implementation is broken. If you allow the implementation
to collect additional references at random places, you can prove quite
easily that nothing is safe :)

Your proof is a bit like the classical error from "full induction" (is this 
the english name?) proofs in math class. If you reason with faulty premises 
you can prove anything. 
>
> You should never rely on automatic freeing of *any* resources unless it is
> guaranteed. Always explicitly free resources when you have finished with
> them.
Well, then you should del all your names too.
Oops wait, how can we be sure that del works? What if del also increments the 
refcount instead of decrementing? What if some operation before the del
incremented the refcount?

Basically what you have proven is, that if you have a faulty open() 
implementation, the open(f,t).write(d) idiom doesn't work.

Guess what. I can prove that open(f,t).write(d) wouldn't work if write is 
implemented buggy. The exact proof is left as an exercise to the reader. :)

In respect to CPython, refcounting behaviour, or more general retaining 
references in any gc regime, is a quite important part of the interface.

Andreas
-- 
Andreas Kostyrka				+43 676 4091256
andreas at kostyrka.priv.at			andreas at mtg.co.at






More information about the Python-list mailing list