[Tutor] Appending an extra column in a data file

Albert-Jan Roskam fomcl at yahoo.com
Thu Apr 11 14:25:35 CEST 2013


<snip>

>> Cool. This solves a problem it had with contextlib.nested some time ago.
>> (sorry for kinda hijacking this thread, but..)
>> Would it be safe (both __exit__ calls are guaranteed to be made) to use
>> code like this (if it worked, that is!)?
> 
> Partly because it doesn't work I really can't figure out what you're
> trying to do.

You are right, I should have stated the goal: make contextlib.nested work in a way
that it does not have the shortcoming that caused it become deprecated, namely,
 __exit__ is not guaranteed to be called if the outer "with" raises an exception.
 

>> import sys
>> import contextlib
>> 
>> def someCloseFunc():
>>   print "Yaaay properly closed!"
>> 
>> @contextlib.contextmanager
>> def funcOne(arg):
>>   e = None
>>   try:
>>     yield arg
>>   except:
>>     e = sys.exc_info()[1]
>>     print e
>>   finally:
>>     someCloseFunc()
>>     if e:
> 
> I guess you already know that the lines two lines below will break the
> contextmanager decorator:
> 
>>       yield e
>>     yield None
>> 

 
Nope, I didn't realize that. Thank you.
 
> 
> What effect are you actually wanting from the two lines below (I'm
> assuming that you didn't want the error message shown)? Is it
> significant that funcTwo is funcOne, or is that just to keep the
> demonstration simple?
 
This is merely to keep the demonstration simple. And yes, I didn't want the error message.
 
> 
>> funcTwo = funcOne
>> with contextlib.nested(funcOne("one-ish"), 
> funcTwo("two-ish")) as (one, two):
>>   print one, two
>> 
>> * traceback
>> one-ish two-ish
>> Yaaay properly closed!
>> generator didn't stop
>> Yaaay properly closed!
>> 
 
Two times "Yaaay properly closed!" means that __exit__ is called twice, right?
Anyway, the code below at least runs without errors. Too bad the outcommented
version with tuple unpacking raises an AttributeError.
 
import sys
import contextlib
 
def someCloseFunc():
  print "Yaaay properly closed!"
 
@contextlib.contextmanager
def funcOne(arg):
  try:
    yield arg
  except:
    yield sys.exc_info()[1]
  finally:
    someCloseFunc()
funcTwo = funcOne

 
with contextlib.nested(funcOne("one-ish"), funcTwo("two-ish")) as (one, two):
  print one, two
 
##funcs = (funcOne, funcTwo)
##with contextlib.nested(*funcs) as (one, two):
##  print one("one-ish"), two("two-ish")


More information about the Tutor mailing list