A general yet simple configuration class.
A configuration class allowing Python expressions in the input.
The configuration settings are stored in the __dict__ of a Python object. An item ‘foo’ in the configuration ‘config’ can be accessed either as dictionary lookup (config['foo']) or as object attribute (config.foo).
The configuration object can be initialized from a multiline string or a text file (or any other object that allows iterating over strings).
The format of the config file/text is described hereafter.
All config lines should have the format: key = value, where key is a string and value is a Python expression The first ‘=’ character on the line is the delimiter between key and value. Blanks around both the key and the value are stripped. The value is then evaluated as a Python expression and stored in a variable with name specified by the key. This variable is available for use in subsequent configuration lines. It is an error to use a variable before it is defined. The key,value pair is also stored in the config dictionary, unless the key starts with an underscore (‘_’): this provides for local variables.
Lines starting with ‘#’ are comments and are ignored, as are empty and blank lines. Lines ending with ‘’ are continued on the next line. A line starting with ‘[‘ starts a new section. A section is nothing more than a Python dictionary inside the config dictionary. The section name is delimited by ‘[‘and ‘]’. All subsequent lines will be stored in the section dictionary instead of the toplevel dictionary.
All other lines are executed as python statements. This allows e.g. for importing modules.
Whole dictionaries can be inserted at once in the config with the update() function.
All defined variables while reading config files remain available for use in the config file statements, even over multiple calls to the read() function. Variables inserted with addSection() will not be available as individual variables though, but can be access as self['name'].
As an example, if your config file looks like:
aa = 'bb'
bb = aa
[cc]
aa = 'aa'
_n = 3
rng = range(_n)
the resulting configuration dictionary is {'aa': 'bb', 'bb': 'bb', 'cc': {'aa': 'aa', 'rng': [0, 1, 2]}}
As far as the resulting Config contents is concerned, the following are equivalent:
C.update({'key':'value'})
C.read("key='value'\n")
There is an important difference though: the second line will make a variable key (with value ‘value’) available in subsequent Config read() method calls.
Creates a new Config instance.
The configuration can be initialized with a dictionary, or with a variable that can be passed to the read() function. The latter includes the name of a config file, or a multiline string holding the contents of a configuration file.
Config objects have the following methods:
Add a dictionary to the Config object.
The data, if specified, should be a valid Python dict. If no name is specified, the data are added to the top dictionary and will become attributes. If a name is specified, the data are added to the named attribute, which should be a dictionary. If the name does not specify a dictionary, an empty one is created, deleting the existing attribute.
If a name is specified, but no data, the effect is to add a new empty dictionary (section) with that name.
If removeLocals is set, keys starting with ‘_’ are removed from the data before updating the dictionary and not included in the config. This behaviour can be changed by setting removeLocals to false.
Read a configuration from a file or text
fil is a sequence of strings. Any type that allows a loop like for line in fil: to iterate over its text lines will do. This could be a file type, or a multiline text after splitting on ‘n’.
The function will try to react intelligently if a string is passed as argument. If the string contains at least one ‘n’, it will be interpreted as a multiline string and be splitted on ‘n’. Else, the string will be considered and a file with that name will be opened. It is an error if the file does not exist or can not be opened.
The function returns self, so that you can write: cfg = Config().
Functions defined in the module config
- config.formatDict(d)¶
Format a dict in Python source representation.
Each (key,value) pair is formatted on a line of the form:
key = valueThe resulting text is a legal Python script to define the items in the dict.