diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b740d0e..bc52597 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -67,7 +67,6 @@ jobs: run: | echo "::add-matcher::.github/workflows/matchers/flake8.json" echo "::add-matcher::.github/workflows/matchers/pylint.json" - echo "::add-matcher::.github/workflows/matchers/isort.json" echo "::add-matcher::.github/workflows/matchers/mypy.json" echo "::add-matcher::.github/workflows/matchers/pytest.json" @@ -80,9 +79,6 @@ jobs: - run: black --check --diff --color aioesphomeapi tests name: Check formatting with black if: ${{ matrix.python-version == '3.11' && matrix.extension == 'skip_cython' }} - - run: isort --check --diff aioesphomeapi tests - name: Check import order with isort - if: ${{ matrix.python-version == '3.11' && matrix.extension == 'skip_cython' }} - run: mypy aioesphomeapi name: Check typing with mypy if: ${{ matrix.python-version == '3.11' && matrix.extension == 'skip_cython' }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 62a1a02..6639250 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,41 +1,38 @@ --- exclude: '^aioesphomeapi/api.*$' repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-added-large-files -- repo: https://github.com/asottile/pyupgrade - rev: v2.37.1 - hooks: - - id: pyupgrade - args: [--py37-plus] -- repo: https://github.com/PyCQA/isort - rev: 5.12.0 - hooks: - - id: isort -- repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.1 - hooks: - - id: ruff - args: - - --fix -- repo: https://github.com/psf/black-pre-commit-mirror - rev: 24.1.1 - hooks: - - id: black - args: - - --quiet - files: ^((aioesphomeapi|tests)/.+)?[^/]+\.py$ -- repo: https://github.com/cdce8p/python-typing-update - rev: v0.6.0 - hooks: - - id: python-typing-update - stages: [manual] - args: - - --py39-plus - - --force - - --keep-updates - files: ^(aioesphomeapi)/.+\.py$ + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.2.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-added-large-files + - repo: https://github.com/asottile/pyupgrade + rev: v2.37.1 + hooks: + - id: pyupgrade + args: [--py39-plus] + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.5.4 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 24.1.1 + hooks: + - id: black + args: + - --safe + - --quiet + files: ^((aioesphomeapi|tests)/.+)?[^/]+\.py$ + - repo: https://github.com/cdce8p/python-typing-update + rev: v0.6.0 + hooks: + - id: python-typing-update + stages: [manual] + args: + - --py39-plus + - --force + - --keep-updates + files: ^(aioesphomeapi)/.+\.py$ diff --git a/aioesphomeapi/_frame_helper/base.py b/aioesphomeapi/_frame_helper/base.py index d0d0407..940c61a 100644 --- a/aioesphomeapi/_frame_helper/base.py +++ b/aioesphomeapi/_frame_helper/base.py @@ -1,8 +1,8 @@ from __future__ import annotations +from abc import abstractmethod import asyncio import logging -from abc import abstractmethod from typing import TYPE_CHECKING, Callable, cast from ..core import SocketClosedAPIError diff --git a/aioesphomeapi/_frame_helper/noise.py b/aioesphomeapi/_frame_helper/noise.py index f633d34..d72a6a6 100644 --- a/aioesphomeapi/_frame_helper/noise.py +++ b/aioesphomeapi/_frame_helper/noise.py @@ -2,8 +2,8 @@ from __future__ import annotations import asyncio import binascii -import logging from functools import partial +import logging from struct import Struct from typing import TYPE_CHECKING, Any, Callable diff --git a/aioesphomeapi/client.py b/aioesphomeapi/client.py index 2ad4d5b..f76c7c8 100644 --- a/aioesphomeapi/client.py +++ b/aioesphomeapi/client.py @@ -2,9 +2,9 @@ from __future__ import annotations import asyncio -import logging from collections.abc import Awaitable, Coroutine from functools import partial +import logging from typing import TYPE_CHECKING, Any, Callable, Union from google.protobuf import message @@ -127,9 +127,7 @@ from .model import ( UserService, UserServiceArgType, VoiceAssistantAudioData, -) -from .model import VoiceAssistantAudioSettings as VoiceAssistantAudioSettingsModel -from .model import ( + VoiceAssistantAudioSettings as VoiceAssistantAudioSettingsModel, VoiceAssistantCommand, VoiceAssistantEventType, VoiceAssistantSubscriptionFlag, @@ -951,16 +949,15 @@ class APIClient: req.tilt = tilt if stop: req.stop = stop - else: - if stop: - req.legacy_command = LegacyCoverCommand.STOP - req.has_legacy_command = True - elif position == 1.0: - req.legacy_command = LegacyCoverCommand.OPEN - req.has_legacy_command = True - elif position == 0.0: - req.legacy_command = LegacyCoverCommand.CLOSE - req.has_legacy_command = True + elif stop: + req.legacy_command = LegacyCoverCommand.STOP + req.has_legacy_command = True + elif position == 1.0: + req.legacy_command = LegacyCoverCommand.OPEN + req.has_legacy_command = True + elif position == 0.0: + req.legacy_command = LegacyCoverCommand.CLOSE + req.has_legacy_command = True connection.send_message(req) def fan_command( diff --git a/aioesphomeapi/connection.py b/aioesphomeapi/connection.py index adc2101..f3a8003 100644 --- a/aioesphomeapi/connection.py +++ b/aioesphomeapi/connection.py @@ -1,18 +1,17 @@ from __future__ import annotations import asyncio + +# After we drop support for Python 3.10, we can use the built-in TimeoutError +# instead of the one from asyncio since they are the same in Python 3.11+ +from asyncio import CancelledError, TimeoutError as asyncio_TimeoutError +from dataclasses import astuple, dataclass import enum +from functools import lru_cache, partial import logging import socket import sys import time - -# After we drop support for Python 3.10, we can use the built-in TimeoutError -# instead of the one from asyncio since they are the same in Python 3.11+ -from asyncio import CancelledError -from asyncio import TimeoutError as asyncio_TimeoutError -from dataclasses import astuple, dataclass -from functools import lru_cache, partial from typing import TYPE_CHECKING, Any, Callable import aiohappyeyeballs @@ -226,9 +225,7 @@ class APIConnection: self._params = params self.on_stop: Callable[[bool], None] | None = on_stop self._socket: socket.socket | None = None - self._frame_helper: None | (APINoiseFrameHelper | APIPlaintextFrameHelper) = ( - None - ) + self._frame_helper: None | APINoiseFrameHelper | APIPlaintextFrameHelper = None self.api_version: APIVersion | None = None self.connection_state = CONNECTION_STATE_INITIALIZED diff --git a/aioesphomeapi/host_resolver.py b/aioesphomeapi/host_resolver.py index 14e34c9..ba9503b 100644 --- a/aioesphomeapi/host_resolver.py +++ b/aioesphomeapi/host_resolver.py @@ -1,10 +1,10 @@ from __future__ import annotations import asyncio -import logging -import socket from dataclasses import dataclass from ipaddress import IPv4Address, IPv6Address, ip_address +import logging +import socket from typing import TYPE_CHECKING, cast from zeroconf import IPVersion diff --git a/aioesphomeapi/log_reader.py b/aioesphomeapi/log_reader.py index cc197c4..eeb76b9 100644 --- a/aioesphomeapi/log_reader.py +++ b/aioesphomeapi/log_reader.py @@ -3,9 +3,9 @@ from __future__ import annotations # Helper script and aioesphomeapi to view logs from an esphome device import argparse import asyncio +from datetime import datetime import logging import sys -from datetime import datetime from .api_pb2 import SubscribeLogsResponse # type: ignore from .client import APIClient diff --git a/aioesphomeapi/log_runner.py b/aioesphomeapi/log_runner.py index 44ccd9a..d0cdb52 100644 --- a/aioesphomeapi/log_runner.py +++ b/aioesphomeapi/log_runner.py @@ -1,7 +1,7 @@ from __future__ import annotations -import logging from collections.abc import Coroutine +import logging from typing import Any, Callable from zeroconf.asyncio import AsyncZeroconf diff --git a/aioesphomeapi/model.py b/aioesphomeapi/model.py index af20d6c..070f4c4 100644 --- a/aioesphomeapi/model.py +++ b/aioesphomeapi/model.py @@ -1,10 +1,10 @@ from __future__ import annotations -import enum -import sys from collections.abc import Iterable from dataclasses import asdict, dataclass, field, fields +import enum from functools import cache, lru_cache, partial +import sys from typing import TYPE_CHECKING, Any, Callable, TypeVar, cast from uuid import UUID diff --git a/aioesphomeapi/reconnect_logic.py b/aioesphomeapi/reconnect_logic.py index 199b6fe..8bf318a 100644 --- a/aioesphomeapi/reconnect_logic.py +++ b/aioesphomeapi/reconnect_logic.py @@ -1,15 +1,14 @@ from __future__ import annotations import asyncio -import logging -import time from collections.abc import Awaitable from enum import Enum +import logging +import time from typing import Callable import zeroconf -from zeroconf.const import _TYPE_A as TYPE_A -from zeroconf.const import _TYPE_PTR as TYPE_PTR +from zeroconf.const import _TYPE_A as TYPE_A, _TYPE_PTR as TYPE_PTR from .client import APIClient from .core import ( diff --git a/pyproject.toml b/pyproject.toml index 1126d93..dadea95 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,3 @@ -[tool.isort] -profile = "black" -multi_line_output = 3 -extend_skip = ["api_pb2.py", "api_options_pb2.py"] - [tool.black] exclude = 'api_pb2.py|api_options_pb2.py' target-version = ['py39'] @@ -31,9 +26,39 @@ disable = [ ] [tool.ruff] -ignore = [ - "E721", # We want type() check for protobuf messages +required-version = ">=0.5.0" +exclude = [ + "aioesphomeapi/api_pb2.py", + "aioesphomeapi/api_options_pb2.py", ] +[tool.ruff.lint] +select = [ + "E", # pycodestyle + "F", # pyflakes/autoflake + "I", # isort + "PL", # pylint + "UP", # pyupgrade +] + +ignore = [ + "E501", # line too long + "E721", # We want type() check for protobuf messages + "PLR0911", # Too many return statements ({returns} > {max_returns}) + "PLR0912", # Too many branches ({branches} > {max_branches}) + "PLR0913", # Too many arguments to function call ({c_args} > {max_args}) + "PLR0915", # Too many statements ({statements} > {max_statements}) + "PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable + "PLW2901", # Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target +] + +[tool.ruff.lint.isort] +force-sort-within-sections = true +known-first-party = [ + "aioesphomeapi", +] +combine-as-imports = true +split-on-trailing-comma = false + [build-system] requires = ['setuptools>=65.4.1', 'wheel', 'Cython>=3.0.2']