Coverage for src/typedal/types.py: 100%

1"""

2 Stuff to make mypy happy.

3"""

4

5 import typing

6 from datetime import datetime

7 from typing import Any, Optional, TypedDict

8

9 from pydal.adapters.base import BaseAdapter

10 from pydal.helpers.classes import OpRow as _OpRow

11 from pydal.helpers.classes import Reference as _Reference

12 from pydal.objects import Expression as _Expression

13 from pydal.objects import Field as _Field

14 from pydal.objects import Query as _Query

15 from pydal.objects import Rows as _Rows

16 from pydal.objects import Set as _Set

17 from pydal.objects import Table as _Table

18 from pydal.validators import Validator as _Validator

19 from typing_extensions import NotRequired

20

21 if typing.TYPE_CHECKING:

22 from .core import TypedField

23

24 AnyDict: typing.TypeAlias = dict[str, Any]

25

26

27 class Query(_Query): # type: ignore

28 """

29 Pydal Query object.

30

31 Makes mypy happy.

32 """

33

34

35 class Expression(_Expression): # type: ignore

36 """

37 Pydal Expression object.

38

39 Make mypy happy.

40 """

41

42

43 class Set(_Set): # type: ignore

44 """

45 Pydal Set object.

46

47 Make mypy happy.

48 """

49

50

51 class OpRow(_OpRow): # type: ignore

52 """

53 Pydal OpRow object.

54

55 Make mypy happy.

56 """

57

58

59 class Reference(_Reference): # type: ignore

60 """

61 Pydal Reference object.

62

63 Make mypy happy.

64 """

65

66

67 class Field(_Field): # type: ignore

68 """

69 Pydal Field object.

70

71 Make mypy happy.

72 """

73

74

75 class Rows(_Rows): # type: ignore

76 """

77 Pydal Rows object.

78

79 Make mypy happy.

80 """

81

82

83 class Validator(_Validator): # type: ignore

84 """

85 Pydal Validator object.

86

87 Make mypy happy.

88 """

89

90

91 class _Types:

92 """

93 Internal type storage for stuff that mypy otherwise won't understand.

94 """

95

96 NONETYPE = type(None)

97

98

99 BeforeInsertCallable: typing.TypeAlias = typing.Callable[[OpRow], Any]

100 AfterInsertCallable: typing.TypeAlias = typing.Callable[[OpRow, Reference], Any]

101 BeforeUpdateCallable: typing.TypeAlias = typing.Callable[[Set, OpRow], Any]

102 AfterUpdateCallable: typing.TypeAlias = typing.Callable[[Set, OpRow], Any]

103 BeforeDeleteCallable: typing.TypeAlias = typing.Callable[[Set], Any]

104 AfterDeleteCallable: typing.TypeAlias = typing.Callable[[Set], Any]

105

106

107 class Pagination(TypedDict):

108 """

109 Pagination key of a paginate dict has these items.

110 """

111

112 total_items: int

113 current_page: int

114 per_page: int

115 total_pages: int

116 has_next_page: bool

117 has_prev_page: bool

118 next_page: Optional[int]

119 prev_page: Optional[int]

120

121

122 class PaginateDict(TypedDict):

123 """

124 Result of PaginatedRows.as_dict().

125 """

126

127 data: dict[int, AnyDict]

128 pagination: Pagination

129

130

131 class CacheMetadata(TypedDict):

132 """

133 Used by query builder metadata in the 'cache' key.

134 """

135

136 enabled: bool

137 depends_on: list[Any]

138 key: NotRequired[str | None]

139 status: NotRequired[str | None]

140 expires_at: NotRequired[datetime | None]

141 cached_at: NotRequired[datetime | None]

142

143

144 class PaginationMetadata(TypedDict):

145 """

146 Used by query builder metadata in the 'pagination' key.

147 """

148

149 limit: int

150 current_page: int

151 max_page: int

152 rows: int

153 min_max: tuple[int, int]

154

155

156 class TableProtocol(typing.Protocol): # pragma: no cover

157 """

158 Make mypy happy.

159 """

160

161 id: "TypedField[int]"

162

163 def __getitem__(self, item: str) -> Field:

164 """

165 Tell mypy a Table supports dictionary notation for columns.

166 """

167

168

169 class Table(_Table, TableProtocol): # type: ignore

170 """

171 Make mypy happy.

172 """

173

174

175 class CacheFn(typing.Protocol):

176 """

177 The cache model (e.g. cache.ram) accepts these parameters (all filled by dfeault).

178 """

179

180 def __call__(

181 self: BaseAdapter,

182 sql: str = "",

183 fields: typing.Iterable[str] = (),

184 attributes: typing.Iterable[str] = (),

185 colnames: typing.Iterable[str] = (),

186 ) -> Rows:

187 """

188 Only used for type-hinting.

189 """

190

191

192# CacheFn = typing.Callable[[], Rows]

193 CacheModel = typing.Callable[[str, CacheFn, int], Rows]

194 CacheTuple = tuple[CacheModel, int]

195

196

197 class SelectKwargs(typing.TypedDict, total=False):

198 """

199 Possible keyword arguments for .select().

200 """

201

202 join: Optional[list[Expression]]

203 left: Optional[list[Expression]]

204 orderby: Optional[Expression | str | Table]

205 limitby: Optional[tuple[int, int]]

206 distinct: bool | Field | Expression

207 orderby_on_limitby: bool

208 cacheable: bool

209 cache: CacheTuple

210

211

212 class Metadata(TypedDict):

213 """

214 Loosely structured metadata used by Query Builder.

215 """

216

217 cache: NotRequired[CacheMetadata]

218 pagination: NotRequired[PaginationMetadata]

219

220 query: NotRequired[Query | str | None]

221 ids: NotRequired[str]

222

223 final_query: NotRequired[Query | str | None]

224 final_args: NotRequired[list[Any]]

225 final_kwargs: NotRequired[SelectKwargs]

226 relationships: NotRequired[set[str]]

227

228 sql: NotRequired[str]