structtype 0.6.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {structtype-0.6.0/src/structtype.egg-info → structtype-0.7.0}/PKG-INFO +1 -1
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/__init__.py +14 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/__init__.pyi +55 -67
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/_adapter.py +15 -14
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/_core.c +2771 -577
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/_inspect.py +32 -23
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/_json_schema.py +3 -1
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/_version.py +2 -2
- {structtype-0.6.0 → structtype-0.7.0/src/structtype.egg-info}/PKG-INFO +1 -1
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype.egg-info/SOURCES.txt +1 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_adapter.py +18 -11
- structtype-0.7.0/tests/test_annotations.py +1627 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_check.py +91 -5
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_constraints.py +220 -146
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_inspect.py +17 -23
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_json.py +61 -61
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_schema.py +20 -15
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_struct.py +3 -3
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_struct_meta.py +1 -1
- {structtype-0.6.0 → structtype-0.7.0}/tests/typecheck/fields.py +17 -8
- {structtype-0.6.0 → structtype-0.7.0}/.opencode/opencode.json +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/.opencode/plugins/graphify.js +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/AGENTS.md +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/LICENSE +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/MANIFEST.in +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/Makefile +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/README.md +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/pyproject.toml +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/setup.cfg +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/setup.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/_utils.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/atof.h +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/atof_consts.h +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/common.h +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/itoa.h +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/py.typed +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype/ryu.h +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype.egg-info/dependency_links.txt +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/src/structtype.egg-info/top_level.txt +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/__init__.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/conftest.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_JSONTestSuite.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_attrs.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_cpylint.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_free_threading.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_memory.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_msgspec.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_pydantic.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_raw.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_typecheck.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/test_utils.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/typecheck/api.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/typecheck/basic.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/typecheck/types.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/tests/utils.py +0 -0
- {structtype-0.6.0 → structtype-0.7.0}/uv.lock +0 -0
|
@@ -3,16 +3,23 @@ from ._core import ( # type: ignore
|
|
|
3
3
|
ALL_BUILTIN_TYPES,
|
|
4
4
|
NODEFAULT,
|
|
5
5
|
UNSET,
|
|
6
|
+
BytesValidator,
|
|
7
|
+
CollectionValidator,
|
|
6
8
|
DecodeError,
|
|
7
9
|
EncodeError,
|
|
8
10
|
Factory,
|
|
9
11
|
Field,
|
|
12
|
+
NumericValidator,
|
|
10
13
|
Raw,
|
|
14
|
+
Serializer,
|
|
11
15
|
Struct,
|
|
12
16
|
StructConfig,
|
|
13
17
|
StructMeta,
|
|
18
|
+
StrValidator,
|
|
19
|
+
TimezoneValidator,
|
|
14
20
|
UnsetType,
|
|
15
21
|
ValidationError,
|
|
22
|
+
Validator,
|
|
16
23
|
)
|
|
17
24
|
from ._inspect import FieldInfo, fields
|
|
18
25
|
from ._json_schema import json_schema, json_schema_components, json_schema_dump
|
|
@@ -22,18 +29,25 @@ __all__ = [
|
|
|
22
29
|
"ALL_BUILTIN_TYPES",
|
|
23
30
|
"NODEFAULT",
|
|
24
31
|
"UNSET",
|
|
32
|
+
"BytesValidator",
|
|
33
|
+
"CollectionValidator",
|
|
25
34
|
"DecodeError",
|
|
26
35
|
"EncodeError",
|
|
27
36
|
"Factory",
|
|
28
37
|
"Field",
|
|
29
38
|
"FieldInfo",
|
|
39
|
+
"NumericValidator",
|
|
30
40
|
"Raw",
|
|
41
|
+
"Serializer",
|
|
42
|
+
"StrValidator",
|
|
31
43
|
"Struct",
|
|
32
44
|
"StructAdapter",
|
|
33
45
|
"StructConfig",
|
|
34
46
|
"StructMeta",
|
|
47
|
+
"TimezoneValidator",
|
|
35
48
|
"UnsetType",
|
|
36
49
|
"ValidationError",
|
|
50
|
+
"Validator",
|
|
37
51
|
"__version__",
|
|
38
52
|
"fields",
|
|
39
53
|
"json_schema",
|
|
@@ -179,107 +179,95 @@ class Factory:
|
|
|
179
179
|
|
|
180
180
|
@final
|
|
181
181
|
class Field:
|
|
182
|
-
# Numeric:
|
|
183
|
-
@overload
|
|
184
182
|
def __init__(
|
|
185
183
|
self,
|
|
186
184
|
*,
|
|
187
|
-
gt: int | float | None = None,
|
|
188
|
-
lt: int | float | None = None,
|
|
189
|
-
multiple_of: int | float | None = None,
|
|
190
185
|
alias: str | None = None,
|
|
191
186
|
title: str | None = None,
|
|
192
187
|
description: str | None = None,
|
|
193
188
|
json_schema_extra: dict[str, Any] | None = None,
|
|
194
189
|
examples: list[Any] | None = None,
|
|
195
190
|
deprecated: bool | None = None,
|
|
196
|
-
dump: Callable[[Any], Any] | None = None,
|
|
197
|
-
validate: Callable[[Any], Any] | None = None,
|
|
198
191
|
) -> None: ...
|
|
199
|
-
|
|
192
|
+
alias: Final[str | None]
|
|
193
|
+
title: Final[str | None]
|
|
194
|
+
description: Final[str | None]
|
|
195
|
+
examples: Final[list[Any] | None]
|
|
196
|
+
deprecated: Final[bool | None]
|
|
197
|
+
json_schema_extra: Final[dict[str, Any] | None]
|
|
198
|
+
def __rich_repr__(self) -> list[tuple[str, Any]]: ...
|
|
199
|
+
|
|
200
|
+
@final
|
|
201
|
+
class Serializer:
|
|
200
202
|
def __init__(
|
|
201
203
|
self,
|
|
202
204
|
*,
|
|
203
|
-
|
|
204
|
-
le: int | float | None = None,
|
|
205
|
-
multiple_of: int | float | None = None,
|
|
206
|
-
alias: str | None = None,
|
|
207
|
-
title: str | None = None,
|
|
208
|
-
description: str | None = None,
|
|
209
|
-
json_schema_extra: dict[str, Any] | None = None,
|
|
210
|
-
examples: list[Any] | None = None,
|
|
211
|
-
deprecated: bool | None = None,
|
|
205
|
+
load: Callable[[Any], Any] | None = None,
|
|
212
206
|
dump: Callable[[Any], Any] | None = None,
|
|
213
|
-
validate: Callable[[Any], Any] | None = None,
|
|
214
207
|
) -> None: ...
|
|
215
|
-
|
|
208
|
+
load: Final[Callable[[Any], Any] | None]
|
|
209
|
+
dump: Final[Callable[[Any], Any] | None]
|
|
210
|
+
|
|
211
|
+
class Validator:
|
|
212
|
+
def __init__(self, fn: Callable[[Any], Any] | None = None) -> None: ...
|
|
213
|
+
def __call__(self, value: Any) -> None: ...
|
|
214
|
+
|
|
215
|
+
@final
|
|
216
|
+
class NumericValidator(Validator):
|
|
216
217
|
def __init__(
|
|
217
218
|
self,
|
|
218
219
|
*,
|
|
220
|
+
gt: int | float | None = None,
|
|
219
221
|
ge: int | float | None = None,
|
|
220
222
|
lt: int | float | None = None,
|
|
223
|
+
le: int | float | None = None,
|
|
221
224
|
multiple_of: int | float | None = None,
|
|
222
|
-
alias: str | None = None,
|
|
223
|
-
title: str | None = None,
|
|
224
|
-
description: str | None = None,
|
|
225
|
-
json_schema_extra: dict[str, Any] | None = None,
|
|
226
|
-
examples: list[Any] | None = None,
|
|
227
|
-
deprecated: bool | None = None,
|
|
228
|
-
dump: Callable[[Any], Any] | None = None,
|
|
229
|
-
validate: Callable[[Any], Any] | None = None,
|
|
230
225
|
) -> None: ...
|
|
231
|
-
|
|
226
|
+
gt: Final[int | float | None]
|
|
227
|
+
ge: Final[int | float | None]
|
|
228
|
+
lt: Final[int | float | None]
|
|
229
|
+
le: Final[int | float | None]
|
|
230
|
+
multiple_of: Final[int | float | None]
|
|
231
|
+
|
|
232
|
+
@final
|
|
233
|
+
class StrValidator(Validator):
|
|
232
234
|
def __init__(
|
|
233
235
|
self,
|
|
234
236
|
*,
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
alias: str | None = None,
|
|
239
|
-
title: str | None = None,
|
|
240
|
-
description: str | None = None,
|
|
241
|
-
json_schema_extra: dict[str, Any] | None = None,
|
|
242
|
-
examples: list[Any] | None = None,
|
|
243
|
-
deprecated: bool | None = None,
|
|
244
|
-
dump: Callable[[Any], Any] | None = None,
|
|
245
|
-
validate: Callable[[Any], Any] | None = None,
|
|
237
|
+
pattern: str | None = None,
|
|
238
|
+
min_length: _NonNegativeInt | None = None,
|
|
239
|
+
max_length: _NonNegativeInt | None = None,
|
|
246
240
|
) -> None: ...
|
|
247
|
-
|
|
248
|
-
|
|
241
|
+
pattern: Final[str | None]
|
|
242
|
+
min_length: Final[int | None]
|
|
243
|
+
max_length: Final[int | None]
|
|
244
|
+
|
|
245
|
+
@final
|
|
246
|
+
class BytesValidator(Validator):
|
|
249
247
|
def __init__(
|
|
250
248
|
self,
|
|
251
249
|
*,
|
|
252
|
-
pattern: str | None = None,
|
|
253
250
|
min_length: _NonNegativeInt | None = None,
|
|
254
251
|
max_length: _NonNegativeInt | None = None,
|
|
255
|
-
tz: bool | None = None,
|
|
256
|
-
alias: str | None = None,
|
|
257
|
-
title: str | None = None,
|
|
258
|
-
description: str | None = None,
|
|
259
|
-
json_schema_extra: dict[str, Any] | None = None,
|
|
260
|
-
examples: list[Any] | None = None,
|
|
261
|
-
deprecated: bool | None = None,
|
|
262
|
-
dump: Callable[[Any], Any] | None = None,
|
|
263
|
-
validate: Callable[[Any], Any] | None = None,
|
|
264
252
|
) -> None: ...
|
|
265
|
-
alias: Final[str | None]
|
|
266
|
-
gt: Final[int | float | None]
|
|
267
|
-
ge: Final[int | float | None]
|
|
268
|
-
lt: Final[int | float | None]
|
|
269
|
-
le: Final[int | float | None]
|
|
270
|
-
multiple_of: Final[int | float | None]
|
|
271
|
-
pattern: Final[str | None]
|
|
272
253
|
min_length: Final[int | None]
|
|
273
254
|
max_length: Final[int | None]
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
255
|
+
|
|
256
|
+
@final
|
|
257
|
+
class CollectionValidator(Validator):
|
|
258
|
+
def __init__(
|
|
259
|
+
self,
|
|
260
|
+
*,
|
|
261
|
+
min_length: _NonNegativeInt | None = None,
|
|
262
|
+
max_length: _NonNegativeInt | None = None,
|
|
263
|
+
) -> None: ...
|
|
264
|
+
min_length: Final[int | None]
|
|
265
|
+
max_length: Final[int | None]
|
|
266
|
+
|
|
267
|
+
@final
|
|
268
|
+
class TimezoneValidator(Validator):
|
|
269
|
+
def __init__(self, *, tz: bool) -> None: ...
|
|
270
|
+
tz: Final[bool]
|
|
283
271
|
|
|
284
272
|
class FieldInfo(Struct):
|
|
285
273
|
name: str
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from typing import Any, get_args
|
|
2
2
|
|
|
3
3
|
from ._core import ( # type: ignore
|
|
4
|
-
|
|
4
|
+
Serializer as _Serializer,
|
|
5
5
|
)
|
|
6
6
|
from ._core import ( # type: ignore
|
|
7
7
|
_dump,
|
|
@@ -11,22 +11,22 @@ from ._core import ( # type: ignore
|
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def
|
|
15
|
-
"""True if the annotation carries a ``
|
|
14
|
+
def _has_serializer(ann):
|
|
15
|
+
"""True if the annotation carries a ``Serializer`` with ``load``/``dump``."""
|
|
16
16
|
metadata = getattr(ann, "__metadata__", None)
|
|
17
17
|
if metadata is not None:
|
|
18
18
|
for meta in metadata:
|
|
19
|
-
if isinstance(meta,
|
|
20
|
-
meta.
|
|
19
|
+
if isinstance(meta, _Serializer) and (
|
|
20
|
+
meta.load is not None or meta.dump is not None
|
|
21
21
|
):
|
|
22
22
|
return True
|
|
23
23
|
supertype = getattr(ann, "__supertype__", None) # NewType
|
|
24
|
-
if supertype is not None and
|
|
24
|
+
if supertype is not None and _has_serializer(supertype):
|
|
25
25
|
return True
|
|
26
26
|
value = getattr(ann, "__value__", None) # PEP 695 type alias
|
|
27
|
-
if value is not None and
|
|
27
|
+
if value is not None and _has_serializer(value):
|
|
28
28
|
return True
|
|
29
|
-
return any(
|
|
29
|
+
return any(_has_serializer(arg) for arg in get_args(ann))
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
class StructAdapter:
|
|
@@ -35,8 +35,8 @@ class StructAdapter:
|
|
|
35
35
|
Useful when you want to validate or serialize plain Python types
|
|
36
36
|
(e.g. ``list[int]``) without defining a full ``Struct`` subclass.
|
|
37
37
|
|
|
38
|
-
``
|
|
39
|
-
``StructAdapter`` — annotations carrying one are rejected. Implement the
|
|
38
|
+
``Serializer(load=...)`` / ``Serializer(dump=...)`` codecs are not supported
|
|
39
|
+
on ``StructAdapter`` — annotations carrying one are rejected. Implement the
|
|
40
40
|
``struct_dump`` / ``struct_validate`` protocol methods on the custom type,
|
|
41
41
|
or use a ``Struct``.
|
|
42
42
|
|
|
@@ -49,11 +49,12 @@ class StructAdapter:
|
|
|
49
49
|
__slots__ = ("_type",)
|
|
50
50
|
|
|
51
51
|
def __init__(self, type: Any):
|
|
52
|
-
if
|
|
52
|
+
if _has_serializer(type):
|
|
53
53
|
raise TypeError(
|
|
54
|
-
"`
|
|
55
|
-
"on StructAdapter; define `struct_dump
|
|
56
|
-
"on the custom type, or use a
|
|
54
|
+
"`Serializer(load=...)`/`Serializer(dump=...)` codecs are not "
|
|
55
|
+
"supported on StructAdapter; define `struct_dump`/"
|
|
56
|
+
"`struct_validate` methods on the custom type, or use a "
|
|
57
|
+
"`Struct` instead"
|
|
57
58
|
)
|
|
58
59
|
self._type = type
|
|
59
60
|
|