Passed
Pull Request — main (#167)
by
unknown
01:29
created

pincer.objects.app.command.AppCommand.__eq__()   A

Complexity

Conditions 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nop 2
1
# Copyright Pincer 2021-Present
0 ignored issues
show
introduced by
Missing module docstring
Loading history...
2
# Full MIT License can be found in `LICENSE` at the project root.
3
4
from __future__ import annotations
5
6
from dataclasses import dataclass
7
from typing import List, Union, TYPE_CHECKING
8
9
from .command_types import AppCommandOptionType, AppCommandType
10
from ...utils.api_object import APIObject
0 ignored issues
show
Bug introduced by
The name api_object does not seem to exist in module pincer.utils.
Loading history...
introduced by
Cannot import 'utils.api_object' due to syntax error 'invalid syntax (<unknown>, line 80)'
Loading history...
11
from ...utils.conversion import convert
12
from ...utils.extraction import get_index
0 ignored issues
show
Unused Code introduced by
Unused get_index imported from utils.extraction
Loading history...
13
from ...utils.snowflake import Snowflake
14
from ...utils.types import MISSING
15
16
if TYPE_CHECKING:
17
    from ..app.throttle_scope import ThrottleScope
18
    from ...utils.types import APINullable, Coro, choice_value_types
19
20
21
@dataclass
22
class AppCommandInteractionDataOption(APIObject):
23
    """
24
    Represents a Discord Application Command Interaction Data Option
25
26
    :param name:
27
        the name of the parameter
28
29
    :param type:
30
        value of application command option type
31
32
    :param value:
33
        the value of the pair
34
35
    :param options:
36
        present if this option is a group or subcommand
37
    """
38
    name: str
39
    value: APINullable[str] = MISSING
40
    type: APINullable[AppCommandOptionType] = MISSING
41
    options: APINullable[
42
        List[AppCommandInteractionDataOption]] = MISSING
43
44
45
@dataclass
46
class AppCommandOptionChoice(APIObject):
47
    """
48
    Represents a Discord Application Command Option Choice object
49
50
    :param name:
51
        1-100 character choice name
52
53
    :param value:
54
        value of the choice, up to 100 characters if string
55
    """
56
    name: str
57
    value: Union[choice_value_types]
58
59
60
@dataclass
61
class AppCommandOption(APIObject):
62
    """
63
    Represents a Discord Application Command Option object
64
65
    :param type:
66
        the type of option
67
68
    :param name:
69
        1-32 lowercase character name matching `^[\\w-]{1,32}$`
70
71
    :param description:
72
        1-100 character description
73
74
    :param required:
75
        if the parameter is required or optional--default `False`
76
77
    :param choices:
78
        choices for `STRING`, `INTEGER`, and `NUMBER`
79
        types for the user to pick from, max 25
80
81
    :param options:
82
        if the option is a subcommand or subcommand group type,
83
        this nested options will be the parameters
84
    """
85
    type: AppCommandOptionType
86
    name: str
87
    description: str
88
89
    required: APINullable[bool] = False
90
    choices: APINullable[List[AppCommandOptionChoice]] = MISSING
91
    options: APINullable[List[AppCommandOption]] = MISSING
92
93
    def __post_init__(self):
94
        self.type = AppCommandOptionType(self.type)
95
        self.choices = convert(
96
            self.choices,
97
            AppCommandOptionChoice.from_dict,
98
            AppCommandOptionChoice
99
        )
100
        self.options = convert(
101
            self.options,
102
            AppCommandOption.from_dict,
103
            AppCommandOption
104
        )
105
106
107
@dataclass
0 ignored issues
show
best-practice introduced by
Too many instance attributes (12/7)
Loading history...
108
class AppCommand(APIObject):
109
    """
110
    Represents a Discord Application Command object
111
112
    :param id:
113
        unique id of the command
114
115
    :param type:
116
        the type of command, defaults `1` if not set
117
118
    :param application_id:
119
        unique id of the parent application
120
121
    :param guild_id:
122
        guild id of the command, if not global
123
124
    :param name:
125
        1-32 character name
126
127
    :param description:
128
        1-100 character description for `CHAT_INPUT` commands,
129
        empty string for `USER` and `MESSAGE` commands
130
131
    :param options:
132
        the parameters for the command, max 25
133
134
    :param default_permission:
135
        whether the command is enabled by default
136
        when the app is added to a guild
137
138
    :param version:
139
        autoincrementing version identifier updated during substantial
140
        record changes
141
    :param default_member_permissions:
142
        # TODO: Fix docs for this when discord has implemented it.
143
    :param dm_permission:
144
        # TODO: Fix docs for this when discord has implemented it.
145
    """
146
    type: AppCommandType
147
    name: str
148
    description: str
149
150
    id: APINullable[Snowflake] = MISSING
151
    version: APINullable[Snowflake] = MISSING
152
    application_id: APINullable[Snowflake] = MISSING
153
    options: APINullable[List[AppCommandOption]] = MISSING
154
    guild_id: APINullable[Snowflake] = MISSING
155
    default_permission: APINullable[bool] = True
156
    default_member_permissions: APINullable[None] = None
157
    dm_permission: APINullable[None] = None
158
159
    _eq_props = [
160
        "type", "name", "description", "guild_id", "default_permission",
161
        "options"
162
    ]
163
164
    def __post_init__(self):
165
        self.id = convert(self.id, Snowflake.from_string)
166
        self.version = convert(self.version, Snowflake.from_string)
167
        self.type = AppCommandType(self.type)
168
        self.application_id = convert(
169
            self.application_id, Snowflake.from_string
170
        )
171
172
        self.options = convert(
173
            self.options,
174
            AppCommandOption.from_dict,
175
            AppCommandOption
176
        )
177
        self.guild_id = convert(self.guild_id, Snowflake.from_string)
178
179
        self.options = [] if self.options is MISSING else self.options
180
181
    def __eq__(self, other: Union[AppCommand, ClientCommandStructure]):
182
        if isinstance(other, ClientCommandStructure):
183
            other = other.app
184
185
        return all(
186
            self.__getattribute__(prop) == other.__getattribute__(prop)
187
            for prop in self._eq_props
188
        )
189
190
    def __hash__(self):
191
        return hash((self.id, self.name, self.description, self.guild_id))
192
193
    def add_option(self, option: AppCommandOption):
194
        """
195
        Add a new option field to the current application command.
196
197
        :param option: The option which will be appended.
198
        """
199
        if self.options:
200
            self.options.append(option)
201
        else:
202
            self.options = [option]
203
204
205
@dataclass
206
class ClientCommandStructure:
207
    """
208
    Represents the structure of how the client saves the existing
209
    commands in the register.
210
211
    :param app:
212
        The command application.
213
214
    :param call:
215
        The coroutine which should be called when the command gets
216
        executed.
217
    """
218
    app: AppCommand
219
    call: Coro
220
    cooldown: int
221
    cooldown_scale: float
222
    cooldown_scope: ThrottleScope
223