diff options
-rw-r--r-- | bot/exts/filtering/_settings_types/validations/bypass_roles.py | 25 | ||||
-rw-r--r-- | bot/exts/filtering/_settings_types/validations/channel_scope.py | 30 |
2 files changed, 43 insertions, 12 deletions
diff --git a/bot/exts/filtering/_settings_types/validations/bypass_roles.py b/bot/exts/filtering/_settings_types/validations/bypass_roles.py index 50fb1e650..0ddb2fdb5 100644 --- a/bot/exts/filtering/_settings_types/validations/bypass_roles.py +++ b/bot/exts/filtering/_settings_types/validations/bypass_roles.py @@ -1,6 +1,8 @@ -from typing import ClassVar, Union +from collections.abc import Sequence +from typing import ClassVar from discord import Member +from pydantic import field_validator from bot.exts.filtering._filter_context import FilterContext from bot.exts.filtering._settings_types.settings_entry import ValidationEntry @@ -12,7 +14,26 @@ class RoleBypass(ValidationEntry): name: ClassVar[str] = "bypass_roles" description: ClassVar[str] = "A list of role IDs or role names. Users with these roles will not trigger the filter." - bypass_roles: set[Union[int, str]] # noqa: UP007 + bypass_roles: set[int | str] + + @field_validator("bypass_roles", mode="before") + @classmethod + def init_if_bypass_roles_none(cls, bypass_roles: Sequence[int | str] | None) -> Sequence[int | str]: + """ + Initialize an empty sequence if the value is None. + + This also coerces each element of bypass_roles to an int, if possible. + """ + if bypass_roles is None: + return [] + + def _coerce_to_int(input: int | str) -> int | str: + try: + return int(input) + except ValueError: + return input + + return map(_coerce_to_int, bypass_roles) def triggers_on(self, ctx: FilterContext) -> bool: """Return whether the filter should be triggered on this user given their roles.""" diff --git a/bot/exts/filtering/_settings_types/validations/channel_scope.py b/bot/exts/filtering/_settings_types/validations/channel_scope.py index 69de4199c..3d31131af 100644 --- a/bot/exts/filtering/_settings_types/validations/channel_scope.py +++ b/bot/exts/filtering/_settings_types/validations/channel_scope.py @@ -1,4 +1,5 @@ -from typing import ClassVar, Union +from collections.abc import Sequence +from typing import ClassVar from pydantic import field_validator @@ -29,20 +30,29 @@ class ChannelScope(ValidationEntry): ) } - # NOTE: Don't change this to use the new 3.10 union syntax unless you ensure Pydantic type validation and coercion - # work properly. At the time of writing this code there's a difference. - disabled_channels: set[Union[int, str]] # noqa: UP007 - disabled_categories: set[Union[int, str]] # noqa: UP007 - enabled_channels: set[Union[int, str]] # noqa: UP007 - enabled_categories: set[Union[int, str]] # noqa: UP007 + disabled_channels: set[int | str] + disabled_categories: set[int | str] + enabled_channels: set[int | str] + enabled_categories: set[int | str] @field_validator("*", mode="before") @classmethod - def init_if_sequence_none(cls, sequence: list[str] | None) -> list[str]: - """Initialize an empty sequence if the value is None.""" + def init_if_sequence_none(cls, sequence: Sequence[int | str] | None) -> Sequence[int | str]: + """ + Initialize an empty sequence if the value is None. + + This also coerces each element of sequence to an int, if possible. + """ if sequence is None: return [] - return sequence + + def _coerce_to_int(input: int | str) -> int | str: + try: + return int(input) + except ValueError: + return input + + return map(_coerce_to_int, sequence) def triggers_on(self, ctx: FilterContext) -> bool: """ |