Repository navigation
Conversation
|
Thanks for the pull request, @irfanuddinahmad! This repository is currently maintained by 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 approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo 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:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. DetailsWhere 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:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #461 +/- ##
==========================================
- Coverage 94.19% 92.46% -1.74%
==========================================
Files 31 11 -20
Lines 3068 1327 -1741
Branches 191 145 -46
==========================================
- Hits 2890 1227 -1663
+ Misses 154 78 -76
+ Partials 24 22 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Hi @irfanuddinahmad - flagging that some checks and branch conflicts have popped up. |
|
Rebased on master — conflicts resolved, CI green. |
6458243 to
64f37bf
Compare
Modernize opaque-keys to uv + pyproject.toml (PEP 621/735) + python-semantic-release, and adopt src/ layout. Part of openedx/public-engineering#506 (tracked in openedx/public-engineering#516). - Move opaque_keys/ to src/opaque_keys/. - Replace setup.py with pyproject.toml (PEP 621 static metadata); remove the hardcoded __version__ in favor of importlib.metadata + setuptools-scm. - Switch from pip-compile to uv with PEP 735 dependency groups (test-base, test, django42, quality, doc, ci, dev); commit uv.lock. - Update tox.ini to use tox-uv's uv-venv-lock-runner. - Update CI to install uv (pinned to a commit SHA) and run uv sync / uv run tox. - Add python-semantic-release + release.yml, publishing to PyPI via OIDC. - Delete setup.py, requirements/*.in, requirements/*.txt, .github/workflows/pypi-publish.yml (superseded by release.yml). - tag_format = "v{version}" -- a manual v-prefixed release will bridge the existing unprefixed tag history (4.0.0, 3.1.0, ...) so future releases stay consistent. Addresses salman2013's PR review feedback: - Remove unexplained fail-fast: false in ci.yml. - Author metadata matches sample-plugin's convention (Open edX Project / oscm@openedx.org). - Keep the push trigger on ci.yml alongside workflow_call, per code owners' call (double CI run on master pushes accepted as fine). - Keep the CI job name as Tests, matching the pre-migration name (deferring the per-toxenv rename to avoid breaking required-status-check matching). - No codecov.yml -- it didn't change any pass/fail outcome and isn't required by this migration itself. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
64f37bf to
154466c
Compare
…odernize-python-tooling # Conflicts: # requirements/base.txt # requirements/ci.txt # requirements/dev.txt # requirements/django-test.txt # requirements/doc.txt # requirements/test.txt
…ecf0aa eecf0aa ("fix: remove unnecessary try/except around __version__") was meant to be a trivial 5-line cleanup but instead deleted everything from the try/except through the end of the file -- 385 lines, including the entire OpaqueKey class hierarchy. This broke every consumer that imports from the top-level opaque_keys module (e.g. opaque_keys.edx.django.models does `from opaque_keys import OpaqueKey`), causing an ImportError in CI's django42 job. Restored the full class definitions from the last commit before the bad edit (154466c), keeping the intended __version__ simplification (no try/except, matching the pattern used correctly elsewhere in this migration effort). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ernize-python-tooling requirements/*.txt conflicts (modified on master by an automated dependency-bump merge, deleted here in favor of uv.lock) resolved by keeping the deletion -- superseded by uv.lock/pyproject.toml. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ernize-python-tooling # Conflicts: # requirements/ci.txt # requirements/dev.txt # requirements/django-test.txt # requirements/doc.txt # requirements/pip-tools.txt # requirements/test.txt
…e job Matches openedx/sample-plugin's current release.yml; the custom OPENEDX_SEMANTIC_RELEASE_GITHUB_TOKEN secret isn't needed.
| dynamic = ["version"] | ||
| description = "Create and introspect course and xblock identities through a clear and consistent API" | ||
| readme = "README.rst" | ||
| license = "AGPL-3.0" |
There was a problem hiding this comment.
AGPL-3.0 is deprecated in the SPDX list, and under [project].license this is now published as a validated expression rather than as free text. The built wheel's METADATA carries:
License-Expression: AGPL-3.0
LICENSE:637-638 grants "either version 3 of the License, or (at your option) any later version", so this should be AGPL-3.0-or-later.
There was a problem hiding this comment.
Correction on this one, sorry. LICENSE:637-638 is inside the "How to Apply These Terms to Your New Programs" appendix that ships with every verbatim copy of the AGPL-3.0 text, so it isn't a grant this repo makes. What we published is setup.py:137's License :: OSI Approved :: GNU Affero General Public License v3, with no "or later". Nothing in the source or docs grants "or later" either. AGPL-3.0-only is the one that matches what we published; the deprecation half of the comment still stands.
There was a problem hiding this comment.
Looks like this is the last thing to resolve and then this is good to Switch it to AGPL-3.0-only and then I think this is good to go.
There was a problem hiding this comment.
Done — switched to AGPL-3.0-only in 04d7fd1 (setup.py:137's classifier has no "or later").
| id: release | ||
| uses: python-semantic-release/python-semantic-release@9a026e9303981c866c3425723009becb2437c757 # v10.6.2 | ||
| with: | ||
| github_token: ${{ secrets.OPENEDX_SEMANTIC_RELEASE_GITHUB_TOKEN }} |
There was a problem hiding this comment.
Use secrets.GITHUB_TOKEN here. The org secret isn't needed going forward, and sample-plugin, DoneXBlock, xblocks-core and xblocks-extra are all on the default token already.
There was a problem hiding this comment.
Already secrets.GITHUB_TOKEN here, verified — no change needed.
Makefile now assumes an already-synced/activated local env; uv run stays in CI workflow steps only. See openedx/ccx-keys#190 (review comment r4097501942). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…odernize-python-tooling # Conflicts: # requirements/base.txt # requirements/ci.txt # requirements/dev.txt # requirements/django-test.txt # requirements/doc.txt # requirements/test.txt
feanil
left a comment
There was a problem hiding this comment.
pyproject.toml:10 is still AGPL-3.0. Switch it to AGPL-3.0-only, per the correction on that thread. The rest looks right.
| dynamic = ["version"] | ||
| description = "Create and introspect course and xblock identities through a clear and consistent API" | ||
| readme = "README.rst" | ||
| license = "AGPL-3.0" |
There was a problem hiding this comment.
Looks like this is the last thing to resolve and then this is good to Switch it to AGPL-3.0-only and then I think this is good to go.
Pre-migration setup.py:137 classified this as "License :: OSI Approved :: GNU Affero General Public License v3" with no "or later"/"v3+" wording, so AGPL-3.0-only is the correct SPDX identifier, not AGPL-3.0-or-later. Per feanil's correction (review comment r4135968924). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
With this PR merged, my editable install of |
Summary
Modernize
opaque-keystouv+pyproject.toml(PEP 621/735) +python-semantic-release, and adoptsrc/layout.Part of openedx/public-engineering#506 (tracked in openedx/public-engineering#516).
opaque_keys/tosrc/opaque_keys/(see "src/layout" below).setup.pywithpyproject.toml(PEP 621 static metadata); remove thehardcoded
__version__in favor ofimportlib.metadata+setuptools-scm.uvwith PEP 735 dependency groups (test-base,test,django42,quality,doc,ci,dev); commituv.lock.tox.inito usetox-uv'suv-venv-lock-runner.uv(pinned to a commit SHA) and runuv sync/uv run tox.python-semantic-release+release.yml, publishing to PyPI via OIDC.commitlint.ymlalready existed and needed no changes.src/layoutPer the 2026-07-15 decision on openedx/public-engineering#506, motivated by
flat-layout editable installs not being reliably resolvable by
mypy.mypy.iniswitched from
files = opaque_keys(a literal path) topackages = opaque_keys(import-based resolution via the editable install), which is the actual fix. Verified
locally: editable install resolves correctly,
mypy/pylint/pycodestyleall pass,full test suite passes, and a built wheel installs
opaque_keysat the top level.One side effect: the top-level
settingstest-settings package (previously bundledinto the wheel only as an artifact of
setup.py's barefind_packages()) is nolonger picked up, since it lives outside
src/— its correct scope.Removed
Deleted files:
setup.py,requirements/*.in,requirements/*.txt,.github/workflows/pypi-publish.yml(superseded byrelease.yml'spublish_to_pypijob — the old token-based workflow triggered onrelease: publishedand would otherwise race the new OIDC-based publish oncesemantic-release starts creating releases/tags).
Not included
adoption is out of scope for this migration cycle (its own separate epic). Existing
pylint/pycodestyle/mypy config is left untouched.
edx-platform-style constraint-sync script: not applicable — this repo neverhad the
requirements/edx-platform-constraints.txt+check_pins.pymechanismthat pattern replaces.
Known out-of-scope gaps (flagging, not silently working around)
release.yml'spublish_to_pypijob publishes via OIDC (id-token: write, no storedcredentials) instead of the old
PYPI_UPLOAD_TOKEN. This requires a PyPIproject maintainer to add a trusted publisher for
edx-opaque-keys(PyPI project→ Publishing → Add a new publisher → GitHub, repo
openedx/opaque-keys,workflow
release.yml, no environment) before the first release can actuallypublish. Not a blocker for reviewing/merging this PR, but
publish_to_pypiwillfail on the first push to
masteruntil it's done..github/workflows/upgrade-python-requirements.yml. This repo has one,calling
openedx/.github's shared reusable workflow, which hardcodesADD_PATHS="requirements"for its PR-creation step with noadd_paths-styleinput exposed via
workflow_call. Now thatrequirements/is deleted,make upgrade's real output (uv.lock/pyproject.tomlchanges) won't match thathardcoded glob — the scheduled job will keep running but silently stop producing
real dependency-upgrade PRs (empty diff, no failure, no alert). This can't be
fixed from this repo; it needs a fix in
openedx/.githubitself (parameterizeadd_paths, or auto-detectuv.lockvs.requirements/).Versioning
Dynamic, via
setuptools-scmreading the latest git tag.tag_format = "v{version}"now, so a manual v-prefixed release will bridge the existing unprefixed tag history
(
4.0.0,3.1.0, ...) beforepython-semantic-releasestarts tagging.Testing Notes
Verified locally (macOS, Python 3.12):
uv lockresolves cleanly and stays in syncwith
pyproject.toml;uv run tox -e django42(407 passed),without-django(394passed),
docs, andquality(mypy/pylint/pycodestyle) all pass;python -m build(withSETUPTOOLS_SCM_PRETEND_VERSIONset) produces correctly-versionedwheels/sdists.
CI-only issues found and fixed after opening this PR: fully moving coverage config
off a stale
.coveragercthat was still shadowingpyproject.toml;.readthedocs.yaml(still pointed at the deletedrequirements/doc.txt, switched tomethod: uv/groups: [doc]);__init__.py'simportlib.metadatafallbacktry/except (not present pre-migration) simplified to a direct call, no pragma
needed.
codecov/projectshows a one-time ~1.6 point drop (94.03%→92.46%) once test fileswere correctly excluded from coverage measurement — not a real regression, patch
coverage is 100%. No
codecov.ymlthreshold added to absorb it; expected to showred on this PR.
A commit landed after this PR's initial approval that was meant to be a trivial
"remove the unnecessary
__version__try/except" cleanup, but instead deleted 385lines from
src/opaque_keys/__init__.py— the entireOpaqueKey/OpaqueKeyMetaclass/InvalidKeyErrorclass hierarchy, everything after the imports.This broke every consumer that imports from the top-level
opaque_keysmodule(e.g.
opaque_keys.edx.django.modelsdoesfrom opaque_keys import OpaqueKey),which is why CI's
django42job started failing with anImportError. Restored thefull class hierarchy from the last good commit, keeping the intended
__version__simplification. All tox envs (
django42,without-django,quality) re-verifiedpassing after the restore. Flagging explicitly here since the approval predates this
regression — worth a fresh look rather than relying on it.
Code reviewer notes
django42is the only Django version group for now (this repo'stox.inienvlist has only ever tested one Django version at a time); adding a
django52-style group later just needs[tool.uv].conflictsif two Djangopins need to coexist in one lockfile.
This PR was created with Claude Code.