Reference

Configuration Transformations

copy(cfg, src, dest, expr=None, **kwargs)

Copy a value from one config key to another.

Examples:

>>> cfg = Config(
...     a={'b': 3.14},
...     _TRANSFORM=[
...         dict(name='copy',src='a.b',dest='c.d.e'),
...         dict(name='copy',src='a.b', another_src='c.d', dest='f',
...              expr='[src, another_src, src*2, [src]*2]'),
...     ]
... )
>>> print(cfg.resolve_transforms())
_CFG_ID: 4dea82568c56bf77f51d19e9aaa27f95

a:
  b: 3.14

c:
  d:
    e: 3.14

f:
- 3.14
- e: 3.14
- 6.28
- - 3.14
  - 3.14

Parameters:

Name Type Description Default
cfg Config

The configuration to which the transform is applied.

required
src str

The key of the source value.

required
dest str

The key that is created or overriden using the source value.

required
expr str

If provided, the destination will become an evaluation of the string, replacing names with config values specified by src and other kwargs. simpleeval is the package used in the background and only supports basic operations.

None
Source code in src/runcon/transforms.py
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def copy(cfg: Config, src: str, dest: str, expr: str = None, **kwargs) -> None:
    """Copy a value from one config key to another.

    Examples:
        >>> cfg = Config(
        ...     a={'b': 3.14},
        ...     _TRANSFORM=[
        ...         dict(name='copy',src='a.b',dest='c.d.e'),
        ...         dict(name='copy',src='a.b', another_src='c.d', dest='f',
        ...              expr='[src, another_src, src*2, [src]*2]'),
        ...     ]
        ... )
        >>> print(cfg.resolve_transforms())
        _CFG_ID: 4dea82568c56bf77f51d19e9aaa27f95
        <BLANKLINE>
        a:
          b: 3.14
        <BLANKLINE>
        c:
          d:
            e: 3.14
        <BLANKLINE>
        f:
        - 3.14
        - e: 3.14
        - 6.28
        - - 3.14
          - 3.14
        <BLANKLINE>

    Args:
        cfg: The configuration to which the transform is applied.
        src: The key of the source value.
        dest: The key that is created or overriden using the source value.
        expr: If provided, the destination will become an evaluation of the string,
              replacing names with config values specified by src and other kwargs.
              `simpleeval` is the package used in the background
              and only supports basic operations.
    """
    if expr is None:
        if src not in cfg:
            raise ValueError("config has no key '%s' to copy from:\n%s" % (src, cfg))
        if len(kwargs):
            raise ValueError(
                "kwargs were provided without an 'expr' that uses them:\n%s"
                % set(kwargs.keys())
            )
        cfg[dest] = cfg[src]
    else:
        import copy as copy_module

        import simpleeval as se

        kwargs["src"] = src
        substitutions = se.DEFAULT_NAMES
        for name, key in kwargs.items():
            if name not in expr:
                raise ValueError(
                    "variable %s was given in kwargs but not used in expr '%s'"
                    % (name, expr)
                )
            if key not in cfg:
                raise ValueError(
                    "config has no key '%s' to copy from:\n%s" % (key, cfg)
                )
            substitutions[name] = copy_module.copy(cfg[key])
        cfg[dest] = se.EvalWithCompoundTypes(names=substitutions).eval(expr)

remove_element(cfg, key, idx=None)

Remove an element from a collection.

Examples:

>>> cfg = Config(
...     a={'b': [3.14, 2.71], 'c': 'pi'},
...     _TRANSFORM=[
...         {'name': 'remove_element', 'key': 'a.c'},
...         {'name': 'remove_element', 'key': 'a.b', 'idx': 1},
...     ]
... )
>>> print(cfg.resolve_transforms())
_CFG_ID: a2faf743fded6c92e3fc83b994b7a065

a:
  b:
  - 3.14

Parameters:

Name Type Description Default
cfg Config

The configuration to which the transform is applied.

required
key str

The config key which is removed (or a list-element, see idx).

required
idx int

If not None, specifying a specific list idx to be deleted instead of the entire list.

None
Source code in src/runcon/transforms.py
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def remove_element(cfg: Config, key: str, idx: int = None) -> None:
    """Remove an element from a collection.

    Examples:
        >>> cfg = Config(
        ...     a={'b': [3.14, 2.71], 'c': 'pi'},
        ...     _TRANSFORM=[
        ...         {'name': 'remove_element', 'key': 'a.c'},
        ...         {'name': 'remove_element', 'key': 'a.b', 'idx': 1},
        ...     ]
        ... )
        >>> print(cfg.resolve_transforms())
        _CFG_ID: a2faf743fded6c92e3fc83b994b7a065
        <BLANKLINE>
        a:
          b:
          - 3.14
        <BLANKLINE>

    Args:
        cfg: The configuration to which the transform is applied.
        key: The config key which is removed (or a list-element, see idx).
        idx: If not None, specifying a specific list idx to be deleted
             instead of the entire list.
    """
    if idx is None:
        del cfg[key]
    else:
        del cfg[key][idx]

resolve_env(cfg)

Resolve environment variables in all collections, marked through a leading $.

Examples:

>>> cfg = Config(
...     a={'b': [3.14, '$RESOLVABLE_ENV_VARIABLE']},
...     _TRANSFORM=['resolve_env']
... )
>>> os.environ['RESOLVABLE_ENV_VARIABLE'] = 'pi'
>>> print(cfg.resolve_transforms())
_CFG_ID: a2faf743fded6c92e3fc83b994b7a065

a:
  b:
  - 3.14
  - pi

Parameters:

Name Type Description Default
cfg Any

The configuration, or any subcollection, to which the transform is applied.

required
Source code in src/runcon/transforms.py
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
def resolve_env(cfg: Any) -> Any:
    """Resolve environment variables in all collections, marked through a leading $.

    Examples:
        >>> cfg = Config(
        ...     a={'b': [3.14, '$RESOLVABLE_ENV_VARIABLE']},
        ...     _TRANSFORM=['resolve_env']
        ... )
        >>> os.environ['RESOLVABLE_ENV_VARIABLE'] = 'pi'
        >>> print(cfg.resolve_transforms())
        _CFG_ID: a2faf743fded6c92e3fc83b994b7a065
        <BLANKLINE>
        a:
          b:
          - 3.14
          - pi
        <BLANKLINE>

    Args:
        cfg: The configuration, or any subcollection, to which the transform is applied.
    """
    if is_mapping(cfg):
        for key in cfg:
            cfg[key] = resolve_env(cfg[key])
    elif is_sequence(cfg):
        try:
            for i, _ in enumerate(cfg):
                cfg[i] = resolve_env(cfg[i])
        except TypeError as err:
            if "does not support item assignment" not in str(err):
                raise
            t = type(cfg)
            cfg = t(resolve_env(elem) for elem in cfg)
    elif isinstance(cfg, str):
        if cfg[0] == "$":
            resolve = os.getenv(cfg[1:])
            if resolve is None:
                raise ValueError("environment variable named %s was not defined" % cfg)
            cfg = resolve

    return cfg