aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Chris Lovering <[email protected]>2023-07-31 17:45:33 +0100
committerGravatar Chris Lovering <[email protected]>2023-08-11 15:53:27 +0100
commit505c377a5a333104e6ffff95d4a2bf007097abd4 (patch)
tree0bf5d4e3c6a8afa6e6823b61580a98dfb4a34ada
parentReplace deprecated functions with new pydantic v2 functions (diff)
Use a custom type coercion function as pydantic removed their's
https://docs.pydantic.dev/latest/migration/#changes-to-handling-of-standard-types > While union types will still attempt validation of each choice from left to right, they now preserve the type of the input whenever possible, even if the correct type is not the first choice for which the input would pass validation
-rw-r--r--bot/exts/filtering/_settings_types/validations/bypass_roles.py25
-rw-r--r--bot/exts/filtering/_settings_types/validations/channel_scope.py30
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:
"""