1
+ from .base import DiscordObject
2
+ from aiohttp import FormData
1
3
from datetime import datetime
2
- from typing import Iterable , List , Optional , Union , Set
4
+ from typing import type_check_only
5
+ import attrs
3
6
7
+ from interactions .client import Client
4
8
from interactions .client .const import Absent
5
9
from interactions .client .mixins .send import SendMixin
6
10
from interactions .models .discord .activity import Activity
7
11
from interactions .models .discord .asset import Asset
8
12
from interactions .models .discord .channel import DM , TYPE_GUILD_CHANNEL
9
13
from interactions .models .discord .color import Color
10
- from interactions .models .discord .enums import Permissions , PremiumType , Status , UserFlags
14
+ from interactions .models .discord .enums import MemberFlags , Permissions , PremiumType , Status , UserFlags
11
15
from interactions .models .discord .file import UPLOADABLE_TYPE
12
16
from interactions .models .discord .guild import Guild
13
17
from interactions .models .discord .role import Role
14
18
from interactions .models .discord .snowflake import Snowflake_Type
15
19
from interactions .models .discord .timestamp import Timestamp
16
20
from interactions .models .discord .voice_state import VoiceState
17
- from . base import DiscordObject
21
+ from typing import Any , Dict , Iterable , List , Optional , Set , Union
18
22
19
23
class _SendDMMixin (SendMixin ):
20
24
id : Snowflake_Type
25
+ async def _send_http_request (
26
+ self , message_payload : Union [dict , "FormData" ], files : Union [list ["UPLOADABLE_TYPE" ], None ] = ...
27
+ ) -> dict : ...
28
+
29
+ # note: what we're trying to achieve here is making isinstance checks as accurate as possible when typehinting
30
+ # Member, while "having" the attributes of User (because of __getattr__), is not actually a subclass of either
31
+ # BaseUser or User - it's its own seperate class
32
+ # we still want to typehint Member with all of the User attributes though, so what we do is create fake
33
+ # mixins that actually don't exist, and make BaseUser and User inherit from that
34
+ # then, we can make Member inheir the fake user mixin, and now we have a Member class with User attributes
35
+ # and that understands isinstance(member, User) is false
21
36
22
- class BaseUser (DiscordObject , _SendDMMixin ):
37
+ @type_check_only
38
+ @attrs .define (eq = False , order = False , hash = False , kw_only = True ) # properly typehints added attributes by attrs
39
+ class FakeBaseUserMixin (DiscordObject , _SendDMMixin ):
23
40
username : str
24
41
discriminator : int
25
42
avatar : Asset
43
+ def __str__ (self ) -> str : ...
44
+ @classmethod
45
+ def _process_dict (cls , data : Dict [str , Any ], client : Client ) -> Dict [str , Any ]: ...
26
46
@property
27
47
def tag (self ) -> str : ...
28
48
@property
@@ -36,7 +56,12 @@ class BaseUser(DiscordObject, _SendDMMixin):
36
56
@property
37
57
def mutual_guilds (self ) -> List ["Guild" ]: ...
38
58
39
- class User (BaseUser ):
59
+ @attrs .define (eq = False , order = False , hash = False , kw_only = True )
60
+ class BaseUser (FakeBaseUserMixin ): ...
61
+
62
+ @type_check_only
63
+ @attrs .define (eq = False , order = False , hash = False , kw_only = True )
64
+ class FakeUserMixin (FakeBaseUserMixin ):
40
65
bot : bool
41
66
system : bool
42
67
public_flags : UserFlags
@@ -45,36 +70,49 @@ class User(BaseUser):
45
70
accent_color : Optional ["Color" ]
46
71
activities : list [Activity ]
47
72
status : Absent [Status ]
73
+ @classmethod
74
+ def _process_dict (cls , data : Dict [str , Any ], client : Client ) -> Dict [str , Any ]: ...
48
75
@property
49
76
def member_instances (self ) -> List ["Member" ]: ...
50
77
78
+ @attrs .define (eq = False , order = False , hash = False , kw_only = True )
79
+ class User (FakeUserMixin , BaseUser ): ...
80
+
81
+ @attrs .define (eq = False , order = False , hash = False , kw_only = True )
51
82
class NaffUser (User ):
52
83
verified : bool
53
84
mfa_enabled : bool
54
85
email : Optional [str ]
55
86
locale : Optional [str ]
56
87
bio : Optional [str ]
57
88
flags : UserFlags
58
- _guild_ids : Set [Snowflake_Type ]
89
+ _guild_ids : Set ["Snowflake_Type" ]
90
+ def _add_guilds (self , guild_ids : Set ["Snowflake_Type" ]) -> None : ...
59
91
@property
60
92
def guilds (self ) -> List ["Guild" ]: ...
61
- async def edit (self , username : Absent [str ] = ..., avatar : Absent [UPLOADABLE_TYPE ] = ...) -> None : ...
93
+ async def edit (self , * , username : Absent [str ] = ..., avatar : Absent [UPLOADABLE_TYPE ] = ...) -> None : ...
62
94
63
- class Member (User ): # for typehinting purposes, we can lie
95
+ @attrs .define (eq = False , order = False , hash = False , kw_only = True )
96
+ class Member (FakeUserMixin ):
64
97
bot : bool
65
98
nick : Optional [str ]
66
99
deaf : bool
67
100
mute : bool
101
+ flags : MemberFlags
68
102
joined_at : Timestamp
69
103
premium_since : Optional ["Timestamp" ]
70
104
pending : Optional [bool ]
71
105
guild_avatar : Asset
72
- communication_disabled_until : Optional [Timestamp ]
106
+ communication_disabled_until : Optional [" Timestamp" ]
73
107
_guild_id : Snowflake_Type
74
- _role_ids : List [Snowflake_Type ]
108
+ _role_ids : List ["Snowflake_Type" ]
109
+ _user_ref : frozenset
110
+ @classmethod
111
+ def _process_dict (cls , data : Dict [str , Any ], client : Client ) -> Dict [str , Any ]: ...
75
112
def update_from_dict (self , data ) -> None : ...
76
113
@property
77
114
def user (self ) -> User : ...
115
+ def __str__ (self ) -> str : ...
78
116
@property
79
117
def nickname (self ) -> str : ...
80
118
@nickname .setter
@@ -113,12 +151,14 @@ class Member(User): # for typehinting purposes, we can lie
113
151
self ,
114
152
* ,
115
153
nickname : Absent [str ] = ...,
116
- roles : Absent [Iterable [Snowflake_Type ]] = ...,
154
+ roles : Absent [Iterable [" Snowflake_Type" ]] = ...,
117
155
mute : Absent [bool ] = ...,
118
156
deaf : Absent [bool ] = ...,
119
157
channel_id : Absent ["Snowflake_Type" ] = ...,
120
158
communication_disabled_until : Absent [Union ["Timestamp" , None ]] = ...,
121
- reason : Absent [str ] = ...,
159
+ reason : Absent [str ] = ...
122
160
) -> None : ...
123
161
async def kick (self , reason : Absent [str ] = ...) -> None : ...
124
- async def ban (self , delete_message_days : int = ..., reason : Absent [str ] = ...) -> None : ...
162
+ async def ban (
163
+ self , delete_message_days : Absent [int ] = ..., delete_message_seconds : int = ..., reason : Absent [str ] = ...
164
+ ) -> None : ...
0 commit comments