Coverage for src/typedal/types.py: 100%
76 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-08-05 19:10 +0200
« prev ^ index » next coverage.py v7.5.1, created at 2024-08-05 19:10 +0200
1"""
2Stuff to make mypy happy.
3"""
5import typing
6from datetime import datetime
7from typing import Any, Optional, TypedDict
9from pydal.adapters.base import BaseAdapter
10from pydal.helpers.classes import OpRow as _OpRow
11from pydal.helpers.classes import Reference as _Reference
12from pydal.objects import Expression as _Expression
13from pydal.objects import Field as _Field
14from pydal.objects import Query as _Query
15from pydal.objects import Rows as _Rows
16from pydal.objects import Set as _Set
17from pydal.objects import Table as _Table
18from pydal.validators import Validator as _Validator
19from typing_extensions import NotRequired
21if typing.TYPE_CHECKING:
22 from .core import TypedField
24AnyDict: typing.TypeAlias = dict[str, Any]
27class Query(_Query): # type: ignore
28 """
29 Pydal Query object.
31 Makes mypy happy.
32 """
35class Expression(_Expression): # type: ignore
36 """
37 Pydal Expression object.
39 Make mypy happy.
40 """
43class Set(_Set): # type: ignore
44 """
45 Pydal Set object.
47 Make mypy happy.
48 """
51if typing.TYPE_CHECKING:
53 class OpRow:
54 """
55 Pydal OpRow object for typing (otherwise mypy thinks it's Any).
57 Make mypy happy.
58 """
60 def __getitem__(self, item: str) -> typing.Any:
61 """
62 Dict [] get notation.
63 """
65 def __setitem__(self, key: str, value: typing.Any) -> None:
66 """
67 Dict [] set notation.
68 """
70 # ... and more methods
72else:
74 class OpRow(_OpRow): # type: ignore
75 """
76 Pydal OpRow object at runtime just uses pydal's version.
78 Make mypy happy.
79 """
82class Reference(_Reference): # type: ignore
83 """
84 Pydal Reference object.
86 Make mypy happy.
87 """
90class Field(_Field): # type: ignore
91 """
92 Pydal Field object.
94 Make mypy happy.
95 """
98class Rows(_Rows): # type: ignore
99 """
100 Pydal Rows object.
102 Make mypy happy.
103 """
105 def column(self, column: typing.Any = None) -> list[typing.Any]:
106 """
107 Get a list of all values in a specific column.
109 Example:
110 rows.column('name') -> ['Name 1', 'Name 2', ...]
111 """
112 return [r[str(column) if column else self.colnames[0]] for r in self]
115class Validator(_Validator): # type: ignore
116 """
117 Pydal Validator object.
119 Make mypy happy.
120 """
123class _Types:
124 """
125 Internal type storage for stuff that mypy otherwise won't understand.
126 """
128 NONETYPE = type(None)
131class Pagination(TypedDict):
132 """
133 Pagination key of a paginate dict has these items.
134 """
136 total_items: int
137 current_page: int
138 per_page: int
139 total_pages: int
140 has_next_page: bool
141 has_prev_page: bool
142 next_page: Optional[int]
143 prev_page: Optional[int]
146class PaginateDict(TypedDict):
147 """
148 Result of PaginatedRows.as_dict().
149 """
151 data: dict[int, AnyDict]
152 pagination: Pagination
155class CacheMetadata(TypedDict):
156 """
157 Used by query builder metadata in the 'cache' key.
158 """
160 enabled: bool
161 depends_on: list[Any]
162 key: NotRequired[str | None]
163 status: NotRequired[str | None]
164 expires_at: NotRequired[datetime | None]
165 cached_at: NotRequired[datetime | None]
168class PaginationMetadata(TypedDict):
169 """
170 Used by query builder metadata in the 'pagination' key.
171 """
173 limit: int
174 current_page: int
175 max_page: int
176 rows: int
177 min_max: tuple[int, int]
180class TableProtocol(typing.Protocol): # pragma: no cover
181 """
182 Make mypy happy.
183 """
185 id: "TypedField[int]"
187 def __getitem__(self, item: str) -> Field:
188 """
189 Tell mypy a Table supports dictionary notation for columns.
190 """
193class Table(_Table, TableProtocol): # type: ignore
194 """
195 Make mypy happy.
196 """
199class CacheFn(typing.Protocol):
200 """
201 The cache model (e.g. cache.ram) accepts these parameters (all filled by dfeault).
202 """
204 def __call__(
205 self: BaseAdapter,
206 sql: str = "",
207 fields: typing.Iterable[str] = (),
208 attributes: typing.Iterable[str] = (),
209 colnames: typing.Iterable[str] = (),
210 ) -> Rows:
211 """
212 Only used for type-hinting.
213 """
216# CacheFn = typing.Callable[[], Rows]
217CacheModel = typing.Callable[[str, CacheFn, int], Rows]
218CacheTuple = tuple[CacheModel, int]
221class SelectKwargs(typing.TypedDict, total=False):
222 """
223 Possible keyword arguments for .select().
224 """
226 join: Optional[list[Expression]]
227 left: Optional[list[Expression]]
228 orderby: Optional[Expression | str | Table]
229 limitby: Optional[tuple[int, int]]
230 distinct: bool | Field | Expression
231 orderby_on_limitby: bool
232 cacheable: bool
233 cache: CacheTuple
236class Metadata(TypedDict):
237 """
238 Loosely structured metadata used by Query Builder.
239 """
241 cache: NotRequired[CacheMetadata]
242 pagination: NotRequired[PaginationMetadata]
244 query: NotRequired[Query | str | None]
245 ids: NotRequired[str]
247 final_query: NotRequired[Query | str | None]
248 final_args: NotRequired[list[Any]]
249 final_kwargs: NotRequired[SelectKwargs]
250 relationships: NotRequired[set[str]]
252 sql: NotRequired[str]