[Python-ideas] revisit pep 377: good use case?

Craig Yoshioka craigyk at me.com
Thu Mar 1 04:28:45 CET 2012

I agree about 'try' being another example of a, at least not immediately, flow-controlled block, I think I mentioned as much in a different response. But you're not going to win me over by saying that the #1 goal of 'with' is too best match the flow-control semantics of try|except|finally.  The #1 goal, I would have hoped, was to abstract away the pattern of using try:except:finally to manage a block of code that does IO stuff.  And the current 'with' doesn't even perfectly match the semantics of try|except|finally because if it did, then 'with'  uses of try|except|finally that I can think of that don't have a with equivalent.

try:                            # boilerplate
while True:			# boilerplate
 if alreadyCached():   	# boilerplate
   break			# boilerplate
 try:				# boilerplate
   acquireLock()		# boilerplate
   doSomeStuff()               # <- code that does 
   doMoreStuff()               # <- stuff goes here
   alreadyCached(True)		# boilerplate
 except AlreadyLocked:		# boilerplate
   sleep()			# boilerplate
finally:                        # boilerplate              
cleanUpMyLockIfItExists()      # boilerplate  

There isn't a 'with' equivalent to the above that hides all the unnecessary context state and boilerplate from the enclosed block, therefore the 'client' code must know and remember to check the appropriate flags everytime and if they don't the context's functionality may be broken.  

if not alreadyCached():        # <- check before we execute context block
with aquireCache() as cache:
 ...                          # <- to run the 
 ...                          #    code they put in here

with aquireCache() as cache:     # <- slightly better than above
 if not cache:                  # <- but may still 'break' the context if they forget this
   ...                          # <- to run the 
   ...                          #    code they put in here

On Feb 29, 2012, at 6:15 PM, Nick Coghlan wrote:

> There are two other cases where a suite is guaranteed to at least
> start executing, and one of them is the only case that matters here:
> "try" blocks. The flow control behaviour of "with:" is consistent with
> the behaviour of a "try:" block, and that is not an accident.
> Conditional execution of a try block requires a separate if statement
> or throwing an exception that is caught and suppressed by one of the
> exception handlers. Similarly, conditional execution of a with block
> requires a separate if statement or throwing an exception that is
> caught and suppressed by one of the context managers. Hence, arguments
> of language consistency aren't going to get you anywhere here.
> Guido's verdict on PEP 377 was that the payoff (avoiding a separate if
> statement or a method call that deliberately throws an appropriate
> exception in certain niche use cases) wasn't worth the additional
> complexity in the with statement definition. I now agree with him.
> Regards,
> Nick.
> -- 
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list