MagicStack / MagicStack/uvloop

Python 3.12

未关闭
#643 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

主要语言
Cython
星标
11.9k
派生
616
PR 合并指标
30 天内没有已合并 PR

描述

* **uvloop version**:
* **Python version**: 3.12
* **Platform**: ubuntu
* **Can you reproduce the bug with `PYTHONASYNCIODEBUG` in env?**: Not tested
* **Does uvloop behave differently from vanilla asyncio? How?**:

Tried to reproduce this: Replacing the LoopPolicy with Uvloop leads to the following error.
The error only occurs in Ubuntu + Python 3.12 combination. (3.9, 3.10, 3.11 work)

https://github.com/michaelfeil/infinity/actions/runs/11773635831/job/32790872907

```
______________________ ERROR at setup of test_classifier _______________________
fut = , timeout = 5
async def wait_for(fut, timeout):
"""Wait for the single Future or coroutine to complete, with timeout.

Coroutine will be wrapped in Task.

Returns result of the Future or coroutine. When a timeout occurs,
it cancels the task and raises TimeoutError. To avoid the task
cancellation, wrap it in shield().

If the wait is cancelled, the task is also cancelled.

If the task suppresses the cancellation and returns a value instead,
that value is returned.

This function is a coroutine.
"""
# The special case for timeout <= 0 is for the following case:
#
# async def test_waitfor():
# func_started = False
#
# async def func():
# nonlocal func_started
# func_started = True
#
# try:
# await asyncio.wait_for(func(), 0)
# except asyncio.TimeoutError:
# assert not func_started
# else:
# assert False
#
# asyncio.run(test_waitfor())


if timeout is not None and timeout <= 0:
fut = ensure_future(fut)

if fut.done():
return fut.result()

await _cancel_and_wait(fut)
try:
return fut.result()
except exceptions.CancelledError as exc:
raise TimeoutError from exc

async with timeouts.timeout(timeout):
> return await fut
/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/asyncio/tasks.py:520:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.12/site-packages/asgi_lifespan/_concurrency/asyncio.py:17: in wait
await self._event.wait()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
async def wait(self):
"""Block until the internal flag is true.

If the internal flag is true on entry, return True
immediately. Otherwise, block until another coroutine calls
set() to set the flag to true, then return True.
"""
if self._value:
return True

fut = self._get_loop().create_future()
self._waiters.append(fut)
try:
> await fut
E asyncio.exceptions.CancelledError
/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/asyncio/locks.py:212: CancelledError
The above exception was the direct cause of the following exception:
self =
seconds = 5
coroutine = >
async def run_and_fail_after(
self,
seconds: typing.Optional[float],
coroutine: typing.Callable[[], typing.Awaitable[None]],
) -> None:
try:
> await asyncio.wait_for(coroutine(), timeout=seconds)
.venv/lib/python3.12/site-packages/asgi_lifespan/_concurrency/asyncio.py:44:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/asyncio/tasks.py:519: in wait_for
async with timeouts.timeout(timeout):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
exc_type =
exc_val = CancelledError(), exc_tb =
async def __aexit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> Optional[bool]:
assert self._state in (_State.ENTERED, _State.EXPIRING)

if self._timeout_handler is not None:
self._timeout_handler.cancel()
self._timeout_handler = None

if self._state is _State.EXPIRING:
self._state = _State.EXPIRED

if self._task.uncancel() <= self._cancelling and exc_type is exceptions.CancelledError:
# Since there are no new cancel requests, we're
# handling this.
> raise TimeoutError from exc_val
E TimeoutError
/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/asyncio/timeouts.py:115: TimeoutError
During handling of the above exception, another exception occurred:
@pytest.fixture()
async def client():
> async with AsyncClient(app=app, base_url="http://test", timeout=20) as client, LifespanManager(
app
):
tests/end_to_end/test_torch_classify.py:35:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.venv/lib/python3.12/site-packages/asgi_lifespan/_manager.py:99: in __aenter__
await self.startup()
.venv/lib/python3.12/site-packages/asgi_lifespan/_manager.py:40: in startup
await self._concurrency_backend.run_and_fail_after(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
seconds = 5
coroutine = >
async def run_and_fail_after(
self,
seconds: typing.Optional[float],
coroutine: typing.Callable[[], typing.Awaitable[None]],
) -> None:
try:
await asyncio.wait_for(coroutine(), timeout=seconds)
except asyncio.TimeoutError:
> raise TimeoutError
E TimeoutError
```

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先,在 Ubuntu 上使用 Python 3.12 和 uvloop 复现链接的 infinity GitHub Actions job,然后使用 vanilla asyncio 对同一测试进行比较。traceback 指向 tests/end_to_end/test_torch_classify.py 和 asyncio 的事件等待路径;完成的标准是确定一个 uvloop 特有的原因,并为该故障添加一个回归测试。

由索引模型根据 Issue 内容生成。

评估

技术栈
python, ubuntu
领域
backend, networking
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
需要澄清
新手友好度
28/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。