Coverage for youversion/models/friends.py: 100%
45 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"""Friends and social features data models."""
3from datetime import datetime
4from typing import Any, Protocol
6try:
7 from typing import TypeAlias
8except ImportError:
9 # Python < 3.10 compatibility
10 from typing import TypeAlias
12from .common import UserBase
15class ContactProtocol(Protocol):
16 """Protocol for contact information."""
18 email: str
19 name: str | None
20 phone: str | None
22 def __getattr__(self, name: str) -> Any:
23 """Allow access to dynamically added fields."""
24 class_name = self.__class__.__name__
25 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
28# Type alias for convenience
29Contact: TypeAlias = ContactProtocol
32class ContactsProtocol(Protocol):
33 """Protocol for contacts list."""
35 contacts: list[Contact]
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
44Contacts: TypeAlias = ContactsProtocol
47class FriendProtocol(Protocol):
48 """Protocol for friend information."""
50 user: UserBase
51 friendship_id: int | None
52 created_dt: datetime | None
54 def __getattr__(self, name: str) -> Any:
55 """Allow access to dynamically added fields."""
56 class_name = self.__class__.__name__
57 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
60# Type alias for convenience
61Friend: TypeAlias = FriendProtocol
64class FriendsProtocol(Protocol):
65 """Protocol for friends list."""
67 friends: list[Friend]
68 total: int
70 def __getattr__(self, name: str) -> Any:
71 """Allow access to dynamically added fields."""
72 class_name = self.__class__.__name__
73 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
76# Type alias for convenience
77Friends: TypeAlias = FriendsProtocol
80class FriendOfferProtocol(Protocol):
81 """Protocol for friend offer/request information."""
83 id: int
84 from_user: UserBase
85 to_user: UserBase
86 status: str
87 created_dt: datetime | None
89 def __getattr__(self, name: str) -> Any:
90 """Allow access to dynamically added fields."""
91 class_name = self.__class__.__name__
92 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
95# Type alias for convenience
96FriendOffer: TypeAlias = FriendOfferProtocol
99class OffersProtocol(Protocol):
100 """Protocol for friend offers list."""
102 offers: list[FriendOffer]
103 total: int
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
112Offers: TypeAlias = OffersProtocol
115class FriendableProtocol(Protocol):
116 """Protocol for friendable user (suggestion)."""
118 user: UserBase
119 reason: str | None
120 mutual_friends: int | None
122 def __getattr__(self, name: str) -> Any:
123 """Allow access to dynamically added fields."""
124 class_name = self.__class__.__name__
125 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
128# Type alias for convenience
129Friendable: TypeAlias = FriendableProtocol
132class FriendablesProtocol(Protocol):
133 """Protocol for friendable users list."""
135 users: list[Friendable]
136 total: int
138 def __getattr__(self, name: str) -> Any:
139 """Allow access to dynamically added fields."""
140 class_name = self.__class__.__name__
141 raise AttributeError(f"'{class_name}' has no attribute '{name}'")
144# Type alias for convenience
145Friendables: TypeAlias = FriendablesProtocol