diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ed38b0797c..e0cd7bbdfe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,7 @@ ci: repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: trailing-whitespace - id: end-of-file-fixer @@ -19,7 +19,7 @@ repos: # - --remove-duplicate-keys # - --remove-unused-variables - repo: https://github.com/asottile/pyupgrade - rev: v3.13.0 + rev: v3.15.0 hooks: - id: pyupgrade args: [--py38-plus] @@ -28,7 +28,7 @@ repos: hooks: - id: isort - repo: https://github.com/psf/black - rev: 23.9.1 + rev: 23.11.0 hooks: - id: black args: [--safe, --quiet] @@ -77,7 +77,7 @@ repos: # - id: mypy - repo: https://github.com/pre-commit/mirrors-prettier - rev: v3.0.3 + rev: v3.1.0 hooks: - id: prettier args: [--prose-wrap=always, --print-width=88] diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dd6e0c862..0ce874899d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,8 @@ These changes are available on the `master` branch, but have not yet been releas ([#2206](https://github.com/Pycord-Development/pycord/pull/2206)) - Added function `Guild.delete_auto_moderation_rule`. ([#2153](https://github.com/Pycord-Development/pycord/pull/2153)) +- Added `VoiceChannel.slowmode_delay`. + ([#2112](https://github.com/Pycord-Development/pycord/pull/2112)) ### Changed @@ -180,6 +182,12 @@ These changes are available on the `master` branch, but have not yet been releas ([#2192](https://github.com/Pycord-Development/pycord/pull/2192)) - Fixed `DMChannel.recipient` being `None` and consequently `User.dm_channel` also being `None`. ([#2219](https://github.com/Pycord-Development/pycord/pull/2219)) +- Fixed ffmpeg being terminated prematurely when piping audio stream. + ([#2240](https://github.com/Pycord-Development/pycord/pull/2240)) +- Fixed tasks looping infinitely when `tzinfo` is neither `None` nor UTC. + ([#2196](https://github.com/Pycord-Development/pycord/pull/2196)) +- Fixed `AttributeError` when running permission checks without the `bot` scope. + ([#2113](https://github.com/Pycord-Development/pycord/issues/2113)) - Fixed `Option` not working on bridge commands because `ext.commands.Command` doesn't recognize them. ([#2256](https://github.com/Pycord-Development/pycord/pull/2256)) diff --git a/discord/abc.py b/discord/abc.py index 71a307ab87..a7aba7ecc3 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -712,7 +712,7 @@ def permissions_for(self, obj: Member | Role, /) -> Permissions: return Permissions.all() default = self.guild.default_role - base = Permissions(default.permissions.value) + base = Permissions(default.permissions.value if default else 0) # Handle the role case first if isinstance(obj, Role): diff --git a/discord/channel.py b/discord/channel.py index 6121dd5890..5cd70f52f7 100644 --- a/discord/channel.py +++ b/discord/channel.py @@ -1329,6 +1329,7 @@ class VocalGuildChannel(discord.abc.Connectable, discord.abc.GuildChannel, Hasha "user_limit", "_state", "position", + "slowmode_delay", "_overwrites", "category_id", "rtc_region", @@ -1376,6 +1377,7 @@ def _update( data, "last_message_id" ) self.position: int = data.get("position") + self.slowmode_delay = data.get("rate_limit_per_user", 0) self.bitrate: int = data.get("bitrate") self.user_limit: int = data.get("user_limit") self.flags: ChannelFlags = ChannelFlags._from_value(data.get("flags", 0)) @@ -1483,6 +1485,13 @@ class VoiceChannel(discord.abc.Messageable, VocalGuildChannel): The ID of the last message sent to this channel. It may not always point to an existing or valid message. .. versionadded:: 2.0 + slowmode_delay: :class:`int` + The number of seconds a member must wait between sending messages + in this channel. A value of `0` denotes that it is disabled. + Bots and users with :attr:`~Permissions.manage_channels` or + :attr:`~Permissions.manage_messages` bypass slowmode. + + .. versionadded:: 2.5 flags: :class:`ChannelFlags` Extra features of the channel. @@ -1791,6 +1800,7 @@ async def edit( overwrites: Mapping[Role | Member, PermissionOverwrite] = ..., rtc_region: VoiceRegion | None = ..., video_quality_mode: VideoQualityMode = ..., + slowmode_delay: int = ..., reason: str | None = ..., ) -> VoiceChannel | None: ... diff --git a/discord/ext/tasks/__init__.py b/discord/ext/tasks/__init__.py index 400786d8a4..81d39ab8d1 100644 --- a/discord/ext/tasks/__init__.py +++ b/discord/ext/tasks/__init__.py @@ -575,7 +575,7 @@ def _get_next_sleep_time(self) -> datetime.datetime: if self._current_loop == 0: # if we're at the last index on the first iteration, we need to sleep until tomorrow return datetime.datetime.combine( - datetime.datetime.now(datetime.timezone.utc) + datetime.datetime.now(self._time[0].tzinfo or datetime.timezone.utc) + datetime.timedelta(days=1), self._time[0], ) @@ -584,18 +584,26 @@ def _get_next_sleep_time(self) -> datetime.datetime: if self._current_loop == 0: self._time_index += 1 - if next_time > datetime.datetime.now(datetime.timezone.utc).timetz(): + if ( + next_time + > datetime.datetime.now( + next_time.tzinfo or datetime.timezone.utc + ).timetz() + ): return datetime.datetime.combine( - datetime.datetime.now(datetime.timezone.utc), next_time + datetime.datetime.now(next_time.tzinfo or datetime.timezone.utc), + next_time, ) else: return datetime.datetime.combine( - datetime.datetime.now(datetime.timezone.utc) + datetime.datetime.now(next_time.tzinfo or datetime.timezone.utc) + datetime.timedelta(days=1), next_time, ) - next_date = cast(datetime.datetime, self._last_iteration) + next_date = cast( + datetime.datetime, self._last_iteration.astimezone(next_time.tzinfo) + ) if next_time < next_date.timetz(): next_date += datetime.timedelta(days=1) diff --git a/discord/interactions.py b/discord/interactions.py index 83ca14f128..19b5363082 100644 --- a/discord/interactions.py +++ b/discord/interactions.py @@ -149,6 +149,8 @@ class Interaction: "custom_id", "_channel_data", "_message_data", + "_guild_data", + "_guild", "_permissions", "_app_permissions", "_state", @@ -188,6 +190,11 @@ def _from_data(self, data: InteractionPayload): self.user: User | Member | None = None self._permissions: int = 0 + self._guild: Guild | None = None + self._guild_data = data.get("guild") + if self.guild is None and self._guild_data: + self._guild = Guild(data=self._guild_data, state=self) + # TODO: there's a potential data loss here if self.guild_id: guild = ( @@ -246,6 +253,8 @@ def client(self) -> Client: @property def guild(self) -> Guild | None: """The guild the interaction was sent from.""" + if self._guild: + return self._guild return self._state and self._state._get_guild(self.guild_id) def is_command(self) -> bool: diff --git a/discord/player.py b/discord/player.py index 87b0f5718a..0b4dc417c3 100644 --- a/discord/player.py +++ b/discord/player.py @@ -227,7 +227,7 @@ def _pipe_writer(self, source: io.BufferedIOBase) -> None: # arbitrarily large read size data = source.read(8192) if not data: - self._process.terminate() + self._stdin.close() return try: self._stdin.write(data) diff --git a/discord/raw_models.py b/discord/raw_models.py index 39eab47443..79c8091d98 100644 --- a/discord/raw_models.py +++ b/discord/raw_models.py @@ -256,7 +256,7 @@ def __init__( self.burst: bool = data.get("burst") self.burst_colours: list = data.get("burst_colors", []) self.burst_colors: list = self.burst_colours - self.type: ReactionType = try_enum(data.get("type", 0)) + self.type: ReactionType = try_enum(ReactionType, data.get("type", 0)) try: self.guild_id: int | None = int(data["guild_id"]) @@ -333,7 +333,7 @@ def __init__(self, data: ReactionClearEmojiEvent, emoji: PartialEmoji) -> None: self.burst: bool = data.get("burst") self.burst_colours: list = data.get("burst_colors", []) self.burst_colors: list = self.burst_colours - self.type: ReactionType = try_enum(data.get("type", 0)) + self.type: ReactionType = try_enum(ReactionType, data.get("type", 0)) try: self.guild_id: int | None = int(data["guild_id"]) diff --git a/requirements/_.txt b/requirements/_.txt index 26e696d0f2..2488d446e6 100644 --- a/requirements/_.txt +++ b/requirements/_.txt @@ -1,2 +1,2 @@ -aiohttp>=3.6.0,<3.9.0 +aiohttp>=3.6.0,<3.10.0 typing_extensions>=4,<5; python_version < "3.11" diff --git a/requirements/dev.txt b/requirements/dev.txt index 1831a6fd24..525873d774 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -3,7 +3,7 @@ pylint~=2.17.5 pytest~=7.4.3 pytest-asyncio~=0.21.1 # pytest-order~=1.0.1 -mypy~=1.5.1 +mypy~=1.7.1 coverage~=7.3 pre-commit==3.5.0 codespell==2.2.6 diff --git a/requirements/docs.txt b/requirements/docs.txt index 453c4fcf7b..2c8cb6ede3 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -2,7 +2,7 @@ sphinx==5.3.0 sphinxcontrib_trio==1.1.2 sphinxcontrib-websupport==1.2.4 myst-parser==1.0.0 -sphinxext-opengraph==0.8.2 +sphinxext-opengraph==0.9.0 sphinx-copybutton==0.5.2 furo@ git+https://github.com/pradyunsg/furo@193643f sphinx-autodoc-typehints==1.23.0