structurize 3.5.0__tar.gz → 3.5.2__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.
Files changed (91) hide show
  1. {structurize-3.5.0/structurize.egg-info → structurize-3.5.2}/PKG-INFO +2 -2
  2. structurize-3.5.2/avrotize/_version.py +24 -0
  3. {structurize-3.5.0 → structurize-3.5.2}/avrotize/cddltostructure.py +18 -1
  4. {structurize-3.5.0 → structurize-3.5.2}/avrotize/choice_inference.py +7 -7
  5. {structurize-3.5.0 → structurize-3.5.2}/avrotize/schema_inference.py +9 -4
  6. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretojava.py +3 -2
  7. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretokusto.py +16 -0
  8. {structurize-3.5.0 → structurize-3.5.2}/pyproject.toml +1 -1
  9. {structurize-3.5.0 → structurize-3.5.2/structurize.egg-info}/PKG-INFO +2 -2
  10. {structurize-3.5.0 → structurize-3.5.2}/structurize.egg-info/requires.txt +1 -1
  11. structurize-3.5.0/avrotize/_version.py +0 -34
  12. {structurize-3.5.0 → structurize-3.5.2}/.gitignore +0 -0
  13. {structurize-3.5.0 → structurize-3.5.2}/LICENSE +0 -0
  14. {structurize-3.5.0 → structurize-3.5.2}/MANIFEST.in +0 -0
  15. {structurize-3.5.0 → structurize-3.5.2}/README.md +0 -0
  16. {structurize-3.5.0 → structurize-3.5.2}/avrotize/__init__.py +0 -0
  17. {structurize-3.5.0 → structurize-3.5.2}/avrotize/__main__.py +0 -0
  18. {structurize-3.5.0 → structurize-3.5.2}/avrotize/asn1toavro.py +0 -0
  19. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotize.py +0 -0
  20. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotocpp.py +0 -0
  21. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotocsharp.py +0 -0
  22. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotocsv.py +0 -0
  23. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotodatapackage.py +0 -0
  24. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotodb.py +0 -0
  25. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotogo.py +0 -0
  26. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotographql.py +0 -0
  27. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotoiceberg.py +0 -0
  28. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotojava.py +0 -0
  29. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotojs.py +0 -0
  30. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotojsons.py +0 -0
  31. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotojstruct.py +0 -0
  32. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotokusto.py +0 -0
  33. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotomd.py +0 -0
  34. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotools.py +0 -0
  35. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotoparquet.py +0 -0
  36. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotoproto.py +0 -0
  37. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotopython.py +0 -0
  38. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotorust.py +0 -0
  39. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotots.py +0 -0
  40. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrotoxsd.py +0 -0
  41. {structurize-3.5.0 → structurize-3.5.2}/avrotize/avrovalidator.py +0 -0
  42. {structurize-3.5.0 → structurize-3.5.2}/avrotize/commands.json +0 -0
  43. {structurize-3.5.0 → structurize-3.5.2}/avrotize/common.py +0 -0
  44. {structurize-3.5.0 → structurize-3.5.2}/avrotize/constants.py +0 -0
  45. {structurize-3.5.0 → structurize-3.5.2}/avrotize/csvtoavro.py +0 -0
  46. {structurize-3.5.0 → structurize-3.5.2}/avrotize/datapackagetoavro.py +0 -0
  47. {structurize-3.5.0 → structurize-3.5.2}/avrotize/dependencies/cpp/vcpkg/vcpkg.json +0 -0
  48. {structurize-3.5.0 → structurize-3.5.2}/avrotize/dependencies/typescript/node22/package.json +0 -0
  49. {structurize-3.5.0 → structurize-3.5.2}/avrotize/dependency_resolver.py +0 -0
  50. {structurize-3.5.0 → structurize-3.5.2}/avrotize/dependency_version.py +0 -0
  51. {structurize-3.5.0 → structurize-3.5.2}/avrotize/jsonstoavro.py +0 -0
  52. {structurize-3.5.0 → structurize-3.5.2}/avrotize/jsonstostructure.py +0 -0
  53. {structurize-3.5.0 → structurize-3.5.2}/avrotize/jsontoschema.py +0 -0
  54. {structurize-3.5.0 → structurize-3.5.2}/avrotize/jstructtoavro.py +0 -0
  55. {structurize-3.5.0 → structurize-3.5.2}/avrotize/kstructtoavro.py +0 -0
  56. {structurize-3.5.0 → structurize-3.5.2}/avrotize/kustotoavro.py +0 -0
  57. {structurize-3.5.0 → structurize-3.5.2}/avrotize/kustotojstruct.py +0 -0
  58. {structurize-3.5.0 → structurize-3.5.2}/avrotize/mcp_server.py +0 -0
  59. {structurize-3.5.0 → structurize-3.5.2}/avrotize/openapitostructure.py +0 -0
  60. {structurize-3.5.0 → structurize-3.5.2}/avrotize/parquettoavro.py +0 -0
  61. {structurize-3.5.0 → structurize-3.5.2}/avrotize/proto2parser.py +0 -0
  62. {structurize-3.5.0 → structurize-3.5.2}/avrotize/proto3parser.py +0 -0
  63. {structurize-3.5.0 → structurize-3.5.2}/avrotize/prototoavro.py +0 -0
  64. {structurize-3.5.0 → structurize-3.5.2}/avrotize/sqltoavro.py +0 -0
  65. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretocddl.py +0 -0
  66. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretocpp.py +0 -0
  67. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretocsharp.py +0 -0
  68. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretocsv.py +0 -0
  69. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretodatapackage.py +0 -0
  70. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretodb.py +0 -0
  71. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretogo.py +0 -0
  72. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretographql.py +0 -0
  73. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretoiceberg.py +0 -0
  74. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretojs.py +0 -0
  75. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretojsons.py +0 -0
  76. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretomd.py +0 -0
  77. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretoproto.py +0 -0
  78. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretopython.py +0 -0
  79. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretorust.py +0 -0
  80. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretots.py +0 -0
  81. {structurize-3.5.0 → structurize-3.5.2}/avrotize/structuretoxsd.py +0 -0
  82. {structurize-3.5.0 → structurize-3.5.2}/avrotize/validate.py +0 -0
  83. {structurize-3.5.0 → structurize-3.5.2}/avrotize/xmltoschema.py +0 -0
  84. {structurize-3.5.0 → structurize-3.5.2}/avrotize/xsdtoavro.py +0 -0
  85. {structurize-3.5.0 → structurize-3.5.2}/build.ps1 +0 -0
  86. {structurize-3.5.0 → structurize-3.5.2}/build.sh +0 -0
  87. {structurize-3.5.0 → structurize-3.5.2}/setup.cfg +0 -0
  88. {structurize-3.5.0 → structurize-3.5.2}/structurize.egg-info/SOURCES.txt +0 -0
  89. {structurize-3.5.0 → structurize-3.5.2}/structurize.egg-info/dependency_links.txt +0 -0
  90. {structurize-3.5.0 → structurize-3.5.2}/structurize.egg-info/entry_points.txt +0 -0
  91. {structurize-3.5.0 → structurize-3.5.2}/structurize.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: structurize
3
- Version: 3.5.0
3
+ Version: 3.5.2
4
4
  Summary: Tools to convert from and to JSON Structure from various other schema languages.
5
5
  Author-email: Clemens Vasters <clemensv@microsoft.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -36,7 +36,7 @@ Requires-Dist: pydantic>=2.8.2; extra == "dev"
36
36
  Requires-Dist: avro>=1.12.0; extra == "dev"
37
37
  Requires-Dist: testcontainers>=4.7.2; extra == "dev"
38
38
  Requires-Dist: pymysql>=1.1.1; extra == "dev"
39
- Requires-Dist: psycopg2>=2.9.9; extra == "dev"
39
+ Requires-Dist: psycopg2-binary>=2.9.9; extra == "dev"
40
40
  Requires-Dist: pyodbc>=5.1.0; extra == "dev"
41
41
  Requires-Dist: pymongo>=4.8.0; extra == "dev"
42
42
  Requires-Dist: oracledb>=2.3.0; extra == "dev"
@@ -0,0 +1,24 @@
1
+ # file generated by vcs-versioning
2
+ # don't change, don't track in version control
3
+ from __future__ import annotations
4
+
5
+ __all__ = [
6
+ "__version__",
7
+ "__version_tuple__",
8
+ "version",
9
+ "version_tuple",
10
+ "__commit_id__",
11
+ "commit_id",
12
+ ]
13
+
14
+ version: str
15
+ __version__: str
16
+ __version_tuple__: tuple[int | str, ...]
17
+ version_tuple: tuple[int | str, ...]
18
+ commit_id: str | None
19
+ __commit_id__: str | None
20
+
21
+ __version__ = version = '3.5.2'
22
+ __version_tuple__ = version_tuple = (3, 5, 2)
23
+
24
+ __commit_id__ = commit_id = 'gff224504a'
@@ -165,6 +165,17 @@ class CddlToStructureConverter:
165
165
  # Counter for auto-generated type names
166
166
  self._auto_name_counter: int = 0
167
167
 
168
+ @staticmethod
169
+ def _wrap_ref(schema: Dict[str, Any]) -> Dict[str, Any]:
170
+ """Wrap a bare $ref in a type object per JSON Structure spec Section 3.4.1.
171
+
172
+ Bare {"$ref": "..."} is only valid inside a type attribute (e.g. union arrays).
173
+ In all other positions (items, properties, values), it must be {"type": {"$ref": "..."}}.
174
+ """
175
+ if '$ref' in schema and 'type' not in schema:
176
+ return {'type': {'$ref': schema['$ref']}}
177
+ return schema
178
+
168
179
  def _create_inline_definition(
169
180
  self, type_def: Dict[str, Any], base_name: str
170
181
  ) -> Dict[str, Any]:
@@ -900,6 +911,7 @@ class CddlToStructureConverter:
900
911
  keys_type = {'type': 'string'}
901
912
 
902
913
  values_type = member_type if member_type else {'type': 'any'}
914
+ values_type = self._wrap_ref(values_type)
903
915
 
904
916
  return {
905
917
  'keys': keys_type,
@@ -915,6 +927,7 @@ class CddlToStructureConverter:
915
927
  prop_schema = member_type.copy() if isinstance(member_type, dict) else member_type
916
928
  else:
917
929
  prop_schema = {'type': 'any'}
930
+ prop_schema = self._wrap_ref(prop_schema)
918
931
 
919
932
  # Handle occurrence indicators
920
933
  if occurrence_indicator:
@@ -1073,7 +1086,7 @@ class CddlToStructureConverter:
1073
1086
  tuple_order: List[str] = []
1074
1087
  for idx, item_type in enumerate(items_types):
1075
1088
  prop_name = f"_{idx}"
1076
- properties[prop_name] = item_type
1089
+ properties[prop_name] = self._wrap_ref(item_type)
1077
1090
  tuple_order.append(prop_name)
1078
1091
  return {
1079
1092
  'type': 'tuple',
@@ -1086,6 +1099,7 @@ class CddlToStructureConverter:
1086
1099
  items_type = items_types[0]
1087
1100
  # Extract inline compound types to definitions
1088
1101
  items_type = self._create_inline_definition(items_type, f"{context_name}_item")
1102
+ items_type = self._wrap_ref(items_type)
1089
1103
  else:
1090
1104
  # Multiple types that aren't a tuple - use union for items
1091
1105
  # Extract each inline compound type to definitions
@@ -1528,6 +1542,9 @@ class CddlToStructureConverter:
1528
1542
  else:
1529
1543
  base_type = {'type': 'any'}
1530
1544
 
1545
+ # Wrap bare $ref so constraints can be added alongside
1546
+ base_type = self._wrap_ref(base_type)
1547
+
1531
1548
  # Extract controller (constraint argument)
1532
1549
  if hasattr(operator_node, 'controller'):
1533
1550
  controller_value = self._extract_controller_value(operator_node.controller)
@@ -214,17 +214,17 @@ def _detect_discriminators(
214
214
  if len(values) < 2:
215
215
  continue
216
216
 
217
- # Discriminators must be identifier-like strings (type names, enum values)
218
- # Valid: "PlayerTracking", "ball_data", "goal-event", "Event.Type"
219
- # Invalid: "1", "2024/2025", "true", "2024-01-15T10:30:00Z", UUIDs
217
+ # Discriminators must be identifier-like strings (type names, enum values, codes)
218
+ # Valid: "PlayerTracking", "ball_data", "goal-event", "1", "用户", "true"
219
+ # Invalid: "2024/2025", "2024-01-15T10:30:00Z", UUIDs
220
220
  import re
221
221
  def is_valid_discriminator(s: str) -> bool:
222
- """Check if a string looks like a type name or identifier."""
222
+ """Check if a string looks like a type name, identifier, or short code."""
223
223
  if not s or not isinstance(s, str):
224
224
  return False
225
- # Must start with a letter, contain only alphanumeric, underscore, hyphen, dot
226
- # This matches typical identifiers: PascalCase, camelCase, snake_case, kebab-case
227
- return bool(re.match(r'^[A-Za-z][A-Za-z0-9_\-\.]*$', s))
225
+ # Accept word characters (Unicode letters, digits, underscore), hyphens, dots
226
+ # Reject slashes, colons, and other URI/date characters
227
+ return bool(re.match(r'^[\w][\w\-\.]*$', s, re.UNICODE))
228
228
 
229
229
  if not all(is_valid_discriminator(v) for v in values):
230
230
  continue
@@ -1236,11 +1236,14 @@ class JsonStructureSchemaInferrer(SchemaInferrer):
1236
1236
 
1237
1237
  # For inline unions with selector, we need $extends pointing to a base type
1238
1238
  # Compute common fields across all variants to create a proper base type
1239
+ disc_safe = avro_name(result.discriminator_field)
1239
1240
  all_variant_props = [c.get("properties", {}) for c in choices_map.values()]
1240
1241
  if all_variant_props:
1241
1242
  common_prop_names = set(all_variant_props[0].keys())
1242
1243
  for props in all_variant_props[1:]:
1243
1244
  common_prop_names &= set(props.keys())
1245
+ # Exclude discriminator from common props - each variant has a different default
1246
+ common_prop_names.discard(disc_safe)
1244
1247
 
1245
1248
  # Build base type with common properties
1246
1249
  base_name = avro_name(f"{type_name.rsplit('.', 1)[-1]}Base")
@@ -1277,7 +1280,6 @@ class JsonStructureSchemaInferrer(SchemaInferrer):
1277
1280
  definitions[variant_name] = variant_record
1278
1281
  new_choices_map[variant_name] = {"type": {"$ref": f"#/definitions/{variant_name}"}}
1279
1282
 
1280
- disc_safe = avro_name(result.discriminator_field)
1281
1283
  return {
1282
1284
  "type": "choice",
1283
1285
  "name": avro_name(type_name.rsplit('.', 1)[-1]),
@@ -1477,7 +1479,8 @@ class JsonStructureSchemaInferrer(SchemaInferrer):
1477
1479
  if all_items:
1478
1480
  item_types = self.consolidated_jstruct_type_list(type_name, all_items)
1479
1481
  if len(item_types) == 1:
1480
- return [{"type": "array", "items": item_types[0]}]
1482
+ items_schema = item_types[0] if isinstance(item_types[0], dict) else {"type": item_types[0]}
1483
+ return [{"type": "array", "items": items_schema}]
1481
1484
  else:
1482
1485
  # Build choice from multiple item types
1483
1486
  choices_map: Dict[str, Any] = {}
@@ -1539,7 +1542,8 @@ class JsonStructureSchemaInferrer(SchemaInferrer):
1539
1542
  item_types.append(item2)
1540
1543
  if item_types:
1541
1544
  if len(item_types) == 1:
1542
- list_types.append({"type": "array", "items": item_types[0]})
1545
+ items_schema = item_types[0] if isinstance(item_types[0], dict) else {"type": item_types[0]}
1546
+ list_types.append({"type": "array", "items": items_schema})
1543
1547
  else:
1544
1548
  # Build choices map from item types
1545
1549
  choices_map: Dict[str, Any] = {}
@@ -1563,7 +1567,8 @@ class JsonStructureSchemaInferrer(SchemaInferrer):
1563
1567
  value_types.append(item3)
1564
1568
  if value_types:
1565
1569
  if len(value_types) == 1:
1566
- list_types.append({"type": "map", "values": value_types[0]})
1570
+ values_schema = value_types[0] if isinstance(value_types[0], dict) else {"type": value_types[0]}
1571
+ list_types.append({"type": "map", "values": values_schema})
1567
1572
  else:
1568
1573
  list_types.append({"type": "map", "values": {"type": "choice", "choices": value_types}})
1569
1574
 
@@ -4,7 +4,7 @@
4
4
  import json
5
5
  import os
6
6
  from typing import Dict, List, Tuple, Union, Set, Optional, Any
7
- from avrotize.constants import JACKSON_VERSION
7
+ from avrotize.constants import JACKSON_VERSION, JACKSON_ANNOTATIONS_VERSION
8
8
 
9
9
  from avrotize.common import pascal, camel, process_template
10
10
 
@@ -878,7 +878,8 @@ class StructureToJava:
878
878
  "structuretojava/pom.xml.jinja",
879
879
  groupid=groupid,
880
880
  artifactid=artifactid,
881
- jackson_version=JACKSON_VERSION
881
+ jackson_version=JACKSON_VERSION,
882
+ jackson_annotations_version=JACKSON_ANNOTATIONS_VERSION
882
883
  )
883
884
  with open(pom_path, 'w', encoding='utf-8') as file:
884
885
  file.write(pom_content)
@@ -120,6 +120,21 @@ class StructureToKusto:
120
120
  """Check if a type is concrete (not abstract)."""
121
121
  return not schema.get('abstract', False)
122
122
 
123
+ def normalize_structure_type(self, structure_type: Union[str, dict, list]) -> Union[str, dict, list]:
124
+ """Normalize wrapped type expressions into the shapes the converter expects."""
125
+ if isinstance(structure_type, list):
126
+ non_null_types = [t for t in structure_type if t != 'null']
127
+ if len(non_null_types) == 1:
128
+ return self.normalize_structure_type(non_null_types[0])
129
+ return structure_type
130
+
131
+ if isinstance(structure_type, dict) and 'type' in structure_type and '$ref' not in structure_type:
132
+ nested_type = structure_type['type']
133
+ if isinstance(nested_type, (dict, list)):
134
+ return self.normalize_structure_type(nested_type)
135
+
136
+ return structure_type
137
+
123
138
  def find_all_object_types(self, schema: Dict, schema_doc: Dict) -> List[Dict]:
124
139
  """
125
140
  Find all concrete object types in the schema, including those in definitions.
@@ -516,6 +531,7 @@ class StructureToKusto:
516
531
 
517
532
  def convert_structure_type_to_kusto_type(self, structure_type: Union[str, dict, list], schema_doc: Optional[Dict] = None) -> str:
518
533
  """Converts a JSON Structure type to a Kusto type."""
534
+ structure_type = self.normalize_structure_type(structure_type)
519
535
  if isinstance(structure_type, list):
520
536
  # Handle type unions
521
537
  non_null_types = [t for t in structure_type if t != 'null']
@@ -46,7 +46,7 @@ dev = [
46
46
  "avro>=1.12.0",
47
47
  "testcontainers>=4.7.2",
48
48
  "pymysql>=1.1.1",
49
- "psycopg2>=2.9.9",
49
+ "psycopg2-binary>=2.9.9",
50
50
  "pyodbc>=5.1.0",
51
51
  "pymongo>=4.8.0",
52
52
  "oracledb>=2.3.0",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: structurize
3
- Version: 3.5.0
3
+ Version: 3.5.2
4
4
  Summary: Tools to convert from and to JSON Structure from various other schema languages.
5
5
  Author-email: Clemens Vasters <clemensv@microsoft.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -36,7 +36,7 @@ Requires-Dist: pydantic>=2.8.2; extra == "dev"
36
36
  Requires-Dist: avro>=1.12.0; extra == "dev"
37
37
  Requires-Dist: testcontainers>=4.7.2; extra == "dev"
38
38
  Requires-Dist: pymysql>=1.1.1; extra == "dev"
39
- Requires-Dist: psycopg2>=2.9.9; extra == "dev"
39
+ Requires-Dist: psycopg2-binary>=2.9.9; extra == "dev"
40
40
  Requires-Dist: pyodbc>=5.1.0; extra == "dev"
41
41
  Requires-Dist: pymongo>=4.8.0; extra == "dev"
42
42
  Requires-Dist: oracledb>=2.3.0; extra == "dev"
@@ -26,7 +26,7 @@ pydantic>=2.8.2
26
26
  avro>=1.12.0
27
27
  testcontainers>=4.7.2
28
28
  pymysql>=1.1.1
29
- psycopg2>=2.9.9
29
+ psycopg2-binary>=2.9.9
30
30
  pyodbc>=5.1.0
31
31
  pymongo>=4.8.0
32
32
  oracledb>=2.3.0
@@ -1,34 +0,0 @@
1
- # file generated by setuptools-scm
2
- # don't change, don't track in version control
3
-
4
- __all__ = [
5
- "__version__",
6
- "__version_tuple__",
7
- "version",
8
- "version_tuple",
9
- "__commit_id__",
10
- "commit_id",
11
- ]
12
-
13
- TYPE_CHECKING = False
14
- if TYPE_CHECKING:
15
- from typing import Tuple
16
- from typing import Union
17
-
18
- VERSION_TUPLE = Tuple[Union[int, str], ...]
19
- COMMIT_ID = Union[str, None]
20
- else:
21
- VERSION_TUPLE = object
22
- COMMIT_ID = object
23
-
24
- version: str
25
- __version__: str
26
- __version_tuple__: VERSION_TUPLE
27
- version_tuple: VERSION_TUPLE
28
- commit_id: COMMIT_ID
29
- __commit_id__: COMMIT_ID
30
-
31
- __version__ = version = '3.5.0'
32
- __version_tuple__ = version_tuple = (3, 5, 0)
33
-
34
- __commit_id__ = commit_id = 'g95f637e11'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes