Skip to content

errors.py

Custom exceptions used by Copier.

ConfigFileError

Bases: ValueError, CopierError

Parent class defining problems with the config file.

Source code in copier/errors.py
44
45
class ConfigFileError(ValueError, CopierError):
    """Parent class defining problems with the config file."""

CopierAnswersInterrupt

Bases: CopierError, KeyboardInterrupt

CopierAnswersInterrupt is raised during interactive question prompts.

It typically follows a KeyboardInterrupt (i.e. ctrl-c) and provides an opportunity for the caller to conduct additional cleanup, such as writing the partially completed answers to a file.

Attributes:

Name Type Description
answers

AnswersMap that contains the partially completed answers object.

last_question

Question representing the last_question that was asked at the time the interrupt was raised.

template

Template that was being processed for answers.

Source code in copier/errors.py
 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
class CopierAnswersInterrupt(CopierError, KeyboardInterrupt):
    """CopierAnswersInterrupt is raised during interactive question prompts.

    It typically follows a KeyboardInterrupt (i.e. ctrl-c) and provides an
    opportunity for the caller to conduct additional cleanup, such as writing
    the partially completed answers to a file.

    Attributes:
        answers:
            AnswersMap that contains the partially completed answers object.

        last_question:
            Question representing the last_question that was asked at the time
            the interrupt was raised.

        template:
            Template that was being processed for answers.

    """

    def __init__(
        self, answers: AnswersMap, last_question: Question, template: Template
    ) -> None:
        self.answers = answers
        self.last_question = last_question
        self.template = template

CopierError

Bases: Exception

Base class for all other Copier errors.

Source code in copier/errors.py
26
27
class CopierError(Exception):
    """Base class for all other Copier errors."""

CopierWarning

Bases: Warning

Base class for all other Copier warnings.

Source code in copier/errors.py
170
171
class CopierWarning(Warning):
    """Base class for all other Copier warnings."""

DirtyLocalWarning

Bases: UserWarning, CopierWarning

Changes and untracked files present in template.

Source code in copier/errors.py
182
183
class DirtyLocalWarning(UserWarning, CopierWarning):
    """Changes and untracked files present in template."""

ExtensionNotFoundError

Bases: UserMessageError

Extensions listed in the configuration could not be loaded.

Source code in copier/errors.py
88
89
class ExtensionNotFoundError(UserMessageError):
    """Extensions listed in the configuration could not be loaded."""

InteractiveSessionError

Bases: UserMessageError

An interactive session is required to run this program.

Source code in copier/errors.py
198
199
200
201
202
class InteractiveSessionError(UserMessageError):
    """An interactive session is required to run this program."""

    def __init__(self, message: str) -> None:
        super().__init__(f"Interactive session required: {message}")

InvalidConfigFileError

Bases: ConfigFileError

Indicates that the config file is wrong.

Source code in copier/errors.py
48
49
50
51
52
53
54
class InvalidConfigFileError(ConfigFileError):
    """Indicates that the config file is wrong."""

    def __init__(self, conf_path: Path, quiet: bool):
        msg = str(conf_path)
        printf_exception(self, "INVALID CONFIG FILE", msg=msg, quiet=quiet)
        super().__init__(msg)

InvalidTypeError

Bases: TypeError, CopierError

The question type is not among the supported ones.

Source code in copier/errors.py
66
67
class InvalidTypeError(TypeError, CopierError):
    """The question type is not among the supported ones."""

MissingFileWarning

Bases: UserWarning, CopierWarning

I still couldn't find what I'm looking for.

Source code in copier/errors.py
194
195
class MissingFileWarning(UserWarning, CopierWarning):
    """I still couldn't find what I'm looking for."""

MissingSettingsWarning

Bases: UserWarning, CopierWarning

Settings path has been defined but file is missing.

Source code in copier/errors.py
190
191
class MissingSettingsWarning(UserWarning, CopierWarning):
    """Settings path has been defined but file is missing."""

MultipleConfigFilesError

Bases: ConfigFileError

Both copier.yml and copier.yaml found, and that's an error.

Source code in copier/errors.py
57
58
59
60
61
62
63
class MultipleConfigFilesError(ConfigFileError):
    """Both copier.yml and copier.yaml found, and that's an error."""

    def __init__(self, conf_paths: PathSeq):
        msg = str(conf_paths)
        printf_exception(self, "MULTIPLE CONFIG FILES", msg=msg)
        super().__init__(msg)

MultipleYieldTagsError

Bases: CopierError

Multiple yield tags are used in one path name, but it is not allowed.

Source code in copier/errors.py
136
137
class MultipleYieldTagsError(CopierError):
    """Multiple yield tags are used in one path name, but it is not allowed."""

OldTemplateWarning

Bases: UserWarning, CopierWarning

Template was designed for an older Copier version.

Source code in copier/errors.py
178
179
class OldTemplateWarning(UserWarning, CopierWarning):
    """Template was designed for an older Copier version."""

PathError

Bases: CopierError, ValueError

The path is invalid in the given context.

Source code in copier/errors.py
70
71
class PathError(CopierError, ValueError):
    """The path is invalid in the given context."""

PathNotAbsoluteError

Bases: PathError

The path is not absolute, but it should be.

Source code in copier/errors.py
74
75
76
77
78
class PathNotAbsoluteError(PathError):
    """The path is not absolute, but it should be."""

    def __init__(self, *, path: Path) -> None:
        super().__init__(f'"{path}" is not an absolute path')

PathNotRelativeError

Bases: PathError

The path is not relative, but it should be.

Source code in copier/errors.py
81
82
83
84
85
class PathNotRelativeError(PathError):
    """The path is not relative, but it should be."""

    def __init__(self, *, path: Path) -> None:
        super().__init__(f'"{path}" is not a relative path')

ShallowCloneWarning

Bases: UserWarning, CopierWarning

The template repository is a shallow clone.

Source code in copier/errors.py
186
187
class ShallowCloneWarning(UserWarning, CopierWarning):
    """The template repository is a shallow clone."""

TaskError

Bases: CalledProcessError, UserMessageError

Exception raised when a task fails.

Source code in copier/errors.py
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
class TaskError(subprocess.CalledProcessError, UserMessageError):
    """Exception raised when a task fails."""

    def __init__(
        self,
        command: str | Sequence[str],
        returncode: int,
        stdout: str | bytes | None,
        stderr: str | bytes | None,
    ):
        subprocess.CalledProcessError.__init__(
            self, returncode=returncode, cmd=command, output=stdout, stderr=stderr
        )
        message = f"Task {command!r} returned non-zero exit status {returncode}."
        UserMessageError.__init__(self, message)

    @classmethod
    def from_process(
        cls, process: CompletedProcess[str] | CompletedProcess[bytes]
    ) -> Self:
        """Create a TaskError from a CompletedProcess."""
        return cls(
            command=process.args,
            returncode=process.returncode,
            stdout=process.stdout,
            stderr=process.stderr,
        )

from_process(process) classmethod

Create a TaskError from a CompletedProcess.

Source code in copier/errors.py
156
157
158
159
160
161
162
163
164
165
166
@classmethod
def from_process(
    cls, process: CompletedProcess[str] | CompletedProcess[bytes]
) -> Self:
    """Create a TaskError from a CompletedProcess."""
    return cls(
        command=process.args,
        returncode=process.returncode,
        stdout=process.stdout,
        stderr=process.stderr,
    )

UnknownCopierVersionWarning

Bases: UserWarning, CopierWarning

Cannot determine installed Copier version.

Source code in copier/errors.py
174
175
class UnknownCopierVersionWarning(UserWarning, CopierWarning):
    """Cannot determine installed Copier version."""

UnsafeTemplateError

Bases: CopierError

Unsafe Copier template features are used without explicit consent.

Source code in copier/errors.py
120
121
122
123
124
125
126
127
128
129
class UnsafeTemplateError(CopierError):
    """Unsafe Copier template features are used without explicit consent."""

    def __init__(self, features: Sequence[str]):
        assert features
        s = "s" if len(features) > 1 else ""
        super().__init__(
            f"Template uses potentially unsafe feature{s}: {', '.join(features)}.\n"
            "If you trust this template, consider adding the `--trust` option when running `copier copy/update`."
        )

UnsupportedVersionError

Bases: UserMessageError

Copier version does not support template version.

Source code in copier/errors.py
40
41
class UnsupportedVersionError(UserMessageError):
    """Copier version does not support template version."""

UserMessageError

Bases: CopierError

Exit the program giving a message to the user.

Source code in copier/errors.py
30
31
32
33
34
35
36
37
class UserMessageError(CopierError):
    """Exit the program giving a message to the user."""

    def __init__(self, message: str):
        self.message = message

    def __str__(self) -> str:
        return self.message

YieldTagInFileError

Bases: CopierError

A yield tag is used in the file content, but it is not allowed.

Source code in copier/errors.py
132
133
class YieldTagInFileError(CopierError):
    """A yield tag is used in the file content, but it is not allowed."""