structurize 2.21.0__tar.gz → 2.21.1__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 (81) hide show
  1. {structurize-2.21.0/structurize.egg-info → structurize-2.21.1}/PKG-INFO +1 -1
  2. {structurize-2.21.0 → structurize-2.21.1}/avrotize/_version.py +3 -3
  3. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotopython.py +4 -2
  4. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretojava.py +86 -1
  5. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretopython.py +21 -13
  6. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretots.py +4 -2
  7. {structurize-2.21.0 → structurize-2.21.1/structurize.egg-info}/PKG-INFO +1 -1
  8. {structurize-2.21.0 → structurize-2.21.1}/.gitignore +0 -0
  9. {structurize-2.21.0 → structurize-2.21.1}/LICENSE +0 -0
  10. {structurize-2.21.0 → structurize-2.21.1}/MANIFEST.in +0 -0
  11. {structurize-2.21.0 → structurize-2.21.1}/README.md +0 -0
  12. {structurize-2.21.0 → structurize-2.21.1}/avrotize/__init__.py +0 -0
  13. {structurize-2.21.0 → structurize-2.21.1}/avrotize/__main__.py +0 -0
  14. {structurize-2.21.0 → structurize-2.21.1}/avrotize/asn1toavro.py +0 -0
  15. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotize.py +0 -0
  16. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotocpp.py +0 -0
  17. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotocsharp.py +0 -0
  18. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotocsv.py +0 -0
  19. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotodatapackage.py +0 -0
  20. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotodb.py +0 -0
  21. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotogo.py +0 -0
  22. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotographql.py +0 -0
  23. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotoiceberg.py +0 -0
  24. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotojava.py +0 -0
  25. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotojs.py +0 -0
  26. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotojsons.py +0 -0
  27. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotojstruct.py +0 -0
  28. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotokusto.py +0 -0
  29. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotomd.py +0 -0
  30. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotools.py +0 -0
  31. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotoparquet.py +0 -0
  32. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotoproto.py +0 -0
  33. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotorust.py +0 -0
  34. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotots.py +0 -0
  35. {structurize-2.21.0 → structurize-2.21.1}/avrotize/avrotoxsd.py +0 -0
  36. {structurize-2.21.0 → structurize-2.21.1}/avrotize/cddltostructure.py +0 -0
  37. {structurize-2.21.0 → structurize-2.21.1}/avrotize/commands.json +0 -0
  38. {structurize-2.21.0 → structurize-2.21.1}/avrotize/common.py +0 -0
  39. {structurize-2.21.0 → structurize-2.21.1}/avrotize/constants.py +0 -0
  40. {structurize-2.21.0 → structurize-2.21.1}/avrotize/csvtoavro.py +0 -0
  41. {structurize-2.21.0 → structurize-2.21.1}/avrotize/datapackagetoavro.py +0 -0
  42. {structurize-2.21.0 → structurize-2.21.1}/avrotize/dependencies/cpp/vcpkg/vcpkg.json +0 -0
  43. {structurize-2.21.0 → structurize-2.21.1}/avrotize/dependencies/typescript/node22/package.json +0 -0
  44. {structurize-2.21.0 → structurize-2.21.1}/avrotize/dependency_resolver.py +0 -0
  45. {structurize-2.21.0 → structurize-2.21.1}/avrotize/dependency_version.py +0 -0
  46. {structurize-2.21.0 → structurize-2.21.1}/avrotize/jsonstoavro.py +0 -0
  47. {structurize-2.21.0 → structurize-2.21.1}/avrotize/jsonstostructure.py +0 -0
  48. {structurize-2.21.0 → structurize-2.21.1}/avrotize/jstructtoavro.py +0 -0
  49. {structurize-2.21.0 → structurize-2.21.1}/avrotize/kstructtoavro.py +0 -0
  50. {structurize-2.21.0 → structurize-2.21.1}/avrotize/kustotoavro.py +0 -0
  51. {structurize-2.21.0 → structurize-2.21.1}/avrotize/openapitostructure.py +0 -0
  52. {structurize-2.21.0 → structurize-2.21.1}/avrotize/parquettoavro.py +0 -0
  53. {structurize-2.21.0 → structurize-2.21.1}/avrotize/proto2parser.py +0 -0
  54. {structurize-2.21.0 → structurize-2.21.1}/avrotize/proto3parser.py +0 -0
  55. {structurize-2.21.0 → structurize-2.21.1}/avrotize/prototoavro.py +0 -0
  56. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretocddl.py +0 -0
  57. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretocpp.py +0 -0
  58. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretocsharp.py +0 -0
  59. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretocsv.py +0 -0
  60. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretodatapackage.py +0 -0
  61. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretodb.py +0 -0
  62. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretogo.py +0 -0
  63. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretographql.py +0 -0
  64. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretoiceberg.py +0 -0
  65. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretojs.py +0 -0
  66. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretojsons.py +0 -0
  67. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretokusto.py +0 -0
  68. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretomd.py +0 -0
  69. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretoproto.py +0 -0
  70. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretorust.py +0 -0
  71. {structurize-2.21.0 → structurize-2.21.1}/avrotize/structuretoxsd.py +0 -0
  72. {structurize-2.21.0 → structurize-2.21.1}/avrotize/xsdtoavro.py +0 -0
  73. {structurize-2.21.0 → structurize-2.21.1}/build.ps1 +0 -0
  74. {structurize-2.21.0 → structurize-2.21.1}/build.sh +0 -0
  75. {structurize-2.21.0 → structurize-2.21.1}/pyproject.toml +0 -0
  76. {structurize-2.21.0 → structurize-2.21.1}/setup.cfg +0 -0
  77. {structurize-2.21.0 → structurize-2.21.1}/structurize.egg-info/SOURCES.txt +0 -0
  78. {structurize-2.21.0 → structurize-2.21.1}/structurize.egg-info/dependency_links.txt +0 -0
  79. {structurize-2.21.0 → structurize-2.21.1}/structurize.egg-info/entry_points.txt +0 -0
  80. {structurize-2.21.0 → structurize-2.21.1}/structurize.egg-info/requires.txt +0 -0
  81. {structurize-2.21.0 → structurize-2.21.1}/structurize.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: structurize
3
- Version: 2.21.0
3
+ Version: 2.21.1
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
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '2.21.0'
32
- __version_tuple__ = version_tuple = (2, 21, 0)
31
+ __version__ = version = '2.21.1'
32
+ __version_tuple__ = version_tuple = (2, 21, 1)
33
33
 
34
- __commit_id__ = commit_id = 'g1df522119'
34
+ __commit_id__ = commit_id = 'g9b9841dd3'
@@ -327,7 +327,8 @@ class AvroToPython:
327
327
  def generate_test_class(self, package_name: str, class_name: str, fields: List[Dict[str, str]], import_types: Set[str]) -> None:
328
328
  """Generates a unit test class for a Python data class"""
329
329
  test_class_name = f"Test_{class_name}"
330
- tests_package_name = "test_"+package_name.replace('.', '_').lower()
330
+ flat_package = package_name.replace('.', '_').lower()
331
+ tests_package_name = flat_package if flat_package.startswith('test_') else f"test_{flat_package}"
331
332
  test_class_definition = process_template(
332
333
  "avrotopython/test_class.jinja",
333
334
  package_name=package_name,
@@ -348,7 +349,8 @@ class AvroToPython:
348
349
  def generate_test_enum(self, package_name: str, class_name: str, symbols: List[str]) -> None:
349
350
  """Generates a unit test class for a Python enum"""
350
351
  test_class_name = f"Test_{class_name}"
351
- tests_package_name = "test_"+package_name.replace('.', '_').lower()
352
+ flat_package = package_name.replace('.', '_').lower()
353
+ tests_package_name = flat_package if flat_package.startswith('test_') else f"test_{flat_package}"
352
354
  test_class_definition = process_template(
353
355
  "avrotopython/test_enum.jinja",
354
356
  package_name=package_name,
@@ -384,7 +384,12 @@ class StructureToJava:
384
384
  field_count=len(field_names)
385
385
  )
386
386
 
387
- class_definition = class_definition.rstrip() + equals_hashcode + "\n}\n"
387
+ # Generate createTestInstance() method for testing (only for non-abstract classes)
388
+ create_test_instance = ''
389
+ if not is_abstract:
390
+ create_test_instance = self.generate_create_test_instance_method(class_name, fields, schema_namespace)
391
+
392
+ class_definition = class_definition.rstrip() + create_test_instance + equals_hashcode + "\n}\n"
388
393
 
389
394
  if write_file:
390
395
  self.write_to_file(package, class_name, class_definition)
@@ -455,6 +460,86 @@ class StructureToJava:
455
460
  return str(value)
456
461
  return f"/* unsupported const value */"
457
462
 
463
+ def get_test_value(self, java_type: str) -> str:
464
+ """ Get a test value for a Java type """
465
+ # Handle arrays/lists
466
+ if java_type.startswith("List<") or java_type.startswith("ArrayList<"):
467
+ return "new java.util.ArrayList<>()"
468
+ if java_type.startswith("Map<"):
469
+ return "new java.util.HashMap<>()"
470
+ if java_type.endswith("[]"):
471
+ return f"new {java_type[:-2]}[0]"
472
+
473
+ # Primitive test values
474
+ test_values = {
475
+ 'String': '"test-string"',
476
+ 'string': '"test-string"',
477
+ 'int': '42',
478
+ 'Integer': '42',
479
+ 'long': '42L',
480
+ 'Long': '42L',
481
+ 'double': '3.14',
482
+ 'Double': '3.14',
483
+ 'float': '3.14f',
484
+ 'Float': '3.14f',
485
+ 'boolean': 'true',
486
+ 'Boolean': 'true',
487
+ 'byte': '(byte)0',
488
+ 'Byte': '(byte)0',
489
+ 'short': '(short)0',
490
+ 'Short': '(short)0',
491
+ 'BigInteger': 'java.math.BigInteger.ZERO',
492
+ 'BigDecimal': 'java.math.BigDecimal.ZERO',
493
+ 'byte[]': 'new byte[0]',
494
+ 'LocalDate': 'java.time.LocalDate.now()',
495
+ 'LocalTime': 'java.time.LocalTime.now()',
496
+ 'Instant': 'java.time.Instant.now()',
497
+ 'Duration': 'java.time.Duration.ZERO',
498
+ 'UUID': 'java.util.UUID.randomUUID()',
499
+ 'URI': 'java.net.URI.create("http://example.com")',
500
+ 'Object': 'new Object()',
501
+ 'void': 'null',
502
+ 'Void': 'null',
503
+ }
504
+
505
+ if java_type in test_values:
506
+ return test_values[java_type]
507
+
508
+ # Check if it's a generated type (enum or class)
509
+ if java_type in self.generated_types_java_package:
510
+ type_kind = self.generated_types_java_package[java_type]
511
+ if type_kind == "enum":
512
+ return f'{java_type}.values()[0]'
513
+ elif type_kind == "class":
514
+ return f'{java_type}.createTestInstance()'
515
+
516
+ # Default: try to instantiate
517
+ return f'new {java_type}()'
518
+
519
+ def generate_create_test_instance_method(self, class_name: str, fields: List[Dict], parent_package: str) -> str:
520
+ """ Generates a static createTestInstance method that creates a fully initialized instance """
521
+ method = f"\n{INDENT}/**\n{INDENT} * Creates a test instance with all required fields populated\n{INDENT} * @return a fully initialized test instance\n{INDENT} */\n"
522
+ method += f"{INDENT}public static {class_name} createTestInstance() {{\n"
523
+ method += f"{INDENT*2}{class_name} instance = new {class_name}();\n"
524
+
525
+ for field in fields:
526
+ # Skip const fields
527
+ if field.get('is_const', False):
528
+ continue
529
+
530
+ field_name = field['name']
531
+ field_type = field['type']
532
+
533
+ # Get a test value for this field
534
+ test_value = self.get_test_value(field_type)
535
+
536
+ # Setter name: set{Pascal(field_name)}
537
+ method += f"{INDENT*2}instance.set{pascal(field_name)}({test_value});\n"
538
+
539
+ method += f"{INDENT*2}return instance;\n"
540
+ method += f"{INDENT}}}\n"
541
+ return method
542
+
458
543
  def generate_enum(self, structure_schema: Dict, field_name: str, parent_package: str, write_file: bool) -> JavaType:
459
544
  """ Generates a Java enum from JSON Structure enum schema """
460
545
 
@@ -286,6 +286,7 @@ class StructureToPython:
286
286
  class_name = pascal(explicit_name if explicit_name else structure_schema.get('name', 'UnnamedClass'))
287
287
  schema_namespace = structure_schema.get('namespace', parent_namespace)
288
288
  namespace = self.concat_namespace(self.base_package, schema_namespace).lower()
289
+ package_name = self.python_package_from_structure_type(schema_namespace, class_name)
289
290
  python_qualified_name = self.python_fully_qualified_name_from_structure_type(schema_namespace, class_name)
290
291
 
291
292
  if python_qualified_name in self.generated_types:
@@ -358,8 +359,8 @@ class StructureToPython:
358
359
  )
359
360
 
360
361
  if write_file:
361
- self.write_to_file(namespace, class_name, class_definition)
362
- self.generate_test_class(namespace, class_name, field_docstrings, import_types)
362
+ self.write_to_file(package_name, class_name, class_definition)
363
+ self.generate_test_class(package_name, class_name, field_docstrings, import_types)
363
364
 
364
365
  self.generated_types[python_qualified_name] = 'class'
365
366
  self.generated_structure_types[python_qualified_name] = structure_schema
@@ -424,6 +425,7 @@ class StructureToPython:
424
425
  class_name = pascal(structure_schema.get('name', field_name + 'Enum'))
425
426
  schema_namespace = structure_schema.get('namespace', parent_namespace)
426
427
  namespace = self.concat_namespace(self.base_package, schema_namespace).lower()
428
+ package_name = self.python_package_from_structure_type(schema_namespace, class_name)
427
429
  python_qualified_name = self.python_fully_qualified_name_from_structure_type(schema_namespace, class_name)
428
430
 
429
431
  if python_qualified_name in self.generated_types:
@@ -442,8 +444,8 @@ class StructureToPython:
442
444
  )
443
445
 
444
446
  if write_file:
445
- self.write_to_file(namespace, class_name, enum_definition)
446
- self.generate_test_enum(namespace, class_name, symbols)
447
+ self.write_to_file(package_name, class_name, enum_definition)
448
+ self.generate_test_enum(package_name, class_name, symbols)
447
449
 
448
450
  self.generated_types[python_qualified_name] = 'enum'
449
451
  self.generated_enum_symbols[python_qualified_name] = symbols
@@ -513,6 +515,7 @@ class StructureToPython:
513
515
  class_name = pascal(structure_schema.get('name', 'UnnamedMap'))
514
516
  schema_namespace = structure_schema.get('namespace', parent_namespace)
515
517
  namespace = self.concat_namespace(self.base_package, schema_namespace).lower()
518
+ package_name = self.python_package_from_structure_type(schema_namespace, class_name)
516
519
  python_qualified_name = self.python_fully_qualified_name_from_structure_type(schema_namespace, class_name)
517
520
 
518
521
  if python_qualified_name in self.generated_types:
@@ -537,7 +540,7 @@ class StructureToPython:
537
540
  )
538
541
 
539
542
  if write_file:
540
- self.write_to_file(namespace, class_name, map_definition)
543
+ self.write_to_file(package_name, class_name, map_definition)
541
544
 
542
545
  self.generated_types[python_qualified_name] = 'map'
543
546
  return python_qualified_name
@@ -623,7 +626,8 @@ class StructureToPython:
623
626
  import_types: Set[str]) -> None:
624
627
  """Generates a unit test class for a Python dataclass"""
625
628
  test_class_name = f"Test_{class_name}"
626
- tests_package_name = "test_" + package_name.replace('.', '_').lower()
629
+ # Use a simpler file naming scheme based on class name only
630
+ test_file_name = f"test_{class_name.lower()}"
627
631
  test_class_definition = process_template(
628
632
  "structuretopython/test_class.jinja",
629
633
  package_name=package_name,
@@ -636,7 +640,7 @@ class StructureToPython:
636
640
  )
637
641
 
638
642
  base_dir = os.path.join(self.output_dir, "tests")
639
- test_file_path = os.path.join(base_dir, f"{tests_package_name.replace('.', '_').lower()}.py")
643
+ test_file_path = os.path.join(base_dir, f"{test_file_name}.py")
640
644
  if not os.path.exists(os.path.dirname(test_file_path)):
641
645
  os.makedirs(os.path.dirname(test_file_path), exist_ok=True)
642
646
  with open(test_file_path, 'w', encoding='utf-8') as file:
@@ -645,7 +649,8 @@ class StructureToPython:
645
649
  def generate_test_enum(self, package_name: str, class_name: str, symbols: List[str]) -> None:
646
650
  """Generates a unit test class for a Python enum"""
647
651
  test_class_name = f"Test_{class_name}"
648
- tests_package_name = "test_" + package_name.replace('.', '_').lower()
652
+ # Use a simpler file naming scheme based on class name only
653
+ test_file_name = f"test_{class_name.lower()}"
649
654
  test_class_definition = process_template(
650
655
  "structuretopython/test_enum.jinja",
651
656
  package_name=package_name,
@@ -654,7 +659,7 @@ class StructureToPython:
654
659
  symbols=symbols
655
660
  )
656
661
  base_dir = os.path.join(self.output_dir, "tests")
657
- test_file_path = os.path.join(base_dir, f"{tests_package_name.replace('.', '_').lower()}.py")
662
+ test_file_path = os.path.join(base_dir, f"{test_file_name}.py")
658
663
  if not os.path.exists(os.path.dirname(test_file_path)):
659
664
  os.makedirs(os.path.dirname(test_file_path), exist_ok=True)
660
665
  with open(test_file_path, 'w', encoding='utf-8') as file:
@@ -662,9 +667,8 @@ class StructureToPython:
662
667
 
663
668
  def write_to_file(self, package: str, class_name: str, python_code: str):
664
669
  """Writes a Python class to a file"""
665
- # Add 'struct' module to the package path
666
- full_package = f"{package}.struct"
667
- parent_package_name = '.'.join(full_package.split('.')[:-1])
670
+ # The containing directory is the parent package (matches avrotopython.py)
671
+ parent_package_name = '.'.join(package.split('.')[:-1])
668
672
  parent_package_path = os.sep.join(parent_package_name.split('.')).lower()
669
673
  directory_path = os.path.join(self.output_dir, "src", parent_package_path)
670
674
  if not os.path.exists(directory_path):
@@ -777,7 +781,11 @@ class StructureToPython:
777
781
  def convert_structure_to_python(structure_schema_path, py_file_path, package_name='', dataclasses_json_annotation=False, avro_annotation=False):
778
782
  """Converts JSON Structure schema to Python dataclasses"""
779
783
  if not package_name:
780
- package_name = os.path.splitext(os.path.basename(structure_schema_path))[0].lower().replace('-', '_')
784
+ # Strip .json extension, then also strip .struct suffix if present (*.struct.json naming convention)
785
+ base_name = os.path.splitext(os.path.basename(structure_schema_path))[0]
786
+ if base_name.endswith('.struct'):
787
+ base_name = base_name[:-7] # Remove '.struct' suffix
788
+ package_name = base_name.lower().replace('-', '_')
781
789
 
782
790
  structure_to_python = StructureToPython(package_name, dataclasses_json_annotation=dataclasses_json_annotation, avro_annotation=avro_annotation)
783
791
  structure_to_python.convert(structure_schema_path, py_file_path)
@@ -400,8 +400,10 @@ class StructureToTypeScript:
400
400
  write_file: bool = True) -> str:
401
401
  """ Generates a TypeScript enum from JSON Structure enum """
402
402
  enum_name = pascal(structure_schema.get('name', field_name + 'Enum'))
403
- namespace = self.concat_namespace(self.base_package, structure_schema.get('namespace', parent_namespace)).lower()
404
- typescript_qualified_name = self.typescript_fully_qualified_name_from_structure_type(parent_namespace, enum_name)
403
+ schema_namespace = structure_schema.get('namespace', parent_namespace)
404
+ namespace = self.concat_namespace(self.base_package, schema_namespace).lower()
405
+ # Use schema_namespace (not parent_namespace) to match the file location
406
+ typescript_qualified_name = self.typescript_fully_qualified_name_from_structure_type(schema_namespace, enum_name)
405
407
 
406
408
  if typescript_qualified_name in self.generated_types:
407
409
  return typescript_qualified_name
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: structurize
3
- Version: 2.21.0
3
+ Version: 2.21.1
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes