tranche¶
- class tranche.Tranche¶
Bases:
objectA “meta” config parser that keeps a dictionary of config parsers and their sources to combine when needed. The custom config parser allows provenance of the source of different config options and allows the “user” config options to always take precedence over other config options (even if they are added later).
Example
>>> config = Tranche() >>> config.add_from_file('default.cfg') >>> config.add_user_config('user.cfg') >>> value = config.get('section', 'option')
- combined¶
The combined config options
- Type:
{None, configparser.ConfigParser}
- combined_comments¶
The combined comments associated with sections and options
- Type:
{None, dict}
- sources¶
The source of each section or option
- Type:
{None, dict}
- add_from_file(filename)¶
Add the contents of a config file to the parser.
- Parameters:
filename (str) – The relative or absolute path to the config file
- Return type:
None
- add_from_package(package, config_filename, exception=True)¶
Add the contents of a config file to the parser.
- add_section(section, user=False)¶
Add an empty section. The file from which this function was called is retained for provenance, mirroring
set().- Parameters:
- Raises:
configparser.DuplicateSectionError – If the section already exists in the calling file’s layer
- Return type:
None
- add_user_config(filename)¶
Add a the contents of a user config file to the parser. These options take precedence over all other options.
- Parameters:
filename (str) – The relative or absolute path to the config file
- Return type:
None
- append(other)¶
Append a deep copy of another config parser to this one. Config options from
otherwill take precedence over those from this config parser.- Parameters:
other (tranche.Tranche) – The other, higher priority config parser
- Return type:
None
- combine(raw=False)¶
Combine the config files into one. This is normally handled automatically.
- Parameters:
raw (bool, optional) – Whether to combine “raw” config options, rather than using extended interpolation
- Return type:
None
- copy()¶
Get a deep copy of the config parser
- Returns:
config_copy – The deep copy
- Return type:
- defaults()¶
Get the options in the special
[DEFAULT]section.
- explain(section, option)¶
Explain the provenance of an option.
Returns a dictionary with the effective value, the source file path, and which layer provided it (“user” or “base”).
- get(section, option, **kwargs)¶
Get an option value for a given section.
- Parameters:
section (str) – The name of the config section
option (str) – The name of the config option
**kwargs (Any) – Additional keyword arguments forwarded to
configparser.ConfigParser.get().
- Returns:
value – The value of the config option
- Return type:
str | None
- getboolean(section, option, **kwargs)¶
Get an option boolean value for a given section.
- Parameters:
section (str) – The name of the config section
option (str) – The name of the config option
**kwargs (Any) – Additional keyword arguments forwarded to
configparser.ConfigParser.getboolean().
- Returns:
value – The value of the config option
- Return type:
bool | None
- getexpression(section, option, dtype=None, backend=None, allow_numpy=False, fallback=None, **kwargs)¶
Get an option as an expression (typically a list, though tuples and dicts are also available). The expression is required to have valid python syntax, so that string entries are required to be in single or double quotes.
- Parameters:
section (str) – The section in the config file
option (str) – The option in the config file
dtype ({Type[bool], Type[int], Type[float], Type[list], Type[tuple], Type[str]}, optional) – If supplied, each element in a list or tuple, or each value in a dictionary are cast to this type. This is likely most useful for ensuring that all elements in a list of numbers are of type float, rather than int, when the distinction is important.
backend ({"literal", "safe"} or None) –
None (default): choose “safe” if allow_numpy=True else “literal”.
”literal”: use ast.literal_eval (safest, literals only)
”safe”: use a whitelisted AST evaluator optionally allowing numpy
allow_numpy (bool, optional) – If True and backend=”safe”, enable limited numpy functions (np.arange, np.linspace, np.array) under names “np”/”numpy”.
fallback (Any, optional) – A fallback value to return if the option is not found.
**kwargs (Any) – Additional keyword arguments forwarded to
configparser.ConfigParser.get().
- Return type:
- getfloat(section, option, **kwargs)¶
Get an option float value for a given section.
- Parameters:
section (str) – The name of the config section
option (str) – The name of the config option
**kwargs (Any) – Additional keyword arguments forwarded to
configparser.ConfigParser.getfloat().
- Returns:
value – The value of the config option
- Return type:
float | None
- getint(section, option, **kwargs)¶
Get an option integer value for a given section.
- Parameters:
section (str) – The name of the config section
option (str) – The name of the config option
**kwargs (Any) – Additional keyword arguments forwarded to
configparser.ConfigParser.getint().
- Returns:
value – The value of the config option
- Return type:
int | None
- getlist(section, option, dtype=<class 'str'>, *, fallback=None, **kwargs)¶
Get an option value as a list for a given section.
- Parameters:
section (str) – The name of the config section
option (str) – The name of the config option
dtype ({Type[str], Type[int], Type[float]}) – The type of the elements in the list.
fallback (list, optional) – A fallback value to return if the option is not found.
**kwargs (Any) – Additional keyword arguments forwarded to
configparser.ConfigParser.get().
- Returns:
value – The value of the config option parsed into a list.
- Return type:
list | None
- getnumpy(section, option, dtype=None, backend=None, fallback=None, **kwargs)¶
Shortcut for expressions requiring NumPy.
Equivalent to
getexpression(..., allow_numpy=True)with adaptive backend selection (safe if backend is None).- Parameters:
section (str) – Section name.
option (str) – Option name.
dtype (type, optional) – Cast list/tuple/dict elements to this type.
backend ({"literal", "safe"} or None, optional) – Override backend. None => choose “safe”.
fallback (Any, optional) – A fallback value to return if the option is not found.
**kwargs (Any) – Additional keyword arguments forwarded to
configparser.ConfigParser.get().
- Return type:
- has_option(section, option)¶
Whether the given section has the given option
- has_section(section)¶
Whether the given section is part of the config
- items(section=<object object>, **kwargs)¶
Get section or option items from the combined config.
Mirrors
configparser.ConfigParser.items().- Parameters:
section (str, optional) – If given, return a list of
(option, value)pairs for that section. If omitted, return a list of(name, section)pairs for every section, where eachsectionis atranche.section.Sectionwrapper.**kwargs (Any) – Additional keyword arguments (e.g.
raw,vars) forwarded toconfigparser.ConfigParser.items()whensectionis given.
- Returns:
items – Either
(name, Section)pairs or(option, value)pairs.- Return type:
- keys()¶
Get the section names in the combined config (including
DEFAULT).
- list_files()¶
Get a list of files contributing to the combined config options
- options(section)¶
Get the list of option names available in the given section.
- prepend(other)¶
Prepend a deep copy of another config parser to this one. Config options from this config parser will take precedence over those from
other.- Parameters:
other (tranche.Tranche) – The other, higher priority config parser
- Return type:
None
- read_dict(dictionary, source='<dict>', user=False)¶
Add config options read from a nested dictionary.
This mirrors
configparser.ConfigParser.read_dict(). Keys and values are converted to strings. Options added this way have empty comments.- Parameters:
dictionary (Mapping[str, Mapping[str, Any]]) – A mapping of the form
{section: {option: value, ...}, ...}.source (str, optional) – A label used as the provenance “source” for these options. If several calls share a source, later options overwrite earlier ones.
user (bool, optional) – Whether these options should be treated as user overrides that take precedence over all base options.
- Return type:
None
- read_file(f, source=None, user=False)¶
Add config options read from an open file or iterable of lines.
This mirrors
configparser.ConfigParser.read_file()while preserving comments, provenance and layered precedence.- Parameters:
f (iterable of str) – An open file object or any iterable yielding config lines.
source (str, optional) – A label used as the provenance “source” for these options. If not given,
f.nameis used when available, otherwise"<stream>". A later call with the samesourcereplaces the earlier layer.user (bool, optional) – Whether these options should be treated as user overrides that take precedence over all base options.
- Return type:
None
- read_string(string, source='<string>', user=False)¶
Add config options read from a string.
This mirrors
configparser.ConfigParser.read_string()while preserving comments, provenance and layered precedence. Environment variables of the form${env:VAR}are interpolated, just as foradd_from_file().- Parameters:
string (str) – The config contents to parse.
source (str, optional) – A label used as the provenance “source” for these options. A later call with the same
sourcereplaces the earlier layer.user (bool, optional) – Whether these options should be treated as user overrides that take precedence over all base options.
- Return type:
None
- register_symbol(name, obj)¶
Make ‘name’ available to the safe expression backend.
Restrictions:
name must not contain ‘__’ or ‘.’
cannot override reserved core names: ‘np’, ‘numpy’, ‘math’, ‘range’, ‘int’, ‘float’, ‘pi’
Examples
Register a stdlib function (math.sqrt) and call it from the config:
>>> import math >>> config = Tranche() >>> config.register_symbol('sqrt', math.sqrt) >>> # INI has: >>> # [calc] >>> # val = sqrt(9) >>> config.getexpression('calc', 'val', backend='safe') 3.0
Register a reducer (statistics.mean):
>>> import statistics >>> config.register_symbol('mean', statistics.mean) >>> # INI has: >>> # [data] >>> # avg = mean([1, 2, 3]) >>> config.getexpression('data', 'avg', backend='safe') 2
Register a type (datetime.timedelta) supporting keyword args:
>>> from datetime import timedelta >>> config.register_symbol('timedelta', timedelta) >>> # INI has: >>> # [sched] >>> # interval = timedelta(days=2) >>> config.getexpression('sched', 'interval', backend='safe') datetime.timedelta(days=2)
- Parameters:
name (str) – The name to register
obj (any) – The object to register under the given name
- Return type:
None
- remove_option(section, option)¶
Remove an option from a section across all layers.
The option is removed from every contributing file (both base and user layers) so that it no longer appears in the combined config.
- Parameters:
- Returns:
existed – Whether the option existed in any layer before removal
- Return type:
- Raises:
configparser.NoSectionError – If the section is not present in any layer
- remove_section(section)¶
Remove a section and all of its options across all layers.
The section is removed from every contributing file (both base and user layers) so that it no longer appears in the combined config.
- sections()¶
Get the list of section names in the combined config.
The special
[DEFAULT]section is not included, mirroringconfigparser.ConfigParser.sections().
- set(section, option, value=None, comment=None, user=False)¶
- Set the value of the given option in the given section. The file from
which this function was called is also retained for provenance.
- Parameters:
section (str) – The name of the config section
option (str) – The name of the config option
value (str, optional) – The value to set the option to
comment (str, optional) – A comment to include with the config option when it is written to a file
user (bool, optional) – Whether this config option was supplied by the user (e.g. through a command-line flag) and should take priority over other sources
- Return type:
None
- validate(validator)¶
Call a user-provided validator function on the config as a nested dict.
The validator is called with a dictionary of the form:
{section: {option: value, …}, …}
where all values are strings as returned by get().
This allows integration with validation libraries such as Pydantic or voluptuous, or custom validation logic. If the validator raises an exception, it will propagate to the caller.
- Parameters:
validator (Callable[[dict[str, dict[str, str]]], None]) – A function that takes a nested dictionary of config values and raises on error.
- Return type:
None
Examples
>>> def my_validator(cfg): ... assert 'main' in cfg ... assert 'foo' in cfg['main'] >>> config.validate(my_validator)
- values()¶
Get a
tranche.section.Sectionwrapper for each section.- Returns:
values – The sections of the combined config
- Return type:
- write(fp, include_sources=True, include_comments=True, raw=True)¶
Write the config options to the given file pointer.
- Parameters:
fp (TextIO) – The file pointer to write to.
include_sources (bool, optional) – Whether to include a comment above each option indicating the source file where it was defined
include_comments (bool, optional) – Whether to include the original comments associated with each section or option
raw (bool, optional) – Whether to write “raw” config options, rather than using extended interpolation
- Return type:
None