diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml
index 2d15da0..42b8e10 100644
--- a/.github/workflows/python-package.yml
+++ b/.github/workflows/python-package.yml
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
- python-version: ["3.11", "3.12"]
+ python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v2
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 4a3e61a..d1655a0 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -14,5 +14,5 @@ repos:
language: node
pass_filenames: false
types: [python]
- additional_dependencies: ["pyright@1.1.364"]
+ additional_dependencies: ["pyright@1.1.382"]
repo: local
diff --git a/README.md b/README.md
index d6896c1..1a261fc 100644
--- a/README.md
+++ b/README.md
@@ -2,12 +2,12 @@
# aioreactive - ReactiveX for asyncio using async and await
+
[![PyPI](https://img.shields.io/pypi/v/aioreactive.svg)](https://pypi.python.org/pypi/aioreactive)
![Python package](https://github.com/dbrattli/aioreactive/workflows/Python%20package/badge.svg)
![Publish Package](https://github.com/dbrattli/aioreactive/actions/workflows/python-publish.yml/badge.svg)
[![codecov](https://codecov.io/gh/dbrattli/aioreactive/branch/master/graph/badge.svg)](https://codecov.io/gh/dbrattli/aioreactive)
-
> *NEWS: Project rebooted Nov. 2020. Rebuilt using [Expression](https://github.com/dbrattli/Expression).*
Aioreactive is [RxPY](https://github.com/ReactiveX/RxPY) for asyncio.
@@ -19,9 +19,9 @@ and, integrates naturally with the Python language.
> aioreactive is the unification of RxPY and reactive programming with
> asyncio using async and await.
-## The design goals for aioreactive:
+## The design goals for aioreactive
-* Python 3.11+ only. We have a hard dependency [Expression v5]([https://www.python.org/dev/peps/pep-0585/](https://github.com/dbrattli/Expression)).
+* Python 3.10+ only. We have a hard dependency [Expression v5]([https://www.python.org/dev/peps/pep-0585/](https://github.com/dbrattli/Expression)).
* All operators and tools are implemented as plain old functions.
* Everything is `async`. Sending values is async, subscribing to
observables is async. Disposing subscriptions is async.
diff --git a/aioreactive/__init__.py b/aioreactive/__init__.py
index 5a059b5..3e1bb69 100644
--- a/aioreactive/__init__.py
+++ b/aioreactive/__init__.py
@@ -1,6 +1,6 @@
"""Aioreactive module.
-Contains the AsyncRx chained obserable that allows method chaining of all operators.
+Contains the AsyncRx chained observable that allows method chaining of all operators.
Also contains all operators as plain functions.
@@ -16,11 +16,11 @@
from __future__ import annotations
from collections.abc import AsyncIterable, Awaitable, Callable, Iterable
-from typing import Any, TypeVar, TypeVarTuple
+from typing import Any, TypeVar
from expression import Option, curry_flip, pipe
from expression.system.disposable import AsyncDisposable
-from typing_extensions import Unpack
+from typing_extensions import TypeVarTuple, Unpack
from .observables import AsyncAnonymousObservable, AsyncIterableObservable
from .observers import (
diff --git a/aioreactive/timeshift.py b/aioreactive/timeshift.py
index b5b1f94..913a643 100644
--- a/aioreactive/timeshift.py
+++ b/aioreactive/timeshift.py
@@ -1,7 +1,7 @@
import asyncio
import logging
from collections.abc import Awaitable, Callable, Iterable
-from datetime import UTC, datetime, timedelta
+from datetime import datetime, timedelta, timezone
from typing import NoReturn, TypeVar
from expression import curry_flipped
@@ -59,7 +59,7 @@ async def loop() -> TailCallResult[None, ...]:
ns, due_time = await inbox.receive()
- diff = due_time - datetime.now(UTC)
+ diff = due_time - datetime.now(timezone.utc)
seconds = diff.total_seconds()
if seconds > 0:
await asyncio.sleep(seconds)
@@ -84,7 +84,7 @@ async def matcher() -> None:
agent = MailboxProcessor.start(worker, token)
async def fn(ns: Notification[_TSource]) -> None:
- due_time = datetime.now(UTC) + timedelta(seconds=seconds)
+ due_time = datetime.now(timezone.utc) + timedelta(seconds=seconds)
agent.post((ns, due_time))
obv: AsyncNotificationObserver[_TSource] = AsyncNotificationObserver(fn)
diff --git a/poetry.lock b/poetry.lock
index 565abe5..59445f5 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,28 +1,14 @@
-# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
-
-[[package]]
-name = "autoflake"
-version = "1.7.8"
-description = "Removes unused imports and unused variables"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "autoflake-1.7.8-py3-none-any.whl", hash = "sha256:46373ef69b6714f5064c923bb28bd797c4f8a9497f557d87fc36665c6d956b39"},
- {file = "autoflake-1.7.8.tar.gz", hash = "sha256:e7e46372dee46fa1c97acf310d99d922b63d369718a270809d7c278d34a194cf"},
-]
-
-[package.dependencies]
-pyflakes = ">=1.1.0,<3"
+# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
[[package]]
name = "certifi"
-version = "2023.11.17"
+version = "2024.8.30"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
files = [
- {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"},
- {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"},
+ {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
+ {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
]
[[package]]
@@ -250,61 +236,75 @@ files = [
[[package]]
name = "dunamai"
-version = "1.19.0"
+version = "1.22.0"
description = "Dynamic version generation"
optional = false
-python-versions = ">=3.5,<4.0"
+python-versions = ">=3.5"
files = [
- {file = "dunamai-1.19.0-py3-none-any.whl", hash = "sha256:1ed948676bbf0812bfaafe315a134634f8d6eb67138513c75aa66e747404b9c6"},
- {file = "dunamai-1.19.0.tar.gz", hash = "sha256:6ad99ae34f7cd290550a2ef1305d2e0292e6e6b5b1b830dfc07ceb7fd35fec09"},
+ {file = "dunamai-1.22.0-py3-none-any.whl", hash = "sha256:eab3894b31e145bd028a74b13491c57db01986a7510482c9b5fff3b4e53d77b7"},
+ {file = "dunamai-1.22.0.tar.gz", hash = "sha256:375a0b21309336f0d8b6bbaea3e038c36f462318c68795166e31f9873fdad676"},
]
[package.dependencies]
packaging = ">=20.9"
+[[package]]
+name = "exceptiongroup"
+version = "1.2.2"
+description = "Backport of PEP 654 (exception groups)"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
+ {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
+]
+
+[package.extras]
+test = ["pytest (>=6)"]
+
[[package]]
name = "expression"
-version = "5.0.2"
+version = "5.3.0"
description = "Practical functional programming for Python 3.11+"
optional = false
-python-versions = ">=3.11,<4"
+python-versions = "<4,>=3.10"
files = [
- {file = "expression-5.0.2-py3-none-any.whl", hash = "sha256:2b54eeccb6247d86f598a3ce1a4e1efc56e4c7ca901f622d8203919d4106e147"},
- {file = "expression-5.0.2.tar.gz", hash = "sha256:37019851b0794820c1167b185d6be4a22111604f3bab221f4136e429e5d9b57f"},
+ {file = "expression-5.3.0-py3-none-any.whl", hash = "sha256:951a07aa3e8676ca42af0f29ca2c4d01ea0742317fde981cba8cf49a0a118064"},
+ {file = "expression-5.3.0.tar.gz", hash = "sha256:07a43669622851a413897b118319b4c9ac03e8251b6228683ebbf22f12827122"},
]
[package.dependencies]
-typing-extensions = ">=4.1.1,<5.0.0"
+typing-extensions = ">=4.6.0"
[package.extras]
-all = ["pydantic (>=2.0.0,<3.0.0)"]
-pydantic = ["pydantic (>=2.0.0,<3.0.0)"]
+all = ["pydantic (>=2.6.2,<3.0.0)"]
+pydantic = ["pydantic (>=2.6.2,<3.0.0)"]
[[package]]
name = "filelock"
-version = "3.13.1"
+version = "3.16.1"
description = "A platform independent file lock."
optional = false
python-versions = ">=3.8"
files = [
- {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"},
- {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"},
+ {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
+ {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
]
[package.extras]
-docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"]
-testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"]
-typing = ["typing-extensions (>=4.8)"]
+docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4.1)"]
+testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"]
+typing = ["typing-extensions (>=4.12.2)"]
[[package]]
name = "identify"
-version = "2.5.33"
+version = "2.6.1"
description = "File identification library for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "identify-2.5.33-py2.py3-none-any.whl", hash = "sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34"},
- {file = "identify-2.5.33.tar.gz", hash = "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d"},
+ {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"},
+ {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"},
]
[package.extras]
@@ -312,15 +312,18 @@ license = ["ukkonen"]
[[package]]
name = "idna"
-version = "3.7"
+version = "3.10"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.6"
files = [
- {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"},
- {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
+ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
+ {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
]
+[package.extras]
+all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
+
[[package]]
name = "iniconfig"
version = "2.0.0"
@@ -334,53 +337,51 @@ files = [
[[package]]
name = "nodeenv"
-version = "1.8.0"
+version = "1.9.1"
description = "Node.js virtual environment builder"
optional = false
-python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*"
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
files = [
- {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"},
- {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"},
+ {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"},
+ {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"},
]
-[package.dependencies]
-setuptools = "*"
-
[[package]]
name = "packaging"
-version = "23.2"
+version = "24.1"
description = "Core utilities for Python packages"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
- {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
+ {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
+ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
]
[[package]]
name = "platformdirs"
-version = "4.1.0"
-description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+version = "4.3.6"
+description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
optional = false
python-versions = ">=3.8"
files = [
- {file = "platformdirs-4.1.0-py3-none-any.whl", hash = "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380"},
- {file = "platformdirs-4.1.0.tar.gz", hash = "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420"},
+ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
+ {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
]
[package.extras]
-docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"]
+docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"]
+test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"]
+type = ["mypy (>=1.11.2)"]
[[package]]
name = "pluggy"
-version = "1.3.0"
+version = "1.5.0"
description = "plugin and hook calling mechanisms for python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
- {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
+ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
+ {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
]
[package.extras]
@@ -389,13 +390,13 @@ testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "pre-commit"
-version = "2.21.0"
+version = "3.8.0"
description = "A framework for managing and maintaining multi-language pre-commit hooks."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.9"
files = [
- {file = "pre_commit-2.21.0-py2.py3-none-any.whl", hash = "sha256:e2f91727039fc39a92f58a588a25b87f936de6567eed4f0e673e0507edc75bad"},
- {file = "pre_commit-2.21.0.tar.gz", hash = "sha256:31ef31af7e474a8d8995027fefdfcf509b5c913ff31f2015b4ec4beb26a6f658"},
+ {file = "pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f"},
+ {file = "pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af"},
]
[package.dependencies]
@@ -405,113 +406,106 @@ nodeenv = ">=0.11.1"
pyyaml = ">=5.1"
virtualenv = ">=20.10.0"
-[[package]]
-name = "pyflakes"
-version = "2.5.0"
-description = "passive checker of Python programs"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "pyflakes-2.5.0-py2.py3-none-any.whl", hash = "sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2"},
- {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"},
-]
-
[[package]]
name = "pytest"
-version = "7.4.4"
+version = "8.3.3"
description = "pytest: simple powerful testing with Python"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"},
- {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"},
+ {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"},
+ {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"},
]
[package.dependencies]
colorama = {version = "*", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
iniconfig = "*"
packaging = "*"
-pluggy = ">=0.12,<2.0"
+pluggy = ">=1.5,<2"
+tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras]
-testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
+dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
[[package]]
name = "pytest-asyncio"
-version = "0.18.3"
+version = "0.24.0"
description = "Pytest support for asyncio"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "pytest-asyncio-0.18.3.tar.gz", hash = "sha256:7659bdb0a9eb9c6e3ef992eef11a2b3e69697800ad02fb06374a210d85b29f91"},
- {file = "pytest_asyncio-0.18.3-1-py3-none-any.whl", hash = "sha256:16cf40bdf2b4fb7fc8e4b82bd05ce3fbcd454cbf7b92afc445fe299dabb88213"},
- {file = "pytest_asyncio-0.18.3-py3-none-any.whl", hash = "sha256:8fafa6c52161addfd41ee7ab35f11836c5a16ec208f93ee388f752bea3493a84"},
+ {file = "pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b"},
+ {file = "pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276"},
]
[package.dependencies]
-pytest = ">=6.1.0"
+pytest = ">=8.2,<9"
[package.extras]
-testing = ["coverage (==6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (==0.931)", "pytest-trio (>=0.7.0)"]
+docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"]
+testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
[[package]]
name = "pyyaml"
-version = "6.0.1"
+version = "6.0.2"
description = "YAML parser and emitter for Python"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
files = [
- {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
- {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
- {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
- {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
- {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
- {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
- {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
- {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
- {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
- {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
- {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
- {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
- {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
- {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
- {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
- {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
- {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
- {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
- {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
- {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
- {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
- {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
- {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
- {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
- {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
- {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
- {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
- {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
- {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
- {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
- {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
- {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
- {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
- {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
- {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
- {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
- {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
- {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
- {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
- {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
- {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
- {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
- {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
- {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
- {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
- {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
- {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
- {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
- {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
+ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
+ {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
+ {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
+ {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
+ {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
+ {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
+ {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
+ {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
+ {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
+ {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
+ {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
+ {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
+ {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
+ {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
+ {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
+ {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
+ {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
+ {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
+ {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
+ {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
+ {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
+ {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
+ {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
+ {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
+ {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
+ {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
+ {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
+ {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
+ {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
+ {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
+ {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
+ {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
+ {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
+ {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
+ {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
+ {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
+ {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
+ {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
+ {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
+ {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
+ {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
+ {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
+ {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
+ {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
+ {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
+ {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
+ {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
+ {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
+ {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
+ {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
+ {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
+ {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
+ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
]
[[package]]
@@ -530,13 +524,13 @@ typing-extensions = ">=4.1.1,<5.0.0"
[[package]]
name = "requests"
-version = "2.32.0"
+version = "2.32.3"
description = "Python HTTP for Humans."
optional = false
python-versions = ">=3.8"
files = [
- {file = "requests-2.32.0-py3-none-any.whl", hash = "sha256:f2c3881dddb70d056c5bd7600a4fae312b2a300e39be6a118d30b90bd27262b5"},
- {file = "requests-2.32.0.tar.gz", hash = "sha256:fa5490319474c82ef1d2c9bc459d3652e3ae4ef4c4ebdd18a21145a47ca4b6b8"},
+ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
+ {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
]
[package.dependencies]
@@ -550,57 +544,53 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
-name = "setuptools"
-version = "69.0.3"
-description = "Easily download, build, install, upgrade, and uninstall Python packages"
+name = "tomli"
+version = "2.0.1"
+description = "A lil' TOML parser"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.7"
files = [
- {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"},
- {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"},
+ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
+ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
-[package.extras]
-docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
-testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
-testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
-
[[package]]
name = "typing-extensions"
-version = "4.9.0"
+version = "4.12.2"
description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
- {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
- {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
+ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
+ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
]
[[package]]
name = "urllib3"
-version = "2.1.0"
+version = "2.2.3"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.8"
files = [
- {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"},
- {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"},
+ {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
+ {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
]
[package.extras]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
+h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"]
[[package]]
name = "virtualenv"
-version = "20.25.0"
+version = "20.26.6"
description = "Virtual Python Environment builder"
optional = false
python-versions = ">=3.7"
files = [
- {file = "virtualenv-20.25.0-py3-none-any.whl", hash = "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3"},
- {file = "virtualenv-20.25.0.tar.gz", hash = "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b"},
+ {file = "virtualenv-20.26.6-py3-none-any.whl", hash = "sha256:7345cc5b25405607a624d8418154577459c3e0277f5466dd79c49d5e492995f2"},
+ {file = "virtualenv-20.26.6.tar.gz", hash = "sha256:280aede09a2a5c317e409a00102e7077c6432c5a38f0ef938e643805a7ad2c48"},
]
[package.dependencies]
@@ -609,10 +599,10 @@ filelock = ">=3.12.2,<4"
platformdirs = ">=3.9.1,<5"
[package.extras]
-docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
+docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"]
test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"]
[metadata]
lock-version = "2.0"
-python-versions = ">= 3.11, < 4"
-content-hash = "f58815388ad47a96fe03eb2d6a1fc23f057dd008ec0bade544bee51ac50ce224"
+python-versions = ">= 3.10, < 4"
+content-hash = "6b75728d3702ddf8dfcad0ffa98fcdb06335154840edc8c296168dce60091641"
diff --git a/pyproject.toml b/pyproject.toml
index 15324b5..5a0418f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,7 +1,7 @@
[tool.poetry]
name = "aioreactive"
version = "0.0.0" # NOTE: will be updated by publish script
-description = "sync/await Reactive Tools for Python 3.11+"
+description = "sync/await Reactive Tools for Python 3.10+"
readme = "README.md"
authors = ["Dag Brattli ", "Børge Lanes"]
license = "MIT License"
@@ -20,18 +20,17 @@ classifiers = [
packages = [{ include = "aioreactive" }, { include = "aioreactive/py.typed" }]
[tool.poetry.dependencies]
-python = ">= 3.11, < 4"
+python = ">= 3.10, < 4"
typing-extensions = "^4.1.1"
-Expression = "^5.0.1"
+Expression = "^5.3.0"
reactivex = "^4.0.0"
[tool.poetry.dev-dependencies]
-pytest-asyncio = "^0.18.1"
-pytest = "^7.4.4"
+pytest-asyncio = "^0.24.0"
+pytest = "^8.3.3"
coverage = "^6.3.2"
coveralls = "^3.3.1"
-pre-commit = "^2.17.0"
-autoflake = "^1.4"
+pre-commit = "^3.8.0"
dunamai = "^1.9.0"
[tool.ruff]
diff --git a/pyrightconfig.json b/pyrightconfig.json
index 8a07b5b..931df36 100644
--- a/pyrightconfig.json
+++ b/pyrightconfig.json
@@ -7,6 +7,6 @@
],
"reportImportCycles": false,
"reportMissingImports": false,
- "pythonVersion": "3.11",
+ "pythonVersion": "3.10",
"typeCheckingMode": "strict"
}
\ No newline at end of file
diff --git a/tests/test_async_iteration.py b/tests/test_async_iteration.py
index b351d95..712756f 100644
--- a/tests/test_async_iteration.py
+++ b/tests/test_async_iteration.py
@@ -9,14 +9,14 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type: ignore
+@pytest.fixture(scope="function") # type: ignore
def event_loop():
loop = VirtualTimeEventLoop()
yield loop
loop.close()
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_async_iteration() -> None:
xs = rx.from_iterable([1, 2, 3])
result: list[int] = []
@@ -27,7 +27,7 @@ async def test_async_iteration() -> None:
assert result == [1, 2, 3]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_async_comprehension() -> None:
xs = rx.from_iterable([1, 2, 3])
@@ -36,7 +36,7 @@ async def test_async_comprehension() -> None:
assert result == [1, 2, 3]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_async_iteration_aync_with() -> None:
xs = rx.from_iterable([1, 2, 3])
result: list[int] = []
@@ -48,7 +48,7 @@ async def test_async_iteration_aync_with() -> None:
assert result == [1, 2, 3]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_async_iteration_inception() -> None:
# iterable to async source to async iterator to async source
xs = rx.from_iterable([1, 2, 3])
diff --git a/tests/test_chain.py b/tests/test_chain.py
index 1451cf5..86e5edb 100644
--- a/tests/test_chain.py
+++ b/tests/test_chain.py
@@ -11,14 +11,17 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type: ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_chain_map():
xs = AsyncRx.from_iterable([1, 2, 3])
@@ -38,7 +41,7 @@ def mapper(value: int) -> int:
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_chain_simple_pipe():
xs = AsyncRx.from_iterable([1, 2, 3])
@@ -62,7 +65,7 @@ async def predicate(value: int) -> bool:
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_chain_complex_pipe():
xs = AsyncRx.from_iterable([1, 2, 3])
diff --git a/tests/test_debounce.py b/tests/test_debounce.py
index b75a51b..af4b85a 100644
--- a/tests/test_debounce.py
+++ b/tests/test_debounce.py
@@ -17,14 +17,17 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type:ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_debounce():
xs: AsyncTestSubject[int] = AsyncTestSubject()
@@ -50,7 +53,7 @@ async def test_debounce():
await subscription.dispose_async()
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_debounce_filter():
xs: AsyncTestSubject[int] = AsyncTestSubject()
diff --git a/tests/test_delay.py b/tests/test_delay.py
index 63ab45d..6b23edb 100644
--- a/tests/test_delay.py
+++ b/tests/test_delay.py
@@ -17,14 +17,16 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type:ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_delay_done():
xs: AsyncTestSubject[int] = AsyncTestSubject()
@@ -43,7 +45,7 @@ async def test_delay_done():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_delay_cancel_before_done():
xs: AsyncTestSubject[int] = AsyncTestSubject()
@@ -60,7 +62,7 @@ async def test_delay_cancel_before_done():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_delay_throw():
error = Exception("ex")
xs: AsyncTestSubject[int] = AsyncTestSubject()
diff --git a/tests/test_distinct_until_changed.py b/tests/test_distinct_until_changed.py
index 85eaa86..240ff2e 100644
--- a/tests/test_distinct_until_changed.py
+++ b/tests/test_distinct_until_changed.py
@@ -1,3 +1,4 @@
+import asyncio
import pytest
from expression.core import pipe
@@ -11,14 +12,16 @@ class MyException(Exception):
pass
-@pytest.fixture() # type: ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_distinct_until_changed_different():
xs = rx.from_iterable([1, 2, 3])
@@ -34,7 +37,7 @@ async def test_distinct_until_changed_different():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_distinct_until_changed_changed():
xs = AsyncRx.from_iterable([1, 2, 2, 1, 3, 3, 1, 2, 2])
diff --git a/tests/test_eventloop.py b/tests/test_eventloop.py
index f4796be..5f4317a 100644
--- a/tests/test_eventloop.py
+++ b/tests/test_eventloop.py
@@ -6,14 +6,16 @@
from aioreactive.testing import VirtualTimeEventLoop
-@pytest.fixture() # type: ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_sleep():
loop = asyncio.get_event_loop()
await asyncio.sleep(100)
@@ -22,7 +24,7 @@ async def test_sleep():
assert loop.time() == 200
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_call_soon():
result = []
@@ -37,7 +39,7 @@ def action(value: int) -> None:
assert result == [1, 2, 3]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_call_later():
result = []
@@ -52,7 +54,7 @@ def action(value: int) -> None:
assert result == [2, 3, 1]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_call_at():
result = []
@@ -67,7 +69,7 @@ def action(value: int) -> None:
assert result == [2, 3, 1]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_cancel():
result = []
diff --git a/tests/test_filter.py b/tests/test_filter.py
index 0ec4945..83779e0 100644
--- a/tests/test_filter.py
+++ b/tests/test_filter.py
@@ -12,14 +12,16 @@ class MyException(Exception):
pass
-@pytest.fixture() # type:ignore
-def event_loop() -> Generator[Any, Any, Any]:
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_filter_happy() -> None:
xs = rx.from_iterable([1, 2, 3])
result = []
@@ -37,7 +39,7 @@ async def predicate(value: int) -> bool:
assert result == [2, 3]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_filter_predicate_throws() -> None:
xs = rx.from_iterable([1, 2, 3])
err = MyException("err")
diff --git a/tests/test_flat_map.py b/tests/test_flat_map.py
index 1251bef..ceaedab 100644
--- a/tests/test_flat_map.py
+++ b/tests/test_flat_map.py
@@ -1,3 +1,4 @@
+import asyncio
import pytest
from expression.core import pipe
@@ -7,14 +8,16 @@
from aioreactive.types import AsyncObservable
-@pytest.fixture() # type: ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_flap_map_done():
xs: rx.AsyncSubject[int] = rx.AsyncSubject()
@@ -34,7 +37,7 @@ def mapper(value: int) -> rx.AsyncObservable[int]:
assert obv.values == [(0, OnNext(10)), (0, OnNext(20)), (0, OnCompleted())]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_flat_map_monad():
m = rx.single(42)
@@ -47,7 +50,7 @@ def mapper(x: int) -> AsyncObservable[int]:
assert a == b
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_flat_map_monad_law_left_identity():
# return x >>= f is the same thing as f x
@@ -62,7 +65,7 @@ def f(x: int) -> AsyncObservable[int]:
assert a == b
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_flat_map_monad_law_right_identity():
# m >>= return is no different than just m.
@@ -77,7 +80,7 @@ def mapper(x: str) -> AsyncObservable[str]:
assert a == b
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_flat_map_monad_law_associativity():
# (m >>= f) >>= g is just like doing m >>= (\x -> f x >>= g)
diff --git a/tests/test_forward_pipe.py b/tests/test_forward_pipe.py
index e82fe58..1617e3c 100644
--- a/tests/test_forward_pipe.py
+++ b/tests/test_forward_pipe.py
@@ -12,14 +12,16 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type: ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_forward_pipe_map() -> None:
xs = rx.from_iterable([1, 2, 3])
@@ -38,7 +40,7 @@ def mapper(value: int) -> int:
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_forward_pipe_simple_pipe() -> None:
xs = rx.from_iterable([1, 2, 3])
@@ -60,7 +62,7 @@ async def predicate(value: int) -> bool:
assert obv.values == [(0, OnNext(20)), (0, OnNext(30)), (0, OnCompleted())]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_forward_pipe_complex_pipe() -> None:
xs = rx.from_iterable([1, 2, 3])
result = []
diff --git a/tests/test_from_iterable.py b/tests/test_from_iterable.py
index cd32ae2..b55653e 100644
--- a/tests/test_from_iterable.py
+++ b/tests/test_from_iterable.py
@@ -1,3 +1,4 @@
+import asyncio
import pytest
import aioreactive as rx
@@ -5,14 +6,16 @@
from aioreactive.testing import AsyncTestObserver, VirtualTimeEventLoop
-@pytest.fixture() # type:ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_from_iterable_happy():
xs = rx.from_iterable([1, 2, 3])
@@ -26,7 +29,7 @@ async def test_from_iterable_happy():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_from_iterable_observer_throws():
xs = rx.from_iterable([1, 2, 3])
error = Exception("error")
diff --git a/tests/test_map.py b/tests/test_map.py
index d5cf1d0..0b404d5 100644
--- a/tests/test_map.py
+++ b/tests/test_map.py
@@ -10,14 +10,15 @@
from aioreactive.testing import VirtualTimeEventLoop
-@pytest.fixture() # type:ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_map_works():
xs: AsyncObservable[int] = rx.from_iterable([1, 2, 3])
values: list[int] = []
@@ -37,7 +38,7 @@ def mapper(value: int) -> int:
assert values == [10, 20, 30]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_map_mapper_throws():
error = Exception("ex")
exception = None
@@ -65,7 +66,7 @@ def mapper(x: int):
assert False
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_map_subscription_cancel():
xs: rx.AsyncSubject[int] = rx.AsyncSubject()
sub: Optional[AsyncDisposable] = None
@@ -90,7 +91,7 @@ async def asend(value: int) -> None:
assert result == [100]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_mapi_works():
xs: AsyncObservable[int] = rx.from_iterable([1, 2, 3])
values: list[int] = []
diff --git a/tests/test_merge.py b/tests/test_merge.py
index e782ec1..37e6fcb 100644
--- a/tests/test_merge.py
+++ b/tests/test_merge.py
@@ -1,3 +1,4 @@
+import asyncio
import logging
import pytest
@@ -15,14 +16,16 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type: ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_merge_done():
xs: AsyncTestSubject[AsyncObservable[int]] = AsyncTestSubject()
@@ -38,7 +41,7 @@ async def test_merge_done():
assert obv.values == [(0, OnNext(10)), (0, OnNext(20)), (0, OnCompleted())]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_merge_streams():
xs: AsyncTestSubject[AsyncObservable[int]] = AsyncTestSubject()
s1: AsyncTestSubject[int] = AsyncTestSubject()
@@ -75,7 +78,7 @@ async def test_merge_streams():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_merge_streams_concat():
s1: AsyncTestSubject[int] = AsyncTestSubject()
s2 = rx.from_iterable([1, 2, 3])
diff --git a/tests/test_pipe.py b/tests/test_pipe.py
index 5c953c9..2ce7287 100644
--- a/tests/test_pipe.py
+++ b/tests/test_pipe.py
@@ -15,14 +15,16 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type: ignore
-def event_loop() -> Generator[VirtualTimeEventLoop, None, None]:
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_pipe_map() -> None:
xs = rx.from_iterable([1, 2, 3])
@@ -41,7 +43,7 @@ def mapper(value: int) -> int:
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_pipe_simple_pipe() -> None:
xs = rx.from_iterable([1, 2, 3])
@@ -63,7 +65,7 @@ async def predicate(value: int) -> bool:
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_pipe_complex_pipe() -> None:
xs = rx.from_iterable([1, 2, 3])
result: List[int] = []
diff --git a/tests/test_reduce.py b/tests/test_reduce.py
index 398227a..6343ea4 100644
--- a/tests/test_reduce.py
+++ b/tests/test_reduce.py
@@ -12,13 +12,13 @@ class MyException(Exception):
pass
-@pytest.fixture()
-def event_loop():
- loop = VirtualTimeEventLoop()
- try:
- yield loop
- finally:
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
def sync_sum(a: int, b: int) -> int:
@@ -30,7 +30,7 @@ async def async_sum(a: int, b: int) -> int:
return a + b
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_reduce():
xs = rx.from_iterable([1, 2, 3, 4])
observer = AsyncTestObserver()
@@ -44,7 +44,7 @@ async def test_reduce():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_reduce_async():
xs = rx.from_iterable([1, 2, 3, 4])
observer = AsyncTestObserver()
diff --git a/tests/test_scan.py b/tests/test_scan.py
index 0ed251f..6ffd61b 100644
--- a/tests/test_scan.py
+++ b/tests/test_scan.py
@@ -13,13 +13,13 @@ class MyException(Exception):
pass
-@pytest.fixture()
-def event_loop():
- loop = VirtualTimeEventLoop()
- try:
- yield loop
- finally:
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
def sync_sum(a: int, b: int) -> int:
@@ -31,7 +31,7 @@ async def async_sum(a: int, b: int) -> int:
return a + b
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_scan():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
@@ -54,7 +54,7 @@ async def test_scan():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_scan_async():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
diff --git a/tests/test_single.py b/tests/test_single.py
index e387a60..44b7b4b 100644
--- a/tests/test_single.py
+++ b/tests/test_single.py
@@ -14,14 +14,16 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type:ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_unit_happy():
xs = rx.single(42)
@@ -30,7 +32,7 @@ async def test_unit_happy():
assert obv.values == [(0, OnNext(42)), (0, OnCompleted())]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_unit_observer_throws():
error = Exception("error")
xs = rx.single(42)
@@ -48,7 +50,7 @@ async def asend(value: int) -> None:
assert obv.values == [(0, OnNext(42)), (0, OnError(error))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_unit_close():
xs = rx.single(42)
sub: Optional[AsyncDisposable] = None
@@ -69,7 +71,7 @@ async def asend(value: int) -> None:
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_unit_happy_resolved_future():
fut: Awaitable[int] = asyncio.Future()
xs = rx.from_async(fut)
@@ -83,7 +85,7 @@ async def test_unit_happy_resolved_future():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_unit_happy_future_resolve():
fut: Awaitable[int] = asyncio.Future()
xs = rx.from_async(fut)
@@ -99,7 +101,7 @@ async def test_unit_happy_future_resolve():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_unit_future_exception():
fut: Awaitable[int] = asyncio.Future()
ex = Exception("ex")
@@ -113,7 +115,7 @@ async def test_unit_future_exception():
assert obv.values == [(0, OnError(ex))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_unit_future_cancel():
fut: Awaitable[int] = asyncio.Future()
xs = rx.from_async(fut)
diff --git a/tests/test_single_stream.py b/tests/test_single_stream.py
index 262f538..c02e6f6 100644
--- a/tests/test_single_stream.py
+++ b/tests/test_single_stream.py
@@ -23,14 +23,16 @@ class MyException(Exception):
pass
-@pytest.fixture() # type: ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_happy():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
@@ -43,7 +45,7 @@ async def test_stream_happy():
assert sink.values == [(1, OnNext(10)), (2, OnNext(20)), (3, OnNext(30))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_throws():
ex = MyException("ex")
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
@@ -66,7 +68,7 @@ async def test_stream_throws():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_send_after_close():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
@@ -86,7 +88,7 @@ async def test_stream_send_after_close():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_cancel():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
sub = None
@@ -107,7 +109,7 @@ def mapper(value: int) -> int:
assert sink.values == [(1, OnNext(100))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_cancel_asend():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
sub: Optional[AsyncDisposable] = None
@@ -132,7 +134,7 @@ def mapper(value: int) -> int:
assert sink.values == [(1, OnNext(100))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_cancel_mapper():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
sub: Optional[AsyncDisposable] = None
@@ -155,7 +157,7 @@ async def mapper(value: int) -> int:
assert sink.values == [(1, OnNext(100))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_cancel_context():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
@@ -170,7 +172,7 @@ async def test_stream_cancel_context():
assert sink.values == []
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_cold_send():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
@@ -188,7 +190,7 @@ async def asend(value: int) -> None:
assert sink.values == [(10, OnNext(42)), (11, OnNext(20))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_cold_throw():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
error = MyException()
@@ -206,7 +208,7 @@ async def athrow():
assert sink.values == [(10, OnError(error))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_cold_close():
xs: AsyncTestSingleSubject[int] = AsyncTestSingleSubject()
diff --git a/tests/test_slice.py b/tests/test_slice.py
index c19ee66..48e4b35 100644
--- a/tests/test_slice.py
+++ b/tests/test_slice.py
@@ -1,3 +1,4 @@
+import asyncio
import logging
import pytest
@@ -11,14 +12,16 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type:ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_slice_special():
xs = AsyncRx.from_iterable([1, 2, 3, 4, 5])
@@ -36,7 +39,7 @@ async def test_slice_special():
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_slice_step():
xs = AsyncRx.from_iterable([1, 2, 3, 4, 5])
diff --git a/tests/test_stream.py b/tests/test_stream.py
index a068974..5c63b7c 100644
--- a/tests/test_stream.py
+++ b/tests/test_stream.py
@@ -3,7 +3,7 @@
from typing import Optional
import pytest
-from expression.core import pipe
+from expression import pipe
from expression.system.disposable import AsyncDisposable
import aioreactive as rx
@@ -22,14 +22,16 @@ class MyException(Exception):
pass
-@pytest.fixture() # type: ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_happy() -> None:
xs: AsyncTestSubject[int] = AsyncTestSubject()
@@ -42,7 +44,7 @@ async def test_stream_happy() -> None:
assert obv.values == [(1, OnNext(10)), (2, OnNext(20)), (3, OnNext(30))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_throws() -> None:
ex = MyException("ex")
xs: AsyncTestSubject[int] = AsyncTestSubject()
@@ -67,7 +69,7 @@ async def test_stream_throws() -> None:
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_send_after_close() -> None:
xs: AsyncTestSubject[int] = AsyncTestSubject()
@@ -88,7 +90,7 @@ async def test_stream_send_after_close() -> None:
]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module") # type: ignore
async def test_stream_cancel() -> None:
xs: AsyncTestSubject[int] = AsyncTestSubject()
subscription: Optional[AsyncDisposable] = None
@@ -107,7 +109,7 @@ def mapper(value: int) -> int:
assert obv.values == [(1, OnNext(100))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module") # type: ignore
async def test_stream_cancel_asend() -> None:
xs: AsyncTestSubject[int] = AsyncTestSubject()
subscription: Optional[AsyncDisposable] = None
@@ -132,7 +134,7 @@ def mapper(value: int) -> int:
assert obv.values == [(1, OnNext(100))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module") # type: ignore
async def test_stream_cancel_mapper():
xs: AsyncTestSubject[int] = AsyncTestSubject()
subscription: Optional[AsyncDisposable] = None
@@ -156,7 +158,7 @@ def mapper(value: int) -> int:
assert obv.values == [(100, OnNext(100))]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_stream_cancel_context():
xs: AsyncTestSubject[int] = AsyncTestSubject()
diff --git a/tests/test_take.py b/tests/test_take.py
index dc2b6a5..c95a0a4 100644
--- a/tests/test_take.py
+++ b/tests/test_take.py
@@ -1,3 +1,4 @@
+import asyncio
import logging
from asyncio import CancelledError
@@ -13,14 +14,16 @@
logging.basicConfig(level=logging.DEBUG)
-@pytest.fixture() # type:ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+
+@pytest.mark.asyncio(loop_scope="module")
async def test_take_zero() -> None:
xs = rx.from_iterable([1, 2, 3, 4, 5])
@@ -33,7 +36,7 @@ async def test_take_zero() -> None:
assert obv.values == [(0, OnCompleted())]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_take_empty() -> None:
xs: AsyncObservable[int] = rx.empty()
@@ -46,7 +49,7 @@ async def test_take_empty() -> None:
assert obv.values == [(0, OnCompleted())]
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_take_negative() -> None:
xs = rx.from_iterable([1, 2, 3, 4, 5])
@@ -54,7 +57,7 @@ async def test_take_negative() -> None:
pipe(xs, rx.take(-1))
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_take_normal() -> None:
xs = rx.from_iterable([1, 2, 3, 4, 5])
diff --git a/tests/test_with_latest_from.py b/tests/test_with_latest_from.py
index 3e39850..0a05269 100644
--- a/tests/test_with_latest_from.py
+++ b/tests/test_with_latest_from.py
@@ -8,7 +8,6 @@
import aioreactive as rx
from aioreactive.testing import (
AsyncTestObserver,
- AsyncTestSubject,
VirtualTimeEventLoop,
)
from aioreactive.types import AsyncObservable, AsyncObserver
@@ -16,15 +15,16 @@
log = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)
+class EventLoopPolicy(asyncio.DefaultEventLoopPolicy):
+ def get_event_loop(self) -> asyncio.AbstractEventLoop:
+ return VirtualTimeEventLoop()
-@pytest.fixture() # type: ignore
-def event_loop():
- loop = VirtualTimeEventLoop()
- yield loop
- loop.close()
+@pytest.fixture(scope="module") # type: ignore
+def event_loop_policy():
+ return EventLoopPolicy()
-@pytest.mark.asyncio
+@pytest.mark.asyncio(loop_scope="module")
async def test_withlatestfrom_never_never():
xs: AsyncObservable[int] = rx.never()
ys: AsyncObservable[int] = rx.never()