avrotize 2.1.2__tar.gz → 2.2.4__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.
- {avrotize-2.1.2 → avrotize-2.2.4}/PKG-INFO +26 -24
- {avrotize-2.1.2 → avrotize-2.2.4}/README.md +1 -1
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/_version.py +2 -2
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotokusto.py +31 -11
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotopython/dataclass_core.jinja +18 -9
- avrotize-2.2.4/avrotize/avrotopython/enum_core.jinja +87 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotopython/pyproject_toml.jinja +1 -1
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotopython/test_class.jinja +9 -3
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotopython/test_enum.jinja +1 -2
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotopython.py +216 -154
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/commands.json +22 -1
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/common.py +45 -16
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/kustotoavro.py +12 -6
- avrotize-2.2.4/avrotize/prototoavro.py +358 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/pyproject.toml +25 -23
- avrotize-2.1.2/avrotize/avrotopython/enum_core.jinja +0 -9
- avrotize-2.1.2/avrotize/prototoavro.py +0 -304
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/__init__.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/__main__.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/asn1toavro.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotize.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocpp/CMakeLists.txt.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocpp/build.bat.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocpp/build.sh.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocpp/dataclass_body.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocpp/vcpkg.json.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocpp.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocsharp/class_test.cs.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocsharp/dataclass_core.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocsharp/enum_test.cs.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocsharp/project.csproj.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocsharp/project.sln.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocsharp/testproject.csproj.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocsharp.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotocsv.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotodatapackage.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotodb.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotogo/go_enum.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotogo/go_helpers.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotogo/go_struct.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotogo/go_test.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotogo/go_union.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotogo.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotographql.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotoiceberg.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotojava.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotojs.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotojsons.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotomd/README.md.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotomd.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotools.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotoparquet.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotoproto.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotorust/dataclass_enum.rs.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotorust/dataclass_struct.rs.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotorust/dataclass_union.rs.jinja +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotorust.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotots.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/avrotoxsd.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/constants.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/csvtoavro.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/datapackagetoavro.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/dependency_resolver.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/generic/generic.avsc +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/jsonstoavro.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/kstructtoavro.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/parquettoavro.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/proto2parser.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/proto3parser.py +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/prototypes/any.avsc +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/prototypes/api.avsc +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/prototypes/duration.avsc +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/prototypes/field_mask.avsc +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/prototypes/struct.avsc +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/prototypes/timestamp.avsc +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/prototypes/type.avsc +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/prototypes/wrappers.avsc +0 -0
- {avrotize-2.1.2 → avrotize-2.2.4}/avrotize/xsdtoavro.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: avrotize
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.4
|
|
4
4
|
Summary: Tools to convert from and to Avro Schema from various other schema languages.
|
|
5
5
|
Author-email: Clemens Vasters <clemensv@microsoft.com>
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -8,37 +8,39 @@ Description-Content-Type: text/markdown
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Dist: jsonschema>=4.
|
|
11
|
+
Requires-Dist: jsonschema>=4.23.0
|
|
12
12
|
Requires-Dist: lark>=1.1.9
|
|
13
|
-
Requires-Dist: pyarrow>=
|
|
14
|
-
Requires-Dist: asn1tools>=0.
|
|
15
|
-
Requires-Dist: jsonpointer>=
|
|
13
|
+
Requires-Dist: pyarrow>=17.0.0
|
|
14
|
+
Requires-Dist: asn1tools>=0.167.0
|
|
15
|
+
Requires-Dist: jsonpointer>=3.0.0
|
|
16
16
|
Requires-Dist: jsonpath-ng>=1.6.1
|
|
17
17
|
Requires-Dist: jsoncomparison>=1.1.0
|
|
18
|
-
Requires-Dist: requests>=2.
|
|
19
|
-
Requires-Dist: azure-kusto-data>=4.
|
|
20
|
-
Requires-Dist: azure-identity>=1.
|
|
18
|
+
Requires-Dist: requests>=2.32.3
|
|
19
|
+
Requires-Dist: azure-kusto-data>=4.5.1
|
|
20
|
+
Requires-Dist: azure-identity>=1.17.1
|
|
21
21
|
Requires-Dist: datapackage>=1.15.4
|
|
22
22
|
Requires-Dist: jinja2>=3.1.4
|
|
23
|
-
Requires-Dist: pyiceberg>=0.
|
|
23
|
+
Requires-Dist: pyiceberg>=0.7.0
|
|
24
24
|
Requires-Dist: pandas>=2.2.2
|
|
25
|
-
Requires-Dist:
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist:
|
|
28
|
-
Requires-Dist:
|
|
29
|
-
Requires-Dist:
|
|
30
|
-
Requires-Dist:
|
|
31
|
-
Requires-Dist:
|
|
32
|
-
Requires-Dist:
|
|
33
|
-
Requires-Dist:
|
|
34
|
-
Requires-Dist:
|
|
35
|
-
Requires-Dist:
|
|
25
|
+
Requires-Dist: docker>=7.1.0
|
|
26
|
+
Requires-Dist: requests==2.32.3
|
|
27
|
+
Requires-Dist: pytest>=8.3.2 ; extra == "dev"
|
|
28
|
+
Requires-Dist: fastavro>=1.9.5 ; extra == "dev"
|
|
29
|
+
Requires-Dist: xmlschema>=3.3.2 ; extra == "dev"
|
|
30
|
+
Requires-Dist: xmlunittest>=1.0.1 ; extra == "dev"
|
|
31
|
+
Requires-Dist: pylint>=3.2.6 ; extra == "dev"
|
|
32
|
+
Requires-Dist: dataclasses_json>=0.6.7 ; extra == "dev"
|
|
33
|
+
Requires-Dist: dataclasses>=0.8 ; extra == "dev"
|
|
34
|
+
Requires-Dist: pydantic>=2.8.2 ; extra == "dev"
|
|
35
|
+
Requires-Dist: avro>=1.12.0 ; extra == "dev"
|
|
36
|
+
Requires-Dist: testcontainers>=4.7.2 ; extra == "dev"
|
|
37
|
+
Requires-Dist: pymysql>=1.1.1 ; extra == "dev"
|
|
36
38
|
Requires-Dist: psycopg2>=2.9.9 ; extra == "dev"
|
|
37
39
|
Requires-Dist: pyodbc>=5.1.0 ; extra == "dev"
|
|
38
|
-
Requires-Dist: pymongo>=4.
|
|
39
|
-
Requires-Dist: oracledb>=2.
|
|
40
|
+
Requires-Dist: pymongo>=4.8.0 ; extra == "dev"
|
|
41
|
+
Requires-Dist: oracledb>=2.3.0 ; extra == "dev"
|
|
40
42
|
Requires-Dist: cassandra-driver>=3.29.1 ; extra == "dev"
|
|
41
|
-
Requires-Dist: sqlalchemy>=2.0.
|
|
43
|
+
Requires-Dist: sqlalchemy>=2.0.32 ; extra == "dev"
|
|
42
44
|
Provides-Extra: dev
|
|
43
45
|
|
|
44
46
|
# Avrotize
|
|
@@ -56,7 +58,7 @@ The tool leans on the Apache Avro-derived [Avrotize Schema](specs/avrotize-schem
|
|
|
56
58
|
|
|
57
59
|
## Installation
|
|
58
60
|
|
|
59
|
-
You can install Avrotize from PyPI, [having installed Python 3.
|
|
61
|
+
You can install Avrotize from PyPI, [having installed Python 3.10 or later](https://www.python.org/downloads/):
|
|
60
62
|
|
|
61
63
|
```bash
|
|
62
64
|
pip install avrotize
|
|
@@ -13,7 +13,7 @@ The tool leans on the Apache Avro-derived [Avrotize Schema](specs/avrotize-schem
|
|
|
13
13
|
|
|
14
14
|
## Installation
|
|
15
15
|
|
|
16
|
-
You can install Avrotize from PyPI, [having installed Python 3.
|
|
16
|
+
You can install Avrotize from PyPI, [having installed Python 3.10 or later](https://www.python.org/downloads/):
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
19
|
pip install avrotize
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import json
|
|
4
4
|
import sys
|
|
5
5
|
from typing import Any, List
|
|
6
|
+
from avrotize.common import build_flat_type_dict, inline_avro_references, strip_first_doc
|
|
6
7
|
from azure.kusto.data import KustoClient, KustoConnectionStringBuilder, ClientRequestProperties
|
|
7
8
|
|
|
8
9
|
|
|
@@ -13,12 +14,12 @@ class AvroToKusto:
|
|
|
13
14
|
"""Initializes a new instance of the AvroToKusto class."""
|
|
14
15
|
pass
|
|
15
16
|
|
|
16
|
-
def convert_record_to_kusto(self,
|
|
17
|
+
def convert_record_to_kusto(self, type_dict:dict, recordschema: dict, emit_cloudevents_columns: bool, emit_cloudevents_dispatch_table: bool) -> List[str]:
|
|
17
18
|
"""Converts an Avro record schema to a Kusto table schema."""
|
|
18
19
|
# Get the name and fields of the top-level record
|
|
19
|
-
table_name =
|
|
20
|
-
fields =
|
|
21
|
-
|
|
20
|
+
table_name = recordschema["name"]
|
|
21
|
+
fields = recordschema["fields"]
|
|
22
|
+
|
|
22
23
|
# Create a StringBuilder to store the kusto statements
|
|
23
24
|
kusto = []
|
|
24
25
|
|
|
@@ -40,9 +41,11 @@ class AvroToKusto:
|
|
|
40
41
|
kusto.append("")
|
|
41
42
|
|
|
42
43
|
# Add the doc string as table metadata
|
|
43
|
-
if "doc" in
|
|
44
|
+
if "doc" in recordschema:
|
|
45
|
+
doc_data = recordschema["doc"]
|
|
46
|
+
doc_data = (doc_data[:997] + "...") if len(doc_data) > 1000 else doc_data
|
|
44
47
|
doc_string = json.dumps(json.dumps({
|
|
45
|
-
"description":
|
|
48
|
+
"description": doc_data
|
|
46
49
|
}))
|
|
47
50
|
kusto.append(
|
|
48
51
|
f".alter table [{table_name}] docstring {doc_string};")
|
|
@@ -52,11 +55,24 @@ class AvroToKusto:
|
|
|
52
55
|
for field in fields:
|
|
53
56
|
column_name = field["name"]
|
|
54
57
|
if "doc" in field:
|
|
58
|
+
doc_data = field["doc"]
|
|
59
|
+
if len(doc_data) > 900:
|
|
60
|
+
doc_data = (doc_data[:897] + "...")
|
|
55
61
|
doc_content = {
|
|
56
|
-
"description":
|
|
62
|
+
"description": doc_data
|
|
57
63
|
}
|
|
58
64
|
if isinstance(field["type"], list) or isinstance(field["type"], dict):
|
|
59
|
-
|
|
65
|
+
inline_schema = inline_avro_references(field["type"].copy(), type_dict.copy(), '')
|
|
66
|
+
if (len(json.dumps(inline_schema)) + len(doc_data)) > 900:
|
|
67
|
+
while strip_first_doc(inline_schema):
|
|
68
|
+
if (len(json.dumps(inline_schema)) + len(doc_data)) < 900:
|
|
69
|
+
break
|
|
70
|
+
if (len(json.dumps(inline_schema)) + len(doc_data)) > 900:
|
|
71
|
+
doc_content["schema"] = '{ "doc": "Schema too large to inline. Please refer to the Avro schema for more details." }'
|
|
72
|
+
else:
|
|
73
|
+
doc_content["schema"] = inline_schema
|
|
74
|
+
else:
|
|
75
|
+
doc_content["schema"] = inline_schema
|
|
60
76
|
doc = json.dumps(json.dumps(doc_content))
|
|
61
77
|
doc_string_statement.append(f" [{column_name}]: {doc}")
|
|
62
78
|
if doc_string_statement and emit_cloudevents_columns:
|
|
@@ -120,6 +136,9 @@ class AvroToKusto:
|
|
|
120
136
|
kusto.append("]\n```\n\n")
|
|
121
137
|
|
|
122
138
|
if emit_cloudevents_columns:
|
|
139
|
+
kusto.append(
|
|
140
|
+
f".drop materialized-view {table_name}Latest ifexists;")
|
|
141
|
+
kusto.append("")
|
|
123
142
|
kusto.append(
|
|
124
143
|
f".create materialized-view with (backfill=true) {table_name}Latest on table {table_name} {{")
|
|
125
144
|
kusto.append(
|
|
@@ -128,8 +147,8 @@ class AvroToKusto:
|
|
|
128
147
|
kusto.append("")
|
|
129
148
|
|
|
130
149
|
if emit_cloudevents_dispatch_table:
|
|
131
|
-
event_type =
|
|
132
|
-
|
|
150
|
+
event_type = recordschema["namespace"] + "." + \
|
|
151
|
+
recordschema["name"] if "namespace" in recordschema else recordschema["name"]
|
|
133
152
|
|
|
134
153
|
query = f"_cloudevents_dispatch | where (specversion == '1.0' and type == '{event_type}') | " + \
|
|
135
154
|
"project"
|
|
@@ -224,8 +243,9 @@ class AvroToKusto:
|
|
|
224
243
|
" {\"column\": \"data\", \"path\": \"$.data\"}")
|
|
225
244
|
kusto_script.append("]\n```\n\n")
|
|
226
245
|
|
|
246
|
+
type_dict = build_flat_type_dict(schema)
|
|
227
247
|
for record in schema:
|
|
228
|
-
kusto_script.extend(self.convert_record_to_kusto(
|
|
248
|
+
kusto_script.extend(self.convert_record_to_kusto(type_dict,
|
|
229
249
|
record, emit_cloudevents_columns, emit_cloudevents_dispatch_table))
|
|
230
250
|
return "\n".join(kusto_script)
|
|
231
251
|
|
|
@@ -12,17 +12,23 @@ import dataclasses
|
|
|
12
12
|
{%- if dataclasses_json_annotation %}
|
|
13
13
|
import dataclasses_json
|
|
14
14
|
import json
|
|
15
|
+
{%- for field in fields if field.type == "datetime" or field.type == "typing.Optional[datetime.datetime]" %}
|
|
16
|
+
{%- if loop.first %}
|
|
17
|
+
from marshmallow import fields
|
|
18
|
+
{%- endif %}
|
|
19
|
+
{%- endfor %}
|
|
15
20
|
{%- endif %}
|
|
16
21
|
{%- if avro_annotation %}
|
|
17
22
|
import avro.schema
|
|
18
23
|
import avro.io
|
|
19
24
|
{%- endif %}
|
|
20
|
-
{%- for import_type in import_types %}
|
|
21
|
-
{
|
|
22
|
-
|
|
23
|
-
{%-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
{%- for import_type in import_types if import_type not in ['datetime.datetime', 'datetime.date', 'datetime.time', 'datetime.timedelta', 'decimal.Decimal'] %}
|
|
26
|
+
from {{ '.'.join(import_type.split('.')[:-1]) | lower }} import {{ import_type.split('.')[-1] }}
|
|
27
|
+
{%- endfor %}
|
|
28
|
+
{%- for import_type in import_types if import_type in ['datetime.datetime', 'datetime.date', 'datetime.time', 'datetime.timedelta'] %}
|
|
29
|
+
{%- if loop.first %}
|
|
30
|
+
import datetime
|
|
31
|
+
{%- endif %}
|
|
26
32
|
{%- endfor %}
|
|
27
33
|
|
|
28
34
|
{% if dataclasses_json_annotation %}
|
|
@@ -38,8 +44,9 @@ class {{ class_name }}:
|
|
|
38
44
|
{%- endfor -%}
|
|
39
45
|
"""
|
|
40
46
|
{% for field in fields %}
|
|
41
|
-
{
|
|
42
|
-
{%-
|
|
47
|
+
{%- set isdate = field.type == "datetime" or field.type == "typing.Optional[datetime.datetime]" %}
|
|
48
|
+
{{ field.name }}: {{ field.type }}=dataclasses.field(kw_only=True{% if dataclasses_json_annotation %}, metadata=dataclasses_json.config(field_name="{{ field.original_name }}"{%- if isdate -%}, encoder=lambda d: datetime.datetime.isoformat(d) if d else None, decoder=lambda d:datetime.datetime.fromisoformat(d) if d else None, mm_field=fields.DateTime(format='iso'){%- endif -%}){%- endif %})
|
|
49
|
+
{%- endfor %}
|
|
43
50
|
{% if avro_annotation %}
|
|
44
51
|
AvroType: typing.ClassVar[avro.schema.Schema] = avro.schema.parse(
|
|
45
52
|
"{{ avro_schema_json }}"
|
|
@@ -132,7 +139,9 @@ class {{ class_name }}:
|
|
|
132
139
|
|
|
133
140
|
{%- if dataclasses_json_annotation %}
|
|
134
141
|
if content_type == 'application/json':
|
|
135
|
-
|
|
142
|
+
#pylint: disable=no-member
|
|
143
|
+
result = self.to_json()
|
|
144
|
+
#pylint: enable=no-member
|
|
136
145
|
{%- endif %}
|
|
137
146
|
|
|
138
147
|
if result is not None and content_type.endswith('+gzip'):
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
{%- if ordinals | length == 0 %}
|
|
4
|
+
_{{ class_name }}_members = []
|
|
5
|
+
{%- endif %}
|
|
6
|
+
|
|
7
|
+
class {{ class_name }}(Enum):
|
|
8
|
+
"""
|
|
9
|
+
{{ docstring }}
|
|
10
|
+
"""
|
|
11
|
+
{%- for symbol in symbols %}
|
|
12
|
+
{{ symbol }} = '{{symbol}}'
|
|
13
|
+
{%- endfor %}
|
|
14
|
+
|
|
15
|
+
@classmethod
|
|
16
|
+
def from_ordinal(cls, ordinal: int|str) -> '{{ class_name }}':
|
|
17
|
+
"""
|
|
18
|
+
Get enum member by ordinal
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
ordinal (int| str): The ordinal of the enum member. This can be an integer or a string representation of an integer.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
The enum member corresponding to the ordinal.
|
|
25
|
+
"""
|
|
26
|
+
{%- if ordinals | length == 0 %}
|
|
27
|
+
# pylint: disable=global-statement
|
|
28
|
+
global _{{ class_name }}_members
|
|
29
|
+
# pylint: enable=global-statement
|
|
30
|
+
{%- endif %}
|
|
31
|
+
|
|
32
|
+
if ordinal is None:
|
|
33
|
+
raise ValueError("ordinal must not be None")
|
|
34
|
+
if isinstance(ordinal, str) and ordinal.isdigit():
|
|
35
|
+
ordinal = int(ordinal)
|
|
36
|
+
{%- if ordinals | length > 0 %}
|
|
37
|
+
if isinstance(ordinal, int):
|
|
38
|
+
{%- for sym, ord in ordinals.items() -%}
|
|
39
|
+
{%- if loop.first %}
|
|
40
|
+
if ordinal == {{ ord }}:
|
|
41
|
+
{%- else %}
|
|
42
|
+
elif ordinal == {{ ord }}:
|
|
43
|
+
{%- endif %}
|
|
44
|
+
return {{ class_name }}.{{ sym }}
|
|
45
|
+
{%- endfor %}
|
|
46
|
+
raise ValueError("Ordinal not found in enum")
|
|
47
|
+
else:
|
|
48
|
+
raise ValueError("Ordinal must be an integer or a string representation of an integer")
|
|
49
|
+
{%- else %}
|
|
50
|
+
if not _{{ class_name }}_members:
|
|
51
|
+
_{{ class_name }}_members = list(cls)
|
|
52
|
+
if 0 <= int(ordinal) < len(_{{ class_name }}_members):
|
|
53
|
+
return _{{ class_name }}_members[ordinal]
|
|
54
|
+
else:
|
|
55
|
+
raise IndexError("Ordinal out of range for enum")
|
|
56
|
+
{%- endif %}
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def to_ordinal(cls, member: '{{ class_name }}') -> int:
|
|
60
|
+
"""
|
|
61
|
+
Get enum ordinal
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
member ({{ class_name }}): The enum member to get the ordinal of.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
The ordinal of the enum member.
|
|
68
|
+
"""
|
|
69
|
+
{%- if ordinals | length == 0 %}
|
|
70
|
+
# pylint: disable=global-statement
|
|
71
|
+
global _{{ class_name }}_members
|
|
72
|
+
# pylint: enable=global-statement
|
|
73
|
+
|
|
74
|
+
if not _{{ class_name }}_members:
|
|
75
|
+
_{{ class_name }}_members = list(cls)
|
|
76
|
+
return _{{ class_name }}_members.index(member)
|
|
77
|
+
{%- else %}
|
|
78
|
+
{% for sym, ord in ordinals.items() %}
|
|
79
|
+
if member == {{ class_name }}.{{ sym }}:
|
|
80
|
+
return {{ ord }}
|
|
81
|
+
{%- endfor %}
|
|
82
|
+
raise ValueError("Member not found in enum")
|
|
83
|
+
{%- endif %}
|
|
84
|
+
|
|
85
|
+
{%- if ordinals | length == 0 %}
|
|
86
|
+
_{{ class_name }}_members = list({{ class_name }})
|
|
87
|
+
{%- endif %}
|
|
@@ -8,11 +8,11 @@ import unittest
|
|
|
8
8
|
|
|
9
9
|
sys.path.append(os.path.realpath(os.path.join(os.path.dirname(__file__), '../src'.replace('/', os.sep))))
|
|
10
10
|
|
|
11
|
-
from {{
|
|
11
|
+
from {{ package_name | lower }} import {{ class_name }}
|
|
12
12
|
|
|
13
|
-
{%- for import_type in import_types %}
|
|
13
|
+
{%- for import_type in import_types if import_type not in ['decimal.Decimal', 'datetime.datetime', 'datetime.date', 'datetime.time', 'datetime.timedelta'] %}
|
|
14
14
|
{%- set import_type_name = 'Test_'+import_type.split('.')[-1] %}
|
|
15
|
-
{%- set import_package_name = 'test_'+import_type.
|
|
15
|
+
{%- set import_package_name = 'test_'+'_'.join(import_type.split('.')[:-1]) | lower %}
|
|
16
16
|
|
|
17
17
|
{%- if import_type.startswith('.') %}
|
|
18
18
|
from .{{ import_package_name }} import {{ import_type_name }}
|
|
@@ -20,6 +20,12 @@ from .{{ import_package_name }} import {{ import_type_name }}
|
|
|
20
20
|
from {{ import_package_name }} import {{ import_type_name }}
|
|
21
21
|
{%- endif -%}
|
|
22
22
|
{%- endfor %}
|
|
23
|
+
{%- for import_type in import_types if import_type in ['datetime.datetime', 'datetime.date', 'datetime.time', 'datetime.timedelta'] %}
|
|
24
|
+
{%- if loop.first %}
|
|
25
|
+
import datetime
|
|
26
|
+
{%- endif %}
|
|
27
|
+
{%- endfor %}
|
|
28
|
+
|
|
23
29
|
|
|
24
30
|
class {{ test_class_name }}(unittest.TestCase):
|
|
25
31
|
"""
|
|
@@ -4,7 +4,7 @@ import unittest
|
|
|
4
4
|
|
|
5
5
|
sys.path.append(os.path.realpath(os.path.join(os.path.dirname(__file__), '../src'.replace('/', os.sep))))
|
|
6
6
|
|
|
7
|
-
from {{
|
|
7
|
+
from {{ package_name | lower }} import {{ class_name }}
|
|
8
8
|
|
|
9
9
|
class {{ test_class_name }}(unittest.TestCase):
|
|
10
10
|
|
|
@@ -21,4 +21,3 @@ class {{ test_class_name }}(unittest.TestCase):
|
|
|
21
21
|
"""
|
|
22
22
|
return "{{ symbols[0] }}"
|
|
23
23
|
|
|
24
|
-
|