openedx / XBlock

Framework for building custom learning components that run in the Open edX LMS!
https://docs.openedx.org/projects/xblock/en/latest/xblock-tutorial/index.html
Apache License 2.0
452 stars 217 forks source link

feat!: collapse extraneous XBlock mixins #718

Closed kdmccormick closed 6 months ago

kdmccormick commented 7 months ago

Supporting info

Proposed in this DEPR issue:

excerpt:

The implementations of the XBlock and XBlockAside classes are chopped into about a dozen tiny mixins. This was done many years ago, probably for some mix of reasons including code organization and theoretical reusability. Now, in 2024 in the openedx GitHub org, there are uses of the XBlock, XBlockAside, and XBlockMixin classes, but we do not see uses of any of the other classes or mixins (other than one extraneous reference to HandlersMixin in edx-platform, which can be removed).

Unfortunately, these mixins make it harder/impossible to write robust type constraints for XBlock and XBlockAside. They also make it harder to find code in the XBlock package. See discussion.

The edx-platform upgrade PR is here:

Description

Various extraneous classes have been removed from the XBlock API. We believe that most, if not all, XBlock API users will be unaffected by this change.

Diagram

Generated with pyreverse and dot.

Before

xblock-before

After

xblock-after

Change list

Bumps version from 2.0.0 to 3.0.0.

Testing

Docs

You can preview the doc additions by clicking "Details" on the docs build, hitting "View Docs", and going to the "XBlock API" page).

Homepage: https://docsopenedxorg--718.org.readthedocs.build/projects/xblock/en/718/index.html New XBlockAside generated docs: https://docsopenedxorg--718.org.readthedocs.build/projects/xblock/en/718/xblock.html#xblock.core.XBlockAside

XBlock and XBlockAside attributes

From the root of the repo, you can run this script in order to compare the list of attributes on XBlock/XBlockAside before and after this PR, both for the classes and their instances.


rm -rf dir_before dir_after
mkdir dir_before dir_after

cd dir_before
git switch master
python -c 'from xblock import core; print(*sorted(dir(core.XBlock)), sep="\n")' > block_cls.list
python -c 'from xblock import core; print(*sorted(dir(core.XBlock(None, None, None))), sep="\n")' > block_obj.list
python -c 'from xblock import core; print(*sorted(dir(core.XBlockAside)), sep="\n")'  > aside_cls.list
python -c 'from xblock import core; print(*sorted(dir(core.XBlockAside(None, None, runtime=None))), sep="\n")' > aside_obj.list
cd ..

cd dir_after
git switch kdmccormick/mixins
python -c 'from xblock import core; print(*sorted(dir(core.XBlock)), sep="\n")' > block_cls.list
python -c 'from xblock import core; print(*sorted(dir(core.XBlock(None, None, None))), sep="\n")' > block_obj.list
python -c 'from xblock import core; print(*sorted(dir(core.XBlockAside)), sep="\n")'  > aside_cls.list
python -c 'from xblock import core; print(*sorted(dir(core.XBlockAside(None, None, runtime=None))), sep="\n")' > aside_obj.list
cd ..

diff dir_before list dir_after

This should yield:

diff dir_before/aside_cls.list dir_after/aside_cls.list
39a40
> context_key
49a51
> index_dictionary
62a65
> usage_key
diff dir_before/aside_obj.list dir_after/aside_obj.list
42a43
> context_key
52a54
> index_dictionary
67a70
> usage_key
diff dir_before/block_cls.list dir_after/block_cls.list
0a1
> __annotations__
diff dir_before/block_obj.list dir_after/block_obj.list
0a1
> __annotations__

which indicates that:

kdmccormick commented 6 months ago

@ormsbee

Can you manually invoke the decorator on Blocklike after it's defined? I haven't done something like this in ages, but I think it'd be something like this?

Good idea. That bit of backwards incompatibility was making me a little nervous, so I'm glad to smooth it out. The syntax ended up being:

Blocklike.needs('field-data')(Blocklike)