For review: PEP 343: Anonymous Block Redux and Generator Enhancements

Andrew Dalke dalke at dalkescientific.com
Sat Jun 4 15:23:52 EDT 2005


Nicolas Fleury wrote:
> I think it is simple and that the implementation is as much 
> straight-forward.  Think about it, it just means that:

Okay, I think I understand now.

Consider the following

server = open_server_connection()
with abc(server)
with server.lock()
do_something(server)

server.close()

it would be translated to

server = open_server_connection()
with abc(server):
  with server.lock()
    do_something(server)
    server.close()

when I meant for the first code example to be implemented
like this

server = open_server_connection()
with abc(server):
  with server.lock()
    do_something(server)

server.close()


(It should probably use the with-block to handle the server open
and close, but that's due to my lack of imagination in coming up
with a decent example.)

Because of the implicit indentation it isn't easy to see that
the "server.close()" is in an inner block and not at the outer
one that it appears to be in.  To understand the true scoping
a reader would need to scan the code for 'with' lines, rather
than just looking at the layout.


> Good point.  As a C++ programmer, I use RAII a lot.

And I've used it a few times in Python, before I found
out it wasn't a guaranteed behavior by the language.

> So I come to another conclusion: the indentation syntax will most of the 
> time result in a waste of space.  Typically a programmer would want its 
> with-block to end at the end of the current block.

A test for how often this is needed would be to look in existing
code for the number of try/finally blocks.  I have seen and
written some gnarly deeply stacked blocks but not often - once
a year?

That's not to say it's a good indicator.  A lot of existing code
looks like this

def get_first_line(filename):
  f = open(filename)
  return f.readline()

depending on the gc to clean up the code.  A more ... not
correct, but at least finicky ... implementation could be

def get_first_line(filename):
  f = open(filename)
  try:
    return f.readline()
  finally:
    f.close()

Almost no one does that.  With the PEP perhaps the idiomatic
code would be

def get_first_line(filename):
  with open(filename) as f:
    return f.readline()


(Add __enter__/__exit__ semantics to the file object?  Make
a new 'opening' function?  Don't know.)

What I mean by all of this is that the new PEP may encourage
more people to use indented blocks, in a way that can't be
inferred by simply looking at existing code.  In that case
your proposal, or the one written

  with abc, defg(mutex) as D, server.lock() as L:
    ..

may be needed.

				Andrew
				dalke at dalkescientific.com




More information about the Python-list mailing list