1
2
3
4
5
6
7
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
37
38
39
40
41
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
83
84
85
86
87
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
|
"""Sources."""
from __future__ import annotations
from abc import ABC, abstractmethod
from pathlib import Path
from typing import Any, Iterator, List
from tox.config.loader.api import Loader, OverrideMap
from ..loader.section import Section
from ..sets import ConfigSet, CoreConfigSet
class Source(ABC):
"""
Source is able to return a configuration value (for either the core or per environment source).
"""
FILENAME = ""
def __init__(self, path: Path) -> None:
self.path: Path = path #: the path to the configuration source
self._section_to_loaders: dict[str, list[Loader[Any]]] = {}
def get_loaders(
self,
section: Section,
base: list[str] | None,
override_map: OverrideMap,
conf: ConfigSet,
) -> Iterator[Loader[Any]]:
"""
Return a loader that loads settings from a given section name.
:param section: the section to load
:param base: base sections to fallback to
:param override_map: a list of overrides to apply
:param conf: the config set to use
:returns: the loaders to use
"""
section = self.transform_section(section)
key = section.key
if key in self._section_to_loaders:
yield from self._section_to_loaders[key]
return
loaders: list[Loader[Any]] = []
self._section_to_loaders[key] = loaders
loader: Loader[Any] | None = self.get_loader(section, override_map)
if loader is not None:
loaders.append(loader)
yield loader
if base is not None:
conf.add_config(
keys="base",
of_type=List[str],
desc="inherit missing keys from these sections",
default=base,
)
for base_section in self.get_base_sections(conf["base"], section):
child = loader
loader = self.get_loader(base_section, override_map)
if loader is None:
loader = child
continue
if child is not None and loader is not None:
child.parent = loader
yield loader
loaders.append(loader)
@abstractmethod
def transform_section(self, section: Section) -> Section:
raise NotImplementedError
@abstractmethod
def get_loader(self, section: Section, override_map: OverrideMap) -> Loader[Any] | None:
raise NotImplementedError
@abstractmethod
def get_base_sections(self, base: list[str], in_section: Section) -> Iterator[Section]:
raise NotImplementedError
@abstractmethod
def sections(self) -> Iterator[Section]:
"""
Return a loader that loads the core configuration values.
:returns: the core loader from this source
"""
raise NotImplementedError
@abstractmethod
def envs(self, core_conf: CoreConfigSet) -> Iterator[str]:
"""
:param core_conf: the core configuration set
:returns: a list of environments defined within this source
"""
raise NotImplementedError
@abstractmethod
def get_tox_env_section(self, item: str) -> tuple[Section, list[str], list[str]]:
""":returns: the section for a tox environment"""
raise NotImplementedError
@abstractmethod
def get_core_section(self) -> Section:
""":returns: the core section"""
raise NotImplementedError
__all__ = [
"Section",
"Source",
]
|