Coverage for yuio / ty.py: 100%

55 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-03 15:42 +0000

1# Yuio project, MIT license. 

2# 

3# https://github.com/taminomara/yuio/ 

4# 

5# You're free to copy this file to your project and edit it for your needs, 

6# just keep this copyright line please :3 

7 

8""" 

9Type annotations are unfortunately bulky. Yuio provides shortcuts for common annotated 

10types such as positive ints or non-empty containers. 

11 

12.. type:: PosInt 

13 :canonical: typing.Annotated[int, ~yuio.parse.Gt(0)] 

14 

15 Positive int. 

16 

17.. type:: NonNegInt 

18 :canonical: typing.Annotated[int, ~yuio.parse.Ge(0)] 

19 

20 Non-negative int. 

21 

22.. type:: PosFloat 

23 :canonical: typing.Annotated[float, ~yuio.parse.Gt(0)] 

24 

25 Positive float. 

26 

27.. type:: NonNegFloat 

28 :canonical: typing.Annotated[float, ~yuio.parse.Ge(0)] 

29 

30 Non-negative float. 

31 

32.. type:: NonEmptyStr 

33 :canonical: typing.Annotated[str, ~yuio.parse.LenGt(0)] 

34 

35 Non-empty string. 

36 

37.. type:: NonEmptyList 

38 :canonical: typing.Annotated[list[T], ~yuio.parse.LenGt(0)] 

39 

40 Non-empty list. 

41 

42.. type:: NonEmptySet 

43 :canonical: typing.Annotated[set[T], ~yuio.parse.LenGt(0)] 

44 

45 Non-empty set. 

46 

47.. type:: NonEmptyFrozenSet 

48 :canonical: typing.Annotated[frozenset[T], ~yuio.parse.LenGt(0)] 

49 

50 Non-empty frozenset. 

51 

52.. type:: NonEmptyDict 

53 :canonical: typing.Annotated[dict[K, V], ~yuio.parse.LenGt(0)] 

54 

55 Non-empty dict. 

56 

57.. type:: Path 

58 :canonical: pathlib.Path 

59 

60 Filepath. 

61 

62.. type:: NonExistentPath 

63 :canonical: typing.Annotated[Path, ~yuio.parse.NonExistentPath] 

64 

65 Filepath not pointing to an existing file or directory. 

66 

67.. type:: ExistingPath 

68 :canonical: typing.Annotated[Path, ~yuio.parse.ExistingPath] 

69 

70 Filepath pointing to an existing file or directory. 

71 

72.. type:: File 

73 :canonical: typing.Annotated[Path, ~yuio.parse.File] 

74 

75 Filepath pointing to an existing regular file. 

76 

77.. type:: Dir 

78 :canonical: typing.Annotated[Path, ~yuio.parse.Dir] 

79 

80 Filepath pointing to an existing directory. 

81 

82.. type:: GitRepo 

83 :canonical: typing.Annotated[Path, ~yuio.parse.GitRepo] 

84 

85 Filepath pointing to an existing directory that has ``.git`` sub-directory. 

86 

87.. type:: TimeDelta 

88 :canonical: ~datetime.timedelta 

89 

90 Time delta. 

91 

92.. type:: PosTimeDelta 

93 :canonical: typing.Annotated[TimeDelta, ~yuio.parse.Gt(~datetime.timedelta(0))] 

94 

95 Positive time delta. 

96 

97.. type:: NonNegTimeDelta 

98 :canonical: typing.Annotated[TimeDelta, ~yuio.parse.Ge(~datetime.timedelta(0))] 

99 

100 Non-negative time delta. 

101 

102.. type:: Seconds 

103 :canonical: typing.Annotated[~datetime.timedelta, ~yuio.parse.Seconds()] 

104 

105 Timedelta that's parsed from int as number of seconds. 

106 

107.. type:: PosSeconds 

108 :canonical: typing.Annotated[Seconds, ~yuio.parse.Gt(~datetime.timedelta(0))] 

109 

110 Positive number of seconds. 

111 

112.. type:: NonNegSeconds 

113 :canonical: typing.Annotated[Seconds, ~yuio.parse.Ge(~datetime.timedelta(0))] 

114 

115 Non-negative number of seconds. 

116 

117 

118Re-imports 

119---------- 

120 

121.. type:: JsonValue 

122 :no-index: 

123 

124 Alias of :obj:`yuio.json_schema.JsonValue`. 

125 

126.. type:: SecretString 

127 :no-index: 

128 

129 Alias of :obj:`yuio.secret.SecretString`. 

130 

131.. type:: SecretValue 

132 :no-index: 

133 

134 Alias of :obj:`yuio.secret.SecretValue`. 

135 

136""" 

137 

138from __future__ import annotations 

139 

140import datetime 

141import pathlib 

142 

143import yuio.parse 

144from yuio.json_schema import JsonValue 

145from yuio.secret import SecretString, SecretValue 

146 

147from typing import TYPE_CHECKING 

148 

149if TYPE_CHECKING: 

150 import typing_extensions as _t 

151else: 

152 from yuio import _typing as _t 

153 

154__all__ = [ 

155 "Dir", 

156 "ExistingPath", 

157 "File", 

158 "GitRepo", 

159 "JsonValue", 

160 "NonEmptyDict", 

161 "NonEmptyFrozenSet", 

162 "NonEmptyList", 

163 "NonEmptySet", 

164 "NonEmptyStr", 

165 "NonExistentPath", 

166 "NonNegFloat", 

167 "NonNegInt", 

168 "NonNegSeconds", 

169 "NonNegTimeDelta", 

170 "Path", 

171 "PosFloat", 

172 "PosInt", 

173 "PosSeconds", 

174 "PosTimeDelta", 

175 "Seconds", 

176 "SecretString", 

177 "SecretValue", 

178 "TimeDelta", 

179] 

180 

181 

182T = _t.TypeVar("T") 

183K = _t.TypeVar("K") 

184V = _t.TypeVar("V") 

185 

186 

187PosInt: _t.TypeAlias = _t.Annotated[int, yuio.parse.Gt(0)] 

188""" 

189Positive int. 

190 

191""" 

192 

193NonNegInt: _t.TypeAlias = _t.Annotated[int, yuio.parse.Ge(0)] 

194""" 

195Non-negative int. 

196 

197""" 

198 

199PosFloat: _t.TypeAlias = _t.Annotated[float, yuio.parse.Gt(0)] 

200""" 

201Positive float. 

202 

203""" 

204 

205NonNegFloat: _t.TypeAlias = _t.Annotated[float, yuio.parse.Ge(0)] 

206""" 

207Non-negative float. 

208 

209""" 

210 

211NonEmptyStr: _t.TypeAlias = _t.Annotated[str, yuio.parse.LenGt(0)] 

212""" 

213Non-empty string. 

214 

215""" 

216 

217NonEmptyList: _t.TypeAlias = _t.Annotated[list[T], yuio.parse.LenGt(0)] 

218""" 

219Non-empty list. 

220 

221""" 

222 

223NonEmptySet: _t.TypeAlias = _t.Annotated[set[T], yuio.parse.LenGt(0)] 

224""" 

225Non-empty set. 

226 

227""" 

228 

229NonEmptyFrozenSet: _t.TypeAlias = _t.Annotated[frozenset[T], yuio.parse.LenGt(0)] 

230""" 

231Non-empty frozenset. 

232 

233""" 

234 

235NonEmptyDict: _t.TypeAlias = _t.Annotated[dict[K, V], yuio.parse.LenGt(0)] 

236""" 

237Non-empty dict. 

238 

239""" 

240 

241Path: _t.TypeAlias = pathlib.Path 

242""" 

243Filepath. 

244 

245""" 

246 

247NonExistentPath: _t.TypeAlias = _t.Annotated[Path, yuio.parse.NonExistentPath] 

248""" 

249Filepath not pointing to an existing file or directory. 

250 

251""" 

252 

253ExistingPath: _t.TypeAlias = _t.Annotated[Path, yuio.parse.ExistingPath] 

254""" 

255Filepath pointing to an existing file or directory. 

256 

257""" 

258 

259File: _t.TypeAlias = _t.Annotated[Path, yuio.parse.File] 

260""" 

261Filepath pointing to an existing regular file. 

262 

263""" 

264 

265Dir: _t.TypeAlias = _t.Annotated[Path, yuio.parse.Dir] 

266""" 

267Filepath pointing to an existing directory. 

268 

269""" 

270 

271GitRepo: _t.TypeAlias = _t.Annotated[Path, yuio.parse.GitRepo] 

272""" 

273Filepath pointing to an existing directory that has ``.git`` sub-directory. 

274 

275""" 

276 

277TimeDelta: _t.TypeAlias = datetime.timedelta 

278""" 

279Time delta. 

280 

281""" 

282 

283_TD_ZERO = datetime.timedelta() 

284 

285PosTimeDelta: _t.TypeAlias = _t.Annotated[ 

286 TimeDelta, yuio.parse.Gt(_TD_ZERO), yuio.parse.WithMeta(desc="HH:MM:SS") 

287] 

288""" 

289Positive time delta. 

290 

291""" 

292 

293NonNegTimeDelta: _t.TypeAlias = _t.Annotated[ 

294 TimeDelta, yuio.parse.Ge(_TD_ZERO), yuio.parse.WithMeta(desc="HH:MM:SS") 

295] 

296""" 

297Non-negative time delta. 

298 

299""" 

300 

301Seconds: _t.TypeAlias = _t.Annotated[datetime.timedelta, yuio.parse.Seconds()] 

302""" 

303Timedelta that's parsed from int as number of seconds. 

304 

305""" 

306 

307PosSeconds: _t.TypeAlias = _t.Annotated[Seconds, yuio.parse.Gt(_TD_ZERO)] 

308""" 

309Positive number of seconds. 

310 

311""" 

312 

313NonNegSeconds: _t.TypeAlias = _t.Annotated[Seconds, yuio.parse.Ge(_TD_ZERO)] 

314""" 

315Non-negative number of seconds. 

316 

317"""