如何在Python 3.2程序中优雅地包含Python 3.3 from None exception语法?

dpy*_*yro 4 python exception forward-compatibility python-3.2 python-3.3

我正在尝试重新引发异常,以便为用户提供有关实际错误的更好信息.Python 3.3包括PEP 409.它添加了raise NewException from None语法来抑制原始异常的上下文.

但是,我的目标是Python 3.2.Python脚本将解析,但在运行时如果遇到from None它将产生的语法 TypeError: exception causes must derive from BaseException.例如:

try:
    regex_c = re.compile('^{}$'.format(regex)) 
except re.error as e:
    e_msg = 'Regular expression error in "{}"'.format(regex)
    e_reraise = Exception(e_msg)
    # Makes use of the new Python 3.3 exception syntax [from None]
    # to suppress the context of the original exception
    # Causes an additional TypeError exception in Python 3.2
    raise e_reraise from None
Run Code Online (Sandbox Code Playgroud)

封装raise e_reraise from Nonetryjust中会产生更大的异常堆栈跟踪.版本检查也不起作用,因为我python3.3在Xubuntu 12.10上提取了/usr/lib/python3/dist-packages/*为python3.2模块设置的模块.(你得到一个方便的Error in sys.excepthook:,创造了一个巨大的追溯.)

有没有办法在Python 3.3中运行时使用PEP 409功能,而在Python 3.2中默默地忽略它?

Mar*_*ers 5

您可以设置exc.__cause__ = None在Python 3.3中禁止上下文打印:

except re.error as e:
    e_msg = 'Regular expression error in "{}"'.format(regex)
    e_reraise = Exception(e_msg)
    e_reraise.__cause__ = None  # 'raise e_reraise from None'
    raise e_reraise    
Run Code Online (Sandbox Code Playgroud)

在Python 3.3中,当你使用raise exc from cause真正发生的事情是:

exc.__cause__ = cause
raise exc
Run Code Online (Sandbox Code Playgroud)

exc.__cause__依次设置隐式设置exc.__suppress_context__ = True.请参阅PEP 415,其中详细说明了如何raise exc from None处理.

exc.__cause__ = None在Python 3.2中设置时,没有任何变化:

$ python3.2
Python 3.2.3 (default, Apr 13 2012, 13:31:19) 
[GCC 4.2.1 Compatible Apple Clang 3.0 (tags/Apple/clang-211.12)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
...     raise ValueError()
... except:
...     exc = TypeError()
...     exc.__cause__ = None
...     raise exc
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
TypeError
Run Code Online (Sandbox Code Playgroud)

但是在Python 3.3中,上下文被抑制了:

$ python3.3
Python 3.3.0 (default, Sep 29 2012, 08:16:08) 
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
...     raise ValueError()
... except:
...     exc = TypeError()
...     exc.__cause__ = None
...     raise exc
... 
Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
TypeError
Run Code Online (Sandbox Code Playgroud)

就像你曾经使用过raise exc from None:

>>> try:
...     raise ValueError()
... except:
...     raise TypeError() from None
... 
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
TypeError
Run Code Online (Sandbox Code Playgroud)