8c9d4fbc46
- Rename _manifest_util.py → manifest_util.py (module isn't private) - Rename _as_json_object → as_json_object, _parse_git_upstream → parse_git_upstream, _parse_git_gate_config → parse_git_gate_config, _validate_unique_git_names → validate_unique_git_names, _validate_egress_routes → validate_egress_routes (none are private at module boundary — underscore prefix was a carry-over from the old monolithic manifest.py where everything lived in one namespace) - Move _is_ip_literal → util.is_ip_literal (generic, belongs in the top-level util module) - Update all import sites across manifest_*.py, manifest_extends.py, manifest_schema.py; existing callers of manifest.py are unaffected All 867 unit tests pass.
25 lines
863 B
Python
25 lines
863 B
Python
"""Shared manifest primitives used by all manifest sub-modules."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import cast
|
|
|
|
|
|
class ManifestError(Exception):
|
|
"""A manifest file (or the manifest tree) is invalid."""
|
|
|
|
|
|
def as_json_object(value: object, label: str) -> dict[str, object]:
|
|
"""Assert that `value` is a JSON object (str-keyed dict) and return
|
|
a view typed as `dict[str, object]` so downstream `.get(...)` calls
|
|
have a typed surface."""
|
|
if not isinstance(value, dict):
|
|
raise ManifestError(f"{label} must be a JSON object (was {type(value).__name__})")
|
|
items = cast(dict[object, object], value)
|
|
out: dict[str, object] = {}
|
|
for k, v in items.items():
|
|
if not isinstance(k, str):
|
|
raise ManifestError(f"{label} keys must be strings (found {type(k).__name__})")
|
|
out[k] = v
|
|
return out
|