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
6 changes: 3 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ jobs:
PYTHON_PATH: ${{ steps.sp.outputs.python-path }}
run: |
just setup "$PYTHON_PATH"
just install-docs
- name: Install Emacs
if: ${{ github.event.inputs.debug == 'true' }}
run: |
Expand All @@ -61,6 +60,7 @@ jobs:
run: |
just check-lint
just check-format
just check-types
just check-package
just check-types-isolated
just check-docs
just check-readme
just check-package
10 changes: 3 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,9 @@ jobs:
PYTHON_PATH: ${{ steps.sp.outputs.python-path }}
run: |
just setup "$PYTHON_PATH"
just install
- name: Run Unit Tests
run: |
just test-all
just test

- name: Store coverage files
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
Expand Down Expand Up @@ -124,10 +123,9 @@ jobs:
PYTHON_PATH: ${{ steps.sp.outputs.python-path }}
run: |
just setup "$PYTHON_PATH"
just install
- name: Run Unit Tests
run: |
just test-all
just test

- name: Store coverage files
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
Expand Down Expand Up @@ -178,10 +176,9 @@ jobs:
PYTHON_PATH: ${{ steps.sp.outputs.python-path }}
run: |
just setup "$env:PYTHON_PATH"
just install
- name: Run Unit Tests
run: |
just test-all
just test

- name: Store coverage files
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
Expand Down Expand Up @@ -213,7 +210,6 @@ jobs:
PYTHON_PATH: ${{ steps.sp.outputs.python-path }}
run: |
just setup "$PYTHON_PATH"
just install

- name: Get coverage files
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131
Expand Down
39 changes: 29 additions & 10 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
repos:
- repo: local
hooks:
- id: lint
name: Lint
entry: just lint
language: system
pass_filenames: false
- id: format
name: Format
entry: just format
language: system
pass_filenames: false
- id: lint
name: Lint
entry: just lint
language: system
pass_filenames: false

- id: format
name: Format
entry: just format
language: system
pass_filenames: false

- id: typing
name: Typing
entry: just check-types
language: system
pass_filenames: false

- id: docs
name: Docs
entry: just check-docs
language: system
pass_filenames: false

- id: pip
name: Package
entry: just check-package
language: system
pass_filenames: false
50 changes: 50 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import inspect


def first_breakable_line(obj) -> tuple[str, int]:
"""
Return the absolute line number of the first executable statement
in a function or bound method.
"""
import ast
import textwrap

func = obj.__func__ if inspect.ismethod(obj) else obj

source = inspect.getsource(func)
source = textwrap.dedent(source)
filename = inspect.getsourcefile(func)
assert filename
_, start_lineno = inspect.getsourcelines(func)

tree = ast.parse(source)

for node in tree.body[0].body:
if (
isinstance(node, ast.Expr)
and isinstance(node.value, ast.Constant)
and isinstance(node.value.value, str)
):
continue

return filename, start_lineno + node.lineno - 1

# fallback: just return the line after the def
return filename, start_lineno + 1


def pytest_runtest_call(item):
# --trace cli option does not work for unittest style tests so we implement it here
test = getattr(item, "obj", None)
if item.config.option.trace and inspect.ismethod(test):
from IPython.terminal.debugger import TerminalPdb

try:
file = inspect.getsourcefile(test)
assert file
dbg = TerminalPdb()
dbg.set_break(*first_breakable_line(test))
dbg.cmdqueue.append("continue")
dbg.set_trace()
except (OSError, AssertionError):
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except (OSError, AssertionError):
except (OSError, AssertionError):
# Best-effort debugger setup: ignore failures to locate source or set breakpoints.

Copilot uses AI. Check for mistakes.
pass
92 changes: 56 additions & 36 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,22 @@ install-uv:
install-uv:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

# setup the venv and pre-commit hooks
# setup the venv, pre-commit hooks
setup python="python":
uv venv -p {{ python }}
@just run pre-commit install
@just install-precommit

# install git pre-commit hooks
install-precommit:
@just run pre-commit install
@just run --no-default-groups --group precommit --exact --isolated pre-commit install

# update and install development dependencies
install *OPTS:
@just install-precommit
uv sync {{ OPTS }}
@just run pre-commit install

# install documentation dependencies
install-docs:
uv sync --group docs --all-extras
_install-docs:
uv sync --no-default-groups --group docs --all-extras

[script]
_lock-python:
Expand All @@ -48,16 +47,28 @@ _lock-python:

# lock to specific python and versions of given dependencies
test-lock +PACKAGES: _lock-python
uv add {{ PACKAGES }}
uv add --no-sync {{ PACKAGES }}
uv sync --reinstall --no-default-groups --no-install-project

# run static type checking
check-types:
@just run mypy
@just run pyright
# run static type checking with mypy
check-types-mypy *RUN_ARGS:
@just run --no-default-groups --all-extras --group typing {{ RUN_ARGS }} mypy

# run static type checking with pyright
check-types-pyright *RUN_ARGS:
@just run --no-default-groups --all-extras --group typing {{ RUN_ARGS }} pyright

# run all static type checking
check-types: check-types-mypy check-types-pyright

# run all static type checking in an isolated environment
check-types-isolated:
@just check-types-mypy --exact --isolated
@just check-types-pyright --exact --isolated

# run package checks
check-package:
@just run pip check
uv pip check

# remove doc build artifacts
[script]
Expand All @@ -80,11 +91,11 @@ clean-git-ignored:
clean: clean-docs clean-env clean-git-ignored

# build html documentation
build-docs-html: install-docs
build-docs-html: _install-docs
@just run sphinx-build --fresh-env --builder html --doctree-dir ./doc/build/doctrees ./doc/source ./doc/build/html

# build pdf documentation
build-docs-pdf: install-docs
build-docs-pdf: _install-docs
@just run sphinx-build --fresh-env --builder latexpdf --doctree-dir ./doc/build/doctrees ./doc/source ./doc/build/pdf

# build the docs
Expand All @@ -102,14 +113,14 @@ open-docs:
webbrowser.open(f'file://{os.getcwd()}/doc/build/html/index.html')

# build and open the documentation
docs: install-docs build-docs-html open-docs
docs: _install-docs build-docs-html open-docs

# serve the documentation, with auto-reload
docs-live: install-docs
@just run sphinx-autobuild doc/source doc/build --open-browser --watch src --port 8000 --delay 1
docs-live:
@just run --no-default-groups --group docs sphinx-autobuild doc doc/_build --open-browser --watch src --port 8000 --delay 1
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs-live runs sphinx-autobuild against doc/doc/_build, but the rest of the justfile (and the repository layout) uses doc/source as the source and doc/build as the build output. As written, this will fail because doc/_build doesn’t exist and it won’t pick up conf.py from doc/source. Align the paths with the other docs targets (or update the other targets if the intent is to move the docs root).

Suggested change
@just run --no-default-groups --group docs sphinx-autobuild doc doc/_build --open-browser --watch src --port 8000 --delay 1
@just run --no-default-groups --group docs sphinx-autobuild ./doc/source ./doc/build/html --open-browser --watch src --port 8000 --delay 1

Copilot uses AI. Check for mistakes.

_link_check:
-uv run sphinx-build -b linkcheck -Q -D linkcheck_timeout=10 ./doc/source ./doc/build
-uv run --no-default-groups --group docs sphinx-build -b linkcheck -Q -D linkcheck_timeout=10 ./doc/source ./doc/build

# check the documentation links for broken links
[script]
Expand All @@ -128,11 +139,11 @@ check-docs-links: _link_check

# lint the documentation
check-docs:
@just run doc8 --ignore-path ./doc/build --max-line-length 100 -q ./doc
@just run --no-default-groups --group lint doc8 --ignore-path ./doc/build --max-line-length 100 -q ./doc

# fetch the intersphinx references for the given package
[script]
fetch-refs LIB: install-docs
fetch-refs LIB: _install-docs
import os
from pathlib import Path
import logging as _logging
Expand All @@ -154,53 +165,62 @@ fetch-refs LIB: install-docs

# lint the code
check-lint:
@just run ruff check --select I
@just run ruff check
@just run --no-default-groups --group lint ruff check --select I
@just run --no-default-groups --group lint ruff check

# check if the code needs formatting
check-format:
@just run ruff format --check
@just run --no-default-groups --group lint ruff format --check

# check that the readme renders
check-readme:
@just run -m readme_renderer ./README.md -o /tmp/README.html
@just run --no-default-groups --group lint -m readme_renderer ./README.md -o /tmp/README.html

_check-readme-quiet:
@just --quiet check-readme

# sort the python imports
sort-imports:
@just run ruff check --fix --select I
@just run --no-default-groups --group lint ruff check --fix --select I

# format the code and sort imports
format: sort-imports
just --fmt --unstable
@just run ruff format
@just run --no-default-groups --group lint ruff format

# sort the imports and fix linting issues
lint: sort-imports
@just run ruff check --fix
@just run --no-default-groups --group lint ruff check --fix

# fix formatting, linting issues and import sorting
fix: lint format

# run all static checks
check: check-lint check-format check-types check-package check-docs check-docs-links check-readme

# run all tests
test-all:
@just run pytest --cov-append
# run all checks including documentation link checking (slow)
check-all: check check-docs-links
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check already includes check-docs-links, so check-all: check check-docs-links will run link checking twice. Either remove check-docs-links from check and keep it in check-all, or drop the redundant dependency in check-all.

Suggested change
check-all: check check-docs-links
check-all: check

Copilot uses AI. Check for mistakes.

# run tests
test *TESTS:
@just run pytest --cov-append {{ TESTS }}
@just run --no-default-groups --exact --group test --isolated pytest {{ TESTS }} --cov
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just test adds a bare --cov even though pytest is already configured with coverage options in pyproject.toml (--cov=enum_properties, --cov-branch). Passing --cov without a target can expand coverage collection to the whole environment and can change results/performance. Consider removing the extra --cov here (or replace it with --cov-append if the goal is to preserve data across multiple invocations with the same COVERAGE_FILE).

Suggested change
@just run --no-default-groups --exact --group test --isolated pytest {{ TESTS }} --cov
@just run --no-default-groups --exact --group test --isolated pytest {{ TESTS }}

Copilot uses AI. Check for mistakes.

# debug an test
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in comment: “debug an test” → “debug a test”.

Suggested change
# debug an test
# debug a test

Copilot uses AI. Check for mistakes.
debug-test *TESTS:
@just run pytest \
-o addopts='-ra -q' \
-s --trace --pdbcls=IPython.terminal.debugger:Pdb \
--headed {{ TESTS }}
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug-test passes --headed, but there’s no dependency/plugin in this repo that provides that pytest option (e.g., pytest-playwright). This will make just debug-test … error with “unrecognized arguments: --headed”. Either remove --headed or add the required plugin and document it as a dev dependency.

Suggested change
--headed {{ TESTS }}
{{ TESTS }}

Copilot uses AI. Check for mistakes.

# run the pre-commit checks
precommit:
@just run pre-commit

# generate the test coverage report
coverage:
@just run coverage combine --keep *.coverage
@just run coverage report
@just run coverage xml
@just run --no-default-groups --group coverage coverage combine --keep *.coverage
@just run --no-default-groups --group coverage coverage report
@just run --no-default-groups --group coverage coverage xml

# run the command in the virtual environment
run +ARGS:
Expand All @@ -223,7 +243,7 @@ validate_version VERSION:
print(raw_version)

# issue a relase for the given semver string (e.g. 2.1.0)
release VERSION:
release VERSION: install check-all
@just validate_version v{{ VERSION }}
git tag -s v{{ VERSION }} -m "{{ VERSION }} Release"
git push origin v{{ VERSION }}
Loading
Loading