chore: ruff cleanup — fix 7 long-standing lint findings
Mechanical, no behavior change. `ruff check src/ tests/` now passes with zero findings. - cli.py:147 (SIM105) — replace `try/except SynologyError/pass` around the cleanup logout with `contextlib.suppress(SynologyError)`. - compose.py:271 (B007) — drop the unused `i` from the env_list preview-detection loop (the apply loop below still uses enumerate). - compose.py:329 (E501) — extract `verb = "Updated" if … else "Added"` into a local before the return so the f-string fits in 100 cols. - images.py:237 (E501) — extract `stopped_name = in_use_stopped[0]` before the return and split the message across two f-strings. - test_auth.py:38, 127, 140 (SIM117) — combine nested `with patch(…):` / `with pytest.raises(…):` into single parenthesised with-statements. 236 tests pass. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import json
|
||||
import logging
|
||||
import sys
|
||||
@@ -144,10 +145,8 @@ async def _run_setup() -> None:
|
||||
client.sid = sid
|
||||
click.echo(click.style("Login successful!", fg="green"))
|
||||
# Logout cleanly
|
||||
try:
|
||||
with contextlib.suppress(SynologyError):
|
||||
await client.request("SYNO.API.Auth", "logout", version=6, params={})
|
||||
except SynologyError:
|
||||
pass
|
||||
else:
|
||||
click.echo(click.style("Login failed: no session ID returned.", fg="red"), err=True)
|
||||
sys.exit(1)
|
||||
|
||||
@@ -268,7 +268,7 @@ def register_compose(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None
|
||||
# Determine previous value and build description
|
||||
old_value: str | None = None
|
||||
if isinstance(env_list, list):
|
||||
for i, entry in enumerate(env_list):
|
||||
for entry in env_list:
|
||||
if isinstance(entry, str) and entry.startswith(f"{var_name}="):
|
||||
old_value = entry.split("=", 1)[1]
|
||||
break
|
||||
@@ -325,8 +325,9 @@ def register_compose(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None
|
||||
except Exception as e:
|
||||
return f"Error writing compose file: {e}"
|
||||
|
||||
verb = "Updated" if action == "update" else "Added"
|
||||
return (
|
||||
f"{'Updated' if action == 'update' else 'Added'} env var in '{service_name}' ({project_name}):\n"
|
||||
f"{verb} env var in '{service_name}' ({project_name}):\n"
|
||||
f" {var_name}={var_value}\n\n"
|
||||
f"Tip: Run redeploy_project('{project_name}', confirmed=True) to apply the change."
|
||||
)
|
||||
|
||||
@@ -233,8 +233,10 @@ def register_images(mcp: FastMCP, config: AppConfig, client: DsmClient) -> None:
|
||||
)
|
||||
|
||||
if in_use_stopped:
|
||||
stopped_name = in_use_stopped[0]
|
||||
return (
|
||||
f"Cannot delete '{display_name}': image is used by stopped container '{in_use_stopped[0]}'.\n"
|
||||
f"Cannot delete '{display_name}': image is used by stopped container "
|
||||
f"'{stopped_name}'.\n"
|
||||
f"Delete the container first or run system_prune to clean up stopped containers."
|
||||
)
|
||||
|
||||
|
||||
+12
-6
@@ -35,8 +35,10 @@ def test_resolve_credentials_no_credentials(monkeypatch):
|
||||
config = make_config()
|
||||
auth = AuthManager(config)
|
||||
|
||||
with patch("keyring.get_password", return_value=None):
|
||||
with pytest.raises(AuthenticationError, match="No credentials found"):
|
||||
with (
|
||||
patch("keyring.get_password", return_value=None),
|
||||
pytest.raises(AuthenticationError, match="No credentials found"),
|
||||
):
|
||||
auth.resolve_credentials()
|
||||
|
||||
|
||||
@@ -124,8 +126,10 @@ async def test_login_2fa_required():
|
||||
mock_client = AsyncMock()
|
||||
mock_client.request.side_effect = SynologyError("2FA required", code=403)
|
||||
|
||||
with patch.object(auth, "resolve_credentials", return_value=("user", "pass", None)):
|
||||
with pytest.raises(AuthenticationError, match="2FA is required"):
|
||||
with (
|
||||
patch.object(auth, "resolve_credentials", return_value=("user", "pass", None)),
|
||||
pytest.raises(AuthenticationError, match="2FA is required"),
|
||||
):
|
||||
await auth.login(mock_client)
|
||||
|
||||
|
||||
@@ -137,8 +141,10 @@ async def test_login_no_sid_returned():
|
||||
mock_client = AsyncMock()
|
||||
mock_client.request.return_value = {} # No 'sid' key
|
||||
|
||||
with patch.object(auth, "resolve_credentials", return_value=("user", "pass", None)):
|
||||
with pytest.raises(AuthenticationError, match="no session ID"):
|
||||
with (
|
||||
patch.object(auth, "resolve_credentials", return_value=("user", "pass", None)),
|
||||
pytest.raises(AuthenticationError, match="no session ID"),
|
||||
):
|
||||
await auth.login(mock_client)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user