1+ from .base import DiscordObject
2+ from aiohttp import FormData
13from datetime import datetime
2- from typing import Iterable , List , Optional , Union , Set
4+ from typing import type_check_only
5+ import attrs
36
7+ from interactions .client import Client
48from interactions .client .const import Absent
59from interactions .client .mixins .send import SendMixin
610from interactions .models .discord .activity import Activity
711from interactions .models .discord .asset import Asset
812from interactions .models .discord .channel import DM , TYPE_GUILD_CHANNEL
913from 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
1115from interactions .models .discord .file import UPLOADABLE_TYPE
1216from interactions .models .discord .guild import Guild
1317from interactions .models .discord .role import Role
1418from interactions .models .discord .snowflake import Snowflake_Type
1519from interactions .models .discord .timestamp import Timestamp
1620from interactions .models .discord .voice_state import VoiceState
17- from . base import DiscordObject
21+ from typing import Any , Dict , Iterable , List , Optional , Set , Union
1822
1923class _SendDMMixin (SendMixin ):
2024 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
2136
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 ):
2340 username : str
2441 discriminator : int
2542 avatar : Asset
43+ def __str__ (self ) -> str : ...
44+ @classmethod
45+ def _process_dict (cls , data : Dict [str , Any ], client : Client ) -> Dict [str , Any ]: ...
2646 @property
2747 def tag (self ) -> str : ...
2848 @property
@@ -36,7 +56,12 @@ class BaseUser(DiscordObject, _SendDMMixin):
3656 @property
3757 def mutual_guilds (self ) -> List ["Guild" ]: ...
3858
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 ):
4065 bot : bool
4166 system : bool
4267 public_flags : UserFlags
@@ -45,36 +70,49 @@ class User(BaseUser):
4570 accent_color : Optional ["Color" ]
4671 activities : list [Activity ]
4772 status : Absent [Status ]
73+ @classmethod
74+ def _process_dict (cls , data : Dict [str , Any ], client : Client ) -> Dict [str , Any ]: ...
4875 @property
4976 def member_instances (self ) -> List ["Member" ]: ...
5077
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 )
5182class NaffUser (User ):
5283 verified : bool
5384 mfa_enabled : bool
5485 email : Optional [str ]
5586 locale : Optional [str ]
5687 bio : Optional [str ]
5788 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 : ...
5991 @property
6092 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 : ...
6294
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 ):
6497 bot : bool
6598 nick : Optional [str ]
6699 deaf : bool
67100 mute : bool
101+ flags : MemberFlags
68102 joined_at : Timestamp
69103 premium_since : Optional ["Timestamp" ]
70104 pending : Optional [bool ]
71105 guild_avatar : Asset
72- communication_disabled_until : Optional [Timestamp ]
106+ communication_disabled_until : Optional [" Timestamp" ]
73107 _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 ]: ...
75112 def update_from_dict (self , data ) -> None : ...
76113 @property
77114 def user (self ) -> User : ...
115+ def __str__ (self ) -> str : ...
78116 @property
79117 def nickname (self ) -> str : ...
80118 @nickname .setter
@@ -113,12 +151,14 @@ class Member(User): # for typehinting purposes, we can lie
113151 self ,
114152 * ,
115153 nickname : Absent [str ] = ...,
116- roles : Absent [Iterable [Snowflake_Type ]] = ...,
154+ roles : Absent [Iterable [" Snowflake_Type" ]] = ...,
117155 mute : Absent [bool ] = ...,
118156 deaf : Absent [bool ] = ...,
119157 channel_id : Absent ["Snowflake_Type" ] = ...,
120158 communication_disabled_until : Absent [Union ["Timestamp" , None ]] = ...,
121- reason : Absent [str ] = ...,
159+ reason : Absent [str ] = ...
122160 ) -> None : ...
123161 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