Skip to content

feat: setup basedpyright #10

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

Draft
wants to merge 25 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
2a48b94
Start migration to uv
Paillat-dev May 13, 2025
c99b3d9
Setup ruff and hatch
Paillat-dev May 13, 2025
73cc121
Change pre-commit to use ruff
Paillat-dev May 13, 2025
130140a
Format with ruff
Paillat-dev May 13, 2025
c8f7934
Fix mistake
Paillat-dev May 13, 2025
15ab8d6
Add dev deps
Paillat-dev May 13, 2025
a2e36b4
Change workflows to use uv and ruff
Paillat-dev May 13, 2025
9d38186
:heavy_plus_sign: Add colorlog and remove requirements folder and fix…
Paillat-dev May 26, 2025
901fb98
:green_heart: Fix sphinx build ?
Paillat-dev May 26, 2025
625b4ed
:bug: Add __version.py for version management and update import in __…
Paillat-dev May 26, 2025
7999861
:pencil2: Update lib-checks.yml to run ruff on ubuntu-latest
Paillat-dev May 26, 2025
ce8602b
:bug: Update lib-checks.yml to run mypy with uv
Paillat-dev May 26, 2025
0658d79
:fire: Delete MANIFEST.in
Paillat-dev May 26, 2025
c2ec96e
:sparkles: Enhance lib-checks.yml to include ruff formatter check
Paillat-dev May 26, 2025
08d8dc6
:sparkles: Add support for BasedPyRight in CI and update dependencies
Paillat-dev May 26, 2025
8fe3d79
:heavy_plus_sign: Add requests dependency
Paillat-dev May 26, 2025
31259de
Merge branch 'master' into setup-basedpyright
Paillat-dev May 30, 2025
11565b0
tf
Paillat-dev May 30, 2025
12ca7f0
Fix pypoject.toml
Paillat-dev May 30, 2025
31089b1
Fix lock file
Paillat-dev May 30, 2025
05b077a
Auto-fixes from ruff
Paillat-dev May 30, 2025
123558f
Upgrade to |
Paillat-dev May 30, 2025
3b67fb9
Fix typing shit
Paillat-dev May 30, 2025
9da447c
Formatting
Paillat-dev May 30, 2025
c6282e7
Merge branch 'master' into setup-basedpyright
plun1331 May 30, 2025
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
118,600 changes: 118,600 additions & 0 deletions .basedpyright/baseline.json

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions .github/workflows/lib-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,23 @@ jobs:
run: uv run ruff check discord/
- name: "Run ruff formatter check"
run: uv run ruff format --check discord/
basedpyright:
runs-on: ubuntu-latest
steps:
- name: "Checkout Repository"
uses: actions/checkout@v4
- name: "Setup Python"
uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: "Install uv"
uses: astral-sh/setup-uv@v6
with:
enable-cache: true
- name: Sync dependencies
run: uv sync --no-python-downloads --group dev
- name: "Run basedpyright"
run: uv run basedpyright
mypy:
if: ${{ github.event_name != 'schedule' }}
runs-on: ubuntu-latest
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,8 @@ docs/build/linkcheck
/build/
/vscode/

# Auto-generated by setuptools-scm on build, should not be committed
/discord/_version.py

# BasedPyRight baseline file should be included
!.basedpyright/baseline.json
2 changes: 2 additions & 0 deletions CHANGELOG-V3.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

These changes are part of `pycord-test/pycord`, and are candidates for the next major
release.
**⚠️ This version removes support for Python 3.9. ⚠️**

### Added

Expand All @@ -12,3 +13,4 @@ release.
### Deprecated

### Removed
- **⚠️ Removed support for Python 3.9.**
8 changes: 4 additions & 4 deletions discord/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
Protocol,
Sequence,
TypeVar,
Union,
overload,
runtime_checkable,
)
Expand Down Expand Up @@ -71,6 +70,7 @@

if TYPE_CHECKING:
from datetime import datetime
from typing import TypeAlias

from .asset import Asset
from .channel import (
Expand Down Expand Up @@ -98,9 +98,9 @@
from .ui.view import View
from .user import ClientUser

PartialMessageableChannel = Union[TextChannel, VoiceChannel, StageChannel, Thread, DMChannel, PartialMessageable]
MessageableChannel = Union[PartialMessageableChannel, GroupChannel]
SnowflakeTime = Union["Snowflake", datetime]
PartialMessageableChannel = TextChannel | VoiceChannel | StageChannel | Thread | DMChannel | PartialMessageable
MessageableChannel = PartialMessageableChannel | GroupChannel
SnowflakeTime: TypeAlias = "Snowflake | datetime"

MISSING = utils.MISSING

Expand Down
4 changes: 2 additions & 2 deletions discord/activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from __future__ import annotations

import datetime
from typing import TYPE_CHECKING, Any, Union, overload
from typing import TYPE_CHECKING, Any, overload

from .asset import Asset
from .colour import Colour
Expand Down Expand Up @@ -805,7 +805,7 @@ def __repr__(self) -> str:
return f"<CustomActivity name={self.name!r} emoji={self.emoji!r}>"


ActivityTypes = Union[Activity, Game, CustomActivity, Streaming, Spotify]
ActivityTypes = Activity | Game | CustomActivity | Streaming | Spotify


@overload
Expand Down
3 changes: 2 additions & 1 deletion discord/commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,8 @@ def _match_option_param_names(self, params, options):
lambda o, a: o.input_type == SlashCommandOptionType.string
and o.converter is not None, # pass on converters
lambda o, a: isinstance(o.input_type, SlashCommandOptionType), # pass on slash cmd option type enums
lambda o, a: isinstance(o._raw_type, tuple) and a == Union[o._raw_type], # type: ignore # union types
# TODO: Union is deprecated
lambda o, a: isinstance(o._raw_type, tuple) and a == Union[o._raw_type], # type: ignore # union types # noqa: UP007
lambda o, a: self._is_typing_optional(a) and not o.required and o._raw_type in a.__args__, # optional
lambda o, a: isinstance(a, type) and issubclass(a, o._raw_type), # 'normal' types
]
Expand Down
49 changes: 27 additions & 22 deletions discord/commands/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import inspect
import logging
from enum import Enum
from typing import TYPE_CHECKING, Literal, Optional, Type, Union
from typing import TYPE_CHECKING, Literal, Optional, Union # pyright: ignore[reportDeprecated]

from ..abc import GuildChannel, Mentionable
from ..channel import (
Expand All @@ -53,24 +53,26 @@
from ..role import Role
from ..user import User

InputType = Union[
Type[str],
Type[bool],
Type[int],
Type[float],
Type[GuildChannel],
Type[Thread],
Type[Member],
Type[User],
Type[Attachment],
Type[Role],
Type[Mentionable],
SlashCommandOptionType,
Converter,
Type[Converter],
Type[Enum],
Type[DiscordEnum],
]
InputType = (
type[
str
| bool
| int
| float
| GuildChannel
| Thread
| Member
| User
| Attachment
| Role
| Mentionable
| Converter # pyright: ignore[reportMissingTypeArgument]
| Enum
| DiscordEnum
]
| SlashCommandOptionType
| Converter # pyright: ignore[reportMissingTypeArgument]
)

__all__ = (
"ThreadOption",
Expand Down Expand Up @@ -270,17 +272,20 @@ def __init__(self, input_type: InputType = str, /, description: str | None = Non

if self.input_type == SlashCommandOptionType.integer:
minmax_types = (int, type(None))
minmax_typehint = Optional[int]
# TODO: Optional should not be used
minmax_typehint = Optional[int] # noqa: UP007
elif self.input_type == SlashCommandOptionType.number:
minmax_types = (int, float, type(None))
minmax_typehint = Optional[Union[int, float]]
# TODO: Optional and Union should not be used
minmax_typehint = Optional[Union[int, float]] # noqa: UP007
else:
minmax_types = (type(None),)
minmax_typehint = type(None)

if self.input_type == SlashCommandOptionType.string:
minmax_length_types = (int, type(None))
minmax_length_typehint = Optional[int]
# TODO: Optional should not be used
minmax_length_typehint = Optional[int] # noqa: UP007
else:
minmax_length_types = (type(None),)
minmax_length_typehint = type(None)
Expand Down
4 changes: 2 additions & 2 deletions discord/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Union
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
from aiohttp import ClientResponse, ClientWebSocketResponse

try:
from requests import Response

_ResponseType = Union[ClientResponse, Response]
_ResponseType = ClientResponse | Response
except ModuleNotFoundError:
_ResponseType = ClientResponse

Expand Down
4 changes: 2 additions & 2 deletions discord/ext/bridge/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from __future__ import annotations

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

from discord.commands import ApplicationContext
from discord.interactions import Interaction, InteractionMessage
Expand Down Expand Up @@ -190,7 +190,7 @@ async def delete(self, *, delay: float | None = None, reason: str | None = None)
await self._original_response_message.delete(delay=delay, reason=reason)


Context = Union[BridgeExtContext, BridgeApplicationContext]
Context = BridgeExtContext | BridgeApplicationContext
"""
A Union class for either :class:`BridgeExtContext` or :class:`BridgeApplicationContext`.
Can be used as a type hint for Context for bridge commands.
Expand Down
18 changes: 7 additions & 11 deletions discord/ext/commands/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
DEALINGS IN THE SOFTWARE.
"""

from typing import TYPE_CHECKING, Any, Callable, Coroutine, TypeVar, Union
from typing import TYPE_CHECKING, Any, Callable, Coroutine, TypeVar

if TYPE_CHECKING:
from .cog import Cog
Expand All @@ -33,15 +33,11 @@
T = TypeVar("T")

Coro = Coroutine[Any, Any, T]
MaybeCoro = Union[T, Coro[T]]
MaybeCoro = T | Coro[T]
CoroFunc = Callable[..., Coro[Any]]

Check = Union[
Callable[["Cog", "Context[Any]"], MaybeCoro[bool]],
Callable[["Context[Any]"], MaybeCoro[bool]],
]
Hook = Union[Callable[["Cog", "Context[Any]"], Coro[Any]], Callable[["Context[Any]"], Coro[Any]]]
Error = Union[
Callable[["Cog", "Context[Any]", "CommandError"], Coro[Any]],
Callable[["Context[Any]", "CommandError"], Coro[Any]],
]
Check = Callable[["Cog", "Context[Any]"], MaybeCoro[bool]] | Callable[["Context[Any]"], MaybeCoro[bool]] # pyright: ignore[reportExplicitAny]
Hook = Callable[["Cog", "Context[Any]"], Coro[Any]] | Callable[["Context[Any]"], Coro[Any]] # pyright: ignore[reportExplicitAny]
Error = (
Callable[["Cog", "Context[Any]", "CommandError"], Coro[Any]] | Callable[["Context[Any]", "CommandError"], Coro[Any]] # pyright: ignore[reportExplicitAny]
)
4 changes: 2 additions & 2 deletions discord/ext/commands/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

import inspect
import re
from typing import TYPE_CHECKING, Any, Generic, TypeVar, Union
from typing import TYPE_CHECKING, Any, Generic, TypeVar

import discord.abc
import discord.utils
Expand All @@ -54,7 +54,7 @@


T = TypeVar("T")
BotT = TypeVar("BotT", bound="Union[Bot, AutoShardedBot]")
BotT = TypeVar("BotT", bound="Bot | AutoShardedBot")
CogT = TypeVar("CogT", bound="Cog")

if TYPE_CHECKING:
Expand Down
3 changes: 2 additions & 1 deletion discord/ext/commands/flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,8 @@ async def convert_flag(ctx, argument: str, flag: Flag, annotation: Any = None) -
return await convert_flag(ctx, argument, flag, annotation)
elif origin is Union and annotation.__args__[-1] is type(None):
# typing.Optional[x]
annotation = Union[annotation.__args__[:-1]]
# TODO: Union is deprecated
annotation = Union[annotation.__args__[:-1]] # noqa: UP007
return await run_converters(ctx, annotation, argument, param)
elif origin is dict:
# typing.Dict[K, V] -> typing.Tuple[K, V]
Expand Down
13 changes: 5 additions & 8 deletions discord/guild.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,8 @@
TYPE_CHECKING,
Any,
ClassVar,
List,
NamedTuple,
Optional,
Sequence,
Tuple,
Union,
overload,
)

Expand Down Expand Up @@ -77,7 +73,7 @@
from .member import Member, VoiceState
from .mixins import Hashable
from .monetization import Entitlement
from .onboarding import Onboarding
from .onboarding import Onboarding, OnboardingPrompt
from .permissions import PermissionOverwrite
from .role import Role
from .scheduled_events import ScheduledEvent, ScheduledEventLocation
Expand All @@ -87,6 +83,7 @@
from .user import User
from .welcome_screen import WelcomeScreen, WelcomeScreenChannel
from .widget import Widget
from .enums import OnboardingMode

__all__ = ("Guild",)

Expand Down Expand Up @@ -115,9 +112,9 @@
from .voice_client import VoiceClient
from .webhook import Webhook

VocalGuildChannel = Union[VoiceChannel, StageChannel]
GuildChannel = Union[VoiceChannel, StageChannel, TextChannel, ForumChannel, CategoryChannel]
ByCategoryItem = Tuple[Optional[CategoryChannel], List[GuildChannel]]
VocalGuildChannel = VoiceChannel | StageChannel
GuildChannel = VoiceChannel | StageChannel | TextChannel | ForumChannel | CategoryChannel
ByCategoryItem = tuple[CategoryChannel | None, list[GuildChannel]]


class BanEntry(NamedTuple):
Expand Down
24 changes: 12 additions & 12 deletions discord/interactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from __future__ import annotations

import asyncio
from typing import TYPE_CHECKING, Any, Coroutine, Union
from typing import TYPE_CHECKING, Any, Coroutine

from . import utils
from .channel import ChannelType, PartialMessageable, _threaded_channel_factory
Expand Down Expand Up @@ -88,17 +88,17 @@
from .ui.modal import Modal
from .ui.view import View

InteractionChannel = Union[
VoiceChannel,
StageChannel,
TextChannel,
ForumChannel,
CategoryChannel,
Thread,
DMChannel,
GroupChannel,
PartialMessageable,
]
InteractionChannel = (
VoiceChannel
| StageChannel
| TextChannel
| ForumChannel
| CategoryChannel
| Thread
| DMChannel
| GroupChannel
| PartialMessageable
)

MISSING: Any = utils.MISSING

Expand Down
8 changes: 5 additions & 3 deletions discord/invite.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

from __future__ import annotations

from typing import TYPE_CHECKING, TypeVar, Union
from typing import TYPE_CHECKING, TypeVar

from .appinfo import PartialAppInfo
from .asset import Asset
Expand All @@ -41,6 +41,8 @@
)

if TYPE_CHECKING:
from typing import TypeAlias

from .abc import GuildChannel
from .guild import Guild
from .scheduled_events import ScheduledEvent
Expand All @@ -53,8 +55,8 @@
from .types.scheduled_events import ScheduledEvent as ScheduledEventPayload
from .user import User

InviteGuildType = Union[Guild, "PartialInviteGuild", Object]
InviteChannelType = Union[GuildChannel, "PartialInviteChannel", Object]
InviteGuildType: TypeAlias = "Guild | PartialInviteGuild | Object"
InviteChannelType: TypeAlias = "GuildChannel | PartialInviteChannel | Object"

import datetime

Expand Down
2 changes: 1 addition & 1 deletion discord/iterators.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@

T = TypeVar("T")
OT = TypeVar("OT")
_Func = Callable[[T], Union[OT, Awaitable[OT]]]
_Func = Callable[[T], OT | Awaitable[OT]]

OLDEST_OBJECT = Object(id=0)

Expand Down
Loading