Made dataclasses frozen and slotted for immutability and lower memory usage.
CI / Formatting (push) Successful in 5s
CI / Linting (push) Successful in 5s
CI / Tests (Python 3.12) (push) Successful in 20s
CI / Tests (Python 3.13) (push) Successful in 22s
CI / Tests (Python 3.14) (push) Successful in 50s
CI / Type Checking (push) Successful in 25s
CI / Spelling (push) Has been cancelled
CI / Formatting (push) Successful in 5s
CI / Linting (push) Successful in 5s
CI / Tests (Python 3.12) (push) Successful in 20s
CI / Tests (Python 3.13) (push) Successful in 22s
CI / Tests (Python 3.14) (push) Successful in 50s
CI / Type Checking (push) Successful in 25s
CI / Spelling (push) Has been cancelled
This commit is contained in:
@@ -43,7 +43,7 @@ class CommandMark(TypedDict):
|
||||
cooldown: int | float
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class CommandEvent:
|
||||
"""Parsed command information from a chat message."""
|
||||
|
||||
@@ -57,7 +57,7 @@ class CommandEvent:
|
||||
type CommandHandler = "Callable[[CommandContext], Awaitable[None]]"
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class CommandInfo:
|
||||
"""Metadata about a registered command."""
|
||||
|
||||
@@ -72,7 +72,7 @@ class CommandInfo:
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
"""Compute derived fields."""
|
||||
self.all_triggers = frozenset({self.name}) | self.aliases
|
||||
object.__setattr__(self, "all_triggers", frozenset({self.name}) | self.aliases)
|
||||
|
||||
|
||||
def on_command(
|
||||
|
||||
@@ -43,7 +43,7 @@ if TYPE_CHECKING:
|
||||
from .templates import ModuleTemplates
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class ModuleContext:
|
||||
"""Shared services available to all module handlers.
|
||||
|
||||
@@ -97,7 +97,7 @@ class ModuleContext:
|
||||
self.logger = logging.getLogger(f"owlbot.modules.{self.module_name}")
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class PropagationState:
|
||||
"""Mutable state for controlling event propagation across handlers."""
|
||||
|
||||
@@ -105,7 +105,7 @@ class PropagationState:
|
||||
reason: str = ""
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class EventContext[E]:
|
||||
"""Context passed to event handlers.
|
||||
|
||||
@@ -200,7 +200,7 @@ class EventContext[E]:
|
||||
self._propagation.reason = reason
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class CommandContext:
|
||||
"""Context passed to command handlers.
|
||||
|
||||
@@ -304,7 +304,7 @@ class CommandContext:
|
||||
return self.module.admin_client
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class RouteContext:
|
||||
"""Context passed to HTTP route handlers.
|
||||
|
||||
|
||||
+10
-10
@@ -76,7 +76,7 @@ def _parse_timestamp(ts: str | None) -> datetime | None:
|
||||
return None
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class User:
|
||||
"""Represents a chat user's identity and metadata."""
|
||||
|
||||
@@ -118,7 +118,7 @@ class User:
|
||||
return "MODERATOR" in self.scopes
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class ChatEvent:
|
||||
"""Represents a chat message sent by a user."""
|
||||
|
||||
@@ -155,7 +155,7 @@ class ChatEvent:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class UserJoinedEvent:
|
||||
"""Fired when a user joins the chat."""
|
||||
|
||||
@@ -179,7 +179,7 @@ class UserJoinedEvent:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class UserPartedEvent:
|
||||
"""Fired when a user disconnects from chat."""
|
||||
|
||||
@@ -203,7 +203,7 @@ class UserPartedEvent:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class NameChangedEvent:
|
||||
"""Fired when a user changes their display name."""
|
||||
|
||||
@@ -231,7 +231,7 @@ class NameChangedEvent:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class StreamStartedEvent:
|
||||
"""Fired when the stream goes live."""
|
||||
|
||||
@@ -257,7 +257,7 @@ class StreamStartedEvent:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class StreamStoppedEvent:
|
||||
"""Fired when the stream goes offline."""
|
||||
|
||||
@@ -283,7 +283,7 @@ class StreamStoppedEvent:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class StreamStatus:
|
||||
"""Current stream status snapshot included in some events."""
|
||||
|
||||
@@ -315,7 +315,7 @@ class StreamStatus:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class StreamTitleUpdatedEvent:
|
||||
"""Fired when the stream title is changed."""
|
||||
|
||||
@@ -344,7 +344,7 @@ class StreamTitleUpdatedEvent:
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class VisibilityUpdateEvent:
|
||||
"""Fired when message visibility changes (moderation action)."""
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ if TYPE_CHECKING:
|
||||
from .http_client import HttpClient
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class StreamKey:
|
||||
"""A stream key for ingest authentication.
|
||||
|
||||
@@ -49,7 +49,7 @@ class StreamKey:
|
||||
return {"key": self.key, "comment": self.comment}
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class VideoVariant:
|
||||
"""A video output variant (quality level) for transcoding.
|
||||
|
||||
@@ -113,7 +113,7 @@ class VideoVariant:
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class SocialHandle:
|
||||
"""A social media handle displayed on the server page.
|
||||
|
||||
@@ -134,7 +134,7 @@ class SocialHandle:
|
||||
return {"platform": self.platform, "url": self.url}
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class ExternalAction:
|
||||
"""An external action button displayed in the player UI.
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ type RouteHandler = (
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class RouteInfo:
|
||||
"""Metadata about a registered route."""
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ if TYPE_CHECKING:
|
||||
from .processing import ProcessingManager
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class EditorSession:
|
||||
"""A clip editor session."""
|
||||
|
||||
@@ -40,7 +40,7 @@ class EditorSession:
|
||||
expiry_task: asyncio.Task[None] | None = None
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class ModuleState:
|
||||
"""Runtime state for the clips module."""
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ from .placeholder_handlers import HANDLERS, PlaceholderError
|
||||
DEFAULT_MAX_DEPTH: int = 4
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class TextNode:
|
||||
"""A span of literal text that needs no further processing.
|
||||
|
||||
@@ -63,7 +63,7 @@ class TextNode:
|
||||
text: str
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class PlaceholderNode:
|
||||
"""A ``$(name ...)`` placeholder expression.
|
||||
|
||||
@@ -82,7 +82,7 @@ class PlaceholderNode:
|
||||
type Node = TextNode | PlaceholderNode
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class PlaceholderContext:
|
||||
"""Bundles the runtime state needed to resolve placeholders.
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ if TYPE_CHECKING:
|
||||
logger = logging.getLogger("owlbot.web")
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(slots=True)
|
||||
class _RouteGroup:
|
||||
"""Groups route handlers that share the same path pattern.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user