From 496bf2d72ffb286a44d134542e9c7eb6cc683fff Mon Sep 17 00:00:00 2001 From: farhan Date: Fri, 26 Jun 2026 20:56:58 +0500 Subject: [PATCH] fix: support AnnotatableBlock in the new content runtime While extracting the Annotatable block from openedx-platform, we parted ways with RawMixin, which contains the parse_xml_new_runtime method. That method is still required by the extracted annotatable block to make it compatible with the new content runtime, and it was missed during extraction. So this change copies the method from RawMixin into the extracted AnnotatableBlock. Without this, loading an annotatable block in a Content Library crashed with "XML Serialization is only supported with OpenedXContentRuntime", because the base XBlock.parse_xml treats annotatable's nested OLX (,

, ) as child blocks and calls runtime.add_node_as_child(), which the new runtime does not implement. Co-Authored-By: Claude Opus 4.8 (1M context) --- xblocks_contrib/annotatable/annotatable.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/xblocks_contrib/annotatable/annotatable.py b/xblocks_contrib/annotatable/annotatable.py index 3e698d1a..e6a44365 100644 --- a/xblocks_contrib/annotatable/annotatable.py +++ b/xblocks_contrib/annotatable/annotatable.py @@ -246,6 +246,28 @@ def workbench_scenarios(): ), ] + @classmethod + def parse_xml_new_runtime(cls, node, runtime, keys): + """ + Interpret the parsed XML in `node`, creating a new instance of this + module. + """ + # In the new/openedx_content-based runtime, XModule parsing (from + # XmlMixin) is disabled, so definition_from_xml will not be + # called, and instead the "normal" XBlock parse_xml will be used. + # However, it's not compatible with RawMixin, so we implement + # support here. + data_field_value = cls.definition_from_xml(node, None)[0]["data"] + for child in node.getchildren(): + node.remove(child) + # Get attributes, if any, via normal parse_xml. + try: + block = super().parse_xml_new_runtime(node, runtime, keys) + except AttributeError: + block = super().parse_xml(node, runtime, keys) + block.data = data_field_value + return block + @classmethod def definition_from_xml(cls, xml_object, system): if len(xml_object) == 0 and len(list(xml_object.items())) == 0: