diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 9b2ef84..b49eceb 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", pypy-3.10] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", pypy-3.10] steps: - uses: actions/checkout@v4 - name: Set up Python diff --git a/README.md b/README.md index a5cecff..469b517 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ a backport of asyncio.TaskGroup, asyncio.Runner and asyncio.timeout ## background This is a backport of the TaskGroup, Runner and timeout code from -Python 3.12.8 to Python 3.8, Python 3.9, Python 3.10 and Python 3.11. +Python 3.12.8 to Python 3.9, Python 3.10 and Python 3.11. ## operation diff --git a/pyproject.toml b/pyproject.toml index 9f14c39..47e1908 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ classifiers = ["License :: OSI Approved :: MIT License"] dynamic = ["version", "description"] dependencies = ["exceptiongroup", "typing_extensions>=4.12.2,<5"] readme = "README.md" -requires_python = ">=3.8" +requires_python = ">=3.9" [project.urls] Home = "https://github.com/graingert/taskgroup" diff --git a/taskgroup/install.py b/taskgroup/install.py index b4fd162..64444eb 100644 --- a/taskgroup/install.py +++ b/taskgroup/install.py @@ -1,6 +1,6 @@ -import sys import contextvars import asyncio +import collections.abc import types from typing import cast, Optional, Type @@ -8,11 +8,6 @@ from typing_extensions import Self, TypeVar -if sys.version_info >= (3, 9): - from collections.abc import Generator, Coroutine -else: - from typing import Generator, Coroutine - UNCANCEL_DONE = object() @@ -53,12 +48,12 @@ def _async_yield(v): class WrapCoro( - Generator[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], - Coroutine[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], + collections.abc.Generator[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], + collections.abc.Coroutine[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], ): def __init__( self, - coro: Coroutine[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], + coro: collections.abc.Coroutine[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], context: contextvars.Context, ): self._coro = coro diff --git a/taskgroup/runners.py b/taskgroup/runners.py index 7ccd0e1..64c66c0 100644 --- a/taskgroup/runners.py +++ b/taskgroup/runners.py @@ -95,7 +95,7 @@ def close(self) -> None: loop.run_until_complete( loop.shutdown_default_executor(constants.THREAD_JOIN_TIMEOUT) # type: ignore ) - elif sys.version_info >= (3, 9): + else: loop.run_until_complete(loop.shutdown_default_executor()) finally: if self._set_event_loop: diff --git a/taskgroup/taskgroups.py b/taskgroup/taskgroups.py index 212c5fd..3c71a29 100644 --- a/taskgroup/taskgroups.py +++ b/taskgroup/taskgroups.py @@ -7,6 +7,7 @@ __all__ = ["TaskGroup"] import sys +import collections.abc from types import TracebackType from asyncio import events from asyncio import exceptions @@ -23,11 +24,6 @@ from typing_extensions import Self, TypeAlias, Literal, TypeVar import contextlib -if sys.version_info >= (3, 9): - from collections.abc import Generator, Coroutine, Awaitable -else: - from typing import Generator, Coroutine, Awaitable - _T = TypeVar("_T") @@ -39,19 +35,15 @@ _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) -_TaskYieldType: TypeAlias = "futures.Future[object] | None" +_TaskYieldType: TypeAlias = Optional[futures.Future[object]] if sys.version_info >= (3, 12): - _TaskCompatibleCoro: TypeAlias = Coroutine[Any, Any, _T_co] -elif sys.version_info >= (3, 9): + _TaskCompatibleCoro: TypeAlias = collections.abc.Coroutine[Any, Any, _T_co] +else: _TaskCompatibleCoro: TypeAlias = Union[ - Generator[_TaskYieldType, None, _T_co], - Coroutine[Any, Any, _T_co], + collections.abc.Generator[_TaskYieldType, None, _T_co], + collections.abc.Coroutine[Any, Any, _T_co], ] -else: - _TaskCompatibleCoro: TypeAlias = ( - "Generator[_TaskYieldType, None, _T_co] | Awaitable[_T_co]" - ) class _TaskGroup: diff --git a/taskgroup/tasks.py b/taskgroup/tasks.py index c30e83a..88d5d10 100644 --- a/taskgroup/tasks.py +++ b/taskgroup/tasks.py @@ -1,16 +1,12 @@ from __future__ import annotations import asyncio +import collections.abc import contextvars -from typing import Any, Union, TYPE_CHECKING, Generic +from typing import Any, Optional, Union from typing_extensions import TypeAlias, TypeVar, Self import sys -if sys.version_info >= (3, 9): - from collections.abc import Generator, Coroutine, Awaitable -else: - from typing import Generator, Coroutine, Awaitable - _YieldT_co = TypeVar("_YieldT_co", covariant=True) _SendT_contra = TypeVar("_SendT_contra", contravariant=True, default=None) _ReturnT_co = TypeVar("_ReturnT_co", covariant=True, default=None) @@ -19,30 +15,26 @@ _T = TypeVar("_T") _T_co = TypeVar("_T_co", covariant=True) -_TaskYieldType: TypeAlias = "asyncio.Future[object] | None" +_TaskYieldType: TypeAlias = Optional[asyncio.Future[object]] if sys.version_info >= (3, 12): - _TaskCompatibleCoro: TypeAlias = Coroutine[Any, Any, _T_co] -elif sys.version_info >= (3, 9): + _TaskCompatibleCoro: TypeAlias = collections.abc.Coroutine[Any, Any, _T_co] +else: _TaskCompatibleCoro: TypeAlias = Union[ - Generator[_TaskYieldType, None, _T_co], - Coroutine[Any, Any, _T_co], + collections.abc.Generator[_TaskYieldType, None, _T_co], + collections.abc.Coroutine[Any, Any, _T_co], ] -else: - _TaskCompatibleCoro: TypeAlias = ( - "Generator[_TaskYieldType, None, _T_co] | Awaitable[_T_co]" - ) class _Interceptor( - Generator[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], - Coroutine[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], + collections.abc.Generator[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], + collections.abc.Coroutine[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd], ): def __init__( self, coro: ( - Coroutine[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd] - | Generator[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd] + collections.abc.Coroutine[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd] + | collections.abc.Generator[_YieldT_co, _SendT_contra_nd, _ReturnT_co_nd] ), context: contextvars.Context, ): @@ -65,21 +57,7 @@ def close(self) -> None: super().close() -if TYPE_CHECKING: - - class _Task(asyncio.Task[_T_co]): - pass - - -elif sys.version_info >= (3, 9): - _Task = asyncio.Task -else: - - class _Task(asyncio.Task, Generic[_T_co]): - pass - - -class Task(_Task[_T_co]): +class Task(asyncio.Task[_T_co]): def __init__( self, coro: _TaskCompatibleCoro[_T_co], *args, context=None, **kwargs ) -> None: