Skip to content

Exceptions

anycfg.exceptions, every name also importable from anycfg.

Every condition the library reports is a ConfigError, and each class also inherits the builtin exception for the same condition — ParseError is a ValueError, a PolicyError a PermissionError. A parser's own exception never crosses the API: every format translates it into ParseError, which carries a position and may name document structure (a key, a section, a tag, an alias) but never a value, a line or a snippet. An OSError from reading a file is raised as itself, so one clause covers every load failure:

import anycfg

try:
    config = anycfg.load("app.yaml")
except (anycfg.ConfigError, OSError) as error:
    ...

An error a load re-raises keeps its type and identity, and gains where it happened: config_source (the failing source), config_frames (an ErrorFrame per include, render, command or merge step, innermost first), config_key and config_model, rendered into its message as [in <source>; included from <file>, line <n>; at <a.b[0]> (<Model>)]. A wrong argument to a function raises a plain TypeError or ValueError.

anycfg.exceptions.ConfigError

Bases: Exception

Base class for every error anycfg raises.

An OSError from reading a source is not wrapped; catch (ConfigError, OSError) to cover every load failure.

__str__()

Source code in src/anycfg/exceptions.py
89
90
91
92
93
def __str__(self) -> str:
    # super(), not BaseException: a subclass that also inherits a stdlib
    # error (CalledProcessError, TimeoutExpired) keeps that error's own
    # wording and only gains the suffix.
    return super().__str__() + _render_context(self)

anycfg.exceptions.ParseError(msg, *, path=None, lineno=None, colno=None)

Bases: ConfigError, ValueError

A document is not valid in its format.

Every format raises this, translated from its parser's own error and raised from None, so the parser library is not part of the API and none of the document's text reaches the message, the attributes or the exception chain.

Attributes:

Name Type Description
path

The source's name, or None for in-memory content.

lineno

1-based line, or None when the parser does not say.

colno

1-based column, or None.

msg

The problem, without document text.

Source code in src/anycfg/exceptions.py
118
119
120
121
122
123
124
125
126
127
128
129
130
def __init__(
    self,
    msg: str,
    *,
    path: "_ty.Optional[str]" = None,
    lineno: "_ty.Optional[int]" = None,
    colno: "_ty.Optional[int]" = None,
) -> None:
    self.msg = msg
    self.path = path
    self.lineno = lineno
    self.colno = colno
    super().__init__(msg)

colno = colno instance-attribute

lineno = lineno instance-attribute

msg = msg instance-attribute

path = path instance-attribute

__reduce__()

Source code in src/anycfg/exceptions.py
138
139
140
141
142
143
def __reduce__(self):
    return (
        _rebuild_parse_error,
        (self.msg, self.path, self.lineno, self.colno),
        self.__dict__,
    )

__str__()

Source code in src/anycfg/exceptions.py
132
133
134
135
136
def __str__(self) -> str:
    where = [part for part in (self.path, self.lineno, self.colno) if part]
    position = ":".join(str(part) for part in where)
    text = f"{position}: {self.msg}" if position else self.msg
    return text + _render_context(self)

anycfg.exceptions.ConfigValueError

Bases: ConfigError, ValueError

A configuration value or structure the library cannot accept.

anycfg.exceptions.ConfigTypeError

Bases: ConfigError, TypeError

A configuration value of a type the requested operation cannot use.

anycfg.exceptions.TemplateError

Bases: ConfigError, ValueError

Rendering a template file or interpolating a value failed.

The engine's own exception is the __cause__. An interpolation failure carries config_key, the path of the value that failed.

anycfg.exceptions.UnsupportedFormatError

Bases: ConfigError, ValueError

No registered format reads or writes this source.

The message names the formats that are registered, and the extra to install when the format is known but its dependency is missing.

anycfg.exceptions.MissingDependencyError

Bases: UnsupportedFormatError, ImportError

A format or feature is known, but the extra it needs is not installed.

Also an ImportError. The message names the extra to install.

Policy refusals

anycfg.exceptions.PolicyError

Bases: ConfigError, PermissionError

The load's Policy refuses an operation.

Also a PermissionError, and so an OSError: "refused to do this" is what that type means. Raised before anything is read or run.

anycfg.exceptions.CommandsDisabledError

Bases: PolicyError

A command source was reached while the policy does not allow commands.

anycfg.exceptions.TemplatesDisabledError

Bases: PolicyError

A template source was reached while the policy does not allow it.

Raised for any template when allow_templates is off, and under a sandboxed policy for a template engine that cannot be sandboxed.

anycfg.exceptions.ConfinementError

Bases: PolicyError

A file read resolved outside every root confine_to allows.

The message names the resolved target and every root it was checked against, because a refusal nobody can diagnose gets switched off. For a glob match it names the pattern instead, since the match is a file name the document did not write.

anycfg.exceptions.BudgetExceededError

Bases: PolicyError

A load went past one of the policy's bounds: includes, depth or bytes.

Commands

anycfg.exceptions.CommandError

Bases: ConfigError, CalledProcessError

A command source exited non-zero.

Also a subprocess.CalledProcessError, with its constructor and its returncode/output/stderr attributes. The message ends with the tail of stderr; stdout, the payload, stays on .output.

__str__()

Source code in src/anycfg/exceptions.py
215
216
217
218
219
220
def __str__(self) -> str:
    return (
        _subprocess.CalledProcessError.__str__(self)
        + _stderr_tail(self.stderr)
        + _render_context(self)
    )

anycfg.exceptions.CommandTimeoutError

Bases: ConfigError, TimeoutExpired

A command source did not finish within its timeout.

Also a subprocess.TimeoutExpired, keeping its constructor, its timeout/cmd attributes and its wording. The process tree was killed.

__str__()

Source code in src/anycfg/exceptions.py
230
231
232
233
234
235
def __str__(self) -> str:
    return (
        _subprocess.TimeoutExpired.__str__(self)
        + _stderr_tail(self.stderr)
        + _render_context(self)
    )

Context

anycfg.exceptions.ErrorFrame

Bases: NamedTuple

One step on the way from the load call to the source that failed.

kind is "include", "render", "command" or "merge"; source is the file, template or command text of that step, and line the line within it where known (the line an !include is written on).

kind instance-attribute

line = None class-attribute instance-attribute

source instance-attribute