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

80 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-05-22 20:36 +0200

1""" 

2Stuff to make mypy happy. 

3""" 

4 

5import typing 

6from datetime import datetime 

7from typing import Any, Optional, TypedDict 

8 

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 

20 

21if typing.TYPE_CHECKING: 

22 from .core import TypedField 

23 

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

25 

26 

27class Query(_Query): # type: ignore 

28 """ 

29 Pydal Query object. 

30 

31 Makes mypy happy. 

32 """ 

33 

34 

35class Expression(_Expression): # type: ignore 

36 """ 

37 Pydal Expression object. 

38 

39 Make mypy happy. 

40 """ 

41 

42 

43class Set(_Set): # type: ignore 

44 """ 

45 Pydal Set object. 

46 

47 Make mypy happy. 

48 """ 

49 

50 

51class OpRow(_OpRow): # type: ignore 

52 """ 

53 Pydal OpRow object. 

54 

55 Make mypy happy. 

56 """ 

57 

58 

59class Reference(_Reference): # type: ignore 

60 """ 

61 Pydal Reference object. 

62 

63 Make mypy happy. 

64 """ 

65 

66 

67class Field(_Field): # type: ignore 

68 """ 

69 Pydal Field object. 

70 

71 Make mypy happy. 

72 """ 

73 

74 

75class Rows(_Rows): # type: ignore 

76 """ 

77 Pydal Rows object. 

78 

79 Make mypy happy. 

80 """ 

81 

82 

83class Validator(_Validator): # type: ignore 

84 """ 

85 Pydal Validator object. 

86 

87 Make mypy happy. 

88 """ 

89 

90 

91class _Types: 

92 """ 

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

94 """ 

95 

96 NONETYPE = type(None) 

97 

98 

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

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

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

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

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

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

105 

106 

107class 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 

122class PaginateDict(TypedDict): 

123 """ 

124 Result of PaginatedRows.as_dict(). 

125 """ 

126 

127 data: dict[int, AnyDict] 

128 pagination: Pagination 

129 

130 

131class 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 

144class 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 

156class 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 

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

170 """ 

171 Make mypy happy. 

172 """ 

173 

174 

175class 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] 

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

194CacheTuple = tuple[CacheModel, int] 

195 

196 

197class 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 

212class 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]