Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ext.bridge): add walk command functions & dynamically fetch attrs in commands variants #1867

Merged
merged 24 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6a3d2ec
feat(ext.bridge): walk command functions
Middledot Jan 11, 2023
1ba86dd
fix(ext.bridge): dynamically fetch attributes ...
Middledot Jan 11, 2023
3d408d3
chore(changlog): add entry
Middledot Jan 11, 2023
c46830c
chore(ext.bridge): add docs
Middledot Jan 11, 2023
224c94a
Merge branch 'master' into bridge-dev
Middledot Jan 11, 2023
c2ba234
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 11, 2023
358eec7
use shorter Iterator return type
BobDotCom Jan 11, 2023
f59430a
fix deprecated types
BobDotCom Jan 11, 2023
59f0064
finish changes
BobDotCom Jan 11, 2023
0fc7704
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jan 11, 2023
d973059
Merge branch 'master' into bridge-dev
Middledot Apr 2, 2023
2a5631e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 2, 2023
51d9eb5
Merge branch 'master' into bridge-dev
Middledot Apr 7, 2023
a521713
Merge branch 'master' into bridge-dev
Middledot Apr 9, 2023
db67dae
Merge branch 'master' into bridge-dev
plun1331 Apr 18, 2023
ba10e8d
refactor: remove comment
Middledot Apr 29, 2023
f85dcaa
Merge branch 'master' into bridge-dev
Middledot Apr 29, 2023
3602f08
fix(ext.bridge): re-add code for l10n set-ing
Middledot Apr 29, 2023
3a97bb1
feat(ext.bridge): dynamic set
Middledot Apr 29, 2023
90d1b9f
changelog: clarify
Middledot Apr 29, 2023
a93aec7
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 29, 2023
5f6083c
fix: I found a fix
Middledot Apr 29, 2023
e90b094
style(pre-commit): auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 29, 2023
96995fa
Merge branch 'master' into bridge-dev
Lulalaby May 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ These changes are available on the `master` branch, but have not yet been releas
- Added `view.parent` which is set when the view was sent by
`interaction.response.send_message`.
([#2036](https://github.com/Pycord-Development/pycord/pull/2036))
- Added functions (`bridge.Bot.walk_bridge_commands` &
`BridgeCommandGroup.walk_commands`) to cycle through all bridge commands and their
children/subcommands.
([#1867](https://github.com/Pycord-Development/pycord/pull/1867))

### Changed

Expand All @@ -62,6 +66,8 @@ These changes are available on the `master` branch, but have not yet been releas
([#2025](https://github.com/Pycord-Development/pycord/pull/2025))
- Store `view.message` on receiving Interaction for a component.
([#2036](https://github.com/Pycord-Development/pycord/pull/2036))
- Attributes shared between ext and slash commands are now dynamically fetched on bridge
commands. ([#1867](https://github.com/Pycord-Development/pycord/pull/1867))

### Removed

Expand Down
16 changes: 16 additions & 0 deletions discord/ext/bridge/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from __future__ import annotations

from abc import ABC
from collections.abc import Iterator

from discord.commands import ApplicationContext
from discord.errors import CheckFailure, DiscordException
Expand Down Expand Up @@ -60,6 +61,21 @@ def bridge_commands(self) -> list[BridgeCommand | BridgeCommandGroup]:

return cmds

def walk_bridge_commands(
self,
) -> Iterator[BridgeCommand | BridgeCommandGroup]:
"""An iterator that recursively walks through all the bot's bridge commands.

Yields
------
Union[:class:`.BridgeCommand`, :class:`.BridgeCommandGroup`]
A bridge command or bridge group of the bot.
"""
for cmd in self._bridge_commands:
yield cmd
if isinstance(cmd, BridgeCommandGroup):
yield from cmd.walk_commands()

async def get_application_context(
self, interaction: Interaction, cls=None
) -> BridgeApplicationContext:
Expand Down
64 changes: 52 additions & 12 deletions discord/ext/bridge/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from __future__ import annotations

import inspect
from collections.abc import Iterator
from typing import TYPE_CHECKING, Any, Callable

import discord.commands.options
Expand All @@ -38,7 +39,7 @@
SlashCommandOptionType,
)

from ...utils import filter_params, find, get
from ...utils import MISSING, find, get
from ..commands import BadArgument
from ..commands import Bot as ExtBot
from ..commands import (
Expand Down Expand Up @@ -156,6 +157,8 @@ class BridgeCommand:
The prefix-based version of this bridge command.
"""

__special_attrs__ = ["slash_variant", "ext_variant", "parent"]

def __init__(self, callback, **kwargs):
self.parent = kwargs.pop("parent", None)
self.slash_variant: BridgeSlashCommand = kwargs.pop(
Expand All @@ -166,13 +169,10 @@ def __init__(self, callback, **kwargs):
) or BridgeExtCommand(callback, **kwargs)

@property
def name_localizations(self) -> dict[str, str]:
def name_localizations(self) -> dict[str, str] | None:
"""Returns name_localizations from :attr:`slash_variant`

You can edit/set name_localizations directly with

.. code-block:: python3

bridge_command.name_localizations["en-UK"] = ... # or any other locale
# or
bridge_command.name_localizations = {"en-UK": ..., "fr-FR": ...}
Expand All @@ -184,13 +184,10 @@ def name_localizations(self, value):
self.slash_variant.name_localizations = value

@property
def description_localizations(self) -> dict[str, str]:
def description_localizations(self) -> dict[str, str] | None:
"""Returns description_localizations from :attr:`slash_variant`

You can edit/set description_localizations directly with

.. code-block:: python3

bridge_command.description_localizations["en-UK"] = ... # or any other locale
# or
bridge_command.description_localizations = {"en-UK": ..., "fr-FR": ...}
Expand All @@ -201,9 +198,34 @@ def description_localizations(self) -> dict[str, str]:
def description_localizations(self, value):
self.slash_variant.description_localizations = value

@property
def qualified_name(self) -> str:
return self.slash_variant.qualified_name
def __getattribute__(self, name):
try:
# first, look for the attribute on the bridge command
return super().__getattribute__(name)
except AttributeError as e:
# if it doesn't exist, check this list, if the name of
# the parameter is here
if name is self.__special_attrs__:
raise e

# looks up the result in the variants.
# slash cmd prioritized
result = getattr(self.slash_variant, name, MISSING)
try:
if result is MISSING:
return getattr(self.ext_variant, name)
return result
except AttributeError:
raise AttributeError(
f"'{self.__class__.__name__}' object has no attribute '{name}'"
)

def __setattr__(self, name, value) -> None:
if name not in self.__special_attrs__:
setattr(self.slash_variant, name, value)
setattr(self.ext_variant, name, value)

return super().__setattr__(name, value)

def add_to(self, bot: ExtBot) -> None:
"""Adds the command to a bot. This method is inherited by :class:`.BridgeCommandGroup`.
Expand Down Expand Up @@ -321,6 +343,14 @@ class BridgeCommandGroup(BridgeCommand):
If :func:`map_to` is used, the mapped slash command.
"""

__special_attrs__ = [
"slash_variant",
"ext_variant",
"parent",
"subcommands",
"mapped",
]

ext_variant: BridgeExtGroup
slash_variant: BridgeSlashGroup

Expand All @@ -341,6 +371,16 @@ def __init__(self, callback, *args, **kwargs):
kwargs.update(map_to)
self.mapped = self.slash_variant.command(**kwargs)(callback)

def walk_commands(self) -> Iterator[BridgeCommand]:
"""An iterator that recursively walks through all the bridge group's subcommands.

Yields
------
:class:`.BridgeCommand`
A bridge command of this bridge group.
"""
yield from self.subcommands

def command(self, *args, **kwargs):
"""A decorator to register a function as a subcommand.

Expand Down