During load phase, when an otherwise NORMAL_KEY ends with a trailing _, eg, NORMAL_KEY_, this will register the attribute as a key collector and duplicate gets/sets/dels there. Mapping protocol.
Example:
#1-one.py
OPTIONS_ = {}
OPTIONS_HELLO = 1
#2-two.py
OPTIONS_WHY = [1,2,3]
Now settings shows:
>>> settings.OPTIONS_
{"HELLO": 1, "WHY": [1,2,3]}
>>> settings.OPTIONS_HELLO
1
>>> # settings.OPTIONS? automatic property...
Use case is simple adding of collectors from sources like env:// or json, but python-based part files can use this property to implement load-time validation (raise if bad value), deep-nesting/merging (create [A][B] = 1 from A_B = 1), mangling (eg. copy deprecated names with warning), ...
Since this is load time, dynamic collectors should be cautious of side effects. A key may be added/removed multiple times during part load.
During load phase, when an otherwise
NORMAL_KEYends with a trailing_, eg,NORMAL_KEY_, this will register the attribute as a key collector and duplicate gets/sets/dels there. Mapping protocol.Example:
Now
settingsshows:Use case is simple adding of collectors from sources like
env://or json, but python-based part files can use this property to implement load-time validation (raise if bad value), deep-nesting/merging (create[A][B] = 1fromA_B = 1), mangling (eg. copy deprecated names with warning), ...Since this is load time, dynamic collectors should be cautious of side effects. A key may be added/removed multiple times during part load.