Coverage for src/lpip/models.py: 100%
46 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-17 20:19 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-17 20:19 +0000
1"""Domain models for config, catalog entries, and pip requirements."""
3from __future__ import annotations
5from dataclasses import dataclass
6from enum import StrEnum
7from pathlib import Path
10class SourceType(StrEnum):
11 FILE = "file"
12 GIT = "git"
15class RefreshMode(StrEnum):
16 ALWAYS = "always"
17 AUTO = "auto"
18 NEVER = "never"
21@dataclass(frozen=True)
22class PackageSource:
23 """One [packages.<name>] record (ADR-0010, ADR-0011)."""
25 name: str
26 url: str
27 revision: str | None = None
28 subdirectory: str | None = None
29 catalog_source: str | None = None
32@dataclass(frozen=True)
33class SourceConfig:
34 type: SourceType
35 path: str
36 url: str | None = None
37 revision: str | None = None
38 refresh: RefreshMode | None = None
39 name: str = "default"
42@dataclass(frozen=True)
43class PolicyConfig:
44 allowed_schemes: tuple[str, ...] = ("git+ssh", "git+https")
45 require_pinned_revision: bool = False
48@dataclass(frozen=True)
49class RuntimeConfig:
50 python: str = "python3"
53@dataclass(frozen=True)
54class EffectiveConfig:
55 """Merged config after CLI / env / files / defaults."""
57 sources: tuple[SourceConfig, ...]
58 policy: PolicyConfig
59 runtime: RuntimeConfig
60 config_path: Path | None = None
62 @property
63 def source(self) -> SourceConfig:
64 """First source (legacy `[source]` / env overlay)."""
65 return self.sources[0]
68@dataclass(frozen=True)
69class RenderedRequirement:
70 """Pip direct-URL requirement string for one package (AC-0006)."""
72 package: str
73 text: str