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 @@
[](https://aioitertools.omnilib.dev)
[](https://pypi.org/project/aioitertools)
[](https://aioitertools.omnilib.dev/en/latest/changelog.html)
-[](https://github.com/omnilib/aioitertools/blob/master/LICENSE)
+[](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"}