Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions xblock/cds_init_args_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
Minimal mixin for Split Mongo: pops ``cds_init_args`` and exposes ``get_cds_init_args``.

``XModuleMixin`` does the same; use this when ``XModuleMixin`` is omitted from the
runtime mixin list so ``construct_xblock_from_class(..., cds_init_args=...)`` still works.
"""


class CdsInitArgsMixin:
"""
Initialization data used by SplitModuleStoreRuntime to defer FieldData initialization.

Mirrors the ``cds_init_args`` handling in ``xmodule.x_module.XModuleMixin`` without
pulling in the rest of XModule behavior.
"""

def __init__(self, *args, **kwargs):
self._cds_init_args = kwargs.pop("cds_init_args", None)
super().__init__(*args, **kwargs)

def get_cds_init_args(self):
"""Get initialization data used by SplitModuleStoreRuntime to defer FieldData initialization."""
if self._cds_init_args is None:
raise KeyError("cds_init_args was not provided for this XBlock")
if self._cds_init_args is False:
raise RuntimeError("Tried to get SplitModuleStoreRuntime cds_init_args twice for the same XBlock.")
args = self._cds_init_args
self._cds_init_args = False
return args
19 changes: 19 additions & 0 deletions xblock/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from web_fragments.fragment import Fragment

from xblock.cds_init_args_mixin import CdsInitArgsMixin
from xblock.core import XBlock, XBlockAside, XML_NAMESPACES
from xblock.fields import Field, BlockScope, Scope, ScopeIds, UserScope
from xblock.field_data import FieldData
Expand Down Expand Up @@ -1273,6 +1274,24 @@ def mix(self, cls):
else:
base_class = cls
mixins = self._mixins
if (
hasattr(base_class, "__name__")
and base_class.__name__ == "VideoBlock"
and getattr(base_class, "is_extracted", False)
):
def _is_xmodule_mixin(mixin):
return (
getattr(mixin, "__name__", None) == "XModuleMixin"
or f"{getattr(mixin, '__module__', '')}.{getattr(mixin, '__name__', '')}"
== "xmodule.x_module.XModuleMixin"
)

# Split Mongo passes ``cds_init_args`` into the block constructor; XModuleMixin pops it.
# If we drop XModuleMixin, substitute this minimal mixin in the same MRO slot.
mixins = tuple(
CdsInitArgsMixin if _is_xmodule_mixin(m) else m
for m in mixins
)

mixin_key = (base_class, mixins)

Expand Down
Loading