Coverage for youversion/models/bible.py: 100%
43 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-26 11:31 +0100
« prev ^ index » next coverage.py v7.14.3, created at 2026-06-26 11:31 +0100
1"""Bible-related data models."""
3from typing import Any, Protocol
5try:
6 from typing import TypeAlias
7except ImportError:
8 # Python < 3.10 compatibility
9 from typing import TypeAlias
12class LanguageProtocol(Protocol):
13 """Protocol for language information."""
15 id: int
16 name: str
17 language_tag: str
18 local_name: str | None
20 def __getattr__(self, name: str) -> Any:
21 """Allow access to dynamically added fields."""
22 class_name = self.__class__.__name__
23 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
26# Type alias for convenience
27Language: TypeAlias = LanguageProtocol
30class PublisherProtocol(Protocol):
31 """Protocol for publisher information."""
33 id: int
34 name: str
35 url: str | None
37 def __getattr__(self, name: str) -> Any:
38 """Allow access to dynamically added fields."""
39 class_name = self.__class__.__name__
40 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
43# Type alias for convenience
44Publisher: TypeAlias = PublisherProtocol
47class BookProtocol(Protocol):
48 """Protocol for Bible book information."""
50 id: int
51 name: str
52 abbreviation: str
53 chapters: list[int]
54 testament: str | None
56 def __getattr__(self, name: str) -> Any:
57 """Allow access to dynamically added fields."""
58 class_name = self.__class__.__name__
59 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
62# Type alias for convenience
63Book: TypeAlias = BookProtocol
66class VersionProtocol(Protocol):
67 """Protocol for Bible version information."""
69 id: int
70 title: str
71 abbreviation: str
72 language: Language
73 publisher: Publisher
74 books: list[Book]
75 text: bool
76 audio: bool
77 copyright_short: str | None
78 copyright_long: str | None
79 local_title: str | None
80 local_abbreviation: str | None
81 language_tag_selected: str | None
82 last_modified: int | None
83 metadata_build: int | None
84 reader_footer: str | None
85 reader_footer_url: str | None
87 def __getattr__(self, name: str) -> Any:
88 """Allow access to dynamically added fields."""
89 class_name = self.__class__.__name__
90 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
93# Type alias for convenience
94Version: TypeAlias = VersionProtocol
97class ChapterProtocol(Protocol):
98 """Protocol for chapter information."""
100 usfm: str
101 human: str
102 canonical: bool
103 toc: bool
105 def __getattr__(self, name: str) -> Any:
106 """Allow access to dynamically added fields."""
107 class_name = self.__class__.__name__
108 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
111# Type alias for convenience
112Chapter: TypeAlias = ChapterProtocol
115class ChapterContentProtocol(Protocol):
116 """Protocol for chapter content with verses."""
118 id: int
119 reference: str
120 content: str
121 verses: list[str]
122 chapters: list[Chapter]
123 version: Version
125 def __getattr__(self, name: str) -> Any:
126 """Allow access to dynamically added fields."""
127 class_name = self.__class__.__name__
128 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
131# Type alias for convenience
132ChapterContent: TypeAlias = ChapterContentProtocol
135class ConfigurationProtocol(Protocol):
136 """Protocol for Bible configuration."""
138 versions: list[Version]
139 languages: list[Language]
140 stylesheets: list[dict] | None
142 def __getattr__(self, name: str) -> Any:
143 """Allow access to dynamically added fields."""
144 class_name = self.__class__.__name__
145 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
148# Type alias for convenience
149Configuration: TypeAlias = ConfigurationProtocol
152class RecommendedLanguagesProtocol(Protocol):
153 """Protocol for recommended languages for a country."""
155 languages: list[Language]
156 country: str
158 def __getattr__(self, name: str) -> Any:
159 """Allow access to dynamically added fields."""
160 class_name = self.__class__.__name__
161 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
164# Type alias for convenience
165RecommendedLanguages: TypeAlias = RecommendedLanguagesProtocol