问题
I tried to mess around with context managers and got a bit surprised when running my code with Python 2.6. Indeed, the exc_value
parameter seems to be a string instead of an exception.
A bit of code to hi-light this issue :
import sys
class contextmanager(object):
def __enter__(self):
pass
def __exit__(self, type_, value, traceback):
assert (type_ is None) == (value is None)
if value is not None:
print(type(value))
if __name__ == '__main__':
print(sys.version_info)
with contextmanager():
__name_ # should trigger name exception
With Python 2.7 :
<type 'exceptions.NameError'> # GOOD
Traceback (most recent call last):
File "test_conman.py", line 17, in <module>
__name_
NameError: name '__name_' is not defined
With Python 3.2 :
sys.version_info(major=3, minor=2, micro=3, releaselevel='final', serial=0)
<class 'NameError'> # GOOD
Traceback (most recent call last):
File "test_conman.py", line 17, in <module>
__name_
NameError: name '__name_' is not defined
With Python 2.6 :
(2, 6, 7, 'final', 0)
<type 'str'> # BAD
Traceback (most recent call last):
File "test_conman.py", line 17, in <module>
__name_
NameError: name '__name_' is not defined
My understanding is that exc_value
should always be an exception.
Is there anything I did wrong ?
Is there anything I misunderstood ?
Is this a known issue ?
References
What’s New in Python 2.6 : PEP 343: The with statement
Python 2 docs : object.__exit__(self, exc_type, exc_value, traceback)
回答1:
This was a bug in Python 2.6, see issue 7853. It was fixed for Python 2.7a3 but never backported to the 2.6 branch.
In other words, you did nothing wrong, Python did.
Unfortunately, there's no real work-around other than to handle the fact that you don't have an exception instance in 2.6 but only the string value.
来源:https://stackoverflow.com/questions/30012062/exc-value-parameter-from-exit-context-manager-is-string-instead-of-excep