我正在尝试使我的WSGI服务器实现与Python 2和Python 3兼容。我有这个代码:
def start_response(status, response_headers, exc_info = None):
if exc_info:
try:
if headers_sent:
# Re-raise original exception if headers sent.
raise exc_info[0], exc_info[1], exc_info[2]
finally:
# Avoid dangling circular ref.
exc_info = None
elif headers_set:
raise AssertionError("Headers already set!")
headers_set[:] = [status, response_headers]
return write
......相关部分是:
# Re-raise original exception if headers sent.
raise exc_info[0], exc_info[1], exc_info[2]
Python 3不再支持该语法,因此必须将其翻译为:
raise exc_info[0].with_traceback(exc_info[1], exc_info[2])
问题:Python 2语法在Python 3中生成解析错误。如何编写可由Python 2和Python 3解析的代码?我尝试了以下方法,但这不起作用:
if sys.version_info[0] >= 3:
raise exc_info[0].with_traceback(exc_info[1], exc_info[2])
else:
eval("raise exc_info[0], exc_info[1], exc_info[2]; 1", None, { 'exc_info': exc_info })
答案 0 :(得分:46)
您可以使用six
吗?它的存在是为了解决这个问题。
import six, sys
six.reraise(*sys.exc_info())
答案 1 :(得分:0)
你可以做一些有创意的事。
检查代码的开头 - 你的构造函数或其他什么,检查你正在使用的python版本,因为你的普通版本检查工具不能正常工作,请尝试这样做:
try:
eval('a python 3 expression') # something that only works in python3+
python_version = 3
except:
python_version = 2
然后,您的其余代码可以轻松地引用它以了解要使用的内容。
至于解析错误,你可以在函数中使用exec,如下所示:
def what_to_run():
if python_version = 3:
return 'raise exc_info[0].with_traceback(exc_info[1], exc_info[2])'
else:
return 'raise exc_info[0], exc_info[1], exc_info[2]'
在你的功能中你会写这个:
def start_response(status, response_headers, exc_info = None):
if exc_info:
try:
if headers_sent:
# Re-raise original exception if headers sent.
exec(what_to_run())
finally:
# Avoid dangling circular ref.
exc_info = None
elif headers_set:
raise AssertionError("Headers already set!")
headers_set[:] = [status, response_headers]
return write
有点乱,没有经过测试,但它应该工作,至少你理解这个想法。