From dc62ad26a9f6bbc8bfd3b12e74f9377a51a753f3 Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Fri, 25 Apr 2025 08:32:12 +0200 Subject: [PATCH 1/4] Drop support for Python 3.7, 3.8. --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 155edf3..da3e84f 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,7 @@ Changelog 4.1 (unreleased) ---------------- -- Nothing changed yet. +- Drop support for Python 3.7, 3.8. 4.0 (2023-08-28) From 782f40549b1ca48ef1edb9639e449051f2c226a9 Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Fri, 25 Apr 2025 08:32:12 +0200 Subject: [PATCH 2/4] Add support for Python 3.12, 3.13. --- CHANGES.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index da3e84f..4ebeca1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ Changelog 4.1 (unreleased) ---------------- +- Add support for Python 3.12, 3.13. + - Drop support for Python 3.7, 3.8. From f5fdcca63bb57b5f46602b39874d35c7f64df708 Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Fri, 25 Apr 2025 08:34:40 +0200 Subject: [PATCH 3/4] Configuring for pure-python --- .github/workflows/pre-commit.yml | 36 +++++++++++++++++ .github/workflows/tests.yml | 55 +++++++++++++------------- .meta.toml | 6 +-- .pre-commit-config.yaml | 28 ++++++++++++++ CONTRIBUTING.md | 2 +- MANIFEST.in | 1 + pyproject.toml | 32 ++++++++++++++++ setup.cfg | 2 - tox.ini | 66 +++++++++++++++----------------- 9 files changed, 158 insertions(+), 70 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..ff77ae6 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,36 @@ +# 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: + permissions: + contents: read + pull-requests: write + 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@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd #v3.0.1 + with: + extra_args: --all-files --show-diff-on-failure + env: + PRE_COMMIT_COLOR: always + - uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 #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 0e45a78..0d61152 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,50 +12,51 @@ on: jobs: build: + permissions: + contents: read + pull-requests: write strategy: # We want to see all failures: fail-fast: false matrix: os: - - ["ubuntu", "ubuntu-20.04"] + - ["ubuntu", "ubuntu-latest"] config: # [Python version, tox env] - - ["3.9", "lint"] - - ["3.7", "py37"] - - ["3.8", "py38"] - - ["3.9", "py39"] - - ["3.10", "py310"] - - ["3.11", "py311"] - - ["pypy-3.9", "pypy3"] - - ["3.9", "coverage"] + - ["3.11", "release-check"] + - ["3.9", "py39"] + - ["3.10", "py310"] + - ["3.11", "py311"] + - ["3.12", "py312"] + - ["3.13", "py313"] + - ["pypy-3.10", "pypy3"] + - ["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 name: ${{ matrix.config[1] }} steps: - - uses: actions/checkout@v3 - - name: Set up Python - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 with: - python-version: ${{ matrix.config[0] }} - - name: Pip cache - uses: actions/cache@v3 + persist-credentials: false + - name: Install uv + caching + uses: astral-sh/setup-uv@v5 with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ matrix.config[0] }}-${{ hashFiles('setup.*', 'tox.ini') }} - restore-keys: | - ${{ runner.os }}-pip-${{ matrix.config[0] }}- - ${{ runner.os }}-pip- - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install tox + enable-cache: true + cache-dependency-glob: | + setup.* + tox.ini + python-version: ${{ matrix.matrix.config[0] }} + github-token: ${{ secrets.GITHUB_TOKEN }} - name: Test - run: tox -e ${{ matrix.config[1] }} + if: ${{ !startsWith(runner.os, 'Mac') }} + run: uvx --with tox-uv tox -e ${{ matrix.config[1] }} + - name: Test (macOS) + if: ${{ startsWith(runner.os, 'Mac') }} + run: uvx --with tox-uv tox -e ${{ matrix.config[1] }}-universal2 - name: Coverage if: matrix.config[1] == 'coverage' run: | - pip install coveralls - coveralls --service=github + uvx coveralls --service=github env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.meta.toml b/.meta.toml index b8f8c93..e9fe59f 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 = "fd874ae4" +commit-id = "c6354ebd" [python] with-pypy = true @@ -10,6 +10,7 @@ with-sphinx-doctests = false with-windows = false with-future-python = false with-macos = false +with-docs = false [coverage] fail-under = 95 @@ -21,9 +22,6 @@ additional-config = [ " src/grokcore/layout/__init__.py: F401", ] -[tox] -use-flake8 = true - [manifest] additional-rules = [ "recursive-include src *.pt", diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..b201c4b --- /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: "6.0.1" + hooks: + - id: isort + - repo: https://github.com/hhatto/autopep8 + rev: "v2.3.2" + hooks: + - id: autopep8 + args: [--in-place, --aggressive, --aggressive] + - repo: https://github.com/asottile/pyupgrade + rev: v3.19.1 + 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.2.0" + hooks: + - id: flake8 + additional_dependencies: + - flake8-debugger == 4.1.2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 31d95f0..0ab12fe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ +--> # Contributing to zopefoundation projects The projects under the zopefoundation GitHub organization are open source and diff --git a/MANIFEST.in b/MANIFEST.in index ce08cff..539cfd8 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 src *.py recursive-include src *.pt diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a121e08 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,32 @@ +# Generated from: +# https://github.com/zopefoundation/meta/tree/master/config/pure-python + +[build-system] +requires = [ + "setuptools == 75.8.2", + "wheel", +] +build-backend = "setuptools.build_meta" + +[tool.coverage.run] +branch = true +source = ["grokcore.layout"] + +[tool.coverage.report] +fail_under = 95 +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.cfg b/setup.cfg index 53cda54..62098e1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,5 @@ # Generated from: # https://github.com/zopefoundation/meta/tree/master/config/pure-python -[bdist_wheel] -universal = 0 [flake8] doctests = 1 diff --git a/tox.ini b/tox.ini index 7099904..9643973 100644 --- a/tox.ini +++ b/tox.ini @@ -3,12 +3,13 @@ [tox] minversion = 3.18 envlist = + release-check lint - py37 - py38 py39 py310 py311 + py312 + py313 pypy3 coverage @@ -17,61 +18,54 @@ usedevelop = true package = wheel wheel_build_env = .pkg deps = + setuptools == 75.8.2 commands = zope-testrunner --test-path=src {posargs:-vc} extras = test -[testenv:lint] +[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 -commands = - isort --check-only --diff {toxinidir}/src {toxinidir}/setup.py - flake8 src setup.py - check-manifest - check-python-versions deps = + setuptools == 75.8.2 + wheel + twine + build check-manifest - check-python-versions >= 0.19.1 + check-python-versions >= 0.20.0 wheel - flake8 - isort +commands_pre = +commands = + check-manifest + check-python-versions --only setup.py,tox.ini,.github/workflows/tests.yml + python -m build --sdist --no-isolation + twine check dist/* -[testenv:isort-apply] +[testenv:lint] +description = This env runs all linters configured in .pre-commit-config.yaml basepython = python3 skip_install = true -commands_pre = deps = - isort + pre-commit +commands_pre = commands = - isort {toxinidir}/src {toxinidir}/setup.py [] + pre-commit run --all-files --show-diff-on-failure [testenv:coverage] 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 html --ignore-errors - coverage report --ignore-errors --show-missing --fail-under=95 - -[coverage:run] -branch = True -source = grokcore.layout - -[coverage:report] -precision = 2 -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 From f06d1feee436d47cb1be90fe317712c375a5ac91 Mon Sep 17 00:00:00 2001 From: Michael Howitz Date: Fri, 25 Apr 2025 08:36:13 +0200 Subject: [PATCH 4/4] Update Python version support. --- setup.py | 8 ++++---- src/grokcore/layout/meta.py | 2 +- src/grokcore/layout/tests/test_functional.py | 6 +++--- src/grokcore/layout/tests/test_package.py | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/setup.py b/setup.py index f9e75a3..000a2e6 100644 --- a/setup.py +++ b/setup.py @@ -40,11 +40,11 @@ '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', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: Python :: Implementation :: PyPy', @@ -54,13 +54,13 @@ author='Grok Team', author_email='zope-dev@zope.dev', url='https://github.com/zopefoundation/grokcore.layout', - license='ZPL 2.1', + license='ZPL-2.1', packages=find_packages('src'), package_dir={'': 'src'}, namespace_packages=['grokcore'], include_package_data=True, zip_safe=False, - python_requires='>=3.7', + python_requires='>=3.9', extras_require={'test': test_requires}, install_requires=[ 'grokcore.component >= 2.5', diff --git a/src/grokcore/layout/meta.py b/src/grokcore/layout/meta.py index 5822595..f43c760 100644 --- a/src/grokcore/layout/meta.py +++ b/src/grokcore/layout/meta.py @@ -38,5 +38,5 @@ def execute(self, factory, config, context, layer, provides, **kw): discriminator=('adapter', adapts, provides), callable=grokcore.component.provideAdapter, args=(factory, adapts, provides), - ) + ) return True diff --git a/src/grokcore/layout/tests/test_functional.py b/src/grokcore/layout/tests/test_functional.py index e3eb8a5..618742d 100644 --- a/src/grokcore/layout/tests/test_functional.py +++ b/src/grokcore/layout/tests/test_functional.py @@ -24,12 +24,12 @@ def suiteFromPackage(name): getRootFolder = layer.getRootFolder globs = dict( getRootFolder=getRootFolder, - ) + ) optionflags = ( doctest.ELLIPSIS + doctest.NORMALIZE_WHITESPACE + doctest.REPORT_NDIFF - ) + ) for filename in files: if filename == '__init__.py': @@ -54,6 +54,6 @@ def test_suite(): suite = unittest.TestSuite() for name in [ 'functional' - ]: + ]: suite.addTest(suiteFromPackage(name)) return suite diff --git a/src/grokcore/layout/tests/test_package.py b/src/grokcore/layout/tests/test_package.py index c4b6de7..3a581cf 100644 --- a/src/grokcore/layout/tests/test_package.py +++ b/src/grokcore/layout/tests/test_package.py @@ -33,7 +33,7 @@ def suiteFromPackage(name): continue if filename == '__init__.py': continue - dottedname = 'grokcore.layout.tests.{}.{}'.format(name, filename[:-3]) + dottedname = f'grokcore.layout.tests.{name}.{filename[:-3]}' suite.addTest(make_test(dottedname)) return suite