From d705496426da6c1302eba3fc59bab8172f01d43f Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 17 Oct 2022 20:58:00 +0500 Subject: [PATCH 01/35] refactor!: use `attrs.asdict` as a way to get json data of the object --- interactions/api/models/message.py | 117 +++--------------------- interactions/client/models/component.py | 84 ++--------------- interactions/utils/attrs_utils.py | 34 ++++--- 3 files changed, 43 insertions(+), 192 deletions(-) diff --git a/interactions/api/models/message.py b/interactions/api/models/message.py index 318383faa..ca62d3caf 100644 --- a/interactions/api/models/message.py +++ b/interactions/api/models/message.py @@ -230,17 +230,6 @@ class EmbedImageStruct(DictSerializerMixin): height: Optional[int] = field(default=None) width: Optional[int] = field(default=None) - def __setattr__(self, key, value) -> None: - super().__setattr__(key, value) - if key not in {"_json", "_extras"} and ( - key not in self._json or value != self._json.get(key) - ): - if value is not None and value is not MISSING: - self._json.update({key: value}) - - elif value is None and key in self._json.keys(): - del self._json[key] - @define() class EmbedProvider(DictSerializerMixin): @@ -254,17 +243,6 @@ class EmbedProvider(DictSerializerMixin): name: Optional[str] = field(default=None) url: Optional[str] = field(default=None) - def __setattr__(self, key, value) -> None: - super().__setattr__(key, value) - if key not in {"_json", "_extras"} and ( - key not in self._json or value != self._json.get(key) - ): - if value is not None and value is not MISSING: - self._json.update({key: value}) - - elif value is None and key in self._json.keys(): - del self._json[key] - @define() class EmbedAuthor(DictSerializerMixin): @@ -290,17 +268,6 @@ class EmbedAuthor(DictSerializerMixin): icon_url: Optional[str] = field(default=None) proxy_icon_url: Optional[str] = field(default=None) - def __setattr__(self, key, value) -> None: - super().__setattr__(key, value) - if key not in {"_json", "_extras"} and ( - key not in self._json or value != self._json.get(key) - ): - if value is not None and value is not MISSING: - self._json.update({key: value}) - - elif value is None and key in self._json.keys(): - del self._json[key] - @define() class EmbedFooter(DictSerializerMixin): @@ -324,17 +291,6 @@ class EmbedFooter(DictSerializerMixin): icon_url: Optional[str] = field(default=None) proxy_icon_url: Optional[str] = field(default=None) - def __setattr__(self, key, value) -> None: - super().__setattr__(key, value) - if key not in {"_json", "_extras"} and ( - key not in self._json or value != self._json.get(key) - ): - if value is not None and value is not MISSING: - self._json.update({key: value}) - - elif value is None and key in self._json.keys(): - del self._json[key] - @define() class EmbedField(DictSerializerMixin): @@ -360,17 +316,6 @@ class EmbedField(DictSerializerMixin): inline: Optional[bool] = field(default=None) value: str = field() - def __setattr__(self, key, value) -> None: - super().__setattr__(key, value) - if key not in {"_json", "_extras"} and ( - key not in self._json or value != self._json.get(key) - ): - if value is not None and value is not MISSING: - self._json.update({key: value}) - - elif value is None and key in self._json.keys(): - del self._json[key] - @define() @deepcopy_kwargs() @@ -423,28 +368,6 @@ class Embed(DictSerializerMixin): author: Optional[EmbedAuthor] = field(converter=EmbedAuthor, default=None) fields: Optional[List[EmbedField]] = field(converter=convert_list(EmbedField), default=None) - def __setattr__(self, key, value) -> None: - super().__setattr__(key, value) - - if key not in {"_json", "_extras"} and ( - key not in self._json - or ( - value != self._json.get(key) - or not isinstance(value, dict) - # we don't need this instance check in components because serialisation works for them - ) - ): - if value is not None and value is not MISSING: - try: - value = [val._json for val in value] if isinstance(value, list) else value._json - except AttributeError: - if isinstance(value, datetime): - value = value.isoformat() - self._json.update({key: value}) - - elif value is None and key in self._json.keys(): - del self._json[key] - def add_field(self, name: str, value: str, inline: Optional[bool] = False) -> None: """ Adds a field to the embed @@ -457,13 +380,10 @@ def add_field(self, name: str, value: str, inline: Optional[bool] = False) -> No :type inline?: Optional[bool] """ - fields = self.fields or [] - fields.append(EmbedField(name=name, value=value, inline=inline)) + if self.fields is None: + self.fields = [] - self.fields = fields - # We must use "=" here to call __setattr__. Append does not call any magic, making it impossible to modify the - # json when using it, so the object what would be sent wouldn't be modified. - # Imo this is still better than doing a `self._json.update({"fields": [field._json for ...]})` + self.fields.append(EmbedField(name=name, value=value, inline=inline)) def clear_fields(self) -> None: """ @@ -488,13 +408,10 @@ def insert_field_at( :type inline?: Optional[bool] """ - try: - fields = self.fields - fields.insert(index, EmbedField(name=name, value=value, inline=inline)) - self.fields = fields + if self.fields is None: + self.fields = [] - except AttributeError as e: - raise AttributeError("No fields found in Embed") from e + self.fields.insert(index, EmbedField(name=name, value=value, inline=inline)) def set_field_at( self, index: int, name: str, value: str, inline: Optional[bool] = False @@ -512,14 +429,11 @@ def set_field_at( :type inline?: Optional[bool] """ - try: - fields = self.fields - fields[index] = EmbedField(name=name, value=value, inline=inline) - self.fields = fields - - except AttributeError as e: - raise AttributeError("No fields found in Embed") from e + if self.fields is None: + self.fields = [] + try: + self.fields[index] = EmbedField(name=name, value=value, inline=inline) except IndexError as e: raise IndexError("No fields at this index") from e @@ -531,14 +445,11 @@ def remove_field(self, index: int) -> None: :type index: int """ - try: - fields = self.fields - fields.pop(index) - self.fields = fields - - except AttributeError as e: - raise AttributeError("No fields found in Embed") from e + if self.fields is None: + self.fields = [] + try: + self.fields.pop(index) except IndexError as e: raise IndexError("Field not Found at index") from e diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index b8a3f0d60..538f23672 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -1,10 +1,8 @@ -import contextlib from typing import List, Optional, Union from ...api.error import LibraryException from ...api.models.emoji import Emoji from ...utils.attrs_utils import DictSerializerMixin, convert_list, define, field -from ...utils.missing import MISSING from ..enums import ButtonStyle, ComponentType, TextStyleType __all__ = ( @@ -20,27 +18,7 @@ @define() -class ComponentMixin(DictSerializerMixin): - """ - A mixin designed to let subclasses attribute changes be mirrored to their _json - Arguably, this should be moved to the DictSerializerMixin, but testing would need to be done first - """ - - def __setattr__(self, key, value) -> None: - super().__setattr__(key, value) - if key not in {"_json", "_extras"} and ( - key not in self._json or value != self._json.get(key) - ): - if value is not None and value is not MISSING: - with contextlib.suppress(AttributeError): - value = [val._json for val in value] if isinstance(value, list) else value._json - self._json.update({key: value}) - elif value is None and key in self._json.keys(): - del self._json[key] - - -@define() -class SelectOption(ComponentMixin): +class SelectOption(DictSerializerMixin): """ A class object representing the select option of a select menu. The structure for a select option: :: @@ -62,13 +40,9 @@ class SelectOption(ComponentMixin): emoji: Optional[Emoji] = field(converter=Emoji, default=None) default: Optional[bool] = field(default=None) - def __attrs_post_init__(self): - if self.emoji: - self._json.update({"emoji": self.emoji._json}) - @define() -class SelectMenu(ComponentMixin): +class SelectMenu(DictSerializerMixin): """ A class object representing the select menu of a component. The structure for a select menu: :: @@ -98,14 +72,9 @@ class SelectMenu(ComponentMixin): disabled: Optional[bool] = field(default=None) channel_types: Optional[List[int]] = field(default=None) - def __attrs_post_init__(self) -> None: - self._json.update({"type": self.type.value}) - if self.options: - self._json.update({"options": [option._json for option in self.options]}) - @define() -class Button(ComponentMixin): +class Button(DictSerializerMixin): """ A class object representing the button of a component. The structure for a button: :: @@ -131,14 +100,9 @@ class Button(ComponentMixin): url: Optional[str] = field(default=None) disabled: Optional[bool] = field(default=None) - def __attrs_post_init__(self) -> None: - self._json.update({"type": self.type.value, "style": self.style.value}) - if self.emoji: - self._json.update({"emoji": self.emoji._json}) - @define() -class Component(ComponentMixin): +class Component(DictSerializerMixin): """ A class object representing the component in an interaction response/followup. @@ -190,12 +154,10 @@ def __attrs_post_init__(self): self.components = ( [Component(**components) for components in self.components] if self.components else None ) - if self._json.get("components"): - self._json["components"] = [component._json for component in self.components] @define() -class TextInput(ComponentMixin): +class TextInput(DictSerializerMixin): """ A class object representing the text input of a modal. The structure for a text input: :: @@ -227,12 +189,9 @@ class TextInput(ComponentMixin): min_length: Optional[int] = field(default=None) max_length: Optional[int] = field(default=None) - def __attrs_post_init__(self): - self._json.update({"type": self.type.value, "style": self.style.value}) - @define() -class Modal(ComponentMixin): +class Modal(DictSerializerMixin): """ A class object representing a modal. The structure for a modal: :: @@ -251,18 +210,9 @@ class Modal(ComponentMixin): title: str = field() components: List[Component] = field(converter=convert_list(Component)) - def __attrs_post_init__(self): - self._json.update( - { - "components": [ - {"type": 1, "components": [component._json]} for component in self.components - ] - } - ) - @define() -class ActionRow(ComponentMixin): +class ActionRow(DictSerializerMixin): """ A class object representing the action row for interaction responses holding components. @@ -286,26 +236,6 @@ class ActionRow(ComponentMixin): type: ComponentType = field(ComponentType, default=ComponentType.ACTION_ROW) components: Optional[List[Component]] = field(converter=convert_list(Component), default=None) - def __attrs_post_init__(self) -> None: - for component in self.components: - if isinstance(component, SelectMenu): - component._json["options"] = ( - [ - option._json if isinstance(option, SelectOption) else option - for option in component._json["options"] - ] - if component._json.get("options") - else [] - ) - self.components = ( - [Component(**component._json) for component in self.components] - if self._json.get("components") - else None - ) - self._json.update({"type": self.type.value}) - if self._json.get("components"): - self._json["components"] = [component._json for component in self.components] - @classmethod def new(cls, *components: Union[Button, SelectMenu, TextInput]) -> "ActionRow": r""" diff --git a/interactions/utils/attrs_utils.py b/interactions/utils/attrs_utils.py index d1dd9e75f..b80e16f25 100644 --- a/interactions/utils/attrs_utils.py +++ b/interactions/utils/attrs_utils.py @@ -1,6 +1,8 @@ from copy import deepcopy +from datetime import datetime +from enum import Enum from functools import wraps -from typing import Dict, Mapping, Optional, Tuple +from typing import Any, Dict, Mapping, Optional, Tuple import attrs @@ -14,7 +16,6 @@ @attrs.define(eq=False, init=False, on_setattr=attrs.setters.NO_OP) class DictSerializerMixin: - _json: dict = attrs.field(init=False, repr=False) _extras: dict = attrs.field(init=False, repr=False) """A dict containing values that were not serialized from Discord.""" @@ -29,7 +30,6 @@ def __init__(self, kwargs_dict: dict = None, /, **other_kwargs): if self.__deepcopy_kwargs__: kwargs = deepcopy(kwargs) - self._json = kwargs.copy() passed_kwargs = {} attribs: Tuple[attrs.Attribute, ...] = self.__attrs_attrs__ # type: ignore @@ -63,14 +63,6 @@ def __init__(self, kwargs_dict: dict = None, /, **other_kwargs): elif isinstance(value, DictSerializerMixin): value._client = client - # make sure json is recursively handled - if isinstance(value, list): - self._json[attrib_name] = [ - i._json if isinstance(i, DictSerializerMixin) else i for i in value - ] - elif isinstance(value, DictSerializerMixin): - self._json[attrib_name] = value._json # type: ignore - passed_kwargs[attrib_name] = value elif attrib.default is not attrs.NOTHING: @@ -88,6 +80,25 @@ def __init__(self, kwargs_dict: dict = None, /, **other_kwargs): self._extras = kwargs self.__attrs_init__(**passed_kwargs) # type: ignore + @property + def _json(self) -> dict: + """Returns the json data of the object""" + from ..api.models.misc import Snowflake + + def _filter(attrib: attrs.Attribute, value: Any): + return not attrib.name.startswith("_") and value + + def _serializer(obj: Any, attrib: attrs.Attribute, value: Any): + if isinstance(value, Snowflake): + return str(value) + if isinstance(value, Enum): + return value.value + if isinstance(value, datetime): + return value.isoformat() + return value + + return attrs.asdict(self, filter=_filter, value_serializer=_serializer) + def update(self, kwargs_dict: dict = None, /, **other_kwargs): """ Update an object with new attributes. @@ -112,7 +123,6 @@ def update(self, kwargs_dict: dict = None, /, **other_kwargs): if value is None: continue - self._json[name] = value setattr( self, name, converter(value) if (converter := attribs[name].converter) else value ) From ce8907cbe403f355d8b0967ce422423199de0c58 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 10:12:08 +0500 Subject: [PATCH 02/35] refactor: remove `self._json` mentions --- interactions/api/models/presence.py | 9 +++------ interactions/api/models/webhook.py | 10 ++++++---- interactions/client/models/command.py | 19 +++---------------- interactions/utils/attrs_utils.py | 2 +- 4 files changed, 13 insertions(+), 27 deletions(-) diff --git a/interactions/api/models/presence.py b/interactions/api/models/presence.py index c116ee701..33ffc8e1e 100644 --- a/interactions/api/models/presence.py +++ b/interactions/api/models/presence.py @@ -177,11 +177,8 @@ class ClientPresence(DictSerializerMixin): afk: bool = field(default=False) def __attrs_post_init__(self): - if not self._json.get("since"): + if not self.since: # If since is not provided by the developer... self.since = int(time.time() * 1000) if self.status == "idle" else 0 - self._json["since"] = self.since - if not self._json.get("afk"): - self.afk = self._json["afk"] = False - if not self._json.get("activities"): - self.activities = self._json["activities"] = [] + if not self.activities: + self.activities = [] diff --git a/interactions/api/models/webhook.py b/interactions/api/models/webhook.py index 4b8898ca4..e1fc763f0 100644 --- a/interactions/api/models/webhook.py +++ b/interactions/api/models/webhook.py @@ -11,6 +11,8 @@ from ...client.models.component import ActionRow, Button, SelectMenu from ..http import HTTPClient from .message import Attachment, Embed, Message + from .channel import Channel + from .guild import Guild __all__ = ( "Webhook", @@ -52,8 +54,8 @@ class Webhook(ClientSerializerMixin, IDMixin): avatar: str = field(repr=False) token: Optional[str] = field(default=None) application_id: Snowflake = field(converter=Snowflake) - source_guild: Optional[Any] = field(default=None) - source_channel: Optional[Any] = field(default=None) + source_guild: Optional["Guild"] = field(default=None) + source_channel: Optional["Channel"] = field(default=None) url: Optional[str] = field(default=None) def __attrs_post_init__(self): @@ -63,12 +65,12 @@ def __attrs_post_init__(self): self.source_guild = ( Guild(**self.source_guild, _client=self._client) - if self._json.get("source_guild") + if self.source_guild # TODO: is it dict? else None ) self.source_channel = ( Channel(**self.source_channel, _client=self._client) - if self._json.get("source_channel") + if self.source_channel else None ) diff --git a/interactions/client/models/command.py b/interactions/client/models/command.py index c92d3cabf..04c471f7d 100644 --- a/interactions/client/models/command.py +++ b/interactions/client/models/command.py @@ -58,17 +58,11 @@ class Choice(DictSerializerMixin): name_localizations: Optional[Dict[Union[str, Locale], str]] = field(default=None) def __attrs_post_init__(self): - if self._json.get("name_localizations"): - if any( - type(x) != str for x in self._json["name_localizations"] - ): # check if Locale object is used to create localisation at any certain point. - self._json["name_localizations"] = { - k.value if isinstance(k, Locale) else k: v - for k, v in self._json["name_localizations"].items() - } + # TODO: test it + if self.name_localizations: self.name_localizations = { k if isinstance(k, Locale) else Locale(k): v - for k, v in self._json["name_localizations"].items() + for k, v in self.name_localizations.items() } @@ -140,19 +134,15 @@ class Option(DictSerializerMixin): converter: Optional[str] = field(default=None) def __attrs_post_init__(self): - self._json.pop("converter", None) - # needed for nested classes if self.options is not None: self.options = [ Option(**option) if isinstance(option, dict) else option for option in self.options ] - self._json["options"] = [option._json for option in self.options] if self.choices is not None: self.choices = [ Choice(**choice) if isinstance(choice, dict) else choice for choice in self.choices ] - self._json["choices"] = [choice._json for choice in self.choices] @define() @@ -178,9 +168,6 @@ class Permission(DictSerializerMixin): type: PermissionType = field(converter=PermissionType) permission: bool = field() - def __attrs_post_init__(self): - self._json["type"] = self.type.value - @define() class ApplicationCommand(DictSerializerMixin): diff --git a/interactions/utils/attrs_utils.py b/interactions/utils/attrs_utils.py index b80e16f25..5e6bbdcf8 100644 --- a/interactions/utils/attrs_utils.py +++ b/interactions/utils/attrs_utils.py @@ -86,7 +86,7 @@ def _json(self) -> dict: from ..api.models.misc import Snowflake def _filter(attrib: attrs.Attribute, value: Any): - return not attrib.name.startswith("_") and value + return not attrib.name.startswith("_") and attrib.name not in {"converter", } and value def _serializer(obj: Any, attrib: attrs.Attribute, value: Any): if isinstance(value, Snowflake): From 802e42bdd74b7cbd399188b5dd6c95f3b57b0932 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 05:12:32 +0000 Subject: [PATCH 03/35] ci: correct from checks. --- interactions/api/models/webhook.py | 6 ++---- interactions/utils/attrs_utils.py | 9 ++++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/interactions/api/models/webhook.py b/interactions/api/models/webhook.py index e1fc763f0..77e9b3ca1 100644 --- a/interactions/api/models/webhook.py +++ b/interactions/api/models/webhook.py @@ -10,9 +10,9 @@ if TYPE_CHECKING: from ...client.models.component import ActionRow, Button, SelectMenu from ..http import HTTPClient - from .message import Attachment, Embed, Message from .channel import Channel from .guild import Guild + from .message import Attachment, Embed, Message __all__ = ( "Webhook", @@ -69,9 +69,7 @@ def __attrs_post_init__(self): else None ) self.source_channel = ( - Channel(**self.source_channel, _client=self._client) - if self.source_channel - else None + Channel(**self.source_channel, _client=self._client) if self.source_channel else None ) @classmethod diff --git a/interactions/utils/attrs_utils.py b/interactions/utils/attrs_utils.py index 5e6bbdcf8..0e8ba050d 100644 --- a/interactions/utils/attrs_utils.py +++ b/interactions/utils/attrs_utils.py @@ -86,7 +86,14 @@ def _json(self) -> dict: from ..api.models.misc import Snowflake def _filter(attrib: attrs.Attribute, value: Any): - return not attrib.name.startswith("_") and attrib.name not in {"converter", } and value + return ( + not attrib.name.startswith("_") + and attrib.name + not in { + "converter", + } + and value + ) def _serializer(obj: Any, attrib: attrs.Attribute, value: Any): if isinstance(value, Snowflake): From 0e42d8811cace4ab14e84631bd3eb7d9b935e203 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 10:51:40 +0500 Subject: [PATCH 04/35] refactor: wsclient is hard. part I --- interactions/api/gateway/client.py | 49 +++++++++++------------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index e4a6eb84f..ab524f3ea 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -358,19 +358,15 @@ def _dispatch_event(self, event: str, data: dict) -> None: if data["type"] == InteractionType.APPLICATION_COMMAND: _name = f"command_{_context.data.name}" - if _context.data._json.get("options"): - for option in _context.data.options: + if options := _context.data.options: + for option in options: _type = self.__option_type_context( _context, - (option["type"] if isinstance(option, dict) else option.type.value), + option.type.value, ) if _type: - if isinstance(option, dict): - _type[option["value"]]._client = self._http - option.update({"value": _type[option["value"]]}) - else: - _type[option.value]._client = self._http - option._json.update({"value": _type[option.value]}) + _type[option.value]._client = self._http + option.value = _type[option.value] # TODO: uhh _option = self.__sub_command_context(option, _context) __kwargs.update(_option) @@ -378,12 +374,12 @@ def _dispatch_event(self, event: str, data: dict) -> None: elif data["type"] == InteractionType.MESSAGE_COMPONENT: _name = f"component_{_context.data.custom_id}" - if _context.data._json.get("values"): + if values := _context.data.values: if _context.data.component_type.value not in {5, 6, 7, 8}: - __args.append(_context.data.values) + __args.append(values) else: _list = [] # temp storage for items - for value in _context.data._json.get("values"): + for value in values: _data = self.__select_option_type_context( _context, _context.data.component_type.value ) # resolved. @@ -394,10 +390,8 @@ def _dispatch_event(self, event: str, data: dict) -> None: elif data["type"] == InteractionType.APPLICATION_COMMAND_AUTOCOMPLETE: _name = f"autocomplete_{_context.data.name}" - if _context.data._json.get("options"): + if _context.data.options: for option in _context.data.options: - if isinstance(option, dict): - option = Option(**option) if option.type not in ( OptionType.SUB_COMMAND, OptionType.SUB_COMMAND_GROUP, @@ -411,8 +405,6 @@ def _dispatch_event(self, event: str, data: dict) -> None: elif option.type == OptionType.SUB_COMMAND: for _option in option.options: - if isinstance(_option, dict): - _option = Option(**_option) if _option.focused: __name, _value = self.__sub_command_context( _option, _context @@ -424,11 +416,7 @@ def _dispatch_event(self, event: str, data: dict) -> None: elif option.type == OptionType.SUB_COMMAND_GROUP: for _option in option.options: - if isinstance(_option, dict): - _option = Option(**_option) for __option in _option.options: - if isinstance(__option, dict): - __option = Option(**__option) if __option.focused: __name, _value = self.__sub_command_context( __option, _context @@ -524,7 +512,7 @@ def _dispatch_event(self, event: str, data: dict) -> None: old_obj = _cache.get(id) if old_obj: before = model(**old_obj._json) - old_obj.update(**obj._json) + old_obj.update(**data) # TODO: are you sure? else: before = None old_obj = obj @@ -734,7 +722,7 @@ def __contextualize(self, data: dict) -> "_Context": return context(**data) def __sub_command_context( - self, data: Union[dict, Option], context: "_Context" + self, data: Option, context: "_Context" ) -> Union[Tuple[str], dict]: """ Checks if an application command schema has sub commands @@ -747,8 +735,9 @@ def __sub_command_context( :return: A dictionary of the collected options, if any. :rtype: Union[Tuple[str], dict] """ + # TODO: uhhhhhhhhhhhhhhhhhh __kwargs: dict = {} - _data: dict = data._json if isinstance(data, Option) else data + _data: dict = data._json def _check_auto(option: dict) -> Optional[Tuple[str]]: return (option["name"], option["value"]) if option.get("focused") else None @@ -764,12 +753,7 @@ def _check_auto(option: dict) -> Optional[Tuple[str]]: for sub_option in _data["options"]: _check = _check_auto(sub_option) _type = self.__option_type_context( - context, - ( - sub_option["type"] - if isinstance(sub_option, dict) - else sub_option.type.value - ), + context, sub_option.type.value, ) if _type: @@ -1129,9 +1113,10 @@ async def _update_presence(self, presence: ClientPresence) -> None: :param presence: The presence to change the bot to on identify. :type presence: ClientPresence """ - payload: dict = {"op": OpCodeType.PRESENCE.value, "d": presence._json} + _presence = presence._json + payload: dict = {"op": OpCodeType.PRESENCE.value, "d": _presence} await self._send_packet(payload) - log.debug(f"UPDATE_PRESENCE: {presence._json}") + log.debug(f"UPDATE_PRESENCE: {_presence}") self.__presence = presence async def request_guild_members( From f5a736ebb9e0ecf506943f0200001a5398946bc3 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 05:52:07 +0000 Subject: [PATCH 05/35] ci: correct from checks. --- interactions/api/gateway/client.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index ab524f3ea..93792fe1d 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -721,9 +721,7 @@ def __contextualize(self, data: dict) -> "_Context": return context(**data) - def __sub_command_context( - self, data: Option, context: "_Context" - ) -> Union[Tuple[str], dict]: + def __sub_command_context(self, data: Option, context: "_Context") -> Union[Tuple[str], dict]: """ Checks if an application command schema has sub commands needed for argument collection. @@ -753,7 +751,8 @@ def _check_auto(option: dict) -> Optional[Tuple[str]]: for sub_option in _data["options"]: _check = _check_auto(sub_option) _type = self.__option_type_context( - context, sub_option.type.value, + context, + sub_option.type.value, ) if _type: From ed2b1612b596dac1e38de7d6ba42e926d769e0b9 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 11:12:46 +0500 Subject: [PATCH 06/35] Update attrs_utils.pyi --- interactions/utils/attrs_utils.pyi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interactions/utils/attrs_utils.pyi b/interactions/utils/attrs_utils.pyi index 7845f3c9a..d914f0f2d 100644 --- a/interactions/utils/attrs_utils.pyi +++ b/interactions/utils/attrs_utils.pyi @@ -11,7 +11,6 @@ _P = TypeVar("_P") @attrs.define(eq=False, init=False, on_setattr=attrs.setters.NO_OP) class DictSerializerMixin: - _json: dict = attrs.field(init=False) _extras: dict = attrs.field(init=False) """A dict containing values that were not serialized from Discord.""" __deepcopy_kwargs__: bool = attrs.field(init=False) @@ -19,6 +18,9 @@ class DictSerializerMixin: def __init__(self, kwargs_dict: dict = None, /, **other_kwargs): ... + @property + def _json(self) -> dict: ... + @attrs.define(eq=False, init=False, on_setattr=attrs.setters.NO_OP) class ClientSerializerMixin(DictSerializerMixin): From 657d7298a0912db293cbd5b8fbed689a5f705c15 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 11:13:04 +0500 Subject: [PATCH 07/35] refactor: remove json editing --- interactions/client/models/command.py | 1 - 1 file changed, 1 deletion(-) diff --git a/interactions/client/models/command.py b/interactions/client/models/command.py index 04c471f7d..014eea866 100644 --- a/interactions/client/models/command.py +++ b/interactions/client/models/command.py @@ -598,7 +598,6 @@ def decorator(coro: Callable[..., Awaitable]) -> "Command": if int(option.type) == 2 and option.name == _group: break self.options[i].options.append(subcommand) - self.options[i]._json["options"].append(subcommand._json) self.coroutines[f"{_group} {_name}"] = self.__wrap_coro(coro) self.num_options[f"{_group} {_name}"] = len( {opt for opt in _options if int(opt.type) > 2} From 7a0135acf1720805e695033747c6d14e23f32d79 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 11:13:30 +0500 Subject: [PATCH 08/35] refactor: why --- interactions/api/models/guild.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interactions/api/models/guild.py b/interactions/api/models/guild.py index fa5ed1bc4..bd883a7aa 100644 --- a/interactions/api/models/guild.py +++ b/interactions/api/models/guild.py @@ -1131,7 +1131,7 @@ async def modify_channel( ) _type = ch.type - payload = Channel( + payload = dict( name=_name, type=_type, topic=_topic, @@ -1144,8 +1144,6 @@ async def modify_channel( nsfw=_nsfw, ) - payload = payload._json - if ( archived is not MISSING or auto_archive_duration is not MISSING or locked is not MISSING ) and not ch.thread_metadata: From b1cc157527deeac8d1e1ae340c682b96ac1ec257 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 11:13:44 +0500 Subject: [PATCH 09/35] refactor: add wat --- interactions/api/models/channel.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interactions/api/models/channel.py b/interactions/api/models/channel.py index ca9bfd12d..7910f6123 100644 --- a/interactions/api/models/channel.py +++ b/interactions/api/models/channel.py @@ -1728,8 +1728,7 @@ async def create_forum_post( elif isinstance(content, Message): if content.attachments and any(attach.id is None for attach in content.attachments): - del content._json["attachments"] - + # TODO: wat for attach in content.attachments: _data = await attach.download() From 415ebe8b497cc22ddb853a2bcace90e4aec6da6b Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 13:32:37 +0500 Subject: [PATCH 10/35] refactor: limit `._json` usage & remove json modifing --- interactions/client/models/component.py | 53 +++++-------------------- 1 file changed, 10 insertions(+), 43 deletions(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index 538f23672..291aa2cf1 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -258,26 +258,13 @@ def __check_action_row(): ): _components = [] for action_row in components: - for component in ( - action_row if isinstance(action_row, list) else action_row.components - ): - if isinstance(component, SelectMenu): - component._json["options"] = ( - [ - option if isinstance(option, dict) else option._json - for option in component.options - ] - if component._json.get("options") - else [] - ) - _components.append( { "type": 1, "components": [ ( - component._json - if component._json.get("custom_id") or component._json.get("url") + component_json + if (component_json := component._json).get("custom_id") or component_json.get("url") else [] ) for component in ( @@ -294,8 +281,8 @@ def __check_action_row(): _components: List[dict] = [{"type": 1, "components": []}] _components[0]["components"] = [ ( - component._json - if component._json.get("custom_id") or component._json.get("url") + component_json + if (component_json := component._json).get("custom_id") or component_json.get("url") else [] ) for component in components.components @@ -308,24 +295,13 @@ def __check_components(): if isinstance(components, list) and all( isinstance(component, (Button, SelectMenu)) for component in components ): - for component in components: - if isinstance(component, SelectMenu): - component._json["options"] = ( - [ - options if isinstance(options, dict) else options._json - for options in component._json["options"] - ] - if component._json.get("options") - else [] - ) - _components = [ { "type": 1, "components": [ ( - component._json - if component._json.get("custom_id") or component._json.get("url") + component_json + if (component_json := component._json).get("custom_id") or component_json.get("url") else [] ) for component in components @@ -337,25 +313,16 @@ def __check_components(): elif isinstance(components, Button): _components: List[dict] = [{"type": 1, "components": []}] _components[0]["components"] = ( - [components._json] - if components._json.get("custom_id") or components._json.get("url") + [component_json] + if (component_json := components._json).get("custom_id") or component_json.get("url") else [] ) return _components elif isinstance(components, SelectMenu): _components: List[dict] = [{"type": 1, "components": []}] - components._json["options"] = ( - [ - options if isinstance(options, dict) else options._json - for options in components._json["options"] - ] - if components._json.get("options") - else [] - ) - _components[0]["components"] = ( - [components._json] - if components._json.get("custom_id") or components._json.get("url") + [components_json] + if (components_json := components._json).get("custom_id") or components_json.get("url") else [] ) return _components From 68489e75d1c456aa94a9850097bfcf907edc5521 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 08:32:54 +0000 Subject: [PATCH 11/35] ci: correct from checks. --- interactions/client/models/component.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index 291aa2cf1..c891cd0e8 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -264,7 +264,8 @@ def __check_action_row(): "components": [ ( component_json - if (component_json := component._json).get("custom_id") or component_json.get("url") + if (component_json := component._json).get("custom_id") + or component_json.get("url") else [] ) for component in ( @@ -282,7 +283,8 @@ def __check_action_row(): _components[0]["components"] = [ ( component_json - if (component_json := component._json).get("custom_id") or component_json.get("url") + if (component_json := component._json).get("custom_id") + or component_json.get("url") else [] ) for component in components.components @@ -301,7 +303,8 @@ def __check_components(): "components": [ ( component_json - if (component_json := component._json).get("custom_id") or component_json.get("url") + if (component_json := component._json).get("custom_id") + or component_json.get("url") else [] ) for component in components @@ -314,7 +317,8 @@ def __check_components(): _components: List[dict] = [{"type": 1, "components": []}] _components[0]["components"] = ( [component_json] - if (component_json := components._json).get("custom_id") or component_json.get("url") + if (component_json := components._json).get("custom_id") + or component_json.get("url") else [] ) return _components @@ -322,7 +326,8 @@ def __check_components(): _components: List[dict] = [{"type": 1, "components": []}] _components[0]["components"] = ( [components_json] - if (components_json := components._json).get("custom_id") or components_json.get("url") + if (components_json := components._json).get("custom_id") + or components_json.get("url") else [] ) return _components From 2d1221dcc2619e48d87133e962c560abf0acdef6 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 13:33:46 +0500 Subject: [PATCH 12/35] refactor: run pre-commit --- interactions/api/models/webhook.py | 2 +- interactions/client/models/component.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/interactions/api/models/webhook.py b/interactions/api/models/webhook.py index 77e9b3ca1..22134d578 100644 --- a/interactions/api/models/webhook.py +++ b/interactions/api/models/webhook.py @@ -1,5 +1,5 @@ from enum import IntEnum -from typing import TYPE_CHECKING, Any, List, Optional, Union +from typing import TYPE_CHECKING, List, Optional, Union from ...utils.attrs_utils import ClientSerializerMixin, define, field from ...utils.missing import MISSING diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index 291aa2cf1..c891cd0e8 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -264,7 +264,8 @@ def __check_action_row(): "components": [ ( component_json - if (component_json := component._json).get("custom_id") or component_json.get("url") + if (component_json := component._json).get("custom_id") + or component_json.get("url") else [] ) for component in ( @@ -282,7 +283,8 @@ def __check_action_row(): _components[0]["components"] = [ ( component_json - if (component_json := component._json).get("custom_id") or component_json.get("url") + if (component_json := component._json).get("custom_id") + or component_json.get("url") else [] ) for component in components.components @@ -301,7 +303,8 @@ def __check_components(): "components": [ ( component_json - if (component_json := component._json).get("custom_id") or component_json.get("url") + if (component_json := component._json).get("custom_id") + or component_json.get("url") else [] ) for component in components @@ -314,7 +317,8 @@ def __check_components(): _components: List[dict] = [{"type": 1, "components": []}] _components[0]["components"] = ( [component_json] - if (component_json := components._json).get("custom_id") or component_json.get("url") + if (component_json := components._json).get("custom_id") + or component_json.get("url") else [] ) return _components @@ -322,7 +326,8 @@ def __check_components(): _components: List[dict] = [{"type": 1, "components": []}] _components[0]["components"] = ( [components_json] - if (components_json := components._json).get("custom_id") or components_json.get("url") + if (components_json := components._json).get("custom_id") + or components_json.get("url") else [] ) return _components From 15f70488d04b2c546410c965b64b4fc057d1671a Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 14:38:14 +0500 Subject: [PATCH 13/35] fix: oop --- interactions/utils/attrs_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interactions/utils/attrs_utils.py b/interactions/utils/attrs_utils.py index 0e8ba050d..61c7e3b29 100644 --- a/interactions/utils/attrs_utils.py +++ b/interactions/utils/attrs_utils.py @@ -92,7 +92,7 @@ def _filter(attrib: attrs.Attribute, value: Any): not in { "converter", } - and value + and value is not None ) def _serializer(obj: Any, attrib: attrs.Attribute, value: Any): From fd30a94b5bae3dad9a46847ed8138c07ef5759e5 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 14:38:35 +0500 Subject: [PATCH 14/35] refactor: wsclient is hard. part 2 --- interactions/api/gateway/client.py | 48 +++++++++++------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index 93792fe1d..c3dcd69fa 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -366,7 +366,6 @@ def _dispatch_event(self, event: str, data: dict) -> None: ) if _type: _type[option.value]._client = self._http - option.value = _type[option.value] # TODO: uhh _option = self.__sub_command_context(option, _context) __kwargs.update(_option) @@ -721,13 +720,13 @@ def __contextualize(self, data: dict) -> "_Context": return context(**data) - def __sub_command_context(self, data: Option, context: "_Context") -> Union[Tuple[str], dict]: + def __sub_command_context(self, option: Option, context: "_Context") -> Union[Tuple[str], dict]: """ Checks if an application command schema has sub commands needed for argument collection. - :param data: The data structure of the option. - :type data: Union[dict, Option] + :param option: The option object. + :type option: Option :param context: The context to refer subcommands from. :type context: object :return: A dictionary of the collected options, if any. @@ -735,33 +734,30 @@ def __sub_command_context(self, data: Option, context: "_Context") -> Union[Tupl """ # TODO: uhhhhhhhhhhhhhhhhhh __kwargs: dict = {} - _data: dict = data._json + _data: dict = option._json - def _check_auto(option: dict) -> Optional[Tuple[str]]: - return (option["name"], option["value"]) if option.get("focused") else None + def _check_auto(_option: dict) -> Optional[Tuple[str]]: + print(_option) + return (_option["name"], _option["value"]) if _option.get("focused") else None check = _check_auto(_data) if check: return check - if _data.get("options"): + if options := _data.get("options"): if _data["type"] == OptionType.SUB_COMMAND: __kwargs["sub_command"] = _data["name"] - for sub_option in _data["options"]: + for sub_option in options: _check = _check_auto(sub_option) _type = self.__option_type_context( context, - sub_option.type.value, + sub_option["type"], ) if _type: - if isinstance(sub_option, dict): - _type[sub_option["value"]]._client = self._http - sub_option.update({"value": _type[sub_option["value"]]}) - else: - _type[sub_option.value]._client = self._http - sub_option._json.update({"value": _type[sub_option.value]}) + _type[sub_option["value"]]._client = self._http + sub_option.update({"value": _type[sub_option["value"]]}) if _check: return _check @@ -776,31 +772,23 @@ def _check_auto(option: dict) -> Optional[Tuple[str]]: _check = _check_auto(sub_option) _type = self.__option_type_context( context, - ( - sub_option["type"] - if isinstance(sub_option, dict) - else sub_option.type.value - ), + sub_option["type"], ) if _type: - if isinstance(sub_option, dict): - _type[sub_option["value"]]._client = self._http - sub_option.update({"value": _type[sub_option["value"]]}) - else: - _type[sub_option.value]._client = self._http - sub_option._json.update({"value": _type[sub_option.value]}) + _type[sub_option["value"]]._client = self._http + sub_option.update({"value": _type[sub_option["value"]]}) if _check: return _check __kwargs[sub_option["name"]] = sub_option["value"] - elif _data.get("type") and _data["type"] == OptionType.SUB_COMMAND: + elif _data.get("type") == OptionType.SUB_COMMAND: # sub_command_groups must have options so there is no extra check needed for those __kwargs["sub_command"] = _data["name"] - elif _data.get("value") is not None and _data.get("name") is not None: - __kwargs[_data["name"]] = _data["value"] + elif (name := _data.get("name")) is not None and (value := _data.get("value")) is not None: + __kwargs[name] = value return __kwargs From 171e1ea5ca17e9ad8de84b8a0654ce52732db170 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 18 Oct 2022 14:38:49 +0500 Subject: [PATCH 15/35] chore: remove comment --- interactions/api/models/webhook.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interactions/api/models/webhook.py b/interactions/api/models/webhook.py index 22134d578..e2e5e9aaf 100644 --- a/interactions/api/models/webhook.py +++ b/interactions/api/models/webhook.py @@ -65,7 +65,7 @@ def __attrs_post_init__(self): self.source_guild = ( Guild(**self.source_guild, _client=self._client) - if self.source_guild # TODO: is it dict? + if self.source_guild else None ) self.source_channel = ( From 8ded3ed287936138a6150bc2d97272c34c417343 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 09:39:02 +0000 Subject: [PATCH 16/35] ci: correct from checks. --- interactions/api/models/webhook.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interactions/api/models/webhook.py b/interactions/api/models/webhook.py index e2e5e9aaf..ca6dea014 100644 --- a/interactions/api/models/webhook.py +++ b/interactions/api/models/webhook.py @@ -64,9 +64,7 @@ def __attrs_post_init__(self): from .guild import Guild self.source_guild = ( - Guild(**self.source_guild, _client=self._client) - if self.source_guild - else None + Guild(**self.source_guild, _client=self._client) if self.source_guild else None ) self.source_channel = ( Channel(**self.source_channel, _client=self._client) if self.source_channel else None From b9f0e6ee40872264c35eedcecdc7792b31e97fa0 Mon Sep 17 00:00:00 2001 From: Damego Date: Wed, 19 Oct 2022 11:38:06 +0500 Subject: [PATCH 17/35] refactor: remove comments and debug print --- interactions/api/gateway/client.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index c3dcd69fa..85cbf356c 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -511,7 +511,7 @@ def _dispatch_event(self, event: str, data: dict) -> None: old_obj = _cache.get(id) if old_obj: before = model(**old_obj._json) - old_obj.update(**data) # TODO: are you sure? + old_obj.update(**data) else: before = None old_obj = obj @@ -732,12 +732,10 @@ def __sub_command_context(self, option: Option, context: "_Context") -> Union[Tu :return: A dictionary of the collected options, if any. :rtype: Union[Tuple[str], dict] """ - # TODO: uhhhhhhhhhhhhhhhhhh __kwargs: dict = {} _data: dict = option._json def _check_auto(_option: dict) -> Optional[Tuple[str]]: - print(_option) return (_option["name"], _option["value"]) if _option.get("focused") else None check = _check_auto(_data) From a0c23280bec7f56ac4c663a94a4741d56dd92035 Mon Sep 17 00:00:00 2001 From: Damego Date: Wed, 19 Oct 2022 11:40:08 +0500 Subject: [PATCH 18/35] refactor(channel): remove _json modifing --- interactions/api/models/channel.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/interactions/api/models/channel.py b/interactions/api/models/channel.py index 7910f6123..4779d429d 100644 --- a/interactions/api/models/channel.py +++ b/interactions/api/models/channel.py @@ -1727,8 +1727,8 @@ async def create_forum_post( _content = content elif isinstance(content, Message): + _content = content._json if content.attachments and any(attach.id is None for attach in content.attachments): - # TODO: wat for attach in content.attachments: _data = await attach.download() @@ -1742,9 +1742,7 @@ async def create_forum_post( _files = [__files._json_payload(0)] __files = [__files] - content._json["attachments"] = _files - - _content = content._json + _content["attachments"] = _files elif isinstance(content, Attachment): if content.id: From d6a2a9cc1bd0c0aafa985f815ced8bb8747548c1 Mon Sep 17 00:00:00 2001 From: Damego Date: Wed, 19 Oct 2022 12:15:55 +0500 Subject: [PATCH 19/35] chore: remove comment --- interactions/client/models/command.py | 1 - 1 file changed, 1 deletion(-) diff --git a/interactions/client/models/command.py b/interactions/client/models/command.py index 014eea866..451ae1856 100644 --- a/interactions/client/models/command.py +++ b/interactions/client/models/command.py @@ -58,7 +58,6 @@ class Choice(DictSerializerMixin): name_localizations: Optional[Dict[Union[str, Locale], str]] = field(default=None) def __attrs_post_init__(self): - # TODO: test it if self.name_localizations: self.name_localizations = { k if isinstance(k, Locale) else Locale(k): v From 138e56b11bb941186d3d699475e703ac86566f5f Mon Sep 17 00:00:00 2001 From: Damego Date: Wed, 19 Oct 2022 13:04:18 +0500 Subject: [PATCH 20/35] refactor: wsclient is hard. Part 3. refactor `__sub_command_context` --- interactions/api/gateway/client.py | 47 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index 85cbf356c..1799a434a 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -366,6 +366,8 @@ def _dispatch_event(self, event: str, data: dict) -> None: ) if _type: _type[option.value]._client = self._http + # I'm not sure about line below because its doesn't affect anything + option.value = _type[option.value] _option = self.__sub_command_context(option, _context) __kwargs.update(_option) @@ -733,59 +735,58 @@ def __sub_command_context(self, option: Option, context: "_Context") -> Union[Tu :rtype: Union[Tuple[str], dict] """ __kwargs: dict = {} - _data: dict = option._json - def _check_auto(_option: dict) -> Optional[Tuple[str]]: - return (_option["name"], _option["value"]) if _option.get("focused") else None + def _check_auto(_option: Option) -> Optional[Tuple[str]]: + return (_option.name, _option.value) if _option.focused else None - check = _check_auto(_data) + check = _check_auto(option) if check: return check - if options := _data.get("options"): - if _data["type"] == OptionType.SUB_COMMAND: - __kwargs["sub_command"] = _data["name"] + if options := option.options: + if option.type == OptionType.SUB_COMMAND: + __kwargs["sub_command"] = option.name for sub_option in options: _check = _check_auto(sub_option) _type = self.__option_type_context( context, - sub_option["type"], + sub_option.type, ) if _type: - _type[sub_option["value"]]._client = self._http - sub_option.update({"value": _type[sub_option["value"]]}) + _type[sub_option.value]._client = self._http + sub_option.value = _type[sub_option.value] # ? uh? if _check: return _check - __kwargs[sub_option["name"]] = sub_option["value"] - elif _data["type"] == OptionType.SUB_COMMAND_GROUP: - __kwargs["sub_command_group"] = _data["name"] - for _group_option in _data["options"]: + __kwargs[sub_option.name] = sub_option.value + elif option.type == OptionType.SUB_COMMAND_GROUP: + __kwargs["sub_command_group"] = option.name + for _group_option in option.options: _check_auto(_group_option) - __kwargs["sub_command"] = _group_option["name"] + __kwargs["sub_command"] = _group_option.name - for sub_option in _group_option["options"]: + for sub_option in _group_option.options: _check = _check_auto(sub_option) _type = self.__option_type_context( context, - sub_option["type"], + sub_option.type, ) if _type: - _type[sub_option["value"]]._client = self._http - sub_option.update({"value": _type[sub_option["value"]]}) + _type[sub_option.value]._client = self._http + sub_option.value = _type[sub_option.value] # ? uh? if _check: return _check - __kwargs[sub_option["name"]] = sub_option["value"] + __kwargs[sub_option.name] = sub_option.value - elif _data.get("type") == OptionType.SUB_COMMAND: + elif option.type == OptionType.SUB_COMMAND: # sub_command_groups must have options so there is no extra check needed for those - __kwargs["sub_command"] = _data["name"] + __kwargs["sub_command"] = option.name - elif (name := _data.get("name")) is not None and (value := _data.get("value")) is not None: + elif (name := option.name) is not None and (value := option.value) is not None: __kwargs[name] = value return __kwargs From 447b1a0e0ae6b4c4f6f68b09fd45e52b3afa4621 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 19 Oct 2022 08:04:29 +0000 Subject: [PATCH 21/35] ci: correct from checks. --- interactions/api/gateway/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index 1799a434a..317ff6134 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -756,7 +756,7 @@ def _check_auto(_option: Option) -> Optional[Tuple[str]]: if _type: _type[sub_option.value]._client = self._http - sub_option.value = _type[sub_option.value] # ? uh? + sub_option.value = _type[sub_option.value] # ? uh? if _check: return _check @@ -776,7 +776,7 @@ def _check_auto(_option: Option) -> Optional[Tuple[str]]: if _type: _type[sub_option.value]._client = self._http - sub_option.value = _type[sub_option.value] # ? uh? + sub_option.value = _type[sub_option.value] # ? uh? if _check: return _check From 7b48fafb394c0f7f34d3eb526db8eea6011aef61 Mon Sep 17 00:00:00 2001 From: Damego Date: Wed, 19 Oct 2022 13:05:42 +0500 Subject: [PATCH 22/35] chore: remove comments --- interactions/api/gateway/client.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index 317ff6134..3ef0d721b 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -756,7 +756,7 @@ def _check_auto(_option: Option) -> Optional[Tuple[str]]: if _type: _type[sub_option.value]._client = self._http - sub_option.value = _type[sub_option.value] # ? uh? + sub_option.value = _type[sub_option.value] if _check: return _check @@ -776,7 +776,7 @@ def _check_auto(_option: Option) -> Optional[Tuple[str]]: if _type: _type[sub_option.value]._client = self._http - sub_option.value = _type[sub_option.value] # ? uh? + sub_option.value = _type[sub_option.value] if _check: return _check From c2bf51f1f70826fbfbf0ae42ca1922621fb9a1a6 Mon Sep 17 00:00:00 2001 From: Damego Date: Sun, 6 Nov 2022 22:14:44 +0500 Subject: [PATCH 23/35] Update interactions/utils/attrs_utils.py --- interactions/utils/attrs_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interactions/utils/attrs_utils.py b/interactions/utils/attrs_utils.py index 61c7e3b29..5954687af 100644 --- a/interactions/utils/attrs_utils.py +++ b/interactions/utils/attrs_utils.py @@ -97,7 +97,7 @@ def _filter(attrib: attrs.Attribute, value: Any): def _serializer(obj: Any, attrib: attrs.Attribute, value: Any): if isinstance(value, Snowflake): - return str(value) + return int(value) if isinstance(value, Enum): return value.value if isinstance(value, datetime): From 619d07363fcd10217357fe7ebc2d5260594a121d Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 7 Nov 2022 08:13:28 +0500 Subject: [PATCH 24/35] Update interactions/client/models/component.py Co-authored-by: EdVraz <88881326+EdVraz@users.noreply.github.com> --- interactions/client/models/component.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index c891cd0e8..6e692e759 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -264,8 +264,6 @@ def __check_action_row(): "components": [ ( component_json - if (component_json := component._json).get("custom_id") - or component_json.get("url") else [] ) for component in ( From 805483caa44979d20eb692b37209d4073924ac54 Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 7 Nov 2022 08:13:36 +0500 Subject: [PATCH 25/35] Update interactions/client/models/component.py Co-authored-by: EdVraz <88881326+EdVraz@users.noreply.github.com> --- interactions/client/models/component.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index 6e692e759..69dea98e6 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -281,8 +281,6 @@ def __check_action_row(): _components[0]["components"] = [ ( component_json - if (component_json := component._json).get("custom_id") - or component_json.get("url") else [] ) for component in components.components From 0245a7ba8e22160a4944ab6309c5ae95deeeb91f Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 7 Nov 2022 08:13:55 +0500 Subject: [PATCH 26/35] Update interactions/client/models/component.py Co-authored-by: EdVraz <88881326+EdVraz@users.noreply.github.com> --- interactions/client/models/component.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index 69dea98e6..656d4beef 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -237,7 +237,7 @@ class ActionRow(DictSerializerMixin): components: Optional[List[Component]] = field(converter=convert_list(Component), default=None) @classmethod - def new(cls, *components: Union[Button, SelectMenu, TextInput]) -> "ActionRow": + def new(cls, *components: Union[Button, SelectMenu, TextInput]) -> List["ActionRow"]: r""" A class method for creating a new ``ActionRow``. From ec13a1fe6523284ca6d4a2608a65eb9f146ed7e9 Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 7 Nov 2022 08:14:04 +0500 Subject: [PATCH 27/35] Update interactions/client/models/component.py Co-authored-by: EdVraz <88881326+EdVraz@users.noreply.github.com> --- interactions/client/models/component.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index 656d4beef..813017fb9 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -299,8 +299,6 @@ def __check_components(): "components": [ ( component_json - if (component_json := component._json).get("custom_id") - or component_json.get("url") else [] ) for component in components From 12b27fcb6546ef82b748d9995d8d94bf8ce616fe Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 7 Nov 2022 08:14:14 +0500 Subject: [PATCH 28/35] Update interactions/client/models/component.py Co-authored-by: EdVraz <88881326+EdVraz@users.noreply.github.com> --- interactions/client/models/component.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index 813017fb9..7745336eb 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -311,8 +311,6 @@ def __check_components(): _components: List[dict] = [{"type": 1, "components": []}] _components[0]["components"] = ( [component_json] - if (component_json := components._json).get("custom_id") - or component_json.get("url") else [] ) return _components From 8cce2d27e6e88ac7af28d364a6893e1b90cd87f6 Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 7 Nov 2022 08:15:44 +0500 Subject: [PATCH 29/35] Update attrs_utils.py --- interactions/utils/attrs_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interactions/utils/attrs_utils.py b/interactions/utils/attrs_utils.py index 5954687af..61c7e3b29 100644 --- a/interactions/utils/attrs_utils.py +++ b/interactions/utils/attrs_utils.py @@ -97,7 +97,7 @@ def _filter(attrib: attrs.Attribute, value: Any): def _serializer(obj: Any, attrib: attrs.Attribute, value: Any): if isinstance(value, Snowflake): - return int(value) + return str(value) if isinstance(value, Enum): return value.value if isinstance(value, datetime): From 2cea0dc407486bdb97b0b3710bc85d8465cb9499 Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 7 Nov 2022 15:57:33 +0500 Subject: [PATCH 30/35] fix syntax error --- interactions/client/models/component.py | 31 ++++--------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index 7745336eb..b7d73b07b 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -262,10 +262,7 @@ def __check_action_row(): { "type": 1, "components": [ - ( - component_json - else [] - ) + component._json for component in ( action_row if isinstance(action_row, list) @@ -279,10 +276,7 @@ def __check_action_row(): elif isinstance(components, ActionRow): _components: List[dict] = [{"type": 1, "components": []}] _components[0]["components"] = [ - ( - component_json - else [] - ) + component._json for component in components.components ] return _components @@ -297,31 +291,16 @@ def __check_components(): { "type": 1, "components": [ - ( - component_json - else [] - ) + component._json for component in components ], } ] return _components - elif isinstance(components, Button): - _components: List[dict] = [{"type": 1, "components": []}] - _components[0]["components"] = ( - [component_json] - else [] - ) - return _components - elif isinstance(components, SelectMenu): + elif isinstance(components, (Button, SelectMenu)): _components: List[dict] = [{"type": 1, "components": []}] - _components[0]["components"] = ( - [components_json] - if (components_json := components._json).get("custom_id") - or components_json.get("url") - else [] - ) + _components[0]["components"] = [components._json] return _components else: raise LibraryException( From e13013717f7955e606b1b22f598b3c103dd267d9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 10:57:50 +0000 Subject: [PATCH 31/35] ci: correct from checks. --- interactions/client/models/component.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index b7d73b07b..a1ad8eb9f 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -275,10 +275,7 @@ def __check_action_row(): elif isinstance(components, ActionRow): _components: List[dict] = [{"type": 1, "components": []}] - _components[0]["components"] = [ - component._json - for component in components.components - ] + _components[0]["components"] = [component._json for component in components.components] return _components else: return False @@ -290,10 +287,7 @@ def __check_components(): _components = [ { "type": 1, - "components": [ - component._json - for component in components - ], + "components": [component._json for component in components], } ] return _components From 87a25bc7b53a4ffc466ae17096a4b288f605c758 Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 7 Nov 2022 17:15:03 +0500 Subject: [PATCH 32/35] fix: missed action rows in the modal components --- interactions/client/models/component.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index a1ad8eb9f..cb195b6d5 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -210,6 +210,13 @@ class Modal(DictSerializerMixin): title: str = field() components: List[Component] = field(converter=convert_list(Component)) + @property + def _json(self) -> dict: + json: dict = super()._json + json["components"] = [{"type": 1, "components": [component]} for component in json["components"]] + + return json + @define() class ActionRow(DictSerializerMixin): From a187eefce826f3293b4efc48f57ba8a642511c65 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 7 Nov 2022 12:15:24 +0000 Subject: [PATCH 33/35] ci: correct from checks. --- interactions/client/models/component.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interactions/client/models/component.py b/interactions/client/models/component.py index cb195b6d5..5c5b95725 100644 --- a/interactions/client/models/component.py +++ b/interactions/client/models/component.py @@ -213,7 +213,9 @@ class Modal(DictSerializerMixin): @property def _json(self) -> dict: json: dict = super()._json - json["components"] = [{"type": 1, "components": [component]} for component in json["components"]] + json["components"] = [ + {"type": 1, "components": [component]} for component in json["components"] + ] return json From a3af8fa4822f5813e3072ac81a532e81a444393d Mon Sep 17 00:00:00 2001 From: Damego Date: Mon, 7 Nov 2022 18:05:59 +0500 Subject: [PATCH 34/35] remove comment --- interactions/api/gateway/client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/interactions/api/gateway/client.py b/interactions/api/gateway/client.py index 5b8b9c8ae..b27cd008c 100644 --- a/interactions/api/gateway/client.py +++ b/interactions/api/gateway/client.py @@ -372,7 +372,6 @@ def _dispatch_event(self, event: str, data: dict) -> None: ) if _type: _type[option.value]._client = self._http - # I'm not sure about line below because its doesn't affect anything option.value = _type[option.value] _option = self.__sub_command_context(option, _context) __kwargs.update(_option) From 75b6bfa278fd95c0a92343c2e605706cda22db83 Mon Sep 17 00:00:00 2001 From: Damego Date: Tue, 8 Nov 2022 16:15:21 +0500 Subject: [PATCH 35/35] if snowflakes are technically str, why i have to do this? --- interactions/client/bot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interactions/client/bot.py b/interactions/client/bot.py index 9be989250..5a404fe63 100644 --- a/interactions/client/bot.py +++ b/interactions/client/bot.py @@ -639,7 +639,7 @@ async def __sync(self) -> None: # sourcery no-metrics if isinstance(coro._command_data, list): _guild_command: dict for _guild_command in coro._command_data: - _guild_id = _guild_command.get("guild_id") + _guild_id = int(_guild_command.get("guild_id")) if _guild_id in __blocked_guilds: log.fatal(f"Cannot sync commands on guild with id {_guild_id}!") raise LibraryException(50001, message="Missing Access |")