2525
2626from  __future__ import  annotations 
2727
28- from  typing  import  TYPE_CHECKING , Any , Final , TypeVar 
28+ from  enum  import  IntEnum 
29+ from  typing  import  TYPE_CHECKING , Any , TypeVar 
2930
3031from  .asset  import  Asset 
3132from  .colour  import  Colour 
3637from  .utils  import  (
3738    MISSING ,
3839    _bytes_to_base64_data ,
40+     cached_slot_property ,
41+     deprecated ,
3942    snowflake_time ,
4043)
4144
@@ -109,6 +112,43 @@ def _parse_tag_int(data: RoleTagPayload, key: str) -> int | None:
109112        return  None 
110113
111114
115+ class  RoleType (IntEnum ):
116+     """Represents the type of role. 
117+ 
118+     This is NOT provided by discord but is rather computed by pycord based on the role tags. 
119+ 
120+     .. versionadded:: 2.7 
121+ 
122+     Attributes 
123+     ---------- 
124+     APPLICATION: :class:`int` 
125+         The role is an application role. 
126+     BOOSTER: :class:`int` 
127+         The role is a guild's booster role. 
128+     GUILD_PRODUCT: :class:`int` 
129+         The role is a guild product role. 
130+     PREMIUM_SUBSCRIPTION_BASE: :class:`int` 
131+         The role is a base subscription role. 
132+     PREMIUM_SUBSCRIPTION_TIER: :class:`int` 
133+         The role is a subscription role. 
134+     DRAFT_PREMIUM_SUBSCRIPTION_TIER: :class:`int` 
135+         The role is a draft subscription role. 
136+     INTEGRATION: :class:`int` 
137+         The role is an integration role. 
138+     CONNECTION: :class:`int` 
139+         The role is a guild connections role. 
140+     """ 
141+ 
142+     APPLICATION  =  1 
143+     BOOSTER  =  2 
144+     GUILD_PRODUCT  =  3 
145+     PREMIUM_SUBSCRIPTION_BASE  =  4   # Not possible to determine currently, will be INTEGRATION if it's a base subscription 
146+     PREMIUM_SUBSCRIPTION_TIER  =  5 
147+     DRAFT_PREMIUM_SUBSCRIPTION_TIER  =  5 
148+     INTEGRATION  =  7 
149+     CONNECTION  =  8 
150+ 
151+ 
112152class  RoleTags :
113153    """Represents tags on a role. 
114154
@@ -142,6 +182,7 @@ class RoleTags:
142182        "_guild_connections" ,
143183        "bot_id" ,
144184        "_data" ,
185+         "_type" ,
145186    )
146187
147188    def  __init__ (self , data : RoleTagPayload ):
@@ -161,102 +202,73 @@ def __init__(self, data: RoleTagPayload):
161202            data , "available_for_purchase" 
162203        )
163204
164-     @property  
165-     def  is_bot_role (self ) ->  bool :
166-         """Whether the role is associated with a bot. 
167-         .. versionadded:: 2.7 
168-         """ 
205+     @cached_slot_property ("_type" ) 
206+     def  type (self ) ->  RoleType :
207+         """Determine the role type based on tag flags.""" 
208+         # Bot role 
209+         if  self .bot_id  is  not None :
210+             return  RoleType .APPLICATION 
211+ 
212+         # Role connection 
213+         if  self ._guild_connections  is  True :
214+             return  RoleType .CONNECTION 
215+ 
216+         # Paid roles 
217+         if  self ._guild_connections  is  False :
218+             if  self ._premium_subscriber  is  False :
219+                 return  RoleType .GUILD_PRODUCT 
220+ 
221+             if  self ._premium_subscriber  is  True :
222+                 return  RoleType .BOOSTER 
223+ 
224+             # subscription roles 
225+             if  self .integration_id  is  not None :
226+                 if  (
227+                     self ._premium_subscriber  is  None 
228+                     and  self .subscription_listing_id  is  not None 
229+                 ):
230+                     if  self ._available_for_purchase  is  True :
231+                         return  RoleType .PREMIUM_SUBSCRIPTION_TIER 
232+                     return  RoleType .DRAFT_PREMIUM_SUBSCRIPTION_TIER 
233+ 
234+         # integration role (Twitch/YouTube) 
235+         if  self .integration_id  is  not None :
236+             return  RoleType .INTEGRATION 
237+ 
238+         raise  ValueError ("Unable to determine the role type based on provided tags." )
239+ 
240+     @deprecated ("RoleTags.type" , "2.7" ) 
241+     def  is_bot_managed (self ) ->  bool :
242+         """Whether the role is associated with a bot.""" 
169243        return  self .bot_id  is  not None 
170244
171-     @property  
172-     def  is_booster_role (self ) ->  bool :
173-         """Whether the role is the "boost", role for the guild. 
174-         .. versionadded:: 2.7 
175-         """ 
176-         return  self ._guild_connections  is  False  and  self ._premium_subscriber  is  True 
177- 
178-     @property  
179-     def  is_guild_product_role (self ) ->  bool :
180-         """Whether the role is a guild product role. 
245+     @deprecated ("RoleTags.type" , "2.7" ) 
246+     def  is_premium_subscriber (self ) ->  bool :
247+         """Whether the role is the premium subscriber, AKA "boost", role for the guild.""" 
248+         return  self ._premium_subscriber  is  None 
181249
182-         .. versionadded:: 2.7 
183-         """ 
184-         return  self ._guild_connections  is  False  and  self ._premium_subscriber  is  False 
185- 
186-     @property  
250+     @deprecated ("RoleTags.type" , "2.7" ) 
187251    def  is_integration (self ) ->  bool :
188252        """Whether the guild manages the role through some form of 
189253        integrations such as Twitch or through guild subscriptions. 
190254        """ 
191255        return  self .integration_id  is  not None 
192256
193-     @property  
194-     def  is_base_subscription_role (self ) ->  bool :
195-         """Whether the role is a base subscription role. 
196- 
197-         .. versionadded:: 2.7 
198-         """ 
199-         return  (
200-             self ._guild_connections  is  False 
201-             and  self ._premium_subscriber  is  False 
202-             and  self .integration_id  is  not None 
203-         )
204- 
205-     @property  
206-     def  is_subscription_role (self ) ->  bool :
207-         """Whether the role is a subscription role. 
208- 
209-         .. versionadded:: 2.7 
210-         """ 
211-         return  (
212-             self ._guild_connections  is  False 
213-             and  self ._premium_subscriber  is  None 
214-             and  self .integration_id  is  not None 
215-             and  self .subscription_listing_id  is  not None 
216-             and  self ._available_for_purchase  is  True 
217-         )
218- 
219-     @property  
220-     def  is_draft_subscription_role (self ) ->  bool :
221-         """Whether the role is a draft subscription role. 
222- 
223-         .. versionadded:: 2.7 
224-         """ 
225-         return  (
226-             self ._guild_connections  is  False 
227-             and  self ._premium_subscriber  is  None 
228-             and  self .subscription_listing_id  is  not None 
229-             and  self .integration_id  is  not None 
230-             and  self ._available_for_purchase  is  False 
231-         )
257+     @deprecated ("RoleTags.type" , "2.7" ) 
258+     def  is_available_for_purchase (self ) ->  bool :
259+         """Whether the role is available for purchase.""" 
260+         return  self ._available_for_purchase  is  True 
232261
233-     @property  
262+     @deprecated ( "RoleTags.type" ,  "2.7" )  
234263    def  is_guild_connections_role (self ) ->  bool :
235-         """Whether the role is a guild connections role. 
236- 
237-         .. versionadded:: 2.7 
238-         """ 
264+         """Whether the role is a guild connections role.""" 
239265        return  self ._guild_connections  is  True 
240266
241-     QUALIFIERS : Final  =  (
242-         "is_bot_role" ,
243-         "is_booster_role" ,
244-         "is_guild_product_role" ,
245-         "is_integration" ,
246-         "is_base_subscription_role" ,
247-         "is_subscription_role" ,
248-         "is_draft_subscription_role" ,
249-         "is_guild_connections_role" ,
250-     )
251- 
252267    def  __repr__ (self ) ->  str :
253268        return  (
254269            f"<RoleTags bot_id={ self .bot_id } { self .integration_id }  
255270            +  f"subscription_listing_id={ self .subscription_listing_id }  
256-             +  " " .join (
257-                 q .removeprefix ("is_" ) for  q  in  self .QUALIFIERS  if  getattr (self , q )
258-             )
259-             +  ">" 
271+             +  f"type={ self .type !r}  
260272        )
261273
262274
@@ -431,6 +443,31 @@ def is_default(self) -> bool:
431443        """Checks if the role is the default role.""" 
432444        return  self .guild .id  ==  self .id 
433445
446+     @deprecated ("Role.type" , "2.7" ) 
447+     def  is_bot_managed (self ) ->  bool :
448+         """Whether the role is associated with a bot. 
449+ 
450+         .. versionadded:: 1.6 
451+         """ 
452+         return  self .tags  is  not None  and  self .tags .is_bot_managed ()
453+ 
454+     @deprecated ("Role.type" , "2.7" ) 
455+     def  is_premium_subscriber (self ) ->  bool :
456+         """Whether the role is the premium subscriber, AKA "boost", role for the guild. 
457+ 
458+         .. versionadded:: 1.6 
459+         """ 
460+         return  self .tags  is  not None  and  self .tags .is_premium_subscriber ()
461+ 
462+     @deprecated ("Role.type" , "2.7" ) 
463+     def  is_integration (self ) ->  bool :
464+         """Whether the guild manages the role through some form of 
465+         integrations such as Twitch or through guild subscriptions. 
466+ 
467+         .. versionadded:: 1.6 
468+         """ 
469+         return  self .tags  is  not None  and  self .tags .is_integration ()
470+ 
434471    def  is_assignable (self ) ->  bool :
435472        """Whether the role is able to be assigned or removed by the bot. 
436473
@@ -443,6 +480,26 @@ def is_assignable(self) -> bool:
443480            and  (me .top_role  >  self  or  me .id  ==  self .guild .owner_id )
444481        )
445482
483+     @deprecated ("Role.type" , "2.7" ) 
484+     def  is_available_for_purchase (self ) ->  bool :
485+         """Whether the role is available for purchase. 
486+ 
487+         Returns ``True`` if the role is available for purchase, and 
488+         ``False`` if it is not available for purchase or if the 
489+         role is not linked to a guild subscription. 
490+ 
491+         .. versionadded:: 2.7 
492+         """ 
493+         return  self .tags  is  not None  and  self .tags .is_available_for_purchase ()
494+ 
495+     @deprecated ("Role.type" , "2.7" ) 
496+     def  is_guild_connections_role (self ) ->  bool :
497+         """Whether the role is a guild connections role. 
498+ 
499+         .. versionadded:: 2.7 
500+         """ 
501+         return  self .tags  is  not None  and  self .tags .is_guild_connections_role ()
502+ 
446503    @property  
447504    def  permissions (self ) ->  Permissions :
448505        """Returns the role's permissions.""" 
@@ -489,6 +546,14 @@ def icon(self) -> Asset | None:
489546
490547        return  Asset ._from_icon (self ._state , self .id , self ._icon , "role" )
491548
549+     @property  
550+     def  type (self ) ->  RoleType :
551+         """The type of the role. 
552+ 
553+         .. versionadded:: 2.7 
554+         """ 
555+         return  self .tags .type 
556+ 
492557    async  def  _move (self , position : int , reason : str  |  None ) ->  None :
493558        if  position  <=  0 :
494559            raise  InvalidArgument ("Cannot move role to position 0 or below" )
0 commit comments