Skip to content

refactor: migrate ENABLE_EXAM_SETTINGS_HTML_VIEW and LICENSING off FEATURES-as-dict - #39017

Open
feanil wants to merge 3 commits into
masterfrom
feanil/features-dict-exam-settings-licensing
Open

refactor: migrate ENABLE_EXAM_SETTINGS_HTML_VIEW and LICENSING off FEATURES-as-dict#39017
feanil wants to merge 3 commits into
masterfrom
feanil/features-dict-exam-settings-licensing

Conversation

@feanil

@feanil feanil commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Two production/settings readers that still went through the FEATURES dict.

  • ENABLE_EXAM_SETTINGS_HTML_VIEWxmodule/course_block.py read it via getattr(settings, 'FEATURES', {}).get('ENABLE_EXAM_SETTINGS_HTML_VIEW', False) to mark the legacy proctored/timed-exam CourseBlock fields as deprecated. It had no flat definition, so this adds an annotated ENABLE_EXAM_SETTINGS_HTML_VIEW = False to openedx/envs/common.py and reads it via getattr(settings, 'ENABLE_EXAM_SETTINGS_HTML_VIEW', False) — matching the adjacent DEFAULT_MOBILE_AVAILABLE/ENABLE_SPECIAL_EXAMS readers (getattr kept because the module is imported in contexts where settings may not be configured, e.g. asset compilation).
  • LICENSINGlms/envs/production.py and cms/envs/production.py set XBLOCK_SETTINGS["VideoBlock"]["licensing_enabled"] from FEATURES["LICENSING"]. LICENSING is a flat setting (openedx/envs/common.py) available via the common star-import, so read it directly.

Verified: xmodule/tests/test_course_block.py passes (33); reloading course_block under @override_settings(ENABLE_EXAM_SETTINGS_HTML_VIEW=True) yields EXAM_SETTINGS_HTML_VIEW_ENABLED == True; ruff clean. Operator configs that set these via FEATURES: YAML continue to work through the production FEATURES:-to-settings loop.

feanil and others added 3 commits August 24, 2026 11:13
xmodule/course_block.py read this flag via
getattr(settings, 'FEATURES', {}).get('ENABLE_EXAM_SETTINGS_HTML_VIEW', False) to decide
whether the legacy proctored/timed-exam CourseBlock fields are marked deprecated in the
advanced settings editor. The flag had no flat definition anywhere.

Add an annotated ENABLE_EXAM_SETTINGS_HTML_VIEW = False to openedx/envs/common.py and read
it with getattr(settings, 'ENABLE_EXAM_SETTINGS_HTML_VIEW', False) -- matching the adjacent
DEFAULT_MOBILE_AVAILABLE / ENABLE_SPECIAL_EXAMS readers. getattr is kept (rather than bare
settings.X) because this module is imported in contexts where settings may not be fully
configured, e.g. static asset compilation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
lms/envs/production.py and cms/envs/production.py set
XBLOCK_SETTINGS["VideoBlock"]["licensing_enabled"] from FEATURES["LICENSING"]. LICENSING is
a flat setting (defined in openedx/envs/common.py) and is available in these modules through
the common star-import, so read it directly instead of through the FEATURES dict.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
xmodule/course_block.py read six settings through getattr(settings, 'NAME',
default): DEFAULT_COURSE_VISIBILITY_IN_CATALOG, DEFAULT_MOBILE_AVAILABLE,
ENABLE_EXAM_SETTINGS_HTML_VIEW, ENABLE_SPECIAL_EXAMS, ENABLE_PROCTORED_EXAMS,
and PROCTORING_BACKENDS. All six are defined in openedx/envs/common.py, which is
star-imported into both lms/envs/common.py and cms/envs/common.py, so every
settings module this block runs under (production, test, devstack, pact,
docker-production) defines them. The getattr defaults are therefore unreachable.

The defaults did not guard the "settings not configured at all" case either:
getattr(settings, 'NAME', default) returns the default only on AttributeError,
but an unconfigured LazySettings raises ImproperlyConfigured, which propagates
regardless. So the accompanying "updating assets does not have settings defined"
comment described a protection getattr never provided.

Read all six directly as settings.NAME and drop the stale comment. Behavior is
unchanged: the values match the previous getattr defaults, and where they did
not (PROCTORING_BACKENDS), the setting is always defined so the default never
fired.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@feanil
feanil marked this pull request as ready for review September 2, 2026 12:27
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.

1 participant