ConfigDict¶
- class configdict.configdict.ConfigDict(name, default=None, validator=None, docs=None, adaptor=None, precallback=None, persistent=False, load=True, fmt='yaml', sortKeys=False, description='', strict=True, advancedPrefix='.')[source]¶
Bases:
CheckedDict
This is an optionally persistent dictionary used for configuration.
It is saved under the config folder determined by the OS (and is thus OS dependent). In persistent mode no two instances of the same config can coexist.
- Parameters:
name (
str
) – a str of the formprefix.name
orprefix/name
(these are the same) or simplyname
if this is an isolated configuration. The data will be saved at$USERCONFIGDIR/{prefix}/{name}.{fmt}
if prefix is given, or$USERCONFIGDIR/{name}.{fmt}
. For instance, in Linux a config with a name “myproj.myconfig” and a yaml format will be saved to “~/.config/mydir/myconfig.yaml”default (
Optional
[dict
[str
,Any
]]) – a dict with all default values. A config can accept only keys which are already present in the default. This argument can be None if the config is built successively viaConfigDict.addKey()
(see example below) but the dict is not usable until all the keys have been added and the user callsConfigDict.load()
explicitelyvalidator (
Optional
[dict
[str
,Any
]]) –a dict containing choices, types and/or ranges for the keys in the default. Given a default like:
{'keyA': 'foo', 'keyB': 20}
, a validator could be:{ 'keyA::choices': ['foo', 'bar'], 'keyB::type': float, 'keyB::range': (10, 30) }
Choices can be defined lazyly by giving a lambda
docs (
Optional
[dict
[str
,str
]]) – a dict containing documentation for each keypersistent – if True, any change to the dict will be automatically saved. Otherwise a dict can be saved manually via
ConfigDict.save()
load – if True, the saved version will be loaded after creation. This is disabled if no default dict is given. This is the case when building the default after creation -
ConfigDict.load()
should be called manually in this case (see example).precallback (
Optional
[Callable
[[ConfigDict
,str
,Any
,Any
],Any
]]) – function (dict, key, oldvalue, newvalue) -> None|newvalue, If given, it is called before the modification is done. This function should return None to allow modification, any value to modify the value, or raise ValueError to stop the transactionsortKeys – if True, keys are sorted whenever the dict is saved/edited.
advancedPrefix – keys with this prefix are marked as advanced. Whenever the dict is displayed or edited, these keys appear after all the other keys
Example
# No default given. The default is built by adding keys subsequently. # load needs to be called to end the declaration # This method is somewhat similar to ArgParse config = ConfigDict("myproj.subproj") config.addKey("keyA", 10, doc="documentaion of keyA") config.addKey("keyB", 0.5, range=(0, 1)) config.addKey("keyC", "blue", choices=("blue", "red"), doc="documentation of keyC") config.load() # Alternatively, a config can be built within a context manager. 'load' is called when exiting the context: with ConfigDict("maelzel.snd.plotting") as conf conf.addKey('backend', 'matplotlib', choices={'matlotlib'}) conf.addKey('spectrogram.colormap', 'inferno', choices=_cmaps) conf.addKey('samplesplot.figsize', (24, 4)) conf.addKey('spectrogram.figsize', (24, 8)) conf.addKey('spectrogram.maxfreq', 12000, doc="Highest frequency in a spectrogram") # The same effect can be achieved by passing the default/validator/doc default = { "keyA": 10, "keyB": 0.5, "keyC": "blue } validator = { "keyB::range": (0, 1), "keyC::choices": ("blue", "red") } docs = { "keyA": "documentation of keyA" "keyC": "documentation of keyC" } cfg = ConfigDict("myproj.subproj", default=default, validator=validator, docs=docs) # no need to call .load in this case # Using inheritance class MyConfig(ConfigDict): def __init__(self): super().__init__(name="myconfig", default=default, validator=validator, docs=docs) cfg = MyConfig()
Attributes Summary
The name of this ConfigDict.
Is this a persistent ConfigDict?
Methods Summary
__call__
(key, value[, type, choices, range, ...])Call self as a function.
addKey
(key, value[, type, choices, range, ...])Add a
key: value
pair to the default settings.asCsv
()Returns this dict as a csv str, with columns: key, value, spec, doc
asYaml
([sortKeys])Returns this dict as yaml str, with comments, defaults, etc.
checkDict
(d)Check if dict d can be used to update self
checkValue
(key, value)Check if value is valid for key
clear
()clone
([updates, name, persistent, ...])Create a clone of this dict
copy
()Create a copy if this dict.
diff
([other])Get a dict containing keys:values which differ from the default or from another dict
dump
()Dump this config to stdout
edit
([waitOnModified, sortKeys])Edit this config by opening it in an external application.
fromkeys
([value])Create a new dictionary with keys from iterable and values set to value.
generateRstDocumentation
([maxWidth, ...])Generate ReST documentation for this dictionary
get
(key[, default])Return the value for key if key is in the dictionary, else default.
getChoices
(key)Return a seq.
getDoc
(key)Get documentation for key (if present)
getPath
()Return the path this dict will be saved to
getRange
(key)Returns the valid range for this key's value, if specified.
getType
(key)Returns the expected type for key's value
getTypestr
(key)The same as .getType but returns a string representation of the type
getValidateFunc
(key)Returns a function to validate a value for
key
isCongruentWith
(other)Returns True if self and other share same default
items
()keys
()load
([configpath])Read the saved config, update self.
Create a version of this class with all values set to the default
normalizeKey
(key)- rtype:
str
override
(key, value[, default])The same as value if value is not None else config.get(key, default)
pop
(k[,d])If the key is not found, return the default if given; otherwise, raise a KeyError.
popitem
()Remove and return a (key, value) pair as a 2-tuple.
registerCallback
(func[, pattern])Register a callback to be fired when a key matching the given pattern is changed.
reset
([save])Reset this dict to its default
resetKey
(key)Reset the given key to its default value
save
([path, header])Save this to its persistent path (or a custom path)
setdefault
(key[, default])Insert key with a value of default if key is not in the dictionary.
update
([d])Update this dict with the values in d.
updated
([d])The same as
update()
, but returns selfvalidatorTypes
(key)Return the validator types for a given key
values
()Attributes Documentation
- name¶
The name of this ConfigDict. The name determines where it is saved
- persistent¶
Is this a persistent ConfigDict?
Methods Documentation
- __call__(key, value, type=None, choices=None, range=None, doc='', validatefunc=None)¶
Call self as a function.
- Return type:
None
- addKey(key, value, type=None, choices=None, range=None, validatefunc=None, adaptor=None, doc=None)¶
Add a
key: value
pair to the default settings.This is used when building the default config item by item (see example). After adding all new keys it is necessary to call
ConfigDict.load()
Example
cfg = ConfigDict("foo", load=False) # We define a default step by step cfg.addKey("width", 100, range=(50, 150)) cfg.addKey("color", "red", choices=("read", "blue", "green")) cfg.addKey("height", doc="Height should be higher than width", validatefunc=lambda cfg, key, height: height > cfg['width']) # Now update the dict with the newly defined default and any # saved version cfg.load()
- Parameters:
key (
str
) – a string keyvalue (
Any
) – a default valuetype (
Union
[type
,tuple
[type
,...
],None
]) – the type accepted, as passed to isinstance (can be a tuple)choices (
Union
[Set
,tuple
,None
]) – a set/tuple of possible valuesrange (
Optional
[tuple
[Any
,Any
]]) – a (min, max) tuple defining an allowed range for this valuevalidatefunc (
Optional
[Callable
[[dict
,str
,Any
],bool
]]) – a function(config: dict, key:str, value) -> bool
, should return True if value is valid for key or False otherwisedoc (
Optional
[str
]) – documentation for this key
- Return type:
None
- asCsv()[source]¶
Returns this dict as a csv str, with columns: key, value, spec, doc
- Return type:
str
- asYaml(sortKeys=False)¶
Returns this dict as yaml str, with comments, defaults, etc.
- Return type:
str
- checkDict(d)¶
Check if dict d can be used to update self
- Parameters:
d (dict) – a dict which might update self
- Return type:
str
- Returns:
An error message if d has any invalid key or value, “” if everything is ok
- checkValue(key, value)¶
Check if value is valid for key
This is only possible if a validator was set
- Parameters:
key (
str
) – the key to checkvalue – the value to check according to the contraints defined for the key (range, type, etc)
- Return type:
Optional
[str
]- Returns:
None if the value is acceptable for the key, an error message otherwise
Example
error = config.checkType(key, value) if error: print(error)
- clear() None. Remove all items from D. ¶
- clone(updates=None, name=None, persistent=False, cloneCallbacks=True, **kws)[source]¶
Create a clone of this dict
- Parameters:
name (
Optional
[str
]) – the name of the clone. If not given, the name of this dict is used.persistent – Should the clone be made persitent?
cloneCallbacks – should the registered callbacks of the original (if any) be cloned?
updates (
Optional
[dict
]) – a dict with updates**kws – same as updates but only for keys which are valid keywords
- Return type:
TypeVar
(_ConfigDictT
, bound= ConfigDict)- Returns:
the cloned dict
- copy()[source]¶
Create a copy if this dict.
The copy will be unnamed and not persistent. Use
ConfigDict.clone()
to create a named/persistent clone of this dict.- Return type:
TypeVar
(_CheckedDictT
, bound= CheckedDict)- Returns:
the copy of this dict
- diff(other=None)¶
Get a dict containing keys:values which differ from the default or from another dict
- Parameters:
other (
Optional
[dict
]) – if given, another dict which this is compared against. Otherwise the diff is calculated to the default dict- Return type:
dict
- Returns:
a dict containing key – value pairs where self differs from other
- edit(waitOnModified=True, sortKeys=False)[source]¶
Edit this config by opening it in an external application.
The format used is yaml. This is independent of the format used for persistence. The application used is the user’s default application for the .yaml format and can be configured at the os level. In macos we use
open
, in linuxxdg-open
and in windowsstart
, which all respond to the user’s own configuration regarding default applications.Note
A temporary file is created for editing. The persisted file is only modified if the editing is accepted.
- Parameters:
waitOnModified – if True, the transaction is accepted whenever the file being edited is saved. Otherwise a message box is created which needs to be clicked in order to confirm the transaction. Just exiting the application will not cancel the edit job since many applications which have a server mode or unique instance mode might in fact exit right away from the perspective of the subprocess which launched them
sortKeys – if True, keys appear in sorted order
- Return type:
None
- fromkeys(value=None, /)¶
Create a new dictionary with keys from iterable and values set to value.
- generateRstDocumentation(maxWidth=80, withName=True, withDescription=True, withLink=True, linkPrefix='')[source]¶
Generate ReST documentation for this dictionary
The generated string can then be dumped to a file and included in documentation
- Parameters:
maxWidth – the max. width of a line
withName – if True, add the name of the config (if it has a name)
withDescription – if True, add this dict’s description (if it has any)
withLink – if True, for each key:value pair generate a RST link using the given linkPrefix For example, for a key ‘foo’ and a linkPrefix=’config’ the generated link will be
.. _configfoo
. This link can be used within the documentation to link to this keylinkPrefix – a prefix to use for all links
- Return type:
str
- Returns:
the generated rst documentation, as str.
- get(key, default=None, /)¶
Return the value for key if key is in the dictionary, else default.
- getChoices(key)¶
Return a seq. of possible values for key
k
orNone
- Return type:
Optional
[list
]
- getDoc(key)¶
Get documentation for key (if present)
- Return type:
Optional
[str
]
- getPath()[source]¶
Return the path this dict will be saved to
If the dict has no name, an empty string is returned
- Return type:
str
- getRange(key)¶
Returns the valid range for this key’s value, if specified.
- Parameters:
key (
str
) – the key to get the range from.- Return type:
Optional
[tuple
]- Returns:
the range of values allowed for this key, or None if there is no range defined for this key.
Raises KeyError if the key is not present
- getType(key)¶
Returns the expected type for key’s value
- Parameters:
key (
str
) – the key to query- Return type:
Union
[type
,tuple
[type
,...
]]
Note
All numbers are reduced to type float, all strings are of type str, otherwise the type of the default value, which can be a collection like a list or a dict
See Also:
checkValue()
- getTypestr(key)¶
The same as .getType but returns a string representation of the type
- Parameters:
key (
str
) – the key to query- Return type:
str
- getValidateFunc(key)¶
Returns a function to validate a value for
key
A validate function has the form
(config, value) -> bool
- Parameters:
key (str) – the key to query for a validate function
- Return type:
Optional
[Callable
[[dict
,str
,Any
],bool
]]- Returns:
The validate function, or None
- items() a set-like object providing a view on D's items ¶
- keys() a set-like object providing a view on D's keys ¶
- load(configpath=None)[source]¶
Read the saved config, update self.
If there is no saved version or the dict has no name, then the dict is set to the default defined at construction.
When defining the default iteratively (via addKey), calling load marks the end of the definition: after calling load no other keys can be added to this dict.
- Parameters:
configpath (
Optional
[str
]) – an custom path to load a saved version from. Otherwise it is loaded fromConfigDict.getPath()
(this is only possible if the dict has a name, since the resolved path is determined from the name)- Return type:
None
Example
from configdict import ConfigDict conf = ConfigDict('foo.bar') conf.addKey('key1', 'value1', ...) conf.addKey('key2', 'value2', ...) ... # When finished defining keys, call .load conf.load() # Now the dict can be used
When
- makeDefault()¶
Create a version of this class with all values set to the default
- Return type:
TypeVar
(_CheckedDictT
, bound= CheckedDict)
- static normalizeKey(key)¶
- Return type:
str
- override(key, value, default=None)¶
The same as value if value is not None else config.get(key, default)
- Return type:
None
- pop(k[, d]) v, remove specified key and return the corresponding value. ¶
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()¶
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- registerCallback(func, pattern='.*')[source]¶
Register a callback to be fired when a key matching the given pattern is changed.
If no pattern is given, the function will be called for every key.
- Parameters:
func (
Callable
[[ConfigDict
,str
,Any
],None
]) – a function of the form(dict, key, value) -> None
, where dict is this ConfigDict itself, key is the key which was just changed and value is the new value.pattern – a regex pattern. The function will be called if the pattern matches the key being modified.
- Return type:
None
- save(path=None, header='')[source]¶
Save this to its persistent path (or a custom path)
If this config was created with the persistent flag on, it does not need to be saved manually, it is saved whenever it is modified. However if it was created with
persistent=False
then this method can be used to write this dict so it will be loaded in a future session- Parameters:
path (
Optional
[str
]) – the path to save the config. If None and this is a named config, it is saved to the path returned bygetPath()
header – if given, this string is written prior to the dict, as a comment. This is only supported when saving to yaml
- Return type:
None
- setdefault(key, default=None, /)¶
Insert key with a value of default if key is not in the dictionary.
Return the value for key if key is in the dictionary, else default.
- update(d=None, **kws)[source]¶
Update this dict with the values in d.
Note
keywords have priority over d (similar to builtin dict)
- Parameters:
d (
Optional
[dict
]) – values in this dictionary will overwrite values in self. Keys not present in self will raise an exception**kws – any key:value here will also be used to update self
- Return type:
None
- updated(d=None, **kws)¶
The same as
update()
, but returns self- Return type:
TypeVar
(_CheckedDictT
, bound= CheckedDict)
- validatorTypes(key)¶
Return the validator types for a given key
A validator type for a given key can be a choices validator, where a set of possible values is given for a given key; it can be a range, where the value must be within a given range; a type, where a value must be of a certain type; or a function, which must return True if the value is valid, or False or an error message as string if the value is invalid
- Parameters:
key (
str
) – the key to query- Return type:
list
[str
]- Returns:
a list of validator types, where each item is one of ‘choices’, ‘range’, ‘type’, ‘func’
- values() an object providing a view on D's values ¶