structtype 0.10.0__tar.gz → 0.12.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.10.0 → structtype-0.12.0}/AGENTS.md +11 -5
- {structtype-0.10.0 → structtype-0.12.0}/Makefile +42 -8
- {structtype-0.10.0/src/structtype.egg-info → structtype-0.12.0}/PKG-INFO +1 -1
- {structtype-0.10.0 → structtype-0.12.0}/pyproject.toml +4 -1
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/__init__.py +0 -2
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/__init__.pyi +1 -11
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/_adapter.py +53 -8
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/_core.c +839 -594
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/_inspect.py +18 -22
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/_json_schema.py +1 -2
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/_version.py +2 -2
- {structtype-0.10.0 → structtype-0.12.0/src/structtype.egg-info}/PKG-INFO +1 -1
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype.egg-info/SOURCES.txt +3 -1
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_adapter.py +42 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_annotations.py +1026 -42
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_attrs.py +37 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_check.py +0 -1
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_free_threading.py +38 -0
- structtype-0.12.0/tests/test_frozendict.py +93 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_inspect.py +0 -4
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_json.py +498 -72
- structtype-0.12.0/tests/test_memory.py +151 -0
- structtype-0.12.0/tests/test_roundtrip.py +220 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_schema.py +0 -4
- structtype-0.12.0/tests/test_threading.py +177 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/typecheck/types.py +1 -6
- {structtype-0.10.0 → structtype-0.12.0}/tests/utils.py +5 -0
- {structtype-0.10.0 → structtype-0.12.0}/uv.lock +3 -3
- structtype-0.10.0/tests/test_memory.py +0 -63
- structtype-0.10.0/tests/test_raw.py +0 -138
- {structtype-0.10.0 → structtype-0.12.0}/.opencode/opencode.json +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/.opencode/plugins/graphify.js +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/LICENSE +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/MANIFEST.in +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/README.md +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/setup.cfg +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/setup.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/_config.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/_utils.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/atof.h +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/atof_consts.h +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/common.h +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/itoa.h +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/py.typed +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype/ryu.h +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype.egg-info/dependency_links.txt +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/src/structtype.egg-info/top_level.txt +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/__init__.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/conftest.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_JSONTestSuite.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_constraints.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_cpylint.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_msgspec.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_pydantic.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_struct.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_struct_meta.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_typecheck.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/test_utils.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/typecheck/api.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/typecheck/basic.py +0 -0
- {structtype-0.10.0 → structtype-0.12.0}/tests/typecheck/fields.py +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
## Project
|
|
4
4
|
|
|
5
5
|
Fast struct validation + JSON serialization for Python.
|
|
6
|
-
Core is a monolithic C extension (`src/structtype/_core.c`, ~
|
|
6
|
+
Core is a monolithic C extension (`src/structtype/_core.c`, ~21K lines).
|
|
7
7
|
No runtime deps.
|
|
8
8
|
|
|
9
9
|
## Setup
|
|
@@ -14,7 +14,8 @@ uv sync --frozen
|
|
|
14
14
|
|
|
15
15
|
## Commands
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Use `make` targets where available. Targeted tests can be run directly with
|
|
18
|
+
`uv run` as shown below.
|
|
18
19
|
|
|
19
20
|
| Task | Command |
|
|
20
21
|
|---|---|
|
|
@@ -22,12 +23,13 @@ All commands go through `make`.
|
|
|
22
23
|
| Targeted tests | `uv run --reinstall pytest tests/test_json.py -k test_something` |
|
|
23
24
|
| Coverage (Python) | `make test-cov` |
|
|
24
25
|
| Coverage (Python + C) | `make test-cov-c` |
|
|
26
|
+
| Coverage (Python + C, all Pythons, merged) | `make test-cov-c-all` |
|
|
25
27
|
| Tests in all supported Pythons | `make test-all` |
|
|
26
28
|
| Build docs | `make docs` |
|
|
27
29
|
| Format | `make format` |
|
|
28
30
|
| Lint | `make ruff-check` |
|
|
29
31
|
| Type check | `make type-check` |
|
|
30
|
-
|
|
|
32
|
+
| Static checks | `make check` |
|
|
31
33
|
|
|
32
34
|
## Conventions
|
|
33
35
|
|
|
@@ -38,16 +40,17 @@ All commands go through `make`.
|
|
|
38
40
|
- Type stubs (`.pyi`) alongside public modules
|
|
39
41
|
- Sentinel values: `NODEFAULT`, `UNSET`, `_NoDefault`, `UnsetType`
|
|
40
42
|
- never do git commit
|
|
43
|
+
- check for performance regressions, speed is a goal
|
|
41
44
|
|
|
42
45
|
## Key API
|
|
43
46
|
|
|
44
47
|
- `structtype.Struct` — base class with config options (frozen, tag, rename, etc.)
|
|
45
48
|
- `structtype.Field` — field metadata (alias, title, description, examples, deprecated, json_schema_extra)
|
|
46
49
|
- `structtype.Constraint` — base constraint (callable `fn`); subclasses: `NumericConstraint`, `StrConstraint`, `BytesConstraint`, `CollectionConstraint`, `TimezoneConstraint`
|
|
47
|
-
- `structtype.Serializer` —
|
|
48
|
-
- `structtype.Raw` — lazy JSON passthrough
|
|
50
|
+
- `structtype.Serializer` — load/dump codecs for supported custom and native types
|
|
49
51
|
- `structtype.fields(type_or_instance)` — get FieldInfo tuple for a struct type/instance
|
|
50
52
|
- `structtype._inspect.type_info()` / `multi_type_info()` — type introspection
|
|
53
|
+
- `structtype.StructAdapter` — validate and serialize values against arbitrary types
|
|
51
54
|
|
|
52
55
|
### Struct Methods
|
|
53
56
|
|
|
@@ -67,7 +70,10 @@ Struct instances support the mapping protocol:
|
|
|
67
70
|
|
|
68
71
|
- `make test-cov` reinstalls the C extension before running. `make test-cov-c` builds an `-O0 --coverage` instrumented extension **in place**; afterwards any reinstalling target (`make test`, `make test-cov`) restores the optimized build.
|
|
69
72
|
- C coverage requires `lcov`/`genhtml`; report lands in `htmlcov-c/`.
|
|
73
|
+
- `make check` runs static type and Ruff checks only; it does not run tests,
|
|
74
|
+
documentation builds, or formatting.
|
|
70
75
|
- Validation matches keys by the **alias** name only, except `struct_validate(obj, from_attributes=True)` on a **non-dict object**, which matches by both the python field name and the alias. Dict/JSON input (even with `from_attributes=True`) and all dump/serialization use only the alias name.
|
|
76
|
+
- For `Annotated[MyType, Serializer(load=...)]`, an existing `MyType` instance bypasses `load`; other Python values and JSON representations are passed to `load`. Serializers remain rejected on `Any`, `bool`, `int`, `float`, `str`, `list`, `dict`, `tuple`, `TypedDict`, `NamedTuple`, `frozendict`, and `Literal`. `Serializer` and `Constraint` must attach to a concrete type inside `Annotated` — `Annotated[Union[A, B], ...]` and `Annotated[Optional[T], ...]` are rejected; use `Annotated[T, ...] | None` for optional fields.
|
|
71
77
|
|
|
72
78
|
## graphify
|
|
73
79
|
|
|
@@ -18,8 +18,8 @@ docs-serve: ## Open built docs in browser
|
|
|
18
18
|
uv run python -m webbrowser site/index.html
|
|
19
19
|
|
|
20
20
|
.PHONY: wheels
|
|
21
|
-
wheels: ## build wheels
|
|
22
|
-
uvx --from cibuildwheel==4.2.
|
|
21
|
+
wheels: ## build wheels (musllinux skipped; unset CIBW_SKIP or run cibuildwheel directly to include it)
|
|
22
|
+
CIBW_SKIP='*-musllinux_*' uvx --from cibuildwheel==4.2.1 cibuildwheel
|
|
23
23
|
|
|
24
24
|
##@ Quality
|
|
25
25
|
.PHONY: test-cov
|
|
@@ -30,11 +30,41 @@ test-cov: ## Run tests with coverage
|
|
|
30
30
|
test-cov-c: ## Run tests with Python + C coverage (lcov report in htmlcov-c/)
|
|
31
31
|
rm -rf build coverage-c.info coverage-c.info.* htmlcov-c
|
|
32
32
|
STRUCTTYPE_COVERAGE=1 uv run --with setuptools python setup.py build_ext --inplace --force
|
|
33
|
-
./.venv/bin/python -m pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=structtype
|
|
34
|
-
|
|
35
|
-
lcov --
|
|
36
|
-
lcov --
|
|
37
|
-
|
|
33
|
+
./.venv/bin/python -m pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=structtype \
|
|
34
|
+
--deselect tests/test_json.py::TestEncoderMisc::test_encode_infinite_recursive_object_errors
|
|
35
|
+
lcov --capture --directory build --output-file coverage-c.info --rc branch_coverage=1 --rc geninfo_unexecuted_blocks=1
|
|
36
|
+
lcov --extract coverage-c.info "*/src/structtype/*" --output-file coverage-c.info --rc branch_coverage=1
|
|
37
|
+
lcov --summary coverage-c.info --rc branch_coverage=1
|
|
38
|
+
genhtml coverage-c.info --output-directory htmlcov-c --branch-coverage >/dev/null
|
|
39
|
+
|
|
40
|
+
# C coverage is version-dependent: `_core.c` has many `#if PY30x_PLUS` and
|
|
41
|
+
# `#ifdef Py_GIL_DISABLED` regions, so a single build only covers part of the
|
|
42
|
+
# code. This target builds an instrumented extension for every supported
|
|
43
|
+
# Python, runs the suite under each, and merges the lcov data.
|
|
44
|
+
.PHONY: test-cov-c-all
|
|
45
|
+
test-cov-c-all: ## Run C coverage across all supported Pythons, merged (htmlcov-c/)
|
|
46
|
+
rm -rf build coverage-c.info coverage-c.info.* htmlcov-c
|
|
47
|
+
@set -e; \
|
|
48
|
+
for py in $(PY_VERSIONS); do \
|
|
49
|
+
tag=$$(echo "$$py" | tr -d '.'); \
|
|
50
|
+
venv=".venv-cov-$$tag"; \
|
|
51
|
+
echo "=== C coverage: $$py ($$venv) ==="; \
|
|
52
|
+
rm -rf build; \
|
|
53
|
+
env -u VIRTUAL_ENV UV_PROJECT_ENVIRONMENT="$$venv" STRUCTTYPE_COVERAGE=1 \
|
|
54
|
+
uv run -p "$$py" --with setuptools python setup.py build_ext --inplace --force; \
|
|
55
|
+
"$$venv/bin/python" -m pytest -q \
|
|
56
|
+
--deselect tests/test_json.py::TestEncoderMisc::test_encode_infinite_recursive_object_errors; \
|
|
57
|
+
lcov --capture --directory build --output-file "coverage-c.info.$$tag" \
|
|
58
|
+
--rc branch_coverage=1 --rc geninfo_unexecuted_blocks=1; \
|
|
59
|
+
lcov --extract "coverage-c.info.$$tag" "*/src/structtype/*" \
|
|
60
|
+
--output-file "coverage-c.info.$$tag" --rc branch_coverage=1; \
|
|
61
|
+
done; \
|
|
62
|
+
lcov $$(for f in coverage-c.info.*; do printf ' -a %s' "$$f"; done) \
|
|
63
|
+
--output-file coverage-c.info --rc branch_coverage=1; \
|
|
64
|
+
lcov --summary coverage-c.info --rc branch_coverage=1; \
|
|
65
|
+
genhtml coverage-c.info --output-directory htmlcov-c --branch-coverage >/dev/null; \
|
|
66
|
+
env -u VIRTUAL_ENV uv run --reinstall-package structtype python -c "import structtype" >/dev/null; \
|
|
67
|
+
echo "Merged C coverage written to htmlcov-c/. Re-run 'make test-all' to restore the other optimized builds."
|
|
38
68
|
|
|
39
69
|
.PHONY: test
|
|
40
70
|
test: ## Run tests in current Python
|
|
@@ -71,7 +101,7 @@ DEBUG_VENV = .venv-debug
|
|
|
71
101
|
.PHONY: test-debug
|
|
72
102
|
test-debug: ## Build core with Py_DEBUG + ASan/UBSan + debug allocator and run all tests
|
|
73
103
|
uv venv --clear --python $(DEBUG_PY) $(DEBUG_VENV)
|
|
74
|
-
STRUCTTYPE_SANITIZE=1 uv pip install --python $(DEBUG_VENV) --reinstall --no-cache --group dev
|
|
104
|
+
STRUCTTYPE_SANITIZE=1 uv pip install --python $(DEBUG_VENV) --reinstall --no-cache --group dev .
|
|
75
105
|
$(SANITIZE_PRELOAD) STRUCTTYPE_ASAN_RUNTIME=$(ASAN_RUNTIME) ASAN_OPTIONS=detect_leaks=0 \
|
|
76
106
|
PYTHONMALLOC=debug PYTHONFAULTHANDLER=1 PYTHONDEVMODE=1 \
|
|
77
107
|
$(DEBUG_VENV)/bin/python -m pytest
|
|
@@ -109,6 +139,10 @@ bench: ## run benchmarks
|
|
|
109
139
|
bench-validators: ## run Serializer/Validator benchmarks
|
|
110
140
|
uv run -p 3.15 benchmarks/bench_validators.py
|
|
111
141
|
|
|
142
|
+
.PHONY: bench-codecs
|
|
143
|
+
bench-codecs: ## run Constraint + Serializer heavy benchmarks
|
|
144
|
+
uv run -p 3.15 benchmarks/bench_codecs.py
|
|
145
|
+
|
|
112
146
|
##@ Utility
|
|
113
147
|
.PHONY: clean
|
|
114
148
|
clean: ## Delete all temporary files
|
|
@@ -69,12 +69,15 @@ editable_mode = "compat"
|
|
|
69
69
|
|
|
70
70
|
[tool.cibuildwheel]
|
|
71
71
|
build = "cp3*"
|
|
72
|
-
skip = ["pp*", "*-manylinux_i686", "*-
|
|
72
|
+
skip = ["pp*", "*-manylinux_i686", "*-win32"]
|
|
73
73
|
test-command = "pip install pytest>=9 && pytest {project}/tests"
|
|
74
74
|
|
|
75
75
|
[tool.ruff]
|
|
76
76
|
target-version = "py310"
|
|
77
77
|
|
|
78
|
+
[tool.ruff.lint.isort]
|
|
79
|
+
combine-as-imports = true
|
|
80
|
+
|
|
78
81
|
[tool.coverage.report]
|
|
79
82
|
exclude_lines = [
|
|
80
83
|
'pragma: no cover',
|
|
@@ -12,7 +12,6 @@ from ._core import ( # type: ignore
|
|
|
12
12
|
Factory,
|
|
13
13
|
Field,
|
|
14
14
|
NumericConstraint,
|
|
15
|
-
Raw,
|
|
16
15
|
Serializer,
|
|
17
16
|
StrConstraint,
|
|
18
17
|
Struct,
|
|
@@ -38,7 +37,6 @@ __all__ = [
|
|
|
38
37
|
"Field",
|
|
39
38
|
"FieldInfo",
|
|
40
39
|
"NumericConstraint",
|
|
41
|
-
"Raw",
|
|
42
40
|
"Serializer",
|
|
43
41
|
"StrConstraint",
|
|
44
42
|
"Struct",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ruff: noqa: PYI041, PYI015
|
|
1
|
+
# ruff: noqa: PYI041, PYI015
|
|
2
2
|
import enum
|
|
3
3
|
from collections.abc import Callable, Iterable, Iterator, Mapping
|
|
4
4
|
from inspect import Signature
|
|
@@ -109,16 +109,6 @@ class Struct(metaclass=StructMeta):
|
|
|
109
109
|
from_attributes: bool = False,
|
|
110
110
|
) -> Self: ...
|
|
111
111
|
|
|
112
|
-
# Lie and say `Raw` is a subclass of `bytes`, so mypy will accept it in most
|
|
113
|
-
# places where an object that implements the buffer protocol is valid
|
|
114
|
-
@final
|
|
115
|
-
class Raw(bytes):
|
|
116
|
-
@overload
|
|
117
|
-
def __new__(cls) -> "Raw": ...
|
|
118
|
-
@overload
|
|
119
|
-
def __new__(cls, msg: Buffer | str) -> "Raw": ...
|
|
120
|
-
def copy(self) -> "Raw": ...
|
|
121
|
-
|
|
122
112
|
#: We can't represent this in types, only via a name:
|
|
123
113
|
_NonNegativeInt: TypeAlias = int
|
|
124
114
|
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
+
import types
|
|
2
|
+
import typing
|
|
1
3
|
from typing import Any, get_args
|
|
2
4
|
|
|
3
|
-
from ._core import (
|
|
5
|
+
from ._core import ( # type: ignore
|
|
6
|
+
Constraint as _Constraint,
|
|
4
7
|
JSONDecoder as _JSONDecoder,
|
|
5
|
-
)
|
|
6
|
-
from ._core import (
|
|
7
8
|
Serializer as _Serializer,
|
|
8
|
-
)
|
|
9
|
-
from ._core import ( # type: ignore
|
|
10
9
|
_dump,
|
|
11
10
|
_json_encode,
|
|
12
11
|
_validate,
|
|
@@ -31,6 +30,38 @@ def _has_serializer(ann):
|
|
|
31
30
|
return any(_has_serializer(arg) for arg in get_args(ann))
|
|
32
31
|
|
|
33
32
|
|
|
33
|
+
def _is_union(t):
|
|
34
|
+
"""True if ``t`` is ``typing.Union`` or a ``types.UnionType`` (``X | Y``)."""
|
|
35
|
+
if getattr(t, "__origin__", None) is typing.Union:
|
|
36
|
+
return True
|
|
37
|
+
return isinstance(t, types.UnionType)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _has_constraint_on_union(ann):
|
|
41
|
+
"""True if a ``Constraint`` is attached to a union or optional type.
|
|
42
|
+
|
|
43
|
+
``Struct`` rejects this at class creation; ``StructAdapter`` mirrors the
|
|
44
|
+
same rule at construction. A concrete member may still be constrained and
|
|
45
|
+
then made optional, e.g. ``Annotated[T, Constraint(...)] | None``.
|
|
46
|
+
"""
|
|
47
|
+
metadata = getattr(ann, "__metadata__", None)
|
|
48
|
+
if metadata is not None:
|
|
49
|
+
origin = getattr(ann, "__origin__", None)
|
|
50
|
+
if (
|
|
51
|
+
origin is not None
|
|
52
|
+
and _is_union(origin)
|
|
53
|
+
and any(isinstance(meta, _Constraint) for meta in metadata)
|
|
54
|
+
):
|
|
55
|
+
return True
|
|
56
|
+
supertype = getattr(ann, "__supertype__", None) # NewType
|
|
57
|
+
if supertype is not None and _has_constraint_on_union(supertype):
|
|
58
|
+
return True
|
|
59
|
+
value = getattr(ann, "__value__", None) # PEP 695 type alias
|
|
60
|
+
if value is not None and _has_constraint_on_union(value):
|
|
61
|
+
return True
|
|
62
|
+
return any(_has_constraint_on_union(arg) for arg in get_args(ann))
|
|
63
|
+
|
|
64
|
+
|
|
34
65
|
class StructAdapter:
|
|
35
66
|
"""Adapter for validating and serializing types without subclassing ``Struct``.
|
|
36
67
|
|
|
@@ -42,6 +73,11 @@ class StructAdapter:
|
|
|
42
73
|
``struct_dump`` / ``struct_validate`` protocol methods on the custom type,
|
|
43
74
|
or use a ``Struct``.
|
|
44
75
|
|
|
76
|
+
``Constraint`` annotations are supported on concrete types. A ``Constraint``
|
|
77
|
+
attached to a union or optional type is rejected at construction, matching
|
|
78
|
+
``Struct`` class creation; make the field optional with
|
|
79
|
+
``Annotated[T, Constraint(...)] | None``.
|
|
80
|
+
|
|
45
81
|
>>> from structtype import StructAdapter
|
|
46
82
|
>>> adapter = StructAdapter(list[int])
|
|
47
83
|
>>> adapter.struct_validate_json(b"[1, 2, 3]")
|
|
@@ -58,6 +94,12 @@ class StructAdapter:
|
|
|
58
94
|
"`struct_validate` methods on the custom type, or use a "
|
|
59
95
|
"`Struct` instead"
|
|
60
96
|
)
|
|
97
|
+
if _has_constraint_on_union(type):
|
|
98
|
+
raise TypeError(
|
|
99
|
+
"`Constraint` must be applied to a concrete type, not a union "
|
|
100
|
+
"or optional type; use `Annotated[T, Constraint(...)] | None` "
|
|
101
|
+
"for optional fields"
|
|
102
|
+
)
|
|
61
103
|
self._type = type
|
|
62
104
|
self._decoder_loose = None
|
|
63
105
|
self._decoder_strict = None
|
|
@@ -70,7 +112,8 @@ class StructAdapter:
|
|
|
70
112
|
buf : str or bytes
|
|
71
113
|
The JSON message to decode.
|
|
72
114
|
strict : bool, optional
|
|
73
|
-
If True (default),
|
|
115
|
+
If True (default), use strict type validation and coercion rules.
|
|
116
|
+
If False, allow the documented lax-mode conversions.
|
|
74
117
|
"""
|
|
75
118
|
if strict:
|
|
76
119
|
decoder = self._decoder_strict
|
|
@@ -122,9 +165,11 @@ class StructAdapter:
|
|
|
122
165
|
obj : Any
|
|
123
166
|
A Python object to validate and convert.
|
|
124
167
|
strict : bool, optional
|
|
125
|
-
If True (default),
|
|
168
|
+
If True (default), use strict type validation and coercion rules.
|
|
169
|
+
If False, allow the documented lax-mode conversions.
|
|
126
170
|
from_attributes : bool, optional
|
|
127
|
-
If True, accept objects
|
|
171
|
+
If True, accept non-dict objects by reading matching attributes.
|
|
172
|
+
Dict input continues to match fields by serialized alias names.
|
|
128
173
|
"""
|
|
129
174
|
return _validate(
|
|
130
175
|
obj,
|