vtjson 2.1.6__py3-none-any.whl → 2.1.8__py3-none-any.whl
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.
- vtjson/vtjson.py +1 -1
- {vtjson-2.1.6.dist-info → vtjson-2.1.8.dist-info}/METADATA +25 -22
- vtjson-2.1.8.dist-info/RECORD +9 -0
- vtjson-2.1.6.dist-info/RECORD +0 -9
- {vtjson-2.1.6.dist-info → vtjson-2.1.8.dist-info}/AUTHORS +0 -0
- {vtjson-2.1.6.dist-info → vtjson-2.1.8.dist-info}/LICENSE +0 -0
- {vtjson-2.1.6.dist-info → vtjson-2.1.8.dist-info}/WHEEL +0 -0
- {vtjson-2.1.6.dist-info → vtjson-2.1.8.dist-info}/top_level.txt +0 -0
vtjson/vtjson.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: vtjson
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.8
|
|
4
4
|
Summary: A lightweight package for validating JSON like Python objects
|
|
5
5
|
Author-email: Michel Van den Bergh <michel.vandenbergh@uhasselt.be>
|
|
6
6
|
Project-URL: Homepage, https://github.com/vdbergh/vtjson
|
|
@@ -24,14 +24,14 @@ A lightweight package for validating JSON like Python objects.
|
|
|
24
24
|
|
|
25
25
|
## Schemas
|
|
26
26
|
|
|
27
|
-
Validation of JSON like Python objects is done according to a `schema` which is somewhat inspired by a typescript type. The format of a schema is more or less self explanatory. As an [
|
|
27
|
+
Validation of JSON like Python objects is done according to a `schema` which is somewhat inspired by a typescript type. The format of a schema is more or less self explanatory. As an example one may consult the [schema of the run object](https://raw.githubusercontent.com/vdbergh/vtjson/refs/heads/main/docs/example1.md) in the mongodb database underlying the Fishtest web application <https://tests.stockfishchess.org/tests>.
|
|
28
28
|
|
|
29
29
|
The following conventions are used:
|
|
30
30
|
|
|
31
31
|
- As in typescript, a (string) key ending in `?` represents an optional key. The corresponding schema (the item the key points to) will only be used for validation when the key is present in the object that should be validated. A key can also be made optional by wrapping it as `optional_key(key)`.
|
|
32
32
|
- If in a list/tuple the last entry is `...` (ellipsis) it means that the next to last entry will be repeated zero or more times. In this way generic types can be created. For example the schema `[str, ...]` represents a list of strings.
|
|
33
33
|
|
|
34
|
-
As of version 2.1, a suitable adapted `vtjson` schema can be used as a Python type
|
|
34
|
+
As of version 2.1, a suitable adapted `vtjson` schema can be used as a Python type annotation. Here is the above example rewritten in a way that is [compatible with type annotations](https://raw.githubusercontent.com/vdbergh/vtjson/refs/heads/main/docs/example2.md). E.g. if one wants to ensure that a run object obtained via an api has the correct type one can do
|
|
35
35
|
|
|
36
36
|
```python
|
|
37
37
|
from typing import assert_type
|
|
@@ -160,7 +160,7 @@ A schema can be, in order of precedence:
|
|
|
160
160
|
```
|
|
161
161
|
|
|
162
162
|
where the optional argument `_deferred_compiles` is an opaque data structure used for handling recursive schemas. If appropriate, the function `_compile` internally invokes the method `schema.__compile__` and this should produce an instance of the class `compiled_schema`. The method `__compile__` may invoke the function `_compile` again. If this happens then the optional argument `_deferred_compiles` should be passed unmodified. Please consult the source code of `vtjson` for more details.
|
|
163
|
-
- A Python type
|
|
163
|
+
- A Python type annotation such as `list[str]`. This is discussed further below.
|
|
164
164
|
- A Python type. In that case validation is done by checking membership. By convention the schema `float` matches both ints and floats. Similarly the schema `complex` matches ints and floats besides of course complex numbers.
|
|
165
165
|
- A callable. Validation is done by applying the callable to the object. If applying the callable throws an exception then the corresponding message will be part of the non-validation message.
|
|
166
166
|
- An instance of `Sequence` that is not an instance of `str` (e.g a `list` or a `tuple`). Validation is done by first checking membership of the schema type, and then performing validation for each of the entries of the object being validated against the corresponding entries of the schema.
|
|
@@ -168,7 +168,7 @@ A schema can be, in order of precedence:
|
|
|
168
168
|
- A `set`. A set validates an object if the object is a set and the elements of the object are validated by an element of the schema.
|
|
169
169
|
- An arbitrary Python object. Validation is done by checking equality of the schema and the object, except when the schema is `float`, in which case `math.isclose` is used. Below we call such an object a `const schema`.
|
|
170
170
|
|
|
171
|
-
## Validating Mapping
|
|
171
|
+
## Validating against Mapping schemas
|
|
172
172
|
|
|
173
173
|
For a Mapping schema containing only `const keys` (i.e. keys corresponding to a `const schema`) the interpretation is obvious (see the introductory example above). Below we discuss the validation of an object against a Mapping schema in the general case.
|
|
174
174
|
|
|
@@ -182,25 +182,26 @@ For a Mapping schema containing only `const keys` (i.e. keys corresponding to a
|
|
|
182
182
|
|
|
183
183
|
A consequence of this algorithm is that non-const keys are automatically optional. So applying the wrapper `optional_key` to them is meaningless and has no effect.
|
|
184
184
|
|
|
185
|
-
## Type
|
|
185
|
+
## Type annotations integration
|
|
186
186
|
|
|
187
|
-
### Type
|
|
187
|
+
### Type annotations as schemas
|
|
188
188
|
|
|
189
|
-
`vtjson` recognizes the following type
|
|
189
|
+
`vtjson` recognizes the following type annotations as schemas.
|
|
190
190
|
|
|
191
191
|
```python
|
|
192
|
-
Annotated,
|
|
193
|
-
Protocol, NamedTuple, Literal, NewType, TypedDict,
|
|
192
|
+
Annotated, Mapping[...,...] and subtypes, Container[...] and subtypes,
|
|
193
|
+
tuple[...], Tuple[...], Protocol, NamedTuple, Literal, NewType, TypedDict,
|
|
194
|
+
Union (or the equivalent operator |), Any.
|
|
194
195
|
```
|
|
195
196
|
|
|
196
197
|
For example `dict[str, str]` is translated internally into the schema `{str: str}`. See below for more information.
|
|
197
198
|
|
|
198
199
|
### Annotated
|
|
199
200
|
|
|
200
|
-
- More general vtjson schemas can work along Python type
|
|
201
|
+
- More general vtjson schemas can work along Python type annotations by using the `typing.Annotated` contruct. The most naive way to do this is via
|
|
201
202
|
|
|
202
203
|
```python
|
|
203
|
-
Annotated[
|
|
204
|
+
Annotated[type_annotation, vtjson_schema, skip_first]
|
|
204
205
|
```
|
|
205
206
|
|
|
206
207
|
For example
|
|
@@ -209,8 +210,8 @@ For example `dict[str, str]` is translated internally into the schema `{str: str
|
|
|
209
210
|
Annotated[list[object], [int, str, float], skip_first]
|
|
210
211
|
```
|
|
211
212
|
|
|
212
|
-
A type checker such as `mypy` will only see the type
|
|
213
|
-
- In some use cases a vtjon_schema will meaningfully refine a Python type or type
|
|
213
|
+
A type checker such as `mypy` will only see the type annotation (`list[object]` in the example), whereas vtjson will only see the vtjson schema (`[int, str, float]` in the example). `skip_first` is a built-in short hand for `Apply(skip_first=True)` (see below) which directs vtjson to ignore the first argument of an `Annotated` schema.
|
|
214
|
+
- In some use cases a vtjon_schema will meaningfully refine a Python type or type annotation. In that case one should not use `skip_first`. For example:
|
|
214
215
|
|
|
215
216
|
```python
|
|
216
217
|
Annotated[datetime, fields({"tzinfo": timezone.utc})]
|
|
@@ -225,18 +226,18 @@ For example `dict[str, str]` is translated internally into the schema `{str: str
|
|
|
225
226
|
```
|
|
226
227
|
|
|
227
228
|
matches even integers.
|
|
228
|
-
- If one wants to pre-compile a schema and still use it as a type
|
|
229
|
+
- If one wants to pre-compile a schema and still use it as a type annotation (assuming it is valid as such) then one can do:
|
|
229
230
|
|
|
230
231
|
```python
|
|
231
232
|
schema = <schema definition>
|
|
232
233
|
Schema = Annotated[schema, compile(schema), skip_first]
|
|
233
234
|
```
|
|
234
235
|
|
|
235
|
-
### Supported type
|
|
236
|
+
### Supported type annotations
|
|
236
237
|
|
|
237
|
-
Note that Python imposes strong restrictions on what constitutes a valid type
|
|
238
|
+
Note that Python imposes strong restrictions on what constitutes a valid type annotation but `vtjson` is much more lax about this. Enforcing the restrictions is left to the type checkers or the Python interpreter.
|
|
238
239
|
|
|
239
|
-
- `TypedDict`. A TypedDict type
|
|
240
|
+
- `TypedDict`. A TypedDict type annotation is translated into a `dict` schema. E.g.
|
|
240
241
|
|
|
241
242
|
```python
|
|
242
243
|
class Movie(TypedDict):
|
|
@@ -270,16 +271,18 @@ Note that Python imposes strong restrictions on what constitutes a valid type hi
|
|
|
270
271
|
|
|
271
272
|
- `NewType` is translated into a `set_name` schema. E.g. `NewType('Movie', str)` becomes `set_name(str, 'Movie')`
|
|
272
273
|
|
|
273
|
-
- `dict[...]` and `Dict[...]` are translated into the equivalent `dict` schemas. E.g. `dict[str, str]` becomes `{str: str}`.
|
|
274
|
-
|
|
275
274
|
- `tuple[...]` and `Tuple[...]` are translated into the equivalent `tuple` schemas.
|
|
276
275
|
|
|
277
|
-
- `
|
|
276
|
+
- `Mapping[S, T]` and subtypes validate those objects that are members of the origin type (a subclass of `Mapping`) and whose (key, value) pairs match `(S, T)`.
|
|
277
|
+
|
|
278
|
+
- `Container[T]` and subtypes validate those objects that are members of the origin type (a subclass of `Container`) and whose elements match `T`.
|
|
278
279
|
|
|
279
280
|
- `Union` and the `|` operator are translated into `union`.
|
|
280
281
|
|
|
281
282
|
- `Literal` is also translated into `union`.
|
|
282
283
|
|
|
284
|
+
- `Any` is translated into `anything`.
|
|
285
|
+
|
|
283
286
|
### Apply objects
|
|
284
287
|
|
|
285
288
|
- If the list of arguments of an Annotated schema includes Apply objects then those modify the treatement of the arguments that come before them. We already encountered `skip_first` which is a built-in alias for `Apply(skip_first=True)`. The full signature of `Apply` is
|
|
@@ -306,7 +309,7 @@ Vtjson includes the command
|
|
|
306
309
|
safe_cast(schema, object)
|
|
307
310
|
```
|
|
308
311
|
|
|
309
|
-
(where `schema` should be a valid type
|
|
312
|
+
(where `schema` should be a valid type annotation) that functions exactly like `cast` except that it also verifies at run time that the given object matches the given schema.
|
|
310
313
|
|
|
311
314
|
## Creating types
|
|
312
315
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
vtjson/__init__.py,sha256=oLX4JH6_R7dYtTiGfBG3pQGR21IArspifdmZilbuGOw,68
|
|
2
|
+
vtjson/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
vtjson/vtjson.py,sha256=rpgDncJmLcr6yoU2Ibh2pyubJJIyWXgxxvAWuMNfy_s,69567
|
|
4
|
+
vtjson-2.1.8.dist-info/AUTHORS,sha256=qmxaXxaIO-YPNHJAZ0dcCrnPCs1x9ocbtMksiy4i80M,21
|
|
5
|
+
vtjson-2.1.8.dist-info/LICENSE,sha256=n7xW-zX8xBLHzCdqWIMRuMzBD_ACLcNCwio0LEkKt1o,1077
|
|
6
|
+
vtjson-2.1.8.dist-info/METADATA,sha256=ayfdkXUD6NbZ-7iOj9rbyI2WBfH7OW_URMug__SeleY,24323
|
|
7
|
+
vtjson-2.1.8.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
|
|
8
|
+
vtjson-2.1.8.dist-info/top_level.txt,sha256=9DlSF3l63igcvnYPcj117F2hzOW4Nx0N-JBoW3jjBZM,7
|
|
9
|
+
vtjson-2.1.8.dist-info/RECORD,,
|
vtjson-2.1.6.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
vtjson/__init__.py,sha256=oLX4JH6_R7dYtTiGfBG3pQGR21IArspifdmZilbuGOw,68
|
|
2
|
-
vtjson/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
vtjson/vtjson.py,sha256=UO58eUc0yShJ9Nm8zvhc3egHUzfLcLXdlj2TpKxtmYE,69567
|
|
4
|
-
vtjson-2.1.6.dist-info/AUTHORS,sha256=qmxaXxaIO-YPNHJAZ0dcCrnPCs1x9ocbtMksiy4i80M,21
|
|
5
|
-
vtjson-2.1.6.dist-info/LICENSE,sha256=n7xW-zX8xBLHzCdqWIMRuMzBD_ACLcNCwio0LEkKt1o,1077
|
|
6
|
-
vtjson-2.1.6.dist-info/METADATA,sha256=-PFoASAchEaDMOxJfx8icFTmVMxbfLFEkK9btIfWn28,24054
|
|
7
|
-
vtjson-2.1.6.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
|
|
8
|
-
vtjson-2.1.6.dist-info/top_level.txt,sha256=9DlSF3l63igcvnYPcj117F2hzOW4Nx0N-JBoW3jjBZM,7
|
|
9
|
-
vtjson-2.1.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|