Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: XBlock overrides #778

Merged
merged 16 commits into from
Aug 19, 2024
Merged

feat: XBlock overrides #778

merged 16 commits into from
Aug 19, 2024

Conversation

nsprenkle
Copy link
Contributor

@nsprenkle nsprenkle commented Aug 7, 2024

Add ability to override another XBlock with the xblock.v1.overrides entrypoint.

Notes

Usage

setup(
    # ...
    entry_points={
        "xblock.v1.overrides": [
            "html = my_new_repo.my_new_block:HtmlBlock",
            "problem = my_new_repo.my_new_block:ProblemBlock",
            "video = my_new_repo.my_new_block:VideoBlock",
        ],
    }
)

Tests

  • Unit tests
  • Smoke tests in LMS
    • Overridden block types work as expected
    • Non-overridden block types work as expected
  • Tests in Studio
    • Overridden block types work as expected
    • Non-overridden block types work as expected
  • Import tests
    • Overridden block types work as expected
    • Non-overridden block types work as expected
  • Export tests
    • Overridden block types work as expected
    • Non-overridden block types work as expected
  • Other????

@farhan farhan requested a review from a team August 8, 2024 10:01
farhan
farhan previously requested changes Aug 8, 2024
Copy link
Contributor

@farhan farhan left a comment

Choose a reason for hiding this comment

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

@nsprenkle Thanks for creating the PR

  • Didn't do the manual testing
  • Done with the quick review, suggest some changes
  • Was thinking we are merging then filtering the entrypoints here but to keep the signature of method seems alright to me

xblock/plugin.py Outdated Show resolved Hide resolved
xblock/plugin.py Outdated Show resolved Hide resolved
xblock/plugin.py Outdated Show resolved Hide resolved
@nsprenkle nsprenkle requested a review from farhan August 8, 2024 15:19
@nsprenkle
Copy link
Contributor Author

@farhan, thanks for the review. Have tried to address all your comments and is ready for your re-review

xblock/plugin.py Outdated Show resolved Hide resolved
@farhan
Copy link
Contributor

farhan commented Aug 9, 2024

@kdmccormick PR seems alright to me. Your review is mandatory.

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.

Very nice implementation. Thanks so much for jumping in and making this happen. Just a few requests.

CHANGELOG.rst Outdated Show resolved Hide resolved
xblock/plugin.py Outdated Show resolved Hide resolved
xblock/plugin.py Outdated Show resolved Hide resolved
xblock/plugin.py Outdated Show resolved Hide resolved
xblock/plugin.py Outdated Show resolved Hide resolved
CHANGELOG.rst Show resolved Hide resolved
xblock/plugin.py Outdated Show resolved Hide resolved
@nsprenkle nsprenkle force-pushed the nsprenkle/xblock-overrides branch from df98da0 to e5b5967 Compare August 14, 2024 17:33
@nsprenkle
Copy link
Contributor Author

@kdmccormick and @farhan , have updated to your suggestions. Ready for re-review.

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.

A few more comments but nothing that needs re-review. I haven't manually tested, so I'm approving on the assumption that you have.

Thank a bunch @nsprenkle ! This will be awesome for site operators to have 🎸

docs/xblock-tutorial/edx_platform/overrides.rst Outdated Show resolved Hide resolved
docs/xblock-tutorial/edx_platform/overrides.rst Outdated Show resolved Hide resolved
docs/xblock-tutorial/edx_platform/overrides.rst Outdated Show resolved Hide resolved
xblock/test/test_plugin.py Show resolved Hide resolved
@kdmccormick kdmccormick dismissed farhan’s stale review August 15, 2024 12:44

changes addressed

farhan
farhan previously requested changes Aug 16, 2024
xblock/plugin.py Outdated
Comment on lines 68 to 80
# Get the default entry point
default_plugin = _default_select_no_override(identifier, block_entry_points)

# If we have an unambiguous override, that gets priority. Otherwise, return default.
if len(overrides) == 1:
return overrides[0]
elif len(overrides) > 1:
raise AmbiguousPluginError(all_entry_points)
return default_plugin
Copy link
Contributor

Choose a reason for hiding this comment

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

Following approach seems clean to me.
@kdmccormick You can give a second thought

    # Prioritize and return a single unambiguous override; otherwise, return the single entry point.
    # Raise errors for missing, multiple entry points, or multiple overrides.
    if len(all_entry_points) == 0:
        raise PluginMissingError(identifier)
    elif len(all_entry_points) > 1:
        raise AmbiguousPluginError(all_entry_points)
    elif len(overrides) > 1:
        raise AmbiguousPluginOverrideError(overrides)
    elif len(overrides) == 1:
        return overrides[0]
    else:  # len(all_entry_points) == 1
        return all_entry_points[0]
  1. Avoid introducing new method i-e- _default_select_no_override.
  2. Put the the _default_select_no_override docs in default_select method docs.
  3. Introduce separate Exception for multiple override. For example AmbiguousPluginOverrideError. We can also use AmbiguousPluginError but pass overrides and generate separate message for it.

Copy link
Member

Choose a reason for hiding this comment

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

Regarding _default_select_no_override -- Yeah, I do not feel strongly since it is an internal implementation detail, but combining the functions does make it easier to follow IMO. If you are willing to make that change @nsprenkle, great; if not, I don't want to block merging on this concern.

Regarding the error message -- @farhan makes a very good point, we should make it clear whether there are multiple regular plugins vs. multiple overrides. As it is, the error cases would be indistinguishable to an operator.

@nsprenkle , I don't have a preference between a new exception class vs. the same exception with a different message. If you do go with separate exceptions, please just make AmbiguousPluginOverrideError a subclass of AmbiguousPluginError so that existing catch AmbiguousPluginError statements will catch AmbiguousPluginOverrideError.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kdmccormick , added as a new Exception

xblock/plugin.py Outdated
Comment on lines 116 to 123
If multiple classes are found for either `{cls.entry_points}.overrides` or
`{cls.entry_points}`, it will raise an `AmbiguousPluginError`.

If `default` is provided, return it if no entry_point matching
`identifier` is found. Otherwise, will raise a PluginMissingError
If no classes are found for `{cls.entry_points}`, it will raise a `PluginMissingError`.
Copy link
Contributor

Choose a reason for hiding this comment

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

Swap both lines as per order

        If no classes are found for `{cls.entry_points}`, it will raise a `PluginMissingError`.


        If multiple classes are found for either `{cls.entry_points}.overrides` or
        `{cls.entry_points}`, it will raise an `AmbiguousPluginError`.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Arguably, load_class doesn't even care about those details since those reside in the select function. I would prefer to delete them entirely than split hairs over the ordering.

Copy link
Member

Choose a reason for hiding this comment

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

Arguably, load_class doesn't even care about those details since those reside in the select function.

+1, they are good as is

FWIW they are helpful lines to have in the docstring

@nsprenkle
Copy link
Contributor Author

@kdmccormick / @farhan. Will merge / create a new release on Monday. Thanks, both!

Copy link
Contributor

@farhan farhan left a comment

Choose a reason for hiding this comment

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

@nsprenkle Nice work 🌟
Rebase the branch, Squash merge it and release the new version

@nsprenkle nsprenkle force-pushed the nsprenkle/xblock-overrides branch from db7d24d to b9ac909 Compare August 19, 2024 14:55
@nsprenkle nsprenkle merged commit 2082432 into master Aug 19, 2024
10 checks passed
@nsprenkle nsprenkle deleted the nsprenkle/xblock-overrides branch August 19, 2024 15:39
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.

Xblock version 5.0.0 broke plugin
3 participants