From 090dbf06cee8bf730edf14907609dc6512d7b35b Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Tue, 21 Feb 2023 00:39:08 -0500 Subject: [PATCH 01/12] feat: migrate build backend to hatchling --- MANIFEST.in | 8 -------- pyproject.toml | 17 +++++++++++------ setup.py | 36 ------------------------------------ 3 files changed, 11 insertions(+), 50 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 setup.py diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 462660ad53..0000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,8 +0,0 @@ -include README.md -include LICENSE -include disnake/bin/* -include disnake/py.typed -include disnake/ext/commands/py.typed -include disnake/ext/tasks/py.typed -global-exclude *.py[cod] -exclude pdm.lock diff --git a/pyproject.toml b/pyproject.toml index 954a33b2b7..7f1c1e3604 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ # SPDX-License-Identifier: MIT [build-system] -requires = ["setuptools>=61"] -build-backend = "setuptools.build_meta" +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" [project] name = "disnake" @@ -104,10 +104,6 @@ build = [ "twine~=6.1", ] -[tool.setuptools.packages.find] -where = ["."] -include = ["disnake*"] - [tool.nox] script-venv-backend = "uv|virtualenv" @@ -124,6 +120,15 @@ pyright = { cmd = "nox -Rs pyright --", help = "Run pyright" } setup_env = { cmd = "{pdm} run noxfile.py -s dev", help = "Set up the local environment and all dependencies" } test = { cmd = "nox -Rs test --", help = "Run pytest" } +[tool.hatch.build] +include = [ + "disnake/", +] + +[tool.hatch.version] +source = "vcs" +fallback-version = "0.0.0" + [tool.ruff] line-length = 100 target-version = "py38" diff --git a/setup.py b/setup.py deleted file mode 100644 index 0f6db17d46..0000000000 --- a/setup.py +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: MIT - -import re - -from setuptools import setup - -version = "" -with open("disnake/__init__.py", encoding="utf-8") as f: - version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1) # type: ignore - -if not version: - raise RuntimeError("version is not set") - -if version.endswith(("a", "b", "rc")): - # append version identifier based on commit count - try: - import subprocess # noqa: TID251 - - p = subprocess.Popen( - ["git", "rev-list", "--count", "HEAD"], stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - out, err = p.communicate() - if out: - version += out.decode("utf-8").strip() - p = subprocess.Popen( - ["git", "rev-parse", "--short", "HEAD"], stdout=subprocess.PIPE, stderr=subprocess.PIPE - ) - out, err = p.communicate() - if out: - version += "+g" + out.decode("utf-8").strip() - except Exception: - pass - -setup( - version=version, -) From 7cbf902bd09e338b5e40d92d1da40e5fd2f599a5 Mon Sep 17 00:00:00 2001 From: arielle Date: Fri, 5 Sep 2025 06:06:57 -0400 Subject: [PATCH 02/12] fix: use the version from disnake/__init__.py --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7f1c1e3604..f57b82496b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT [build-system] -requires = ["hatchling", "hatch-vcs"] +requires = ["hatchling"] build-backend = "hatchling.build" [project] @@ -126,8 +126,8 @@ include = [ ] [tool.hatch.version] -source = "vcs" -fallback-version = "0.0.0" +path = "disnake/__init__.py" +pattern = '__version__ = "(?P.+)"' [tool.ruff] line-length = 100 From 22a63ae3ecb44f3cc1ad947f345ceb6424856997 Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Sat, 23 Aug 2025 19:34:17 -0400 Subject: [PATCH 03/12] feat: add partial dynamic versioning support (not yet backwards compat) --- .gitattributes | 2 +- .github/workflows/lint-test.yml | 5 ++++ .github/workflows/release.yaml | 3 +++ .gitignore | 1 + disnake/__init__.py | 20 ++++----------- disnake/_version.pyi | 14 +++++++++++ pyproject.toml | 43 ++++++++++++++++++++++++++++++--- 7 files changed, 69 insertions(+), 19 deletions(-) create mode 100644 disnake/_version.pyi diff --git a/.gitattributes b/.gitattributes index 4630853702..c6426a5028 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,3 @@ # force LF for pyproject to make hashFiles in CI consistent (windows <3) # (see https://github.com/actions/runner/issues/498) -pyproject.toml text eol=lf +pyproject.toml text eol=lf export-subst diff --git a/.github/workflows/lint-test.yml b/.github/workflows/lint-test.yml index 36c58e2fa4..3e4817ee43 100644 --- a/.github/workflows/lint-test.yml +++ b/.github/workflows/lint-test.yml @@ -99,6 +99,8 @@ jobs: - lint steps: - uses: actions/checkout@v4 + with: + fetch-depth: '0' - name: Set up environment id: setup-env @@ -176,6 +178,9 @@ jobs: - lint steps: - uses: actions/checkout@v4 + with: + fetch-depth: '0' + - name: Set up environment id: setup diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 480b6cc996..4b2732483e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -18,6 +18,9 @@ jobs: steps: - uses: actions/checkout@v4 + with: + fetch-depth: '0' + - name: Set up environment id: setup diff --git a/.gitignore b/.gitignore index d5b3a7975b..ef0400f930 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ __pypackages__/ .pdm.toml .pdm-python pdm.lock +disnake/_version.py diff --git a/disnake/__init__.py b/disnake/__init__.py index 92eae6bec7..fb27d3703b 100644 --- a/disnake/__init__.py +++ b/disnake/__init__.py @@ -14,14 +14,17 @@ __author__ = "Rapptz, EQUENOS" __license__ = "MIT" __copyright__ = "Copyright 2015-present Rapptz, 2021-present EQUENOS" -__version__ = "2.12.0a" __path__ = __import__("pkgutil").extend_path(__path__, __name__) import logging -from typing import Literal, NamedTuple from . import abc as abc, opus as opus, ui as ui, utils as utils # explicitly re-export modules +from ._version import ( + VersionInfo, # pyright: ignore[reportUnusedImport] # noqa: F401 + __version__, # noqa: F401 + version_info, # pyright: ignore[reportUnusedImport] # noqa: F401 +) from .activity import * from .app_commands import * from .appinfo import * @@ -77,17 +80,4 @@ from .welcome_screen import * from .widget import * - -class VersionInfo(NamedTuple): - major: int - minor: int - micro: int - releaselevel: Literal["alpha", "beta", "candidate", "final"] - serial: int - - -# fmt: off -version_info: VersionInfo = VersionInfo(major=2, minor=12, micro=0, releaselevel="alpha", serial=0) -# fmt: on - logging.getLogger(__name__).addHandler(logging.NullHandler()) diff --git a/disnake/_version.pyi b/disnake/_version.pyi new file mode 100644 index 0000000000..a935e0ebb4 --- /dev/null +++ b/disnake/_version.pyi @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: MIT + +from typing import Literal, NamedTuple + +__version__: str + +class VersionInfo(NamedTuple): + major: int + minor: int + micro: int + releaselevel: Literal["alpha", "beta", "candidate", "final"] + serial: int + +version_info: VersionInfo diff --git a/pyproject.toml b/pyproject.toml index f57b82496b..276001cbf0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT [build-system] -requires = ["hatchling"] +requires = ["hatchling", "versioningit>=3.3.0"] build-backend = "hatchling.build" [project] @@ -124,10 +124,47 @@ test = { cmd = "nox -Rs test --", help = "Run pytest" } include = [ "disnake/", ] +artifacts = ["disnake/_version.py"] [tool.hatch.version] -path = "disnake/__init__.py" -pattern = '__version__ = "(?P.+)"' +source = "versioningit" + +[tool.versioningit.vcs] +method = "git-archive" +describe-subst = "$Format:%(describe:tags,match=v*)$" + +[tool.versioningit.format] +distance = "{base_version}+{distance}.{vcs}{rev}" +dirty = "{base_version}+d{build_date:%Y%m%d}" +distance-dirty = "{base_version}.a{distance}+{vcs}{rev}.d{build_date:%Y%m%d}" + +[tool.versioningit.template-fields.version-tuple] +split-on = '^(\d+)\.(\d+)\.(\d+)\.([a-zA-Z])(\d+)(?:.\d+)?' + + +[tool.versioningit.write] +file = "disnake/_version.py" +template = """ +# SPDX-License-Identifier: MIT + +from typing import Literal, NamedTuple + +__version__ = "{version}" + + +class VersionInfo(NamedTuple): + major: int + minor: int + micro: int + releaselevel: Literal["alpha", "beta", "candidate", "final"] + serial: int + + +# fmt: off +version_info: VersionInfo = VersionInfo(*{version_tuple}[:5]) +# fmt: on + +""" [tool.ruff] line-length = 100 From 138452288f9a3f16e731ae5e5a4bc9507d055f24 Mon Sep 17 00:00:00 2001 From: arielle Date: Tue, 26 Aug 2025 22:10:59 -0400 Subject: [PATCH 04/12] fix: version back compat --- pyproject.toml | 18 +++++++-------- scripts/versioning.py | 54 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 scripts/versioning.py diff --git a/pyproject.toml b/pyproject.toml index 276001cbf0..caf5198808 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MIT [build-system] -requires = ["hatchling", "versioningit>=3.3.0"] +requires = ["hatchling", "versioningit>=3.3.0,<4.0", "packaging"] build-backend = "hatchling.build" [project] @@ -126,6 +126,11 @@ include = [ ] artifacts = ["disnake/_version.py"] +[tool.hatch.build.targets.sdist] +include = [ + "scripts/versioning.py" +] + [tool.hatch.version] source = "versioningit" @@ -138,9 +143,8 @@ distance = "{base_version}+{distance}.{vcs}{rev}" dirty = "{base_version}+d{build_date:%Y%m%d}" distance-dirty = "{base_version}.a{distance}+{vcs}{rev}.d{build_date:%Y%m%d}" -[tool.versioningit.template-fields.version-tuple] -split-on = '^(\d+)\.(\d+)\.(\d+)\.([a-zA-Z])(\d+)(?:.\d+)?' - +[tool.versioningit.template-fields] +method = { module = "scripts.versioning", value = "template_fields"} [tool.versioningit.write] file = "disnake/_version.py" @@ -159,11 +163,7 @@ class VersionInfo(NamedTuple): releaselevel: Literal["alpha", "beta", "candidate", "final"] serial: int - -# fmt: off -version_info: VersionInfo = VersionInfo(*{version_tuple}[:5]) -# fmt: on - +version_info: VersionInfo = VersionInfo{version_tuple} """ [tool.ruff] diff --git a/scripts/versioning.py b/scripts/versioning.py new file mode 100644 index 0000000000..0a405ff1f4 --- /dev/null +++ b/scripts/versioning.py @@ -0,0 +1,54 @@ +# SPDX-License-Identifier: MIT + +import copy +from typing import Any, Dict, Optional + +import packaging.version +import versioningit + + +def template_fields( + *, + version: str, + description: Optional[versioningit.VCSDescription], + base_version: Optional[str], + next_version: Optional[str], + params: Dict[str, Any], +) -> Dict[str, Any]: + """Implements the ``"basic"`` ``template-fields`` method""" + params = copy.deepcopy(params) + parsed_version = packaging.version.parse(version) + fields: Dict[str, Any] = {} + if description is not None: + fields.update(description.fields) + fields["branch"] = description.branch + if base_version is not None: + fields["base_version"] = base_version + if next_version is not None: + fields["next_version"] = next_version + fields["version"] = version + + releaselevels = { + "a": "alpha", + "b": "beta", + "rc": "candidate", + "": "final", + } + + if parsed_version.pre: + releaselevel = releaselevels.get(parsed_version.pre[0], "final") + else: + releaselevel = "final" + + fields["version_tuple"] = ( + parsed_version.major, + parsed_version.minor, + parsed_version.micro, + releaselevel, + parsed_version.dev or 0, + ) + try: + fields["normalized_version"] = str(packaging.version.Version(version)) + except ValueError: + fields["normalized_version"] = version + return fields From 294e2f3d99e98dcef988cdfc660dc9950125a8a8 Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Mon, 25 Aug 2025 17:44:05 -0400 Subject: [PATCH 05/12] fix: provide a fallback version when the version cannot be determined --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index caf5198808..43bb981119 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -134,6 +134,9 @@ include = [ [tool.hatch.version] source = "versioningit" +[tool.versioningit] +default-version = "0.0.0" + [tool.versioningit.vcs] method = "git-archive" describe-subst = "$Format:%(describe:tags,match=v*)$" From a3e98d7605d214b7db72fe70a631f458fcce8beb Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Sat, 25 Feb 2023 20:30:38 -0500 Subject: [PATCH 06/12] fix: use importlib.metadata for docs building --- docs/conf.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 40b4b3dc7d..b777c559b7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -12,6 +12,7 @@ # All configuration values have a default; values that are commented out # serve to show the default. +import importlib.metadata import importlib.util import inspect import os @@ -106,14 +107,10 @@ # |version| and |release|, also used in various other places throughout the # built documents. # -# The short X.Y version. - -version = "" -with open("../disnake/__init__.py") as f: - version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', f.read(), re.MULTILINE).group(1) # type: ignore - # The full version, including alpha/beta/rc tags. -release = version +release = importlib.metadata.version("disnake") +# The short X.Y version. +version = ".".join(release.split(".")[:2]) _IS_READTHEDOCS = bool(os.getenv("READTHEDOCS")) From cc0b2307503cef820b7670e51e3f7d3a8e2a7e9f Mon Sep 17 00:00:00 2001 From: arielle Date: Wed, 27 Aug 2025 02:27:39 -0400 Subject: [PATCH 07/12] fix: show the next version on the docs changelog --- docs/conf.py | 6 ++++++ docs/whats_new.rst | 2 +- pyproject.toml | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index b777c559b7..6ccb5c64db 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,6 +21,7 @@ import sys from typing import Any, Dict, Optional +import versioningit from sphinx.application import Sphinx # If extensions (or modules to document with autodoc) are in another directory, @@ -112,6 +113,11 @@ # The short X.Y version. version = ".".join(release.split(".")[:2]) +next_version = versioningit.get_next_version(os.path.abspath("..")) + +rst_prolog += f""" +.. |next_version| replace:: {next_version} +""" _IS_READTHEDOCS = bool(os.getenv("READTHEDOCS")) diff --git a/docs/whats_new.rst b/docs/whats_new.rst index 3f0cafccaf..d964efb579 100644 --- a/docs/whats_new.rst +++ b/docs/whats_new.rst @@ -13,7 +13,7 @@ Changelog This page keeps a detailed human friendly rendering of what's new and changed in specific versions. Please see :ref:`version_guarantees` for more information. -.. towncrier-draft-entries:: |release| [UNRELEASED] +.. towncrier-draft-entries:: |next_version| [UNRELEASED] .. towncrier release notes start diff --git a/pyproject.toml b/pyproject.toml index 43bb981119..1d7df7232f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,7 @@ docs = [ "towncrier==23.6.0", "sphinx-notfound-page==0.8.3", "sphinxext-opengraph==0.9.1", + "versioningit>=3.3.0", ] [dependency-groups] From d2eb4b7bbbdb0cd85234329fc0d80f95a2d5db83 Mon Sep 17 00:00:00 2001 From: onerandomusername Date: Thu, 4 Sep 2025 18:48:40 -0400 Subject: [PATCH 08/12] fix: build on rtd --- .readthedocs.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index 6cc4e82301..ac6730eeea 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -7,6 +7,9 @@ build: os: ubuntu-24.04 tools: python: "3.8" + jobs: + post_checkout: + - git fetch --tags || true sphinx: configuration: docs/conf.py fail_on_warning: false From 781cc75475b0f770d640ba7be37c6bd22676ba48 Mon Sep 17 00:00:00 2001 From: arielle Date: Tue, 26 Aug 2025 22:56:53 -0400 Subject: [PATCH 09/12] chore: add changelog --- changelog/1323.misc.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/1323.misc.rst diff --git a/changelog/1323.misc.rst b/changelog/1323.misc.rst new file mode 100644 index 0000000000..d6b1d715ff --- /dev/null +++ b/changelog/1323.misc.rst @@ -0,0 +1 @@ +Use hatchling and versioningit for building disnake rather than using setuptools. From 28ab5b2d664bd757d08c31766317a62366dc4ff4 Mon Sep 17 00:00:00 2001 From: arielle Date: Sat, 13 Sep 2025 01:14:11 -0400 Subject: [PATCH 10/12] fix: drop check-manifest --- .github/workflows/lint-test.yml | 4 ---- noxfile.py | 8 -------- pyproject.toml | 21 --------------------- 3 files changed, 33 deletions(-) diff --git a/.github/workflows/lint-test.yml b/.github/workflows/lint-test.yml index 3e4817ee43..9740cf65a8 100644 --- a/.github/workflows/lint-test.yml +++ b/.github/workflows/lint-test.yml @@ -193,10 +193,6 @@ jobs: run: | nox -s slotscheck - - name: Run check-manifest - if: (success() || failure()) && steps.setup.outcome == 'success' - run: nox -s check-manifest - # This only runs if the previous steps were successful, no point in running it otherwise - name: Try building package run: | diff --git a/noxfile.py b/noxfile.py index c4745cd3cc..eda13938e7 100755 --- a/noxfile.py +++ b/noxfile.py @@ -23,7 +23,6 @@ nox.options.reuse_venv = "yes" nox.options.sessions = [ "lint", - "check-manifest", "slotscheck", "pyright", "test", @@ -146,13 +145,6 @@ def lint(session: nox.Session) -> None: session.run("pre-commit", "run", "--all-files", *session.posargs) -@nox.session(name="check-manifest") -def check_manifest(session: nox.Session) -> None: - """Run check-manifest.""" - install_deps(session, project=False, groups=["tools"]) - session.run("check-manifest", "-v") - - @nox.session def slotscheck(session: nox.Session) -> None: """Run slotscheck.""" diff --git a/pyproject.toml b/pyproject.toml index 1d7df7232f..141794a44a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,6 @@ nox = [ tools = [ "pre-commit~=3.0", "slotscheck~=0.16.4", - "check-manifest==0.49", "ruff==0.12.12", ] changelog = [ @@ -451,23 +450,3 @@ exclude_lines = [ "^\\s*raise NotImplementedError$", "^\\s*\\.\\.\\.$", ] - - -[tool.check-manifest] -ignore = [ - # CI - ".pre-commit-config.yaml", - ".readthedocs.yml", - ".libcst.codemod.yaml", - "noxfile.py", - # docs - "CONTRIBUTING.md", - "RELEASE.md", - "assets/**", - "changelog/**", - "docs/**", - "examples/**", - # tests - "tests/**", - "scripts/**", -] From b4b12cef007491ef998daaa907a3432ec445127b Mon Sep 17 00:00:00 2001 From: arielle Date: Fri, 26 Sep 2025 09:40:58 -0400 Subject: [PATCH 11/12] no more check-manifest --- noxfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index e5b0da2741..77305725c8 100755 --- a/noxfile.py +++ b/noxfile.py @@ -77,7 +77,7 @@ def __post_init__(self) -> None: ExecutionGroup( sessions=("pyright",), python=python, - pyright_paths=("disnake", "tests", "examples", "noxfile.py", "setup.py"), + pyright_paths=("disnake", "tests", "examples", "noxfile.py"), project=True, # FIXME: orjson doesn't yet support python 3.14, remove once we migrate to uv and have version-specific locks extras=("speed", "voice") if python not in EXPERIMENTAL_PYTHON_VERSIONS else ("voice",), @@ -100,7 +100,7 @@ def __post_init__(self) -> None: ), # the other sessions, they don't need pyright, but they need to run ExecutionGroup( - sessions=("lint", "slotscheck", "check-manifest"), + sessions=("lint", "slotscheck"), groups=("tools",), ), # build @@ -261,7 +261,7 @@ def slotscheck(session: nox.Session) -> None: session.run("python", "-m", "slotscheck", "--verbose", "-m", "disnake") -@nox.session(requires=["check-manifest"]) +@nox.session() def build(session: nox.Session) -> None: """Build a dist.""" install_deps(session) From 53f6902022c17c9ff8b0f5650ce469d3050cebe6 Mon Sep 17 00:00:00 2001 From: arielle Date: Fri, 26 Sep 2025 12:52:39 -0400 Subject: [PATCH 12/12] fix: typing --- noxfile.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index 77305725c8..25dd47c6b7 100755 --- a/noxfile.py +++ b/noxfile.py @@ -82,7 +82,7 @@ def __post_init__(self) -> None: # FIXME: orjson doesn't yet support python 3.14, remove once we migrate to uv and have version-specific locks extras=("speed", "voice") if python not in EXPERIMENTAL_PYTHON_VERSIONS else ("voice",), groups=("test", "nox"), - dependencies=("setuptools", "pytz", "requests"), # needed for type checking + dependencies=("pytz", "requests"), # needed for type checking ) for python in ALL_PYTHONS ), @@ -95,7 +95,7 @@ def __post_init__(self) -> None: # codemodding and pyright ExecutionGroup( sessions=("codemod", "autotyping", "pyright"), - pyright_paths=("scripts",), + pyright_paths=("scripts/codemods", "scripts/ci"), groups=("codemod",), ), # the other sessions, they don't need pyright, but they need to run @@ -105,8 +105,10 @@ def __post_init__(self) -> None: ), # build ExecutionGroup( - sessions=("build",), + sessions=("build", "pyright"), + pyright_paths=("scripts/versioning.py",), groups=("build",), + dependencies=(PYPROJECT["build-system"]["requires"]), ), ## testing *(