From f6a458fa45122b6b2e71fb19c0b7a334174a03c3 Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Wed, 28 Jan 2026 09:40:47 -0500 Subject: [PATCH 1/3] docs: Add learnings about `_services.copy()` fix to preview.py Capturing what we learned in https://github.com/openedx/openedx-platform/pull/37900#issuecomment-3811194293 --- cms/djangoapps/contentstore/views/preview.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index 05fc1705e83e..f8d16bf64f45 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -200,6 +200,16 @@ def _prepare_runtime_for_preview(request, block): # See the docstring of `DjangoXBlockUserService`. deprecated_anonymous_user_id = anonymous_id_for_user(request.user, None) + # NOTE: As of Ulmo, these services only apply to the preview views. If you want a service to be present in all + # Studio ModuleStoreRuntimes, then add it to load_services_for_studio. + # HISTORICAL CONTEXT: Until Ulmo, the `block.runtime._services.update(service)` call below would + # actually update the services dictionary for all runtimes, as `_services` was aliased between them. + # This caused a grading bug, under certain conditions, so it was fixed + # in https://github.com/openedx/openedx-platform/pull/37825; now, every runtime gets a fresh, + # independent copy of `_services`. That's good, except that some Studio code had become dependent + # on the bugged behavior and thus expected the "preview" services below to be present in all Studio runtimes. + # We fixed the known instance of that bugged assumption here: https://github.com/openedx/openedx-platform/pull/37900. + # This comment is left here as a note for future devs investigating similar bugs. services = { "studio_user_permissions": StudioPermissionsService(request.user), "i18n": XBlockI18nService, From 9652adce62e22c7c51069b028f778ac52f6f5ff0 Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Wed, 28 Jan 2026 09:47:38 -0500 Subject: [PATCH 2/3] style: rm trailing whitespace --- cms/djangoapps/contentstore/views/preview.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index f8d16bf64f45..66a00e2542d5 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -204,12 +204,12 @@ def _prepare_runtime_for_preview(request, block): # Studio ModuleStoreRuntimes, then add it to load_services_for_studio. # HISTORICAL CONTEXT: Until Ulmo, the `block.runtime._services.update(service)` call below would # actually update the services dictionary for all runtimes, as `_services` was aliased between them. - # This caused a grading bug, under certain conditions, so it was fixed + # This caused a grading bug, under certain conditions, so it was fixed # in https://github.com/openedx/openedx-platform/pull/37825; now, every runtime gets a fresh, # independent copy of `_services`. That's good, except that some Studio code had become dependent # on the bugged behavior and thus expected the "preview" services below to be present in all Studio runtimes. # We fixed the known instance of that bugged assumption here: https://github.com/openedx/openedx-platform/pull/37900. - # This comment is left here as a note for future devs investigating similar bugs. + # This comment is left here as a note for future devs investigating similar bugs. services = { "studio_user_permissions": StudioPermissionsService(request.user), "i18n": XBlockI18nService, From 53fccae48436466ac76359b9a2b44bffbf5b8aa0 Mon Sep 17 00:00:00 2001 From: Kyle McCormick Date: Wed, 28 Jan 2026 13:53:27 -0500 Subject: [PATCH 3/3] style: line too long --- cms/djangoapps/contentstore/views/preview.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index 66a00e2542d5..b83158e35c76 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -208,7 +208,8 @@ def _prepare_runtime_for_preview(request, block): # in https://github.com/openedx/openedx-platform/pull/37825; now, every runtime gets a fresh, # independent copy of `_services`. That's good, except that some Studio code had become dependent # on the bugged behavior and thus expected the "preview" services below to be present in all Studio runtimes. - # We fixed the known instance of that bugged assumption here: https://github.com/openedx/openedx-platform/pull/37900. + # We fixed the known instance of that bugged assumption here: + # https://github.com/openedx/openedx-platform/pull/37900. # This comment is left here as a note for future devs investigating similar bugs. services = { "studio_user_permissions": StudioPermissionsService(request.user),