From fa747fce2f4e06931f31bc98e8d522e48ce52b55 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2024 18:08:27 +0000 Subject: [PATCH 1/4] Bump the required group across 1 directory with 12 updates Bumps the required group with 12 updates in the / directory: | Package | From | To | | --- | --- | --- | | [pydoclint](https://github.com/jsh9/pydoclint) | `0.5.6` | `0.5.9` | | [black](https://github.com/psf/black) | `24.8.0` | `24.10.0` | | [mkdocs-macros-plugin](https://github.com/fralau/mkdocs_macros_plugin) | `1.0.5` | `1.3.7` | | [mkdocs-material](https://github.com/squidfunk/mkdocs-material) | `9.5.34` | `9.5.43` | | [mkdocstrings[python]](https://github.com/mkdocstrings/mkdocstrings) | `0.25.2` | `0.26.2` | | [mkdocstrings-python](https://github.com/mkdocstrings/python) | `1.10.9` | `1.12.2` | | [mypy](https://github.com/python/mypy) | `1.11.2` | `1.13.0` | | [types-protobuf](https://github.com/python/typeshed) | `5.27.0.20240626` | `5.28.3.20241030` | | [nox](https://github.com/wntrblm/nox) | `2024.4.15` | `2024.10.9` | | [pylint](https://github.com/pylint-dev/pylint) | `3.2.7` | `3.3.1` | | [pytest](https://github.com/pytest-dev/pytest) | `8.3.2` | `8.3.3` | | [hypothesis](https://github.com/HypothesisWorks/hypothesis) | `6.111.2` | `6.116.0` | 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 `black` from 24.8.0 to 24.10.0 - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/24.8.0...24.10.0) Updates `mkdocs-macros-plugin` from 1.0.5 to 1.3.7 - [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.3.7) Updates `mkdocs-material` from 9.5.34 to 9.5.43 - [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.43) Updates `mkdocstrings[python]` from 0.25.2 to 0.26.2 - [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.25.2...0.26.2) Updates `mkdocstrings-python` from 1.10.9 to 1.12.2 - [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.12.2) Updates `mypy` from 1.11.2 to 1.13.0 - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.11.2...v1.13.0) Updates `types-protobuf` from 5.27.0.20240626 to 5.28.3.20241030 - [Commits](https://github.com/python/typeshed/commits) Updates `nox` from 2024.4.15 to 2024.10.9 - [Release notes](https://github.com/wntrblm/nox/releases) - [Changelog](https://github.com/wntrblm/nox/blob/main/CHANGELOG.md) - [Commits](https://github.com/wntrblm/nox/compare/2024.04.15...2024.10.09) 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 `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) Updates `hypothesis` from 6.111.2 to 6.116.0 - [Release notes](https://github.com/HypothesisWorks/hypothesis/releases) - [Commits](https://github.com/HypothesisWorks/hypothesis/compare/hypothesis-python-6.111.2...hypothesis-python-6.116.0) --- updated-dependencies: - dependency-name: pydoclint dependency-type: direct:production update-type: version-update:semver-patch dependency-group: required - dependency-name: black dependency-type: direct:production update-type: version-update:semver-minor 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-minor dependency-group: required - dependency-name: mkdocstrings-python dependency-type: direct:production update-type: version-update:semver-minor dependency-group: required - dependency-name: mypy dependency-type: direct:production update-type: version-update:semver-minor dependency-group: required - dependency-name: types-protobuf dependency-type: direct:production update-type: version-update:semver-minor dependency-group: required - dependency-name: nox 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: pytest dependency-type: direct:production update-type: version-update:semver-patch dependency-group: required - dependency-name: hypothesis dependency-type: direct:production update-type: version-update:semver-minor dependency-group: required ... Signed-off-by: dependabot[bot] --- pyproject.toml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d5e1e0577..4678f17d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,44 +47,44 @@ 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"] +dev-formatting = ["black == 24.10.0", "isort == 5.13.2"] dev-mkdocs = [ - "black == 24.8.0", + "black == 24.10.0", "Markdown==3.7", "mike == 2.1.3", "mkdocs-gen-files == 0.5.0", "mkdocs-literate-nav == 0.6.1", - "mkdocs-macros-plugin == 1.0.5", - "mkdocs-material == 9.5.34", - "mkdocstrings[python] == 0.25.2", - "mkdocstrings-python == 1.10.9", + "mkdocs-macros-plugin == 1.3.7", + "mkdocs-material == 9.5.43", + "mkdocstrings[python] == 0.26.2", + "mkdocstrings-python == 1.12.2", "frequenz-repo-config[lib] == 0.10.0", ] dev-mypy = [ - "mypy == 1.11.2", + "mypy == 1.13.0", "types-Markdown == 3.7.0.20240822", - "types-protobuf == 5.27.0.20240626", + "types-protobuf == 5.28.3.20241030", "types-setuptools == 74.0.0.20240831", # For checking the noxfile, docs/ script, and tests "frequenz-sdk[dev-mkdocs,dev-noxfile,dev-pytest]", ] -dev-noxfile = ["nox == 2024.4.15", "frequenz-repo-config[lib] == 0.10.0"] +dev-noxfile = ["nox == 2024.10.9", "frequenz-repo-config[lib] == 0.10.0"] dev-pylint = [ - "pylint == 3.2.7", + "pylint == 3.3.1", # For checking the noxfile, docs/ script, and tests "frequenz-sdk[dev-mkdocs,dev-noxfile,dev-pytest]", ] dev-pytest = [ - "pytest == 8.3.2", + "pytest == 8.3.3", "frequenz-repo-config[extra-lint-examples] == 0.10.0", "pytest-mock == 3.14.0", "pytest-asyncio == 0.24.0", "time-machine == 2.12.0", "async-solipsism == 0.7", - "hypothesis == 6.111.2", + "hypothesis == 6.116.0", ] dev = [ "frequenz-sdk[dev-mkdocs,dev-flake8,dev-formatting,dev-mkdocs,dev-mypy,dev-noxfile,dev-pylint,dev-pytest]", From 5ee9a7831a40926c60a141cbb260f90d62565ef1 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Mon, 4 Nov 2024 19:14:35 +0100 Subject: [PATCH 2/4] Make the `MovingWindow` constructor keyword-only The `MovingWindow` constructor now takes all arguments as keyword-only to avoid mistakes, such as confusing the `size` with the `input_sampling_period`. Signed-off-by: Leandro Lucarella --- RELEASE_NOTES.md | 2 ++ benchmarks/timeseries/periodic_feature_extractor.py | 4 +++- src/frequenz/sdk/timeseries/_moving_window.py | 2 +- tests/timeseries/test_moving_window.py | 6 +++++- tests/timeseries/test_periodic_feature_extractor.py | 4 +++- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index c00209dc5..d509bf132 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -15,6 +15,8 @@ actor = ConfigManagingActor(config_files=["config.toml"]) ``` +* The `MovingWindow` now take all arguments as keyword-only to avoid mistakes. + ## New Features - The `ConfigManagingActor` can now take multiple configuration files as input, allowing to override default configurations with custom configurations. diff --git a/benchmarks/timeseries/periodic_feature_extractor.py b/benchmarks/timeseries/periodic_feature_extractor.py index 9a5bc765e..2b6c947e8 100644 --- a/benchmarks/timeseries/periodic_feature_extractor.py +++ b/benchmarks/timeseries/periodic_feature_extractor.py @@ -35,7 +35,9 @@ async def init_feature_extractor( # We only need the moving window to initialize the PeriodicFeatureExtractor class. lm_chan = Broadcast[Sample[Quantity]](name="lm_net_power") async with MovingWindow( - timedelta(seconds=1), lm_chan.new_receiver(), timedelta(seconds=1) + size=timedelta(seconds=1), + resampled_data_recv=lm_chan.new_receiver(), + input_sampling_period=timedelta(seconds=1), ) as moving_window: await lm_chan.new_sender().send( Sample(datetime.now(tz=timezone.utc), Quantity(0)) diff --git a/src/frequenz/sdk/timeseries/_moving_window.py b/src/frequenz/sdk/timeseries/_moving_window.py index c1cefb9de..73069b1db 100644 --- a/src/frequenz/sdk/timeseries/_moving_window.py +++ b/src/frequenz/sdk/timeseries/_moving_window.py @@ -130,12 +130,12 @@ async def run() -> None: def __init__( # pylint: disable=too-many-arguments self, + *, size: timedelta, resampled_data_recv: Receiver[Sample[Quantity]], input_sampling_period: timedelta, resampler_config: ResamplerConfig | None = None, align_to: datetime = UNIX_EPOCH, - *, name: str | None = None, ) -> None: """ diff --git a/tests/timeseries/test_moving_window.py b/tests/timeseries/test_moving_window.py index f1ae49673..3f0e4cd56 100644 --- a/tests/timeseries/test_moving_window.py +++ b/tests/timeseries/test_moving_window.py @@ -59,7 +59,11 @@ def init_moving_window( """ lm_chan = Broadcast[Sample[Quantity]](name="lm_net_power") lm_tx = lm_chan.new_sender() - window = MovingWindow(size, lm_chan.new_receiver(), timedelta(seconds=1)) + window = MovingWindow( + size=size, + resampled_data_recv=lm_chan.new_receiver(), + input_sampling_period=timedelta(seconds=1), + ) return window, lm_tx diff --git a/tests/timeseries/test_periodic_feature_extractor.py b/tests/timeseries/test_periodic_feature_extractor.py index a298b0324..79484fe66 100644 --- a/tests/timeseries/test_periodic_feature_extractor.py +++ b/tests/timeseries/test_periodic_feature_extractor.py @@ -60,7 +60,9 @@ async def init_feature_extractor_no_data( # We only need the moving window to initialize the PeriodicFeatureExtractor class. lm_chan = Broadcast[Sample[Quantity]](name="lm_net_power") moving_window = MovingWindow( - timedelta(seconds=1), lm_chan.new_receiver(), timedelta(seconds=1) + size=timedelta(seconds=1), + resampled_data_recv=lm_chan.new_receiver(), + input_sampling_period=timedelta(seconds=1), ) async with moving_window: await lm_chan.new_sender().send( From a3fe218ff7277229fb6eb2e64323c18ab83cf624 Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Mon, 4 Nov 2024 19:17:32 +0100 Subject: [PATCH 3/4] Fix the new pydoclint check DOC503 This check verifies that the `Raises` section of a method docstring contains the same exception types present in `raise` statements in the code. Some checks were correctly failing because of wrong documentation or typos, but some fail only because `pydoclint` is not smart enough to figure out the type of variables, so one must always have `raise ExceptionType` in the code to make the check pass. It also fails when the exception is raised indirectly, but we want to document it anyways, for example if raised by some utility function or private method. For cases where this is possible, the code was changed to do explicit `raise ExceptionType`, for other cases the check is simply disabled. In other cases a `raise` was replaced with an `assert_never` to make the check pass and also make sure a failure is detected by `mypy` instead of at runtime. Signed-off-by: Leandro Lucarella --- src/frequenz/sdk/_internal/_channels.py | 6 +++--- src/frequenz/sdk/actor/_background_service.py | 4 +++- src/frequenz/sdk/timeseries/_moving_window.py | 19 +++++++++++-------- src/frequenz/sdk/timeseries/_resampling.py | 4 +++- .../_battery_power_formula.py | 5 ++--- .../_consumer_power_formula.py | 3 ++- tests/actor/test_run_utils.py | 2 +- .../_battery_pool/test_battery_pool.py | 13 +++++++------ tests/utils/mock_microgrid_client.py | 4 +++- 9 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/frequenz/sdk/_internal/_channels.py b/src/frequenz/sdk/_internal/_channels.py index eabd26892..74b2f6929 100644 --- a/src/frequenz/sdk/_internal/_channels.py +++ b/src/frequenz/sdk/_internal/_channels.py @@ -153,7 +153,7 @@ def get_or_create(self, message_type: type[T], key: str) -> Broadcast[T]: entry = self._channels[key] if entry.message_type is not message_type: - exception = ValueError( + error_message = ( f"Type mismatch, a channel for key {key!r} exists and the requested " f"message type {message_type} is not the same as the existing " f"message type {entry.message_type}." @@ -161,12 +161,12 @@ def get_or_create(self, message_type: type[T], key: str) -> Broadcast[T]: if _logger.isEnabledFor(logging.DEBUG): _logger.debug( "%s at:\n%s", - str(exception), + error_message, # We skip the last frame because it's this method, and limit the # stack to 9 frames to avoid adding too much noise. "".join(traceback.format_stack(limit=10)[:9]), ) - raise exception + raise ValueError(error_message) return typing.cast(Broadcast[T], entry.channel) diff --git a/src/frequenz/sdk/actor/_background_service.py b/src/frequenz/sdk/actor/_background_service.py index 6e6587094..2d44d2afe 100644 --- a/src/frequenz/sdk/actor/_background_service.py +++ b/src/frequenz/sdk/actor/_background_service.py @@ -129,7 +129,9 @@ def cancel(self, msg: str | None = None) -> None: for task in self._tasks: task.cancel(msg) - async def stop(self, msg: str | None = None) -> None: + # We need the noqa because pydoclint can't figure out `rest` is + # a `BaseExceptionGroup` instance. + async def stop(self, msg: str | None = None) -> None: # noqa: DOC503 """Stop this background service. This method cancels all running tasks spawned by this service and waits for them diff --git a/src/frequenz/sdk/timeseries/_moving_window.py b/src/frequenz/sdk/timeseries/_moving_window.py index 73069b1db..4ed8e52ee 100644 --- a/src/frequenz/sdk/timeseries/_moving_window.py +++ b/src/frequenz/sdk/timeseries/_moving_window.py @@ -9,7 +9,7 @@ import math from collections.abc import Sequence from datetime import datetime, timedelta -from typing import SupportsIndex, overload +from typing import SupportsIndex, assert_never, overload import numpy as np from frequenz.channels import Broadcast, Receiver, Sender @@ -282,7 +282,7 @@ def at(self, key: int | datetime) -> float: # pylint: disable=invalid-name assert timestamp is not None return self._buffer[self._buffer.to_internal_index(timestamp)] - raise TypeError("Key has to be either a timestamp or an integer.") + assert_never(key) def window( self, @@ -385,7 +385,10 @@ def __getitem__(self, key: datetime) -> float: def __getitem__(self, key: slice) -> ArrayLike: """See the main __getitem__ method.""" - def __getitem__(self, key: SupportsIndex | datetime | slice) -> float | ArrayLike: + # We need the noqa because `IndexError` is raised indirectly by `at()` and `window()` + def __getitem__( # noqa: DOC503 + self, key: SupportsIndex | datetime | slice + ) -> float | ArrayLike: """ Return a sub window of the `MovingWindow`. @@ -400,12 +403,15 @@ def __getitem__(self, key: SupportsIndex | datetime | slice) -> float | ArrayLik where the bounds correspond to the slice bounds. Note that a half open interval, which is open at the end, is returned. + Note: + Slicing with a step other than 1 is not supported. + Args: key: Either an integer or a timestamp or a slice of timestamps or integers. Raises: IndexError: when requesting an out of range timestamp or index - TypeError: when the key is not a datetime or slice object. + ValueError: when requesting a slice with a step other than 1 Returns: A float if the key is a number or a timestamp. @@ -422,10 +428,7 @@ def __getitem__(self, key: SupportsIndex | datetime | slice) -> float | ArrayLik if isinstance(key, SupportsIndex): return self.at(key.__index__()) - raise TypeError( - "Key has to be either a timestamp or an integer " - "or a slice of timestamps or integers" - ) + assert_never(key) # We need to register the class as a subclass of Sequence like this because diff --git a/src/frequenz/sdk/timeseries/_resampling.py b/src/frequenz/sdk/timeseries/_resampling.py index c23dc0888..07c06361f 100644 --- a/src/frequenz/sdk/timeseries/_resampling.py +++ b/src/frequenz/sdk/timeseries/_resampling.py @@ -801,7 +801,9 @@ async def _receive_samples(self) -> None: if sample.value is not None and not sample.value.isnan(): self._helper.add_sample(sample) - async def resample(self, timestamp: datetime) -> None: + # We need the noqa because pydoclint can't figure out that `recv_exception` is an + # `Exception` instance. + async def resample(self, timestamp: datetime) -> None: # noqa: DOC503 """Calculate a new sample for the passed `timestamp` and send it. The helper is used to calculate the new sample and the sender is used diff --git a/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_battery_power_formula.py b/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_battery_power_formula.py index 6080d9932..f011570c0 100644 --- a/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_battery_power_formula.py +++ b/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_battery_power_formula.py @@ -44,9 +44,8 @@ def generate( ComponentNotFound: if there are no batteries in the component graph, or if they don't have an inverter as a predecessor. FormulaGenerationError: If a battery has a non-inverter predecessor - in the component graph. - FormulaGenerationError: If not all batteries behind a set of inverters - have been requested. + in the component graph, or if not all batteries behind a set of + inverters have been requested. """ builder = self._get_builder( "battery-power", ComponentMetricId.ACTIVE_POWER, Power.from_watts diff --git a/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_consumer_power_formula.py b/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_consumer_power_formula.py index 618b0f928..8e302ece2 100644 --- a/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_consumer_power_formula.py +++ b/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_consumer_power_formula.py @@ -49,7 +49,8 @@ def _are_grid_meters(self, grid_successors: set[Component]) -> bool: for successor in grid_successors ) - def generate(self) -> FormulaEngine[Power]: + # We need the noqa here because `RuntimeError` is raised indirectly + def generate(self) -> FormulaEngine[Power]: # noqa: DOC503 """Generate formula for calculating consumer power from the component graph. Returns: diff --git a/tests/actor/test_run_utils.py b/tests/actor/test_run_utils.py index f56a380f9..38cc8be48 100644 --- a/tests/actor/test_run_utils.py +++ b/tests/actor/test_run_utils.py @@ -35,7 +35,7 @@ async def _run(self) -> None: """Run the faulty actor. Raises: - CancelledError: the exception causes the actor to be cancelled + asyncio.CancelledError: the exception causes the actor to be cancelled """ self.is_cancelled = True raise asyncio.CancelledError(f"Faulty Actor {self.name} failed") diff --git a/tests/timeseries/_battery_pool/test_battery_pool.py b/tests/timeseries/_battery_pool/test_battery_pool.py index df5191e49..cdb4d3aa6 100644 --- a/tests/timeseries/_battery_pool/test_battery_pool.py +++ b/tests/timeseries/_battery_pool/test_battery_pool.py @@ -263,7 +263,7 @@ async def run_scenarios( Raises: TimeoutError: If metric update was not received. - AssertError: If received metric is not as expected. + AssertionError: If received metric is not as expected. """ for idx, scenario in enumerate(scenarios): # Update data stream @@ -278,9 +278,9 @@ async def run_scenarios( # Wait for result and check if received expected message try: msg = await asyncio.wait_for(receiver.receive(), timeout=waiting_time_sec) - except TimeoutError as err: + except TimeoutError: _logger.error("Test scenario %d failed with timeout error.", idx) - raise err + raise if scenario.expected_result is None: assert msg is None @@ -288,9 +288,9 @@ async def run_scenarios( try: compare_messages(msg, scenario.expected_result) - except AssertionError as err: + except AssertionError: _logger.error("Test scenario: %d failed.", idx) - raise err + raise async def test_all_batteries_capacity( @@ -404,7 +404,8 @@ def compare_messages(msg: Any, expected_msg: Any) -> None: assert msg_dict == expected_dict -async def run_test_battery_status_channel( # pylint: disable=too-many-arguments +# pylint: disable-next=too-many-arguments,too-many-positional-arguments +async def run_test_battery_status_channel( battery_status_sender: Sender[ComponentPoolStatus], battery_pool_metric_receiver: Receiver[T], all_batteries: set[int], diff --git a/tests/utils/mock_microgrid_client.py b/tests/utils/mock_microgrid_client.py index d72973b80..902bcdd0c 100644 --- a/tests/utils/mock_microgrid_client.py +++ b/tests/utils/mock_microgrid_client.py @@ -126,7 +126,8 @@ def component_graph(self) -> ComponentGraph: """ return self._component_graph - async def send(self, data: ComponentData) -> None: + # We need the noqa because the `SenderError` is raised indirectly by `send()`. + async def send(self, data: ComponentData) -> None: # noqa: DOC503 """Send component data using channel. This simulates component sending data. Right now only battery and inverter @@ -136,6 +137,7 @@ async def send(self, data: ComponentData) -> None: data: Data to be send Raises: + RuntimeError: if the type of data is not supported. SenderError: if the underlying channel was closed. A [ChannelClosedError][frequenz.channels.ChannelClosedError] is set as the cause. From 483b4ced621bc710bd87b4acd6d945c82843b76f Mon Sep 17 00:00:00 2001 From: Leandro Lucarella Date: Mon, 4 Nov 2024 19:22:35 +0100 Subject: [PATCH 4/4] Fix the new `too-many-positional-arguments` pylint errors When appropriate, we just make arguments keyword-only, which is a good practice anyway. For tests, in general we just disabled the check. Signed-off-by: Leandro Lucarella --- .../_component_pool_status_tracker.py | 1 + .../_battery_status_tracker.py | 1 + .../_component_status/_component_status.py | 1 + .../_ev_charger_status_tracker.py | 1 + .../_pv_inverter_status_tracker.py | 1 + .../_battery_distribution_algorithm.py | 13 ++++- .../_power_managing/_power_managing_actor.py | 2 +- .../_battery_pool_reference_store.py | 1 + .../_ev_charger_pool_reference_store.py | 1 + .../formula_engine/_formula_engine_pool.py | 12 ++--- .../_formula_generators/_formula_generator.py | 12 ++--- .../_resampled_formula_builder.py | 1 + .../pv_pool/_pv_pool_reference_store.py | 1 + .../actor/_power_managing/test_matryoshka.py | 2 +- .../_component_status/test_battery_status.py | 16 +++---- .../test_battery_distribution_algorithm.py | 48 +++++++++++++++---- tests/timeseries/_formula_engine/utils.py | 12 ++--- tests/timeseries/mock_microgrid.py | 2 +- tests/timeseries/mock_resampler.py | 2 +- .../test_periodic_feature_extractor.py | 2 +- tests/timeseries/test_resampling.py | 3 +- tests/utils/component_data_wrapper.py | 11 +++-- 22 files changed, 100 insertions(+), 46 deletions(-) diff --git a/src/frequenz/sdk/microgrid/_power_distributing/_component_pool_status_tracker.py b/src/frequenz/sdk/microgrid/_power_distributing/_component_pool_status_tracker.py index 09b18226e..c0aed7e2d 100644 --- a/src/frequenz/sdk/microgrid/_power_distributing/_component_pool_status_tracker.py +++ b/src/frequenz/sdk/microgrid/_power_distributing/_component_pool_status_tracker.py @@ -33,6 +33,7 @@ class ComponentPoolStatusTracker: def __init__( # pylint: disable=too-many-arguments self, + *, component_ids: abc.Set[int], component_status_sender: Sender[ComponentPoolStatus], max_data_age: timedelta, diff --git a/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_battery_status_tracker.py b/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_battery_status_tracker.py index bbc5161f0..dd181827c 100644 --- a/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_battery_status_tracker.py +++ b/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_battery_status_tracker.py @@ -99,6 +99,7 @@ class BatteryStatusTracker(ComponentStatusTracker, BackgroundService): @override def __init__( # pylint: disable=too-many-arguments self, + *, component_id: int, max_data_age: timedelta, max_blocking_duration: timedelta, diff --git a/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_component_status.py b/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_component_status.py index 34d5c5078..ce34befc5 100644 --- a/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_component_status.py +++ b/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_component_status.py @@ -85,6 +85,7 @@ class ComponentStatusTracker(BackgroundService, ABC): @abstractmethod def __init__( # pylint: disable=too-many-arguments,super-init-not-called self, + *, component_id: int, max_data_age: timedelta, max_blocking_duration: timedelta, diff --git a/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_ev_charger_status_tracker.py b/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_ev_charger_status_tracker.py index 5285239dd..48fe2478b 100644 --- a/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_ev_charger_status_tracker.py +++ b/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_ev_charger_status_tracker.py @@ -46,6 +46,7 @@ class EVChargerStatusTracker(ComponentStatusTracker, BackgroundService): @override def __init__( # pylint: disable=too-many-arguments self, + *, component_id: int, max_data_age: timedelta, max_blocking_duration: timedelta, diff --git a/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_pv_inverter_status_tracker.py b/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_pv_inverter_status_tracker.py index f3ad7ebe5..39e38ba3c 100644 --- a/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_pv_inverter_status_tracker.py +++ b/src/frequenz/sdk/microgrid/_power_distributing/_component_status/_pv_inverter_status_tracker.py @@ -43,6 +43,7 @@ class PVInverterStatusTracker(ComponentStatusTracker, BackgroundService): @override def __init__( # pylint: disable=too-many-arguments self, + *, component_id: int, max_data_age: timedelta, max_blocking_duration: timedelta, diff --git a/src/frequenz/sdk/microgrid/_power_distributing/_distribution_algorithm/_battery_distribution_algorithm.py b/src/frequenz/sdk/microgrid/_power_distributing/_distribution_algorithm/_battery_distribution_algorithm.py index fccdb828b..b4e390e1d 100644 --- a/src/frequenz/sdk/microgrid/_power_distributing/_distribution_algorithm/_battery_distribution_algorithm.py +++ b/src/frequenz/sdk/microgrid/_power_distributing/_distribution_algorithm/_battery_distribution_algorithm.py @@ -449,6 +449,7 @@ def _compute_battery_availability_ratio( def _distribute_power( # pylint: disable=too-many-arguments self, + *, components: list[InvBatPair], power_w: float, available_soc: dict[int, float], @@ -730,7 +731,11 @@ def _distribute_consume_power( ) return self._distribute_power( - components, power_w, available_soc, incl_bounds, excl_bounds + components=components, + power_w=power_w, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) def _distribute_supply_power( @@ -761,7 +766,11 @@ def _distribute_supply_power( ) result: DistributionResult = self._distribute_power( - components, -1 * power_w, available_soc, incl_bounds, excl_bounds + components=components, + power_w=-1 * power_w, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) for inverter_id in result.distribution.keys(): diff --git a/src/frequenz/sdk/microgrid/_power_managing/_power_managing_actor.py b/src/frequenz/sdk/microgrid/_power_managing/_power_managing_actor.py index 2211f1a3a..590ec2b6c 100644 --- a/src/frequenz/sdk/microgrid/_power_managing/_power_managing_actor.py +++ b/src/frequenz/sdk/microgrid/_power_managing/_power_managing_actor.py @@ -32,12 +32,12 @@ class PowerManagingActor(Actor): # pylint: disable=too-many-instance-attributes def __init__( # pylint: disable=too-many-arguments self, + *, proposals_receiver: Receiver[Proposal], bounds_subscription_receiver: Receiver[ReportRequest], power_distributing_requests_sender: Sender[_power_distributing.Request], power_distributing_results_receiver: Receiver[_power_distributing.Result], channel_registry: ChannelRegistry, - *, component_category: ComponentCategory, component_type: ComponentType | None = None, # arguments to actors need to serializable, so we pass an enum for the algorithm diff --git a/src/frequenz/sdk/timeseries/battery_pool/_battery_pool_reference_store.py b/src/frequenz/sdk/timeseries/battery_pool/_battery_pool_reference_store.py index cffbde00a..4e7e99fa4 100644 --- a/src/frequenz/sdk/timeseries/battery_pool/_battery_pool_reference_store.py +++ b/src/frequenz/sdk/timeseries/battery_pool/_battery_pool_reference_store.py @@ -39,6 +39,7 @@ class BatteryPoolReferenceStore: # pylint: disable=too-many-instance-attributes def __init__( # pylint: disable=too-many-arguments self, + *, channel_registry: ChannelRegistry, resampler_subscription_sender: Sender[ComponentMetricRequest], batteries_status_receiver: Receiver[ComponentPoolStatus], diff --git a/src/frequenz/sdk/timeseries/ev_charger_pool/_ev_charger_pool_reference_store.py b/src/frequenz/sdk/timeseries/ev_charger_pool/_ev_charger_pool_reference_store.py index 1c42f6eb3..7bc7cc291 100644 --- a/src/frequenz/sdk/timeseries/ev_charger_pool/_ev_charger_pool_reference_store.py +++ b/src/frequenz/sdk/timeseries/ev_charger_pool/_ev_charger_pool_reference_store.py @@ -35,6 +35,7 @@ class EVChargerPoolReferenceStore: def __init__( # pylint: disable=too-many-arguments self, + *, channel_registry: ChannelRegistry, resampler_subscription_sender: Sender[ComponentMetricRequest], status_receiver: Receiver[ComponentPoolStatus], diff --git a/src/frequenz/sdk/timeseries/formula_engine/_formula_engine_pool.py b/src/frequenz/sdk/timeseries/formula_engine/_formula_engine_pool.py index 95ed22c59..dfd7b62c8 100644 --- a/src/frequenz/sdk/timeseries/formula_engine/_formula_engine_pool.py +++ b/src/frequenz/sdk/timeseries/formula_engine/_formula_engine_pool.py @@ -80,12 +80,12 @@ def from_string( return self._string_engines[channel_key] builder = ResampledFormulaBuilder( - self._namespace, - formula, - self._channel_registry, - self._resampler_subscription_sender, - component_metric_id, - Quantity, + namespace=self._namespace, + formula_name=formula, + channel_registry=self._channel_registry, + resampler_subscription_sender=self._resampler_subscription_sender, + metric_id=component_metric_id, + create_method=Quantity, ) formula_engine = builder.from_string(formula, nones_are_zeros=nones_are_zeros) self._string_engines[channel_key] = formula_engine diff --git a/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_formula_generator.py b/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_formula_generator.py index 2fe011c45..4a538b655 100644 --- a/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_formula_generator.py +++ b/src/frequenz/sdk/timeseries/formula_engine/_formula_generators/_formula_generator.py @@ -91,12 +91,12 @@ def _get_builder( create_method: Callable[[float], QuantityT], ) -> ResampledFormulaBuilder[QuantityT]: builder = ResampledFormulaBuilder( - self._namespace, - name, - self._channel_registry, - self._resampler_subscription_sender, - component_metric_id, - create_method, + namespace=self._namespace, + formula_name=name, + channel_registry=self._channel_registry, + resampler_subscription_sender=self._resampler_subscription_sender, + metric_id=component_metric_id, + create_method=create_method, ) return builder diff --git a/src/frequenz/sdk/timeseries/formula_engine/_resampled_formula_builder.py b/src/frequenz/sdk/timeseries/formula_engine/_resampled_formula_builder.py index 39b2fc76a..56001a129 100644 --- a/src/frequenz/sdk/timeseries/formula_engine/_resampled_formula_builder.py +++ b/src/frequenz/sdk/timeseries/formula_engine/_resampled_formula_builder.py @@ -24,6 +24,7 @@ class ResampledFormulaBuilder(FormulaBuilder[QuantityT]): def __init__( # pylint: disable=too-many-arguments self, + *, namespace: str, formula_name: str, channel_registry: ChannelRegistry, diff --git a/src/frequenz/sdk/timeseries/pv_pool/_pv_pool_reference_store.py b/src/frequenz/sdk/timeseries/pv_pool/_pv_pool_reference_store.py index caf9e42ce..57a05af4c 100644 --- a/src/frequenz/sdk/timeseries/pv_pool/_pv_pool_reference_store.py +++ b/src/frequenz/sdk/timeseries/pv_pool/_pv_pool_reference_store.py @@ -36,6 +36,7 @@ class PVPoolReferenceStore: def __init__( # pylint: disable=too-many-arguments self, + *, channel_registry: ChannelRegistry, resampler_subscription_sender: Sender[ComponentMetricRequest], status_receiver: Receiver[ComponentPoolStatus], diff --git a/tests/actor/_power_managing/test_matryoshka.py b/tests/actor/_power_managing/test_matryoshka.py index 771783f18..6828f98a4 100644 --- a/tests/actor/_power_managing/test_matryoshka.py +++ b/tests/actor/_power_managing/test_matryoshka.py @@ -28,7 +28,7 @@ def __init__( self._system_bounds = system_bounds self.algorithm = Matryoshka(max_proposal_age=timedelta(seconds=60.0)) - def tgt_power( # pylint: disable=too-many-arguments + def tgt_power( # pylint: disable=too-many-arguments,too-many-positional-arguments self, priority: int, power: float | None, diff --git a/tests/actor/power_distributing/_component_status/test_battery_status.py b/tests/actor/power_distributing/_component_status/test_battery_status.py index 8daab8c4f..9f5d5ce02 100644 --- a/tests/actor/power_distributing/_component_status/test_battery_status.py +++ b/tests/actor/power_distributing/_component_status/test_battery_status.py @@ -41,7 +41,7 @@ from ....utils.receive_timeout import Timeout, receive_timeout -def battery_data( # pylint: disable=too-many-arguments +def battery_data( # pylint: disable=too-many-arguments,too-many-positional-arguments component_id: int, timestamp: datetime | None = None, relay_state: BatteryRelayState = BatteryRelayState.CLOSED, @@ -149,7 +149,7 @@ async def test_sync_update_status_with_messages( async with ( mock_microgrid, BatteryStatusTracker( - BATTERY_ID, + component_id=BATTERY_ID, max_data_age=timedelta(seconds=5), max_blocking_duration=timedelta(seconds=30), status_sender=status_channel.new_sender(), @@ -322,7 +322,7 @@ async def test_sync_blocking_feature(self, mocker: MockerFixture) -> None: BatteryStatusTracker( # increase max_data_age_sec for blocking tests. # Otherwise it will block blocking. - BATTERY_ID, + component_id=BATTERY_ID, max_data_age=timedelta(seconds=500), max_blocking_duration=timedelta(seconds=30), status_sender=status_channel.new_sender(), @@ -461,7 +461,7 @@ async def test_sync_blocking_interrupted_with_with_max_data( async with ( mock_microgrid, BatteryStatusTracker( - BATTERY_ID, + component_id=BATTERY_ID, max_data_age=timedelta(seconds=5), max_blocking_duration=timedelta(seconds=30), status_sender=status_channel.new_sender(), @@ -512,7 +512,7 @@ async def test_sync_blocking_interrupted_with_invalid_message( async with ( mock_microgrid, BatteryStatusTracker( - BATTERY_ID, + component_id=BATTERY_ID, max_data_age=timedelta(seconds=5), max_blocking_duration=timedelta(seconds=30), status_sender=status_channel.new_sender(), @@ -576,7 +576,7 @@ async def test_timers( async with ( mock_microgrid, BatteryStatusTracker( - BATTERY_ID, + component_id=BATTERY_ID, max_data_age=timedelta(seconds=5), max_blocking_duration=timedelta(seconds=30), status_sender=status_channel.new_sender(), @@ -645,7 +645,7 @@ async def test_async_battery_status(self, mocker: MockerFixture) -> None: async with ( mock_microgrid, BatteryStatusTracker( - BATTERY_ID, + component_id=BATTERY_ID, max_data_age=timedelta(seconds=5), max_blocking_duration=timedelta(seconds=30), status_sender=status_channel.new_sender(), @@ -733,7 +733,7 @@ async def setup_tracker( async with ( mock_microgrid, BatteryStatusTracker( - BATTERY_ID, + component_id=BATTERY_ID, max_data_age=timedelta(seconds=0.2), max_blocking_duration=timedelta(seconds=1), status_sender=status_channel.new_sender(), diff --git a/tests/actor/power_distributing/test_battery_distribution_algorithm.py b/tests/actor/power_distributing/test_battery_distribution_algorithm.py index efea3cf02..0ecf37a81 100644 --- a/tests/actor/power_distributing/test_battery_distribution_algorithm.py +++ b/tests/actor/power_distributing/test_battery_distribution_algorithm.py @@ -189,7 +189,11 @@ def test_distribute_power_one_battery(self) -> None: algorithm = BatteryDistributionAlgorithm(distributor_exponent=1) result = algorithm._distribute_power( # pylint: disable=protected-access - components, 650, available_soc, incl_bounds, excl_bounds + components=components, + power_w=650, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) assert result.distribution == approx({1: 500}) @@ -210,7 +214,11 @@ def test_distribute_power_two_batteries_1(self) -> None: algorithm = BatteryDistributionAlgorithm(distributor_exponent=1) result = algorithm._distribute_power( # pylint: disable=protected-access - components, 600, available_soc, incl_bounds, excl_bounds + components=components, + power_w=600, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) assert result.distribution == approx({1: 400, 3: 200}) @@ -231,7 +239,11 @@ def test_distribute_power_two_batteries_2(self) -> None: algorithm = BatteryDistributionAlgorithm(distributor_exponent=1) result = algorithm._distribute_power( # pylint: disable=protected-access - components, 600, available_soc, incl_bounds, excl_bounds + components=components, + power_w=600, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) assert result.distribution == approx({1: 200, 3: 400}) @@ -254,7 +266,11 @@ def test_distribute_power_two_batteries_one_inverter(self) -> None: algorithm = BatteryDistributionAlgorithm(distributor_exponent=1) result = algorithm._distribute_power( # pylint: disable=protected-access - components, 600, available_soc, incl_bounds, excl_bounds + components=components, + power_w=600, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) assert result.distribution == approx({1: 500}) @@ -276,7 +292,11 @@ def test_distribute_power_two_batteries_bounds(self) -> None: algorithm = BatteryDistributionAlgorithm(distributor_exponent=1) result = algorithm._distribute_power( # pylint: disable=protected-access - components, 600, available_soc, incl_bounds, excl_bounds + components=components, + power_w=600, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) assert result.distribution == approx({1: 250, 3: 330}) @@ -300,7 +320,11 @@ def test_distribute_power_three_batteries(self) -> None: algorithm = BatteryDistributionAlgorithm(distributor_exponent=1) result = algorithm._distribute_power( # pylint: disable=protected-access - components, 1000, available_soc, incl_bounds, excl_bounds + components=components, + power_w=1000, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) assert result.distribution == approx({1: 400, 3: 400, 5: 200}) @@ -324,7 +348,11 @@ def test_distribute_power_three_batteries_2(self) -> None: algorithm = BatteryDistributionAlgorithm(distributor_exponent=1) result = algorithm._distribute_power( # pylint: disable=protected-access - components, 1000, available_soc, incl_bounds, excl_bounds + components=components, + power_w=1000, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) assert result.distribution == approx({1: 400, 3: 300, 5: 300}) @@ -348,7 +376,11 @@ def test_distribute_power_three_batteries_3(self) -> None: algorithm = BatteryDistributionAlgorithm(distributor_exponent=1) result = algorithm._distribute_power( # pylint: disable=protected-access - components, 1000, available_soc, incl_bounds, excl_bounds + components=components, + power_w=1000, + available_soc=available_soc, + incl_bounds=incl_bounds, + excl_bounds=excl_bounds, ) assert result.distribution == approx({1: 0, 3: 300, 5: 0}) diff --git a/tests/timeseries/_formula_engine/utils.py b/tests/timeseries/_formula_engine/utils.py index b1e8f8230..2a745d547 100644 --- a/tests/timeseries/_formula_engine/utils.py +++ b/tests/timeseries/_formula_engine/utils.py @@ -29,12 +29,12 @@ def get_resampled_stream( # pylint: disable=protected-access builder = ResampledFormulaBuilder( - namespace, - "", - _data_pipeline._get()._channel_registry, - _data_pipeline._get()._resampling_request_sender(), - metric_id, - create_method, + namespace=namespace, + formula_name="", + channel_registry=_data_pipeline._get()._channel_registry, + resampler_subscription_sender=_data_pipeline._get()._resampling_request_sender(), + metric_id=metric_id, + create_method=create_method, ) # Resampled data is always `Quantity` type, so we need to convert it to the desired # output type. diff --git a/tests/timeseries/mock_microgrid.py b/tests/timeseries/mock_microgrid.py index 2fb5cca12..818bc9120 100644 --- a/tests/timeseries/mock_microgrid.py +++ b/tests/timeseries/mock_microgrid.py @@ -54,7 +54,7 @@ class MockMicrogrid: # pylint: disable=too-many-instance-attributes mock_client: MockMicrogridClient mock_resampler: MockResampler - def __init__( # pylint: disable=too-many-arguments + def __init__( # pylint: disable=too-many-arguments,too-many-positional-arguments self, grid_meter: bool | None = None, api_client_streaming: bool = False, diff --git a/tests/timeseries/mock_resampler.py b/tests/timeseries/mock_resampler.py index 68e9cada3..976c2fbe2 100644 --- a/tests/timeseries/mock_resampler.py +++ b/tests/timeseries/mock_resampler.py @@ -27,7 +27,7 @@ class MockResampler: """Mock resampler.""" - def __init__( # pylint: disable=too-many-arguments + def __init__( # pylint: disable=too-many-arguments,too-many-positional-arguments self, mocker: MockerFixture, resampler_config: ResamplerConfig, diff --git a/tests/timeseries/test_periodic_feature_extractor.py b/tests/timeseries/test_periodic_feature_extractor.py index 79484fe66..a61062ebb 100644 --- a/tests/timeseries/test_periodic_feature_extractor.py +++ b/tests/timeseries/test_periodic_feature_extractor.py @@ -128,7 +128,7 @@ async def test_feature_extractor() -> None: # pylint: disable=too-many-statemen async with init_feature_extractor(data, timedelta(seconds=5)) as feature_extractor: assert np.allclose(feature_extractor.avg(start, end), [1.5, 1.5]) - async def _test_fun( # pylint: disable=too-many-arguments + async def _test_fun( # pylint: disable=too-many-arguments,too-many-positional-arguments data: list[float], period: int, start: int, diff --git a/tests/timeseries/test_resampling.py b/tests/timeseries/test_resampling.py index 81598fa30..9d57ee458 100644 --- a/tests/timeseries/test_resampling.py +++ b/tests/timeseries/test_resampling.py @@ -64,7 +64,8 @@ async def _advance_time(fake_time: time_machine.Coordinates, seconds: float) -> fake_time.shift(seconds) -async def _assert_no_more_samples( # pylint: disable=too-many-arguments +# pylint: disable-next=too-many-arguments,too-many-positional-arguments +async def _assert_no_more_samples( resampler: Resampler, initial_time: datetime, sink_mock: AsyncMock, diff --git a/tests/utils/component_data_wrapper.py b/tests/utils/component_data_wrapper.py index d4071d533..c76612caa 100644 --- a/tests/utils/component_data_wrapper.py +++ b/tests/utils/component_data_wrapper.py @@ -30,11 +30,14 @@ MeterData, ) +# Disable these checks for the file as we need to pass a lot of data +# pylint: disable=too-many-arguments,too-many-positional-arguments + class BatteryDataWrapper(BatteryData): """Wrapper for the BatteryData with default arguments.""" - def __init__( # pylint: disable=too-many-arguments + def __init__( self, component_id: int, timestamp: datetime, @@ -92,7 +95,7 @@ def copy_with_new_timestamp(self, new_timestamp: datetime) -> BatteryDataWrapper class InverterDataWrapper(InverterData): """Wrapper for the InverterData with default arguments.""" - def __init__( # pylint: disable=too-many-arguments,too-many-locals + def __init__( # pylint: disable=too-many-locals self, component_id: int, timestamp: datetime, @@ -160,7 +163,7 @@ def copy_with_new_timestamp(self, new_timestamp: datetime) -> InverterDataWrappe class EvChargerDataWrapper(EVChargerData): """Wrapper for the EvChargerData with default arguments.""" - def __init__( # pylint: disable=too-many-arguments,too-many-locals + def __init__( # pylint: disable=too-many-locals self, component_id: int, timestamp: datetime, @@ -228,7 +231,7 @@ def copy_with_new_timestamp(self, new_timestamp: datetime) -> EvChargerDataWrapp class MeterDataWrapper(MeterData): """Wrapper for the MeterData with default arguments.""" - def __init__( # pylint: disable=too-many-arguments + def __init__( self, component_id: int, timestamp: datetime,