vtjson 2.2.2__py3-none-any.whl → 2.2.4__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 CHANGED
@@ -204,7 +204,7 @@ class SchemaError(Exception):
204
204
  pass
205
205
 
206
206
 
207
- __version__ = "2.2.2"
207
+ __version__ = "2.2.4"
208
208
 
209
209
 
210
210
  @dataclass
@@ -323,7 +323,7 @@ T = TypeVar("T")
323
323
 
324
324
 
325
325
  @overload
326
- def _canonize_key(key: str | optional_key[str]) -> optional_key[str]: ...
326
+ def _canonize_key(key: StringKeyType) -> optional_key[str]: ...
327
327
 
328
328
 
329
329
  @overload
@@ -445,6 +445,9 @@ class optional_key(Generic[K]):
445
445
  return hash(self.key)
446
446
 
447
447
 
448
+ StringKeyType = TypeVar("StringKeyType", bound=Union[str, optional_key[str]])
449
+
450
+
448
451
  class _union(compiled_schema):
449
452
  schemas: list[compiled_schema]
450
453
 
@@ -725,29 +728,29 @@ class set_label(wrapper):
725
728
  )
726
729
 
727
730
 
728
- class quote(compiled_schema):
731
+ class _quote(compiled_schema):
732
+
733
+ def __init__(self, schema: object) -> None:
734
+ setattr(self, "__validate__", _const(schema, strict_eq=True).__validate__)
735
+
736
+
737
+ class quote(wrapper):
729
738
  """
730
739
  An object matches the schema `quote(schema)` if it is equal to `schema`.
731
740
  For example the schema `str` matches strings but the schema `quote(str)`
732
741
  matches the object `str`.
733
742
  """
734
743
 
735
- schema: _const
744
+ schema: object
736
745
 
737
746
  def __init__(self, schema: object) -> None:
738
747
  """
739
748
  :param schema: the schema to be quoted
740
749
  """
741
- self.schema = _const(schema, strict_eq=True)
750
+ self.schema = schema
742
751
 
743
- def __validate__(
744
- self,
745
- obj: object,
746
- name: str = "object",
747
- strict: bool = True,
748
- subs: Mapping[str, object] = {},
749
- ) -> str:
750
- return self.schema.__validate__(obj, name=name, strict=strict, subs=subs)
752
+ def __compile__(self, _deferred_compiles: _mapping | None = None) -> _quote:
753
+ return _quote(self.schema)
751
754
 
752
755
 
753
756
  class _set_name(compiled_schema):
@@ -786,9 +789,8 @@ class _set_name(compiled_schema):
786
789
 
787
790
  class set_name(wrapper):
788
791
  """
789
- An object matches the schema `set_name(schema, name, reason=False)` if it
790
- matches `schema`, but the `name` argument will be used in non-validation
791
- messages.
792
+ An object matches the schema `set_name(schema, name)` if it matches `schema`,
793
+ but the `name` argument will be used in non-validation messages.
792
794
  """
793
795
 
794
796
  reason: bool
@@ -799,11 +801,15 @@ class set_name(wrapper):
799
801
  """
800
802
  :param schema: the original schema
801
803
  :param name: name for use in non-validation messages
802
- :param reason: indicates whether the original non-validation message
803
- should be suppressed
804
+ :param reason: if `True` then the original non-validation message
805
+ will not be suppressed
804
806
  """
805
807
  if not isinstance(name, str):
806
808
  raise SchemaError(f"The name {_c(name)} is not a string")
809
+ if not isinstance(reason, bool):
810
+ raise SchemaError(
811
+ f"The parameter 'reason' (value:{repr(reason)}) is not a boolean"
812
+ )
807
813
  self.schema = schema
808
814
  self.name = name
809
815
  self.reason = reason
@@ -1493,7 +1499,9 @@ def _compile(
1493
1499
  origin = object()
1494
1500
 
1495
1501
  ret: compiled_schema
1496
- if isinstance(schema, type) and issubclass(schema, compiled_schema):
1502
+ if isinstance(schema, compiled_schema):
1503
+ ret = schema
1504
+ elif isinstance(schema, type) and issubclass(schema, compiled_schema):
1497
1505
  try:
1498
1506
  ret = schema()
1499
1507
  except Exception:
@@ -1504,8 +1512,6 @@ def _compile(
1504
1512
  ret = _validate_schema(schema)
1505
1513
  elif isinstance(schema, wrapper):
1506
1514
  ret = schema.__compile__(_deferred_compiles=_deferred_compiles)
1507
- elif isinstance(schema, compiled_schema):
1508
- ret = schema
1509
1515
  elif supports_TypedDict and typing.is_typeddict(schema):
1510
1516
  ret = _compile(
1511
1517
  protocol(schema, dict=True), _deferred_compiles=_deferred_compiles
@@ -2037,7 +2043,7 @@ class one_of(compiled_schema):
2037
2043
  class keys(compiled_schema):
2038
2044
  """
2039
2045
  This represents a dictionary containing all the keys in a collection of
2040
- keys
2046
+ keys.
2041
2047
  """
2042
2048
 
2043
2049
  args: tuple[object, ...]
@@ -2199,12 +2205,13 @@ class _fields(compiled_schema):
2199
2205
 
2200
2206
  def __init__(
2201
2207
  self,
2202
- d: Mapping[optional_key[str], object],
2208
+ d: Mapping[StringKeyType, object],
2203
2209
  _deferred_compiles: _mapping | None = None,
2204
2210
  ) -> None:
2205
2211
  self.d = {}
2206
2212
  for k, v in d.items():
2207
- self.d[k] = _compile(v, _deferred_compiles=_deferred_compiles)
2213
+ key_ = _canonize_key(k)
2214
+ self.d[key_] = _compile(v, _deferred_compiles=_deferred_compiles)
2208
2215
 
2209
2216
  def __validate__(
2210
2217
  self,
@@ -2234,23 +2241,22 @@ class _fields(compiled_schema):
2234
2241
  return ""
2235
2242
 
2236
2243
 
2237
- class fields(wrapper):
2244
+ class fields(wrapper, Generic[StringKeyType]):
2238
2245
  """
2239
2246
  Matches Python objects with attributes `field1, field2, ..., fieldN` whose
2240
2247
  corresponding values should validate against `schema1, schema2, ...,
2241
- schemaN` respectively
2248
+ schemaN` respectively.
2242
2249
  """
2243
2250
 
2244
- d: dict[optional_key[str], object]
2251
+ d: Mapping[StringKeyType, object]
2245
2252
 
2246
- def __init__(self, d: Mapping[str | optional_key[str], object]) -> None:
2253
+ def __init__(self, d: Mapping[StringKeyType, object]) -> None:
2247
2254
  """
2248
2255
  :param d: a dictionary associating fields with schemas
2249
2256
 
2250
2257
  :raises SchemaError: exception thrown when the schema definition is
2251
2258
  found to contain an error
2252
2259
  """
2253
- self.d = {}
2254
2260
  if not isinstance(d, Mapping):
2255
2261
  raise SchemaError(f"{repr(d)} is not a Mapping")
2256
2262
  for k, v in d.items():
@@ -2259,8 +2265,7 @@ class fields(wrapper):
2259
2265
  f"key {repr(k)} in {repr(d)} is not an instance of"
2260
2266
  " optional_key and not a string"
2261
2267
  )
2262
- key_ = _canonize_key(k)
2263
- self.d[key_] = v
2268
+ self.d = d
2264
2269
 
2265
2270
  def __compile__(self, _deferred_compiles: _mapping | None = None) -> _fields:
2266
2271
  return _fields(self.d, _deferred_compiles=_deferred_compiles)
@@ -2682,6 +2687,48 @@ class _set(compiled_schema):
2682
2687
  return str(self.schema_)
2683
2688
 
2684
2689
 
2690
+ class _protocol(compiled_schema):
2691
+
2692
+ def __init__(
2693
+ self,
2694
+ schema: object,
2695
+ dict: bool = False,
2696
+ _deferred_compiles: _mapping | None = None,
2697
+ ) -> None:
2698
+ type_hints = _get_type_hints(schema)
2699
+ total = True
2700
+ if hasattr(schema, "__total__") and isinstance(schema.__total__, bool):
2701
+ total = schema.__total__
2702
+ type_dict = _to_dict(type_hints, total=total)
2703
+ if hasattr(schema, "__name__") and isinstance(schema.__name__, str):
2704
+ name = schema.__name__
2705
+ else:
2706
+ name = "schema"
2707
+
2708
+ if not dict:
2709
+ setattr(
2710
+ self,
2711
+ "__validate__",
2712
+ _set_name(
2713
+ fields(type_dict),
2714
+ name,
2715
+ reason=True,
2716
+ _deferred_compiles=_deferred_compiles,
2717
+ ).__validate__,
2718
+ )
2719
+ else:
2720
+ setattr(
2721
+ self,
2722
+ "__validate__",
2723
+ _set_name(
2724
+ type_dict,
2725
+ name,
2726
+ reason=True,
2727
+ _deferred_compiles=_deferred_compiles,
2728
+ ).__validate__,
2729
+ )
2730
+
2731
+
2685
2732
  class protocol(wrapper):
2686
2733
  """
2687
2734
  An object matches the schema `protocol(schema, dict=False)` if `schema` is
@@ -2689,9 +2736,8 @@ class protocol(wrapper):
2689
2736
  which validate the corresponding fields in the object.
2690
2737
  """
2691
2738
 
2692
- type_dict: dict[optional_key[str], object]
2739
+ schema: object
2693
2740
  dict: bool
2694
- __name__: str
2695
2741
 
2696
2742
  def __init__(self, schema: object, dict: bool = False):
2697
2743
  """
@@ -2704,34 +2750,14 @@ class protocol(wrapper):
2704
2750
  """
2705
2751
  if not isinstance(dict, bool):
2706
2752
  raise SchemaError("bool flag is not a bool")
2707
- type_hints = _get_type_hints(schema)
2753
+
2708
2754
  self.dict = dict
2709
- total = True
2710
- if hasattr(schema, "__total__") and isinstance(schema.__total__, bool):
2711
- total = schema.__total__
2712
- self.type_dict = _to_dict(type_hints, total=total)
2713
- if hasattr(schema, "__name__") and isinstance(schema.__name__, str):
2714
- self.__name__ = schema.__name__
2715
- else:
2716
- self.__name__ = "schema"
2755
+ self.schema = schema
2717
2756
 
2718
2757
  def __compile__(
2719
2758
  self, _deferred_compiles: _mapping | None = None
2720
2759
  ) -> compiled_schema:
2721
- if not self.dict:
2722
- return _set_name(
2723
- _fields(self.type_dict),
2724
- self.__name__,
2725
- reason=True,
2726
- _deferred_compiles=_deferred_compiles,
2727
- )
2728
- else:
2729
- return _set_name(
2730
- dict(self.type_dict),
2731
- self.__name__,
2732
- reason=True,
2733
- _deferred_compiles=_deferred_compiles,
2734
- )
2760
+ return _protocol(self.schema, self.dict)
2735
2761
 
2736
2762
 
2737
2763
  class _Literal(compiled_schema):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vtjson
3
- Version: 2.2.2
3
+ Version: 2.2.4
4
4
  Summary: An easy to use validation library compatible with Python type annotations
5
5
  Author-email: Michel Van den Bergh <michel.vandenbergh@uhasselt.be>
6
6
  Project-URL: Homepage, https://github.com/vdbergh/vtjson
@@ -78,7 +78,7 @@ class book_schema(TypedDict):
78
78
  year: int
79
79
  ```
80
80
 
81
- Attempting to validate the bad book would raise the same exception as before.
81
+ Attempting to validate the bad book would raise a similar exception as before.
82
82
 
83
83
  Schemas can of course be more complicated and in particular they can be nested.
84
84
  Here is an example that shows more of the features of `vtjson`.
@@ -126,7 +126,7 @@ class person_schema(TypedDict):
126
126
  class book_schema(TypedDict):
127
127
  title: str
128
128
  authors: list[person_schema]
129
- editor: NotRequired[list[person_schema]]
129
+ editor: NotRequired[person_schema]
130
130
  year: Annotated[int, ge(1900)]
131
131
  ```
132
132
 
@@ -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=-9xIldrpAY6Pf2PDtP9C5d81qb_9cRe4caxZ_Mk9Lj8,86872
4
+ vtjson-2.2.4.dist-info/AUTHORS,sha256=qmxaXxaIO-YPNHJAZ0dcCrnPCs1x9ocbtMksiy4i80M,21
5
+ vtjson-2.2.4.dist-info/LICENSE,sha256=n7xW-zX8xBLHzCdqWIMRuMzBD_ACLcNCwio0LEkKt1o,1077
6
+ vtjson-2.2.4.dist-info/METADATA,sha256=6xmw9KzIW_gMfBAcRJXJlGDfIjv1UxhPJBgmDxCX5Z4,3958
7
+ vtjson-2.2.4.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
8
+ vtjson-2.2.4.dist-info/top_level.txt,sha256=9DlSF3l63igcvnYPcj117F2hzOW4Nx0N-JBoW3jjBZM,7
9
+ vtjson-2.2.4.dist-info/RECORD,,
@@ -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=_NcOEWxuqZiVJQSn0ZoI9eGxL5GsbtacWIb-BwTPzTY,86274
4
- vtjson-2.2.2.dist-info/AUTHORS,sha256=qmxaXxaIO-YPNHJAZ0dcCrnPCs1x9ocbtMksiy4i80M,21
5
- vtjson-2.2.2.dist-info/LICENSE,sha256=n7xW-zX8xBLHzCdqWIMRuMzBD_ACLcNCwio0LEkKt1o,1077
6
- vtjson-2.2.2.dist-info/METADATA,sha256=reeTR8tvW1KdngstUC6dTdOas_8NXHqdRroKLH_eUfU,3963
7
- vtjson-2.2.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
8
- vtjson-2.2.2.dist-info/top_level.txt,sha256=9DlSF3l63igcvnYPcj117F2hzOW4Nx0N-JBoW3jjBZM,7
9
- vtjson-2.2.2.dist-info/RECORD,,
File without changes