[Python-Dev] PEP 343 rewrite complete

Phillip J. Eby pje at telecommunity.com
Thu Jun 2 18:58:43 CEST 2005

At 09:20 AM 6/2/2005 -0700, Guido van Rossum wrote:
>On 6/2/05, Phillip J. Eby <pje at telecommunity.com> wrote:
> > At 01:08 AM 6/3/2005 +1000, Nick Coghlan wrote:
> > >Also, I'm wondering if it would be useful to have a 'closing' template
> > >that looked like:
> > >
> > >    @with_template
> > >    def closing(obj):
> > >        try:
> > >            yield obj
> > >        finally:
> > >            obj.close()
> >
> > +1 if you make it 'if hasattr(obj,"close"): obj.close()' in the finally
> > clause, so that it will still work if the type of the object changes.
>But then you'd get back the bug where it would silently do nothing
>when you pass it the wrong thing;

That's not a bug, it's a feature.  If the object doesn't have a 'close()' 
method, clearly it doesn't need to be closed.  If it's the "wrong" object 
for what you're using it for in the body of the 'with' block, it'll show up 
there, so this doesn't hide any errors.

The idea is that "with closing(foo):" is just an assertion that you only 
intend to use 'foo' in the body of that block, and not afterwards, so if 
'foo' is something that needs closing, go ahead and close it.

The specific use case I have in mind is situations where a piece of code 
expects an iterable, but there are callers (or callees) that need to do 
cleanup.  On the other hand some callers (or callees) would like to just 
pass in or return a list, or are passing or returning an object from 
somewhere else that may or may not have a close() method.

Thus, a whole bunch of code would suddenly be strewed with assumptions 
about whether things can be closed or not, which seems like pure 
administrivia.  The important functionality is what the object does 
*before* you close it; that's what the programmer should be able to remain 
focused on.

>wasn't that argument used against an
>earlier proposal to skip calling __exit__() when it doesn't exist?

I thought the resolution of that discussion was that you should use an 
explicit wrapper if you want this behavior -- which is what 'closing()' 
is.  Anyway, if you don't like it, don't put it in.  I just thought it 
would be a good example to include for a wrapper whose behavior is more 
optional in nature.

More information about the Python-Dev mailing list