@@ -117,25 +117,6 @@ def all_flags_value(flags: Dict[str, int]) -> int:
117
117
return functools .reduce (operator .or_ , flags .values ())
118
118
119
119
120
- def fill_with_flags (* , inverted : bool = False ):
121
- def decorator (cls : Type [BF ]) -> Type [BF ]:
122
- cls .VALID_FLAGS = {}
123
- for name , value in cls .__dict__ .items ():
124
- if isinstance (value , flag_value ):
125
- value ._parent = cls
126
- cls .VALID_FLAGS [name ] = value .flag
127
-
128
- if inverted :
129
- cls .DEFAULT_VALUE = all_flags_value (cls .VALID_FLAGS )
130
- else :
131
- cls .DEFAULT_VALUE = 0
132
-
133
- return cls
134
-
135
- return decorator
136
-
137
-
138
- # n.b. flags must inherit from this and use the decorator above
139
120
class BaseFlags :
140
121
VALID_FLAGS : ClassVar [Dict [str , int ]]
141
122
DEFAULT_VALUE : ClassVar [int ]
@@ -151,6 +132,29 @@ def __init__(self, **kwargs: bool):
151
132
raise TypeError (f"{ key !r} is not a valid flag name." )
152
133
setattr (self , key , value )
153
134
135
+ @classmethod
136
+ def __init_subclass__ (cls , inverted : bool = False , no_fill_flags : bool = False ):
137
+ # add a way to bypass filling flags, eg for ListBaseFlags.
138
+ if no_fill_flags :
139
+ return cls
140
+
141
+ # use the parent's current flags as a base if they exist
142
+ cls .VALID_FLAGS = getattr (cls , "VALID_FLAGS" , {}).copy ()
143
+
144
+ for name , value in cls .__dict__ .items ():
145
+ if isinstance (value , flag_value ):
146
+ value ._parent = cls
147
+ cls .VALID_FLAGS [name ] = value .flag
148
+
149
+ if not cls .VALID_FLAGS :
150
+ raise RuntimeError (
151
+ "At least one flag must be defined in a BaseFlags subclass, or 'no_fill_flags' must be set to True"
152
+ )
153
+
154
+ cls .DEFAULT_VALUE = all_flags_value (cls .VALID_FLAGS ) if inverted else 0
155
+
156
+ return cls
157
+
154
158
@classmethod
155
159
def _from_value (cls , value : int ) -> Self :
156
160
self = cls .__new__ (cls )
@@ -295,7 +299,7 @@ def _set_flag(self, o: int, toggle: bool) -> None:
295
299
raise TypeError (f"Value to set for { self .__class__ .__name__ } must be a bool." )
296
300
297
301
298
- class ListBaseFlags (BaseFlags ):
302
+ class ListBaseFlags (BaseFlags , no_fill_flags = True ):
299
303
"""
300
304
A base class for flags that aren't powers of 2.
301
305
Instead, values are used as exponents to map to powers of 2 to avoid collisions,
@@ -330,8 +334,7 @@ def __repr__(self) -> str:
330
334
return f"<{ self .__class__ .__name__ } values={ self .values } >"
331
335
332
336
333
- @fill_with_flags (inverted = True )
334
- class SystemChannelFlags (BaseFlags ):
337
+ class SystemChannelFlags (BaseFlags , inverted = True ):
335
338
"""
336
339
Wraps up a Discord system channel flag value.
337
340
@@ -466,7 +469,6 @@ def join_notification_replies(self):
466
469
return 8
467
470
468
471
469
- @fill_with_flags ()
470
472
class MessageFlags (BaseFlags ):
471
473
"""
472
474
Wraps up a Discord Message flag value.
@@ -621,7 +623,6 @@ def failed_to_mention_roles_in_thread(self):
621
623
return 1 << 8
622
624
623
625
624
- @fill_with_flags ()
625
626
class PublicUserFlags (BaseFlags ):
626
627
"""
627
628
Wraps up the Discord User Public flags.
@@ -814,7 +815,6 @@ def all(self) -> List[UserFlags]:
814
815
return [public_flag for public_flag in UserFlags if self ._has_flag (public_flag .value )]
815
816
816
817
817
- @fill_with_flags ()
818
818
class Intents (BaseFlags ):
819
819
"""
820
820
Wraps up a Discord gateway intent flag.
@@ -1449,7 +1449,6 @@ def automod(self):
1449
1449
return (1 << 20 ) | (1 << 21 )
1450
1450
1451
1451
1452
- @fill_with_flags ()
1453
1452
class MemberCacheFlags (BaseFlags ):
1454
1453
"""Controls the library's cache policy when it comes to members.
1455
1454
@@ -1632,7 +1631,6 @@ def _voice_only(self):
1632
1631
return self .value == 1
1633
1632
1634
1633
1635
- @fill_with_flags ()
1636
1634
class ApplicationFlags (BaseFlags ):
1637
1635
"""
1638
1636
Wraps up the Discord Application flags.
@@ -1777,7 +1775,6 @@ def gateway_message_content_limited(self):
1777
1775
return 1 << 19
1778
1776
1779
1777
1780
- @fill_with_flags ()
1781
1778
class ChannelFlags (BaseFlags ):
1782
1779
"""Wraps up the Discord Channel flags.
1783
1780
@@ -1872,7 +1869,6 @@ def pinned(self):
1872
1869
return 1 << 1
1873
1870
1874
1871
1875
- @fill_with_flags ()
1876
1872
class AutoModKeywordPresets (ListBaseFlags ):
1877
1873
"""
1878
1874
Wraps up the pre-defined auto moderation keyword lists, provided by Discord.
0 commit comments