Skip to content

feat: modernize Python tooling (pyproject.toml + uv) - #891

Open
irfanuddinahmad wants to merge 9 commits into
masterfrom
irfanuddinahmad/uv-migration
Open

feat: modernize Python tooling (pyproject.toml + uv)#891
irfanuddinahmad wants to merge 9 commits into
masterfrom
irfanuddinahmad/uv-migration

Conversation

@irfanuddinahmad

@irfanuddinahmad irfanuddinahmad commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Modernizes this repo's Python tooling per the org-wide standardization tracked in openedx/public-engineering#513 (and the parent openedx/public-engineering#506):

  • Consolidate tool config (isort/pytest settings) into pyproject.toml, replacing setup.cfg/pytest.ini. This is a deployed Django service, not a published package, so [project] is minimal (name/version/requires-python only, no PyPI packaging metadata) and no semantic-release is added.
  • Switch dependency management from pip-compile to uv: requirements/*.in+*.txt are replaced by PEP 735 [dependency-groups] + a single uv.lock. Since there's no [project.dependencies] list, runtime deps live in an explicit base group that test/quality/doc/production/dev all compose via {include-group = "base"}.
  • Add a tox.ini (this repo had none before, running CI via make targets directly) modeled on the sibling service repos' pattern, update the Makefile, and switch CI to install uv and run tests via uv run tox.

Part of openedx/public-engineering#513.

Test plan

  • uv lock resolves cleanly
  • Could not fully verify uv sync/uv run tox on my machine (no libmysqlclient/pkg-config locally to build mysqlclient from source) -- CI's ubuntu-latest runners have these preinstalled, so this needs verifying there.

🤖 Generated with Claude Code

@openedx-webhooks openedx-webhooks added open-source-contribution PR author is not from Axim or 2U core contributor PR author is a Core Contributor (who may or may not have write access to this repo). labels Jul 9, 2026
@openedx-webhooks

Copy link
Copy Markdown

Thanks for the pull request, @irfanuddinahmad!

This repository is currently maintained by @sameeramin.

Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review.

🔘 Get product approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

Details
Where can I find more information?

If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources:

When can I expect my changes to be merged?

Our goal is to get community contributions seen and reviewed as efficiently as possible.

However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@github-project-automation github-project-automation Bot moved this to Needs Triage in Contributions Jul 9, 2026
@mphilbrick211 mphilbrick211 moved this from Needs Triage to Ready for Review in Contributions Jul 13, 2026
@mphilbrick211
mphilbrick211 requested a review from sameeramin July 13, 2026 15:59
Irfan Ahmad and others added 5 commits July 15, 2026 09:15
Move isort/pytest settings from setup.cfg/pytest.ini into pyproject.toml.
license-manager is a deployed Django service, not a published package, so
no [build-system]/packaging metadata is added here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace requirements/*.in + *.txt with PEP 735 dependency-groups in
pyproject.toml and a single uv.lock. Since this repo has no [project]
packaging metadata, runtime deps live in an explicit `base` group that
test/quality/doc/production/dev all compose via {include-group = "base"}.
Add a tox.ini (this repo had none before) modeled on the sibling service
repos' pattern, update the Makefile, and switch CI to install uv and run
tests via `uv run tox`.

Note: could not fully verify `uv sync`/`uv run tox` locally on this
machine (no libmysqlclient/pkg-config for building mysqlclient from
source) -- `uv lock` resolves cleanly; full sync needs verifying via CI.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
CI failed with "make is not allowed, use allowlist_externals to allow it" --
missed adding allowlist_externals when the pii_check testenv was migrated
to the uv-venv-lock-runner.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…t dirs

CI failed with "Unable to import 'ddt'/'pytest'" -- make lint scans the
whole license_manager tree, which includes per-app tests/ subdirectories,
so pylint needs to resolve their test-only imports. The old CI happened
to work because its "quality" job actually installed the full dev.txt
(quality+test combined via validation.txt) before running make lint, not
a quality-only environment. Compose {include-group = "test"} instead of
just "base" so quality gets the same effective scope.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
uv treats a dependency-group literally named "dev" as an implicit
default group, synced in addition to whatever --group is explicitly
requested, unless [tool.uv].default-groups says otherwise. Every
`uv sync --group X` call site here (Makefile targets, CI workflows)
was silently also installing the entire dev/test/quality/ci superset
(including mysqlclient) regardless of which group was actually asked
for -- confirmed by reproducing "uv sync --group ci" trying to build
mysqlclient because "license-manager:dev depends on mysqlclient".
Setting default-groups = [] makes every sync install exactly what's
asked for. Also add .venv to .gitignore (uv's default venv dir; only
the old bare "venv" pattern existed).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@irfanuddinahmad
irfanuddinahmad force-pushed the irfanuddinahmad/uv-migration branch from ad526d4 to ccc7a8e Compare July 15, 2026 04:17
Same category of fixes farhan flagged on the batch's other reviewed PRs:

- Makefile: prefix uv run on all bare tool invocations (test, coverage,
  isort_check, isort, style, lint, pii_check) -- these fail on a clean
  checkout where only uv is installed
- ci.yml: remove actions/setup-python from both the tests and quality
  jobs (redundant once astral-sh/setup-uv gets python-version) and add
  enable-cache/python-version to setup-uv
- mysql8-migrations-check.yml: add python-version to setup-uv (already
  had enable-cache) and drop the now-redundant actions/setup-python step
- Migrate .coveragerc into [tool.coverage.run] and delete the old file

package = false and no CHANGELOG.rst already correctly reflect this
being a deployed service, not a published package -- no changes needed
there. Codecov here uses the CLI (uv run --with codecov codecov), not
codecov-action, so no SHA-pinning concern.

Verified: pyproject.toml parses, uv sync (no lock drift), Makefile
dry-run confirms the uv run prefixes resolve correctly. Could not run
the full tox matrix locally -- same mysqlclient build environment
limitation as other repos in this batch.

@sameeramin sameeramin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM 👍🏼

Irfan Ahmad added 2 commits July 28, 2026 17:43
Cross-checked against review comments/fixes from openedx-ledger#242,
edx-enterprise-subsidy-client#222, enterprise-access#1015, and
enterprise-subsidy#441.

- Add the [tool.coverage.report]/[html] sections that were missing
  (only [tool.coverage.run] existed).
- Wrap the bare `coverage erase` (clean target) and
  `coverage html && open ...` (html_coverage target) with `uv run`.
…olutions

Both factors previously synced the same `test` dependency-group (locked
against Django 5.2) and then force-overrode just the Django package via
tox's deps=, leaving every other transitive dependency resolved against
the 5.2-compatible graph even under django42.

Add a real `django42` dependency-group (mirroring `test-base` with
Django>=4.2,<5.0 instead of >=5.2,<6.0), mark it mutually exclusive with
`test`/`quality`/`doc`/`dev` via [tool.uv].conflicts, and point tox's
django42 factor at it directly instead of overriding Django after the
fact. `uv lock` now produces two distinct resolutions - e.g.
django-autocomplete-light 4.0.3 vs 5.0.0, django-filter 25.1 vs 25.2,
and social-auth-app-django 5.4.3 vs 6.0.0.
Replaced uv pip uninstall/install --no-binary (x2, for mysqlclient and
xmlsec) with a single native `uv sync --group production --group mysql8
--no-binary-package mysqlclient --no-binary-package xmlsec`. mysqlclient
is already a real project dependency (installs via `production`); xmlsec
wasn't declared anywhere, so added a dedicated `mysql8` group for it --
same as master's pre-migration behavior, where it came in only via this
same job's own pip uninstall+reinstall step. Verified both genuinely
trigger source builds (--no-cache, to bypass any stale cached wheel).

No merge conflict with master (already CLEAN/MERGEABLE) and no codecov
threshold to reconsider in this repo. The django42/django52 fork-
resolution fix was already on this branch (11e536e) before I started.

Found while auditing this repo for uv pip usage per the lessons learned on
openedx-platform#38915.
@mphilbrick211 mphilbrick211 moved this from Ready for Review to Ready to Merge in Contributions Aug 19, 2026
@mphilbrick211

Copy link
Copy Markdown

Hi @sameeramin! Are you able to merge this for us?

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

Labels

core contributor PR author is a Core Contributor (who may or may not have write access to this repo). open-source-contribution PR author is not from Axim or 2U

Projects

Status: Ready to Merge

Development

Successfully merging this pull request may close these issues.

5 participants