Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* text=auto
.githooks/* text eol=lf
93 changes: 93 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -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 <label> <fix label> <fix command> <files...>
report() {
local label=$1 fixlabel=$2 fix=$3
shift 3
printf '\n%s (%d):' "$label" "$#"
printf ' %q' "$@"
printf '\n%s: %s' "$fixlabel" "$fix"
printf ' %q' "$@"
printf '\n'
}

format_files=()
lint_files=()

for path in "${python_files[@]}"; do
git show ":$path" >"$staged_file" ||
abort "Could not read the staged content of $path."

# Format the staged content; a non-zero exit is a real failure here
# (for example a syntax error or a broken config).
# --force-exclude makes ruff honor its exclude settings for stdin input.
errors=$("$ruff_cmd" format --force-exclude --stdin-filename "$path" - \
<"$staged_file" 2>&1 >"$formatted_file") ||
abort "Ruff format failed on $path:" "$errors"

if ! cmp -s "$staged_file" "$formatted_file"; then
format_files+=("$path")
fi

# Lint the formatted content, so that violations the formatter
# fixes anyway (e.g. trailing whitespace) are not reported twice.
output=$("$ruff_cmd" check --force-exclude --no-fix \
--stdin-filename "$path" - <"$formatted_file" 2>&1)
case $? in
0) ;;
1) lint_files+=("$path") ;;
*) abort "Ruff check failed on $path:" "$output" ;;
esac
done

if (( ${#format_files[@]} || ${#lint_files[@]} )); then
printf '%s\n' 'Ruff checks failed - no files were changed.'
if (( ${#format_files[@]} )); then
report 'Needs formatting' 'Fix with' 'ruff format' "${format_files[@]}"
fi
if (( ${#lint_files[@]} )); then
report 'Lint errors' 'Try' 'ruff check --fix' "${lint_files[@]}"
fi
printf '\n%s\n' 'Review and stage the fixes, then retry the commit.'
exit 1
fi
26 changes: 12 additions & 14 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,33 @@ on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

permissions: {}

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
tests:
name: "Python ${{ matrix.python-version }}"
runs-on: "ubuntu-latest"
permissions:
contents: read

strategy:
fail-fast: false
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:
# 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"
with:
persist-credentials: false
- 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 }}"
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 }}
41 changes: 41 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Release

on:
push:
tags: ["v[0-9]*"]

permissions: {}

jobs:
build:
name: 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:
name: 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
15 changes: 0 additions & 15 deletions .pre-commit-config.yaml

This file was deleted.

34 changes: 34 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -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
49 changes: 44 additions & 5 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
CHANGES
*******

0.13 (unreleased)
=================
1.0.0 (unreleased)
==================

- Add type annotations and integrate ``mypy`` and ``pyright``.

- Switch to ``pyproject.toml`` based project setup.

- Replace ``repoze.lru.lru_cache`` with ``functools.lru_cache``
to get rid of the dependency and gain typing support.

- ``reg.arginfo`` is now implemented manually using
``inspect.signature``, instead of relying on the deprecated
Expand All @@ -14,11 +21,43 @@ CHANGES
is now very limited, compared to ``inspect.signature``, since
that already properly handles ``self`` parameters.

- Added support for Python 3.10, 3.11, 3.12, 3.13 and 3.14
- Add support for Python 3.11, 3.12, 3.13, 3.14 and 3.15.

- Drop support for Python below 3.11.

- Support Pypy 3.12.

- Use GitHub Actions for CI.

- Fix docs, docstrings and Sphinx config.

- Update developing documentation.

- Make an overall cleanup.

- Fix readthedocs integration.

- Replace flake8, black, isort, pyupgrade and pre-commit with Ruff_.

.. _Ruff: https://docs.astral.sh/ruff

- Add a tracked Git pre-commit hook for Ruff checks on staged Python files.

- Remove coveralls integration.

- Adjust the deployment strategy:

* Move the Pypi upload from ``zest.release`` to ``gh-actions``.

- Drop support for Python below 3.10
* Use ``v`` + version as release tags like ``v1.0.0``.

- Use GitHub Actions for CI
* 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.12 (2020-01-29)
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include *.txt *.rst *.cfg *.py *.ini *.toml *.yaml
exclude .installed.cfg
exclude .githooks/pre-commit
recursive-include reg *.py py.typed
recursive-include tests *.py
recursive-include doc *.rst Makefile *.py *.bat
3 changes: 0 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
:target: https://github.com/morepath/reg/actions?workflow=CI
:alt: CI Status

.. image:: https://coveralls.io/repos/github/morepath/reg/badge.svg?branch=master
:target: https://coveralls.io/github/morepath/reg?branch=master

.. image:: https://img.shields.io/pypi/v/reg.svg
:target: https://pypi.org/project/reg/

Expand Down
1 change: 0 additions & 1 deletion develop_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# development
-e '.[test,coverage,lint,docs,mypy,pyright]'
pre-commit
tox >= 4

# releaser
Expand Down
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@

# General information about the project.
project = "Reg"
copyright = "2010 - %s, Morepath Developers" % datetime.today().year
copyright = f"2010 - {datetime.today().year}, Morepath Developers"
author = "Martijn Faassen"

# The version info for the project you're documenting, acts as replacement for
Expand Down
Loading
Loading