localstack-py-avro-schema 3.9.2__py3-none-any.whl → 3.9.3__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.
- {localstack_py_avro_schema-3.9.2.dist-info → localstack_py_avro_schema-3.9.3.dist-info}/METADATA +1 -1
- {localstack_py_avro_schema-3.9.2.dist-info → localstack_py_avro_schema-3.9.3.dist-info}/RECORD +7 -7
- py_avro_schema/_schemas.py +58 -21
- {localstack_py_avro_schema-3.9.2.dist-info → localstack_py_avro_schema-3.9.3.dist-info}/WHEEL +0 -0
- {localstack_py_avro_schema-3.9.2.dist-info → localstack_py_avro_schema-3.9.3.dist-info}/licenses/LICENSE +0 -0
- {localstack_py_avro_schema-3.9.2.dist-info → localstack_py_avro_schema-3.9.3.dist-info}/licenses/LICENSE_HEADER.txt +0 -0
- {localstack_py_avro_schema-3.9.2.dist-info → localstack_py_avro_schema-3.9.3.dist-info}/top_level.txt +0 -0
{localstack_py_avro_schema-3.9.2.dist-info → localstack_py_avro_schema-3.9.3.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: localstack-py-avro-schema
|
|
3
|
-
Version: 3.9.
|
|
3
|
+
Version: 3.9.3
|
|
4
4
|
Summary: Generate Apache Avro schemas for Python types including standard library data-classes and Pydantic data models.
|
|
5
5
|
Author-email: LocalStack Contributors <info@localstack.cloud>, "J.P. Morgan Chase & Co." <open_source@jpmorgan.com>
|
|
6
6
|
License: Apache License
|
{localstack_py_avro_schema-3.9.2.dist-info → localstack_py_avro_schema-3.9.3.dist-info}/RECORD
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
localstack_py_avro_schema-3.9.
|
|
2
|
-
localstack_py_avro_schema-3.9.
|
|
1
|
+
localstack_py_avro_schema-3.9.3.dist-info/licenses/LICENSE,sha256=zE1N4JILDTkSIDtdmqdnKKxKEQh_VdqeoAV2230eNOI,10141
|
|
2
|
+
localstack_py_avro_schema-3.9.3.dist-info/licenses/LICENSE_HEADER.txt,sha256=Nx3RGmYbJKjIKM8Y2yMrCPJgCw4oBt_H62PxDKlAsto,564
|
|
3
3
|
py_avro_schema/__init__.py,sha256=bK6hTw4XJy5bAP4lgIvJR5LHtEiyUWq4GNJ5w-uSEpc,2414
|
|
4
4
|
py_avro_schema/_alias.py,sha256=nCQqtn7IbpjV0ibpJf9aMX9FvwVx2EDC1iKzwjQ7CqI,3412
|
|
5
|
-
py_avro_schema/_schemas.py,sha256=
|
|
5
|
+
py_avro_schema/_schemas.py,sha256=uUyztznCjmIescXDWEFetwAgBZ0mAIdGHpdea1EEY9k,48182
|
|
6
6
|
py_avro_schema/_testing.py,sha256=3aSfMbNDDeatl3H7GEUcynxK81HFiF-WCLOZ3FCCLiw,2261
|
|
7
7
|
py_avro_schema/_typing.py,sha256=9kBlPA7C33zZP3nRhCvSJA_0m54uvUo0AQ4wJJmSxMk,3291
|
|
8
8
|
py_avro_schema/py.typed,sha256=HnEDkaznpgfRW07Qfogy4tFLu_4dcQ5YcOsI7pmU5rQ,52
|
|
9
|
-
localstack_py_avro_schema-3.9.
|
|
10
|
-
localstack_py_avro_schema-3.9.
|
|
11
|
-
localstack_py_avro_schema-3.9.
|
|
12
|
-
localstack_py_avro_schema-3.9.
|
|
9
|
+
localstack_py_avro_schema-3.9.3.dist-info/METADATA,sha256=hykDGJcbbKVESlOoQ3zQFWlSQ8KAv9JA18_y_AIhv6o,15164
|
|
10
|
+
localstack_py_avro_schema-3.9.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
11
|
+
localstack_py_avro_schema-3.9.3.dist-info/top_level.txt,sha256=0t4oO_5rsdfZGSk8iSzK4TjdyfVz-RE1IZ2TIz6YvI0,15
|
|
12
|
+
localstack_py_avro_schema-3.9.3.dist-info/RECORD,,
|
py_avro_schema/_schemas.py
CHANGED
|
@@ -45,9 +45,11 @@ from typing import (
|
|
|
45
45
|
get_type_hints,
|
|
46
46
|
)
|
|
47
47
|
|
|
48
|
+
import avro.name
|
|
48
49
|
import more_itertools
|
|
49
50
|
import orjson
|
|
50
51
|
import typeguard
|
|
52
|
+
from avro.errors import InvalidName
|
|
51
53
|
|
|
52
54
|
import py_avro_schema._typing
|
|
53
55
|
from py_avro_schema._alias import get_aliases, get_field_aliases_and_actual_type
|
|
@@ -843,19 +845,33 @@ class EnumSchema(NamedSchema):
|
|
|
843
845
|
if symbol_types != {str}:
|
|
844
846
|
raise TypeError(f"Avro enum schema members must be strings. {py_type} uses {symbol_types} values.")
|
|
845
847
|
|
|
848
|
+
def _is_valid_enum(self) -> bool:
|
|
849
|
+
"""Checks if all the symbols of the enum are valid Avro names."""
|
|
850
|
+
try:
|
|
851
|
+
for _symbol in self.symbols:
|
|
852
|
+
avro.name.validate_basename(_symbol)
|
|
853
|
+
except InvalidName:
|
|
854
|
+
return False
|
|
855
|
+
return True
|
|
856
|
+
|
|
846
857
|
def data_before_deduplication(self, names: NamesType) -> JSONObj:
|
|
847
858
|
"""Return the schema data"""
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
"
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
+
if not self._is_valid_enum():
|
|
860
|
+
# Special case for StrEnum might contain invalid avro names. We just use a StrSubclassSchema schema instead.
|
|
861
|
+
enum_schema = {"type": "string", "namedString": self.name}
|
|
862
|
+
else:
|
|
863
|
+
enum_schema = {
|
|
864
|
+
"type": "enum",
|
|
865
|
+
"name": self.name,
|
|
866
|
+
"symbols": self.symbols,
|
|
867
|
+
# This is the default for the enum, not the default value for a record field using the enum type!
|
|
868
|
+
# See Avro schema specification for use. For now, we force the default value to be the first symbol.
|
|
869
|
+
# This means that if the writer schema has an additional member that the reader schema does NOT have,
|
|
870
|
+
# the reader will simply and silently assume the default specified here.
|
|
871
|
+
# Now that may not always be what we want, but standard lib Python enums don't really have a way
|
|
872
|
+
# to specify this.
|
|
873
|
+
"default": self.symbols[0],
|
|
874
|
+
}
|
|
859
875
|
if self.namespace is not None:
|
|
860
876
|
enum_schema["namespace"] = self.namespace
|
|
861
877
|
fqn = f"{self.namespace}.{self.name}"
|
|
@@ -1064,7 +1080,15 @@ class PydanticSchema(RecordSchema):
|
|
|
1064
1080
|
|
|
1065
1081
|
@register_schema
|
|
1066
1082
|
class PlainClassSchema(RecordSchema):
|
|
1067
|
-
"""
|
|
1083
|
+
"""
|
|
1084
|
+
An Avro record schema for a plain Python class with type annotations, e.g.,
|
|
1085
|
+
::
|
|
1086
|
+
class MyClass:
|
|
1087
|
+
var: str
|
|
1088
|
+
|
|
1089
|
+
def __init__(self, var: str = "foo"):
|
|
1090
|
+
self.var = var
|
|
1091
|
+
"""
|
|
1068
1092
|
|
|
1069
1093
|
@classmethod
|
|
1070
1094
|
def handles_type(cls, py_type: Type) -> bool:
|
|
@@ -1077,13 +1101,13 @@ class PlainClassSchema(RecordSchema):
|
|
|
1077
1101
|
and not hasattr(py_type, "__pydantic_private__")
|
|
1078
1102
|
# If we are subclassing a string, used the "named string" approach
|
|
1079
1103
|
and (inspect.isclass(py_type) and not issubclass(py_type, str))
|
|
1080
|
-
#
|
|
1081
|
-
and bool(get_type_hints(py_type
|
|
1104
|
+
# and any other class with typed annotations
|
|
1105
|
+
and bool(get_type_hints(py_type))
|
|
1082
1106
|
)
|
|
1083
1107
|
|
|
1084
1108
|
def __init__(self, py_type: Type, namespace: Optional[str] = None, options: Option = Option(0)):
|
|
1085
1109
|
"""
|
|
1086
|
-
An Avro record schema for a plain Python class with
|
|
1110
|
+
An Avro record schema for a plain Python class with type hints
|
|
1087
1111
|
|
|
1088
1112
|
:param py_type: The Python class to generate a schema for.
|
|
1089
1113
|
:param namespace: The Avro namespace to add to schemas.
|
|
@@ -1091,17 +1115,30 @@ class PlainClassSchema(RecordSchema):
|
|
|
1091
1115
|
"""
|
|
1092
1116
|
super().__init__(py_type, namespace=namespace, options=options)
|
|
1093
1117
|
py_type = _type_from_annotated(py_type)
|
|
1094
|
-
|
|
1095
|
-
self.py_fields =
|
|
1118
|
+
|
|
1119
|
+
self.py_fields: list[tuple[str, type]] = []
|
|
1120
|
+
for k, v in py_type.__annotations__.items():
|
|
1121
|
+
self.py_fields.append((k, v))
|
|
1122
|
+
# We store __init__ parameters with default values. They can be used as defaults for the record.
|
|
1123
|
+
self.signature_fields = {
|
|
1124
|
+
param.name: (param.annotation, param.default)
|
|
1125
|
+
for param in list(inspect.signature(py_type.__init__).parameters.values())[1:]
|
|
1126
|
+
if param.default is not inspect._empty
|
|
1127
|
+
}
|
|
1096
1128
|
self.record_fields = [self._record_field(field) for field in self.py_fields]
|
|
1097
1129
|
|
|
1098
|
-
def _record_field(self, py_field:
|
|
1130
|
+
def _record_field(self, py_field: tuple[str, Type]) -> RecordField:
|
|
1099
1131
|
"""Return an Avro record field object for a given Python instance attribute"""
|
|
1100
|
-
|
|
1101
|
-
|
|
1132
|
+
aliases, actual_type = get_field_aliases_and_actual_type(py_field[1])
|
|
1133
|
+
name = py_field[0]
|
|
1134
|
+
default = dataclasses.MISSING
|
|
1135
|
+
if field := self.signature_fields.get(name):
|
|
1136
|
+
_annotation, _default = field
|
|
1137
|
+
if actual_type is _annotation:
|
|
1138
|
+
default = _default
|
|
1102
1139
|
field_obj = RecordField(
|
|
1103
1140
|
py_type=actual_type,
|
|
1104
|
-
name=
|
|
1141
|
+
name=name,
|
|
1105
1142
|
namespace=self.namespace_override,
|
|
1106
1143
|
default=default,
|
|
1107
1144
|
aliases=aliases,
|
{localstack_py_avro_schema-3.9.2.dist-info → localstack_py_avro_schema-3.9.3.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|