Skip to content

Commit 9bb2a41

Browse files
committed
fix ruff warnings
1 parent 813d8d8 commit 9bb2a41

6 files changed

Lines changed: 30 additions & 24 deletions

File tree

custom_components/pyscript/decorator.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import asyncio
77
import logging
88
import os
9-
from typing import Any, ClassVar, Type, TypeVar
9+
from typing import Any, ClassVar, TypeVar
1010
import weakref
1111

1212
from homeassistant.config_entries import ConfigEntry
@@ -32,7 +32,7 @@
3232
class DecoratorRegistry:
3333
"""Decorator registry."""
3434

35-
_decorators: dict[str, Type[Decorator]] # decorator name to class
35+
_decorators: dict[str, type[Decorator]] # decorator name to class
3636
hass: ClassVar[HomeAssistant]
3737
prefix: ClassVar[str] = "e"
3838

@@ -60,13 +60,13 @@ def init(cls, hass: HomeAssistant, config_entry: ConfigEntry = None) -> None:
6060

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

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

6565
for dec_type in DECORATORS:
6666
cls.register(dec_type)
6767

6868
@classmethod
69-
def register(cls, dec_type: Type[Decorator]):
69+
def register(cls, dec_type: type[Decorator]) -> None:
7070
"""Register a decorator."""
7171
if not dec_type.name:
7272
raise TypeError(f"Decorator name is required {dec_type}")
@@ -103,7 +103,7 @@ async def get_decorator_by_expr(cls, ast_ctx: AstEval, dec_expr: ast.expr) -> De
103103
return None
104104

105105
@classmethod
106-
async def wait_until(cls, ast_ctx: AstEval, *arg, **kwargs):
106+
async def wait_until(cls, ast_ctx: AstEval, *_arg: Any, **kwargs: Any) -> Any:
107107
"""Build a temporary decorator manager that waits until one of trigger decorators fires."""
108108
func_args = set(kwargs.keys())
109109
if len(func_args) == 0:

custom_components/pyscript/decorator_abc.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class DispatchData:
4646
call_ast_ctx: AstEval | None = field(default=None, kw_only=True)
4747
hass_context: Context | None = field(default=None, kw_only=True)
4848

49-
# Normally shouldnt be used.
49+
# Normally shouldn't be used.
5050
exception: Exception | None = field(default=None, kw_only=True)
5151
exception_text: str | None = field(default=None, kw_only=True)
5252

@@ -90,7 +90,8 @@ async def validate(self) -> None:
9090
self.kwargs = self.kwargs_schema(self.raw_kwargs)
9191

9292
except vol.Invalid as err:
93-
# FIXME For test compatibility. Update the message in the future.
93+
# Keep this wording for transition compatibility. Once the legacy
94+
# subsystem is removed, update the message and related tests.
9495
if len(err.path) == 1:
9596
if "extra keys not allowed" in err.msg:
9697
message = f"invalid keyword argument '{err.path[0]}'"
@@ -105,9 +106,11 @@ async def validate(self) -> None:
105106
)
106107
raise type_error from err
107108

109+
@abstractmethod
108110
async def start(self):
109111
"""Start the decorator."""
110112

113+
@abstractmethod
111114
async def stop(self):
112115
"""Stop the decorator."""
113116

@@ -156,7 +159,7 @@ def add(self, decorator: Decorator) -> None:
156159
self._decorators.append(decorator)
157160
decorator.dm = self
158161

159-
def get_decorators[DT](self, decorator_type: type[DT] | None = None) -> list[DT]: # noqa: D102
162+
def get_decorators[DT](self, decorator_type: type[DT] | None = None) -> list[DT]:
160163
"""Get decorators of a specific type."""
161164
if decorator_type is None:
162165
return self._decorators.copy()
@@ -242,7 +245,7 @@ def __init_subclass__(cls, **kwargs):
242245
{vol.Optional("kwargs"): vol.Coerce(dict[str, Any], msg="should be type dict")}
243246
)
244247

245-
async def dispatch(self, data: DispatchData):
248+
async def dispatch(self, data: DispatchData) -> None:
246249
"""Dispatch a trigger call to the function."""
247250
if not data.trigger:
248251
data.trigger = self
@@ -260,7 +263,8 @@ async def validate(self) -> None:
260263
await super().validate()
261264
decorators = self.dm.get_decorators(TriggerDecorator)
262265
if len(decorators) == 0:
263-
# FIXME For test compatibility. Update the message in the future.
266+
# Keep this wording for transition compatibility. Once the legacy
267+
# subsystem is removed, update the message and related tests.
264268
trig_decorators_reqd = {
265269
"event_trigger",
266270
"mqtt_trigger",

custom_components/pyscript/decorators/service.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ async def validate(self) -> None:
5454

5555
if len(self.args) != 2:
5656
self.args = [DOMAIN, self.dm.func_name]
57-
# FIXME This condition doesn't verify the domain - it may not be Pyscript.
58-
# The error is kept for backward compatibility.
57+
# This condition still does not verify the domain. Keep the behavior
58+
# for transition compatibility and revisit it after the legacy
59+
# subsystem is removed.
5960
if self.args[1] in (SERVICE_RELOAD, SERVICE_JUPYTER_KERNEL_START):
60-
# FIXME For test compatibility. Update the message in the future.
61+
# Keep this wording for transition compatibility. Once the legacy
62+
# subsystem is removed, update the message and related tests.
6163
raise SyntaxError(
6264
f"function '{self.dm.func_name}' defined in {self.dm.ast_ctx.get_global_ctx_name()}: "
6365
f"@service conflicts with builtin service"
@@ -72,7 +74,7 @@ async def validate(self) -> None:
7274
try:
7375
desc = desc[4:].lstrip(" \n\r")
7476
file_desc = io.StringIO(desc)
75-
self.description = yaml.load(file_desc, Loader=yaml.BaseLoader) or OrderedDict()
77+
self.description = yaml.safe_load(file_desc) or OrderedDict()
7678
file_desc.close()
7779
except Exception as exc:
7880
self.dm.logger.error(

custom_components/pyscript/decorators/state.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class StateActiveDecorator(TriggerHandlerDecorator, ExpressionDecorator):
2828
vol.All(
2929
vol.Length(
3030
min=1, max=1, msg="got 2 arguments, expected 1"
31-
), # FIXME For test compatibility. Update the message in the future.
31+
), # Keep this wording for transition compatibility.
3232
vol.All([str]),
3333
)
3434
)
@@ -149,7 +149,7 @@ def _diff(self, dt: float, now: float) -> str:
149149
return "None"
150150
return f"{(now - dt):g} ago"
151151

152-
async def _check_new_state(self, trig_ok: bool):
152+
async def _check_new_state(self, trig_ok: bool) -> None:
153153
now = asyncio.get_running_loop().time()
154154
if _LOGGER.isEnabledFor(logging.DEBUG):
155155
msg = f"check_new_state: {self}"
@@ -206,7 +206,7 @@ async def _check_new_state(self, trig_ok: bool):
206206
_LOGGER.debug("state_hold_false started, %s", self)
207207
self.false_entered_at = now
208208

209-
async def _check_state_hold(self):
209+
async def _check_state_hold(self) -> None:
210210
if self.true_entered_at is None:
211211
raise RuntimeError(f"state_hold not started for {self}")
212212

@@ -218,7 +218,7 @@ async def _check_state_hold(self):
218218
DispatchData(self.last_func_args, trigger_context={"new_vars": self.last_new_vars})
219219
)
220220

221-
async def _cycle(self):
221+
async def _cycle(self) -> None:
222222
"""Run the trigger cycle with state_hold and state_hold_false logic."""
223223
loop = asyncio.get_running_loop()
224224

@@ -283,7 +283,7 @@ async def _cycle(self):
283283
else:
284284
trig_ok = False
285285
await self._check_new_state(trig_ok)
286-
except asyncio.TimeoutError:
286+
except TimeoutError:
287287
await self._check_state_hold()
288288

289289
async def _is_trig_ok(self) -> bool:
@@ -296,7 +296,7 @@ def _on_task_done(self, task: asyncio.Task) -> None:
296296
return
297297
exc = task.exception()
298298
if exc is not None:
299-
self.dm.logger.exception(f"{self} failed", exc_info=exc)
299+
self.dm.logger.error("%s failed", self, exc_info=exc)
300300

301301
async def start(self) -> None:
302302
"""Start the trigger."""

custom_components/pyscript/decorators/timing.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
def dt_now():
2323
"""Return current time."""
24-
# FIXME For test compatibility. The tests patch this function
24+
# Keep this wrapper so tests can patch it during the transition.
2525
return trigger.dt_now()
2626

2727

@@ -70,7 +70,7 @@ class TimeTriggerDecorator(TriggerDecorator):
7070
vol.Length(min=0),
7171
vol.All(
7272
[str], msg="argument 2 should be a string"
73-
), # FIXME For test compatibility. Update the message in the future.
73+
), # Keep this wording for transition compatibility.
7474
)
7575
)
7676

@@ -154,7 +154,7 @@ def _on_task_done(self, task: asyncio.Task) -> None:
154154
return
155155
exc = task.exception()
156156
if exc is not None:
157-
self.dm.logger.exception(f"{self} failed", exc_info=exc)
157+
self.dm.logger.error("%s failed", self, exc_info=exc)
158158

159159
async def start(self) -> None:
160160
"""Start the decorator."""

tests/test_init.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from custom_components.pyscript.global_ctx import GlobalContextMgr
1616
from custom_components.pyscript.state import State
1717
from homeassistant import loader
18-
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED, EVENT_STATE_CHANGED
18+
from homeassistant.const import EVENT_STATE_CHANGED
1919
from homeassistant.core import Context
2020
from homeassistant.helpers.service import async_get_all_descriptions
2121
from homeassistant.setup import async_setup_component

0 commit comments

Comments
 (0)