Skip to content

Commit 670e89d

Browse files
committed
fix linter warnings
1 parent b65bc90 commit 670e89d

11 files changed

Lines changed: 80 additions & 49 deletions

File tree

custom_components/pyscript/decorator.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
1+
"""Decorator registry and manager logic for pyscript decorators."""
2+
13
from __future__ import annotations
24

35
import ast
46
import asyncio
57
import logging
68
import os
9+
from typing import Any, ClassVar, Type, TypeVar
710
import weakref
8-
from typing import Type, ClassVar, Any, TypeVar
911

1012
from homeassistant.config_entries import ConfigEntry
11-
from homeassistant.core import HomeAssistant, Context
13+
from homeassistant.core import Context, HomeAssistant
1214

1315
from .decorator_abc import (
16+
CallHandlerDecorator,
17+
CallResultHandlerDecorator,
1418
Decorator,
1519
DecoratorManager,
16-
DispatchData,
1720
DecoratorManagerStatus,
18-
TriggerHandlerDecorator,
19-
CallHandlerDecorator,
21+
DispatchData,
2022
TriggerDecorator,
21-
CallResultHandlerDecorator,
23+
TriggerHandlerDecorator,
2224
)
2325
from .eval import AstEval, EvalFunc, EvalFuncVar
2426
from .function import Function
@@ -49,15 +51,16 @@ def init(cls, hass: HomeAssistant, config_entry: ConfigEntry = None) -> None:
4951
cls.prefix = ""
5052
space = "\n" + " " * 35
5153
border = space + "=" * 35
52-
_LOGGER.warning(border + space + "DecoratorManager enabled by default" + border)
54+
msg = border + space + "DecoratorManager enabled by default" + border
55+
_LOGGER.warning(msg)
5356
else:
5457
cls.prefix = "e"
5558

5659
DecoratorManager.hass = hass
5760

5861
Function.register_ast({cls.prefix + "task.wait_until": DecoratorRegistry.wait_until_factory})
5962

60-
from .decorators import DECORATORS
63+
from .decorators import DECORATORS # noqa: PLC0415 pylint: disable=import-outside-toplevel
6164

6265
for dec_type in DECORATORS:
6366
cls.register(dec_type)
@@ -171,6 +174,7 @@ class WaitUntilDecoratorManager(DecoratorManager):
171174
"""Decorator manager for task.wait_until."""
172175

173176
def __init__(self, ast_ctx: AstEval, **kwargs: dict[str, Any]) -> None:
177+
"""Initialize the task.wait_until decorator manager."""
174178
super().__init__(ast_ctx, ast_ctx.name)
175179
self.kwargs = kwargs
176180
self._future: asyncio.Future[DispatchData] = self.hass.loop.create_future()
@@ -212,6 +216,7 @@ class FunctionDecoratorManager(DecoratorManager):
212216
"""Maintain and validate a set of decorators applied to a function."""
213217

214218
def __init__(self, ast_ctx: AstEval, eval_func_var: EvalFuncVar) -> None:
219+
"""Initialize the function decorator manager."""
215220
super().__init__(ast_ctx, f"{ast_ctx.get_global_ctx_name()}.{eval_func_var.get_name()}")
216221
self.eval_func: EvalFunc = eval_func_var.func
217222

custom_components/pyscript/decorator_abc.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
"""Base abstractions for pyscript decorators and decorator managers."""
2+
13
from __future__ import annotations
24

3-
import logging
45
from abc import ABC, abstractmethod
5-
from dataclasses import field, dataclass
6+
from dataclasses import dataclass, field
67
from enum import StrEnum
7-
from typing import ClassVar, Any, TypeVar, Type, final
8+
import logging
9+
from typing import Any, ClassVar, final
810

911
import voluptuous as vol
12+
1013
from homeassistant.core import Context, HomeAssistant
1114

1215
from . import trigger
@@ -109,6 +112,7 @@ async def stop(self):
109112
"""Stop the decorator."""
110113

111114
def __repr__(self):
115+
"""Represent the decorator as a string with the decorator name and arguments."""
112116
parts = []
113117
if self.raw_args is not None:
114118
parts.append(",".join(map(str, self.raw_args)))
@@ -117,15 +121,13 @@ def __repr__(self):
117121
return f"@{self.name}({', '.join(parts)})"
118122

119123

120-
DecoratorType = TypeVar("DecoratorType", bound=Decorator)
121-
122-
123124
class DecoratorManager(ABC):
124-
"""Maintain and validate a set of decorators"""
125+
"""Maintain and validate a set of decorators."""
125126

126127
hass: ClassVar[HomeAssistant]
127128

128129
def __init__(self, ast_ctx: AstEval, name: str) -> None:
130+
"""Initialize the manager."""
129131
self.ast_ctx = ast_ctx
130132
self.name = name
131133
self.func_name = name.split(".")[-1]
@@ -154,7 +156,7 @@ def add(self, decorator: Decorator) -> None:
154156
self._decorators.append(decorator)
155157
decorator.dm = self
156158

157-
def get_decorators(self, decorator_type: Type[DecoratorType] | None = None) -> list[DecoratorType]:
159+
def get_decorators[DT](self, decorator_type: type[DT] | None = None) -> list[DT]: # noqa: D102
158160
"""Get decorators of a specific type."""
159161
if decorator_type is None:
160162
return self._decorators.copy()
@@ -221,16 +223,18 @@ async def stop(self):
221223

222224
@abstractmethod
223225
async def dispatch(self, data: DispatchData) -> None:
224-
pass
226+
"""Dispatch a trigger call."""
225227

226228
def __repr__(self):
229+
"""Return a string representation of the manager with status and decorators."""
227230
return f"{self.__class__.__name__}({self.status}) {self._decorators} for {self.name}()>"
228231

229232

230233
class TriggerDecorator(Decorator, ABC):
231234
"""Base class for trigger-based decorators."""
232235

233236
def __init_subclass__(cls, **kwargs):
237+
"""Initialize the decorator class."""
234238
super().__init_subclass__(**kwargs)
235239
# kwargs for all triggers
236240
if "kwargs" not in cls.kwargs_schema.schema.keys():
@@ -280,7 +284,6 @@ class CallHandlerDecorator(Decorator, ABC):
280284
@abstractmethod
281285
async def handle_call(self, data: DispatchData) -> bool | None:
282286
"""Handle an action call. Return False for stop calling."""
283-
pass
284287

285288

286289
class CallResultHandlerDecorator(Decorator, ABC):
@@ -289,4 +292,3 @@ class CallResultHandlerDecorator(Decorator, ABC):
289292
@abstractmethod
290293
async def handle_call_result(self, data: DispatchData, result: Any) -> None:
291294
"""Handle an action call result."""
292-
pass

custom_components/pyscript/decorators/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
"""Pyscript decorators."""
2+
13
from .event import EventTriggerDecorator
24
from .mqtt import MQTTTriggerDecorator
35
from .service import ServiceDecorator
4-
from .state import StateTriggerDecorator, StateActiveDecorator
6+
from .state import StateActiveDecorator, StateTriggerDecorator
57
from .task import TaskUniqueDecorator
6-
from .timing import TimeTriggerDecorator, TimeActiveDecorator
8+
from .timing import TimeActiveDecorator, TimeTriggerDecorator
79
from .webhook import WebhookTriggerDecorator
810

911
DECORATORS = [

custom_components/pyscript/decorators/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Base mixins for pyscript decorators."""
22

3-
import logging
43
from abc import ABC
4+
import logging
55
from typing import Any
66

77
import voluptuous as vol

custom_components/pyscript/decorators/event.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
"""Event decorator."""
2+
13
import logging
24

35
import voluptuous as vol
4-
from homeassistant.core import Event, CALLBACK_TYPE
56

6-
from .base import ExpressionDecorator
7+
from homeassistant.core import CALLBACK_TYPE, Event
8+
79
from ..decorator_abc import DispatchData, TriggerDecorator
10+
from .base import ExpressionDecorator
811

912
_LOGGER = logging.getLogger(__name__)
1013

@@ -29,7 +32,6 @@ async def validate(self) -> None:
2932
self.create_expression(self.args[1])
3033

3134
async def _event_callback(self, event: Event) -> None:
32-
"""Callback for the event trigger."""
3335
_LOGGER.debug("Event trigger received: %s %s", type(event), event)
3436
func_args = {
3537
"trigger_type": "event",

custom_components/pyscript/decorators/mqtt.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
"""Trigger decorator implementations."""
1+
"""Mqtt decorator."""
22

33
from __future__ import annotations
44

55
import json
66
import logging
77

88
import voluptuous as vol
9+
910
from homeassistant.components import mqtt
1011
from homeassistant.core import CALLBACK_TYPE
1112

12-
from .base import ExpressionDecorator, AutoKwargsDecorator
1313
from ..decorator_abc import DispatchData, TriggerDecorator
14+
from .base import AutoKwargsDecorator, ExpressionDecorator
1415

1516
_LOGGER = logging.getLogger(__name__)
1617

custom_components/pyscript/decorators/service.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,27 @@
33
from __future__ import annotations
44

55
import ast
6+
from collections import OrderedDict
67
import io
78
import logging
89
import typing
9-
from collections import OrderedDict
1010

1111
import voluptuous as vol
1212
import yaml
13+
1314
from homeassistant.const import SERVICE_RELOAD
1415
from homeassistant.core import ServiceCall, SupportsResponse
1516
from homeassistant.helpers.service import async_set_service_schema
16-
from ..decorator import FunctionDecoratorManager
1717

18-
from ..decorator_abc import Decorator
1918
from .. import DOMAIN, SERVICE_JUPYTER_KERNEL_START, AstEval, Function, State
19+
from ..decorator import FunctionDecoratorManager
20+
from ..decorator_abc import Decorator
2021

2122
_LOGGER = logging.getLogger(__name__)
2223

2324

2425
def service_validator(args: list[str]) -> list[str]:
26+
"""Validate and normalize service name."""
2527
if len(args) == 0:
2628
return []
2729
s = str(args[0]).strip()
@@ -47,11 +49,12 @@ class ServiceDecorator(Decorator):
4749
description: dict
4850

4951
async def validate(self) -> None:
52+
"""Validate the arguments."""
5053
await super().validate()
5154

5255
if len(self.args) != 2:
5356
self.args = [DOMAIN, self.dm.func_name]
54-
# FIXME This condition doesnt verify the domain - it may not be Pyscript.
57+
# FIXME This condition doesn't verify the domain - it may not be Pyscript.
5558
# The error is kept for backward compatibility.
5659
if self.args[1] in (SERVICE_RELOAD, SERVICE_JUPYTER_KERNEL_START):
5760
# FIXME For test compatibility. Update the message in the future.
@@ -81,7 +84,6 @@ async def validate(self) -> None:
8184
else:
8285
fields = OrderedDict()
8386
for arg in ast_funcdef.args.posonlyargs + ast_funcdef.args.args:
84-
# _LOGGER.warning(f"------ {type(arg.arg)} {arg.arg}")
8587
fields[arg.arg] = OrderedDict(description=f"argument {arg.arg}")
8688
self.description = {"description": desc, "fields": fields}
8789

@@ -99,7 +101,6 @@ async def _service_callback(self, call: ServiceCall) -> None:
99101
}
100102
func_args.update(call.data)
101103

102-
#
103104
async def do_service_call(func, ast_ctx, data):
104105
try:
105106
_LOGGER.debug("Service call start: %s", func.name)
@@ -112,7 +113,6 @@ async def do_service_call(func, ast_ctx, data):
112113
_LOGGER.exception(exc)
113114
return None
114115

115-
#
116116
task = Function.create_task(do_service_call(self.dm.eval_func, ast_ctx, func_args))
117117
await task
118118
return task.result()

custom_components/pyscript/decorators/state.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1+
"""State decorators."""
2+
13
import asyncio
4+
import logging
25
import re
6+
from typing import Any
7+
8+
import voluptuous as vol
39

410
from homeassistant.helpers import config_validation as cv
511

6-
from .base import ExpressionDecorator, AutoKwargsDecorator
712
from ..decorator import WaitUntilDecoratorManager
8-
from ..decorator_abc import *
13+
from ..decorator_abc import DecoratorManagerStatus, DispatchData, TriggerDecorator, TriggerHandlerDecorator
914
from ..state import State
1015
from ..trigger import ident_any_values_changed, ident_values_changed
16+
from .base import AutoKwargsDecorator, ExpressionDecorator
1117

1218
STATE_RE = re.compile(r"\w+\.\w+(\.((\w+)|\*))?$")
1319

@@ -36,6 +42,7 @@ async def validate(self) -> None:
3642
self.var_names = await self._ast_expression.get_names()
3743

3844
async def handle_dispatch(self, data: DispatchData) -> bool:
45+
"""Handle dispatch events."""
3946
new_vars = data.trigger_context.get("new_vars", {})
4047
active_vars = State.notify_var_get(self.var_names, new_vars)
4148
return await self.check_expression_vars(active_vars)
@@ -91,7 +98,11 @@ class StateTriggerDecorator(TriggerDecorator, ExpressionDecorator, AutoKwargsDec
9198
true_entered_at: float | None
9299
false_entered_at: float | None
93100

101+
last_func_args: dict[str, Any]
102+
last_new_vars: dict[str, Any]
103+
94104
async def validate(self) -> None:
105+
"""Validate and normalize arguments."""
95106
await super().validate()
96107
self.state_trig_ident = set()
97108
self.state_trig_ident_any = set()
@@ -136,18 +147,19 @@ async def validate(self) -> None:
136147
def _diff(self, dt: float, now: float) -> str:
137148
if dt is None:
138149
return "None"
139-
else:
140-
return f"{(now-dt):g} ago"
150+
return f"{(now - dt):g} ago"
141151

142152
async def _check_new_state(self, trig_ok: bool):
143153
now = asyncio.get_running_loop().time()
144154
if _LOGGER.isEnabledFor(logging.DEBUG):
145155
msg = f"check_new_state: {self}"
146156
msg += f"\ntrig_ok: {trig_ok} now {now} func_args: {self.last_func_args} new_vars: {self.last_new_vars}"
147157
if self.true_entered_at:
148-
msg += f"\ntrue_entered_at: {self.true_entered_at}({(now-self.true_entered_at):g} ago)\n"
158+
msg += f"\ntrue_entered_at: {self.true_entered_at}({(now - self.true_entered_at):g} ago)\n"
149159
if self.false_entered_at:
150-
msg += f"\nfalse_entered_at: {self.false_entered_at}({(now-self.false_entered_at):g} ago)\n"
160+
msg += (
161+
f"\nfalse_entered_at: {self.false_entered_at}({(now - self.false_entered_at):g} ago)\n"
162+
)
151163
_LOGGER.debug(msg)
152164

153165
state_hold_false_passed = False
@@ -277,8 +289,7 @@ async def _cycle(self):
277289
async def _is_trig_ok(self) -> bool:
278290
if self.has_expression():
279291
return await self.check_expression_vars(self.last_new_vars)
280-
else:
281-
return True
292+
return True
282293

283294
def _on_task_done(self, task: asyncio.Task) -> None:
284295
if task.cancelled():

custom_components/pyscript/decorators/task.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
import logging
66

77
import voluptuous as vol
8+
89
from homeassistant.helpers import config_validation as cv
910

10-
from .base import AutoKwargsDecorator
11-
from ..decorator_abc import DispatchData, CallHandlerDecorator
11+
from ..decorator_abc import CallHandlerDecorator, DispatchData
1212
from ..function import Function
13+
from .base import AutoKwargsDecorator
1314

1415
_LOGGER = logging.getLogger(__name__)
1516

@@ -24,6 +25,7 @@ class TaskUniqueDecorator(CallHandlerDecorator, AutoKwargsDecorator):
2425
kill_me: bool
2526

2627
async def handle_call(self, data: DispatchData) -> bool:
28+
"""Handle call."""
2729
if self.kill_me:
2830
if Function.unique_name_used(data.call_ast_ctx, self.args[0]):
2931
_LOGGER.debug(

0 commit comments

Comments
 (0)