Skip to content

types.py

Complex types, annotations, validators.

LazyDict

Bases: Mapping[_K, _V]

A dict where values are functions that get evaluated only once when requested.

Source code in copier/_types.py
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
class LazyDict(Mapping[_K, _V]):
    """A dict where values are functions that get evaluated only once when requested."""

    def __init__(self, mapping: Mapping[_K, Callable[[], _V]] | None = None):
        self._pending = mapping or {}
        self._done: dict[_K, _V] = {}

    def __getitem__(self, key: _K) -> _V:
        if key not in self._done:
            self._done[key] = self._pending[key]()
        return self._done[key]

    def __iter__(self) -> Iterator[_K]:
        return iter(self._pending)

    def __len__(self) -> int:
        return len(self._pending)

Phase

Bases: str, Enum

The known execution phases.

Source code in copier/_types.py
 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
class Phase(str, Enum):
    """The known execution phases."""

    PROMPT = "prompt"
    TASKS = "tasks"
    MIGRATE = "migrate"
    RENDER = "render"
    UNDEFINED = "undefined"

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

    @classmethod
    @contextmanager
    def use(cls, phase: Phase) -> Iterator[None]:
        """Set the current phase for the duration of a context."""
        token = _phase.set(phase)
        try:
            yield
        finally:
            _phase.reset(token)

    @classmethod
    def current(cls) -> Phase:
        """Get the current phase."""
        return _phase.get()

current() classmethod

Get the current phase.

Source code in copier/_types.py
121
122
123
124
@classmethod
def current(cls) -> Phase:
    """Get the current phase."""
    return _phase.get()

use(phase) classmethod

Set the current phase for the duration of a context.

Source code in copier/_types.py
111
112
113
114
115
116
117
118
119
@classmethod
@contextmanager
def use(cls, phase: Phase) -> Iterator[None]:
    """Set the current phase for the duration of a context."""
    token = _phase.set(phase)
    try:
        yield
    finally:
        _phase.reset(token)

path_is_absolute(value)

Require absolute paths in an argument.

Source code in copier/_types.py
53
54
55
56
57
58
59
def path_is_absolute(value: Path) -> Path:
    """Require absolute paths in an argument."""
    if not value.is_absolute():
        from .errors import PathNotAbsoluteError

        raise PathNotAbsoluteError(path=value)
    return value

path_is_relative(value)

Require relative paths in an argument.

Source code in copier/_types.py
62
63
64
65
66
67
68
def path_is_relative(value: Path) -> Path:
    """Require relative paths in an argument."""
    if value.is_absolute():
        from .errors import PathNotRelativeError

        raise PathNotRelativeError(path=value)
    return value