Coverage for yuio / ty.py: 100%
57 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-29 19:55 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-29 19:55 +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
8"""
9Type annotations are unfortunately bulky. Yuio provides shortcuts for common annotated
10types such as positive ints or non-empty containers.
12.. type:: PosInt
13 :canonical: typing.Annotated[int, ~yuio.parse.Gt(0)]
15 Positive int.
17.. type:: NonNegInt
18 :canonical: typing.Annotated[int, ~yuio.parse.Ge(0)]
20 Non-negative int.
22.. type:: PosFloat
23 :canonical: typing.Annotated[float, ~yuio.parse.Gt(0)]
25 Positive float.
27.. type:: NonNegFloat
28 :canonical: typing.Annotated[float, ~yuio.parse.Ge(0)]
30 Non-negative float.
32.. type:: NonEmptyStr
33 :canonical: typing.Annotated[str, ~yuio.parse.LenGt(0)]
35 Non-empty string.
37.. type:: NonEmptyList
38 :canonical: typing.Annotated[list[T], ~yuio.parse.LenGt(0)]
40 Non-empty list.
42.. type:: NonEmptySet
43 :canonical: typing.Annotated[set[T], ~yuio.parse.LenGt(0)]
45 Non-empty set.
47.. type:: NonEmptyFrozenSet
48 :canonical: typing.Annotated[frozenset[T], ~yuio.parse.LenGt(0)]
50 Non-empty frozenset.
52.. type:: NonEmptyDict
53 :canonical: typing.Annotated[dict[K, V], ~yuio.parse.LenGt(0)]
55 Non-empty dict.
57.. type:: Pair
58 :canonical: typing.Annotated[tuple[K, V], ~yuio.parse.Tuple(delimiter=":")]
60 Colon-separated pair of values.
62.. type:: Path
63 :canonical: pathlib.Path
65 Filepath.
67.. type:: NonExistentPath
68 :canonical: typing.Annotated[Path, ~yuio.parse.NonExistentPath]
70 Filepath not pointing to an existing file or directory.
72.. type:: ExistingPath
73 :canonical: typing.Annotated[Path, ~yuio.parse.ExistingPath]
75 Filepath pointing to an existing file or directory.
77.. type:: File
78 :canonical: typing.Annotated[Path, ~yuio.parse.File]
80 Filepath pointing to an existing regular file.
82.. type:: Dir
83 :canonical: typing.Annotated[Path, ~yuio.parse.Dir]
85 Filepath pointing to an existing directory.
87.. type:: GitRepo
88 :canonical: typing.Annotated[Path, ~yuio.parse.GitRepo]
90 Filepath pointing to an existing directory that has ``.git`` sub-directory.
92.. type:: TimeDelta
93 :canonical: ~datetime.timedelta
95 Time delta.
97.. type:: PosTimeDelta
98 :canonical: typing.Annotated[TimeDelta, ~yuio.parse.Gt(~datetime.timedelta(0))]
100 Positive time delta.
102.. type:: NonNegTimeDelta
103 :canonical: typing.Annotated[TimeDelta, ~yuio.parse.Ge(~datetime.timedelta(0))]
105 Non-negative time delta.
107.. type:: Seconds
108 :canonical: typing.Annotated[~datetime.timedelta, ~yuio.parse.Seconds()]
110 Timedelta that's parsed from int as number of seconds.
112.. type:: PosSeconds
113 :canonical: typing.Annotated[Seconds, ~yuio.parse.Gt(~datetime.timedelta(0))]
115 Positive number of seconds.
117.. type:: NonNegSeconds
118 :canonical: typing.Annotated[Seconds, ~yuio.parse.Ge(~datetime.timedelta(0))]
120 Non-negative number of seconds.
123Re-imports
124----------
126.. type:: JsonValue
127 :no-index:
129 Alias of :obj:`yuio.json_schema.JsonValue`.
131.. type:: SecretString
132 :no-index:
134 Alias of :obj:`yuio.secret.SecretString`.
136.. type:: SecretValue
137 :no-index:
139 Alias of :obj:`yuio.secret.SecretValue`.
141"""
143from __future__ import annotations
145import datetime
146import pathlib
148import yuio.parse
149from yuio.json_schema import JsonValue
150from yuio.secret import SecretString, SecretValue
152from typing import TYPE_CHECKING
154if TYPE_CHECKING:
155 import typing_extensions as _t
156else:
157 from yuio import _typing as _t
159__all__ = [
160 "Dir",
161 "ExistingPath",
162 "File",
163 "GitRepo",
164 "JsonValue",
165 "NonEmptyDict",
166 "NonEmptyFrozenSet",
167 "NonEmptyList",
168 "NonEmptySet",
169 "NonEmptyStr",
170 "NonExistentPath",
171 "NonNegFloat",
172 "NonNegInt",
173 "NonNegSeconds",
174 "NonNegTimeDelta",
175 "Pair",
176 "Path",
177 "PosFloat",
178 "PosInt",
179 "PosSeconds",
180 "PosTimeDelta",
181 "Seconds",
182 "SecretString",
183 "SecretValue",
184 "TimeDelta",
185]
188T = _t.TypeVar("T")
189K = _t.TypeVar("K")
190V = _t.TypeVar("V")
193PosInt: _t.TypeAlias = _t.Annotated[int, yuio.parse.Gt(0)]
194"""
195Positive int.
197"""
199NonNegInt: _t.TypeAlias = _t.Annotated[int, yuio.parse.Ge(0)]
200"""
201Non-negative int.
203"""
205PosFloat: _t.TypeAlias = _t.Annotated[float, yuio.parse.Gt(0)]
206"""
207Positive float.
209"""
211NonNegFloat: _t.TypeAlias = _t.Annotated[float, yuio.parse.Ge(0)]
212"""
213Non-negative float.
215"""
217NonEmptyStr: _t.TypeAlias = _t.Annotated[str, yuio.parse.LenGt(0)]
218"""
219Non-empty string.
221"""
223NonEmptyList: _t.TypeAlias = _t.Annotated[list[T], yuio.parse.LenGt(0)]
224"""
225Non-empty list.
227"""
229NonEmptySet: _t.TypeAlias = _t.Annotated[set[T], yuio.parse.LenGt(0)]
230"""
231Non-empty set.
233"""
235NonEmptyFrozenSet: _t.TypeAlias = _t.Annotated[frozenset[T], yuio.parse.LenGt(0)]
236"""
237Non-empty frozenset.
239"""
241NonEmptyDict: _t.TypeAlias = _t.Annotated[dict[K, V], yuio.parse.LenGt(0)]
242"""
243Non-empty dict.
245"""
247Pair: _t.TypeAlias = _t.Annotated[tuple[K, V], yuio.parse.Tuple(delimiter=":")]
248"""
249Colon-separated pair of values.
251"""
253Path: _t.TypeAlias = pathlib.Path
254"""
255Filepath.
257"""
259NonExistentPath: _t.TypeAlias = _t.Annotated[Path, yuio.parse.NonExistentPath()]
260"""
261Filepath not pointing to an existing file or directory.
263"""
265ExistingPath: _t.TypeAlias = _t.Annotated[Path, yuio.parse.ExistingPath()]
266"""
267Filepath pointing to an existing file or directory.
269"""
271File: _t.TypeAlias = _t.Annotated[Path, yuio.parse.File()]
272"""
273Filepath pointing to an existing regular file.
275"""
277Dir: _t.TypeAlias = _t.Annotated[Path, yuio.parse.Dir()]
278"""
279Filepath pointing to an existing directory.
281"""
283GitRepo: _t.TypeAlias = _t.Annotated[Path, yuio.parse.GitRepo()]
284"""
285Filepath pointing to an existing directory that has ``.git`` sub-directory.
287"""
289TimeDelta: _t.TypeAlias = datetime.timedelta
290"""
291Time delta.
293"""
295_TD_ZERO = datetime.timedelta()
297PosTimeDelta: _t.TypeAlias = _t.Annotated[
298 TimeDelta, yuio.parse.Gt(_TD_ZERO), yuio.parse.WithMeta(desc="HH:MM:SS")
299]
300"""
301Positive time delta.
303"""
305NonNegTimeDelta: _t.TypeAlias = _t.Annotated[
306 TimeDelta, yuio.parse.Ge(_TD_ZERO), yuio.parse.WithMeta(desc="HH:MM:SS")
307]
308"""
309Non-negative time delta.
311"""
313Seconds: _t.TypeAlias = _t.Annotated[datetime.timedelta, yuio.parse.Seconds()]
314"""
315Timedelta that's parsed from int as number of seconds.
317"""
319PosSeconds: _t.TypeAlias = _t.Annotated[Seconds, yuio.parse.Gt(_TD_ZERO)]
320"""
321Positive number of seconds.
323"""
325NonNegSeconds: _t.TypeAlias = _t.Annotated[Seconds, yuio.parse.Ge(_TD_ZERO)]
326"""
327Non-negative number of seconds.
329"""