Files
computer-playbook/utils/yaml_bootstrap.py
kevinveenbirkenbachandClaude Opus 5.5 6e776a5780 refactor(python): clear the open CodeQL code-quality alerts
- Declare `__all__` in every package `__init__.py` whose `PROJECT_ROOT`
  is imported by its modules (163 packages), so the constant counts as
  exported; list every public name where the package defines more.
- Empty the 15 package `__init__.py` files whose `PROJECT_ROOT` no module
  imports.
- Declare the public API of `utils.github.variant.axes` in `__all__`,
  re-exports included, instead of silencing them with `noqa: F401`; the
  list matches the one `feature/store-i18n` already carries.
- Use `import unittest.mock as mock` in `test_applications.py`, as the
  rest of the suite does.
- Spell `_NON_PRINTABLE` in `utils/yaml_bootstrap.py` as the equivalent
  BMP-only positive class; it matches exactly the same 2111 code points
  as the old negated class across U+0000..U+10FFFF.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-20 21:40:58 +02:00

136 lines
5.3 KiB
Python

"""Stdlib reader for the block-YAML subset the bootstrap SPOT files use.
This is a deliberate second YAML touchpoint outside ``utils.cache.yaml``:
the modules that read the distro SPOT must import on the bare bootstrap
python, which runs the ``.env`` generator before any dependency is
installed, so they cannot reach the PyYAML-backed cache.
Supported: nested block mappings, block sequences of scalars, plain and
double-quoted string scalars, full-line and trailing comments, a single
leading document marker. Every other construct raises
:class:`BootstrapYamlError`, so ``load_block(text)`` either equals
``yaml.safe_load(text)`` or fails loud.
The plain-scalar rule is deliberately narrower than YAML's: a plain scalar
must start with a letter, an underscore or a slash, and may then carry only
``[A-Za-z0-9_./+@:-]`` and spaces. That excludes every leading character
PyYAML's implicit resolvers key off, so no accepted plain scalar can come
back as an int, float, bool, timestamp or null.
"""
from __future__ import annotations
import re
_PLAIN = re.compile(r"^[A-Za-z_/][A-Za-z0-9_./+@:\- ]*$")
_RESERVED = re.compile(r"^(?:true|false|yes|no|on|off|y|n|null)$", re.IGNORECASE)
_NON_PRINTABLE = re.compile(
r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f-\x84\x86-\x9f\ud800-\udfff￾￿]"
)
class BootstrapYamlError(ValueError):
"""Raised for a construct outside the supported block subset."""
def _plain(text: str, lineno: int) -> str:
if not _PLAIN.match(text) or ": " in text or text.endswith(":"):
raise BootstrapYamlError(f"line {lineno}: unsupported plain scalar {text!r}")
if _RESERVED.match(text):
raise BootstrapYamlError(f"line {lineno}: {text!r} is not a string, quote it")
return text
def _scalar(raw: str, lineno: int) -> str:
if raw.startswith('"'):
end = raw.find('"', 1)
if end < 0 or "\\" in raw[1:end]:
raise BootstrapYamlError(
f"line {lineno}: unsupported quoted scalar {raw!r}"
)
trailer = raw[end + 1 :].strip()
if trailer and not trailer.startswith("#"):
raise BootstrapYamlError(f"line {lineno}: trailing text after {raw!r}")
return raw[1:end]
return _plain(raw.split(" #", 1)[0].strip(), lineno)
def load_block(text: str) -> dict:
"""Parse *text* as a block mapping and return it.
Args:
text: YAML source restricted to the supported block subset.
Returns:
The root mapping, with every scalar as a ``str``.
Raises:
BootstrapYamlError: for any construct outside the subset.
"""
non_printable = _NON_PRINTABLE.search(text)
if non_printable:
raise BootstrapYamlError(
f"non-printable character {non_printable.group()!r} at offset {non_printable.start()}"
)
root: dict = {}
stack: list[tuple[int, object]] = [(0, root)]
pending: tuple[dict, str, int] | None = None
for lineno, line in enumerate(text.splitlines(), 1):
if "\t" in line:
raise BootstrapYamlError(f"line {lineno}: tab indentation")
body = line.strip()
if not body or body.startswith("#"):
continue
if body == "---":
if lineno != 1:
raise BootstrapYamlError(f"line {lineno}: second document")
if line.startswith(" "):
raise BootstrapYamlError(f"line {lineno}: indented document marker")
continue
indent = len(line) - len(line.lstrip(" "))
if pending is not None:
parent, key, parent_indent = pending
if indent <= parent_indent:
raise BootstrapYamlError(
f"line {lineno}: {key!r} has neither a value nor a block"
)
child: object = [] if body.startswith("- ") else {}
parent[key] = child
stack.append((indent, child))
pending = None
else:
while indent < stack[-1][0]:
stack.pop()
if indent != stack[-1][0]:
raise BootstrapYamlError(f"line {lineno}: unexpected indent")
container = stack[-1][1]
if body.startswith("- "):
if not isinstance(container, list):
raise BootstrapYamlError(f"line {lineno}: sequence entry in a mapping")
container.append(_scalar(body[2:], lineno))
continue
if isinstance(container, list):
raise BootstrapYamlError(f"line {lineno}: mapping entry in a sequence")
key, sep, rest = body.partition(": ")
if not sep:
if not body.endswith(":"):
raise BootstrapYamlError(
f"line {lineno}: not a mapping entry: {body!r}"
)
key, rest = body[:-1], ""
if key != key.strip():
raise BootstrapYamlError(f"line {lineno}: not a mapping entry: {body!r}")
_plain(key, lineno)
if key in container:
raise BootstrapYamlError(f"line {lineno}: duplicate key {key!r}")
rest = rest.strip()
if not rest or rest.startswith("#"):
pending = (container, key, indent)
continue
container[key] = _scalar(rest, lineno)
if pending is not None:
raise BootstrapYamlError(f"{pending[1]!r} has neither a value nor a block")
if not root:
raise BootstrapYamlError("empty document")
return root