ValueError:set_wakeup_fd 仅适用于带有 Django 3.0.2 或 Flask 2.0.0 的 Python 3.8 上的 Windows 主线程

Posted

技术标签:

【中文标题】ValueError:set_wakeup_fd 仅适用于带有 Django 3.0.2 或 Flask 2.0.0 的 Python 3.8 上的 Windows 主线程【英文标题】:ValueError: set_wakeup_fd only works in main thread on Windows on Python 3.8 with Django 3.0.2 or Flask 2.0.0 【发布时间】:2020-02-23 04:24:24 【问题描述】:

当我在 Windows 10 专业版上使用 Apache2.4.41 + Python 3.8.1 + Django 3.0.2 + mysql 8.0.19 运行我的 Django Web 应用程序时,它会在 / 处引发值错误。 set_wakeup_fd 只适用于主线程。

此问题是 Python 3.8 中回归的结果,并于 11 月在 Python 的后续版本中得到修复。更多详情 - https://bugs.python.org/issue38563。

错误的stacktrace如下-

Environment:

Request Method: GET
Request URL: http://127.0.0.1/

Django Version: 3.0.2
Python Version: 3.8.1
Installed Applications:
['Analysis.apps.AnalysisConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize']


Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "c:\python38\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "c:\python38\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "c:\python38\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "F:\IndianMarketAnalysis\ISMA\Analysis\views.py", line 8, in home
    date_list = dict(d.date_list())
  File "F:\IndianMarketAnalysis\ISMA\Analysis\models.py", line 7, in date_list
    with connection.cursor() as cursor:
  File "c:\python38\lib\site-packages\django\utils\asyncio.py", line 19, in inner
    event_loop = asyncio.get_event_loop()
  File "c:\python38\lib\asyncio\events.py", line 636, in get_event_loop
    self.set_event_loop(self.new_event_loop())
  File "c:\python38\lib\asyncio\events.py", line 656, in new_event_loop
    return self._loop_factory()
  File "c:\python38\lib\asyncio\windows_events.py", line 310, in __init__
    super().__init__(proactor)
  File "c:\python38\lib\asyncio\proactor_events.py", line 632, in __init__
    signal.set_wakeup_fd(self._csock.fileno())

Exception Type: ValueError at /
Exception Value: set_wakeup_fd only works in main thread

此外,该应用程序在本地开发环境中运行良好,使用 - python manage.py runserver。

请提出下一步的建议。


同样的问题发生在 Flask 2.0.0 (pip install --pre flask):

@app.get('/')
async def say_hello():
    return 'message': 'Hello!'
> flask run
Traceback (most recent call last):
  File "c:\users\greyli\...\venv\lib\site-packages\flask\app.py", line 1953, in wsgi_app
    response = self.full_dispatch_request()
  File "c:\users\greyli\...\venv\lib\site-packages\flask\app.py", line 1454, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "c:\users\greyli\...\venv\lib\site-packages\flask\app.py", line 1452, in full_dispatch_request
    rv = self.dispatch_request()
  File "c:\users\greyli\...\app.py", line 318, in dispatch_request
    return self.view_functions[rule.endpoint](*req.view_args.values())
  File "c:\users\greyli\...\venv\lib\site-packages\flask\helpers.py", line 781, in outer
    return async_to_sync(inner)(*args, **kwargs)
  File "c:\users\...\venv\lib\site-packages\asgiref\sync.py", line 203, in __call__
    loop_future.result()
  File "C:\Users\greyli\.pyenv\pyenv-win\versions\3.8.0\lib\concurrent\futures\_base.py", line 432, in result
    return self.__get_result()
  File "C:\Users\greyli\.pyenv\pyenv-win\versions\3.8.0\lib\concurrent\futures\_base.py", line 388, in __get_result
    raise self._exception
  File "C:\Users\greyli\.pyenv\pyenv-win\versions\3.8.0\lib\concurrent\futures\thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "c:\users\greyli\...\venv\lib\site-packages\asgiref\sync.py", line 256, in _run_event_loop
    loop.close()
  File "C:\Users\greyli\.pyenv\pyenv-win\versions\3.8.0\lib\asyncio\proactor_events.py", line 679, in 
close
    signal.set_wakeup_fd(-1)
ValueError: set_wakeup_fd only works in main thread

【问题讨论】:

【参考方案1】:

我有完全相同的错误。我打开了issue。

如果您想继续使用当前的 Python 版本,我找到了临时解决方案,即在 asgiref\__init__.py 中添加以下行(正如 issue 中所建议的那样):

if sys.platform == "win32" and sys.version_info >= (3, 8, 0):
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

【讨论】:

更多更新 - 也可以使用以下组合重现此错误 - Python3.8.2rc2 + Django 3.0.3 + Apache 2.4.41【参考方案2】:

不仅是 Django,你也会在使用 Flask 时遇到这个错误,因为 Flask 2.0.0 使用 asgiref 来支持 async

这个 bug 在 Python 3.9 中已经修复,所以有两种解决方案:

升级到 Python 3.9 将如下临时修复(基于Dennis B's answer)添加到您的入口脚本,例如,Flask 的app.py 或Django 的manager.py
# top of the file
import sys, asyncio

if sys.platform == "win32" and (3, 8, 0) <= sys.version_info < (3, 9, 0):
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

【讨论】:

我在 Python 3.9.1 中遇到了同样的错误。【参考方案3】:

升级到 python 3.8.2 ,在我的 Windows 服务器上运行良好。

发行说明 https://docs.python.org/release/3.8.2/whatsnew/changelog.html#python-3-8-2-final

问题 bpo-34679:已修复 asynci.ProactorEventLoop.close() 现在只在主线程中调用 signal.set_wakeup_fd()。

【讨论】:

我希望我也能这么说。我在 3.8.2 的 Windows Server 上遇到了这个问题,但我的本地开发是在 3.8.1 中。本地开发工作正常;服务器没有。 我遇到了与pweave 类似的问题。在 Windows 上升级到 Python 3.8.10 解决了这个问题。【参考方案4】:

我不得不降级到 Python 3.7,然后它开始完美运行。

【讨论】:

我一直在使用 Django/Apache 遇到主题中的错误消息,我尝试了不同版本的 Python 3.8 无济于事。然而,回滚到 Python 3.7 修复了它。

以上是关于ValueError:set_wakeup_fd 仅适用于带有 Django 3.0.2 或 Flask 2.0.0 的 Python 3.8 上的 Windows 主线程的主要内容,如果未能解决你的问题,请参考以下文章

ValueError:未知标签类型

ValueError: '对象对于所需数组来说太深'

ValueError:不支持多类格式

如何解决 raise ValueError("columns must have matching element counts") ValueError: columns mus

“ValueError:标签 ['timestamp'] 不包含在轴中”错误

ValueError:不支持连续[重复]