为什么在我的 Python 3 mod_wsgi 应用程序中使用 Paste ErrorMiddleware 会引发异常?

Why does Paste ErrorMiddleware throw an exception when I use it with my Python 3 mod_wsgi application?

我正在尝试使用 Python Paste 2.0.3 中包含的 ErrorMiddleware,以便在我的 Python 3.4 mod_wsgi 应用程序服务器抛出异常时在浏览器中显示回溯。我遇到的问题是 ErrorMiddleware 在尝试处理我的服务器异常时抛出此异常:

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.4/site-packages/paste/exceptions/errormiddleware.py", line 154, in __call__
    response = self.exception_handler(exc_info, environ)
  File "/usr/lib/python3.4/site-packages/paste/exceptions/errormiddleware.py", line 188, in exception_handler
    simple_html_error=simple_html_error)
  File "/usr/lib/python3.4/site-packages/paste/exceptions/errormiddleware.py", line 391, in handle_exception
    error_stream.write(line)
TypeError: must be str, not bytes

所以我仍然只是在浏览器中获取 500 Internal Server Error

问题似乎是 ErrorMiddleware 正在尝试将字节写入 wsgi 错误流:

    if six.PY3:
        line = line.encode('utf8')
    error_stream.write(line) # line 391 error_stream comes from environ['wsgi.errors']

但是如果我打印出来 environ['wsgi.errors'] 它似乎是一个文本流:

'wsgi.errors': <_io.TextIOWrapper name='<wsgi.errors>' encoding='utf-8'>

这意味着 ErrorMiddleware 无法向其写入字节。

我将我的应用程序包装在 ErrorMiddleware 中,如下所示:

application = ErrorMiddleware(application, debug=True)

是不是我做错了什么导致了这个?我可以配置 mod_wsgi 以便错误流是字节流而不是文本流吗?

wsgi.errors 理论上应该与写入 sys.stdout 相同。

$ python3.6
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.stdout.write('hello\n')
hello
6
>>> sys.stdout.write(b'hello\n')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: write() argument must be str, not bytes

所以他们试图在 Python 上写入字节看起来是错误的 3.