config_decorator package
Submodules
config_decorator.config_decorator module
Class @decorator for defining exquisite settings configurations.
Concepts
A configurable setting is some value in an application that can be “globally” set.
Most often, a configurable setting is used so that an end user can change the behavior of an application. All settings might be saved to a file on disk and read whenever the application starts. In this case, the collection of configurable settings might simply be called the “user options”.
But you could also use configurable settings to decouple code. For example, rather than two objects sharing values by interacting with one another, they could instead share values using a common settings configuration. Then the two objects only need to know common key names, and not about each other.
At its core, each setting has a name (its key), and a value. The value could be a default value specified in code, or it could be a value somehow specified by the user, such as from the command line, or from an environment variable, or from a file saved on disk.
Furthermore, each setting has a description (some helpful text),
a type (int, bool, list, etc.),
an optional validation function,
and other qualities
(see more in the key_chained_val module).
Multiple settings can be organized into
hierarchically-related groups, or sections
(as represented by the ConfigDecorator class,
but generated using the @section decorator).
In addition to settings, each section may also contain sections (or, more aptly, subsections).
You can think of the complete hierarchical collection of sections and their settings as a settings configuration, or as the user options.
Each section of a settings configuration is represented by a
ConfigDecorator instance. The settings themselves are
each represented by a KeyChainedVal instance.
Typical usage
To create a settings configuration, use the @section decorator
once to designate the root object of the settings configuration.
The decorated class is then used to decorate each subsection class,
as well as each settings method. (And then the subsection classes can
be used to decorate sub-subsections and their settings, and so on.)
For example:
def generate_config(self):
'''An example setting configuration generator.'''
@section(None)
class RootSection(object):
pass
@RootSection.section('foo')
class RootSectionFoo(object):
def __init__(self):
pass
@RootSection.section('bar')
class RootSectionBar(object):
def __init__(self):
pass
@RootSectionBar.section('baz')
class BarSubsectionBaz(object):
def __init__(self):
pass
@property
@RootSectionBar.setting(
"An example setting.",
)
def bat(self):
return 'Ta-Da!'
return RootSection
In the example above, there are two root sections defined, “foo” and “bar”. And there’s one setting defined in the “bar.baz” subsection. You could run, e.g.,:
>>> cfg = generate_config()
>>> cfg.bar.baz.bat
'Ta-Da!'
Note that because of how decorators operate on a class (they execute
after the class is defined), the settings defined in a class definition
must be decoratored using that class’s parent section. (In the previous
example, @RootSectionBar.setting was used inside BarSubsectionBaz.)
Important
You cannot access the decorated user class using its name.
The
@sectiondecorator wraps the class definition in aConfigDecoratorinstance, and it returns that object.So in the previous example,
RootSectionis aConfigDecoratorinstance and not aclassobject. I.e., you cannot callobj = RootSection().
- class config_decorator.config_decorator.ConfigDecorator(cls, cls_or_name, parent=None, default_value_type=None, default_allow_none=False)[source]
Bases:
objectRepresents one section of a hierarchical settings configuration.
A settings configuration is a collection of user-settable key-value settings grouped and organized into a tree-like graph of sections.
A settings configuration has one root section, which may have any number of subsections and settings therein. Each subsection may also contain any number of subsections and settings.
Each
ConfigDecoratorwraps a user class that defines the settings in that section. To add subsections to a section, use the section object’sConfigDecorator.section()decorator. One or more classes are defined and decorated this way to build a hierarchical settings configuration.Important
Users of this library do not call
ConfigDecorator()directly.Rather, object creation is handled by the
config_decorator.section()andConfigDecorator.section()decorators.- Parameters:
cls – The class being decorated.
cls_or_name – The section name to use in the settings configuration.
parent – A reference to the parent section (a
ConfigDecoratorobject), orNonefor the root section.default_value_type – Default value_type for unstructured @settings (
KeyChainedValueobjects) under this section (e.g., where the config does not define any specific key names, but it expects to read those key names from user’s config). Typically used for unstructuredlistconfig.default_allow_none – Default
allow_nonefor unstructured @settings (KeyChainedValueobjects) under this section. Pairs well withdefault_value_type.
- _innercls
The class object that was decorated (whose name now references a
ConfigDecoratorinstance, and not theclassobject that was defined.
- _innerobj
An instance of the class object that was decorated.
- _parent
A reference to the parent
ConfigDecoratorsection, orNonefor the root section.
- _kv_cache
An ordered dict of settings defined by the class, used internally when build the settings configuration (i.e., used internally while sourcing Python code).
- _key_vals
This section’s settings, stored as a dict (setting name ⇒
config_decorator.key_chained_val.KeyChainedValueobject).
- _sections
An ordered dict of subsections (section name ⇒
ConfigDecoratorobject).
- _name
The section name, specified in the decorator, or inferred from the class name.
- SEP = '.'
Separator character used to (un)flatten section.subsection.settings paths.
- apply_items(config, **kwargs)[source]
Prepares the passed dict with the config, stringifying values by default.
Args: Same as for _prepare_dict().
- as_dict(**kwargs)[source]
Returns a new dict representing the configuration settings tree.
Args: Same as for _prepare_dict().
- property asobj
Returns a representation of the section that can be accessed like an object.
- Returns:
An object that overrides
__getattr__to find the section or setting in the current section that has the given name.The object also has a magic
_method, if you want to use dot-notation to get at a subsection, but then want access to the actual section object.
- classmethod create_root_for_section(section_name, section_cdec)[source]
Creates a new ConfigDecorator as root of the passed instance.
- del_not_persisted(config_obj)[source]
Removes entries from config_obj without a value from the “config” source.
- find_all(parts, skip_sections=False)[source]
Returns all matching sections or settings.
- Parameters:
parts –
A list of strings used to find matching sections and settings.
If empty, the currect section is returned (the identify function).
If just one name is specified in “parts”, all sections and settings that match that name are assembled and returned (by performing a breadth-first search of the current section and its subsections).
If more than one name is specified, the leading names form the path to the section to search; and then any section or setting in that section matching the final name in “parts” is returned.
skip_sections – If True, do not include section objects in the results.
- Returns:
A list of matching sections and settings.
- find_setting(parts)[source]
Returns the setting with the given path and name.
- Parameters:
parts – A list of strings indicating the section names and setting name.
- Returns:
The indentified setting, or None if no setting found.
- forget_config_values()[source]
Visits every setting and removes the value from the “config” source.
Unless a setting’s value can be gleaned from an environment variable, or was parsed from the command line, or was forceable set by the code, calling this method will effectively set the value back to its default.
- section(name, default_value_type=None, default_allow_none=False)[source]
Class decorator used to create subsections.
For instance:
@section(None) class RootSection(object): pass @RootSection.section('My Subsection') class MySubsection(object): pass @MySubsection.section('A Grandsubsection') class AGrandsubsection(object): pass
- Parameters:
name – The name of the subsection.
- Returns:
A
ConfigDecoratorinstance.
See
config_decorator.config_decorator.section()section()for a more complete explanation.
- section_path(sep=None, _parts=None)[source]
Returns a flattened canonicalized representation of the complete section path.
- Parameters:
sep – The separator character to use, defaults to ConfigDecorator.SEP.
_parts – Used internally on recursive calls to this function.
- Returns:
The “path” to this section, as derived from the name of the root section on downward to this section, using the separator character between each successive section’s name.
- set_section(section_name, sub_dcor)[source]
Assigns the passed ConfigDecorator to the section key named.
# NOTE: This method is clobbery.
- setdefault(*args)[source]
Ensures the indicated setting exists, much like
dict.setdefault.- Parameters:
args – one or more arguments indicating the section path and setting name, and one final argument indicating the default setting value to use.
- Returns:
The setting value (the existing value if already set; otherwise the new default value, which is also the last item in
*args).
- setting(message=None, **kwargs)[source]
Method decorator used to create individual settings in a configuration section.
For instance:
... @RootSection.section('My Subsection') class MySubsection(object): @property @RootSection.setting( "An example setting.", name="my-setting" ) def my_setting(self): return 'My Setting's Default Value'
- update(other, errors_ok=False)[source]
Alias to
update_gross().
- update_gross(other, errors_ok=False)[source]
Consumes all values from a dict, creating new sections and settings as necessary.
- Parameters:
other – The dict whose contents will be consumed.
See also
update_known(), which does not add unknown values.This method is less discerning. It grabs everything from
otherand shoves it in the ConfigDecorator object, creating section and setting objects as necessary.You might find this useful if your app handles arbitrary config. In this case, the application cannot define the config in the code, because it lets the user use whatever names they want. In that case, load the config into a dict (say, using
ConfigObj), and then pass that dictionary to this method.
- update_known(config, errors_ok=False)[source]
Updates existing settings values from a given dictionary.
- Parameters:
config – A dict whose key-values will be used to set settings “config” value sources accordingly.
- Returns:
A dict containing any unknown key-values from “config” that did not correspond to a known section or setting.
- walk(visitor)[source]
Visits every section and runs the passed method on every setting.
- Parameters:
visitor – Function to run on each setting. Will be passed a reference to the
ConfigDecorator, and a reference to theconfig_decorator.key_chained_val.KeyChainedValueobject.
config_decorator.key_chained_val module
Class to manage key-value settings.
- class config_decorator.key_chained_val.KeyChainedValue(section=None, name='', default_f=None, value_type=None, allow_none=False, choices='', doc='', ephemeral=False, hidden=False, validate=None, conform=None, recover=None)[source]
Bases:
objectRepresents one setting of a section of a hierarchical settings configuration.
- __init__(section=None, name='', default_f=None, value_type=None, allow_none=False, choices='', doc='', ephemeral=False, hidden=False, validate=None, conform=None, recover=None)[source]
Inits a
KeyChainedValueobject.Do not create these objects directly, but instead use the
config_decorator.config_decorator.ConfigDecorator.settings()decorator.Except for
section, the following arguments may be specified in the decorator call.For instance:
@property @RootSectionBar.setting( "An example setting.", name='foo-bar', value_type=bool, hidden=True, # etc. ) def foo_bar(self): return 'True'
- Parameters:
section – A reference to the section that contains this setting (a
config_decorator.config_decorator.ConfigDecorator).name – The setting name, either inferred from the class method that is decorated, or specified explicitly.
default_f – A method (i.e., the decorated class method) that generates the default setting value.
value_type – The setting type, either inferred from the type of the default value, or explicitly indicated. It’s often useful to explicitly set
booltypes so that the default function can return a'True'or'False'string.allow_none – True if the value is allowed to be
None, otherwise when the value is set, it will be passed to the type converted, which might fail on None, or produce unexpected results (such as convertingNoneto'None').choices – A optional list of valid values, used to validate input when setting the value.
doc – Helpful text about the setting, which your application could use to show the user. The
doccan specified as a keyword argument, or as the first positional argument to the decorator.ephemeral – If True, the setting is meant not to be persisted between sessions (e.g.,
ephemeralsettings are excluded on a call toconfig_decorator.config_decorator.ConfigDecorator.apply_items().)hidden – If True, the setting is excluded from an output operation if the value is the same as the setting’s default value.
validate – An optional function to validate the value when set from user input. If the validate function returns a falsey value, setting the value raises
ValueError.conform – If set, function used to translate config value to the value used internally. Useful for log levels, datetime, etc.
recover – If set, function used to convert internal value back to storable value. Useful to covert log level back to name, etc.
- property asobj
Returns self, behaving as identify function (need to quack like
ConfigDecorator).
- property default
Returns the default setting value.
- property doc
Returns the setting help text.
- property ephemeral
Returns the ephemeral state.
- forget_config_value()[source]
Removes the “config” setting value set by the
value_from_config()setter.
Returns the hidden state.
- property name
Returns the setting name.
- property persisted
Returns True if the setting value was set via
value_from_config().
- property source
Returns the setting value source.
- Returns:
The name of the highest priority source, as determined by the order of this list:
If the setting value was forced, by a call to the
value_from_forced()setter, the value ‘forced’ is returned.If the setting value was read from a command line argument, by a call to the
value_from_cliarg()setter, the value ‘cliarg’ is returned.If the setting value was read from an environment variable, by a call to the
value_from_envvar()setter, the value ‘envvar’ is returned.If the setting value was read from the dictionary source, by a call to the
value()orvalue_from_config()setters, the value ‘config’ is returned.Finally, if a value was not obtained from any of the above sources, the value ‘default’ is returned.
- property value
Returns the setting value read from the highest priority source.
- Returns:
The setting value from the highest priority source, as determined by the order of this list:
If the setting value was forced, by a call to the
value_from_forced()setter, that value is returned.If the setting value was read from a command line argument, by a call to the
value_from_cliarg()setter, that value is returned.If the setting value was read from an environment variable, by a call to the
value_from_envvar()setter, that value is returned.If the setting value was read from the dictionary source, by a call to the
value()orvalue_from_config()setters, that value is returned.Finally, if a value was not obtained from any of the above sources, the default value is returned.
- property value_from_cliarg
Returns the “cliarg” setting value.
- property value_from_config
Returns the “config” setting value.
- property value_from_default
Returns the conformed default value.
- property value_from_envvar
Returns the “envvar” setting value, sourced from the environment when called.
A name derived from a special prefix, the section path, and the setting name is used to look for an environment variable of the same name.
For example, consider that an application use the prefix “CFGDEC_”, and the setting is under a subsection called “pokey” which is under a topmost section called “hokey”. If the setting is named “foot”, then the environment variable would be named, “CFGDEC_HOKEY_POKEY_FOOT”.
- property value_from_forced
Returns the “forced” setting value.
- property value_unmutated
Returns the storable config value, generally just the stringified value.
config_decorator.slug_name_util module
Real powerful stuff.
Module contents
Root module package-level alias to config_decorator.config_decorator.section().
So you can call, e.g.,
from config_decorator import section
instead of
from config_decorator.config_decorator import section
- class config_decorator.ConfigDecorator(cls, cls_or_name, parent=None, default_value_type=None, default_allow_none=False)[source]
Bases:
objectRepresents one section of a hierarchical settings configuration.
A settings configuration is a collection of user-settable key-value settings grouped and organized into a tree-like graph of sections.
A settings configuration has one root section, which may have any number of subsections and settings therein. Each subsection may also contain any number of subsections and settings.
Each
ConfigDecoratorwraps a user class that defines the settings in that section. To add subsections to a section, use the section object’sConfigDecorator.section()decorator. One or more classes are defined and decorated this way to build a hierarchical settings configuration.Important
Users of this library do not call
ConfigDecorator()directly.Rather, object creation is handled by the
config_decorator.section()andConfigDecorator.section()decorators.- Parameters:
cls – The class being decorated.
cls_or_name – The section name to use in the settings configuration.
parent – A reference to the parent section (a
ConfigDecoratorobject), orNonefor the root section.default_value_type – Default value_type for unstructured @settings (
KeyChainedValueobjects) under this section (e.g., where the config does not define any specific key names, but it expects to read those key names from user’s config). Typically used for unstructuredlistconfig.default_allow_none – Default
allow_nonefor unstructured @settings (KeyChainedValueobjects) under this section. Pairs well withdefault_value_type.
- _innercls
The class object that was decorated (whose name now references a
ConfigDecoratorinstance, and not theclassobject that was defined.
- _innerobj
An instance of the class object that was decorated.
- _parent
A reference to the parent
ConfigDecoratorsection, orNonefor the root section.
- _kv_cache
An ordered dict of settings defined by the class, used internally when build the settings configuration (i.e., used internally while sourcing Python code).
- _key_vals
This section’s settings, stored as a dict (setting name ⇒
config_decorator.key_chained_val.KeyChainedValueobject).
- _sections
An ordered dict of subsections (section name ⇒
ConfigDecoratorobject).
- _name
The section name, specified in the decorator, or inferred from the class name.
- SEP = '.'
Separator character used to (un)flatten section.subsection.settings paths.
- apply_items(config, **kwargs)[source]
Prepares the passed dict with the config, stringifying values by default.
Args: Same as for _prepare_dict().
- as_dict(**kwargs)[source]
Returns a new dict representing the configuration settings tree.
Args: Same as for _prepare_dict().
- property asobj
Returns a representation of the section that can be accessed like an object.
- Returns:
An object that overrides
__getattr__to find the section or setting in the current section that has the given name.The object also has a magic
_method, if you want to use dot-notation to get at a subsection, but then want access to the actual section object.
- classmethod create_root_for_section(section_name, section_cdec)[source]
Creates a new ConfigDecorator as root of the passed instance.
- del_not_persisted(config_obj)[source]
Removes entries from config_obj without a value from the “config” source.
- find_all(parts, skip_sections=False)[source]
Returns all matching sections or settings.
- Parameters:
parts –
A list of strings used to find matching sections and settings.
If empty, the currect section is returned (the identify function).
If just one name is specified in “parts”, all sections and settings that match that name are assembled and returned (by performing a breadth-first search of the current section and its subsections).
If more than one name is specified, the leading names form the path to the section to search; and then any section or setting in that section matching the final name in “parts” is returned.
skip_sections – If True, do not include section objects in the results.
- Returns:
A list of matching sections and settings.
- find_setting(parts)[source]
Returns the setting with the given path and name.
- Parameters:
parts – A list of strings indicating the section names and setting name.
- Returns:
The indentified setting, or None if no setting found.
- forget_config_values()[source]
Visits every setting and removes the value from the “config” source.
Unless a setting’s value can be gleaned from an environment variable, or was parsed from the command line, or was forceable set by the code, calling this method will effectively set the value back to its default.
- section(name, default_value_type=None, default_allow_none=False)[source]
Class decorator used to create subsections.
For instance:
@section(None) class RootSection(object): pass @RootSection.section('My Subsection') class MySubsection(object): pass @MySubsection.section('A Grandsubsection') class AGrandsubsection(object): pass
- Parameters:
name – The name of the subsection.
- Returns:
A
ConfigDecoratorinstance.
See
config_decorator.config_decorator.section()section()for a more complete explanation.
- section_path(sep=None, _parts=None)[source]
Returns a flattened canonicalized representation of the complete section path.
- Parameters:
sep – The separator character to use, defaults to ConfigDecorator.SEP.
_parts – Used internally on recursive calls to this function.
- Returns:
The “path” to this section, as derived from the name of the root section on downward to this section, using the separator character between each successive section’s name.
- set_section(section_name, sub_dcor)[source]
Assigns the passed ConfigDecorator to the section key named.
# NOTE: This method is clobbery.
- setdefault(*args)[source]
Ensures the indicated setting exists, much like
dict.setdefault.- Parameters:
args – one or more arguments indicating the section path and setting name, and one final argument indicating the default setting value to use.
- Returns:
The setting value (the existing value if already set; otherwise the new default value, which is also the last item in
*args).
- setting(message=None, **kwargs)[source]
Method decorator used to create individual settings in a configuration section.
For instance:
... @RootSection.section('My Subsection') class MySubsection(object): @property @RootSection.setting( "An example setting.", name="my-setting" ) def my_setting(self): return 'My Setting's Default Value'
- update(other, errors_ok=False)[source]
Alias to
update_gross().
- update_gross(other, errors_ok=False)[source]
Consumes all values from a dict, creating new sections and settings as necessary.
- Parameters:
other – The dict whose contents will be consumed.
See also
update_known(), which does not add unknown values.This method is less discerning. It grabs everything from
otherand shoves it in the ConfigDecorator object, creating section and setting objects as necessary.You might find this useful if your app handles arbitrary config. In this case, the application cannot define the config in the code, because it lets the user use whatever names they want. In that case, load the config into a dict (say, using
ConfigObj), and then pass that dictionary to this method.
- update_known(config, errors_ok=False)[source]
Updates existing settings values from a given dictionary.
- Parameters:
config – A dict whose key-values will be used to set settings “config” value sources accordingly.
- Returns:
A dict containing any unknown key-values from “config” that did not correspond to a known section or setting.
- walk(visitor)[source]
Visits every section and runs the passed method on every setting.
- Parameters:
visitor – Function to run on each setting. Will be passed a reference to the
ConfigDecorator, and a reference to theconfig_decorator.key_chained_val.KeyChainedValueobject.
- class config_decorator.KeyChainedValue(section=None, name='', default_f=None, value_type=None, allow_none=False, choices='', doc='', ephemeral=False, hidden=False, validate=None, conform=None, recover=None)[source]
Bases:
objectRepresents one setting of a section of a hierarchical settings configuration.
- __init__(section=None, name='', default_f=None, value_type=None, allow_none=False, choices='', doc='', ephemeral=False, hidden=False, validate=None, conform=None, recover=None)[source]
Inits a
KeyChainedValueobject.Do not create these objects directly, but instead use the
config_decorator.config_decorator.ConfigDecorator.settings()decorator.Except for
section, the following arguments may be specified in the decorator call.For instance:
@property @RootSectionBar.setting( "An example setting.", name='foo-bar', value_type=bool, hidden=True, # etc. ) def foo_bar(self): return 'True'
- Parameters:
section – A reference to the section that contains this setting (a
config_decorator.config_decorator.ConfigDecorator).name – The setting name, either inferred from the class method that is decorated, or specified explicitly.
default_f – A method (i.e., the decorated class method) that generates the default setting value.
value_type – The setting type, either inferred from the type of the default value, or explicitly indicated. It’s often useful to explicitly set
booltypes so that the default function can return a'True'or'False'string.allow_none – True if the value is allowed to be
None, otherwise when the value is set, it will be passed to the type converted, which might fail on None, or produce unexpected results (such as convertingNoneto'None').choices – A optional list of valid values, used to validate input when setting the value.
doc – Helpful text about the setting, which your application could use to show the user. The
doccan specified as a keyword argument, or as the first positional argument to the decorator.ephemeral – If True, the setting is meant not to be persisted between sessions (e.g.,
ephemeralsettings are excluded on a call toconfig_decorator.config_decorator.ConfigDecorator.apply_items().)hidden – If True, the setting is excluded from an output operation if the value is the same as the setting’s default value.
validate – An optional function to validate the value when set from user input. If the validate function returns a falsey value, setting the value raises
ValueError.conform – If set, function used to translate config value to the value used internally. Useful for log levels, datetime, etc.
recover – If set, function used to convert internal value back to storable value. Useful to covert log level back to name, etc.
- property asobj
Returns self, behaving as identify function (need to quack like
ConfigDecorator).
- property default
Returns the default setting value.
- property doc
Returns the setting help text.
- property ephemeral
Returns the ephemeral state.
- forget_config_value()[source]
Removes the “config” setting value set by the
value_from_config()setter.
Returns the hidden state.
- property name
Returns the setting name.
- property persisted
Returns True if the setting value was set via
value_from_config().
- property source
Returns the setting value source.
- Returns:
The name of the highest priority source, as determined by the order of this list:
If the setting value was forced, by a call to the
value_from_forced()setter, the value ‘forced’ is returned.If the setting value was read from a command line argument, by a call to the
value_from_cliarg()setter, the value ‘cliarg’ is returned.If the setting value was read from an environment variable, by a call to the
value_from_envvar()setter, the value ‘envvar’ is returned.If the setting value was read from the dictionary source, by a call to the
value()orvalue_from_config()setters, the value ‘config’ is returned.Finally, if a value was not obtained from any of the above sources, the value ‘default’ is returned.
- property value
Returns the setting value read from the highest priority source.
- Returns:
The setting value from the highest priority source, as determined by the order of this list:
If the setting value was forced, by a call to the
value_from_forced()setter, that value is returned.If the setting value was read from a command line argument, by a call to the
value_from_cliarg()setter, that value is returned.If the setting value was read from an environment variable, by a call to the
value_from_envvar()setter, that value is returned.If the setting value was read from the dictionary source, by a call to the
value()orvalue_from_config()setters, that value is returned.Finally, if a value was not obtained from any of the above sources, the default value is returned.
- property value_from_cliarg
Returns the “cliarg” setting value.
- property value_from_config
Returns the “config” setting value.
- property value_from_default
Returns the conformed default value.
- property value_from_envvar
Returns the “envvar” setting value, sourced from the environment when called.
A name derived from a special prefix, the section path, and the setting name is used to look for an environment variable of the same name.
For example, consider that an application use the prefix “CFGDEC_”, and the setting is under a subsection called “pokey” which is under a topmost section called “hokey”. If the setting is named “foot”, then the environment variable would be named, “CFGDEC_HOKEY_POKEY_FOOT”.
- property value_from_forced
Returns the “forced” setting value.
- property value_unmutated
Returns the storable config value, generally just the stringified value.
- config_decorator.section(cls_or_name, parent=None, default_value_type=None, default_allow_none=False)[source]
Class decorator used to indicate the root section of a settings configuration.
For instance:
@section(None) class RootSection(object): pass
See Concepts for more help and usage examples.
- Parameters:
cls_or_name – The section name, or the class being decorated if the decorator was not closed.
parent – When defining a subsection, the reference to the parent section (used internally by
config_decorator.config_decorator.ConfigDecorator.section()).
- Returns:
A
ConfigDecoratorinstance.Important
The name of the decorated class does not reference the defined user class, but rather it’s a
config_decorator.config_decorator.ConfigDecoratorinstance.To access the class definition that was decorated, use the return object’s
_innerclsattribute.To access an instance of the decorated class, use
_innerobj.