From 60a44388cdd9645ed5da268a858f78101b755dc1 Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Wed, 15 Jan 2025 09:09:26 +0100 Subject: [PATCH] Update Python version support. (#24) * Drop support for Python 3.7, 3.8. * Add support for Python 3.13. --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> --- .github/workflows/pre-commit.yml | 33 +++++++ .github/workflows/tests.yml | 23 +++-- .meta.toml | 2 +- .pre-commit-config.yaml | 28 ++++++ CHANGES.rst | 4 + MANIFEST.in | 1 + docs/conf.py | 147 +++++++++++++++------------- pyproject.toml | 21 ++++ setup.py | 5 +- src/zope/deprecation/deprecation.py | 2 +- tox.ini | 54 +++------- 11 files changed, 196 insertions(+), 124 deletions(-) create mode 100644 .github/workflows/pre-commit.yml create mode 100644 .pre-commit-config.yaml create mode 100644 pyproject.toml diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..371ca94 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,33 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/pure-python +name: pre-commit + +on: + pull_request: + push: + branches: + - master + # Allow to run this workflow manually from the Actions tab + workflow_dispatch: + +env: + FORCE_COLOR: 1 + +jobs: + pre-commit: + name: linting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - uses: pre-commit/action@v3.0.1 + with: + extra_args: --all-files --show-diff-on-failure + env: + PRE_COMMIT_COLOR: always + - uses: pre-commit-ci/lite-action@v1.1.0 + if: always() + with: + msg: Apply pre-commit code formatting diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7e2d1fb..ce539f4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,17 +20,15 @@ jobs: - ["ubuntu", "ubuntu-latest"] config: # [Python version, tox env] - - ["3.9", "release-check"] - - ["3.9", "lint"] - - ["3.7", "py37"] - - ["3.8", "py38"] - - ["3.9", "py39"] - - ["3.10", "py310"] - - ["3.11", "py311"] - - ["3.12", "py312"] + - ["3.11", "release-check"] + - ["3.9", "py39"] + - ["3.10", "py310"] + - ["3.11", "py311"] + - ["3.12", "py312"] + - ["3.13", "py313"] - ["pypy-3.10", "pypy3"] - - ["3.9", "docs"] - - ["3.9", "coverage"] + - ["3.11", "docs"] + - ["3.11", "coverage"] runs-on: ${{ matrix.os[1] }} if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name @@ -41,6 +39,7 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.config[0] }} + allow-prereleases: true - name: Pip cache uses: actions/cache@v4 with: @@ -54,7 +53,11 @@ jobs: python -m pip install --upgrade pip pip install tox - name: Test + if: ${{ !startsWith(runner.os, 'Mac') }} run: tox -e ${{ matrix.config[1] }} + - name: Test (macOS) + if: ${{ startsWith(runner.os, 'Mac') }} + run: tox -e ${{ matrix.config[1] }}-universal2 - name: Coverage if: matrix.config[1] == 'coverage' run: | diff --git a/.meta.toml b/.meta.toml index e9c1ebb..4acd36a 100644 --- a/.meta.toml +++ b/.meta.toml @@ -2,7 +2,7 @@ # https://github.com/zopefoundation/meta/tree/master/config/pure-python [meta] template = "pure-python" -commit-id = "b89d6a0a" +commit-id = "886d86ee" [python] with-macos = false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..92c124c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,28 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/pure-python +minimum_pre_commit_version: '3.6' +repos: + - repo: https://github.com/pycqa/isort + rev: "5.13.2" + hooks: + - id: isort + - repo: https://github.com/hhatto/autopep8 + rev: "v2.3.1" + hooks: + - id: autopep8 + args: [--in-place, --aggressive, --aggressive] + - repo: https://github.com/asottile/pyupgrade + rev: v3.19.0 + hooks: + - id: pyupgrade + args: [--py39-plus] + - repo: https://github.com/isidentical/teyit + rev: 0.4.3 + hooks: + - id: teyit + - repo: https://github.com/PyCQA/flake8 + rev: "7.1.1" + hooks: + - id: flake8 + additional_dependencies: + - flake8-debugger == 4.1.2 diff --git a/CHANGES.rst b/CHANGES.rst index 0921d62..895657b 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -5,6 +5,10 @@ 5.1 (unreleased) ================ +- Add support for Python 3.13. + +- Drop support for Python 3.7, 3.8. + - Add support for Python 3.12. diff --git a/MANIFEST.in b/MANIFEST.in index a1103d6..a8b9c14 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,6 +5,7 @@ include *.rst include *.txt include buildout.cfg include tox.ini +include .pre-commit-config.yaml recursive-include docs *.py recursive-include docs *.rst diff --git a/docs/conf.py b/docs/conf.py index dee759b..0907cfa 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,31 +1,33 @@ -# -*- coding: utf-8 -*- # # zope.deprecation documentation build configuration file, created by # sphinx-quickstart on Thu Apr 19 16:41:59 2012. # -# This file is execfile()d with the current directory set to its containing dir. +# This file is execfile()d with the current directory set to its containing +# dir. # # Note that not all possible configuration values are present in this # autogenerated file. # -# All configuration values have a default; values that are commented out -# serve to show the default. +# All configuration values have a default; values that are commented out serve +# to show the default. -import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) +# sys.path.insert(0, os.path.abspath('.')) -# -- General configuration ----------------------------------------------------- +# -- General configuration ----------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# needs_sphinx = '1.0' -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.viewcode'] +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.doctest', + 'sphinx.ext.viewcode'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -34,14 +36,14 @@ source_suffix = '.rst' # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. -project = u'zope.deprecation' -copyright = u'2012, Zope Foundation Contributors' +project = 'zope.deprecation' +copyright = '2012, Zope Foundation Contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -54,40 +56,41 @@ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None +# The reST default role (used for this markup: `text`) to use for all +# documents. +# default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] -# -- Options for HTML output --------------------------------------------------- +# -- Options for HTML output --------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. @@ -96,26 +99,26 @@ # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +# html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +# html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +# html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -124,119 +127,123 @@ # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' +# html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +# html_additional_pages = {} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'zopedeprecationdoc' -# -- Options for LaTeX output -------------------------------------------------- +# -- Options for LaTeX output -------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', + # The paper size ('letterpaper' or 'a4paper'). + # 'papersize': 'letterpaper', -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', + # The font size ('10pt', '11pt' or '12pt'). + # 'pointsize': '10pt', -# Additional stuff for the LaTeX preamble. -#'preamble': '', + # Additional stuff for the LaTeX preamble. + # 'preamble': '', } -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). +# Grouping the document tree into LaTeX files. List of tuples (source start +# file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'zopedeprecation.tex', u'zope.deprecation Documentation', - u'Zope Foundation Contributors', 'manual'), + ('index', 'zopedeprecation.tex', 'zope.deprecation Documentation', + 'Zope Foundation Contributors', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True -# -- Options for manual page output -------------------------------------------- +# -- Options for manual page output -------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'zopedeprecation', u'zope.deprecation Documentation', - [u'Zope Foundation Contributors'], 1) + ('index', 'zopedeprecation', 'zope.deprecation Documentation', + ['Zope Foundation Contributors'], 1) ] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False -# -- Options for Texinfo output ------------------------------------------------ +# -- Options for Texinfo output ------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'zopedeprecation', u'zope.deprecation Documentation', - u'Zope Foundation Contributors', 'zopedeprecation', 'One line description of project.', - 'Miscellaneous'), + ('index', + 'zopedeprecation', + 'zope.deprecation Documentation', + 'Zope Foundation Contributors', + 'zopedeprecation', + 'One line description of project.', + 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..2445ebe --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,21 @@ +# +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/pure-python + +[build-system] +requires = ["setuptools <= 75.6.0"] +build-backend = "setuptools.build_meta" + +[tool.coverage.run] +branch = true +source = ["zope.deprecation"] + +[tool.coverage.report] +fail_under = 99 +precision = 2 +ignore_errors = true +show_missing = true +exclude_lines = ["pragma: no cover", "pragma: nocover", "except ImportError:", "raise NotImplementedError", "if __name__ == '__main__':", "self.fail", "raise AssertionError", "raise unittest.Skip"] + +[tool.coverage.html] +directory = "parts/htmlcov" diff --git a/setup.py b/setup.py index 68187f3..048dabf 100644 --- a/setup.py +++ b/setup.py @@ -49,12 +49,11 @@ def read(*rnames): "License :: OSI Approved :: Zope Public License", "Programming Language :: Python", "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 :: 3.12", + "Programming Language :: Python :: 3.13", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Framework :: Zope :: 3", @@ -62,7 +61,7 @@ def read(*rnames): package_dir={'': 'src'}, packages=find_packages('src'), namespace_packages=['zope', ], - python_requires='>= 3.7', + python_requires='>= 3.9', install_requires=[ 'setuptools', ], diff --git a/src/zope/deprecation/deprecation.py b/src/zope/deprecation/deprecation.py index 91f3f3b..cc249dd 100644 --- a/src/zope/deprecation/deprecation.py +++ b/src/zope/deprecation/deprecation.py @@ -220,7 +220,7 @@ def __call__(self, func): def moved(to_location, unsupported_in=None, cls=DeprecationWarning): old = sys._getframe(1).f_globals['__name__'] - message = '{} has moved to {}.'.format(old, to_location) + message = f'{old} has moved to {to_location}.' if unsupported_in: message += " Import of {} will become unsupported in {}".format( old, unsupported_in) diff --git a/tox.ini b/tox.ini index 98658da..b1e0f46 100644 --- a/tox.ini +++ b/tox.ini @@ -5,12 +5,11 @@ minversion = 3.18 envlist = release-check lint - py37 - py38 py39 py310 py311 py312 + py313 pypy3 docs coverage @@ -20,20 +19,25 @@ usedevelop = true package = wheel wheel_build_env = .pkg deps = -setenv = - py312: VIRTUALENV_PIP=23.1.2 - py312: PIP_REQUIRE_VIRTUALENV=0 + setuptools <= 75.6.0 commands = zope-testrunner --test-path=src {posargs:-vc} sphinx-build -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest extras = test docs + +[testenv:setuptools-latest] +basepython = python3 +deps = + git+https://github.com/pypa/setuptools.git\#egg=setuptools + [testenv:release-check] description = ensure that the distribution is ready to release basepython = python3 skip_install = true deps = + setuptools <= 75.6.0 twine build check-manifest @@ -47,23 +51,14 @@ commands = twine check dist/* [testenv:lint] +description = This env runs all linters configured in .pre-commit-config.yaml basepython = python3 skip_install = true deps = - isort - flake8 -commands = - isort --check-only --diff {toxinidir}/src {toxinidir}/setup.py - flake8 src setup.py - -[testenv:isort-apply] -basepython = python3 -skip_install = true + pre-commit commands_pre = -deps = - isort commands = - isort {toxinidir}/src {toxinidir}/setup.py [] + pre-commit run --all-files --show-diff-on-failure [testenv:docs] basepython = python3 @@ -78,29 +73,10 @@ basepython = python3 allowlist_externals = mkdir deps = - coverage + coverage[toml] commands = mkdir -p {toxinidir}/parts/htmlcov coverage run -m zope.testrunner --test-path=src {posargs:-vc} coverage run -a -m sphinx -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest - coverage html --ignore-errors - coverage report --show-missing --fail-under=99 - -[coverage:run] -branch = True -source = zope.deprecation - -[coverage:report] -precision = 2 -ignore_errors = True -exclude_lines = - pragma: no cover - pragma: nocover - except ImportError: - raise NotImplementedError - if __name__ == '__main__': - self.fail - raise AssertionError - -[coverage:html] -directory = parts/htmlcov + coverage html + coverage report