Skip to content

Commit 6d0c415

Browse files
Revert "Fix all lint issues (#245)" (#246)
1 parent 5b94974 commit 6d0c415

25 files changed

+365
-265
lines changed

.github/workflows/test.yml

+14-6
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,18 @@ jobs:
2525
run: |
2626
sudo apt-get update
2727
sudo apt-get install -y libgirepository1.0-dev
28-
python -m pip install --upgrade pip build setuptools
29-
pip install .[server] .[test]
30-
- name: Lint/test with pre-commit
31-
run: pre-commit run --all-files
28+
python -m pip install --upgrade pip
29+
pip install -e .[server] -r requirements-test.txt
30+
- name: Flake8
31+
run: flake8 scripts/ matter_server/
32+
- name: Black
33+
run: black --check scripts/ matter_server/
34+
- name: isort
35+
run: isort --check scripts/ matter_server/
36+
- name: pylint
37+
run: pylint matter_server/
38+
- name: mypy
39+
run: mypy matter_server/
3240

3341
test:
3442
runs-on: ubuntu-latest
@@ -51,7 +59,7 @@ jobs:
5159
run: |
5260
sudo apt-get update
5361
sudo apt-get install -y libgirepository1.0-dev
54-
python -m pip install --upgrade pip build setuptools
55-
pip install .[server] .[test]
62+
python -m pip install --upgrade pip
63+
pip install -e .[server] -r requirements-test.txt
5664
- name: Pytest
5765
run: pytest --durations 10 --cov-report term-missing --cov=matter_server --cov-report=xml tests/server/

.pre-commit-config.yaml

+17-14
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,6 @@
11
# See https://pre-commit.com for more information
22
# See https://pre-commit.com/hooks.html for more hooks
33
repos:
4-
- repo: https://github.com/pre-commit/pre-commit-hooks
5-
rev: v4.4.0
6-
hooks:
7-
- id: end-of-file-fixer
8-
- id: trailing-whitespace
9-
- id: no-commit-to-branch
10-
args:
11-
- --branch=main
12-
- id: debug-statements
13-
- repo: https://github.com/charliermarsh/ruff-pre-commit
14-
rev: 'v0.0.259'
15-
hooks:
16-
- id: ruff
17-
files: ^(matter_server|scripts)/.+\.py$
184
- repo: https://github.com/psf/black
195
rev: 23.1.0
206
hooks:
@@ -29,6 +15,23 @@ repos:
2915
args: []
3016
exclude_types: [csv, json]
3117
exclude: ^tests/fixtures/
18+
- repo: https://github.com/PyCQA/flake8
19+
rev: 6.0.0
20+
hooks:
21+
- id: flake8
22+
files: ^(matter_server|scripts)/.+\.py$
23+
- repo: https://github.com/PyCQA/isort
24+
rev: 5.12.0
25+
hooks:
26+
- id: isort
27+
files: ^(matter_server|scripts)/.+\.py$
28+
- repo: https://github.com/pre-commit/pre-commit-hooks
29+
rev: v4.4.0
30+
hooks:
31+
- id: no-commit-to-branch
32+
args:
33+
- --branch=main
34+
- id: trailing-whitespace
3235
- repo: local
3336
hooks:
3437
- id: mypy

matter_server/client/client.py

+36-21
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33

44
import asyncio
55
import logging
6-
import uuid
7-
from collections.abc import Callable
86
from types import TracebackType
9-
from typing import TYPE_CHECKING, Any, Final, cast
7+
from typing import TYPE_CHECKING, Any, Callable, Dict, Final, Optional, cast
8+
import uuid
109

1110
from aiohttp import ClientSession
1211

1312
from matter_server.common.errors import ERROR_MAP
14-
from matter_server.common.helpers.util import dataclass_from_dict, dataclass_to_dict
15-
from matter_server.common.models import (
13+
14+
from ..common.helpers.util import dataclass_from_dict, dataclass_to_dict
15+
from ..common.models import (
1616
APICommand,
1717
CommandMessage,
1818
ErrorResultMessage,
@@ -25,7 +25,6 @@
2525
ServerInfoMessage,
2626
SuccessResultMessage,
2727
)
28-
2928
from .connection import MatterClientConnection
3029
from .exceptions import ConnectionClosed, InvalidServerVersion, InvalidState
3130
from .models.node import MatterNode
@@ -43,8 +42,8 @@ def __init__(self, ws_server_url: str, aiohttp_session: ClientSession):
4342
"""Initialize the Client class."""
4443
self.connection = MatterClientConnection(ws_server_url, aiohttp_session)
4544
self.logger = logging.getLogger(__package__)
46-
self._nodes: dict[int, MatterNode] = {}
47-
self._result_futures: dict[str, asyncio.Future] = {}
45+
self._nodes: Dict[int, MatterNode] = {}
46+
self._result_futures: Dict[str, asyncio.Future] = {}
4847
self._subscribers: dict[str, list[Callable[[EventType, Any], None]]] = {}
4948
self._stop_called: bool = False
5049
self._loop: asyncio.AbstractEventLoop | None = None
@@ -57,9 +56,9 @@ def server_info(self) -> ServerInfoMessage | None:
5756
def subscribe(
5857
self,
5958
callback: Callable[[EventType, Any], None],
60-
event_filter: EventType | None = None,
61-
node_filter: int | None = None,
62-
attr_path_filter: str | None = None,
59+
event_filter: Optional[EventType] = None,
60+
node_filter: Optional[int] = None,
61+
attr_path_filter: Optional[str] = None,
6362
) -> Callable[[], None]:
6463
"""
6564
Subscribe to node and server events.
@@ -71,10 +70,16 @@ def subscribe(
7170
# for fast lookups we create a key based on the filters, allowing
7271
# a "catch all" with a wildcard (*).
7372
_event_filter: str
74-
_event_filter = SUB_WILDCARD if event_filter is None else event_filter.value
73+
if event_filter is None:
74+
_event_filter = SUB_WILDCARD
75+
else:
76+
_event_filter = event_filter.value
7577

7678
_node_filter: str
77-
_node_filter = SUB_WILDCARD if node_filter is None else str(node_filter)
79+
if node_filter is None:
80+
_node_filter = SUB_WILDCARD
81+
else:
82+
_node_filter = str(node_filter)
7883

7984
if attr_path_filter is None:
8085
attr_path_filter = SUB_WILDCARD
@@ -118,7 +123,9 @@ async def commission_on_network(self, setup_pin_code: int) -> MatterNodeData:
118123

119124
async def set_wifi_credentials(self, ssid: str, credentials: str) -> None:
120125
"""Set WiFi credentials for commissioning to a (new) device."""
121-
await self.send_command(APICommand.SET_WIFI_CREDENTIALS, ssid=ssid, credentials=credentials)
126+
await self.send_command(
127+
APICommand.SET_WIFI_CREDENTIALS, ssid=ssid, credentials=credentials
128+
)
122129

123130
async def set_thread_operational_dataset(self, dataset: str) -> None:
124131
"""Set Thread Operational dataset in the stack."""
@@ -130,7 +137,7 @@ async def open_commissioning_window(
130137
timeout: int = 300,
131138
iteration: int = 1000,
132139
option: int = 0,
133-
discriminator: int | None = None,
140+
discriminator: Optional[int] = None,
134141
) -> int:
135142
"""
136143
Open a commissioning window to commission a device present on this controller to another.
@@ -223,7 +230,10 @@ async def send_command_no_wait(
223230
if not self.server_info:
224231
raise InvalidState("Not connected")
225232

226-
if require_schema is not None and require_schema > self.server_info.schema_version:
233+
if (
234+
require_schema is not None
235+
and require_schema > self.server_info.schema_version
236+
):
227237
raise InvalidServerVersion(
228238
"Command not available due to incompatible server version. Update the Matter "
229239
f"Server to a version that supports at least api schema {require_schema}."
@@ -258,10 +268,15 @@ async def start_listening(self, init_ready: asyncio.Event | None = None) -> None
258268
message_id=uuid.uuid4().hex, command=APICommand.START_LISTENING
259269
)
260270
await self.connection.send_message(message)
261-
nodes_msg = cast(SuccessResultMessage, await self.connection.receive_message_or_raise())
271+
nodes_msg = cast(
272+
SuccessResultMessage, await self.connection.receive_message_or_raise()
273+
)
262274
# a full dump of all nodes will be the result of the start_listening command
263275
# create MatterNode objects from the basic MatterNodeData objects
264-
nodes = [MatterNode(dataclass_from_dict(MatterNodeData, x)) for x in nodes_msg.result]
276+
nodes = [
277+
MatterNode(dataclass_from_dict(MatterNodeData, x))
278+
for x in nodes_msg.result
279+
]
265280
self._nodes = {node.node_id: node for node in nodes}
266281
# once we've hit this point we're all set
267282
self.logger.info("Matter client initialized.")
@@ -358,8 +373,8 @@ def _signal_event(
358373
self,
359374
event: EventType,
360375
data: Any = None,
361-
node_id: int | None = None,
362-
attribute_path: str | None = None,
376+
node_id: Optional[int] = None,
377+
attribute_path: Optional[str] = None,
363378
) -> None:
364379
"""Signal event to all subscribers."""
365380
# instead of iterating all subscribers we iterate over subscription keys
@@ -375,7 +390,7 @@ def _signal_event(
375390
for callback in self._subscribers.get(key, []):
376391
callback(event, data)
377392

378-
async def __aenter__(self) -> MatterClient:
393+
async def __aenter__(self) -> "MatterClient":
379394
"""Initialize and connect the Matter Websocket client."""
380395
await self.connect()
381396
return self

matter_server/client/connection.py

+7-8
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
import asyncio
55
import logging
66
import pprint
7-
from collections.abc import Callable
8-
from typing import Any, Final, cast
7+
from typing import Any, Callable, Dict, Final, cast
98

109
from aiohttp import ClientSession, ClientWebSocketResponse, WSMsgType, client_exceptions
1110

12-
from matter_server.common.const import SCHEMA_VERSION
13-
from matter_server.common.helpers.json import json_dumps, json_loads
1411
from matter_server.common.helpers.util import dataclass_from_dict
15-
from matter_server.common.models import (
12+
13+
from ..common.const import SCHEMA_VERSION
14+
from ..common.helpers.json import json_dumps, json_loads
15+
from ..common.models import (
1616
CommandMessage,
1717
ErrorResultMessage,
1818
EventMessage,
@@ -21,7 +21,6 @@
2121
ServerInfoMessage,
2222
SuccessResultMessage,
2323
)
24-
2524
from .exceptions import (
2625
CannotConnect,
2726
ConnectionClosed,
@@ -51,8 +50,8 @@ def __init__(
5150
self.server_info: ServerInfoMessage | None = None
5251
self._aiohttp_session = aiohttp_session
5352
self._ws_client: ClientWebSocketResponse | None = None
54-
self._nodes: dict[int, MatterNode] = {}
55-
self._result_futures: dict[str, asyncio.Future] = {}
53+
self._nodes: Dict[int, MatterNode] = {}
54+
self._result_futures: Dict[str, asyncio.Future] = {}
5655
self._subscribers: dict[str, list[Callable[[EventType, Any], None]]] = {}
5756

5857
@property

matter_server/client/models/device_types.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
import typing
1010

11-
from chip.clusters import Objects as all_clusters # noqa: N813
11+
from chip.clusters import Objects as all_clusters
1212

13-
ALL_TYPES: dict[int, type[DeviceType]] = {}
13+
ALL_TYPES: dict[int, type["DeviceType"]] = {}
1414

1515

1616
class DeviceType:

matter_server/client/models/node.py

+20-11
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
from .device_types import (
1818
ALL_TYPES as DEVICE_TYPES,
19-
)
20-
from .device_types import (
2119
Aggregator,
2220
BridgedDevice,
2321
DeviceType,
@@ -144,7 +142,9 @@ def has_attribute(
144142
# allow sending None for Cluster to auto resolve it from the Attribute
145143
cluster = attribute.cluster_id
146144
cluster_id = cluster if isinstance(cluster, int) else cluster.id
147-
attribute_id = attribute if isinstance(attribute, int) else attribute.attribute_id
145+
attribute_id = (
146+
attribute if isinstance(attribute, int) else attribute.attribute_id
147+
)
148148
# the fastest way to check this is just by checking the AttributePath in the raw data...
149149
attr_path = create_attribute_path(self.endpoint_id, cluster_id, attribute_id)
150150
return attr_path in self.node.node_data.attributes
@@ -165,10 +165,12 @@ def set_attribute_value(self, attribute_path: str, attribute_value: Any) -> None
165165
self.clusters[cluster_id] = cluster_instance
166166

167167
# unpack cluster attribute, using the descriptor
168-
attribute_class: Clusters.ClusterAttributeDescriptor = ALL_ATTRIBUTES[cluster_id][
169-
attribute_id
170-
]
171-
attribute_name, attribute_type = get_object_params(cluster_class.descriptor, attribute_id)
168+
attribute_class: Clusters.ClusterAttributeDescriptor = ALL_ATTRIBUTES[
169+
cluster_id
170+
][attribute_id]
171+
attribute_name, attribute_type = get_object_params(
172+
cluster_class.descriptor, attribute_id
173+
)
172174

173175
# we only set the value at cluster instance level and we leave
174176
# the underlying Attributes classproperty alone
@@ -249,15 +251,20 @@ def get_attribute_value(
249251
"""Return Matter Cluster Attribute value for given parameters."""
250252
return self.endpoints[endpoint].get_attribute_value(cluster, attribute)
251253

252-
def has_cluster(self, cluster: type[_CLUSTER_T] | int, endpoint: int | None = None) -> bool:
254+
def has_cluster(
255+
self, cluster: type[_CLUSTER_T] | int, endpoint: int | None = None
256+
) -> bool:
253257
"""Check if node has a specific cluster on any of the endpoints."""
254258
return any(
255259
x
256260
for x in self.endpoints.values()
257-
if x.has_cluster(cluster) and (endpoint is None or x.endpoint_id == endpoint)
261+
if x.has_cluster(cluster)
262+
and (endpoint is None or x.endpoint_id == endpoint)
258263
)
259264

260-
def get_cluster(self, endpoint: int, cluster: type[_CLUSTER_T] | int) -> _CLUSTER_T | None:
265+
def get_cluster(
266+
self, endpoint: int, cluster: type[_CLUSTER_T] | int
267+
) -> _CLUSTER_T | None:
261268
"""
262269
Get a Cluster object containing all attributes.
263270
@@ -293,7 +300,9 @@ def update(self, node_data: MatterNodeData) -> None:
293300
endpoint_id=endpoint_id, attributes_data=attributes_data, node=self
294301
)
295302
# lookup if this is a bridge device
296-
self._is_bridge_device = any(Aggregator in x.device_types for x in self.endpoints.values())
303+
self._is_bridge_device = any(
304+
Aggregator in x.device_types for x in self.endpoints.values()
305+
)
297306
# composed devices reference to other endpoints through the partsList attribute
298307
# create a mapping table to quickly map this
299308
for endpoint in self.endpoints.values():

matter_server/common/errors.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
"""Matter Exceptions."""
22
from __future__ import annotations
33

4+
from typing import Type
5+
46
# mapping from error_code to Exception class
57
ERROR_MAP: dict[int, type] = {}
68

@@ -76,6 +78,6 @@ class InvalidCommand(MatterError):
7678
error_code = 9
7779

7880

79-
def exception_from_error_code(error_code: int) -> type[MatterError]:
81+
def exception_from_error_code(error_code: int) -> Type[MatterError]:
8082
"""Return correct Exception class from error_code."""
8183
return ERROR_MAP.get(error_code, MatterError)

matter_server/common/helpers/api.py

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
"""Several helpers for the WebSockets API."""
22
from __future__ import annotations
33

4-
import inspect
5-
from collections.abc import Callable, Coroutine
64
from dataclasses import MISSING, dataclass
7-
from typing import Any, TypeVar, get_type_hints
5+
import inspect
6+
from typing import Any, Callable, Coroutine, TypeVar, get_type_hints
87

98
from matter_server.common.helpers.util import parse_value
109

@@ -23,7 +22,7 @@ class APICommandHandler:
2322
@classmethod
2423
def parse(
2524
cls, command: str, func: Callable[..., Coroutine[Any, Any, Any]]
26-
) -> APICommandHandler:
25+
) -> "APICommandHandler":
2726
"""Parse APICommandHandler by providing a function."""
2827
return APICommandHandler(
2928
command=command,
@@ -61,6 +60,9 @@ def parse_arguments(
6160
# parse arguments to correct type
6261
for name, param in func_sig.parameters.items():
6362
value = args.get(name)
64-
default = MISSING if param.default is inspect.Parameter.empty else param.default
63+
if param.default is inspect.Parameter.empty:
64+
default = MISSING
65+
else:
66+
default = param.default
6567
final_args[name] = parse_value(name, value, func_types[name], default)
6668
return final_args

0 commit comments

Comments
 (0)