Skip to content

Commit 9865090

Browse files
Merge pull request #5 from Chinchill-AI/fix-lint
fix: resolve all ruff lint errors — zero warnings
2 parents 66f11a4 + 31057e7 commit 9865090

26 files changed

Lines changed: 267 additions & 194 deletions

src/chat_sdk/__init__.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,6 @@
6363
resolve_emoji_from_slack,
6464
)
6565
from chat_sdk.errors import ChatError, ChatNotImplementedError, LockError, RateLimitError
66-
from chat_sdk.shared.errors import (
67-
AdapterRateLimitError,
68-
AuthenticationError,
69-
NetworkError,
70-
PermissionError as AdapterPermissionError,
71-
ResourceNotFoundError,
72-
ValidationError,
73-
)
7466
from chat_sdk.from_full_stream import from_full_stream
7567
from chat_sdk.logger import ConsoleLogger, Logger, LogLevel
7668
from chat_sdk.message_history import MessageHistoryCache, MessageHistoryConfig
@@ -95,6 +87,16 @@
9587
text_input,
9688
)
9789
from chat_sdk.shared.base_format_converter import BaseFormatConverter
90+
from chat_sdk.shared.errors import (
91+
AdapterRateLimitError,
92+
AuthenticationError,
93+
NetworkError,
94+
ResourceNotFoundError,
95+
ValidationError,
96+
)
97+
from chat_sdk.shared.errors import (
98+
PermissionError as AdapterPermissionError,
99+
)
98100
from chat_sdk.shared.streaming_markdown import StreamingMarkdownRenderer
99101
from chat_sdk.state.memory import MemoryStateAdapter
100102
from chat_sdk.thread import ThreadImpl

src/chat_sdk/adapters/discord/adapter.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import os
1414
import re
1515
from contextvars import ContextVar
16-
from datetime import datetime, timezone
16+
from datetime import UTC, datetime
1717
from typing import Any
1818
from urllib.parse import quote
1919

@@ -275,7 +275,9 @@ async def _verify_signature(
275275
verify_key.verify(message, bytes.fromhex(signature))
276276
return True
277277
except ImportError:
278-
self._logger.error("PyNaCl is required for Discord signature verification. Install with: pip install PyNaCl")
278+
self._logger.error(
279+
"PyNaCl is required for Discord signature verification. Install with: pip install PyNaCl"
280+
)
279281
return False
280282
except Exception as exc:
281283
self._logger.warn("Discord signature verification failed", {"error": str(exc)})
@@ -320,7 +322,9 @@ def _handle_component_interaction(
320322
channel_type = channel.get("type", 0)
321323
is_thread = channel_type in (CHANNEL_TYPE_PUBLIC_THREAD, CHANNEL_TYPE_PRIVATE_THREAD)
322324
parent_channel_id = (
323-
channel.get("parent_id", interaction_channel_id) if is_thread and channel.get("parent_id") else interaction_channel_id
325+
channel.get("parent_id", interaction_channel_id)
326+
if is_thread and channel.get("parent_id")
327+
else interaction_channel_id
324328
)
325329

326330
thread_id = self.encode_thread_id(
@@ -391,7 +395,9 @@ def _handle_application_command_interaction(
391395
channel_type = channel.get("type", 0)
392396
is_thread = channel_type in (CHANNEL_TYPE_PUBLIC_THREAD, CHANNEL_TYPE_PRIVATE_THREAD)
393397
parent_channel_id = (
394-
channel.get("parent_id", interaction_channel_id) if is_thread and channel.get("parent_id") else interaction_channel_id
398+
channel.get("parent_id", interaction_channel_id)
399+
if is_thread and channel.get("parent_id")
400+
else interaction_channel_id
395401
)
396402

397403
channel_id = self.encode_thread_id(
@@ -534,7 +540,9 @@ async def _handle_forwarded_message(
534540
mentions = data.get("mentions", [])
535541
is_user_mentioned = data.get("is_mention", False) or any(m.get("id") == self._application_id for m in mentions)
536542
mention_roles = data.get("mention_roles", [])
537-
is_role_mentioned = bool(self._mention_role_ids) and any(role_id in self._mention_role_ids for role_id in mention_roles)
543+
is_role_mentioned = bool(self._mention_role_ids) and any(
544+
role_id in self._mention_role_ids for role_id in mention_roles
545+
)
538546
is_mentioned = is_user_mentioned or is_role_mentioned
539547

540548
# If mentioned and not in a thread, create one
@@ -578,7 +586,7 @@ async def _handle_forwarded_message(
578586
metadata=MessageMetadata(
579587
date_sent=datetime.fromisoformat(data.get("timestamp", ""))
580588
if data.get("timestamp")
581-
else datetime.now(timezone.utc),
589+
else datetime.now(UTC),
582590
edited=False,
583591
),
584592
attachments=[
@@ -1158,7 +1166,7 @@ def _parse_discord_message(self, raw: dict[str, Any], thread_id: str) -> Message
11581166
is_me=is_me,
11591167
),
11601168
metadata=MessageMetadata(
1161-
date_sent=datetime.fromisoformat(msg["timestamp"]) if msg.get("timestamp") else datetime.now(timezone.utc),
1169+
date_sent=datetime.fromisoformat(msg["timestamp"]) if msg.get("timestamp") else datetime.now(UTC),
11621170
edited=msg.get("edited_timestamp") is not None,
11631171
edited_at=datetime.fromisoformat(msg["edited_timestamp"]) if msg.get("edited_timestamp") else None,
11641172
),
@@ -1203,7 +1211,7 @@ async def _create_discord_thread(
12031211
message_id: str,
12041212
) -> dict[str, str]:
12051213
"""Create a Discord thread from a message."""
1206-
thread_name = f"Thread {datetime.now(timezone.utc).isoformat()}"
1214+
thread_name = f"Thread {datetime.now(UTC).isoformat()}"
12071215

12081216
self._logger.debug(
12091217
"Discord API: POST thread",

src/chat_sdk/adapters/github/adapter.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import re
1616
import time
1717
from collections.abc import AsyncIterable
18-
from datetime import datetime, timezone
18+
from datetime import UTC, datetime
1919
from typing import Any
2020

2121
from chat_sdk.adapters.github.cards import card_to_github_markdown
@@ -148,7 +148,8 @@ def __init__(self, config: GitHubAdapterConfig | None = None) -> None:
148148
else:
149149
self._app_credentials = {"app_id": app_id, "private_key": private_key}
150150
self._logger.info(
151-
"GitHub adapter initialized in multi-tenant mode (installation ID will be extracted from webhooks)"
151+
"GitHub adapter initialized in multi-tenant mode "
152+
"(installation ID will be extracted from webhooks)"
152153
)
153154
else:
154155
raise ValidationError(
@@ -366,7 +367,7 @@ def _parse_issue_comment(
366367
metadata=MessageMetadata(
367368
date_sent=datetime.fromisoformat(created_at.replace("Z", "+00:00"))
368369
if created_at
369-
else datetime.now(tz=timezone.utc),
370+
else datetime.now(tz=UTC),
370371
edited=edited,
371372
edited_at=datetime.fromisoformat(updated_at.replace("Z", "+00:00")) if edited and updated_at else None,
372373
),
@@ -408,7 +409,7 @@ def _parse_review_comment(
408409
metadata=MessageMetadata(
409410
date_sent=datetime.fromisoformat(created_at.replace("Z", "+00:00"))
410411
if created_at
411-
else datetime.now(tz=timezone.utc),
412+
else datetime.now(tz=UTC),
412413
edited=edited,
413414
edited_at=datetime.fromisoformat(updated_at.replace("Z", "+00:00")) if edited and updated_at else None,
414415
),
@@ -682,7 +683,10 @@ async def fetch_thread(self, thread_id: str) -> ThreadInfo:
682683
def encode_thread_id(self, platform_data: GitHubThreadId) -> str:
683684
"""Encode platform data into a thread ID string."""
684685
if platform_data.review_comment_id:
685-
return f"github:{platform_data.owner}/{platform_data.repo}:{platform_data.pr_number}:rc:{platform_data.review_comment_id}"
686+
return (
687+
f"github:{platform_data.owner}/{platform_data.repo}"
688+
f":{platform_data.pr_number}:rc:{platform_data.review_comment_id}"
689+
)
686690
return f"github:{platform_data.owner}/{platform_data.repo}:{platform_data.pr_number}"
687691

688692
def decode_thread_id(self, thread_id: str) -> GitHubThreadId:
@@ -762,7 +766,7 @@ async def list_threads(
762766
metadata=MessageMetadata(
763767
date_sent=datetime.fromisoformat(pr.get("created_at", "").replace("Z", "+00:00"))
764768
if pr.get("created_at")
765-
else datetime.now(tz=timezone.utc),
769+
else datetime.now(tz=UTC),
766770
edited=pr.get("created_at") != pr.get("updated_at"),
767771
),
768772
)

src/chat_sdk/adapters/github/cards.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ def _render_text(text: dict[str, Any]) -> list[str]:
152152
def _render_fields(fields: dict[str, Any]) -> list[str]:
153153
"""Render fields as key-value pairs."""
154154
return [
155-
f"**{_escape_markdown(f.get('label', ''))}:** {_escape_markdown(f.get('value', ''))}" for f in fields.get("children", [])
155+
f"**{_escape_markdown(f.get('label', ''))}:** {_escape_markdown(f.get('value', ''))}"
156+
for f in fields.get("children", [])
156157
]
157158

158159

src/chat_sdk/adapters/github/types.py

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

55
from dataclasses import dataclass
6-
from typing import Literal, TypedDict, Union
6+
from typing import Literal, TypedDict
77

88
from chat_sdk.logger import Logger
99

@@ -81,12 +81,9 @@ class GitHubAdapterAutoConfig(GitHubAdapterBaseConfig, total=False):
8181

8282

8383
# Union of all configuration types
84-
GitHubAdapterConfig = Union[
85-
GitHubAdapterPATConfig,
86-
GitHubAdapterAppConfig,
87-
GitHubAdapterMultiTenantAppConfig,
88-
GitHubAdapterAutoConfig,
89-
]
84+
GitHubAdapterConfig = (
85+
GitHubAdapterPATConfig | GitHubAdapterAppConfig | GitHubAdapterMultiTenantAppConfig | GitHubAdapterAutoConfig
86+
)
9087

9188
# =============================================================================
9289
# Thread ID
@@ -290,7 +287,7 @@ class GitHubRawReviewComment(TypedDict):
290287
pr_number: int
291288

292289

293-
GitHubRawMessage = Union[GitHubRawIssueComment, GitHubRawReviewComment]
290+
GitHubRawMessage = GitHubRawIssueComment | GitHubRawReviewComment
294291

295292
# =============================================================================
296293
# GitHub API Response Types

src/chat_sdk/adapters/google_chat/adapter.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import re
1717
import time
1818
from collections.abc import AsyncIterable, Awaitable, Callable
19-
from datetime import datetime, timezone
19+
from datetime import UTC, datetime
2020
from typing import Any
2121

2222
from chat_sdk.adapters.google_chat.cards import card_to_google_card
@@ -135,7 +135,9 @@ def __init__(self, config: GoogleChatAdapterConfig | None = None) -> None:
135135
self._pubsub_topic = config.pubsub_topic or os.environ.get("GOOGLE_CHAT_PUBSUB_TOPIC")
136136
self._impersonate_user = config.impersonate_user or os.environ.get("GOOGLE_CHAT_IMPERSONATE_USER")
137137
self._endpoint_url = config.endpoint_url
138-
self._google_chat_project_number = config.google_chat_project_number or os.environ.get("GOOGLE_CHAT_PROJECT_NUMBER")
138+
self._google_chat_project_number = config.google_chat_project_number or os.environ.get(
139+
"GOOGLE_CHAT_PROJECT_NUMBER"
140+
)
139141
self._pubsub_audience = config.pubsub_audience or os.environ.get("GOOGLE_CHAT_PUBSUB_AUDIENCE")
140142

141143
# In-progress subscription creations to prevent duplicate requests
@@ -433,7 +435,9 @@ async def on_thread_subscribe(self, thread_id: str) -> None:
433435
)
434436

435437
if not self._pubsub_topic:
436-
self._logger.warn("No pubsubTopic configured, skipping space subscription. Set GOOGLE_CHAT_PUBSUB_TOPIC env var.")
438+
self._logger.warn(
439+
"No pubsubTopic configured, skipping space subscription. Set GOOGLE_CHAT_PUBSUB_TOPIC env var."
440+
)
437441
return
438442

439443
decoded = self.decode_thread_id(thread_id)
@@ -470,7 +474,9 @@ async def _ensure_space_subscription(self, space_name: str) -> None:
470474
# Check if we already have a valid subscription
471475
cached = await self._state.get(cache_key)
472476
if cached:
473-
expire_time = cached.get("expire_time", 0) if isinstance(cached, dict) else getattr(cached, "expire_time", 0)
477+
expire_time = (
478+
cached.get("expire_time", 0) if isinstance(cached, dict) else getattr(cached, "expire_time", 0)
479+
)
474480
time_until_expiry = expire_time - int(time.time() * 1000)
475481
if time_until_expiry > SUBSCRIPTION_REFRESH_BUFFER_MS:
476482
self._logger.debug(
@@ -2270,7 +2276,7 @@ async def list_threads(
22702276
last_reply_at=last_reply_at,
22712277
)
22722278
)
2273-
count += 1
2279+
count += 1 # noqa: SIM113
22742280

22752281
self._logger.debug(
22762282
"GChat API: listThreads result",
@@ -2677,9 +2683,9 @@ def _parse_message_metadata(message: dict[str, Any]) -> Any:
26772683
try:
26782684
date_sent = datetime.fromisoformat(create_time.replace("Z", "+00:00"))
26792685
except (ValueError, AttributeError):
2680-
date_sent = datetime.now(tz=timezone.utc)
2686+
date_sent = datetime.now(tz=UTC)
26812687
else:
2682-
date_sent = datetime.now(tz=timezone.utc)
2688+
date_sent = datetime.now(tz=UTC)
26832689

26842690
return MessageMetadata(
26852691
date_sent=date_sent,

src/chat_sdk/adapters/google_chat/cards.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
card_child_to_fallback_text,
1717
table_element_to_ascii,
1818
)
19-
from chat_sdk.shared import card_to_fallback_text as shared_card_to_fallback_text, create_emoji_converter
19+
from chat_sdk.shared import card_to_fallback_text as shared_card_to_fallback_text
20+
from chat_sdk.shared import create_emoji_converter
2021

2122
# Convert emoji placeholders in text to GChat format (Unicode).
2223
convert_emoji = create_emoji_converter("gchat")

src/chat_sdk/adapters/linear/adapter.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import os
1616
import re
1717
import time
18-
from datetime import datetime, timezone
18+
from datetime import UTC, datetime
1919
from typing import Any
2020

2121
from chat_sdk.adapters.linear.cards import card_to_linear_markdown
@@ -414,7 +414,7 @@ def _build_message(
414414
raw=LinearRawMessage(comment=comment),
415415
author=author,
416416
metadata=MessageMetadata(
417-
date_sent=datetime.fromisoformat(created_at) if created_at else datetime.now(timezone.utc),
417+
date_sent=datetime.fromisoformat(created_at) if created_at else datetime.now(UTC),
418418
edited=created_at != updated_at,
419419
edited_at=datetime.fromisoformat(updated_at) if (created_at != updated_at and updated_at) else None,
420420
),
@@ -432,10 +432,7 @@ async def post_message(
432432

433433
# Render message to markdown
434434
card = extract_card(message)
435-
if card:
436-
body = card_to_linear_markdown(card)
437-
else:
438-
body = self._format_converter.render_postable(message)
435+
body = card_to_linear_markdown(card) if card else self._format_converter.render_postable(message)
439436

440437
# Convert emoji placeholders to unicode
441438
body = convert_emoji_placeholders(body, "linear")
@@ -496,10 +493,7 @@ async def edit_message(
496493
decoded = self.decode_thread_id(thread_id)
497494

498495
card = extract_card(message)
499-
if card:
500-
body = card_to_linear_markdown(card)
501-
else:
502-
body = self._format_converter.render_postable(message)
496+
body = card_to_linear_markdown(card) if card else self._format_converter.render_postable(message)
503497

504498
body = convert_emoji_placeholders(body, "linear")
505499

@@ -754,7 +748,7 @@ def _comment_node_to_message(
754748
is_me=user_id == self._bot_user_id,
755749
),
756750
metadata=MessageMetadata(
757-
date_sent=datetime.fromisoformat(node["createdAt"]) if node.get("createdAt") else datetime.now(timezone.utc),
751+
date_sent=datetime.fromisoformat(node["createdAt"]) if node.get("createdAt") else datetime.now(UTC),
758752
edited=node.get("createdAt") != node.get("updatedAt"),
759753
edited_at=(
760754
datetime.fromisoformat(node["updatedAt"])
@@ -854,7 +848,7 @@ def parse_message(self, raw: LinearRawMessage) -> Message:
854848
),
855849
metadata=MessageMetadata(
856850
date_sent=(
857-
datetime.fromisoformat(comment["created_at"]) if comment.get("created_at") else datetime.now(timezone.utc)
851+
datetime.fromisoformat(comment["created_at"]) if comment.get("created_at") else datetime.now(UTC)
858852
),
859853
edited=comment.get("created_at") != comment.get("updated_at"),
860854
edited_at=(

src/chat_sdk/adapters/linear/cards.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ def _render_text(text: TextElement) -> list[str]:
123123
def _render_fields(fields: FieldsElement) -> list[str]:
124124
"""Render fields as key-value pairs."""
125125
return [
126-
f"**{_escape_markdown(f.get('label', ''))}:** {_escape_markdown(f.get('value', ''))}" for f in fields.get("children", [])
126+
f"**{_escape_markdown(f.get('label', ''))}:** {_escape_markdown(f.get('value', ''))}"
127+
for f in fields.get("children", [])
127128
]
128129

129130

src/chat_sdk/adapters/linear/types.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ class LinearAdapterAppConfig(LinearAdapterBaseConfig):
6666

6767

6868
# Union type for all config options
69-
LinearAdapterConfig = LinearAdapterBaseConfig | LinearAdapterAPIKeyConfig | LinearAdapterOAuthConfig | LinearAdapterAppConfig
69+
LinearAdapterConfig = (
70+
LinearAdapterBaseConfig | LinearAdapterAPIKeyConfig | LinearAdapterOAuthConfig | LinearAdapterAppConfig
71+
)
7072

7173

7274
# =============================================================================

0 commit comments

Comments
 (0)