Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
2 changes: 1 addition & 1 deletion .github/actions/setup-env/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ inputs:
python-version:
description: The python version to install
required: false
default: '3.9'
default: '3.10'
use-cached-uv-lock:
description: Whether to download the uv lock cache.
required: false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/create-release-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
- name: Set up environment
uses: ./.github/actions/setup-env
with:
python-version: 3.9
python-version: 3.10

- name: Install dependencies
run: uv sync --no-default-groups --group changelog
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
id: setup
uses: ./.github/actions/setup-env
with:
python-version: 3.9
python-version: 3.10

- name: Build package
run: |
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ formats:
build:
os: ubuntu-24.04
tools:
python: "3.9"
python: "3.10"
jobs:
create_environment:
- asdf plugin add uv
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ Key Features
Installing
----------

**Python 3.9 or higher is required.**
**Python 3.10 or higher is required.**

(If you need python 3.8 or 3.9 support, please use `disnake<2.12`)

To install the library without full voice support, you can just run the
following command:
Expand Down
2 changes: 1 addition & 1 deletion changelog/1394.breaking.rst
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Python 3.8 support has been dropped.
Drop support for Python 3.8 and 3.9 as they are end of life.
1 change: 1 addition & 0 deletions changelog/1427.breaking.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Drop support for Python 3.8 and 3.9 as they are end of life.
18 changes: 3 additions & 15 deletions disnake/ext/commands/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
import inspect
import itertools
import math
import sys
import types
from abc import ABC, abstractmethod
from dataclasses import dataclass
from enum import Enum, EnumMeta
from types import EllipsisType, UnionType
from typing import (
TYPE_CHECKING,
Any,
Expand Down Expand Up @@ -87,16 +87,6 @@
P = TypeVar("P")


if sys.version_info >= (3, 10):
from types import EllipsisType, UnionType
elif TYPE_CHECKING:
EllipsisType = type(Ellipsis)
UnionType = NoReturn

else:
UnionType = object()
EllipsisType = type(Ellipsis)

T = TypeVar("T", bound=Any)
TypeT = TypeVar("TypeT", bound=Type[Any])
BotT = TypeVar("BotT", bound="disnake.Client", covariant=True)
Expand Down Expand Up @@ -361,10 +351,8 @@ def __call__(self) -> NoReturn:
raise NotImplementedError

# support new union syntax for `Range[int, 1, 2] | None`
if sys.version_info >= (3, 10):

def __or__(self, other):
return Union[self, other]
def __or__(self, other):
return Union[self, other]


if TYPE_CHECKING:
Expand Down
2 changes: 1 addition & 1 deletion disnake/role.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ async def _move(self, position: int, reason: Optional[str]) -> None:
roles.append(self.id)

payload: List[RolePositionUpdate] = [
{"id": z[0], "position": z[1]} for z in zip(roles, change_range)
{"id": z[0], "position": z[1]} for z in zip(roles, change_range, strict=True)
]
await http.move_role_position(self.guild.id, payload, reason=reason)

Expand Down
22 changes: 1 addition & 21 deletions disnake/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from bisect import bisect_left
from inspect import getdoc as _getdoc, isawaitable as _isawaitable, signature as _signature
from operator import attrgetter
from types import UnionType
from typing import (
TYPE_CHECKING,
Any,
Expand All @@ -43,7 +44,6 @@
TypedDict,
TypeVar,
Union,
get_origin,
overload,
)
from urllib.parse import parse_qs, urlencode
Expand Down Expand Up @@ -1146,24 +1146,6 @@ def as_chunks(iterator: _Iter[T], max_size: int) -> _Iter[List[T]]:
return _chunk(iterator, max_size)


if sys.version_info >= (3, 10):
PY_310 = True
from types import UnionType
else:
PY_310 = False
UnionType = object()


def flatten_literal_params(parameters: Iterable[Any]) -> Tuple[Any, ...]:
params = []
for p in parameters:
if get_origin(p) is Literal:
params.extend(_unique(flatten_literal_params(p.__args__)))
else:
params.append(p)
return tuple(params)


def normalise_optional_params(parameters: Iterable[Any]) -> Tuple[Any, ...]:
none_cls = type(None)
return (*tuple(p for p in parameters if p is not none_cls), none_cls)
Expand Down Expand Up @@ -1237,8 +1219,6 @@ def evaluate_annotation(
except ValueError:
pass
if origin is Literal:
if not PY_310:
args = flatten_literal_params(tp.__args__)
implicit_str = False
is_literal = True

Expand Down
2 changes: 1 addition & 1 deletion docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ in creating applications that utilise the Discord API.
Prerequisites
-------------

disnake works with Python 3.9 or higher. Support for earlier versions of Python
disnake works with Python 3.10 or higher. Support for earlier versions of Python
is not provided. Python 2.7 or lower is not supported. Python 3.8 or lower is not supported.

.. _installing:
Expand Down
2 changes: 1 addition & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.9"
# requires-python = ">=3.10"
# dependencies = [
# "nox==2025.5.1",
# ]
Expand Down
6 changes: 4 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ readme = "README.md"
authors = [
{ name = "Disnake Development" }
]
requires-python = ">=3.9"
requires-python = ">=3.10"
keywords = ["disnake", "discord", "discord api"]
license = { text = "MIT" }
dependencies = [
Expand All @@ -25,7 +25,6 @@ classifiers = [
"Natural Language :: English",
"Operating System :: OS Independent",
# it is important that the python classifiers are sorted in the sequential order
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand Down Expand Up @@ -214,6 +213,9 @@ ignore = [
"UP006",
"UP035",
"FURB188",
# py 3.10 bump
"UP007",
"UP045",
]

[tool.ruff.lint.per-file-ignores]
Expand Down
4 changes: 3 additions & 1 deletion tests/test_colour.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ def test_from_rgb(value: int, parts: Tuple[int, int, int]) -> None:
def test_from_hsv(value: int, parts: Tuple[float, float, float]) -> None:
expected = Colour(value)
col = Colour.from_hsv(*parts)
assert all(math.isclose(a, b, abs_tol=1) for a, b in zip(expected.to_rgb(), col.to_rgb()))
assert all(
math.isclose(a, b, abs_tol=1) for a, b in zip(expected.to_rgb(), col.to_rgb(), strict=True)
)


def test_alias() -> None:
Expand Down
19 changes: 2 additions & 17 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
# non-3.12 tests shouldn't be using this
from typing import TypeAliasType

NoneType = type(None)


def test_missing() -> None:
assert utils.MISSING != utils.MISSING
Expand Down Expand Up @@ -749,23 +751,6 @@ def test_as_chunks_size(max_size: int) -> None:
utils.as_chunks(iter([]), max_size)


@pytest.mark.parametrize(
("params", "expected"),
[
([], ()),
([disnake.CommandInter, int, Optional[str]], (disnake.CommandInter, int, Optional[str])),
# check flattening + deduplication (both of these are done automatically in 3.9.1+)
([float, Literal[1, 2, Literal[3, 4]], Literal["a", "bc"]], (float, 1, 2, 3, 4, "a", "bc")), # noqa: RUF041
([Literal[1, 1, 2, 3, 3]], (1, 2, 3)),
],
)
def test_flatten_literal_params(params, expected) -> None:
assert utils.flatten_literal_params(params) == expected


NoneType = type(None)


@pytest.mark.parametrize(
("params", "expected"),
[([NoneType], (NoneType,)), ([NoneType, int, NoneType, float], (int, float, NoneType))],
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/test_action_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def test_rows_from_message(self) -> None:

assert len(result) == len(rows)
# compare component types and IDs
for actual, expected in zip(result, rows):
for actual, expected in zip(result, rows, strict=False):
assert [(type(c), c.custom_id) for c in actual] == [
(type(c), c.custom_id) for c in expected
]
Expand Down Expand Up @@ -188,7 +188,7 @@ def test_walk_components(self) -> None:

expected = [(row, component) for row in rows for component in row.children]
for (act_row, act_cmp), (exp_row, exp_cmp) in zip(
ActionRow.walk_components(rows), expected
ActionRow.walk_components(rows), expected, strict=False
):
# test mutation (rows)
# (remove row below the one containing select1)
Expand Down