Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-aioitertools for 
openSUSE:Factory checked in at 2025-11-14 16:13:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-aioitertools (Old)
 and      /work/SRC/openSUSE:Factory/.python-aioitertools.new.2061 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-aioitertools"

Fri Nov 14 16:13:47 2025 rev:7 rq:1317638 version:0.13.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-aioitertools/python-aioitertools.changes  
2024-11-05 15:42:47.174513545 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-aioitertools.new.2061/python-aioitertools.changes
        2025-11-14 16:13:50.198601922 +0100
@@ -1,0 +2,10 @@
+Thu Nov 13 13:37:44 UTC 2025 - John Paul Adrian Glaubitz 
<[email protected]>
+
+- Update to 0.13.0
+  * Modernized project metadata (#208)
+  * Fixed references to old branch (#209)
+  * Tested up to Python 3.14 (#208)
+  * Drop support for Python 3.8 (#208)
+  * Use modern type annotations, clean up lint (#219, #220, #221)
+
+-------------------------------------------------------------------

Old:
----
  aioitertools-0.12.0.tar.gz

New:
----
  aioitertools-0.13.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-aioitertools.spec ++++++
--- /var/tmp/diff_new_pack.MpXLk7/_old  2025-11-14 16:13:51.558658928 +0100
+++ /var/tmp/diff_new_pack.MpXLk7/_new  2025-11-14 16:13:51.558658928 +0100
@@ -17,7 +17,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-aioitertools
-Version:        0.12.0
+Version:        0.13.0
 Release:        0
 Summary:        Itertools and builtins for AsyncIO and mixed iterables
 License:        MIT

++++++ aioitertools-0.12.0.tar.gz -> aioitertools-0.13.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/.flake8 
new/aioitertools-0.13.0/.flake8
--- old/aioitertools-0.12.0/.flake8     2024-09-02 05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/.flake8     1970-01-01 01:00:00.000000000 +0100
@@ -1,15 +0,0 @@
-[flake8]
-ignore =
-    # mccabe complexity
-    C901
-
-    # covered by black/usort
-    E1
-    E2
-    E3
-    E4
-    E704
-
-max-line-length = 88
-per-file-ignores =
-    __init__.py: F401
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/.github/issue_template.md 
new/aioitertools-0.13.0/.github/issue_template.md
--- old/aioitertools-0.12.0/.github/issue_template.md   2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/.github/issue_template.md   2025-11-06 
23:14:49.000000000 +0100
@@ -7,5 +7,5 @@
 * OS:
 * Python version:
 * aioitertools version:
-* Can you repro on master?
+* Can you repro on main?
 * Can you repro in a clean virtualenv?
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/.github/workflows/ci.yml 
new/aioitertools-0.13.0/.github/workflows/ci.yml
--- old/aioitertools-0.12.0/.github/workflows/ci.yml    2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/.github/workflows/ci.yml    2025-11-06 
23:14:49.000000000 +0100
@@ -11,7 +11,7 @@
   contents: read
 
 env:
-  UV_SYSTEM_PYTHON: 1
+  UV_MANAGED_PYTHON: 1
 
 jobs:
   test:
@@ -19,56 +19,65 @@
     strategy:
       fail-fast: false
       matrix:
-        python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
+        python-version: [
+          "3.9",
+          "3.10",
+          "3.11",
+          "3.12",
+          "3.13",
+          "3.13t",
+          "3.14",
+          "3.14t",
+        ]
         os: [macOS-latest, ubuntu-latest, windows-latest]
 
     steps:
       - name: Checkout
-        uses: actions/checkout@v4
-      - name: Set Up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v5
+        uses: actions/checkout@v5
+      - uses: astral-sh/setup-uv@v7
         with:
           python-version: ${{ matrix.python-version }}
-          allow-prereleases: true
-      - uses: hynek/setup-cached-uv@v2
-        with:
-          cache-dependency-path: pyproject.toml
-      - name: Install
-        run: make EXTRAS=dev install
+      - run: uv sync
       - name: Test
         run: make test
       - name: Lint
         run: make lint
 
-  sdist:
-    needs: test
+  compat:
+    env:
+      UV_RESOLUTION: lowest-direct
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@v4
-      - uses: actions/setup-python@v5
+      - uses: actions/checkout@v5
+      - uses: astral-sh/setup-uv@v7
         with:
-          python-version: '3.12'
-      - uses: hynek/setup-cached-uv@v2
+          python-version: "3.9"
+      - run: uv sync
+      - run: make test lint
+
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v5
+      - uses: astral-sh/setup-uv@v7
         with:
-          cache-dependency-path: pyproject.toml
-      - name: Install
-        run: make install
-      - name: Build
-        run: python -m build --sdist
+          python-version: "3.14"
+      - run: uv sync
+      - run: uv build
       - name: Upload
-        uses: actions/upload-artifact@v3
+        uses: actions/upload-artifact@v5
         with:
           name: sdist
           path: dist
-  
+
   publish:
-    needs: sdist
+    needs: [build, compat, test]
     runs-on: ubuntu-latest
     if: startsWith(github.ref, 'refs/tags/v')
     permissions:
       id-token: write
     steps:
-      - uses: actions/download-artifact@v3
+      - uses: actions/download-artifact@v6
         with:
           name: sdist
           path: dist
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/.gitignore 
new/aioitertools-0.13.0/.gitignore
--- old/aioitertools-0.12.0/.gitignore  2024-09-02 05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/.gitignore  2025-11-06 23:14:49.000000000 +0100
@@ -1,3 +1,4 @@
+uv.lock
 html/
 
 # Byte-compiled / optimized / DLL files
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/.readthedocs.yml 
new/aioitertools-0.13.0/.readthedocs.yml
--- old/aioitertools-0.12.0/.readthedocs.yml    2024-09-02 05:27:31.000000000 
+0200
+++ new/aioitertools-0.13.0/.readthedocs.yml    2025-11-06 23:14:49.000000000 
+0100
@@ -2,12 +2,10 @@
 sphinx:
   configuration: docs/conf.py
 build:
-  os: ubuntu-22.04
+  os: ubuntu-24.04
   tools:
-    python: "3.10"
-python:
-  install:
-    - method: pip
-      path: .
-      extra_requirements:
-        - docs
+    python: "3.13"
+  jobs:
+    install:
+      - pip install --upgrade pip
+      - pip install --group 'docs'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/CHANGELOG.md 
new/aioitertools-0.13.0/CHANGELOG.md
--- old/aioitertools-0.12.0/CHANGELOG.md        2024-09-02 05:27:31.000000000 
+0200
+++ new/aioitertools-0.13.0/CHANGELOG.md        2025-11-06 23:14:49.000000000 
+0100
@@ -4,6 +4,25 @@
 [![Generated by attribution][attribution-badge]][attribution-url]
 
 
+v0.13.0
+-------
+
+Maintenance release
+
+- Modernized project metadata (#208)
+- Fixed references to old branch (#209)
+- Tested up to Python 3.14 (#208)
+- Drop support for Python 3.8 (#208)
+- Use modern type annotations, clean up lint (#219, #220, #221)
+
+```text
+$ git shortlog -s v0.12.0...v0.13.0
+     1 Alireza Ghasemi
+     6 Amethyst Reese
+    10 dependabot[bot]
+```
+
+
 v0.12.0
 -------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/CONTRIBUTING.md 
new/aioitertools-0.13.0/CONTRIBUTING.md
--- old/aioitertools-0.12.0/CONTRIBUTING.md     2024-09-02 05:27:31.000000000 
+0200
+++ new/aioitertools-0.13.0/CONTRIBUTING.md     2025-11-06 23:14:49.000000000 
+0100
@@ -2,23 +2,27 @@
 
 ## Preparation
 
-You'll need to have Python 3.8 or newer available for testing.
-I recommend using [pyenv][] for this:
+aioitertools uses [uv][] to manage environments and dependencies, and `make`
+to run tests and linters.
+
+You'll need to have Python 3.9 or newer available for testing:
 
 ```sh
-$ pyenv install 3.12
-$ pyenv shell 3.12
+$ uv python pin 3.14
 ```
 
-## Setup
+## Testing
 
-Create a fresh development enviroment, and install the
-appropriate tools and dependencies:
+Run the test suite:
 
-```sh
-$ cd <path/to/aioitertools>
-$ make venv
-$ source .venv/bin/activate
+```shell-session
+$ make test
+```
+
+Run the linters:
+
+```shell-session
+$ make lint
 ```
 
 ## Submitting
@@ -32,4 +36,4 @@
 * Used `make format` to format code appropriately
 * Validated and tested code with `make test lint`
 
-[pyenv]: https://github.com/pyenv/pyenv
+[uv]: https://docs.astral.sh/uv/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/README.md 
new/aioitertools-0.13.0/README.md
--- old/aioitertools-0.12.0/README.md   2024-09-02 05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/README.md   2025-11-06 23:14:49.000000000 +0100
@@ -6,13 +6,13 @@
 
[![documentation](https://readthedocs.org/projects/aioitertools/badge/?version=latest)](https://aioitertools.omnilib.dev)
 
[![version](https://img.shields.io/pypi/v/aioitertools.svg)](https://pypi.org/project/aioitertools)
 
[![changelog](https://img.shields.io/badge/change-log-blue)](https://aioitertools.omnilib.dev/en/latest/changelog.html)
-[![license](https://img.shields.io/pypi/l/aioitertools.svg)](https://github.com/omnilib/aioitertools/blob/master/LICENSE)
+[![license](https://img.shields.io/pypi/l/aioitertools.svg)](https://github.com/omnilib/aioitertools/blob/main/LICENSE)
 
 
 Install
 -------
 
-aioitertools requires Python 3.8 or newer.
+aioitertools requires Python 3.9 or newer.
 You can install it from PyPI:
 
 ```sh
@@ -85,6 +85,6 @@
 my code is from me and not from my employer. See the `LICENSE` file for 
details.
 
 
-[builtins.py]: 
https://github.com/omnilib/aioitertools/blob/master/aioitertools/builtins.py
-[itertools.py]: 
https://github.com/omnilib/aioitertools/blob/master/aioitertools/itertools.py
-[more_itertools.py]: 
https://github.com/omnilib/aioitertools/blob/master/aioitertools/more_itertools.py
+[builtins.py]: 
https://github.com/omnilib/aioitertools/blob/main/aioitertools/builtins.py
+[itertools.py]: 
https://github.com/omnilib/aioitertools/blob/main/aioitertools/itertools.py
+[more_itertools.py]: 
https://github.com/omnilib/aioitertools/blob/main/aioitertools/more_itertools.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/aioitertools/__version__.py 
new/aioitertools-0.13.0/aioitertools/__version__.py
--- old/aioitertools-0.12.0/aioitertools/__version__.py 2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/__version__.py 2025-11-06 
23:14:49.000000000 +0100
@@ -4,4 +4,4 @@
 Do not edit manually. Get more info at https://attribution.omnilib.dev
 """
 
-__version__ = "0.12.0"
+__version__ = "0.13.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/aioitertools/asyncio.py 
new/aioitertools-0.13.0/aioitertools/asyncio.py
--- old/aioitertools-0.12.0/aioitertools/asyncio.py     2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/asyncio.py     2025-11-06 
23:14:49.000000000 +0100
@@ -9,19 +9,8 @@
 
 import asyncio
 import time
-from typing import (
-    Any,
-    AsyncGenerator,
-    AsyncIterable,
-    Awaitable,
-    cast,
-    Dict,
-    Iterable,
-    List,
-    Optional,
-    Set,
-    Tuple,
-)
+from collections.abc import AsyncGenerator, AsyncIterable, Awaitable, Iterable
+from typing import Any, cast, Optional
 
 from .builtins import iter as aiter, maybe_await
 from .types import AnyIterable, AsyncIterator, MaybeAwaitable, T
@@ -47,8 +36,8 @@
             ...  # use value immediately
 
     """
-    done: Set[Awaitable[T]] = set()
-    pending: Set[Awaitable[T]] = {asyncio.ensure_future(a) for a in aws}
+    done: set[Awaitable[T]] = set()
+    pending: set[Awaitable[T]] = {asyncio.ensure_future(a) for a in aws}
     remaining: Optional[float] = None
 
     if timeout and timeout > 0:
@@ -72,10 +61,10 @@
         # returns Tuple[Set[Future], Set[Future]. Because mypy doesn't like 
assigning
         # these values to existing Set[Awaitable] or even Set[Union[Awaitable, 
Future]],
         # we need to first cast the results to something that we can actually 
use
-        # asyncio.Future: 
https://github.com/python/typeshed/blob/72ff7b94e534c610ddf8939bacbc55343e9465d2/stdlib/3/asyncio/futures.pyi#L30
  # noqa: E501
-        # asyncio.wait(): 
https://github.com/python/typeshed/blob/72ff7b94e534c610ddf8939bacbc55343e9465d2/stdlib/3/asyncio/tasks.pyi#L89
  # noqa: E501
+        # asyncio.Future: 
https://github.com/python/typeshed/blob/72ff7b94e534c610ddf8939bacbc55343e9465d2/stdlib/3/asyncio/futures.pyi#L30
+        # asyncio.wait(): 
https://github.com/python/typeshed/blob/72ff7b94e534c610ddf8939bacbc55343e9465d2/stdlib/3/asyncio/tasks.pyi#L89
         done, pending = cast(
-            Tuple[Set[Awaitable[T]], Set[Awaitable[T]]],
+            tuple[set[Awaitable[T]], set[Awaitable[T]]],
             await asyncio.wait(
                 pending,
                 timeout=remaining,
@@ -172,7 +161,7 @@
     *args: Awaitable[T],
     return_exceptions: bool = False,
     limit: int = -1,
-) -> List[Any]:
+) -> list[Any]:
     """
     Like asyncio.gather but with a limit on concurrency.
 
@@ -189,13 +178,13 @@
     """
 
     # For detecting input duplicates and reconciling them at the end
-    input_map: Dict[Awaitable[T], List[int]] = {}
+    input_map: dict[Awaitable[T], list[int]] = {}
     # This is keyed on what we'll get back from asyncio.wait
-    pos: Dict[asyncio.Future[T], int] = {}
-    ret: List[Any] = [None] * len(args)
+    pos: dict[asyncio.Future[T], int] = {}
+    ret: list[Any] = [None] * len(args)
 
-    pending: Set[asyncio.Future[T]] = set()
-    done: Set[asyncio.Future[T]] = set()
+    pending: set[asyncio.Future[T]] = set()
+    done: set[asyncio.Future[T]] = set()
 
     next_arg = 0
 
@@ -251,7 +240,7 @@
     itr: AnyIterable[MaybeAwaitable[T]],
     return_exceptions: bool = False,
     limit: int = -1,
-) -> List[T]:
+) -> list[T]:
     """
     Wrapper around gather to handle gathering an iterable instead of ``*args``.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/aioitertools/builtins.py 
new/aioitertools-0.13.0/aioitertools/builtins.py
--- old/aioitertools-0.12.0/aioitertools/builtins.py    2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/builtins.py    2025-11-06 
23:14:49.000000000 +0100
@@ -13,21 +13,9 @@
 
 import asyncio
 import builtins
+from collections.abc import AsyncIterable, AsyncIterator, Iterable
 from enum import Enum
-from typing import (
-    Any,
-    AsyncIterable,
-    AsyncIterator,
-    Callable,
-    cast,
-    Iterable,
-    List,
-    Optional,
-    overload,
-    Set,
-    Tuple,
-    Union,
-)
+from typing import Any, Callable, cast, Optional, overload, Union
 
 from . import asyncio as ait_asyncio
 from .helpers import maybe_await, Orderable
@@ -150,7 +138,7 @@
         return default
 
 
-async def list(itr: AnyIterable[T]) -> List[T]:
+async def list(itr: AnyIterable[T]) -> builtins.list[T]:
     """
     Consume a mixed iterable and return a list of items in order.
 
@@ -163,7 +151,7 @@
     return [item async for item in iter(itr)]
 
 
-async def tuple(itr: AnyIterable[T]) -> Tuple[T, ...]:
+async def tuple(itr: AnyIterable[T]) -> builtins.tuple[T, ...]:
     """
     Consume a mixed iterable and return a tuple of items in order.
 
@@ -177,7 +165,7 @@
     return builtins.tuple(await list(itr))
 
 
-async def set(itr: AnyIterable[T]) -> Set[T]:
+async def set(itr: AnyIterable[T]) -> builtins.set[T]:
     """
     Consume a mixed iterable and return a set of items.
 
@@ -192,7 +180,7 @@
 
 async def enumerate(
     itr: AnyIterable[T], start: int = 0
-) -> AsyncIterator[Tuple[int, T]]:
+) -> AsyncIterator[builtins.tuple[int, T]]:
     """
     Consume a mixed iterable and yield the current index and item.
 
@@ -364,21 +352,23 @@
 
 
 @overload
-def zip(__iter1: AnyIterable[T1]) -> AsyncIterator[Tuple[T1]]:  # pragma: no 
cover
+def zip(
+    __iter1: AnyIterable[T1],
+) -> AsyncIterator[builtins.tuple[T1]]:  # pragma: no cover
     pass
 
 
 @overload
 def zip(
     __iter1: AnyIterable[T1], __iter2: AnyIterable[T2]
-) -> AsyncIterator[Tuple[T1, T2]]:  # pragma: no cover
+) -> AsyncIterator[builtins.tuple[T1, T2]]:  # pragma: no cover
     pass
 
 
 @overload
 def zip(
     __iter1: AnyIterable[T1], __iter2: AnyIterable[T2], __iter3: 
AnyIterable[T3]
-) -> AsyncIterator[Tuple[T1, T2, T3]]:  # pragma: no cover
+) -> AsyncIterator[builtins.tuple[T1, T2, T3]]:  # pragma: no cover
     pass
 
 
@@ -388,7 +378,7 @@
     __iter2: AnyIterable[T2],
     __iter3: AnyIterable[T3],
     __iter4: AnyIterable[T4],
-) -> AsyncIterator[Tuple[T1, T2, T3, T4]]:  # pragma: no cover
+) -> AsyncIterator[builtins.tuple[T1, T2, T3, T4]]:  # pragma: no cover
     pass
 
 
@@ -399,7 +389,7 @@
     __iter3: AnyIterable[T3],
     __iter4: AnyIterable[T4],
     __iter5: AnyIterable[T5],
-) -> AsyncIterator[Tuple[T1, T2, T3, T4, T5]]:  # pragma: no cover
+) -> AsyncIterator[builtins.tuple[T1, T2, T3, T4, T5]]:  # pragma: no cover
     pass
 
 
@@ -412,11 +402,11 @@
     __iter5: AnyIterable[Any],
     __iter6: AnyIterable[Any],
     *__iterables: AnyIterable[Any],
-) -> AsyncIterator[Tuple[Any, ...]]:  # pragma: no cover
+) -> AsyncIterator[builtins.tuple[Any, ...]]:  # pragma: no cover
     pass
 
 
-async def zip(*itrs: AnyIterable[Any]) -> AsyncIterator[Tuple[Any, ...]]:
+async def zip(*itrs: AnyIterable[Any]) -> AsyncIterator[builtins.tuple[Any, 
...]]:
     """
     Yield a tuple of items from mixed iterables until the shortest is consumed.
 
@@ -426,7 +416,7 @@
             ...
 
     """
-    its: List[AsyncIterator[Any]] = [iter(itr) for itr in itrs]
+    its: builtins.list[AsyncIterator[Any]] = [iter(itr) for itr in itrs]
 
     while True:
         values = await asyncio.gather(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/aioitertools/helpers.py 
new/aioitertools-0.13.0/aioitertools/helpers.py
--- old/aioitertools-0.12.0/aioitertools/helpers.py     2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/helpers.py     2025-11-06 
23:14:49.000000000 +0100
@@ -2,15 +2,11 @@
 # Licensed under the MIT license
 
 import inspect
-import sys
-from typing import Awaitable, Union
+from collections.abc import Awaitable
 
-from .types import T
+from typing import Protocol, Union
 
-if sys.version_info < (3, 8):  # pragma: no cover
-    from typing_extensions import Protocol
-else:  # pragma: no cover
-    from typing import Protocol
+from .types import T
 
 
 class Orderable(Protocol):  # pragma: no cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/aioitertools/itertools.py 
new/aioitertools-0.13.0/aioitertools/itertools.py
--- old/aioitertools-0.12.0/aioitertools/itertools.py   2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/itertools.py   2025-11-06 
23:14:49.000000000 +0100
@@ -17,7 +17,8 @@
 import builtins
 import itertools
 import operator
-from typing import Any, AsyncIterator, List, Optional, overload, Tuple
+from collections.abc import AsyncIterator
+from typing import Any, Optional, overload
 
 from .builtins import enumerate, iter, list, next, tuple, zip
 from .helpers import maybe_await
@@ -71,7 +72,7 @@
     n: int,
     *,
     strict: bool = False,
-) -> AsyncIterator[Tuple[T, ...]]:
+) -> AsyncIterator[builtins.tuple[T, ...]]:
     """
     Yield batches of values from the given iterable. The final batch may be 
shorter.
 
@@ -119,7 +120,9 @@
 chain = Chain()
 
 
-async def combinations(itr: AnyIterable[T], r: int) -> AsyncIterator[Tuple[T, 
...]]:
+async def combinations(
+    itr: AnyIterable[T], r: int
+) -> AsyncIterator[builtins.tuple[T, ...]]:
     """
     Yield r length subsequences from the given iterable.
 
@@ -132,14 +135,14 @@
             ...  # (0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)
 
     """
-    pool: List[T] = await list(itr)
+    pool: builtins.list[T] = await list(itr)
     for value in itertools.combinations(pool, r):
         yield value
 
 
 async def combinations_with_replacement(
     itr: AnyIterable[T], r: int
-) -> AsyncIterator[Tuple[T, ...]]:
+) -> AsyncIterator[builtins.tuple[T, ...]]:
     """
     Yield r length subsequences from the given iterable with replacement.
 
@@ -152,7 +155,7 @@
             ...  # ("A", "A"), ("A", "B"), ("A", "C"), ("B", "B"), ...
 
     """
-    pool: List[T] = await list(itr)
+    pool: builtins.list[T] = await list(itr)
     for value in itertools.combinations_with_replacement(pool, r):
         yield value
 
@@ -264,20 +267,22 @@
 
 
 @overload
-def groupby(itr: AnyIterable[T]) -> AsyncIterator[Tuple[T, List[T]]]:  # 
pragma: nocover
+def groupby(
+    itr: AnyIterable[T],
+) -> AsyncIterator[builtins.tuple[T, builtins.list[T]]]:  # pragma: nocover
     pass
 
 
 @overload
 def groupby(
     itr: AnyIterable[T], key: KeyFunction[T, R]
-) -> AsyncIterator[Tuple[R, List[T]]]:  # pragma: nocover
+) -> AsyncIterator[builtins.tuple[R, builtins.list[T]]]:  # pragma: nocover
     pass
 
 
 async def groupby(
     itr: AnyIterable[T], key: Optional[KeyFunction[T, R]] = None
-) -> AsyncIterator[Tuple[Any, List[T]]]:
+) -> AsyncIterator[builtins.tuple[Any, builtins.list[T]]]:
     """
     Yield consecutive keys and groupings from the given iterable.
 
@@ -298,7 +303,7 @@
     if key is None:
         key = lambda x: x  # noqa: E731
 
-    grouping: List[T] = []
+    grouping: builtins.list[T] = []
 
     it = iter(itr)
     try:
@@ -385,7 +390,7 @@
 
 async def permutations(
     itr: AnyIterable[T], r: Optional[int] = None
-) -> AsyncIterator[Tuple[T, ...]]:
+) -> AsyncIterator[builtins.tuple[T, ...]]:
     """
     Yield r length permutations of elements in the iterable.
 
@@ -398,14 +403,14 @@
             ...  # (0, 1, 2), (0, 2, 1), (1, 0, 2), ...
 
     """
-    pool: List[T] = await list(itr)
+    pool: builtins.list[T] = await list(itr)
     for value in itertools.permutations(pool, r):
         yield value
 
 
 async def product(
     *itrs: AnyIterable[T], repeat: int = 1
-) -> AsyncIterator[Tuple[T, ...]]:
+) -> AsyncIterator[builtins.tuple[T, ...]]:
     """
     Yield cartesian products of all iterables.
 
@@ -422,6 +427,7 @@
 
     """
     pools = await asyncio.gather(*[list(itr) for itr in itrs])
+    value: builtins.tuple[T, ...]
     for value in itertools.product(*pools, repeat=repeat):
         yield value
 
@@ -489,14 +495,14 @@
             break
 
 
-def tee(itr: AnyIterable[T], n: int = 2) -> Tuple[AsyncIterator[T], ...]:
+def tee(itr: AnyIterable[T], n: int = 2) -> builtins.tuple[AsyncIterator[T], 
...]:
     """
     Return n iterators that each yield items from the given iterable.
 
     The first iterator lazily fetches from the original iterable, and then
     queues the values for the other iterators to yield when needed.
 
-    Caveat: all iterators are dependent on the first iterator – if it is
+    Caveat: all iterators are dependent on the first iterator — if it is
     consumed more slowly than the rest, the other consumers will be blocked
     until the first iterator continues forward.  Similarly, if the first
     iterator is consumed more quickly than the rest, more memory will be
@@ -516,7 +522,7 @@
     """
     assert n > 0
     sentinel = object()
-    queues: List[asyncio.Queue] = [asyncio.Queue() for k in range(n)]
+    queues: builtins.list[asyncio.Queue] = [asyncio.Queue() for k in range(n)]
 
     async def gen(k: int, q: asyncio.Queue) -> AsyncIterator[T]:
         if k == 0:
@@ -546,7 +552,7 @@
 
 async def zip_longest(
     *itrs: AnyIterable[Any], fillvalue: Any = None
-) -> AsyncIterator[Tuple[Any, ...]]:
+) -> AsyncIterator[builtins.tuple[Any, ...]]:
     """
     Yield a tuple of items from mixed iterables until all are consumed.
 
@@ -563,7 +569,7 @@
             b  # 0, 1, 2,  3,  4
 
     """
-    its: List[AsyncIterator[Any]] = [iter(itr) for itr in itrs]
+    its: builtins.list[AsyncIterator[Any]] = [iter(itr) for itr in itrs]
     itr_count = len(its)
     finished = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/aioitertools/more_itertools.py 
new/aioitertools-0.13.0/aioitertools/more_itertools.py
--- old/aioitertools-0.12.0/aioitertools/more_itertools.py      2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/more_itertools.py      2025-11-06 
23:14:49.000000000 +0100
@@ -2,7 +2,8 @@
 # Licensed under the MIT license
 
 import asyncio
-from typing import AsyncIterable, List, Tuple, TypeVar
+from collections.abc import AsyncIterable
+from typing import TypeVar
 
 from aioitertools.helpers import maybe_await
 
@@ -14,7 +15,7 @@
 T = TypeVar("T")
 
 
-async def take(n: int, iterable: AnyIterable[T]) -> List[T]:
+async def take(n: int, iterable: AnyIterable[T]) -> list[T]:
     """
     Return the first n items of iterable as a list.
 
@@ -31,7 +32,7 @@
     return [item async for item in islice(iterable, n)]
 
 
-async def chunked(iterable: AnyIterable[T], n: int) -> AsyncIterable[List[T]]:
+async def chunked(iterable: AnyIterable[T], n: int) -> AsyncIterable[list[T]]:
     """
     Break iterable into chunks of length n.
 
@@ -52,7 +53,7 @@
 
 async def before_and_after(
     predicate: Predicate[T], iterable: AnyIterable[T]
-) -> Tuple[AsyncIterable[T], AsyncIterable[T]]:
+) -> tuple[AsyncIterable[T], AsyncIterable[T]]:
     """
     A variant of :func:`aioitertools.takewhile` that allows complete access to 
the
     remainder of the iterator.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/aioitertools/tests/__init__.py 
new/aioitertools-0.13.0/aioitertools/tests/__init__.py
--- old/aioitertools-0.12.0/aioitertools/tests/__init__.py      2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/tests/__init__.py      2025-11-06 
23:14:49.000000000 +0100
@@ -1,4 +1,4 @@
-# Copyright 2022 Amethyst Reese
+# Copyright Amethyst Reese
 # Licensed under the MIT license
 
 from .asyncio import AsyncioTest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/aioitertools/tests/builtins.py 
new/aioitertools-0.13.0/aioitertools/tests/builtins.py
--- old/aioitertools-0.12.0/aioitertools/tests/builtins.py      2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/tests/builtins.py      2025-11-06 
23:14:49.000000000 +0100
@@ -2,7 +2,7 @@
 # Licensed under the MIT license
 
 import asyncio
-from typing import AsyncIterator
+from collections.abc import AsyncIterator
 from unittest import TestCase
 
 import aioitertools as ait
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/aioitertools-0.12.0/aioitertools/tests/more_itertools.py 
new/aioitertools-0.13.0/aioitertools/tests/more_itertools.py
--- old/aioitertools-0.12.0/aioitertools/tests/more_itertools.py        
2024-09-02 05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/tests/more_itertools.py        
2025-11-06 23:14:49.000000000 +0100
@@ -1,7 +1,7 @@
 # Copyright 2022 Amethyst Reese
 # Licensed under the MIT license
 
-from typing import AsyncIterable
+from collections.abc import AsyncIterable
 from unittest import TestCase
 
 import aioitertools.more_itertools as mit
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/aioitertools/types.py 
new/aioitertools-0.13.0/aioitertools/types.py
--- old/aioitertools-0.12.0/aioitertools/types.py       2024-09-02 
05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/aioitertools/types.py       2025-11-06 
23:14:49.000000000 +0100
@@ -2,17 +2,9 @@
 # Licensed under the MIT license
 
 import sys
+from collections.abc import AsyncIterable, AsyncIterator, Awaitable, Iterable, 
Iterator
 
-from typing import (
-    AsyncIterable,
-    AsyncIterator,
-    Awaitable,
-    Callable,
-    Iterable,
-    Iterator,
-    TypeVar,
-    Union,
-)
+from typing import Callable, TypeVar, Union
 
 if sys.version_info < (3, 10):  # pragma: no cover
     from typing_extensions import ParamSpec
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/docs/conf.py 
new/aioitertools-0.13.0/docs/conf.py
--- old/aioitertools-0.12.0/docs/conf.py        2024-09-02 05:27:31.000000000 
+0200
+++ new/aioitertools-0.13.0/docs/conf.py        2025-11-06 23:14:49.000000000 
+0100
@@ -62,7 +62,7 @@
 html_theme_options = {
     "description": "itertools and more for AsyncIO",
     "fixed_sidebar": True,
-    "badge_branch": "master",
+    "badge_branch": "main",
     "github_button": False,
     "github_user": "omnilib",
     "github_repo": "aioitertools",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/makefile 
new/aioitertools-0.13.0/makefile
--- old/aioitertools-0.12.0/makefile    2024-09-02 05:27:31.000000000 +0200
+++ new/aioitertools-0.13.0/makefile    2025-11-06 23:14:49.000000000 +0100
@@ -1,45 +1,27 @@
 PKG:=aioitertools
-EXTRAS:=dev,docs
 
-UV:=$(shell uv --version)
-ifdef UV
-       VENV:=uv venv
-       PIP:=uv pip
-else
-       VENV:=python -m venv
-       PIP:=python -m pip
-endif
-
-.venv:
-       $(VENV) .venv
-
-venv: .venv
-       source .venv/bin/activate && make install
-       echo 'run `source .venv/bin/activate` to use virtualenv'
-
-install:
-       $(PIP) install -Ue .[$(EXTRAS)]
-
-release: lint test clean
-       flit publish
+all: format test lint
 
 format:
-       python -m ufmt format $(PKG)
+       uv run ufmt format $(PKG)
 
 lint:
-       python -m flake8 $(PKG)
-       python -m ufmt check $(PKG)
+       uv run ruff check $(PKG)
+       uv run ufmt check $(PKG)
+
+fix:
+       uv run ruff check --fix --unsafe-fixes $(PKG)
 
 test:
-       python -m coverage run -m $(PKG).tests
-       python -m coverage report
-       python -m mypy -p $(PKG)
+       uv run coverage run -m $(PKG).tests
+       uv run coverage report
+       uv run mypy -p $(PKG)
 
 html: .venv README.md docs/*
-       source .venv/bin/activate && sphinx-build -b html docs html
+       uv run --group docs sphinx-build -b html docs html
 
 clean:
-       rm -rf .mypy_cache build dist html README MANIFEST *.egg-info
+       rm -rf .mypy_cache uv.lock build dist html README MANIFEST *.egg-info
 
 distclean: clean
        rm -rf .venv
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/aioitertools-0.12.0/pyproject.toml 
new/aioitertools-0.13.0/pyproject.toml
--- old/aioitertools-0.12.0/pyproject.toml      2024-09-02 05:27:31.000000000 
+0200
+++ new/aioitertools-0.13.0/pyproject.toml      2025-11-06 23:14:49.000000000 
+0100
@@ -1,34 +1,32 @@
 [build-system]
-requires = ["flit_core >=3.8,<4"]
+requires = ["flit_core >=3.11,<4"]
 build-backend = "flit_core.buildapi"
 
 [project]
 name = "aioitertools"
 readme = "README.md"
 authors = [{ name = "Amethyst Reese", email = "[email protected]" }]
-license = { file = "LICENSE" }
+license = "MIT"
+license-files = ["LICENSE"]
 dynamic = ["version", "description"]
 classifiers = [
-    "Development Status :: 4 - Beta",
     "Framework :: AsyncIO",
     "Intended Audience :: Developers",
-    "License :: OSI Approved :: MIT License",
     "Topic :: Software Development :: Libraries",
 ]
-requires-python = ">=3.8"
+requires-python = ">=3.9"
 dependencies = ["typing_extensions>=4.0; python_version < '3.10'"]
 
-[project.optional-dependencies]
+[dependency-groups]
 dev = [
     "attribution==1.8.0",
-    "black==24.8.0",
-    "build>=1.2",
-    "coverage==7.6.1",
-    "flake8==7.1.1",
-    "flit==3.9.0",
-    "mypy==1.11.2",
+    "black==25.9.0",
+    "coverage==7.10.7",
+    "flit==3.12.0",
+    "mypy==1.18.2",
     "usort==1.0.8.post1",
-    "ufmt==2.7.1",
+    "ufmt==2.8.0",
+    "ruff>=0.14.3",
 ]
 docs = [
     "sphinx==8.0.2",
@@ -37,6 +35,7 @@
 
 [project.urls]
 Documentation = "https://aioitertools.omnilib.dev";
+Changelog = "https://aioitertools.omnilib.dev/en/latest/changelog.html";
 Github = "https://github.com/omnilib/aioitertools";
 
 [tool.flit.sdist]
@@ -62,3 +61,13 @@
 [tool.mypy]
 # strict = true
 ignore_missing_imports = true
+
+[tool.ruff.lint]
+extend-select = ["UP", "RUF"]
+ignore = ["UP029"]
+
+[tool.ruff.lint.per-file-ignores]
+"__init__.py" = ["F401"]
+
+[tool.uv.dependency-groups]
+docs = {requires-python=">=3.10"}

Reply via email to