From ec3bcda84a30d50bb872521c54df1ff7900df9be Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Sat, 16 Apr 2022 21:38:39 +0100 Subject: [PATCH] Use declarative metadata - Move to pyproject.toml metadata - Update references to `setup.py` - Use pypa/build - Update workflows and tooling --- .github/workflows/docutils-latest.yml | 2 - .github/workflows/lint.yml | 2 +- CHANGES | 4 + MANIFEST.in | 33 ---- Makefile | 2 +- pyproject.toml | 252 ++++++++++++++------------ setup.cfg | 11 -- sphinx/__init__.py | 40 ++-- tox.ini | 8 +- utils/bump_version.py | 30 +-- utils/release-checklist | 8 +- 11 files changed, 185 insertions(+), 207 deletions(-) delete mode 100644 MANIFEST.in diff --git a/.github/workflows/docutils-latest.yml b/.github/workflows/docutils-latest.yml index 91d9a4197f3..0e8029fc21b 100644 --- a/.github/workflows/docutils-latest.yml +++ b/.github/workflows/docutils-latest.yml @@ -21,8 +21,6 @@ jobs: python-version: 3 - name: Check Python version run: python --version - - name: Unpin docutils - run: sed -i -e "s/'docutils>=.*'/'docutils'/" setup.py - name: Install graphviz run: sudo apt-get install graphviz - name: Install dependencies diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5e583d7b604..4a8deb00dc3 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,6 +20,6 @@ jobs: with: python-version: 3 - name: Install dependencies - run: pip install -U tox + run: python -m pip install -U tox pip - name: Run Tox run: tox -e ${{ matrix.tool }} diff --git a/CHANGES b/CHANGES index 90ec78048fe..18294caa998 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,10 @@ Release 5.2.0 (in development) Dependencies ------------ +* #10356: Sphinx now uses declarative metadata with ``pyproject.toml`` to + create packages, using PyPA's ``build`` project as a build backend. Patch by + Adam Turner. + Incompatible changes -------------------- diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 7c2f852a81c..00000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,33 +0,0 @@ -include README.rst -include LICENSE -include AUTHORS -include CHANGES -include CHANGES.old -include CODE_OF_CONDUCT -include CONTRIBUTING.rst -include EXAMPLES - -include babel.cfg -include Makefile -include sphinx-autogen.py -include sphinx-build.py -include sphinx-quickstart.py -include sphinx-apidoc.py -include tox.ini -include sphinx/locale/.tx/config -include sphinx/py.typed - -recursive-include sphinx/templates * -recursive-include sphinx/texinputs * -recursive-include sphinx/texinputs_win * -recursive-include sphinx/themes * -recursive-include sphinx/locale *.js *.pot *.po *.mo -recursive-include sphinx/search/non-minified-js *.js -recursive-include sphinx/search/minified-js *.js -recursive-include sphinx/ext/autosummary/templates * -recursive-include tests * -recursive-include utils * - -recursive-include doc * -prune doc/_build -prune sphinx/locale/.tx diff --git a/Makefile b/Makefile index 9213820b70b..4602246d9cf 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ covertest: .PHONY: build build: - @$(PYTHON) setup.py build + @$(PYTHON) -m build . .PHONY: docs docs: diff --git a/pyproject.toml b/pyproject.toml index 4c65723aacf..7cc05fc22a7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,123 +1,135 @@ -from setuptools import find_packages, setup +[build-system] +requires = ["flit_core>=3.7"] +build-backend = "flit_core.buildapi" -import sphinx +# project metadata +[project] +name = "Sphinx" +description = "Python documentation generator" +readme = "README.rst" +urls.Changelog = "https://www.sphinx-doc.org/en/master/changes.html" +urls.Code = "https://github.com/sphinx-doc/sphinx" +urls.Download = "https://pypi.org/project/Sphinx/" +urls.Homepage = "https://www.sphinx-doc.org/" +urls."Issue tracker" = "https://github.com/sphinx-doc/sphinx/issues" +license.text = "BSD" +requires-python = ">=3.6" -with open('README.rst', encoding='utf-8') as f: - long_desc = f.read() +# Classifiers list: https://pypi.org/classifiers/ +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Environment :: Console", + "Environment :: Web Environment", + "Intended Audience :: Developers", + "Intended Audience :: Education", + "Intended Audience :: End Users/Desktop", + "Intended Audience :: Science/Research", + "Intended Audience :: System Administrators", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Framework :: Setuptools Plugin", + "Framework :: Sphinx", + "Framework :: Sphinx :: Extension", + "Framework :: Sphinx :: Theme", + "Topic :: Documentation", + "Topic :: Documentation :: Sphinx", + "Topic :: Internet :: WWW/HTTP :: Site Management", + "Topic :: Printing", + "Topic :: Software Development", + "Topic :: Software Development :: Documentation", + "Topic :: Text Processing", + "Topic :: Text Processing :: General", + "Topic :: Text Processing :: Indexing", + "Topic :: Text Processing :: Markup", + "Topic :: Text Processing :: Markup :: HTML", + "Topic :: Text Processing :: Markup :: LaTeX", + "Topic :: Utilities", +] +dependencies = [ + "sphinxcontrib-applehelp", + "sphinxcontrib-devhelp", + "sphinxcontrib-jsmath", + "sphinxcontrib-htmlhelp>=2.0.0", + "sphinxcontrib-serializinghtml>=1.1.5", + "sphinxcontrib-qthelp", + "Jinja2>=3.0", + "Pygments>=2.12", + "docutils>=0.14,<0.20", + "snowballstemmer>=2.0", + "babel>=2.9", + "alabaster>=0.7,<0.8", + "imagesize>=1.3", + "requests>=2.5.0", + "packaging>=21.0", + "importlib-metadata>=4.8; python_version < '3.10'", + "colorama>=0.4.5; sys_platform == 'win32'", +] +dynamic = ["version"] -setup( - name='Sphinx', - version=sphinx.__version__, - url='https://www.sphinx-doc.org/', - download_url='https://pypi.org/project/Sphinx/', - license='BSD', - author='Georg Brandl', - author_email='georg@python.org', - description='Python documentation generator', - long_description=long_desc, - long_description_content_type='text/x-rst', - project_urls={ - "Code": "https://github.com/sphinx-doc/sphinx", - "Changelog": "https://www.sphinx-doc.org/en/master/changes.html", - "Issue tracker": "https://github.com/sphinx-doc/sphinx/issues", - }, - zip_safe=False, - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Environment :: Web Environment', - 'Intended Audience :: Developers', - 'Intended Audience :: Education', - 'Intended Audience :: End Users/Desktop', - 'Intended Audience :: Science/Research', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: BSD License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: Implementation :: CPython', - 'Programming Language :: Python :: Implementation :: PyPy', - 'Framework :: Setuptools Plugin', - 'Framework :: Sphinx', - 'Framework :: Sphinx :: Extension', - 'Framework :: Sphinx :: Theme', - 'Topic :: Documentation', - 'Topic :: Documentation :: Sphinx', - 'Topic :: Internet :: WWW/HTTP :: Site Management', - 'Topic :: Printing', - 'Topic :: Software Development', - 'Topic :: Software Development :: Documentation', - 'Topic :: Text Processing', - 'Topic :: Text Processing :: General', - 'Topic :: Text Processing :: Indexing', - 'Topic :: Text Processing :: Markup', - 'Topic :: Text Processing :: Markup :: HTML', - 'Topic :: Text Processing :: Markup :: LaTeX', - 'Topic :: Utilities', - ], - platforms='any', - packages=find_packages(exclude=['tests', 'utils']), - package_data = { - 'sphinx': ['py.typed'], - }, - include_package_data=True, - entry_points={ - 'console_scripts': [ - 'sphinx-build = sphinx.cmd.build:main', - 'sphinx-quickstart = sphinx.cmd.quickstart:main', - 'sphinx-apidoc = sphinx.ext.apidoc:main', - 'sphinx-autogen = sphinx.ext.autosummary.generate:main', - ], - 'distutils.commands': [ - 'build_sphinx = sphinx.setup_command:BuildDoc', - ], - }, - python_requires=">=3.6", - install_requires=[ - 'sphinxcontrib-applehelp', - 'sphinxcontrib-devhelp', - 'sphinxcontrib-jsmath', - 'sphinxcontrib-htmlhelp>=2.0.0', - 'sphinxcontrib-serializinghtml>=1.1.5', - 'sphinxcontrib-qthelp', - 'Jinja2>=3.0', - 'Pygments>=2.12', - 'docutils>=0.14,<0.20', - 'snowballstemmer>=2.0', - 'babel>=2.9', - 'alabaster>=0.7,<0.8', - 'imagesize>=1.3', - 'requests>=2.5.0', - 'packaging>=21.0', - "importlib-metadata>=4.8; python_version < '3.10'", - "colorama>=0.4.5; sys_platform == 'win32'", - ], - extras_require={ - 'docs': [ - 'sphinxcontrib-websupport', - ], - 'lint': [ - 'flake8>=3.5.0', - 'flake8-comprehensions', - 'flake8-bugbear', - 'isort', - 'mypy>=0.971', - 'sphinx-lint', - 'docutils-stubs', - "types-typed-ast", - "types-requests", - ], - 'test': [ - 'pytest>=4.6', - 'html5lib', - "typed_ast; python_version < '3.8'", - 'cython', - ], - }, -) +[project.optional-dependencies] +docs = [ + "sphinxcontrib-websupport", +] +lint = [ + "flake8>=3.5.0", + "flake8-comprehensions", + "flake8-bugbear", + "isort", + "mypy>=0.971", + "sphinx-lint", + "docutils-stubs", + "types-typed-ast", + "types-requests", +] +test = [ + "pytest>=4.6", + "html5lib", + "typed_ast; python_version < '3.8'", + "cython", +] + +[[project.authors]] +name = "Georg Brandl" +email = "georg@python.org" + +[project.scripts] +sphinx-build = "sphinx.cmd.build:main" +sphinx-quickstart = "sphinx.cmd.quickstart:main" +sphinx-apidoc = "sphinx.ext.apidoc:main" +sphinx-autogen = "sphinx.ext.autosummary.generate:main" + +[project.entry-points."distutils.commands"] +build_sphinx = 'sphinx.setup_command:BuildDoc' + +[tool.flit.module] +name = "sphinx" + +[tool.flit.sdist] +include = [ + "LICENSE", + "AUTHORS", + "CHANGES", + # Documentation + "doc/", + "CODE_OF_CONDUCT", # used as an include in the Documentation + "EXAMPLES", # used as an include in the Documentation + # Tests + "tests/", + "tox.ini", + # Utilities + "utils/", + "babel.cfg", +] +exclude = [ + "doc/_build", +] diff --git a/setup.cfg b/setup.cfg index 5cc94b55c9f..c524c3c568f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,14 +1,3 @@ -[metadata] -license_files = LICENSE - -[egg_info] -tag_build = .dev -tag_date = true - -[aliases] -release = egg_info -Db '' -upload = upload --sign --identity=36580288 - [flake8] max-line-length = 95 ignore = E116,E241,E251,E741,W504,I101,B006,B023 diff --git a/sphinx/__init__.py b/sphinx/__init__.py index f036a71f789..dbc6fe36a3a 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -1,13 +1,11 @@ """The Sphinx documentation toolchain.""" # Keep this file executable as-is in Python 3! -# (Otherwise getting the version out of it from setup.py is impossible.) +# (Otherwise getting the version out of it when packaging is impossible.) import os -import subprocess import warnings from os import path -from subprocess import PIPE from .deprecation import RemovedInNextVersionWarning @@ -21,8 +19,8 @@ warnings.filterwarnings('ignore', 'The frontend.Option class .*', DeprecationWarning, module='docutils.frontend') -__version__ = '5.2.0+' -__released__ = '5.2.0' # used when Sphinx builds its own docs +__version__ = '5.2.0' +__display_version__ = __version__ # used for command line version #: Version info for better programmatic use. #: @@ -36,18 +34,22 @@ package_dir = path.abspath(path.dirname(__file__)) -__display_version__ = __version__ # used for command line version -if __version__.endswith('+'): - # try to find out the commit hash if checked out from git, and append - # it to __version__ (since we use this value from setup.py, it gets - # automatically propagated to an installed copy as well) - __display_version__ = __version__ - __version__ = __version__[:-1] # remove '+' for PEP-440 version spec. +_in_development = True +if _in_development: + # Only import subprocess if needed + import subprocess + try: - ret = subprocess.run(['git', 'show', '-s', '--pretty=format:%h'], - cwd=package_dir, - stdout=PIPE, stderr=PIPE, encoding='ascii') - if ret.stdout: - __display_version__ += '/' + ret.stdout.strip() - except Exception: - pass + ret = subprocess.run( + ['git', 'show', '-s', '--pretty=format:%h'], + cwd=package_dir, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + encoding='ascii', + ).stdout + if ret: + __display_version__ += '+/' + ret.strip() + del ret + finally: + del subprocess +del _in_development diff --git a/tox.ini b/tox.ini index 7ca990b56df..012f16a4f65 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,7 @@ [tox] minversion = 2.4.0 envlist = docs,flake8,mypy,twine,py{36,37,38,39,310},du{14,15,16,17,18,19} +isolated_build = True [testenv] usedevelop = True @@ -34,7 +35,7 @@ commands= [testenv:du-latest] commands = - python -m pip install "git+https://repo.or.cz/docutils.git#subdirectory=docutils" + python -m pip install "git+https://repo.or.cz/docutils.git#subdirectory=docutils" --no-warn-conflicts {[testenv]commands} [testenv:flake8] @@ -92,7 +93,7 @@ description = Build documentation. extras = docs -deps = +deps = sphinx-autobuild commands = sphinx-autobuild ./doc ./build/sphinx/ @@ -103,8 +104,9 @@ description = Lint package. deps = twine + build commands = - python setup.py release bdist_wheel sdist + python -m build . twine check dist/* [testenv:bindep] diff --git a/utils/bump_version.py b/utils/bump_version.py index aeaed864b7a..e2aefa842e4 100755 --- a/utils/bump_version.py +++ b/utils/bump_version.py @@ -23,19 +23,23 @@ def stringify_version(version_info, in_develop=True): def bump_version(path, version_info, in_develop=True): version = stringify_version(version_info, in_develop) - release = version - if in_develop: - version += '+' - - with open(path, 'r+', encoding='utf-8') as f: - body = f.read() - body = re.sub(r"(?<=__version__ = ')[^']+", version, body) - body = re.sub(r"(?<=__released__ = ')[^']+", release, body) - body = re.sub(r"(?<=version_info = )\(.*\)", str(version_info), body) - - f.seek(0) - f.truncate(0) - f.write(body) + + with open(path, 'r', encoding='utf-8') as f: + lines = f.read().splitlines() + + for i, line in enumerate(lines): + if line.startswith('__version__ = '): + lines[i] = f"__version__ = '{version}'" + continue + if line.startswith('version_info = '): + lines[i] = f'version_info = {version_info}' + continue + if line.startswith('_in_development = '): + lines[i] = f'_in_development = {in_develop}' + continue + + with open(path, 'w', encoding='utf-8') as f: + f.write('\n'.join(lines) + '\n') def parse_version(version): diff --git a/utils/release-checklist b/utils/release-checklist index 920c1ce8f4d..0d1733229a5 100644 --- a/utils/release-checklist +++ b/utils/release-checklist @@ -10,7 +10,7 @@ for stable releases * Check diff by ``git diff`` * ``git commit -am 'Bump to X.Y.Z final'`` * ``make clean`` -* ``python setup.py release bdist_wheel sdist`` +* ``python -m build .`` * ``twine upload dist/Sphinx-* --sign --identity [your GPG key]`` * open https://pypi.org/project/Sphinx/ and check there are no obvious errors * ``sh utils/bump_docker.sh X.Y.Z`` @@ -34,7 +34,7 @@ for first beta releases * Check diff by ``git diff`` * ``git commit -am 'Bump to X.Y.0 beta1'`` * ``make clean`` -* ``python setup.py release bdist_wheel sdist`` +* ``python -m build .`` * ``twine upload dist/Sphinx-* --sign --identity [your GPG key]`` * open https://pypi.org/project/Sphinx/ and check there are no obvious errors * ``git tag vX.Y.0b1`` @@ -62,7 +62,7 @@ for other beta releases * Check diff by ``git diff`` * ``git commit -am 'Bump to X.Y.0 betaN'`` * ``make clean`` -* ``python setup.py release bdist_wheel sdist`` +* ``python -m build .`` * ``twine upload dist/Sphinx-* --sign --identity [your GPG key]`` * open https://pypi.org/project/Sphinx/ and check there are no obvious errors * ``git tag vX.Y.0bN`` @@ -87,7 +87,7 @@ for major releases * Check diff by ``git diff`` * ``git commit -am 'Bump to X.Y.0 final'`` * ``make clean`` -* ``python setup.py release bdist_wheel sdist`` +* ``python -m build .`` * ``twine upload dist/Sphinx-* --sign --identity [your GPG key]`` * open https://pypi.org/project/Sphinx/ and check there are no obvious errors * ``sh utils/bump_docker.sh X.Y.Z``