From 595813bd2f37cf8bc6cb398233b45150a63e3200 Mon Sep 17 00:00:00 2001 From: ljadach <200298748+ljadach@users.noreply.github.com> Date: Mon, 13 Apr 2026 00:13:11 +0200 Subject: [PATCH 1/2] chore: fix ruff lint errors in _analyze_tasks and test imports Silences three pre-existing ruff findings that have been red on main since ac16da8: - SIM105: use contextlib.suppress(Exception) for the ZoneInfo call - SIM108: collapse the now = datetime.now(...) if/else into a ternary - F401: drop unused timedelta import in test_analyze_tasks_with_timezone No functional change. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/rtm_mcp/tools/tasks.py | 10 +++------- tests/test_tools/test_tasks.py | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/rtm_mcp/tools/tasks.py b/src/rtm_mcp/tools/tasks.py index b0e1c40..53fe257 100644 --- a/src/rtm_mcp/tools/tasks.py +++ b/src/rtm_mcp/tools/tasks.py @@ -971,6 +971,7 @@ def _analyze_tasks(tasks: list[dict[str, Any]], timezone: str | None = None) -> without_estimate = 0 tags_used: set[str] = set() + import contextlib from datetime import UTC, datetime from zoneinfo import ZoneInfo @@ -978,15 +979,10 @@ def _analyze_tasks(tasks: list[dict[str, Any]], timezone: str | None = None) -> # RTM due dates are relative to the user's timezone user_tz = None if timezone: - try: + with contextlib.suppress(Exception): user_tz = ZoneInfo(timezone) - except Exception: - pass - if user_tz: - now = datetime.now(user_tz) - else: - now = datetime.now(UTC) + now = datetime.now(user_tz) if user_tz else datetime.now(UTC) today = now.date() for task in tasks: diff --git a/tests/test_tools/test_tasks.py b/tests/test_tools/test_tasks.py index 7a82111..2434e21 100644 --- a/tests/test_tools/test_tasks.py +++ b/tests/test_tools/test_tasks.py @@ -47,7 +47,7 @@ def test_analyze_overdue_tasks(self) -> None: def test_analyze_tasks_with_timezone(self) -> None: """Test that timezone is properly applied for date comparisons.""" - from datetime import UTC, datetime, timedelta + from datetime import UTC, datetime from zoneinfo import ZoneInfo from rtm_mcp.tools.tasks import _analyze_tasks From e9e47b7eb5ae149e785883d4f7fb56f84122a3d7 Mon Sep 17 00:00:00 2001 From: ljadach <200298748+ljadach@users.noreply.github.com> Date: Mon, 13 Apr 2026 00:13:47 +0200 Subject: [PATCH 2/2] chore: apply ruff format to response_builder, notes, utilities Pure mechanical output of 'uv run ruff format'. Three files had dict literals passed to list.append(...) that ruff now wants split across lines. No functional change. This greens the 'ruff format --check' CI step, which has been failing on main alongside the check errors fixed in 595813b. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/rtm_mcp/response_builder.py | 44 ++++++++++++++------------- src/rtm_mcp/tools/notes.py | 16 +++++----- src/rtm_mcp/tools/utilities.py | 54 +++++++++++++++++++-------------- 3 files changed, 64 insertions(+), 50 deletions(-) diff --git a/src/rtm_mcp/response_builder.py b/src/rtm_mcp/response_builder.py index 3215406..1c632fe 100644 --- a/src/rtm_mcp/response_builder.py +++ b/src/rtm_mcp/response_builder.py @@ -198,27 +198,29 @@ def parse_tasks_response(result: dict[str, Any]) -> list[dict[str, Any]]: notes = [notes] for t in task_data: - tasks.append({ - "id": t.get("id"), - "taskseries_id": ts.get("id"), - "list_id": list_id, - "name": ts.get("name"), - "due": t.get("due") or None, - "has_due_time": t.get("has_due_time") == "1", - "start": t.get("start") or None, - "has_start_time": t.get("has_start_time") == "1", - "completed": t.get("completed") or None, - "deleted": t.get("deleted") or None, - "priority": t.get("priority", "N"), - "postponed": int(t.get("postponed", 0)), - "estimate": t.get("estimate") or None, - "tags": tags if tags else [], - "notes": notes, - "url": ts.get("url") or None, - "location_id": ts.get("location_id") or None, - "created": ts.get("created") or None, - "modified": ts.get("modified") or None, - }) + tasks.append( + { + "id": t.get("id"), + "taskseries_id": ts.get("id"), + "list_id": list_id, + "name": ts.get("name"), + "due": t.get("due") or None, + "has_due_time": t.get("has_due_time") == "1", + "start": t.get("start") or None, + "has_start_time": t.get("has_start_time") == "1", + "completed": t.get("completed") or None, + "deleted": t.get("deleted") or None, + "priority": t.get("priority", "N"), + "postponed": int(t.get("postponed", 0)), + "estimate": t.get("estimate") or None, + "tags": tags if tags else [], + "notes": notes, + "url": ts.get("url") or None, + "location_id": ts.get("location_id") or None, + "created": ts.get("created") or None, + "modified": ts.get("modified") or None, + } + ) return tasks diff --git a/src/rtm_mcp/tools/notes.py b/src/rtm_mcp/tools/notes.py index 31e941a..730e075 100644 --- a/src/rtm_mcp/tools/notes.py +++ b/src/rtm_mcp/tools/notes.py @@ -228,13 +228,15 @@ async def get_task_notes( formatted_notes = [] for note in notes: - formatted_notes.append({ - "id": note.get("id"), - "title": note.get("title", ""), - "body": note.get("$t", note.get("body", "")), - "created": note.get("created"), - "modified": note.get("modified"), - }) + formatted_notes.append( + { + "id": note.get("id"), + "title": note.get("title", ""), + "body": note.get("$t", note.get("body", "")), + "created": note.get("created"), + "modified": note.get("modified"), + } + ) return build_response( data={ diff --git a/src/rtm_mcp/tools/utilities.py b/src/rtm_mcp/tools/utilities.py index da69f44..97680a0 100644 --- a/src/rtm_mcp/tools/utilities.py +++ b/src/rtm_mcp/tools/utilities.py @@ -104,9 +104,11 @@ async def get_tags(ctx: Context) -> dict[str, Any]: if isinstance(tag, str): tags.append({"name": tag}) else: - tags.append({ - "name": tag.get("name", tag.get("$t", "")), - }) + tags.append( + { + "name": tag.get("name", tag.get("$t", "")), + } + ) return build_response( data={ @@ -134,14 +136,16 @@ async def get_locations(ctx: Context) -> dict[str, Any]: locations = [] for loc in locations_data: - locations.append({ - "id": loc.get("id"), - "name": loc.get("name"), - "latitude": float(loc.get("latitude", 0)), - "longitude": float(loc.get("longitude", 0)), - "zoom": int(loc.get("zoom", 0)) if loc.get("zoom") else None, - "address": loc.get("address"), - }) + locations.append( + { + "id": loc.get("id"), + "name": loc.get("name"), + "latitude": float(loc.get("latitude", 0)), + "longitude": float(loc.get("longitude", 0)), + "zoom": int(loc.get("zoom", 0)) if loc.get("zoom") else None, + "address": loc.get("address"), + } + ) return build_response( data={ @@ -166,7 +170,9 @@ async def get_settings(ctx: Context) -> dict[str, Any]: settings = result.get("settings", {}) # Format settings nicely - date_format = "European (DD/MM/YY)" if settings.get("dateformat") == "0" else "American (MM/DD/YY)" + date_format = ( + "European (DD/MM/YY)" if settings.get("dateformat") == "0" else "American (MM/DD/YY)" + ) time_format = "12-hour" if settings.get("timeformat") == "0" else "24-hour" return build_response( @@ -276,11 +282,13 @@ async def get_contacts(ctx: Context) -> dict[str, Any]: contacts = [] for contact in contacts_data: - contacts.append({ - "id": contact.get("id"), - "fullname": contact.get("fullname"), - "username": contact.get("username"), - }) + contacts.append( + { + "id": contact.get("id"), + "fullname": contact.get("fullname"), + "username": contact.get("username"), + } + ) return build_response( data={ @@ -312,11 +320,13 @@ async def get_groups(ctx: Context) -> dict[str, Any]: if isinstance(contacts, dict): contacts = [contacts] - groups.append({ - "id": group.get("id"), - "name": group.get("name"), - "member_count": len(contacts), - }) + groups.append( + { + "id": group.get("id"), + "name": group.get("name"), + "member_count": len(contacts), + } + ) return build_response( data={