Skip to content

Commit af0338a

Browse files
sergeykadSergey
andauthored
chore(internal): enable targeted ruff pylint rules, fix 104 violations (#2102)
* chore(internal): enable targeted ruff pylint rules, fix 104 violations - Add PLE (whole prefix) plus 11 individually-selected PLC/PLR/PLW codes to pyproject.toml, with rationale for why the PL family isn't selected wholesale (PLC0415 fights lazy-init, PLR2004/PLR0913/PLR0917/PLR0911 are noisy on this codebase's patterns) - Fix all 104 violations: explicit check=False on 36 subprocess.run calls, remove 23 unnecessary lambdas, narrow two global statements to only what's assigned, collapse if/else nests to elif, add maxsplit to split/rsplit calls, and misc pylint conventions (dict-index-missing, repeated-equality, manual-from-import, useless-return) - Bump webhook-proxy dev add-on version 2.1.1.dev2 -> 2.1.1.dev3 (with CHANGELOG entry), required by webhook-proxy-dev-version-guard since this PR touches homeassistant-addon-webhook-proxy-dev/ * fix: keep stable webhook-proxy tree dev-first-compliant Per Codex review: allow-stable-edit is documented for stable-only hotfixes, not routine maintenance sweeps. Revert the 2 lint fixes in homeassistant-addon-webhook-proxy/ (keep them in the -dev flavor only) and add a temporary per-file-ignore for PLC0207/PLR5501 scoped to the stable tree, removed at the next promote. --------- Co-authored-by: Sergey <sergey@example.com>
1 parent 02f202b commit af0338a

54 files changed

Lines changed: 183 additions & 160 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

custom_components/ha_mcp_tools/config_flow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ def _sentence_prefix(sentence: str, language: str, english: str) -> str:
228228
if not sentence:
229229
return sentence
230230
if (
231-
language.split("-")[0].lower() in _NO_ASCII_SENTENCE_SPACE
231+
language.split("-", maxsplit=1)[0].lower() in _NO_ASCII_SENTENCE_SPACE
232232
and sentence != english
233233
):
234234
return sentence

custom_components/ha_mcp_tools/websocket_api.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,8 +1977,7 @@ def _name_tier(query_lower: str, texts: Any, *, exact: bool) -> int | None:
19771977
if query_norm and query_norm in _sep_normalized(text_lower):
19781978
return 100
19791979
ratio = _calc_ratio(query_lower, text_lower)
1980-
if ratio > best_ratio:
1981-
best_ratio = ratio
1980+
best_ratio = max(best_ratio, ratio)
19821981
if not exact and best_ratio >= FUZZY_THRESHOLD:
19831982
return best_ratio
19841983
return None
@@ -3206,7 +3205,7 @@ def _exposure_enrichment(
32063205
rather than crashing the join).
32073206
"""
32083207
join = _registry_enrichment(view, entity_id)
3209-
domain = entity_id.split(".")[0] if "." in entity_id else ""
3208+
domain = entity_id.split(".", maxsplit=1)[0] if "." in entity_id else ""
32103209
info: dict[str, Any] = {
32113210
"domain": domain,
32123211
"area": join["area"],
@@ -5196,7 +5195,7 @@ def _assist_default_exposed(hass: HomeAssistant, entity_id: str) -> bool:
51965195
or getattr(entry, "hidden_by", None) is not None
51975196
):
51985197
return False
5199-
domain = entity_id.split(".")[0] if "." in entity_id else entity_id
5198+
domain = entity_id.split(".", maxsplit=1)[0] if "." in entity_id else entity_id
52005199
if domain in DEFAULT_EXPOSED_DOMAINS:
52015200
return True
52025201
from homeassistant.exceptions import HomeAssistantError

homeassistant-addon-webhook-proxy-dev/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ history from before the fork.
99
-->
1010

1111

12+
## v2.1.1.dev3 (2026-07-31)
13+
14+
Internal: lint cleanup (ruff pylint rules) — no behavior change.
15+
16+
1217
## v2.1.1.dev2 (2026-07-30)
1318

1419
Documentation: warn Tailscale Funnel users that Claude.ai connectors require the

homeassistant-addon-webhook-proxy-dev/config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: "Nabu Casa - Webhook Proxy for HA MCP (Dev)"
22
description: "DEV CHANNEL (unstable) — remote access proxy via Nabu Casa or any reverse proxy. Cannot run alongside the stable Webhook Proxy add-on."
3-
version: "2.1.1.dev2"
3+
version: "2.1.1.dev3"
44
slug: "ha_mcp_webhook_proxy_dev"
55
url: "https://github.com/homeassistant-ai/ha-mcp"
66
stage: experimental

homeassistant-addon-webhook-proxy-dev/mcp_proxy_dev/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,9 @@ def _validate_and_mask_target(target_url: str, webhook_id: str) -> str:
280280
"""
281281
# Mask sensitive values in logs to avoid leaking secrets
282282
if "/private_" in target_url:
283-
masked_target = target_url.split("/private_")[0] + "/private_********"
283+
masked_target = (
284+
target_url.split("/private_", maxsplit=1)[0] + "/private_********"
285+
)
284286
else:
285287
masked_target = target_url
286288
masked_wh = webhook_id[:6] + "..." if len(webhook_id) > 6 else "***"

homeassistant-addon-webhook-proxy-dev/mcp_proxy_dev/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
"dependencies": ["webhook"],
88
"documentation": "https://github.com/homeassistant-ai/ha-mcp",
99
"iot_class": "local_push",
10-
"version": "2.1.1.dev2"
10+
"version": "2.1.1.dev3"
1111
}

homeassistant-addon-webhook-proxy-dev/start.py

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,41 +1509,40 @@ def _install_integration_and_handle_restart() -> None:
15091509
{"notification_id": "mcp_proxy_dev_restart"},
15101510
)
15111511
log_info("Setup completed after HA restart")
1512+
elif not _ensure_config_entry():
1513+
log_error(
1514+
"Could not create config entry. Webhook is NOT active. "
1515+
"Restart Home Assistant; if the problem persists, "
1516+
"remove and re-add the integration manually from "
1517+
"Settings → Devices & Services."
1518+
)
1519+
_ha_core_api(
1520+
"POST",
1521+
"/services/persistent_notification/create",
1522+
{
1523+
"title": ("MCP Webhook Proxy: webhook URL is not active"),
1524+
"message": (
1525+
"The addon could not create the integration's "
1526+
"config entry, so the webhook URL is currently "
1527+
"**not active**. Restart Home Assistant; if "
1528+
"the problem persists, remove and re-add the "
1529+
"MCP Webhook Proxy integration from "
1530+
"Settings → Devices & Services."
1531+
),
1532+
"notification_id": "mcp_proxy_dev_setup_failed",
1533+
},
1534+
)
15121535
else:
1513-
if not _ensure_config_entry():
1514-
log_error(
1515-
"Could not create config entry. Webhook is NOT active. "
1516-
"Restart Home Assistant; if the problem persists, "
1517-
"remove and re-add the integration manually from "
1518-
"Settings → Devices & Services."
1519-
)
1520-
_ha_core_api(
1521-
"POST",
1522-
"/services/persistent_notification/create",
1523-
{
1524-
"title": ("MCP Webhook Proxy: webhook URL is not active"),
1525-
"message": (
1526-
"The addon could not create the integration's "
1527-
"config entry, so the webhook URL is currently "
1528-
"**not active**. Restart Home Assistant; if "
1529-
"the problem persists, remove and re-add the "
1530-
"MCP Webhook Proxy integration from "
1531-
"Settings → Devices & Services."
1532-
),
1533-
"notification_id": "mcp_proxy_dev_setup_failed",
1534-
},
1535-
)
1536-
else:
1537-
# Reload the config entry so the integration reads the fresh
1538-
# config file we just wrote (it may have loaded with stale data
1539-
# during HA boot, before this addon started).
1540-
_reload_config_entry()
1541-
# Dismiss any leftover restart notification from first install
1542-
_ha_core_api(
1543-
"POST",
1544-
"/services/persistent_notification/dismiss",
1545-
{"notification_id": "mcp_proxy_dev_restart"},
1546-
)
1536+
# Reload the config entry so the integration reads the fresh
1537+
# config file we just wrote (it may have loaded with stale data
1538+
# during HA boot, before this addon started).
1539+
_reload_config_entry()
1540+
# Dismiss any leftover restart notification from first install
1541+
_ha_core_api(
1542+
"POST",
1543+
"/services/persistent_notification/dismiss",
1544+
{"notification_id": "mcp_proxy_dev_restart"},
1545+
)
15471546

15481547

15491548
def _enforce_oauth_or_disable(enable_oauth: bool) -> None:

pyproject.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,26 @@ select = [
140140
"A", # builtin shadowing
141141
"LOG", # logging best practices
142142
"SIM", # simplify
143+
"PLE", # pylint errors (real bugs: bad logging args, await outside async)
144+
# Targeted pylint conventions/refactors/warnings. The PL family is NOT
145+
# selected wholesale: PLC0415 (import-outside-top-level) fights the
146+
# deliberate lazy-init architecture, and PLR2004 (magic values),
147+
# PLR0913/PLR0917 (wide FastMCP tool signatures) and PLR0911 (too many
148+
# returns -- a separate signal from C901's cyclomatic complexity, and
149+
# noisy on this codebase's early-return validation style) are noise
150+
# here. Add codes individually so a new upstream PLR rule does not land
151+
# enabled by default.
152+
"PLC0206", # dict-index-missing-items
153+
"PLC0207", # missing-maxsplit-arg
154+
"PLR0402", # manual-from-import
155+
"PLR1711", # useless-return
156+
"PLR1714", # repeated-equality-comparison
157+
"PLR1730", # if-stmt-min-max
158+
"PLR5501", # collapsible-else-if
159+
"PLW0108", # unnecessary-lambda
160+
"PLW0602", # global-variable-not-assigned
161+
"PLW1510", # subprocess-run-without-check
162+
"PLW2901", # redefined-loop-name
143163
]
144164
ignore = [
145165
"E501", # line too long — formatter handles this
@@ -162,6 +182,12 @@ ignore = [
162182
[tool.ruff.lint.per-file-ignores]
163183
"__init__.py" = ["F401"]
164184
"tests/**/*" = ["E501", "B011"]
185+
# Temporary: the equivalent PLC0207/PLR5501 fixes landed in
186+
# homeassistant-addon-webhook-proxy-dev/ only, per the dev-first/promote-only
187+
# flow (allow-stable-edit is for stable-only hotfixes, not routine sweeps —
188+
# see homeassistant-addon-webhook-proxy/AGENTS.md "Dev-first, promote-only").
189+
# Remove this ignore once the next promote carries the fix into stable.
190+
"homeassistant-addon-webhook-proxy/**" = ["PLC0207", "PLR5501"]
165191
# C901 is enforced repo-wide with no per-file exemptions (the grandfathered
166192
# list was fully cleared by issue #925). Do NOT add "path" = ["C901"] entries
167193
# here — extract helpers to bring the function below the threshold instead:

scripts/build_mirror_release_notes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ def _run_git(args: list[str], repo_dir: Path) -> str:
110110
cwd=repo_dir,
111111
capture_output=True,
112112
text=True,
113+
check=False,
113114
)
114115
if result.returncode != 0:
115116
raise RuntimeError(f"git {' '.join(args)} failed: {result.stderr.strip()}")

src/ha_mcp/__main__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,6 @@ def _get_timestamped_uvicorn_log_config() -> dict:
574574

575575
async def _cleanup_resources() -> None:
576576
"""Clean up all server resources gracefully."""
577-
global _server
578-
579577
logger.info("Cleaning up server resources...")
580578

581579
# Close WebSocket listener service if running
@@ -730,7 +728,7 @@ def _signal_handler(signum: int, frame: Any) -> None:
730728
This handler initiates graceful shutdown on first signal.
731729
On second signal, forces immediate exit.
732730
"""
733-
global _shutdown_in_progress, _shutdown_event
731+
global _shutdown_in_progress
734732

735733
sig_name = signal.Signals(signum).name
736734

0 commit comments

Comments
 (0)