Skip to content

Commit 033c973

Browse files
authored
Merge branch 'master' into jci/issue35245
2 parents ac8f8a0 + 98a4a32 commit 033c973

File tree

2 files changed

+20
-13
lines changed

2 files changed

+20
-13
lines changed

openedx/core/djangoapps/util/management/commands/dump_settings.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ class Command(BaseCommand):
3333
* _("hello") # <-- this will become just "hello"
3434
* "hello"
3535
36-
Furthermore, objects which are not easily JSON-ifiable will stringified using their `repr(...)`, e.g.:
37-
* "Path('my/path')" # a Path object
38-
* "<lms.myapp.MyClass object at 0x704599fa2fd0>" # some random class instance
39-
* "<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>" # sys.stderr
36+
Furthermore, functions and classes are printed as JSON objects like:
37+
{
38+
"module": "path.to.module",
39+
"qualname": "MyClass.MyInnerClass.my_method", // Or, "<lambda>"
40+
"source_hint": "MY_SETTING = lambda: x + y", // For <lambda>s only
41+
}
4042
41-
and lambdas are printed by *roughly* printing out their source lines (it's impossible in Python to get the *exact*
42-
source code, as it's been compiled into bytecode).
43+
And everything else will be stringified as its `repr(...)`.
4344
"""
4445

4546
def handle(self, *args, **kwargs):
@@ -82,12 +83,18 @@ def _to_json_friendly_repr(value: object) -> object:
8283
# Print gettext_lazy as simply the wrapped string
8384
return proxy_args[0]
8485
try:
86+
module = value.__module__
8587
qualname = value.__qualname__
8688
except AttributeError:
8789
pass
8890
else:
89-
if qualname == "<lambda>":
90-
# Handle lambdas by printing the source lines
91-
return "lambda defined with line(s): " + inspect.getsource(value).strip()
91+
# Handle functions and classes by printing their location (plus approximate source, for lambdas)
92+
return {
93+
"module": module,
94+
"qualname": qualname,
95+
**({
96+
"source_hint": inspect.getsource(value).strip(),
97+
} if qualname == "<lambda>" else {}),
98+
}
9299
# For all other objects, print the repr
93100
return repr(value)

openedx/core/djangoapps/util/tests/test_dump_settings.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def test_for_lms_settings(capsys):
2626
# Check: tuples are converted to lists
2727
assert isinstance(dump['XBLOCK_MIXINS'], list)
2828

29-
# Check: objects (like classes) are repr'd
30-
assert "<class 'xmodule.x_module.XModuleMixin'>" in dump['XBLOCK_MIXINS']
29+
# Check: classes are converted to dicts of info on the class location
30+
assert {"module": "xmodule.x_module", "qualname": "XModuleMixin"} in dump['XBLOCK_MIXINS']
3131

3232
# Check: nested dictionaries come through OK, and int'l strings are just strings
3333
assert dump['COURSE_ENROLLMENT_MODES']['audit']['display_name'] == "Audit"
@@ -46,8 +46,8 @@ def test_for_cms_settings(capsys):
4646
# Check: tuples are converted to lists
4747
assert isinstance(dump['XBLOCK_MIXINS'], list)
4848

49-
# Check: objects (like classes) are repr'd
50-
assert "<class 'xmodule.x_module.XModuleMixin'>" in dump['XBLOCK_MIXINS']
49+
# Check: classes are converted to dicts of info on the class location
50+
assert {"module": "xmodule.x_module", "qualname": "XModuleMixin"} in dump['XBLOCK_MIXINS']
5151

5252
# Check: nested dictionaries come through OK, and int'l strings are just strings
5353
assert dump['COURSE_ENROLLMENT_MODES']['audit']['display_name'] == "Audit"

0 commit comments

Comments
 (0)