From c829640723d5a965f14ace1ab4fbad9735fb8dc8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 23:56:19 +0000 Subject: [PATCH 1/8] Bump the required group with 8 updates Bumps the required group with 8 updates: | Package | From | To | | --- | --- | --- | | [pydoclint](https://github.com/jsh9/pydoclint) | `0.5.6` | `0.5.9` | | [mkdocs-macros-plugin](https://github.com/fralau/mkdocs_macros_plugin) | `1.0.5` | `1.2.0` | | [mkdocs-material](https://github.com/squidfunk/mkdocs-material) | `9.5.34` | `9.5.39` | | [mkdocstrings[python]](https://github.com/mkdocstrings/mkdocstrings) | `0.26.0` | `0.26.1` | | [mkdocstrings-python](https://github.com/mkdocstrings/python) | `1.10.9` | `1.11.1` | | [pylint](https://github.com/pylint-dev/pylint) | `3.2.7` | `3.3.1` | | [hypothesis](https://github.com/HypothesisWorks/hypothesis) | `6.111.2` | `6.112.2` | | [pytest](https://github.com/pytest-dev/pytest) | `8.3.2` | `8.3.3` | Updates `pydoclint` from 0.5.6 to 0.5.9 - [Release notes](https://github.com/jsh9/pydoclint/releases) - [Changelog](https://github.com/jsh9/pydoclint/blob/main/CHANGELOG.md) - [Commits](https://github.com/jsh9/pydoclint/compare/0.5.6...0.5.9) Updates `mkdocs-macros-plugin` from 1.0.5 to 1.2.0 - [Release notes](https://github.com/fralau/mkdocs_macros_plugin/releases) - [Changelog](https://github.com/fralau/mkdocs-macros-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/fralau/mkdocs_macros_plugin/compare/v1.0.5...v1.2.0) Updates `mkdocs-material` from 9.5.34 to 9.5.39 - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.34...9.5.39) Updates `mkdocstrings[python]` from 0.26.0 to 0.26.1 - [Release notes](https://github.com/mkdocstrings/mkdocstrings/releases) - [Changelog](https://github.com/mkdocstrings/mkdocstrings/blob/main/CHANGELOG.md) - [Commits](https://github.com/mkdocstrings/mkdocstrings/compare/0.26.0...0.26.1) Updates `mkdocstrings-python` from 1.10.9 to 1.11.1 - [Release notes](https://github.com/mkdocstrings/python/releases) - [Changelog](https://github.com/mkdocstrings/python/blob/main/CHANGELOG.md) - [Commits](https://github.com/mkdocstrings/python/compare/1.10.9...1.11.1) Updates `pylint` from 3.2.7 to 3.3.1 - [Release notes](https://github.com/pylint-dev/pylint/releases) - [Commits](https://github.com/pylint-dev/pylint/compare/v3.2.7...v3.3.1) Updates `hypothesis` from 6.111.2 to 6.112.2 - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.111.2...hypothesis-python-6.112.2) Updates `pytest` from 8.3.2 to 8.3.3 - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.3.2...8.3.3) --- updated-dependencies: - dependency-name: pydoclint dependency-type: direct:production update-type: version-update:semver-patch dependency-group: required - dependency-name: mkdocs-macros-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: required - dependency-name: mkdocs-material dependency-type: direct:production update-type: version-update:semver-patch dependency-group: required - dependency-name: mkdocstrings[python] dependency-type: direct:production update-type: version-update:semver-patch dependency-group: required - dependency-name: mkdocstrings-python dependency-type: direct:production update-type: version-update:semver-minor dependency-group: required - dependency-name: pylint dependency-type: direct:production update-type: version-update:semver-minor dependency-group: required - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor dependency-group: required - dependency-name: pytest dependency-type: direct:production update-type: version-update:semver-patch dependency-group: required ... Signed-off-by: dependabot[bot] --- pyproject.toml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 12072ce0..2ee2c8c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,7 @@ dev-flake8 = [ "flake8 == 7.1.1", "flake8-docstrings == 1.7.0", "flake8-pyproject == 1.2.3", # For reading the flake8 config from pyproject.toml - "pydoclint == 0.5.6", + "pydoclint == 0.5.9", "pydocstyle == 6.3.0", ] dev-formatting = ["black == 24.8.0", "isort == 5.13.2"] @@ -54,10 +54,10 @@ dev-mkdocs = [ "mkdocs-gen-files == 0.5.0", "mkdocs-include-markdown-plugin == 6.2.2", "mkdocs-literate-nav == 0.6.1", - "mkdocs-macros-plugin == 1.0.5", - "mkdocs-material == 9.5.34", - "mkdocstrings[python] == 0.26.0", - "mkdocstrings-python == 1.10.9", + "mkdocs-macros-plugin == 1.2.0", + "mkdocs-material == 9.5.39", + "mkdocstrings[python] == 0.26.1", + "mkdocstrings-python == 1.11.1", "pymdownx-superfence-filter-lines == 0.1.0", ] dev-mypy = [ @@ -70,13 +70,13 @@ dev-noxfile = ["nox == 2024.4.15", "frequenz-repo-config[lib] == 0.10.0"] dev-pylint = [ # For checking the noxfile, docs/ script, and tests "frequenz-channels[dev-mkdocs,dev-noxfile,dev-pytest]", - "pylint == 3.2.7", + "pylint == 3.3.1", ] dev-pytest = [ "async-solipsism == 0.7", "frequenz-repo-config[extra-lint-examples] == 0.10.0", - "hypothesis == 6.111.2", - "pytest == 8.3.2", + "hypothesis == 6.112.2", + "pytest == 8.3.3", "pytest-asyncio == 0.24.0", "pytest-mock == 3.14.0", ] From 90896d63e669592a9d74749cdae2bc198ccc76f1 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Wed, 9 Oct 2024 10:51:39 +0200 Subject: [PATCH 2/8] Remove exceptions that are not actually raised from the docs Signed-off-by: Leandro Lucarella --- src/frequenz/channels/_anycast.py | 1 - src/frequenz/channels/_merge.py | 1 - src/frequenz/channels/_receiver.py | 1 - 3 files changed, 3 deletions(-) diff --git a/src/frequenz/channels/_anycast.py b/src/frequenz/channels/_anycast.py index 2ea05156..d08efc4e 100644 --- a/src/frequenz/channels/_anycast.py +++ b/src/frequenz/channels/_anycast.py @@ -425,7 +425,6 @@ def consume(self) -> _T: Raises: ReceiverStoppedError: If the receiver stopped producing messages. - ReceiverError: If there is some problem with the receiver. """ if ( # pylint: disable=protected-access self._next is _Empty and self._channel._closed diff --git a/src/frequenz/channels/_merge.py b/src/frequenz/channels/_merge.py index 6be43025..3a306dbb 100644 --- a/src/frequenz/channels/_merge.py +++ b/src/frequenz/channels/_merge.py @@ -179,7 +179,6 @@ def consume(self) -> ReceiverMessageT_co: Raises: ReceiverStoppedError: If the receiver stopped producing messages. - ReceiverError: If there is some problem with the receiver. """ if not self._results and not self._pending: raise ReceiverStoppedError(self) diff --git a/src/frequenz/channels/_receiver.py b/src/frequenz/channels/_receiver.py index c01c8102..47b4e8fd 100644 --- a/src/frequenz/channels/_receiver.py +++ b/src/frequenz/channels/_receiver.py @@ -450,7 +450,6 @@ def consume(self) -> ReceiverMessageT_co: Raises: ReceiverStoppedError: If the receiver stopped producing messages. - ReceiverError: If there is a problem with the receiver. """ if self._recv_closed: raise ReceiverStoppedError(self) From b77667012f299f9d51fe63b3aa4330b0534eb079 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Wed, 9 Oct 2024 10:55:41 +0200 Subject: [PATCH 3/8] Add some `noqa` for exceptions we raise indirectly There is a new check in `pydoclint` that checks all exceptions in the docs are actually raised directly in the function body, but we sometimes want to document exceptions raised indirectly too. Signed-off-by: Leandro Lucarella --- src/frequenz/channels/_receiver.py | 8 ++++++-- src/frequenz/channels/_select.py | 10 ++++++++-- src/frequenz/channels/timer.py | 6 ++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/frequenz/channels/_receiver.py b/src/frequenz/channels/_receiver.py index 47b4e8fd..121f189b 100644 --- a/src/frequenz/channels/_receiver.py +++ b/src/frequenz/channels/_receiver.py @@ -164,7 +164,9 @@ class Receiver(ABC, Generic[ReceiverMessageT_co]): """An endpoint to receive messages.""" - async def __anext__(self) -> ReceiverMessageT_co: + # We need the noqa here because ReceiverError can be raised by ready() and consume() + # implementations. + async def __anext__(self) -> ReceiverMessageT_co: # noqa: DOC503 """Await the next message in the async iteration over received messages. Returns: @@ -215,7 +217,9 @@ def __aiter__(self) -> Self: """ return self - async def receive(self) -> ReceiverMessageT_co: + # We need the noqa here because ReceiverError can be raised by consume() + # implementations. + async def receive(self) -> ReceiverMessageT_co: # noqa: DOC503 """Receive a message. Returns: diff --git a/src/frequenz/channels/_select.py b/src/frequenz/channels/_select.py index e8b6e803..41da79ba 100644 --- a/src/frequenz/channels/_select.py +++ b/src/frequenz/channels/_select.py @@ -196,8 +196,10 @@ def __init__(self, receiver: Receiver[ReceiverMessageT_co], /) -> None: self._handled: bool = False """Flag to indicate if this selected has been handled in the if-chain.""" + # We need the noqa here because pydoclint can't figure out raise self._exception + # actually raise an Exception. @property - def message(self) -> ReceiverMessageT_co: + def message(self) -> ReceiverMessageT_co: # noqa: DOC503 """The message that was received, if any. Returns: @@ -339,7 +341,11 @@ def __init__(self, selected: Selected[ReceiverMessageT_co]) -> None: # https://github.com/python/mypy/issues/13597 -async def select(*receivers: Receiver[Any]) -> AsyncIterator[Selected[Any]]: +# We need the noqa here because BaseExceptionGroup can be raised indirectly by +# _stop_pending_tasks. +async def select( # noqa: DOC503 + *receivers: Receiver[Any], +) -> AsyncIterator[Selected[Any]]: """Iterate over the messages of all receivers as they receive new messages. This function is used to iterate over the messages of all receivers as they receive diff --git a/src/frequenz/channels/timer.py b/src/frequenz/channels/timer.py index b2f0338a..b695fb64 100644 --- a/src/frequenz/channels/timer.py +++ b/src/frequenz/channels/timer.py @@ -466,7 +466,8 @@ class Timer(Receiver[timedelta]): depending on the chosen policy. """ - def __init__( # pylint: disable=too-many-arguments + # We need the noqa here because RuntimeError is raised indirectly. + def __init__( # noqa: DOC503 pylint: disable=too-many-arguments self, interval: timedelta, missed_tick_policy: MissedTickPolicy, @@ -586,7 +587,8 @@ def is_running(self) -> bool: """Whether the timer is running.""" return not self._stopped - def reset( + # We need the noqa here because RuntimeError is raised indirectly. + def reset( # noqa: DOC503 self, *, interval: timedelta | None = None, From a427b2bdd356bb75dbf4a823ee4d065c91ec146c Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Wed, 9 Oct 2024 10:57:17 +0200 Subject: [PATCH 4/8] Import symbols in the top-level namespace Some tools are not smart enough to do proper semantic analysis. That is the case for `pydoclint`, so it can't figure out that `_receiver.ReceiverStoppedError` is what we want to document. To make things simpler we just import the individual symbols to the top-level namespace. Signed-off-by: Leandro Lucarella --- src/frequenz/channels/event.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/frequenz/channels/event.py b/src/frequenz/channels/event.py index 3f3b207a..0d599e89 100644 --- a/src/frequenz/channels/event.py +++ b/src/frequenz/channels/event.py @@ -16,10 +16,10 @@ import asyncio as _asyncio -from frequenz.channels import _receiver +from frequenz.channels._receiver import Receiver, ReceiverStoppedError -class Event(_receiver.Receiver[None]): +class Event(Receiver[None]): """A receiver that can be made ready directly. # Usage @@ -161,7 +161,7 @@ def consume(self) -> None: ReceiverStoppedError: If this receiver is stopped. """ if not self._is_set and self._is_stopped: - raise _receiver.ReceiverStoppedError(self) + raise ReceiverStoppedError(self) assert self._is_set, "calls to `consume()` must be follow a call to `ready()`" From 010506de4cce2dbad5b5454f21f1dd764dc274b8 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Wed, 9 Oct 2024 10:58:23 +0200 Subject: [PATCH 5/8] Use `anext()` instead of `__anext__()` `pylint` doesn't like calling dunder methods explicitly and `anext()` was added in Python 3.10. Since we depend on Python 3.11 we can just use `anext()` and make `pylint` happy. Signed-off-by: Leandro Lucarella --- src/frequenz/channels/_receiver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frequenz/channels/_receiver.py b/src/frequenz/channels/_receiver.py index 121f189b..7ab132ff 100644 --- a/src/frequenz/channels/_receiver.py +++ b/src/frequenz/channels/_receiver.py @@ -230,7 +230,7 @@ async def receive(self) -> ReceiverMessageT_co: # noqa: DOC503 ReceiverError: If there is some problem with the receiver. """ try: - received = await self.__anext__() # pylint: disable=unnecessary-dunder-call + received = await anext(self) except StopAsyncIteration as exc: # If we already had a cause and it was the receiver was stopped, # then reuse that error, as StopAsyncIteration is just an artifact From 94059c811d5f325372364fcd734c17b595e6f28a Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Wed, 9 Oct 2024 10:59:29 +0200 Subject: [PATCH 6/8] Remove unnecessary `pylint: disable=no-member` This rule is now disabled globally, as it is already checked by `mypy` and `pylint` have some false positives, like this one. Signed-off-by: Leandro Lucarella --- src/frequenz/channels/_receiver.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/frequenz/channels/_receiver.py b/src/frequenz/channels/_receiver.py index 7ab132ff..fbe17efb 100644 --- a/src/frequenz/channels/_receiver.py +++ b/src/frequenz/channels/_receiver.py @@ -237,10 +237,7 @@ async def receive(self) -> ReceiverMessageT_co: # noqa: DOC503 # introduced by __anext__. if ( isinstance(exc.__cause__, ReceiverStoppedError) - # pylint is not smart enough to figure out we checked above - # this is a ReceiverStoppedError and thus it does have - # a receiver member - and exc.__cause__.receiver is self # pylint: disable=no-member + and exc.__cause__.receiver is self ): raise exc.__cause__ raise ReceiverStoppedError(self) from exc From 1b538bdda6da6105c7eb6c6c49c0e5a359df1784 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Wed, 9 Oct 2024 11:09:26 +0200 Subject: [PATCH 7/8] Ignore new pylint check in benchmark function Signed-off-by: Leandro Lucarella --- benchmarks/benchmark_broadcast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/benchmark_broadcast.py b/benchmarks/benchmark_broadcast.py index 08181dfc..218fbe4a 100644 --- a/benchmarks/benchmark_broadcast.py +++ b/benchmarks/benchmark_broadcast.py @@ -141,7 +141,7 @@ def time_async_task(task: Coroutine[Any, Any, int]) -> tuple[float, Any]: return timeit.default_timer() - start, ret -# pylint: disable=too-many-arguments +# pylint: disable=too-many-arguments,too-many-positional-arguments def run_one( benchmark_method: Callable[[int, int, int], Coroutine[Any, Any, int]], num_channels: int, From 8ddc919dbf34f03d983ca7df59ea4ea458e68662 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Wed, 9 Oct 2024 11:09:48 +0200 Subject: [PATCH 8/8] Ignore new pylint false positive Signed-off-by: Leandro Lucarella --- src/frequenz/channels/_receiver.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/frequenz/channels/_receiver.py b/src/frequenz/channels/_receiver.py index fbe17efb..13a79481 100644 --- a/src/frequenz/channels/_receiver.py +++ b/src/frequenz/channels/_receiver.py @@ -239,7 +239,9 @@ async def receive(self) -> ReceiverMessageT_co: # noqa: DOC503 isinstance(exc.__cause__, ReceiverStoppedError) and exc.__cause__.receiver is self ): - raise exc.__cause__ + # This is a false positive, we are actually checking __cause__ is a + # ReceiverStoppedError which is an exception. + raise exc.__cause__ # pylint: disable=raising-non-exception raise ReceiverStoppedError(self) from exc return received