diff options
author | 2023-07-31 17:45:33 +0100 | |
---|---|---|
committer | 2023-08-11 15:53:27 +0100 | |
commit | 505c377a5a333104e6ffff95d4a2bf007097abd4 (patch) | |
tree | 0bf5d4e3c6a8afa6e6823b61580a98dfb4a34ada | |
parent | Replace 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.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: """ |