disagreement 0.1.0rc3__tar.gz → 0.3.0b1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. {disagreement-0.1.0rc3/disagreement.egg-info → disagreement-0.3.0b1}/PKG-INFO +18 -1
  2. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/README.md +16 -0
  3. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/__init__.py +2 -2
  4. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/audio.py +17 -0
  5. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/cache.py +31 -1
  6. disagreement-0.3.0b1/disagreement/caching.py +120 -0
  7. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/client.py +1658 -1349
  8. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/color.py +100 -1
  9. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/enums.py +63 -0
  10. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/event_dispatcher.py +2 -2
  11. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/app_commands/commands.py +0 -2
  12. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/app_commands/handler.py +101 -30
  13. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/commands/__init__.py +65 -57
  14. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/commands/core.py +690 -513
  15. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/commands/decorators.py +298 -192
  16. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/commands/errors.py +8 -0
  17. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/gateway.py +630 -575
  18. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/http.py +1120 -875
  19. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/models.py +2588 -2064
  20. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ui/view.py +167 -165
  21. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/voice_client.py +244 -162
  22. {disagreement-0.1.0rc3 → disagreement-0.3.0b1/disagreement.egg-info}/PKG-INFO +18 -1
  23. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement.egg-info/SOURCES.txt +8 -0
  24. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement.egg-info/requires.txt +1 -0
  25. disagreement-0.3.0b1/docs/audit_logs.md +15 -0
  26. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/caching.md +1 -0
  27. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/events.md +33 -0
  28. disagreement-0.3.0b1/docs/http_client.md +20 -0
  29. disagreement-0.3.0b1/docs/invites.md +24 -0
  30. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/message_history.md +2 -0
  31. disagreement-0.3.0b1/docs/scheduled_events.md +26 -0
  32. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/slash_commands.md +12 -0
  33. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/using_components.md +1 -0
  34. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/voice_client.md +11 -0
  35. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/voice_features.md +1 -0
  36. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/pyproject.toml +57 -56
  37. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_additional_converters.py +26 -18
  38. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_channel_permissions.py +8 -8
  39. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_color.py +3 -0
  40. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_command_checks.py +1 -0
  41. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_event_dispatcher.py +10 -1
  42. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_http_reactions.py +1 -3
  43. disagreement-0.3.0b1/tests/test_max_concurrency.py +103 -0
  44. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_sharding.py +49 -1
  45. disagreement-0.3.0b1/tests/test_stage_instance.py +63 -0
  46. disagreement-0.3.0b1/tests/test_templates.py +42 -0
  47. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_textchannel_purge.py +2 -4
  48. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_voice_client.py +36 -3
  49. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_webhooks.py +6 -13
  50. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/LICENSE +0 -0
  51. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/MANIFEST.in +0 -0
  52. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/components.py +0 -0
  53. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/error_handler.py +0 -0
  54. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/errors.py +0 -0
  55. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/__init__.py +0 -0
  56. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/app_commands/__init__.py +0 -0
  57. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/app_commands/context.py +0 -0
  58. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/app_commands/converters.py +0 -0
  59. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/app_commands/decorators.py +0 -0
  60. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/app_commands/hybrid.py +0 -0
  61. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/commands/cog.py +0 -0
  62. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/commands/converters.py +0 -0
  63. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/commands/help.py +0 -0
  64. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/commands/view.py +0 -0
  65. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/loader.py +0 -0
  66. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ext/tasks.py +0 -0
  67. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/hybrid_context.py +0 -0
  68. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/i18n.py +0 -0
  69. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/interactions.py +0 -0
  70. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/logging_config.py +0 -0
  71. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/oauth.py +0 -0
  72. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/permissions.py +0 -0
  73. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/py.typed +0 -0
  74. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/rate_limiter.py +0 -0
  75. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/shard_manager.py +0 -0
  76. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/typing.py +0 -0
  77. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ui/__init__.py +0 -0
  78. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ui/button.py +0 -0
  79. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ui/item.py +0 -0
  80. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ui/modal.py +0 -0
  81. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/ui/select.py +0 -0
  82. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement/utils.py +0 -0
  83. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement.egg-info/dependency_links.txt +0 -0
  84. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/disagreement.egg-info/top_level.txt +0 -0
  85. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/commands.md +0 -0
  86. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/context_menus.md +0 -0
  87. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/converters.md +0 -0
  88. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/extension_loader.md +0 -0
  89. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/gateway.md +0 -0
  90. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/i18n.md +0 -0
  91. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/oauth2.md +0 -0
  92. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/permissions.md +0 -0
  93. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/presence.md +0 -0
  94. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/reactions.md +0 -0
  95. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/sharding.md +0 -0
  96. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/task_loop.md +0 -0
  97. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/typing_indicator.md +0 -0
  98. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/docs/webhooks.md +0 -0
  99. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/basic_bot.py +0 -0
  100. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/component_bot.py +0 -0
  101. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/context_menus.py +0 -0
  102. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/extension_management.py +0 -0
  103. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/hybrid_bot.py +0 -0
  104. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/message_history.py +0 -0
  105. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/modal_command.py +0 -0
  106. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/modal_send.py +0 -0
  107. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/sample_extension.py +0 -0
  108. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/sharded_bot.py +0 -0
  109. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/task_loop.py +0 -0
  110. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/examples/voice_bot.py +0 -0
  111. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/setup.cfg +0 -0
  112. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_cache.py +0 -0
  113. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_client_context_manager.py +0 -0
  114. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_color_acceptance.py +0 -0
  115. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_components_factory.py +0 -0
  116. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_context.py +0 -0
  117. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_context_menus.py +0 -0
  118. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_converter_registration.py +0 -0
  119. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_converters.py +0 -0
  120. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_error_handler.py +0 -0
  121. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_errors.py +0 -0
  122. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_event_error_hook.py +0 -0
  123. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_extension_loader.py +0 -0
  124. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_gateway_backoff.py +0 -0
  125. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_gateway_intent.py +0 -0
  126. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_help_command.py +0 -0
  127. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_http_rate_limit.py +0 -0
  128. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_hybrid_context.py +0 -0
  129. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_i18n.py +0 -0
  130. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_interaction.py +0 -0
  131. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_logging_config.py +0 -0
  132. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_member.py +0 -0
  133. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_message_pager.py +0 -0
  134. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_modal_send.py +0 -0
  135. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_modals.py +0 -0
  136. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_oauth.py +0 -0
  137. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_permissions.py +0 -0
  138. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_presence_and_typing.py +0 -0
  139. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_presence_update.py +0 -0
  140. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_rate_limiter.py +0 -0
  141. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_reactions.py +0 -0
  142. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_send_files.py +0 -0
  143. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_slash_contexts.py +0 -0
  144. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_tasks_extension.py +0 -0
  145. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_textchannel_history.py +0 -0
  146. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_typing_indicator.py +0 -0
  147. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_ui.py +0 -0
  148. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_utils.py +0 -0
  149. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_view_layout.py +0 -0
  150. {disagreement-0.1.0rc3 → disagreement-0.3.0b1}/tests/test_wait_for.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: disagreement
3
- Version: 0.1.0rc3
3
+ Version: 0.3.0b1
4
4
  Summary: A Python library for the Discord API.
5
5
  Author-email: Slipstream <me@slipstreamm.dev>
6
6
  License: BSD 3-Clause
@@ -23,6 +23,7 @@ Requires-Python: >=3.10
23
23
  Description-Content-Type: text/markdown
24
24
  License-File: LICENSE
25
25
  Requires-Dist: aiohttp<4.0.0,>=3.9.0
26
+ Requires-Dist: PyNaCl<2.0.0,>=1.5.0
26
27
  Provides-Extra: test
27
28
  Requires-Dist: pytest>=8.0.0; extra == "test"
28
29
  Requires-Dist: pytest-asyncio>=1.0.0; extra == "test"
@@ -119,6 +120,22 @@ setup_logging(logging.INFO)
119
120
  setup_logging(logging.DEBUG, file="bot.log")
120
121
  ```
121
122
 
123
+ ### HTTP Session Options
124
+
125
+ Pass additional keyword arguments to ``aiohttp.ClientSession`` using the
126
+ ``http_options`` parameter when constructing :class:`disagreement.Client`:
127
+
128
+ ```python
129
+ client = disagreement.Client(
130
+ token=token,
131
+ http_options={"proxy": "http://localhost:8080"},
132
+ )
133
+ ```
134
+
135
+ These options are forwarded to ``HTTPClient`` when it creates the underlying
136
+ ``aiohttp.ClientSession``. You can specify a custom ``connector`` or any other
137
+ session parameter supported by ``aiohttp``.
138
+
122
139
  ### Defining Subcommands with `AppCommandGroup`
123
140
 
124
141
  ```python
@@ -86,6 +86,22 @@ setup_logging(logging.INFO)
86
86
  setup_logging(logging.DEBUG, file="bot.log")
87
87
  ```
88
88
 
89
+ ### HTTP Session Options
90
+
91
+ Pass additional keyword arguments to ``aiohttp.ClientSession`` using the
92
+ ``http_options`` parameter when constructing :class:`disagreement.Client`:
93
+
94
+ ```python
95
+ client = disagreement.Client(
96
+ token=token,
97
+ http_options={"proxy": "http://localhost:8080"},
98
+ )
99
+ ```
100
+
101
+ These options are forwarded to ``HTTPClient`` when it creates the underlying
102
+ ``aiohttp.ClientSession``. You can specify a custom ``connector`` or any other
103
+ session parameter supported by ``aiohttp``.
104
+
89
105
  ### Defining Subcommands with `AppCommandGroup`
90
106
 
91
107
  ```python
@@ -14,10 +14,10 @@ __title__ = "disagreement"
14
14
  __author__ = "Slipstream"
15
15
  __license__ = "BSD 3-Clause License"
16
16
  __copyright__ = "Copyright 2025 Slipstream"
17
- __version__ = "0.1.0rc3"
17
+ __version__ = "0.3.0b1"
18
18
 
19
19
  from .client import Client, AutoShardedClient
20
- from .models import Message, User, Reaction
20
+ from .models import Message, User, Reaction, AuditLogEntry
21
21
  from .voice_client import VoiceClient
22
22
  from .audio import AudioSource, FFmpegAudioSource
23
23
  from .typing import Typing
@@ -114,3 +114,20 @@ class FFmpegAudioSource(AudioSource):
114
114
  if isinstance(self.source, io.IOBase):
115
115
  with contextlib.suppress(Exception):
116
116
  self.source.close()
117
+
118
+ class AudioSink:
119
+ """Abstract base class for audio sinks."""
120
+
121
+ def write(self, user, data):
122
+ """Write a chunk of PCM audio.
123
+
124
+ Subclasses must implement this. The data is raw PCM at 48kHz
125
+ stereo.
126
+ """
127
+
128
+ raise NotImplementedError
129
+
130
+ def close(self) -> None:
131
+ """Cleanup the sink when the voice client disconnects."""
132
+
133
+ return None
@@ -4,7 +4,8 @@ import time
4
4
  from typing import TYPE_CHECKING, Dict, Generic, Optional, TypeVar
5
5
 
6
6
  if TYPE_CHECKING:
7
- from .models import Channel, Guild
7
+ from .models import Channel, Guild, Member
8
+ from .caching import MemberCacheFlags
8
9
 
9
10
  T = TypeVar("T")
10
11
 
@@ -53,3 +54,32 @@ class GuildCache(Cache["Guild"]):
53
54
 
54
55
  class ChannelCache(Cache["Channel"]):
55
56
  """Cache specifically for :class:`Channel` objects."""
57
+
58
+
59
+ class MemberCache(Cache["Member"]):
60
+ """
61
+ A cache for :class:`Member` objects that respects :class:`MemberCacheFlags`.
62
+ """
63
+
64
+ def __init__(self, flags: MemberCacheFlags, ttl: Optional[float] = None) -> None:
65
+ super().__init__(ttl)
66
+ self.flags = flags
67
+
68
+ def _should_cache(self, member: Member) -> bool:
69
+ """Determines if a member should be cached based on the flags."""
70
+ if self.flags.all:
71
+ return True
72
+ if self.flags.none:
73
+ return False
74
+
75
+ if self.flags.online and member.status != "offline":
76
+ return True
77
+ if self.flags.voice and member.voice_state is not None:
78
+ return True
79
+ if self.flags.joined and getattr(member, "_just_joined", False):
80
+ return True
81
+ return False
82
+
83
+ def set(self, key: str, value: Member) -> None:
84
+ if self._should_cache(value):
85
+ super().set(key, value)
@@ -0,0 +1,120 @@
1
+ from __future__ import annotations
2
+
3
+ import operator
4
+ from typing import Any, Callable, ClassVar, Dict, Iterator, Tuple
5
+
6
+
7
+ class _MemberCacheFlagValue:
8
+ flag: int
9
+
10
+ def __init__(self, func: Callable[[Any], bool]):
11
+ self.flag = getattr(func, 'flag', 0)
12
+ self.__doc__ = func.__doc__
13
+
14
+ def __get__(self, instance: 'MemberCacheFlags', owner: type) -> Any:
15
+ if instance is None:
16
+ return self
17
+ return instance.value & self.flag != 0
18
+
19
+ def __set__(self, instance: Any, value: bool) -> None:
20
+ if value:
21
+ instance.value |= self.flag
22
+ else:
23
+ instance.value &= ~self.flag
24
+
25
+ def __repr__(self) -> str:
26
+ return f'<{self.__class__.__name__} flag={self.flag}>'
27
+
28
+
29
+ def flag_value(flag: int) -> Callable[[Callable[[Any], bool]], _MemberCacheFlagValue]:
30
+ def decorator(func: Callable[[Any], bool]) -> _MemberCacheFlagValue:
31
+ setattr(func, 'flag', flag)
32
+ return _MemberCacheFlagValue(func)
33
+ return decorator
34
+
35
+
36
+ class MemberCacheFlags:
37
+ __slots__ = ('value',)
38
+
39
+ VALID_FLAGS: ClassVar[Dict[str, int]] = {
40
+ 'joined': 1 << 0,
41
+ 'voice': 1 << 1,
42
+ 'online': 1 << 2,
43
+ }
44
+ DEFAULT_FLAGS: ClassVar[int] = 1 | 2 | 4
45
+ ALL_FLAGS: ClassVar[int] = sum(VALID_FLAGS.values())
46
+
47
+ def __init__(self, **kwargs: bool):
48
+ self.value = self.DEFAULT_FLAGS
49
+ for key, value in kwargs.items():
50
+ if key not in self.VALID_FLAGS:
51
+ raise TypeError(f'{key!r} is not a valid member cache flag.')
52
+ setattr(self, key, value)
53
+
54
+ @classmethod
55
+ def _from_value(cls, value: int) -> MemberCacheFlags:
56
+ self = cls.__new__(cls)
57
+ self.value = value
58
+ return self
59
+
60
+ def __eq__(self, other: object) -> bool:
61
+ return isinstance(other, MemberCacheFlags) and self.value == other.value
62
+
63
+ def __ne__(self, other: object) -> bool:
64
+ return not self.__eq__(other)
65
+
66
+ def __hash__(self) -> int:
67
+ return hash(self.value)
68
+
69
+ def __repr__(self) -> str:
70
+ return f'<MemberCacheFlags value={self.value}>'
71
+
72
+ def __iter__(self) -> Iterator[Tuple[str, bool]]:
73
+ for name in self.VALID_FLAGS:
74
+ yield name, getattr(self, name)
75
+
76
+ def __int__(self) -> int:
77
+ return self.value
78
+
79
+ def __index__(self) -> int:
80
+ return self.value
81
+
82
+ @classmethod
83
+ def all(cls) -> MemberCacheFlags:
84
+ """A factory method that creates a :class:`MemberCacheFlags` with all flags enabled."""
85
+ return cls._from_value(cls.ALL_FLAGS)
86
+
87
+ @classmethod
88
+ def none(cls) -> MemberCacheFlags:
89
+ """A factory method that creates a :class:`MemberCacheFlags` with all flags disabled."""
90
+ return cls._from_value(0)
91
+
92
+ @classmethod
93
+ def only_joined(cls) -> MemberCacheFlags:
94
+ """A factory method that creates a :class:`MemberCacheFlags` with only the `joined` flag enabled."""
95
+ return cls._from_value(cls.VALID_FLAGS['joined'])
96
+
97
+ @classmethod
98
+ def only_voice(cls) -> MemberCacheFlags:
99
+ """A factory method that creates a :class:`MemberCacheFlags` with only the `voice` flag enabled."""
100
+ return cls._from_value(cls.VALID_FLAGS['voice'])
101
+
102
+ @classmethod
103
+ def only_online(cls) -> MemberCacheFlags:
104
+ """A factory method that creates a :class:`MemberCacheFlags` with only the `online` flag enabled."""
105
+ return cls._from_value(cls.VALID_FLAGS['online'])
106
+
107
+ @flag_value(1 << 0)
108
+ def joined(self) -> bool:
109
+ """Whether to cache members that have just joined the guild."""
110
+ return False
111
+
112
+ @flag_value(1 << 1)
113
+ def voice(self) -> bool:
114
+ """Whether to cache members that are in a voice channel."""
115
+ return False
116
+
117
+ @flag_value(1 << 2)
118
+ def online(self) -> bool:
119
+ """Whether to cache members that are online."""
120
+ return False