Skip to content

build: modernize tooling to uv, pyproject.toml, and semantic-release - #249

Open
farhan wants to merge 5 commits into
openedx:masterfrom
farhan:farhan/modernize-python-repos
Open

build: modernize tooling to uv, pyproject.toml, and semantic-release#249
farhan wants to merge 5 commits into
openedx:masterfrom
farhan:farhan/modernize-python-repos

Conversation

@farhan

@farhan farhan commented Sep 2, 2026

Copy link
Copy Markdown

Important

PR implemented with the assistance of Claude Code. Refined and validated before being submitted for code review.

Caution

Manual baseline tag required before the first automated release. This repo's historical release tags are bare (2.4.1, 2.4.0, …), but python-semantic-release uses the default tag_format = "v{version}" and reads git tags as its only source for the last released version. None of the existing tags match, so PSR would re-derive the version from 0.0.0 and either refuse to release or publish a wrong version. Before enabling automated releases, tag the latest released commit (PyPI latest = 2.4.1) and push it:

git tag v2.4.1 <commit-of-2.4.1-release>
git push upstream v2.4.1

This does not affect this PR's CI (all green).

Modernize enmerkar-underscore
Part of openedx/public-engineering#518

Summary

  • enmerkar-underscore is published to PyPI: https://pypi.org/project/enmerkar-underscore/
  • Replace setup.py/setup.cfg with pyproject.toml (PEP 621 static metadata)
  • Switch from pip-compile to uv with PEP 735 dependency groups; commit uv.lock
  • Retain flake8 as the quality linter, as on master
  • Update CI to use astral-sh/setup-uv, run uv run tox, and SHA-pin all actions
  • Add python-semantic-release + release.yml (OIDC trusted publishing), replacing the token-based publish_pypi.yml
  • Version now derived from git tags via setuptools-scm; __version__ reads it from package metadata at runtime
  • Drop Python 3.11 support; set requires-python = ">=3.12"

Removed/Updated

Deleted files: setup.py, setup.cfg, requirements/

Removed workflows: publish_pypi.yml (replaced by release.yml), upgrade-python-requirements.yml (its pip-compile upgrade flow is replaced by the upgrade Makefile target running uv lock --upgrade)

Updated Makefile targets:

Target Change
requirements Added — uv sync --group dev
upgrade Now runs edx_lint write_uv_constraints + uv lock --upgrade (dropped all pip-compile calls)
lint Now runs flake8 src tests (previously targeted a non-existent django-babel-underscore directory)
test Now runs python -Wd -m pytest tests/ (dropped removed setup.py test)
coverage Retargeted coverage source to src/enmerkar_underscore
docs Simplified to make -C docs html (dropped sphinx-apidoc on a non-existent path)
release/dist Now use python -m build + twine instead of setup.py sdist upload

Python 3.11 dropped

Removed Python 3.11 from the tox envlist, CI matrix, and classifiers; the target is 3.12.

Versioning

setuptools-scm with dynamic = ["version"] — the repo publishes to PyPI, so python-semantic-release controls the version string at release time via git tags. __version__ is exposed at runtime via importlib.metadata.

Important Notes

  • Conventional commit format is now enforced on all future PRs to this repo via the existing commitlint.yml.
  • The pytest-pep8, pytest-flakes, and python-coveralls test dependencies were dropped: pytest-pep8 is incompatible with modern pytest (uses removed hook arguments), and its pep8/pyflakes checks are already covered by flake8 in the quality env; python-coveralls is an unused, deprecated coveralls uploader.
  • docs/conf.py contained invalid Python (import django-babel-underscore, version = django-babel-underscore.__version__) that would fail any docs build; it now reads the version via importlib.metadata. A docs tox environment is now part of the CI matrix.
  • make lint previously targeted a non-existent directory (effectively a no-op); now that it lints src tests, two pre-existing E302 blank-line issues were fixed.
  • Vendored third-party code under src/enmerkar_underscore/vendor/ is excluded from flake8.
  • The package already used a src/ layout on master; no layout change was needed.

Testing Notes

This PR has not been manually tested against the repo's own features. Testing relied on CI checks and local agent tooling (make requirements, make lint, make test, python -m build). Repo-owner is encouraged to run the repo's feature tests before merging.


🤖 Generated with Claude Code

Migrate packaging and dependency management to the current Open edX
standard so the repo stops depending on pip-compile and setup.py.

- Replace setup.py/setup.cfg with PEP 621 pyproject.toml (setuptools-scm)
- Switch pip-compile to uv with PEP 735 dependency groups; commit uv.lock
- Retain flake8 as the quality linter
- Update CI to astral-sh/setup-uv + uv run tox; SHA-pin all actions
- Add release.yml (python-semantic-release + OIDC PyPI publishing)
- Drop Python 3.11; set requires-python = ">=3.12"

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
farhan and others added 4 commits September 2, 2026 21:18
Publishing is handled by python-semantic-release and the PyPI publish
workflow in CI, so the manual `make release` (twine upload) target is a
redundant second release path and has been removed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The docs tox env now runs the same three builders master declared (html,
doctest, linkcheck) with warnings treated as errors (-W). Master listed
these but never ran them in CI, so they were dead and its doctest command
was broken (sphinx.ext.doctest was never enabled); this now wires docs
into CI and makes all three pass:

- tox.ini: set SPHINXOPTS=-W and add the doctest and linkcheck commands
- Makefile: pass -e to sub-make so SPHINXOPTS reaches docs/Makefile
- docs/conf.py: enable sphinx.ext.doctest so the doctest builder registers
- docs/index.rst: lengthen title underline (surfaced by -W)
- docs/_static: add the directory referenced by html_static_path
- README.rst: drop the dead pypip.in badge and repoint the 404 docs link

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the [tool.semantic_release.commit_parser_options] override so PSR
uses its default release tags (minor: feat; patch: fix, perf).
public-engineering#506 states the "docs" minor_tags override is specific
to the backend-plugin-sample example repo and that other libraries should
use the default value unless there is a documented reason not to.
enmerkar-underscore has none, so it follows the #506 default.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The docs had no static assets, so docs/_static/ existed only as an empty
directory kept alive by a .gitkeep placeholder to satisfy conf.py's
html_static_path = ['_static'] under the strict (-W) docs build. Remove
both the placeholder and the now-pointless setting; Sphinx no longer
looks for the directory and the -W html/doctest/linkcheck builds still
pass. Matches how openedx/XBlock handles a repo with no static assets.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@farhan farhan self-assigned this Sep 4, 2026
@farhan
farhan marked this pull request as ready for review September 4, 2026 08:22
from .vendor.markey.tools import TokenStream

__version__ = '2.4.1'
try:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This try and catch can be remove as this is an extra precaution, in case the exception would occour (which is very rare) would make version ambiguous.

Comment thread pyproject.toml
description = "Implements a underscore extractor for django-babel."
requires-python = ">=3.12"
license = "BSD-3-Clause"
license-files = ["LICENSE"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants