Skip to content

Conversation

@feanil
Copy link
Contributor

@feanil feanil commented Jan 20, 2026

This PR migrates edx-platform to use the modern pyproject.toml settnigs file instead of setup.py and setup.cfg.

Switching to this should help us make other future switches of tools more easily as a lot of the docs and capabilities of the new tools require putting config in a pyproject.toml.

We could have just added the pyproject.toml file without removing/relocating everything else but that seemed like it would just be taking on debt that we don't need to. Instead, with the help of Claude Code, I've migrated all the existing settings to the new file.

This PR is best reviewed on a commit by commit basis as that will make it easier to review the diffs more easily in smaller chunks.

For entrypoint validation, I used this script before and after each commit to verify that the entrypoints did not get screwed up in any of this:
verify_entrypoints.py

@feanil feanil force-pushed the feanil/pyproject_toml branch 2 times, most recently from 6153d91 to 87302cd Compare January 20, 2026 18:04
@feanil feanil requested review from bmtcril and ormsbee January 20, 2026 18:36
@feanil feanil marked this pull request as ready for review January 20, 2026 18:48
@feanil feanil requested a review from kdmccormick January 21, 2026 14:44
@feanil feanil enabled auto-merge (rebase) January 23, 2026 15:55
@bmtcril
Copy link
Contributor

bmtcril commented Jan 26, 2026

There are quite a few place that still reference setup.py, mostly where documentation points to entrypoints. Can you clean those up as part of this?

@feanil feanil requested review from a team, farhan, irtazaakram and salman2013 as code owners January 26, 2026 20:57
@feanil
Copy link
Contributor Author

feanil commented Jan 26, 2026

Done.

Copy link
Contributor

@bmtcril bmtcril left a comment

Choose a reason for hiding this comment

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

This looks good to me, but I think will break Tutor's ability to run openedx-platform mounted (since it seems to explicitly look for setup.py). Given that, I suspect other downstream systems and deployment tools will have similar problems and we should probably make this a DEPR (fast track?) to at least increase visibility and give Tutor maintainers a heads up before merging.

https://github.com/overhangio/tutor/blob/7e6741b6d3b5093040104651939996eb77f29514/docs/dev.rst?plain=1#L39

https://github.com/overhangio/tutor/blob/7e6741b6d3b5093040104651939996eb77f29514/tutor/templates/jobs/init/mounted-directories.sh#L16

@feanil feanil disabled auto-merge January 27, 2026 16:10
@feanil
Copy link
Contributor Author

feanil commented Jan 27, 2026

@bmtcril good callout, I've created #37952 to give folks some time and an announcement to transition. We won't make any breaking changes till Feb 10

feanil and others added 12 commits January 27, 2026 12:07
Adds initial pyproject.toml with build system configuration using
setuptools>=61.0 (PEP 621 compatible). No functional changes yet -
setup.py remains fully functional.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates package metadata from setup.py including version, dependencies,
and package definitions.

Changes package name from "Open edX" to "openedx-platform" to comply
with PEP 508 (no spaces allowed). This is safe as the package is not
published and dependents rely on entry points, not the package name.

Simplifies setup.py to contain only entry_points, which will be migrated
in subsequent commits.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates 30 xblock.v1 entry points from setup.py. Removes XBLOCKS
constant as it's no longer needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates 1 xblock_asides.v1 entry point from setup.py. Removes
XBLOCKS_ASIDES constant as it's no longer needed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates 19 openedx.course_tab entry points from setup.py.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates 11 openedx.course_app entry points from setup.py.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates 4 openedx.course_tool entry points from setup.py.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates 17 lms.djangoapp entry points from setup.py.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates 14 cms.djangoapp entry points from setup.py. Preserves
important comment explaining why discussion app (from LMS) is
imported into Studio process.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates 17 openedx.block_structure_transformer entry points from
setup.py.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates final 6 entry point groups from setup.py (user_partition_scheme,
ace.policy, call_to_action, learning_context, dynamic_partition_generator,
console_scripts).

Simplifies setup.py to just call setup() with no arguments - all entry
points now defined in pyproject.toml.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrates pytest configuration from setup.cfg, preserving all settings
and comments including warning filters and test discovery patterns.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
feanil and others added 3 commits January 27, 2026 12:07
Migrates complete importlinter configuration from setup.cfg, preserving
all 4 contracts, ignore_imports with explanatory comments, and GitHub
issue references.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Removes setup.py as all configuration has been migrated to pyproject.toml
(PEP 621).

Verification confirms:
- Package installs correctly with pip install -e .
- All 142 entry points discoverable via importlib.metadata
- All tool configurations (pytest, pycodestyle, isort, importlinter) working
- Django checks pass for both LMS and CMS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update documentation, comments, and docstrings throughout the codebase
to reflect the migration from setup.py to pyproject.toml:

- Transformer class docstrings: changed to reference "entry point name
  in the package configuration" for better future-proofing
- Block structure module docs: updated to reference pyproject.toml
- Test file comments: updated entry point references
- Config files (tox.ini, pytest.ini): updated references
- Documentation (extension_points.rst, course apps ADRs): updated to
  reference pyproject.toml with inclusive language for external packages
- Requirements documentation (github.in): updated with inclusive language
- edxmako README: modernized install command to use pip install

Historical ADRs and references to external packages that may still use
setup.py were intentionally left unchanged or updated with inclusive
language acknowledging both pyproject.toml and setup.py.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@feanil feanil force-pushed the feanil/pyproject_toml branch from b1abfc5 to 21968c5 Compare January 27, 2026 17:07
python_classes =
python_files = tests.py test_*.py tests_*.py *_tests.py __init__.py

[pycodestyle]
Copy link
Contributor

@bradenmacdonald bradenmacdonald Jan 27, 2026

Choose a reason for hiding this comment

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

If we move from pycodestyle to ruff for basic PEP8-style checks (and later pylint -> ruff as well), we could fully delete setup.cfg 😎

It's actually very simple to do! I implemented it just now with open-craft@88f4374

Copy link
Contributor

Choose a reason for hiding this comment

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

That's why I was reviewing this, in the hopes of finally pushing this forward. openedx/public-engineering#348 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, agreed! I think it will be great to unblock that and other modernization efforts with this PR. It already felt kind of big so I didn't want to add the other tooling changes to it but I'd love to work on them or have others work on them once this lands!

Copy link
Member

@kdmccormick kdmccormick left a comment

Choose a reason for hiding this comment

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

Thanks for doing this. LGTM presuming you agree on the point about the fast-track DEPR for the project rename.

Comment on lines +178 to +180

[project.entry-points.console_scripts]
xmodule_assets = "xmodule.static_content:main"
Copy link
Member

Choose a reason for hiding this comment

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

Oops, this is a leftover from the Paver clean-up. That script is now just a no-op that raises a warning. You could remove it here or I could remove it in a followup PR, either way.

Suggested change
[project.entry-points.console_scripts]
xmodule_assets = "xmodule.static_content:main"

This cleans up the underlying script: #37967

build-backend = "setuptools.build_meta"

[project]
name = "openedx-platform"
Copy link
Member

@kdmccormick kdmccormick Jan 30, 2026

Choose a reason for hiding this comment

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

When installed alongside the Open_edX package, this yields AmbiguousPlugin error once XBlock code is hit (and I presume the same is true of other plugin code).

# see that both are installed
app@lms:~/edx-platform$ pip freeze | grep edx-pl
-e git+ssh://git@github.com/kdmccormick/edx-platform@50da2801443140091eb41cffa0976ba1611e09de#egg=Open_edX
-e git+ssh://git@github.com/kdmccormick/edx-platform@50da2801443140091eb41cffa0976ba1611e09de#egg=openedx_platform

# run a command which queries the plugin registry --> AmbiguousPluginError
app@lms:~/edx-platform$ ./manage.py lms shell -c 'from xblock.core import XBlock ; print(XBlock.load_class("course"))'
.....
Traceback (most recent call last):
  File "/openedx/edx-platform/./manage.py", line 92, in <module>
    execute_from_command_line([sys.argv[0]] + django_args)
  File "/openedx/venv/lib/python3.11/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/openedx/venv/lib/python3.11/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/openedx/venv/lib/python3.11/site-packages/django/core/management/base.py", line 420, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/openedx/venv/lib/python3.11/site-packages/django/core/management/base.py", line 464, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/openedx/venv/lib/python3.11/site-packages/django/core/management/commands/shell.py", line 247, in handle
    exec(options["command"], {**globals(), **self.get_namespace(**options)})
  File "<string>", line 1, in <module>
  File "/mnt/xblock/xblock/plugin.py", line 173, in load_class
    selected_entry_point = select(identifier, all_entry_points)
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/xblock/xblock/plugin.py", line 73, in default_select
    default_plugin = _default_select_no_override(identifier, block_entry_points)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/mnt/xblock/xblock/plugin.py", line 49, in _default_select_no_override
    raise AmbiguousPluginError(all_entry_points)
xblock.plugin.AmbiguousPluginError: Ambiguous entry points for course: xmodule.course_block.CourseBlock, xmodule.course_block.CourseBlock

Of course the fix is very easy (see below). But I think this warrants a quick fast-track DEPR and inform in #dev so that tutor maintainers and baremetal devs know what to do?

# after pulling down the package rename commit:
# uninstall the old name of the package (Open_edX) and wipe its egg-info,
# then re-install it under the new name (openedx-platform) 
app@f7e0b83d45c0:~/edx-platform$ pip uninstall --yes Open_edX && rm -rf Open_edX.egg-info && pip install -e .
Found existing installation: Open-edX 0.13
Uninstalling Open-edX-0.13:
  Successfully uninstalled Open-edX-0.13
Obtaining file:///openedx/edx-platform
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Preparing editable metadata (pyproject.toml) ... done
Requirement already satisfied: setuptools in /openedx/venv/lib/python3.11/site-packages (from openedx-platform==0.13) (69.1.1)
Building wheels for collected packages: openedx-platform
  Building editable for openedx-platform (pyproject.toml) ... done
  Created wheel for openedx-platform: filename=openedx_platform-0.13-0.editable-py3-none-any.whl size=17393 sha256=e8ea7a34193eab4dac5b60bb3da31a8fd726735f120c7101cd4573df057a2738
  Stored in directory: /tmp/pip-ephem-wheel-cache-_u74dh2c/wheels/4e/75/f9/c7a68bdebe77de1d8cfffab7a584c23dedb8c22a6826f2c016
Successfully built openedx-platform
Installing collected packages: openedx-platform
  Attempting uninstall: openedx-platform
    Found existing installation: openedx-platform 0.13
    Uninstalling openedx-platform-0.13:
      Successfully uninstalled openedx-platform-0.13
Successfully installed openedx-platform-0.13

# check that only one version of platform is installed
app@f7e0b83d45c0:~/edx-platform$ pip freeze | grep edx-pl
-e git+ssh://git@github.com/kdmccormick/edx-platform@21968c5fb2c163227328ebf57251d32663edf658#egg=openedx_platform

# run a command which queries the plugin registry --> all good
app@f7e0b83d45c0:~/edx-platform$ ./manage.py lms shell -c 'from xblock.core import XBlock ; print(XBlock.load_class("course"))'
....
<class 'xmodule.course_block.CourseBlock'>

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.

5 participants