From a39ca731823666798d559cfc32d59c92b7d325c2 Mon Sep 17 00:00:00 2001 From: Henri Hulski Date: Wed, 7 Oct 2026 20:44:35 +0200 Subject: [PATCH 1/9] docs: update developing.rst and add readthedocs integration --- .readthedocs.yaml | 34 +++++++++++++++++++++ doc/developing.rst | 76 ++++++++++++++++++++++++++++------------------ 2 files changed, 81 insertions(+), 29 deletions(-) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..a5fcb53 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,34 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-lts-latest + tools: + python: "3.14" + +# Build documentation in the "doc/" directory with Sphinx +sphinx: + configuration: doc/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + # fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: +# - pdf +# - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - method: pip + path: . + extra_requirements: + - docs \ No newline at end of file diff --git a/doc/developing.rst b/doc/developing.rst index 57b3ee9..6a29741 100644 --- a/doc/developing.rst +++ b/doc/developing.rst @@ -17,9 +17,7 @@ Then go to the importscan directory:: $ cd importscan -Make sure you have virtualenv_ installed. - -Create a new virtualenv for Python 3 inside the importscan directory:: +Create a new virtualenv inside the importscan directory:: $ python -m venv --upgrade-deps .venv @@ -30,7 +28,7 @@ Activate the virtualenv:: Install the various dependencies and development tools from develop_requirements.txt:: - $ pip install -Ur develop_requirements.txt + (.venv) $ pip install -Ur develop_requirements.txt For upgrading the requirements just run the command again. @@ -39,7 +37,6 @@ For upgrading the requirements just run the command again. The following commands work only if you have the virtualenv activated. .. _github: https://docs.github.com/en/authentication/connecting-to-github-with-ssh -.. _virtualenv: https://pypi.org/project/virtualenv Install pre-commit hook for Black integration --------------------------------------------- @@ -47,7 +44,7 @@ Install pre-commit hook for Black integration We're using Black_ for formatting the code and it's recommended to install the `pre-commit hook`_ for Black integration before committing:: - $ pre-commit install + (.venv) $ pre-commit install .. _`pre-commit hook`: https://black.readthedocs.io/en/stable/integrations/source_version_control.html @@ -56,11 +53,11 @@ Running the tests You can run the tests using `pytest`_:: - $ pytest + (.venv) $ pytest To generate test coverage information as HTML do:: - $ pytest --cov --cov-report html + (.venv) $ pytest --cov --cov-report html You can then point your web browser to the ``htmlcov/index.html`` file in the project directory and click on modules to see detailed coverage @@ -73,13 +70,24 @@ Black To format the code with the `Black Code Formatter`_ run in the root directory:: - $ black importscan + (.venv) $ black importscan Black has also integration_ for the most popular editors. .. _`Black Code Formatter`: https://black.readthedocs.io .. _integration: https://black.readthedocs.io/en/stable/editor_integration.html +isort +----- + +To sort imports with isort_ from the project directory do:: + + (.venv) $ isort . + +isort uses the settings in ``pyproject.toml``. + +.. _isort: https://pycqa.github.io/isort/ + flake8 ------ @@ -88,20 +96,30 @@ mistakes using pyflakes_, checks for PEP8_ style compliance and can do `cyclomatic complexity`_ checking. To do pyflakes and pep8 checking do:: - $ flake8 importscan + (.venv) $ flake8 importscan To also show cyclomatic complexity, use this command:: - $ flake8 --max-complexity=10 importscan + (.venv) $ flake8 --max-complexity=10 importscan .. _flake8: https://pypi.org/project/flake8 - .. _pyflakes: https://pypi.org/project/pyflakes - .. _pep8: https://peps.python.org/pep-0008 - .. _`cyclomatic complexity`: https://en.wikipedia.org/wiki/Cyclomatic_complexity +Type checking +------------- + +Importscan uses mypy_ and pyright_ for type checking. Run either checker +from the project directory:: + + (.venv) $ mypy + (.venv) $ pyright + +Both checkers use the settings in ``pyproject.toml``. + +.. _mypy: https://mypy.readthedocs.io/ +.. _pyright: https://microsoft.github.io/pyright/ Running the documentation tests ------------------------------- @@ -109,32 +127,32 @@ Running the documentation tests The documentation contains code. To check these code snippets, you can run this code using this command:: - (py3) $ sphinx-build -b doctest doc doc/build/doctest + (.venv) $ sphinx-build -b doctest doc doc/_build/doctest Or alternatively if you have ``Make`` installed:: - (py3) $ cd doc - (py3) $ make doctest + (.venv) $ cd doc + (.venv) $ make doctest -Or from the Dectate project directory:: +Or from the Importscan project directory:: - (py3) $ make -C doc doctest + (.venv) $ make -C doc doctest Building the HTML documentation ------------------------------- To build the HTML documentation (output in ``doc/_build/html``), run:: - $ sphinx-build doc doc/_build/html + (.venv) $ sphinx-build doc doc/_build/html Or alternatively if you have ``Make`` installed:: - $ cd doc - $ make html + (.venv) $ cd doc + (.venv) $ make html -Or from the Dectate project directory:: +Or from the Importscan project directory:: - $ make -C doc html + (.venv) $ make -C doc html Tox --- @@ -153,16 +171,16 @@ One tool you can use to install multiple versions of Python is pyenv_. To find out which test environments are defined for Importscan in tox.ini run:: - $ tox -l + (.venv) $ tox -l You can run all tox tests with:: - $ tox + (.venv) $ tox You can also specify a test environment to run e.g.:: - $ tox -e py311 - $ tox -e lint - $ tox -e coverage + (.venv) $ tox -e py311 + (.venv) $ tox -e lint + (.venv) $ tox -e coverage .. _pyenv: https://github.com/pyenv/pyenv From a654edafbee1743b4b6bcb481b70f90947c03b3c Mon Sep 17 00:00:00 2001 From: Henri Hulski Date: Wed, 7 Oct 2026 21:42:38 +0200 Subject: [PATCH 2/9] chore: remove Python 3.10, add Python 3.15 and switch to Pypy 3.12 --- .github/workflows/main.yml | 2 +- .pre-commit-config.yaml | 2 +- pyproject.toml | 30 +++++++++++++++--------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0fcdb62..4c5e82b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,7 +19,7 @@ jobs: strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "pypy3.11"] + python-version: ["3.11", "3.12", "3.13", "3.14", "3.15", "pypy-3.12"] # Steps represent a sequence of tasks that will be executed as part of the job steps: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5ea0c14..b692006 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,4 +12,4 @@ repos: rev: v3.21.2 hooks: - id: pyupgrade - args: [--py310-plus] + args: [--py311-plus] diff --git a/pyproject.toml b/pyproject.toml index a276e3e..166ed91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,17 +16,17 @@ classifiers = [ "Intended Audience :: Developers", "Topic :: Software Development :: Libraries :: Application Frameworks", "Programming Language :: Python", - "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Development Status :: 5 - Production/Stable", ] -requires-python = ">= 3.10" +requires-python = ">= 3.11" [project.urls] Documentation = "https://importscan.readthedocs.io" @@ -77,7 +77,7 @@ extend-select = ["TC", "TC1"] max-line-length = 88 [tool.mypy] -python_version = "3.10" +python_version = "3.11" strict = true files = ["."] exclude = ["doc/conf\\.py$"] @@ -102,11 +102,11 @@ reportUnnecessaryTypeIgnoreComment = "warning" [tool.tox] requires = ["tox>=4"] env_list = [ - "py310", "py311", "py312", "py313", "py314", + "py315", "pypy3", "coverage", "pre-commit", @@ -117,12 +117,12 @@ env_list = [ skip_missing_interpreters = true [tool.tox.gh.python] -"3.10" = ["py310"] "3.11" = ["py311"] "3.12" = ["py312"] "3.13" = ["py313"] "3.14" = ["py314", "pre-commit", "coverage", "mypy", "pyright"] -"pypy-3.11" = ["pypy3"] +"3.15" = ["py315"] +"pypy-3.12" = ["pypy3"] [tool.tox.env_run_base] package = "editable" @@ -130,14 +130,14 @@ extras = ["test"] commands = [["pytest", "{posargs:importscan}"]] [tool.tox.env.coverage] -base_python = ["python3"] +base_python = ["python3.14"] extras = ["test", "coverage"] commands = [ ["pytest", "--cov", "--cov-fail-under=100", "{posargs:importscan}"], ] [tool.tox.env.pre-commit] -base_python = ["python3"] +base_python = ["python3.14"] package = "skip" deps = ["pre-commit"] commands = [ @@ -145,36 +145,36 @@ commands = [ ] [tool.tox.env.docs] -base_python = ["python3"] +base_python = ["python3.14"] extras = ["docs"] commands = [ ["sphinx-build", "-b", "doctest", "doc", "{env_tmp_dir}"], ] [tool.tox.env.mypy] -base_python = ["python3"] +base_python = ["python3.14"] extras = ["mypy"] commands = [ - ["mypy", "--python-version", "3.10"], ["mypy", "--python-version", "3.11"], ["mypy", "--python-version", "3.12"], ["mypy", "--python-version", "3.13"], ["mypy", "--python-version", "3.14"], + ["mypy", "--python-version", "3.15"], ] [tool.tox.env.pyright] -base_python = ["python3"] +base_python = ["python3.14"] extras = ["pyright"] commands = [ - ["pyright", "--pythonversion", "3.10"], ["pyright", "--pythonversion", "3.11"], ["pyright", "--pythonversion", "3.12"], ["pyright", "--pythonversion", "3.13"], ["pyright", "--pythonversion", "3.14"], + ["pyright", "--pythonversion", "3.15"], ] [tool.black] -target-version = ['py310', 'py311', 'py312', 'py313', 'py314'] +target-version = ['py311', 'py312', 'py313', 'py314', 'py315'] include = '\.pyi?$' exclude = ''' ( @@ -193,7 +193,7 @@ exclude = ''' [tool.isort] profile = 'black' -py_version = 310 +py_version = 311 skip_gitignore = true extra_standard_library = ["typing_extensions"] known_first_party = ["dectate", "importscan", "reg"] From b8d0f514c9c43f5793407f1c2a36093b504ce799 Mon Sep 17 00:00:00 2001 From: Henri Hulski Date: Wed, 7 Oct 2026 23:29:27 +0200 Subject: [PATCH 3/9] chore: remove coveralls integration --- .github/workflows/main.yml | 11 ----------- README.rst | 3 --- 2 files changed, 14 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4c5e82b..4454106 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,14 +32,3 @@ jobs: run: python -m pip install --upgrade pip tox tox-gh - name: "Run tox targets for ${{ matrix.python-version }}" run: "python -m tox" - - - name: "Report to coveralls" - # coverage is only created in the py314 environment - # --service=github is a workaround for bug - # https://github.com/coveralls-clients/coveralls-python/issues/251 - if: "matrix.python-version == '3.14'" - run: | - pip install coveralls - coveralls --service=github - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.rst b/README.rst index f454d95..478d667 100644 --- a/README.rst +++ b/README.rst @@ -2,9 +2,6 @@ :target: https://github.com/morepath/importscan/actions?workflow=CI :alt: CI Status -.. image:: https://coveralls.io/repos/github/morepath/importscan/badge.svg?branch=master - :target: https://coveralls.io/github/morepath/importscan?branch=master - .. image:: https://img.shields.io/pypi/v/importscan.svg :target: https://pypi.org/project/importscan/ From a4671e4136d992c6757d99c7497bc8508180ddd1 Mon Sep 17 00:00:00 2001 From: Henri Hulski Date: Thu, 8 Oct 2026 17:40:11 +0200 Subject: [PATCH 4/9] chore: replace flake8, black, isort, pyupgrade and pre-commit with ruff --- .pre-commit-config.yaml | 15 ---------- develop_requirements.txt | 1 - doc/developing.rst | 63 ++++++++++------------------------------ pyproject.toml | 54 +++++++--------------------------- 4 files changed, 26 insertions(+), 107 deletions(-) delete mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml deleted file mode 100644 index b692006..0000000 --- a/.pre-commit-config.yaml +++ /dev/null @@ -1,15 +0,0 @@ -repos: - - repo: https://github.com/psf/black-pre-commit-mirror - rev: 26.10.0 - hooks: - - id: black - - repo: https://github.com/PyCQA/flake8 - rev: "7.4.1" - hooks: - - id: flake8 - additional_dependencies: [flake8-pyproject, flake8-type-checking] - - repo: https://github.com/asottile/pyupgrade - rev: v3.21.2 - hooks: - - id: pyupgrade - args: [--py311-plus] diff --git a/develop_requirements.txt b/develop_requirements.txt index f08b794..c1d8e4c 100644 --- a/develop_requirements.txt +++ b/develop_requirements.txt @@ -1,6 +1,5 @@ # development -e '.[test,coverage,lint,docs,mypy,pyright]' -pre-commit tox >= 4 # releaser diff --git a/doc/developing.rst b/doc/developing.rst index 6a29741..4c850bb 100644 --- a/doc/developing.rst +++ b/doc/developing.rst @@ -38,15 +38,24 @@ For upgrading the requirements just run the command again. .. _github: https://docs.github.com/en/authentication/connecting-to-github-with-ssh -Install pre-commit hook for Black integration ---------------------------------------------- +Code quality checks +------------------- -We're using Black_ for formatting the code and it's recommended to -install the `pre-commit hook`_ for Black integration before committing:: +Morepath uses Ruff_ for linting, import sorting, and code formatting. Run +the checks from the project directory with:: - (.venv) $ pre-commit install + (.venv) $ ruff check . + (.venv) $ ruff format --check . -.. _`pre-commit hook`: https://black.readthedocs.io/en/stable/integrations/source_version_control.html +To apply lint fixes and format the code, run:: + + (.venv) $ ruff check --fix . + (.venv) $ ruff format . + +Ruff uses the project settings in ``pyproject.toml``. The ``lint`` tox +environment runs both checks. + +.. _Ruff: https://docs.astral.sh/ruff/ Running the tests ----------------- @@ -65,48 +74,6 @@ information. .. _`pytest`: https://pytest.org -Black ------ - -To format the code with the `Black Code Formatter`_ run in the root directory:: - - (.venv) $ black importscan - -Black has also integration_ for the most popular editors. - -.. _`Black Code Formatter`: https://black.readthedocs.io -.. _integration: https://black.readthedocs.io/en/stable/editor_integration.html - -isort ------ - -To sort imports with isort_ from the project directory do:: - - (.venv) $ isort . - -isort uses the settings in ``pyproject.toml``. - -.. _isort: https://pycqa.github.io/isort/ - -flake8 ------- - -flake8_ is a tool that can do various checks for common Python -mistakes using pyflakes_, checks for PEP8_ style compliance and -can do `cyclomatic complexity`_ checking. To do pyflakes and pep8 -checking do:: - - (.venv) $ flake8 importscan - -To also show cyclomatic complexity, use this command:: - - (.venv) $ flake8 --max-complexity=10 importscan - -.. _flake8: https://pypi.org/project/flake8 -.. _pyflakes: https://pypi.org/project/pyflakes -.. _pep8: https://peps.python.org/pep-0008 -.. _`cyclomatic complexity`: https://en.wikipedia.org/wiki/Cyclomatic_complexity - Type checking ------------- diff --git a/pyproject.toml b/pyproject.toml index 166ed91..6e976f1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,13 +37,7 @@ Changelog = "https://github.com/morepath/importscan/blob/master/CHANGES.txt" [project.optional-dependencies] test = ["pytest >= 8", "pytest-env"] coverage = ["pytest-cov"] -lint = [ - "black", - "flake8", - "flake8-pyproject", - "flake8-type-checking", - "isort", -] +lint = ["ruff"] docs = ["sphinx < 9.1"] mypy = ["mypy", "pytest"] pyright = ["pyright", "pytest"] @@ -70,11 +64,10 @@ source = ["importscan"] [tool.coverage.report] show_missing = true -[tool.flake8] -show-source = true -ignore = ["E203", "E501", "E704", "W503", "W504"] -extend-select = ["TC", "TC1"] -max-line-length = 88 +[tool.ruff.lint] +select = ["E", "F", "W", "I", "TC", "UP", "RUF"] +ignore = ["E501"] +future-annotations = true [tool.mypy] python_version = "3.11" @@ -109,7 +102,7 @@ env_list = [ "py315", "pypy3", "coverage", - "pre-commit", + "lint", "docs", "mypy", "pyright", @@ -120,7 +113,7 @@ skip_missing_interpreters = true "3.11" = ["py311"] "3.12" = ["py312"] "3.13" = ["py313"] -"3.14" = ["py314", "pre-commit", "coverage", "mypy", "pyright"] +"3.14" = ["py314", "coverage", "mypy", "lint", "pyright"] "3.15" = ["py315"] "pypy-3.12" = ["pypy3"] @@ -136,12 +129,12 @@ commands = [ ["pytest", "--cov", "--cov-fail-under=100", "{posargs:importscan}"], ] -[tool.tox.env.pre-commit] +[tool.tox.env.lint] base_python = ["python3.14"] -package = "skip" -deps = ["pre-commit"] +extras = ["lint"] commands = [ - ["pre-commit", "run", "--all-files"], + ["ruff", "check", "."], + ["ruff", "format", "--check", "."], ] [tool.tox.env.docs] @@ -172,28 +165,3 @@ commands = [ ["pyright", "--pythonversion", "3.14"], ["pyright", "--pythonversion", "3.15"], ] - -[tool.black] -target-version = ['py311', 'py312', 'py313', 'py314', 'py315'] -include = '\.pyi?$' -exclude = ''' -( - /( - \.git - | \.tox - | env - | venv - | .venv - | __pycache__ - | build - | dist - )/ -) -''' - -[tool.isort] -profile = 'black' -py_version = 311 -skip_gitignore = true -extra_standard_library = ["typing_extensions"] -known_first_party = ["dectate", "importscan", "reg"] From b8ad0f27a552120dd23ceb978df677f711ad13bb Mon Sep 17 00:00:00 2001 From: Henri Hulski Date: Thu, 8 Oct 2026 17:42:58 +0200 Subject: [PATCH 5/9] style: format and lint the codebase with ruff --- importscan/scan.py | 5 +++-- importscan/types.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/importscan/scan.py b/importscan/scan.py index 12dfed5..0ccb0fe 100644 --- a/importscan/scan.py +++ b/importscan/scan.py @@ -8,6 +8,7 @@ from collections.abc import Callable, Generator, Iterable from importlib.abc import Loader from types import ModuleType + from typing_extensions import TypeIs from importscan.types import IgnoreModule, ModuleInfo, StrOrBytesPath @@ -152,7 +153,8 @@ def import_module( get_filename = loader._get_filename # type: ignore[attr-defined] try: fn: str = cast( - "str", get_filename(modname) # pyright: ignore[reportOptionalCall] + "str", + get_filename(modname), # pyright: ignore[reportOptionalCall] ) except TypeError: fn = cast("str", get_filename()) # pyright: ignore[reportOptionalCall] @@ -258,7 +260,6 @@ def seen(p: str, m: set[str] = set()) -> bool: # iter_modules is nonrecursive for module_finder, name, ispkg in iter_modules(path, prefix): - if is_ignored is not None and is_ignored(name): # if name is a package, ignoring here causes # all subpackages and submodules to be ignored too diff --git a/importscan/types.py b/importscan/types.py index e3efbc6..d0faeaa 100644 --- a/importscan/types.py +++ b/importscan/types.py @@ -26,7 +26,7 @@ def find_spec( IgnoreModuleCallback: TypeAlias = "Callable[[str], object]" -IgnoreModule: TypeAlias = "str | IgnoreModuleCallback" # noqa: TC008 +IgnoreModule: TypeAlias = "str | IgnoreModuleCallback" ModuleFinder: TypeAlias = MetaPathFinderProtocol | PathEntryFinderProtocol ModuleInfo: TypeAlias = tuple[ModuleFinder, str, bool] StrOrBytesPath: TypeAlias = "PathLike[str] | PathLike[bytes] | str | bytes" From d19c5ade27fbf4e148c933be1246d0bf820e45d4 Mon Sep 17 00:00:00 2001 From: Henri Hulski Date: Thu, 8 Oct 2026 20:19:24 +0200 Subject: [PATCH 6/9] deploy: adjust deployment strategy and publish to pypi using gh-actions --- .github/workflows/main.yml | 7 +++++-- .github/workflows/release.yml | 39 +++++++++++++++++++++++++++++++++++ pyproject.toml | 7 ++++++- 3 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4454106..6df12bd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -18,16 +18,19 @@ jobs: runs-on: "ubuntu-latest" strategy: + fail-fast: false matrix: python-version: ["3.11", "3.12", "3.13", "3.14", "3.15", "pypy-3.12"] # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: "actions/checkout@v6" - - uses: "actions/setup-python@v6" + - uses: "actions/checkout@v7" + - uses: "actions/setup-python@v7" with: python-version: "${{ matrix.python-version }}" + allow-prereleases: true + check-latest: true - name: "Install dependencies" run: python -m pip install --upgrade pip tox tox-gh - name: "Run tox targets for ${{ matrix.python-version }}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..aad6a8a --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,39 @@ +name: Release + +on: + push: + tags: ["v[0-9]*"] + +permissions: {} + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + - uses: actions/setup-python@v7 + with: + python-version: "3.14" + - run: python -m pip install build + - run: python -m build + - uses: actions/upload-artifact@v7 + with: + name: dist + path: dist/ + + publish: + needs: build + runs-on: ubuntu-latest + environment: pypi + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v8 + with: + name: dist + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/pyproject.toml b/pyproject.toml index 6e976f1..3e33b3a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -141,7 +141,8 @@ commands = [ base_python = ["python3.14"] extras = ["docs"] commands = [ - ["sphinx-build", "-b", "doctest", "doc", "{env_tmp_dir}"], + ["sphinx-build", "-W", "-b", "doctest", "doc", "{env_tmp_dir}"], + ["sphinx-build", "-W", "-b", "html", "doc", "{env_tmp_dir}"], ] [tool.tox.env.mypy] @@ -165,3 +166,7 @@ commands = [ ["pyright", "--pythonversion", "3.14"], ["pyright", "--pythonversion", "3.15"], ] + +[tool.zest-releaser] +upload-pypi = false +tag-format = "v{version}" From f84275e1491a10867ac97103a6d3cef9d78251f9 Mon Sep 17 00:00:00 2001 From: Henri Hulski Date: Thu, 8 Oct 2026 22:13:16 +0200 Subject: [PATCH 7/9] docs: update CHANGES --- CHANGES.txt | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 661ce8c..ade263a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -6,19 +6,47 @@ CHANGES - Skip importing packages in scan() since they're already imported in walk_packages(). -- Add type annotations. +- Add type annotations and integrate ``mypy`` and ``pyright``. -- Add support for Python 3.10 - 3.14. +- Switch to ``pyproject.toml`` based project setup. -- Drop support for Python 3.9 and below. +- Add support for Python 3.11 - 3.15. -- Fix Flake8 errors. +- Drop support for Python 3.10 and below. + +- Support Pypy 3.12. + +- Fix linting errors. - Use GitHub Actions for CI. - Add tests for 100% coverage. -- Update docs. +- Update docs and adjust sphinx config. + +- Make an overall cleanup. + +- Fix readthedocs integration. + +- Replace flake8, black, isort, pyupgrade and pre-commit with Ruff_. + + .. _Ruff: https://docs.astral.sh/ruff + +- Remove coveralls integration. + +- Adjust the deployment strategy: + + * Move the Pypi upload from ``zest.release`` to ``gh-actions``. + + * Use ``v`` + version as release tags like ``v1.0.0``. + + * So we still use ``zest.release`` but without publishing to Pypi. + The Pypi upload is triggered by pushing the new release tag to GitHub. + This happens in the Release workflow in ``.github/workflows/release.yml``. + With this workflow we get Trusted Publishing with short-lived OIDC tokens + that PyPI issues to one specific repository, workflow file and environment (``pypi``). + We also get PEP 740 provenance and can set required reviewers for the environment + and a ruleset who can create release tags and trigger releases. 0.2 (2020-01-29) From d871ea342af68e8536a590a29a240793db39d017 Mon Sep 17 00:00:00 2001 From: Henri Hulski Date: Fri, 9 Oct 2026 19:55:24 +0200 Subject: [PATCH 8/9] chore: add tracked Git pre-commit hook for Ruff checks --- .gitattributes | 2 + .githooks/pre-commit | 93 ++++++++++++++++++++++++++++++++++++++++++++ CHANGES.txt | 2 + doc/developing.rst | 17 ++++++++ 4 files changed, 114 insertions(+) create mode 100644 .gitattributes create mode 100755 .githooks/pre-commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e5c6b4a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* text=auto +.githooks/* text eol=lf diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..2b3ce42 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,93 @@ +#!/usr/bin/env bash + +abort() { + printf '%s\n' "$@" >&2 + exit 1 +} + +tmpdir=$(mktemp -d "${TMPDIR:-/tmp}/morepath-ruff.XXXXXX") || + abort 'Ruff pre-commit check: could not create a temporary directory.' +trap 'rm -rf "$tmpdir"' EXIT + +list_file=$tmpdir/staged-files +staged_file=$tmpdir/staged +formatted_file=$tmpdir/formatted + +# Write the list to a file first so a git failure is not silently ignored. +git diff --cached --name-only --diff-filter=ACMR -z -- '*.py' '*.pyi' \ + >"$list_file" || + abort 'Ruff pre-commit check: could not list the staged files.' + +python_files=() +while IFS= read -r -d '' path; do + python_files+=("$path") +done <"$list_file" + +if (( ${#python_files[@]} == 0 )); then + exit 0 +fi + +if [[ -x .venv/bin/ruff ]]; then + ruff_cmd=.venv/bin/ruff +elif [[ -f .venv/Scripts/ruff.exe ]]; then + ruff_cmd=.venv/Scripts/ruff.exe +elif command -v ruff >/dev/null 2>&1; then + ruff_cmd=$(command -v ruff) +elif command -v ruff.exe >/dev/null 2>&1; then + ruff_cmd=$(command -v ruff.exe) +else + abort 'Ruff not found in .venv or PATH.' \ + "Install it with pip install -e '.[lint]'" +fi + +# report