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

1"""Domain models for config, catalog entries, and pip requirements.""" 

2 

3from __future__ import annotations 

4 

5from dataclasses import dataclass 

6from enum import StrEnum 

7from pathlib import Path 

8 

9 

10class SourceType(StrEnum): 

11 FILE = "file" 

12 GIT = "git" 

13 

14 

15class RefreshMode(StrEnum): 

16 ALWAYS = "always" 

17 AUTO = "auto" 

18 NEVER = "never" 

19 

20 

21@dataclass(frozen=True) 

22class PackageSource: 

23 """One [packages.<name>] record (ADR-0010, ADR-0011).""" 

24 

25 name: str 

26 url: str 

27 revision: str | None = None 

28 subdirectory: str | None = None 

29 catalog_source: str | None = None 

30 

31 

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" 

40 

41 

42@dataclass(frozen=True) 

43class PolicyConfig: 

44 allowed_schemes: tuple[str, ...] = ("git+ssh", "git+https") 

45 require_pinned_revision: bool = False 

46 

47 

48@dataclass(frozen=True) 

49class RuntimeConfig: 

50 python: str = "python3" 

51 

52 

53@dataclass(frozen=True) 

54class EffectiveConfig: 

55 """Merged config after CLI / env / files / defaults.""" 

56 

57 sources: tuple[SourceConfig, ...] 

58 policy: PolicyConfig 

59 runtime: RuntimeConfig 

60 config_path: Path | None = None 

61 

62 @property 

63 def source(self) -> SourceConfig: 

64 """First source (legacy `[source]` / env overlay).""" 

65 return self.sources[0] 

66 

67 

68@dataclass(frozen=True) 

69class RenderedRequirement: 

70 """Pip direct-URL requirement string for one package (AC-0006).""" 

71 

72 package: str 

73 text: str