Skip to content

Commit 5bd31f7

Browse files
authored
use ruff in pre-commit for linting and formatting (lbbrhzn#1314)
* ruff fixes * fix linting SIM105 * update ruff taget verdion to py312 * enable ruff in vs code * remove black/flake/etc
1 parent 4b06be7 commit 5bd31f7

20 files changed

+102
-137
lines changed

.github/workflows/constraints.txt

-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
# home assistant
22
pip>=21.0,<24.3
33
pre-commit==3.8.0
4-
bandit==1.7.9
5-
black==24.8.0
6-
flake8==7.1.1
7-
isort==5.13.2
84
pre-comit-hooks==4.1.0
95
pyupgrade==3.17.0
10-
reorder-python-imports==3.13.0
116
sqlalchemy>=1.4.23

.pre-commit-config.yaml

+6-37
Original file line numberDiff line numberDiff line change
@@ -4,44 +4,13 @@ repos:
44
hooks:
55
- id: pyupgrade
66
args: [--py37-plus]
7-
- repo: https://github.com/psf/black
8-
rev: 23.11.0
7+
- repo: https://github.com/astral-sh/ruff-pre-commit
8+
rev: v0.6.4
99
hooks:
10-
- id: black
11-
args:
12-
- --safe
13-
- --quiet
14-
files: ^((custom_components|homeassistant|script|tests)/.+)?[^/]+\.py$
15-
- repo: https://github.com/codespell-project/codespell
16-
rev: v2.2.6
17-
hooks:
18-
- id: codespell
19-
args:
20-
- --ignore-words-list=hass,alot,datas,dof,dur,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing
21-
- --skip="./.*,*.csv,*.json"
22-
- --quiet-level=2
23-
exclude_types: [csv, json]
24-
- repo: https://github.com/PyCQA/flake8
25-
rev: 6.1.0
26-
hooks:
27-
- id: flake8
28-
additional_dependencies:
29-
- flake8-docstrings==1.5.0
30-
- pydocstyle==5.0.2
31-
files: ^(custom_components|homeassistant|script|tests)/.+\.py$
32-
- repo: https://github.com/PyCQA/bandit
33-
rev: 1.7.5
34-
hooks:
35-
- id: bandit
36-
args:
37-
- --quiet
38-
- --format=custom
39-
- --configfile=bandit.yaml
40-
files: ^(custom_components|homeassistant|script|tests|)/.+\.py$
41-
- repo: https://github.com/PyCQA/isort
42-
rev: 5.12.0
43-
hooks:
44-
- id: isort
10+
# Run the linter.
11+
- id: ruff
12+
# Run the formatter.
13+
- id: ruff-format
4514
- repo: https://github.com/pre-commit/pre-commit-hooks
4615
rev: v4.5.0
4716
hooks:

.ruff.toml

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# The contents of this file is based on https://github.com/home-assistant/core/blob/dev/pyproject.toml
22

3-
target-version = "py310"
3+
target-version = "py312"
44

5-
select = [
5+
lint.select = [
66
"B007", # Loop control variable {name} not used within loop body
77
"B014", # Exception handler with duplicate exception
88
"C", # complexity
@@ -26,7 +26,8 @@ select = [
2626
"W", # pycodestyle
2727
]
2828

29-
ignore = [
29+
lint.ignore = [
30+
"C901", # function too complex
3031
"D202", # No blank lines allowed after function docstring
3132
"D203", # 1 blank line required before class docstring
3233
"D213", # Multi-line docstring summary should start at the second line
@@ -38,11 +39,11 @@ ignore = [
3839
"E731", # do not assign a lambda expression, use a def
3940
]
4041

41-
[flake8-pytest-style]
42+
[lint.flake8-pytest-style]
4243
fixture-parentheses = false
4344

44-
[pyupgrade]
45+
[lint.pyupgrade]
4546
keep-runtime-typing = true
4647

47-
[mccabe]
48+
[lint.mccabe]
4849
max-complexity = 25

.vscode/settings.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
{
2-
"python.linting.pylintEnabled": true,
32
"python.linting.enabled": true,
3+
"python.linting.enabledWithoutWorkspace": true,
4+
"python.linting.lintOnSave": true,
5+
"python.linting.pylintEnabled": true,
6+
"python.linting.ruffEnabled": true,
47
"python.pythonPath": "/usr/local/bin/python",
58
"python.analysis.extraPaths": [
69
"/usr/local/lib/python3.9/site-packages"

custom_components/ocpp/api.py

+22-26
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"""Representation of a OCCP Entities."""
2+
23
from __future__ import annotations
34

45
import asyncio
56
from collections import defaultdict
6-
from datetime import datetime, timedelta, timezone
7+
from datetime import datetime, timedelta, UTC
78
import json
89
import logging
910
from math import sqrt
@@ -784,8 +785,7 @@ async def start_transaction(self):
784785
return False
785786

786787
async def stop_transaction(self):
787-
"""
788-
Request remote stop of current transaction.
788+
"""Request remote stop of current transaction.
789789
790790
Leaves charger in finishing state until unplugged.
791791
Use reset() to make the charger available again for remote start
@@ -836,9 +836,9 @@ async def update_firmware(self, firmware_url: str, wait_time: int = 0):
836836
url = schema(firmware_url)
837837
except vol.MultipleInvalid as e:
838838
_LOGGER.debug("Failed to parse url: %s", e)
839-
update_time = (
840-
datetime.now(tz=timezone.utc) + timedelta(hours=wait_time)
841-
).strftime("%Y-%m-%dT%H:%M:%SZ")
839+
update_time = (datetime.now(tz=UTC) + timedelta(hours=wait_time)).strftime(
840+
"%Y-%m-%dT%H:%M:%SZ"
841+
)
842842
req = call.UpdateFirmware(location=url, retrieve_date=update_time)
843843
resp = await self.call(req)
844844
_LOGGER.info("Response: %s", resp)
@@ -875,9 +875,7 @@ async def data_transfer(self, vendor_id: str, message_id: str = "", data: str =
875875
data,
876876
resp.data,
877877
)
878-
self._metrics[cdet.data_response.value].value = datetime.now(
879-
tz=timezone.utc
880-
)
878+
self._metrics[cdet.data_response.value].value = datetime.now(tz=UTC)
881879
self._metrics[cdet.data_response.value].extra_attr = {message_id: resp.data}
882880
return True
883881
else:
@@ -897,9 +895,7 @@ async def get_configuration(self, key: str = ""):
897895
if resp.configuration_key:
898896
value = resp.configuration_key[0][om.value.value]
899897
_LOGGER.debug("Get Configuration for %s: %s", key, value)
900-
self._metrics[cdet.config_response.value].value = datetime.now(
901-
tz=timezone.utc
902-
)
898+
self._metrics[cdet.config_response.value].value = datetime.now(tz=UTC)
903899
self._metrics[cdet.config_response.value].extra_attr = {key: value}
904900
return value
905901
if resp.unknown_key:
@@ -994,7 +990,7 @@ async def monitor_connection(self):
994990
self._metrics[cstat.latency_ping.value].value = latency_ping
995991
self._metrics[cstat.latency_pong.value].value = latency_pong
996992

997-
except asyncio.TimeoutError as timeout_exception:
993+
except TimeoutError as timeout_exception:
998994
_LOGGER.debug(
999995
f"Connection latency from '{self.central.csid}' to '{self.id}': ping={latency_ping} ms, pong={latency_pong} ms",
1000996
)
@@ -1027,7 +1023,7 @@ async def run(self, tasks):
10271023
self.tasks = [asyncio.ensure_future(task) for task in tasks]
10281024
try:
10291025
await asyncio.gather(*self.tasks)
1030-
except asyncio.TimeoutError:
1026+
except TimeoutError:
10311027
pass
10321028
except websockets.exceptions.WebSocketException as websocket_exception:
10331029
_LOGGER.debug(f"Connection closed to '{self.id}': {websocket_exception}")
@@ -1258,9 +1254,9 @@ def on_meter_values(self, connector_id: int, meter_value: dict, **kwargs):
12581254
self._metrics[measurand].value = float(value)
12591255
self._metrics[measurand].unit = unit
12601256
if location is not None:
1261-
self._metrics[measurand].extra_attr[
1262-
om.location.value
1263-
] = location
1257+
self._metrics[measurand].extra_attr[om.location.value] = (
1258+
location
1259+
)
12641260
if context is not None:
12651261
self._metrics[measurand].extra_attr[om.context.value] = context
12661262
processed_keys.append(idx)
@@ -1295,7 +1291,7 @@ def on_meter_values(self, connector_id: int, meter_value: dict, **kwargs):
12951291
def on_boot_notification(self, **kwargs):
12961292
"""Handle a boot notification."""
12971293
resp = call_result.BootNotification(
1298-
current_time=datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
1294+
current_time=datetime.now(tz=UTC).strftime("%Y-%m-%dT%H:%M:%SZ"),
12991295
interval=3600,
13001296
status=RegistrationStatus.accepted.value,
13011297
)
@@ -1333,12 +1329,12 @@ def on_status_notification(self, connector_id, error_code, status, **kwargs):
13331329
self._metrics[cstat.status_connector.value].value = status
13341330
self._metrics[cstat.error_code_connector.value].value = error_code
13351331
if connector_id >= 1:
1336-
self._metrics[cstat.status_connector.value].extra_attr[
1337-
connector_id
1338-
] = status
1339-
self._metrics[cstat.error_code_connector.value].extra_attr[
1340-
connector_id
1341-
] = error_code
1332+
self._metrics[cstat.status_connector.value].extra_attr[connector_id] = (
1333+
status
1334+
)
1335+
self._metrics[cstat.error_code_connector.value].extra_attr[connector_id] = (
1336+
error_code
1337+
)
13421338
if (
13431339
status == ChargePointStatus.suspended_ev.value
13441340
or status == ChargePointStatus.suspended_evse.value
@@ -1489,14 +1485,14 @@ def on_stop_transaction(self, meter_stop, timestamp, transaction_id, **kwargs):
14891485
def on_data_transfer(self, vendor_id, **kwargs):
14901486
"""Handle a Data transfer request."""
14911487
_LOGGER.debug("Data transfer received from %s: %s", self.id, kwargs)
1492-
self._metrics[cdet.data_transfer.value].value = datetime.now(tz=timezone.utc)
1488+
self._metrics[cdet.data_transfer.value].value = datetime.now(tz=UTC)
14931489
self._metrics[cdet.data_transfer.value].extra_attr = {vendor_id: kwargs}
14941490
return call_result.DataTransfer(status=DataTransferStatus.accepted.value)
14951491

14961492
@on(Action.heartbeat)
14971493
def on_heartbeat(self, **kwargs):
14981494
"""Handle a Heartbeat."""
1499-
now = datetime.now(tz=timezone.utc)
1495+
now = datetime.now(tz=UTC)
15001496
self._metrics[cstat.heartbeat.value].value = now
15011497
self.hass.async_create_task(self.central.update(self.central.cpid))
15021498
return call_result.Heartbeat(current_time=now.strftime("%Y-%m-%dT%H:%M:%SZ"))

custom_components/ocpp/button.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Button platform for ocpp."""
2+
23
from __future__ import annotations
34

45
from dataclasses import dataclass

custom_components/ocpp/config_flow.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Adds config flow for ocpp."""
2+
23
from homeassistant import config_entries
34
import voluptuous as vol
45

custom_components/ocpp/const.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Define constants for OCPP integration."""
2+
23
import pathlib
34

45
import homeassistant.components.input_number as input_number

custom_components/ocpp/enums.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Additional enumerated values to use in home assistant."""
2+
23
from enum import Enum, Flag, auto
34

45

custom_components/ocpp/exception.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
""" This file is imported by home assistant, and can be used to define custom exceptions."""
1+
"""This file is imported by home assistant, and can be used to define custom exceptions."""

custom_components/ocpp/number.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Number platform for ocpp."""
2+
23
from __future__ import annotations
34

45
from dataclasses import dataclass

custom_components/ocpp/sensor.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Sensor platform for ocpp."""
2+
23
from __future__ import annotations
34

45
from dataclasses import dataclass
@@ -162,7 +163,7 @@ def device_class(self):
162163
Measurand.rpm,
163164
] or self.metric.lower().startswith("frequency"):
164165
device_class = SensorDeviceClass.FREQUENCY
165-
elif self.metric.lower().startswith(tuple(["power.a", "power.o", "power.r"])):
166+
elif self.metric.lower().startswith(("power.a", "power.o", "power.r")):
166167
device_class = SensorDeviceClass.POWER
167168
elif self.metric.lower().startswith("temperature."):
168169
device_class = SensorDeviceClass.TEMPERATURE

custom_components/ocpp/switch.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Switch platform for ocpp."""
2+
23
from __future__ import annotations
34

45
from dataclasses import dataclass

docs/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Configuration file for the Sphinx documentation builder.
1+
"""Configuration file for the Sphinx documentation builder."""
22

33
# -- Project information
44

manage/update_manifest.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Update the manifest file."""
2+
23
# https://github.com/hacs/integration/blob/main/manage/update_manifest.py
34
import json
45
import os

tests/conftest.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Global fixtures for ocpp integration."""
2+
23
import asyncio
34
from unittest.mock import patch
45

@@ -20,9 +21,11 @@ def auto_enable_custom_integrations(enable_custom_integrations):
2021
@pytest.fixture(name="skip_notifications", autouse=True)
2122
def skip_notifications_fixture():
2223
"""Skip notification calls."""
23-
with patch("homeassistant.components.persistent_notification.async_create"), patch(
24-
"homeassistant.components.persistent_notification.async_dismiss"
25-
), patch("custom_components.ocpp.api.ChargePoint.notify_ha"):
24+
with (
25+
patch("homeassistant.components.persistent_notification.async_create"),
26+
patch("homeassistant.components.persistent_notification.async_dismiss"),
27+
patch("custom_components.ocpp.api.ChargePoint.notify_ha"),
28+
):
2629
yield
2730

2831

@@ -33,9 +36,11 @@ def bypass_get_data_fixture():
3336
"""Skip calls to get data from API."""
3437
future = asyncio.Future()
3538
future.set_result(websockets.WebSocketServer)
36-
with patch("websockets.server.serve", return_value=future), patch(
37-
"websockets.server.WebSocketServer.close"
38-
), patch("websockets.server.WebSocketServer.wait_closed"):
39+
with (
40+
patch("websockets.server.serve", return_value=future),
41+
patch("websockets.server.WebSocketServer.close"),
42+
patch("websockets.server.WebSocketServer.wait_closed"),
43+
):
3944
yield
4045

4146

tests/const.py

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Constants for ocpp tests."""
2+
23
from custom_components.ocpp.const import (
34
CONF_CPID,
45
CONF_CSID,

0 commit comments

Comments
 (0)