jos*_*faz 6 python pycharm python-asyncio starlette fastapi
使用 FastAPI :0.101.1
我运行这个test_read_aynsc并且它通过了。
# app.py
from fastapi import FastAPI
app = FastAPI()
app.get("/")
def read_root():
return {"Hello": "World"}
# conftest.py
import pytest
from typing import Generator
from fastapi.testclient import TestClient
from server import app
@pytest.fixture(scope="session")
def client() -> Generator:
with TestClient(app) as c:
yield c
# test_root.py
def test_read_aynsc(client):
response = client.get("/item")
Run Code Online (Sandbox Code Playgroud)
但是,在 DEBUG 模式(在 pycharm 中)执行此测试会导致错误。这是回溯:
test setup failed
cls = <class 'anyio._backends._asyncio.AsyncIOBackend'>
func = <function start_blocking_portal.<locals>.run_portal at 0x1555c51b0>
args = (), kwargs = {}, options = {}
@classmethod
def run(
cls,
func: Callable[[Unpack[PosArgsT]], Awaitable[T_Retval]],
args: tuple[Unpack[PosArgsT]],
kwargs: dict[str, Any],
options: dict[str, Any],
) -> T_Retval:
@wraps(func)
async def wrapper() -> T_Retval:
task = cast(asyncio.Task, current_task())
task.set_name(get_callable_name(func))
_task_states[task] = TaskState(None, None)
try:
return await func(*args)
finally:
del _task_states[task]
debug = options.get("debug", False)
loop_factory = options.get("loop_factory", None)
if loop_factory is None and options.get("use_uvloop", False):
import uvloop
loop_factory = uvloop.new_event_loop
with Runner(debug=debug, loop_factory=loop_factory) as runner:
> return runner.run(wrapper())
../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:1991:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:193: in run
return self._loop.run_until_complete(task)
../../../Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13763.11/PyCharm.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:202: in run_until_complete
self._run_once()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <_UnixSelectorEventLoop running=False closed=True debug=False>
def _run_once(self):
"""
Simplified re-implementation of asyncio's _run_once that
runs handles as they become ready.
"""
ready = self._ready
scheduled = self._scheduled
while scheduled and scheduled[0]._cancelled:
heappop(scheduled)
timeout = (
0 if ready or self._stopping
else min(max(
scheduled[0]._when - self.time(), 0), 86400) if scheduled
else None)
event_list = self._selector.select(timeout)
self._process_events(event_list)
end_time = self.time() + self._clock_resolution
while scheduled and scheduled[0]._when < end_time:
handle = heappop(scheduled)
ready.append(handle)
> if self._compute_internal_coro:
E AttributeError: '_UnixSelectorEventLoop' object has no attribute '_compute_internal_coro'
../../../Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13763.11/PyCharm.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:236: AttributeError
During handling of the above exception, another exception occurred:
@pytest.fixture(scope="session")
def client() -> Generator:
> with TestClient(app) as c:
tests/fixtures/common/http_client_app.py:10:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/starlette/testclient.py:730: in __enter__
self.portal = portal = stack.enter_context(
../../../.pyenv/versions/3.10.12/lib/python3.10/contextlib.py:492: in enter_context
result = _cm_type.__enter__(cm)
../../../.pyenv/versions/3.10.12/lib/python3.10/contextlib.py:135: in __enter__
return next(self.gen)
../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/from_thread.py:454: in start_blocking_portal
run_future.result()
../../../.pyenv/versions/3.10.12/lib/python3.10/concurrent/futures/_base.py:451: in result
return self.__get_result()
../../../.pyenv/versions/3.10.12/lib/python3.10/concurrent/futures/_base.py:403: in __get_result
raise self._exception
../../../.pyenv/versions/3.10.12/lib/python3.10/concurrent/futures/thread.py:58: in run
result = self.fn(*self.args, **self.kwargs)
../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_core/_eventloop.py:73: in run
return async_backend.run(func, args, {}, backend_options)
../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:1990: in run
with Runner(debug=debug, loop_factory=loop_factory) as runner:
../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:133: in __exit__
self.close()
../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:141: in close
_cancel_all_tasks(loop)
../../../Library/Caches/pypoetry/virtualenvs/kms-backend-F9vGicV3-py3.10/lib/python3.10/site-packages/anyio/_backends/_asyncio.py:243: in _cancel_all_tasks
loop.run_until_complete(tasks.gather(*to_cancel, return_exceptions=True))
../../../Library/Application Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/233.13763.11/PyCharm.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:202: in run_until_complete
self._run_once()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <_UnixSelectorEventLoop running=False closed=True debug=False>
def _run_once(self):
"""
Simplified re-implementation of asyncio's _run_once that
runs handles as they become ready.
"""
ready = self._ready
scheduled = self._scheduled
while scheduled and scheduled[0]._cancelled:
heappop(scheduled)
timeout = (
0 if ready or self._stopping
else min(max(
scheduled[0]._when - self.time(), 0), 86400) if scheduled
else None)
event_list = self._selector.select(timeout)
self._process_events(event_list)
end_time = self.time() + self._clock_resolution
while scheduled and scheduled[0]._when < end_time:
handle = heappop(scheduled)
ready.append(handle)
> if self._compute_internal_coro:
E AttributeError: '_UnixSelectorEventLoop' object has no attribute '_compute_internal_coro'
Run Code Online (Sandbox Code Playgroud)
我不确定导致错误的原因,因为我可以看到_UnixSelectorEventLoop,所以我需要准确地说我的操作系统是 MacOS M1。
为了支持异步调试,PyCharm 使用自定义包装函数修补了一堆异步 API。值得注意的是,它修补asyncio.new_event_loop()了~/Applications/PyCharm Professional Edition.app/Contents/plugins/python/helpers-pro/pydevd_asyncio/pydevd_nest_asyncio.py:169.
Starlette 使用 anyio,默认使用 asyncio 后端。asyncio.events.new_event_loop()Anyio 最终将尝试从未修补的事件循环中获取事件循环。对修补的 asyncio API 的后续调用将抛出错误,因为它们假定修补的事件循环。
在正确修复之前,您可以通过强制 anyio 使用修补程序来解决此new_event_loop问题
TestClient(app, backend_options={'loop_factory': asyncio.new_event_loop})
Run Code Online (Sandbox Code Playgroud)
JetBrains 开发人员表示修复正在进行中,请参阅https://youtrack.jetbrains.com/issue/PY-70245。在那之前,他们建议python.debug.asyncio.repl在帮助|中禁用。查找操作 | 登记处
| 归档时间: |
|
| 查看次数: |
706 次 |
| 最近记录: |