Skip to content

Commit cab332a

Browse files
authored
Merge branch 'master' into unittest
2 parents 9708797 + b6acee0 commit cab332a

24 files changed

+428
-63
lines changed

.pre-commit-config.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ repos:
1818
# - --remove-duplicate-keys
1919
# - --remove-unused-variables
2020
- repo: https://github.com/asottile/pyupgrade
21-
rev: v3.2.2
21+
rev: v3.3.1
2222
hooks:
2323
- id: pyupgrade
2424
args: [--py38-plus]
2525
- repo: https://github.com/PyCQA/isort
26-
rev: 5.10.1
26+
rev: 5.11.4
2727
hooks:
2828
- id: isort
2929
- repo: https://github.com/psf/black
30-
rev: 22.10.0
30+
rev: 22.12.0
3131
hooks:
3232
- id: black
3333
# See https://github.com/psf/black/issues/2188#issuecomment-1289317647 for why we can't use the --preview flag.
@@ -82,7 +82,7 @@ repos:
8282
- id: prettier
8383
args: [--prose-wrap=always, --print-width=88]
8484
- repo: https://github.com/DanielNoord/pydocstringformatter
85-
rev: 93b15ca # TODO: Change this when v8.0 is released
85+
rev: v0.7.3
8686
hooks:
8787
- id: pydocstringformatter
8888
args:

CHANGELOG.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,35 @@ possible (see our [Version Guarantees] for more info).
1010

1111
These changes are available on the `master` branch, but have not yet been released.
1212

13-
_No changes yet_
13+
### Added
14+
15+
- Added new AutoMod trigger metadata properties `regex_patterns`, `allow_list`, and
16+
`mention_total_limit`; and added the `mention_spam` trigger type.
17+
([#1809](https://github.com/Pycord-Development/pycord/pull/1809))
18+
- Added missing `image` parameter to `Guild.create_scheduled_event()` method.
19+
([#1831](https://github.com/Pycord-Development/pycord/pull/1831))
20+
- Added new message types, `interaction_premium_upsell`, `stage_start`, `stage_end`,
21+
`stage_speaker`, `stage_raise_hand`, `stage_topic`, and
22+
`guild_application_premium_subscription`.
23+
([#1852](https://github.com/Pycord-Development/pycord/pull/1852))
24+
25+
## [2.3.2] - 2022-12-03
26+
27+
### Fixed
28+
29+
- Fixed bridge groups missing the `parent` attribute.
30+
([#1823](https://github.com/Pycord-Development/pycord/pull/1823))
31+
32+
## [2.3.2] - 2022-12-03
33+
34+
### Fixed
35+
36+
- Fixed another `AttributeError` relating to the new `bridge_commands` attribute on
37+
`ext.bridge.Bot`. ([#1815](https://github.com/Pycord-Development/pycord/pull/1815))
38+
- Fixed an `AttributeError` in select relating to the select type.
39+
([#1814](https://github.com/Pycord-Development/pycord/pull/1814))
40+
- Fixed `Thread.applied_tags` always returning an empty list.
41+
([#1817](https://github.com/Pycord-Development/pycord/pull/1817))
1442

1543
## [2.3.1] - 2022-11-27
1644

@@ -454,7 +482,8 @@ _No changes yet_
454482
- Fix py3.10 UnionType checks issue.
455483
([#1240](https://github.com/Pycord-Development/pycord/pull/1240))
456484

457-
[unreleased]: https://github.com/Pycord-Development/pycord/compare/v2.3.1...HEAD
485+
[unreleased]: https://github.com/Pycord-Development/pycord/compare/v2.3.2...HEAD
486+
[2.3.2]: https://github.com/Pycord-Development/pycord/compare/v2.3.1...v2.3.2
458487
[2.3.1]: https://github.com/Pycord-Development/pycord/compare/v2.3.0...v2.3.1
459488
[2.3.0]: https://github.com/Pycord-Development/pycord/compare/v2.2.2...v2.3.0
460489
[2.2.2]: https://github.com/Pycord-Development/pycord/compare/v2.2.1...v2.2.2

discord/automod.py

Lines changed: 79 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@
3939
from .mixins import Hashable
4040
from .object import Object
4141

42-
__all__ = ("AutoModRule",)
42+
__all__ = (
43+
"AutoModRule",
44+
"AutoModAction",
45+
"AutoModActionMetadata",
46+
"AutoModTriggerMetadata",
47+
)
4348

4449
if TYPE_CHECKING:
4550
from .abc import Snowflake
@@ -152,7 +157,7 @@ def __init__(self, action_type: AutoModActionType, metadata: AutoModActionMetada
152157
def to_dict(self) -> dict:
153158
return {
154159
"type": self.type.value,
155-
"metadata": self.metadata,
160+
"metadata": self.metadata.to_dict(),
156161
}
157162

158163
@classmethod
@@ -167,45 +172,95 @@ def __repr__(self) -> str:
167172

168173

169174
class AutoModTriggerMetadata:
170-
"""Represents a rule's trigger metadata.
171-
172-
Depending on the trigger type, different attributes will be used.
175+
r"""Represents a rule's trigger metadata, defining additional data used to determine when a rule triggers.
176+
177+
Depending on the trigger type, different metadata attributes will be used:
178+
179+
+-----------------------------+--------------------------------------------------------------------------------+
180+
| Attribute | Trigger Types |
181+
+=============================+================================================================================+
182+
| :attr:`keyword_filter` | :attr:`AutoModTriggerType.keyword` |
183+
+-----------------------------+--------------------------------------------------------------------------------+
184+
| :attr:`regex_patterns` | :attr:`AutoModTriggerType.keyword` |
185+
+-----------------------------+--------------------------------------------------------------------------------+
186+
| :attr:`presets` | :attr:`AutoModTriggerType.keyword_preset` |
187+
+-----------------------------+--------------------------------------------------------------------------------+
188+
| :attr:`allow_list` | :attr:`AutoModTriggerType.keyword`\, :attr:`AutoModTriggerType.keyword_preset` |
189+
+-----------------------------+--------------------------------------------------------------------------------+
190+
| :attr:`mention_total_limit` | :attr:`AutoModTriggerType.mention_spam` |
191+
+-----------------------------+--------------------------------------------------------------------------------+
192+
193+
Each attribute has limits that may change based on the trigger type.
194+
See `here <https://discord.com/developers/docs/resources/auto-moderation#auto-moderation-rule-object-trigger-metadata-field-limits>`_
195+
for information on attribute limits.
173196
174197
.. versionadded:: 2.0
175198
176199
Attributes
177200
----------
178201
keyword_filter: List[:class:`str`]
179-
A list of substrings to filter. Only for triggers of type :attr:`AutoModTriggerType.keyword`.
202+
A list of substrings to filter.
203+
204+
regex_patterns: List[:class:`str`]
205+
A list of regex patterns to filter using Rust-flavored regex, which is not
206+
fully compatible with regex syntax supported by the builtin `re` module.
207+
208+
.. versionadded:: 2.4
209+
180210
presets: List[:class:`AutoModKeywordPresetType`]
181-
A list of keyword presets to filter. Only for triggers of type :attr:`AutoModTriggerType.keyword_preset`.
182-
"""
211+
A list of preset keyword sets to filter.
183212
184-
# maybe add a table of action types and attributes?
185-
# wording for presets could change
213+
allow_list: List[:class:`str`]
214+
A list of substrings to allow, overriding keyword and regex matches.
215+
216+
.. versionadded:: 2.4
217+
218+
mention_total_limit: :class:`int`
219+
The total number of unique role and user mentions allowed.
220+
221+
.. versionadded:: 2.4
222+
"""
186223

187224
__slots__ = (
188225
"keyword_filter",
226+
"regex_patterns",
189227
"presets",
228+
"allow_list",
229+
"mention_total_limit",
190230
)
191231

192232
def __init__(
193233
self,
194234
keyword_filter: list[str] = MISSING,
235+
regex_patterns: list[str] = MISSING,
195236
presets: list[AutoModKeywordPresetType] = MISSING,
237+
allow_list: list[str] = MISSING,
238+
mention_total_limit: int = MISSING,
196239
):
197240
self.keyword_filter = keyword_filter
241+
self.regex_patterns = regex_patterns
198242
self.presets = presets
243+
self.allow_list = allow_list
244+
self.mention_total_limit = mention_total_limit
199245

200246
def to_dict(self) -> dict:
201247
data = {}
202248

203249
if self.keyword_filter is not MISSING:
204250
data["keyword_filter"] = self.keyword_filter
205251

252+
if self.regex_patterns is not MISSING:
253+
data["regex_patterns"] = self.regex_patterns
254+
206255
if self.presets is not MISSING:
207256
data["presets"] = [wordset.value for wordset in self.presets]
208257

258+
if self.allow_list is not MISSING:
259+
data["allow_list"] = self.allow_list
260+
261+
if self.mention_total_limit is not MISSING:
262+
data["mention_total_limit"] = self.mention_total_limit
263+
209264
return data
210265

211266
@classmethod
@@ -215,17 +270,29 @@ def from_dict(cls, data: AutoModTriggerMetadataPayload):
215270
if (keyword_filter := data.get("keyword_filter")) is not None:
216271
kwargs["keyword_filter"] = keyword_filter
217272

273+
if (regex_patterns := data.get("regex_patterns")) is not None:
274+
kwargs["regex_patterns"] = regex_patterns
275+
218276
if (presets := data.get("presets")) is not None:
219277
kwargs["presets"] = [
220278
try_enum(AutoModKeywordPresetType, wordset) for wordset in presets
221279
]
222280

281+
if (allow_list := data.get("allow_list")) is not None:
282+
kwargs["allow_list"] = allow_list
283+
284+
if (mention_total_limit := data.get("mention_total_limit")) is not None:
285+
kwargs["mention_total_limit"] = mention_total_limit
286+
223287
return cls(**kwargs)
224288

225289
def __repr__(self) -> str:
226290
repr_attrs = (
227291
"keyword_filter",
292+
"regex_patterns",
228293
"presets",
294+
"allow_list",
295+
"mention_total_limit",
229296
)
230297
inner = []
231298

@@ -424,9 +491,9 @@ async def edit(
424491
The new actions to perform when the rule is triggered.
425492
enabled: :class:`bool`
426493
Whether this rule is enabled.
427-
exempt_roles: List[:class:`Snowflake`]
494+
exempt_roles: List[:class:`abc.Snowflake`]
428495
The roles that will be exempt from this rule.
429-
exempt_channels: List[:class:`Snowflake`]
496+
exempt_channels: List[:class:`abc.Snowflake`]
430497
The channels that will be exempt from this rule.
431498
reason: Optional[:class:`str`]
432499
The reason for editing this rule. Shows up in the audit log.

discord/cog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ def _inject(self: CogT, bot) -> CogT:
542542

543543
for index, command in enumerate(self.__cog_commands__):
544544
if hasattr(command, "add_to"):
545-
bot._bridge_commands.append(command)
545+
bot.bridge_commands.append(command)
546546
continue
547547

548548
command._set_cog(self)

discord/enums.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,14 @@ class MessageType(Enum):
248248
guild_invite_reminder = 22
249249
context_menu_command = 23
250250
auto_moderation_action = 24
251+
role_subscription_purchase = 25
252+
interaction_premium_upsell = 26
253+
stage_start = 27
254+
stage_end = 28
255+
stage_speaker = 29
256+
stage_raise_hand = 30
257+
stage_topic = 31
258+
guild_application_premium_subscription = 32
251259

252260

253261
class VoiceRegion(Enum):
@@ -880,6 +888,7 @@ class AutoModTriggerType(Enum):
880888
harmful_link = 2
881889
spam = 3
882890
keyword_preset = 4
891+
mention_spam = 5
883892

884893

885894
class AutoModEventType(Enum):

discord/ext/bridge/bot.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ def bridge_commands(self) -> list[BridgeCommand | BridgeCommandGroup]:
4949

5050
return cmds
5151

52-
@bridge_commands.setter
53-
def bridge_commands(self, cmds):
54-
self._bridge_commands = cmds
55-
5652
async def get_application_context(
5753
self, interaction: Interaction, cls=None
5854
) -> BridgeApplicationContext:
@@ -74,10 +70,7 @@ def add_bridge_command(self, command: BridgeCommand):
7470
# Ignore the type hinting error here. All subclasses of BotBase pass the type checks.
7571
command.add_to(self) # type: ignore
7672

77-
if getattr(self, "_bridge_commands", None) is None:
78-
self._bridge_commands = []
79-
80-
self._bridge_commands.append(command)
73+
self.bridge_commands.append(command)
8174

8275
def bridge_command(self, **kwargs):
8376
"""A shortcut decorator that invokes :func:`bridge_command` and adds it to

discord/ext/bridge/core.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,12 +311,17 @@ class BridgeCommandGroup(BridgeCommand):
311311
If :func:`map_to` is used, the mapped slash command.
312312
"""
313313

314+
ext_variant: BridgeExtGroup
315+
slash_variant: BridgeSlashGroup
316+
314317
def __init__(self, callback, *args, **kwargs):
315-
self.ext_variant: BridgeExtGroup = BridgeExtGroup(callback, *args, **kwargs)
316-
name = kwargs.pop("name", self.ext_variant.name)
317-
self.slash_variant: BridgeSlashGroup = BridgeSlashGroup(
318-
callback, name, *args, **kwargs
318+
super().__init__(
319+
callback,
320+
ext_variant=(ext_var := BridgeExtGroup(callback, *args, **kwargs)),
321+
slash_variant=BridgeSlashGroup(callback, ext_var.name, *args, **kwargs),
322+
parent=kwargs.pop("parent", None),
319323
)
324+
320325
self.subcommands: list[BridgeCommand] = []
321326

322327
self.mapped: SlashCommand | None = None

discord/guild.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2156,13 +2156,14 @@ async def fetch_channel(self, channel_id: int, /) -> GuildChannel | Thread:
21562156
def bans(
21572157
self,
21582158
limit: int | None = None,
2159-
before: SnowflakeTime | None = None,
2160-
after: SnowflakeTime | None = None,
2159+
before: Snowflake | None = None,
2160+
after: Snowflake | None = None,
21612161
) -> BanIterator:
21622162
"""|coro|
21632163
21642164
Retrieves an :class:`.AsyncIterator` that enables receiving the guild's bans. In order to use this, you must
21652165
have the :attr:`~Permissions.ban_members` permission.
2166+
Users will always be returned in ascending order sorted by user ID. If both the ``before`` and ``after`` parameters are provided, only before is respected.
21662167
21672168
.. versionchanged:: 2.0
21682169
The ``limit``, ``before``. and ``after`` parameters were added. Now returns a :class:`.BanIterator` instead
@@ -2174,14 +2175,10 @@ def bans(
21742175
----------
21752176
limit: Optional[:class:`int`]
21762177
The number of bans to retrieve. Defaults to 1000.
2177-
before: Optional[Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`]]
2178-
Retrieve bans before this date or object.
2179-
If a datetime is provided, it is recommended to use a UTC aware datetime.
2180-
If the datetime is naive, it is assumed to be local time.
2181-
after: Optional[Union[:class:`.abc.Snowflake`, :class:`datetime.datetime`]]
2182-
Retrieve bans after this date or object.
2183-
If a datetime is provided, it is recommended to use a UTC aware datetime.
2184-
If the datetime is naive, it is assumed to be local time.
2178+
before: Optional[:class:`.abc.Snowflake`]
2179+
Retrieve bans before the given user.
2180+
after: Optional[:class:`.abc.Snowflake`]
2181+
Retrieve bans after the given user.
21852182
21862183
Yields
21872184
------
@@ -3650,6 +3647,7 @@ async def create_scheduled_event(
36503647
location: str | int | VoiceChannel | StageChannel | ScheduledEventLocation,
36513648
privacy_level: ScheduledEventPrivacyLevel = ScheduledEventPrivacyLevel.guild_only,
36523649
reason: str | None = None,
3650+
image: bytes = MISSING,
36533651
) -> ScheduledEvent | None:
36543652
"""|coro|
36553653
Creates a scheduled event.
@@ -3672,6 +3670,8 @@ async def create_scheduled_event(
36723670
so there is no need to change this parameter.
36733671
reason: Optional[:class:`str`]
36743672
The reason to show in the audit log.
3673+
image: Optional[:class:`bytes`]
3674+
The cover image of the scheduled event
36753675
36763676
Returns
36773677
-------
@@ -3709,6 +3709,9 @@ async def create_scheduled_event(
37093709
if end_time is not MISSING:
37103710
payload["scheduled_end_time"] = end_time.isoformat()
37113711

3712+
if image is not MISSING:
3713+
payload["image"] = utils._bytes_to_base64_data(image)
3714+
37123715
data = await self._state.http.create_scheduled_event(
37133716
guild_id=self.id, reason=reason, **payload
37143717
)

discord/http.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2245,6 +2245,7 @@ def create_scheduled_event(
22452245
"description",
22462246
"entity_type",
22472247
"entity_metadata",
2248+
"image",
22482249
)
22492250
payload = {k: v for k, v in payload.items() if k in valid_keys}
22502251

0 commit comments

Comments
 (0)