Skip to content

Commit

Permalink
Merge branch 'master' into update-tags
Browse files Browse the repository at this point in the history
  • Loading branch information
Lulalaby authored Jun 24, 2023
2 parents 2bea071 + b076bd3 commit a25b73a
Show file tree
Hide file tree
Showing 14 changed files with 272 additions and 37 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ repos:
# - --remove-duplicate-keys
# - --remove-unused-variables
- repo: https://github.com/asottile/pyupgrade
rev: v3.4.0
rev: v3.7.0
hooks:
- id: pyupgrade
args: [--py38-plus]
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,17 @@ These changes are available on the `master` branch, but have not yet been releas
([#2042](https://github.com/Pycord-Development/pycord/pull/2042))
- Added `icon` and `unicode_emoji` to `Guild.create_role`.
([#2086](https://github.com/Pycord-Development/pycord/pull/2086))
- Added `cooldown` and `max_concurrency` to `SlashCommandGroup`.
([#2091](https://github.com/Pycord-Development/pycord/pull/2091))
- Added new embedded activities, Gartic Phone and Jamspace.
([#2102](https://github.com/Pycord-Development/pycord/pull/2102))
- Added `bridge.Context` as a shortcut to `Union` of subclasses.
([#2106](https://github.com/Pycord-Development/pycord/pull/2106))
- Added Annotated forms support for typehinting slash command options.
([#2124](https://github.com/Pycord-Development/pycord/pull/2124))
- Added `suppress` and `allowed_mentions` parameters to `Webhook` and
`InteractionResponse` edit methods.
([#2138](https://github.com/Pycord-Development/pycord/pull/2138))

### Changed

Expand Down Expand Up @@ -129,6 +138,8 @@ These changes are available on the `master` branch, but have not yet been releas
([#2079](https://github.com/Pycord-Development/pycord/pull/2079))
- Fixed `HTTPException` when trying to create a forum thread with files.
([#2075](https://github.com/Pycord-Development/pycord/pull/2075))
- Fixed `before_invoke` not being run for `SlashCommandGroup`.
([#2091](https://github.com/Pycord-Development/pycord/pull/2091))
- Fixed `AttributeError` when accessing a `Select`'s values when it hasn't been
interacted with. ([#2104](https://github.com/Pycord-Development/pycord/pull/2104))
- Fixed `Thread.applied_tags` not being updated.
Expand Down
6 changes: 3 additions & 3 deletions discord/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ def _repr_attrs(self) -> tuple[str, ...]:
def _update(self, guild: Guild, data: TextChannelPayload) -> None:
super()._update(guild, data)

async def _get_channel(self) -> "TextChannel":
async def _get_channel(self) -> TextChannel:
return self

def is_news(self) -> bool:
Expand Down Expand Up @@ -1064,11 +1064,11 @@ async def edit(
available_tags: list[ForumTag] = ...,
require_tag: bool = ...,
overwrites: Mapping[Role | Member | Snowflake, PermissionOverwrite] = ...,
) -> "ForumChannel" | None:
) -> ForumChannel | None:
...

@overload
async def edit(self) -> "ForumChannel" | None:
async def edit(self) -> ForumChannel | None:
...

async def edit(self, *, reason=None, **options):
Expand Down
6 changes: 3 additions & 3 deletions discord/colour.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,8 @@ def nitro_pink(cls: type[CT]) -> CT:

@classmethod
def embed_background(cls: type[CT], theme: str = "dark") -> CT:
"""A factory method that returns a :class:`Color` corresponding to the
embed colors on discord clients, with a value of:
"""A factory method that returns a :class:`Colour` corresponding to the
embed colours on discord clients, with a value of:
- ``0x2B2D31`` (dark)
- ``0xEEEFF1`` (light)
Expand All @@ -347,7 +347,7 @@ def embed_background(cls: type[CT], theme: str = "dark") -> CT:
Parameters
----------
theme: :class:`str`
The theme color to apply, must be one of "dark", "light", or "amoled".
The theme colour to apply, must be one of "dark", "light", or "amoled".
"""
themes_cls = {
"dark": 0x2B2D31,
Expand Down
73 changes: 62 additions & 11 deletions discord/commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import functools
import inspect
import re
import sys
import types
from collections import OrderedDict
from enum import Enum
Expand Down Expand Up @@ -64,6 +65,11 @@
from .context import ApplicationContext, AutocompleteContext
from .options import Option, OptionChoice

if sys.version_info >= (3, 11):
from typing import Annotated, get_args, get_origin
else:
from typing_extensions import Annotated, get_args, get_origin

__all__ = (
"_BaseCommand",
"ApplicationCommand",
Expand All @@ -84,6 +90,7 @@

from .. import Permissions
from ..cog import Cog
from ..ext.commands.cooldowns import CooldownMapping, MaxConcurrency

T = TypeVar("T")
CogT = TypeVar("CogT", bound="Cog")
Expand Down Expand Up @@ -294,18 +301,17 @@ async def prepare(self, ctx: ApplicationContext) -> None:
f"The check functions for the command {self.name} failed"
)

if hasattr(self, "_max_concurrency"):
if self._max_concurrency is not None:
# For this application, context can be duck-typed as a Message
await self._max_concurrency.acquire(ctx) # type: ignore # ctx instead of non-existent message
if self._max_concurrency is not None:
# For this application, context can be duck-typed as a Message
await self._max_concurrency.acquire(ctx) # type: ignore # ctx instead of non-existent message

try:
self._prepare_cooldowns(ctx)
await self.call_before_hooks(ctx)
except:
if self._max_concurrency is not None:
await self._max_concurrency.release(ctx) # type: ignore # ctx instead of non-existent message
raise
try:
self._prepare_cooldowns(ctx)
await self.call_before_hooks(ctx)
except:
if self._max_concurrency is not None:
await self._max_concurrency.release(ctx) # type: ignore # ctx instead of non-existent message
raise

def is_on_cooldown(self, ctx: ApplicationContext) -> bool:
"""Checks whether the command is currently on cooldown.
Expand Down Expand Up @@ -732,6 +738,19 @@ def _parse_options(self, params, *, check_params: bool = True) -> list[Option]:
if option == inspect.Parameter.empty:
option = str

if self._is_typing_annotated(option):
type_hint = get_args(option)[0]
metadata = option.__metadata__
# If multiple Options in metadata, the first will be used.
option_gen = (elem for elem in metadata if isinstance(elem, Option))
option = next(option_gen, Option())
# Handle Optional
if self._is_typing_optional(type_hint):
option.input_type = get_args(type_hint)[0]
option.default = None
else:
option.input_type = type_hint

if self._is_typing_union(option):
if self._is_typing_optional(option):
option = Option(option.__args__[0], default=None)
Expand Down Expand Up @@ -820,6 +839,9 @@ def _is_typing_union(self, annotation):
def _is_typing_optional(self, annotation):
return self._is_typing_union(annotation) and type(None) in annotation.__args__ # type: ignore

def _is_typing_annotated(self, annotation):
return get_origin(annotation) is Annotated

@property
def cog(self):
return getattr(self, "_cog", MISSING)
Expand Down Expand Up @@ -1119,6 +1141,8 @@ def __init__(
description: str | None = None,
guild_ids: list[int] | None = None,
parent: SlashCommandGroup | None = None,
cooldown: CooldownMapping | None = None,
max_concurrency: MaxConcurrency | None = None,
**kwargs,
) -> None:
self.name = str(name)
Expand Down Expand Up @@ -1153,6 +1177,33 @@ def __init__(
"description_localizations", MISSING
)

# similar to ApplicationCommand
from ..ext.commands.cooldowns import BucketType, CooldownMapping, MaxConcurrency

# no need to getattr, since slash cmds groups cant be created using a decorator

if cooldown is None:
buckets = CooldownMapping(cooldown, BucketType.default)
elif isinstance(cooldown, CooldownMapping):
buckets = cooldown
else:
raise TypeError(
"Cooldown must be a an instance of CooldownMapping or None."
)

self._buckets: CooldownMapping = buckets

# no need to getattr, since slash cmds groups cant be created using a decorator

if max_concurrency is not None and not isinstance(
max_concurrency, MaxConcurrency
):
raise TypeError(
"max_concurrency must be an instance of MaxConcurrency or None"
)

self._max_concurrency: MaxConcurrency | None = max_concurrency

@property
def module(self) -> str | None:
return self.__module__
Expand Down
12 changes: 7 additions & 5 deletions discord/embeds.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,16 +173,18 @@ class EmbedMedia: # Thumbnail, Image, Video

url: str
proxy_url: str | None
height: int
width: int
height: int | None
width: int | None

@classmethod
def from_dict(cls, data: dict[str, str | int]) -> EmbedMedia:
self = cls.__new__(cls)
self.url = str(data.get("url"))
self.proxy_url = str(data.get("proxy_url"))
self.height = int(data["height"])
self.width = int(data["width"])
self.proxy_url = (
str(proxy_url) if (proxy_url := data.get("proxy_url")) else None
)
self.height = int(height) if (height := data.get("height")) else None
self.width = int(width) if (width := data.get("width")) else None
return self

def __repr__(self) -> str:
Expand Down
11 changes: 9 additions & 2 deletions discord/ext/bridge/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from __future__ import annotations

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, overload
from typing import TYPE_CHECKING, Any, Union, overload

from discord.commands import ApplicationContext
from discord.interactions import Interaction, InteractionMessage
Expand All @@ -38,7 +38,7 @@
from .core import BridgeExtCommand, BridgeSlashCommand


__all__ = ("BridgeContext", "BridgeExtContext", "BridgeApplicationContext")
__all__ = ("BridgeContext", "BridgeExtContext", "BridgeApplicationContext", "Context")


class BridgeContext(ABC):
Expand Down Expand Up @@ -195,3 +195,10 @@ async def delete(
"""
if self._original_response_message:
await self._original_response_message.delete(delay=delay, reason=reason)


Context = Union[BridgeExtContext, BridgeApplicationContext]
"""
A Union class for either :class:`BridgeExtContext` or :class:`BridgeApplicationContext`.
Can be used as a type hint for Context for bridge commands.
"""
17 changes: 11 additions & 6 deletions discord/ext/commands/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@

from discord.utils import MISSING, MissingField, maybe_coroutine, resolve_annotation

if sys.version_info >= (3, 11):
_MISSING = MissingField
else:
_MISSING = MISSING

from .converter import run_converters
from .errors import (
BadFlagArgument,
Expand Down Expand Up @@ -81,13 +86,13 @@ class Flag:
Whether multiple given values overrides the previous value.
"""

name: str = MISSING
name: str = _MISSING
aliases: list[str] = field(default_factory=list)
attribute: str = MISSING
annotation: Any = MISSING
default: Any = MISSING
max_args: int = MISSING
override: bool = MISSING
attribute: str = _MISSING
annotation: Any = _MISSING
default: Any = _MISSING
max_args: int = _MISSING
override: bool = _MISSING
cast_to_dict: bool = False

@property
Expand Down
Loading

0 comments on commit a25b73a

Please sign in to comment.