From 5e9ab6cede2aef43f0fe939f9ae089bfa050149a Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 18:34:53 +0100 Subject: [PATCH 01/11] Switch to hatchling --- .gitignore | 34 +++++++++--------- MANIFEST.in | 20 ----------- pyproject.toml | 75 ++++++++++++++++++++++++++++++++++----- setup.py | 66 ---------------------------------- src/towncrier/_version.py | 4 ++- 5 files changed, 87 insertions(+), 112 deletions(-) delete mode 100644 MANIFEST.in delete mode 100644 setup.py diff --git a/.gitignore b/.gitignore index c44127a6..a5365597 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,25 @@ -*.egg-info/ +*.lock *.o *.py[co] +*.pyproj *.so -_trial_temp*/ -build/ -dropin.cache -doc/ -docs/_build/ -dist/ -venv/ -htmlcov/ -.coverage *~ -*.lock -apidocs/ -.vs/ -*.pyproj .DS_Store -.eggs -.nox/ +.coverage .coverage.* -.vscode +.direnv .idea +.mypy_cache +.nox/ +.pytest_cache .python-version +.vs/ +.vscode +_trial_temp*/ +apidocs/ +dist/ +doc/ +docs/_build/ +dropin.cache +htmlcov/ +venv/ diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 9494555b..00000000 --- a/MANIFEST.in +++ /dev/null @@ -1,20 +0,0 @@ -include *.rst -include .coveragerc -include LICENSE -include CODE_OF_CONDUCT.md -include pyproject.toml -include noxfile.py -include *.yaml -include .git-blame-ignore-revs -include .flake8 -recursive-include src *.rst - -exclude bin -exclude admin -exclude src/towncrier/newsfragments -exclude .readthedocs.yml - -recursive-exclude bin * -recursive-exclude admin * -recursive-exclude src/towncrier/newsfragments * -recursive-exclude docs * diff --git a/pyproject.toml b/pyproject.toml index c2145ba6..f61c3e1c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,70 @@ +[build-system] +requires = [ + "hatchling ~= 1.12.2", + "wheel ~= 0.38.4", + "incremental == 22.10.0", +] +build-backend = "hatchling.build" + +[project] +dynamic = ["version"] +name = "towncrier" +description = "Building newsfiles for your project." +readme = "README.rst" +license = "MIT" +classifiers = [ + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: POSIX :: Linux", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +requires-python = ">=3.7" +dependencies = [ + "click", + "click-default-group", + "incremental", + "jinja2", + "setuptools", + "tomli; python_version<'3.11'", +] + +[project.optional-dependencies] +dev= [ + "packaging", + "sphinx >= 5", + "furo", + "twisted", +] + +[project.scripts] +towncrier = "towncrier._shell:cli" + +[project.urls] +Documentation= "https://towncrier.readthedocs.io/" +Chat = "https://web.libera.chat/?channels=%23twisted" +"Mailing list"= "https://mail.python.org/mailman3/lists/twisted.python.org/" +Issues = "https://github.com/twisted/towncrier/issues" +Repository = "https://github.com/twisted/towncrier" +Tests = "https://github.com/twisted/towncrier/actions?query=branch%3Atrunk" +Coverage = "https://codecov.io/gh/twisted/towncrier" +Distribution = "https://pypi.org/project/towncrier" + + +[tool.hatch.version] +source = "code" +path = "src/towncrier/_version.py" +expression = "_hatchling_version" + + [tool.towncrier] package = "towncrier" package_dir = "src" @@ -77,14 +144,6 @@ module = 'incremental' ignore_missing_imports = true -[build-system] -requires = [ - "setuptools ~= 44.1.1", - "wheel ~= 0.36.2", - "incremental == 22.10.0", -] -build-backend = "setuptools.build_meta" - [tool.coverage.run] parallel = true branch = true diff --git a/setup.py b/setup.py deleted file mode 100644 index c6c11691..00000000 --- a/setup.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python - - -# If incremental is not present then setuptools just silently uses v0.0.0 so -# let's import it and fail instead. -import incremental # noqa - -from setuptools import find_packages, setup - - -setup( - name="towncrier", - url="https://github.com/twisted/towncrier", - project_urls={ - "Documentation": "https://towncrier.readthedocs.io/", - "Chat": "https://web.libera.chat/?channels=%23twisted", - "Mailing list": "https://mail.python.org/mailman3/lists/twisted.python.org/", - "Issues": "https://github.com/twisted/towncrier/issues", - "Repository": "https://github.com/twisted/towncrier", - "Tests": "https://github.com/twisted/towncrier/actions?query=branch%3Atrunk", - "Coverage": "https://codecov.io/gh/twisted/towncrier", - "Distribution": "https://pypi.org/project/towncrier", - }, - classifiers=[ - "Intended Audience :: Developers", - "License :: OSI Approved :: MIT License", - "Operating System :: POSIX :: Linux", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - ], - use_incremental=True, - python_requires=">=3.7", - install_requires=[ - "click", - "click-default-group", - "incremental", - "jinja2", - "setuptools", - "tomli; python_version<'3.11'", - ], - extras_require={ - "dev": [ - "packaging", - "sphinx >= 5", - "furo", - "twisted", - ], - }, - package_dir={"": "src"}, - packages=find_packages("src"), - license="MIT", - zip_safe=False, - include_package_data=True, - description="Building newsfiles for your project.", - long_description=open("README.rst").read(), - long_description_content_type="text/x-rst", - entry_points={"console_scripts": ["towncrier = towncrier._shell:cli"]}, -) diff --git a/src/towncrier/_version.py b/src/towncrier/_version.py index 40c39c27..9515cab3 100644 --- a/src/towncrier/_version.py +++ b/src/towncrier/_version.py @@ -9,4 +9,6 @@ __version__ = Version("towncrier", 22, 12, 1, dev=0) -__all__ = ["__version__"] +_hatchling_version = __version__.short() + +__all__ = ["__version__", "_hatchling_version"] From f968cb07607d27baae491bb5789118fdb83a137d Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 18:43:23 +0100 Subject: [PATCH 02/11] Add news fragment --- src/towncrier/newsfragments/472.misc | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/towncrier/newsfragments/472.misc diff --git a/src/towncrier/newsfragments/472.misc b/src/towncrier/newsfragments/472.misc new file mode 100644 index 00000000..e69de29b From a021ea0409dd14832b38c6a15d43a0defad868ed Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 18:50:52 +0100 Subject: [PATCH 03/11] Duplicate exclude pattern from MANIFEST.in Also rename .readthedocs.yml to its un-deprecated name --- .readthedocs.yml => .readthedocs.yaml | 0 pyproject.toml | 9 +++++++++ 2 files changed, 9 insertions(+) rename .readthedocs.yml => .readthedocs.yaml (100%) diff --git a/.readthedocs.yml b/.readthedocs.yaml similarity index 100% rename from .readthedocs.yml rename to .readthedocs.yaml diff --git a/pyproject.toml b/pyproject.toml index f61c3e1c..6c2780d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,15 @@ source = "code" path = "src/towncrier/_version.py" expression = "_hatchling_version" +[tool.hatch.build] +exclude = [ + "admin", + "bin", + "docs", + ".readthedocs.yaml", + "src/towncrier/newsfragments", +] + [tool.towncrier] package = "towncrier" From 0a6d10ff8ebcd4fe0c0aa6282edac114e48c9f87 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 18:51:48 +0100 Subject: [PATCH 04/11] Ignore a few more common patterns --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index a5365597..fa4a8cd0 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ .coverage .coverage.* .direnv +.envrc .idea .mypy_cache .nox/ @@ -15,6 +16,7 @@ .python-version .vs/ .vscode +Justfile _trial_temp*/ apidocs/ dist/ @@ -22,4 +24,5 @@ doc/ docs/_build/ dropin.cache htmlcov/ +tmp/ venv/ From 2f2a772ede91ce468def9f833561ce3319b741f6 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 18:53:21 +0100 Subject: [PATCH 05/11] Style --- pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6c2780d2..eee66eca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ dependencies = [ ] [project.optional-dependencies] -dev= [ +dev = [ "packaging", "sphinx >= 5", "furo", @@ -49,9 +49,9 @@ dev= [ towncrier = "towncrier._shell:cli" [project.urls] -Documentation= "https://towncrier.readthedocs.io/" +Documentation = "https://towncrier.readthedocs.io/" Chat = "https://web.libera.chat/?channels=%23twisted" -"Mailing list"= "https://mail.python.org/mailman3/lists/twisted.python.org/" +"Mailing list" = "https://mail.python.org/mailman3/lists/twisted.python.org/" Issues = "https://github.com/twisted/towncrier/issues" Repository = "https://github.com/twisted/towncrier" Tests = "https://github.com/twisted/towncrier/actions?query=branch%3Atrunk" From b10784d5fe754b869ae061dbae2817d1a247e6da Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 18:56:22 +0100 Subject: [PATCH 06/11] Fix build (no need for check-manifest anymore) --- noxfile.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/noxfile.py b/noxfile.py index 38b65b98..30c35431 100644 --- a/noxfile.py +++ b/noxfile.py @@ -87,11 +87,10 @@ def docs(session: nox.Session) -> None: @nox.session def build(session: nox.Session) -> None: - session.install("build", "check-manifest>=0.44", "twine") + session.install("build", "twine") - session.run("check-manifest", "--verbose") # If no argument is passed, build builds an sdist and then a wheel from # that sdist. session.run("python", "-m", "build") - session.run("twine", "check", "dist/*") + session.run("twine", "check", "--strict", "dist/*") From eccdd19b58f28e80d2b5e809364d677dbfaf7310 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 18:59:57 +0100 Subject: [PATCH 07/11] Stop checking manifest in ci too --- .github/workflows/ci.yml | 3 --- CONTRIBUTING.rst | 2 +- noxfile.py | 6 ------ 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c858948..c58a1213 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -160,9 +160,6 @@ jobs: - name: Check Newsfragment nox: check_newsfragment run-if: ${{ github.head_ref != 'pre-commit-ci-update-config' }} - - name: Check package manifest - nox: check_manifest - run-if: true - name: Check mypy nox: typecheck run-if: true diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index e69f970b..661f22e4 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -128,7 +128,7 @@ The following list contains some ways how to run the test suite: * To run some quality checks before you create the pull request, we recommend using this call:: - $ nox -e pre_commit check_manifest check_newsfragment + $ nox -e pre_commit check_newsfragment * Or enable `pre-commit` as a git hook:: diff --git a/noxfile.py b/noxfile.py index 30c35431..607f89f9 100644 --- a/noxfile.py +++ b/noxfile.py @@ -55,12 +55,6 @@ def check_newsfragment(session: nox.Session) -> None: session.run("python", "-m", "towncrier.check", "--compare-with", "origin/trunk") -@nox.session -def check_manifest(session: nox.Session) -> None: - session.install("check-manifest") - session.run("check-manifest") - - @nox.session def typecheck(session: nox.Session) -> None: session.install(".", "mypy", "types-setuptools") From 9cccfd44e8b825775043c6fb3dab7fa52eb8e437 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 19:02:25 +0100 Subject: [PATCH 08/11] Style --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index eee66eca..32a2c3c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,6 +6,7 @@ requires = [ ] build-backend = "hatchling.build" + [project] dynamic = ["version"] name = "towncrier" From ed205d3e6f81300e02e64dd1ba9e8ac8b2235617 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 19:08:32 +0100 Subject: [PATCH 09/11] Update src/towncrier/_version.py Co-authored-by: Adi Roiban --- src/towncrier/_version.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/towncrier/_version.py b/src/towncrier/_version.py index 9515cab3..a2529bf2 100644 --- a/src/towncrier/_version.py +++ b/src/towncrier/_version.py @@ -9,6 +9,8 @@ __version__ = Version("towncrier", 22, 12, 1, dev=0) +# The version is exposed in string format to be +# available for the hatching build tools. _hatchling_version = __version__.short() __all__ = ["__version__", "_hatchling_version"] From e3987cc45f32fd30e53140035cc538ab2e4b0723 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 19:37:11 +0100 Subject: [PATCH 10/11] Deprecate towncrier.__version__ --- src/towncrier/__init__.py | 22 ++++++++++++++++++++-- src/towncrier/test/test_packaging.py | 22 ++++++++++++++++++++++ src/towncrier/test/test_project.py | 14 ++++++++++++-- 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 src/towncrier/test/test_packaging.py diff --git a/src/towncrier/__init__.py b/src/towncrier/__init__.py index ab8ced7c..d9d1d5bc 100644 --- a/src/towncrier/__init__.py +++ b/src/towncrier/__init__.py @@ -7,7 +7,25 @@ from __future__ import annotations -from ._version import __version__ - __all__ = ["__version__"] + + +def __getattr__(name: str) -> str: + + if name != "__version__": + raise AttributeError(f"module {__name__} has no attribute {name}") + + import warnings + + from ._version import __version__ + + warnings.warn( + "Accessing towncrier.__version__ is deprecated and will be " + "removed in a future release. Use importlib.metadata directly " + "to query for towncrier's packaging metadata.", + DeprecationWarning, + stacklevel=2, + ) + + return __version__ diff --git a/src/towncrier/test/test_packaging.py b/src/towncrier/test/test_packaging.py new file mode 100644 index 00000000..3355ad51 --- /dev/null +++ b/src/towncrier/test/test_packaging.py @@ -0,0 +1,22 @@ +# Copyright (c) Amber Brown, 2015 +# See LICENSE for details. + +from incremental import Version +from twisted.trial.unittest import TestCase + +from towncrier._version import _hatchling_version + + +class TestPackaging(TestCase): + def test_version_warning(self): + """ + Import __version__ from towncrier returns an Incremental version object + and raises a warning. + """ + with self.assertWarnsRegex( + DeprecationWarning, "Accessing towncrier.__version__ is deprecated.*" + ): + from towncrier import __version__ + + self.assertIsInstance(__version__, Version) + self.assertEqual(_hatchling_version, __version__.short()) diff --git a/src/towncrier/test/test_project.py b/src/towncrier/test/test_project.py index e55a3098..4b420648 100644 --- a/src/towncrier/test/test_project.py +++ b/src/towncrier/test/test_project.py @@ -55,8 +55,18 @@ def test_incremental(self): """ pkg = "../src" - self.assertEqual(metadata_version("towncrier"), get_version(pkg, "towncrier")) - self.assertEqual("towncrier", get_project_name(pkg, "towncrier")) + with self.assertWarnsRegex( + DeprecationWarning, "Accessing towncrier.__version__ is deprecated.*" + ): + version = get_version(pkg, "towncrier") + + with self.assertWarnsRegex( + DeprecationWarning, "Accessing towncrier.__version__ is deprecated.*" + ): + name = get_project_name(pkg, "towncrier") + + self.assertEqual(metadata_version("towncrier"), version) + self.assertEqual("towncrier", name) def _setup_missing(self): """ From 5d0af163d59964b5dff4b37c591e3df1ffa59a16 Mon Sep 17 00:00:00 2001 From: Hynek Schlawack Date: Fri, 27 Jan 2023 19:43:19 +0100 Subject: [PATCH 11/11] Fix type --- src/towncrier/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/towncrier/__init__.py b/src/towncrier/__init__.py index d9d1d5bc..01448b29 100644 --- a/src/towncrier/__init__.py +++ b/src/towncrier/__init__.py @@ -7,11 +7,13 @@ from __future__ import annotations +from incremental import Version + __all__ = ["__version__"] -def __getattr__(name: str) -> str: +def __getattr__(name: str) -> Version: if name != "__version__": raise AttributeError(f"module {__name__} has no attribute {name}")