betterproto2-compiler 0.7.0__tar.gz → 0.8.0__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 (149) hide show
  1. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/.gitignore +2 -1
  2. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/PKG-INFO +2 -2
  3. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/pyproject.toml +9 -13
  4. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/known_types/__init__.py +14 -1
  5. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/known_types/any.py +24 -3
  6. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/known_types/duration.py +2 -2
  7. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/known_types/google_values.py +18 -18
  8. betterproto2_compiler-0.8.0/src/betterproto2_compiler/known_types/struct.py +111 -0
  9. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/known_types/timestamp.py +2 -2
  10. betterproto2_compiler-0.8.0/src/betterproto2_compiler/lib/__init__.py +12 -0
  11. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/lib/google/protobuf/__init__.py +902 -107
  12. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py +22 -5
  13. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/plugin/models.py +81 -50
  14. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/plugin/parser.py +3 -1
  15. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/templates/service_stub_sync.py.j2 +4 -6
  16. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/templates/template.py.j2 +25 -8
  17. betterproto2_compiler-0.8.0/tests/generate.py +181 -0
  18. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/any/any.proto +2 -0
  19. betterproto2_compiler-0.8.0/tests/inputs/compiler_lib/plugin.proto +180 -0
  20. betterproto2_compiler-0.8.0/tests/inputs/compiler_lib/protobuf.proto +13 -0
  21. betterproto2_compiler-0.8.0/tests/inputs/enum/enum.proto +67 -0
  22. betterproto2_compiler-0.8.0/tests/inputs/google/google.proto +12 -0
  23. betterproto2_compiler-0.8.0/tests/inputs/grpclib_reflection/example_service.proto +24 -0
  24. betterproto2_compiler-0.8.0/tests/inputs/grpclib_reflection/reflection.proto +146 -0
  25. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/util.py +0 -12
  26. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/uv.lock +99 -89
  27. betterproto2_compiler-0.7.0/tests/generate.py +0 -168
  28. betterproto2_compiler-0.7.0/tests/inputs/empty_repeated/empty_repeated.proto +0 -11
  29. betterproto2_compiler-0.7.0/tests/inputs/enum/enum.proto +0 -25
  30. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/pytest.ini +0 -0
  31. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/__init__.py +0 -0
  32. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/casing.py +0 -0
  33. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/compile/__init__.py +0 -0
  34. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/compile/importing.py +0 -0
  35. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/compile/naming.py +0 -0
  36. {betterproto2_compiler-0.7.0/src/betterproto2_compiler/lib → betterproto2_compiler-0.8.0/src/betterproto2_compiler/lib/google}/__init__.py +0 -0
  37. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/lib/message_pool.py +0 -0
  38. {betterproto2_compiler-0.7.0/src/betterproto2_compiler → betterproto2_compiler-0.8.0/src/betterproto2_compiler/lib}/py.typed +0 -0
  39. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/plugin/__init__.py +0 -0
  40. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/plugin/__main__.py +0 -0
  41. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/plugin/compiler.py +0 -0
  42. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/plugin/main.py +0 -0
  43. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/plugin/module_validation.py +0 -0
  44. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/plugin/plugin.bat +0 -0
  45. /betterproto2_compiler-0.7.0/src/betterproto2_compiler/lib/google/__init__.py → /betterproto2_compiler-0.8.0/src/betterproto2_compiler/py.typed +0 -0
  46. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/settings.py +0 -0
  47. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/templates/header.py.j2 +0 -0
  48. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/templates/service_stub.py.j2 +0 -0
  49. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/src/betterproto2_compiler/templates/service_stub_async.py.j2 +0 -0
  50. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/__init__.py +0 -0
  51. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/bool/bool.proto +0 -0
  52. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/bytes/bytes.proto +0 -0
  53. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/casing/casing.proto +0 -0
  54. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/casing_inner_class/casing_inner_class.proto +0 -0
  55. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/casing_message_field_uppercase/casing_message_field_uppercase.proto +0 -0
  56. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/deprecated/deprecated.proto +0 -0
  57. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/documentation/documentation.proto +0 -0
  58. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/double/double.proto +0 -0
  59. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/empty_service/empty_service.proto +0 -0
  60. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/encoding_decoding/encoding_decoding.proto +0 -0
  61. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/entry/entry.proto +0 -0
  62. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/example/example.proto +0 -0
  63. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/example_service/example_service.proto +0 -0
  64. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/features/features.proto +0 -0
  65. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/field_name_identical_to_type/field_name_identical_to_type.proto +0 -0
  66. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/fixed/fixed.proto +0 -0
  67. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/float/float.proto +0 -0
  68. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/google_impl_behavior_equivalence/google_impl_behavior_equivalence.proto +0 -0
  69. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/googletypes/googletypes.proto +0 -0
  70. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/googletypes_request/googletypes_request.proto +0 -0
  71. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/googletypes_response/googletypes_response.proto +0 -0
  72. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/googletypes_response_embedded/googletypes_response_embedded.proto +0 -0
  73. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/googletypes_service_returns_empty/googletypes_service_returns_empty.proto +0 -0
  74. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/googletypes_service_returns_googletype/googletypes_service_returns_googletype.proto +0 -0
  75. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/googletypes_struct/googletypes_struct.proto +0 -0
  76. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/googletypes_value/googletypes_value.proto +0 -0
  77. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/grpc_reflection_v1/reflection.proto +0 -0
  78. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_capitalized_package/capitalized.proto +0 -0
  79. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_capitalized_package/test.proto +0 -0
  80. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_child_package_from_package/child.proto +0 -0
  81. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_child_package_from_package/import_child_package_from_package.proto +0 -0
  82. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_child_package_from_package/package_message.proto +0 -0
  83. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_child_package_from_root/child.proto +0 -0
  84. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_child_package_from_root/import_child_package_from_root.proto +0 -0
  85. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_child_scoping_rules/child.proto +0 -0
  86. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_child_scoping_rules/import_child_scoping_rules.proto +0 -0
  87. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_child_scoping_rules/package.proto +0 -0
  88. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_circular_dependency/import_circular_dependency.proto +0 -0
  89. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_circular_dependency/other.proto +0 -0
  90. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_circular_dependency/root.proto +0 -0
  91. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_cousin_package/cousin.proto +0 -0
  92. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_cousin_package/test.proto +0 -0
  93. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_cousin_package_same_name/cousin.proto +0 -0
  94. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_cousin_package_same_name/test.proto +0 -0
  95. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_nested_child_package_from_root/child.proto +0 -0
  96. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_nested_child_package_from_root/import_nested_child_package_from_root.proto +0 -0
  97. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_packages_same_name/import_packages_same_name.proto +0 -0
  98. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_packages_same_name/posts_v1.proto +0 -0
  99. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_packages_same_name/users_v1.proto +0 -0
  100. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_parent_package_from_child/import_parent_package_from_child.proto +0 -0
  101. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_parent_package_from_child/parent_package_message.proto +0 -0
  102. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_root_package_from_child/child.proto +0 -0
  103. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_root_package_from_child/root.proto +0 -0
  104. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_root_sibling/import_root_sibling.proto +0 -0
  105. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_root_sibling/sibling.proto +0 -0
  106. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_service_input_message/child_package_request_message.proto +0 -0
  107. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_service_input_message/import_service_input_message.proto +0 -0
  108. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/import_service_input_message/request_message.proto +0 -0
  109. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/int32/int32.proto +0 -0
  110. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/invalid_field/invalid_field.proto +0 -0
  111. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/manual_validation/manual_validation.proto +0 -0
  112. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/map/map.proto +0 -0
  113. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/mapmessage/mapmessage.proto +0 -0
  114. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/message_wrapping/message_wrapping.proto +0 -0
  115. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/namespace_builtin_types/namespace_builtin_types.proto +0 -0
  116. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/namespace_keywords/namespace_keywords.proto +0 -0
  117. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/nested/nested.proto +0 -0
  118. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/nested2/nested2.proto +0 -0
  119. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/nested2/package.proto +0 -0
  120. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/nestedtwice/nestedtwice.proto +0 -0
  121. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/oneof/oneof.proto +0 -0
  122. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/oneof_default_value_serialization/oneof_default_value_serialization.proto +0 -0
  123. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/oneof_empty/oneof_empty.proto +0 -0
  124. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/oneof_enum/oneof_enum.proto +0 -0
  125. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/pickling/pickling.proto +0 -0
  126. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/proto3_field_presence/proto3_field_presence.proto +0 -0
  127. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/proto3_field_presence_oneof/proto3_field_presence_oneof.proto +0 -0
  128. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/recursivemessage/recursivemessage.proto +0 -0
  129. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/ref/ref.proto +0 -0
  130. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/ref/repeatedmessage.proto +0 -0
  131. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/regression_387/regression_387.proto +0 -0
  132. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/regression_414/regression_414.proto +0 -0
  133. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/repeated/repeated.proto +0 -0
  134. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/repeated_duration_timestamp/repeated_duration_timestamp.proto +0 -0
  135. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/repeatedmessage/repeatedmessage.proto +0 -0
  136. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/repeatedpacked/repeatedpacked.proto +0 -0
  137. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/rpc_empty_input_message/rpc_empty_input_message.proto +0 -0
  138. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/service/service.proto +0 -0
  139. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/service_separate_packages/messages.proto +0 -0
  140. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/service_separate_packages/service.proto +0 -0
  141. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/service_uppercase/service.proto +0 -0
  142. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/signed/signed.proto +0 -0
  143. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/simple_service/simple_service.proto +0 -0
  144. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/stream_stream/stream_stream.proto +0 -0
  145. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/timestamp_dict_encode/timestamp_dict_encode.proto +0 -0
  146. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/unwrap/unwrap.proto +0 -0
  147. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/inputs/validation/validation.proto +0 -0
  148. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/test_casing.py +0 -0
  149. {betterproto2_compiler-0.7.0 → betterproto2_compiler-0.8.0}/tests/test_module_validation.py +0 -0
@@ -7,6 +7,7 @@
7
7
  .python-version
8
8
  build/
9
9
  */tests/output_*
10
+ */tests/outputs/*
10
11
  **/__pycache__
11
12
  dist
12
13
  **/*.egg-info
@@ -18,4 +19,4 @@ output
18
19
  .asv
19
20
  venv
20
21
  .devcontainer
21
- .ruff_cache
22
+ .ruff_cache
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: betterproto2_compiler
3
- Version: 0.7.0
3
+ Version: 0.8.0
4
4
  Summary: Compiler for betterproto2
5
5
  Project-URL: Documentation, https://betterproto.github.io/python-betterproto2/
6
6
  Project-URL: Repository, https://github.com/betterproto/python-betterproto2
@@ -8,7 +8,7 @@ Author-email: Adrien Vannson <adrien.vannson@protonmail.com>, "Daniel G. Taylor"
8
8
  License-Expression: MIT
9
9
  Keywords: compiler,gRPC,protobuf
10
10
  Requires-Python: <4.0,>=3.10
11
- Requires-Dist: betterproto2[grpclib]<0.8,>=0.7.0
11
+ Requires-Dist: betterproto2[grpclib]<0.9,>=0.8.0
12
12
  Requires-Dist: jinja2>=3.0.3
13
13
  Requires-Dist: ruff~=0.9.3
14
14
  Requires-Dist: strenum<0.5,>=0.4.15; python_version == '3.10'
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "betterproto2_compiler"
3
- version = "0.7.0"
3
+ version = "0.8.0"
4
4
  description = "Compiler for betterproto2"
5
5
  authors = [
6
6
  { name = "Adrien Vannson", email = "adrien.vannson@protonmail.com" },
@@ -15,13 +15,17 @@ keywords = [
15
15
  requires-python = ">=3.10,<4.0"
16
16
  dependencies = [
17
17
  # TODO use the version from the current repo?
18
- "betterproto2[grpclib]>=0.7.0,<0.8",
18
+ "betterproto2[grpclib]>=0.8.0,<0.9",
19
+ # "betterproto2[grpclib]",
19
20
  "ruff~=0.9.3",
20
21
  "jinja2>=3.0.3",
21
22
  "typing-extensions>=4.7.1,<5",
22
23
  "strenum>=0.4.15,<0.5 ; python_version == '3.10'",
23
24
  ]
24
25
 
26
+ # [tool.uv.sources]
27
+ # "betterproto2" = { path = "../betterproto2" }
28
+
25
29
  [project.urls]
26
30
  Documentation = "https://betterproto.github.io/python-betterproto2/"
27
31
  Repository = "https://github.com/betterproto/python-betterproto2"
@@ -46,21 +50,12 @@ test = [
46
50
  package = true
47
51
  default-groups = "all"
48
52
 
49
- # [tool.hatch.build.targets.sdist]
50
- # include = ["src/betterproto2_compiler"]
51
-
52
- # [tool.hatch.build.targets.wheel]
53
- # include = ["src/betterproto2_compiler"]
54
-
55
- # [tool.hatch.build.targets.wheel.sources]
56
- # "src/betterproto2_compiler" = "betterproto2_compiler"
57
-
58
53
  [build-system]
59
54
  requires = ["hatchling"]
60
55
  build-backend = "hatchling.build"
61
56
 
62
57
  [tool.ruff]
63
- extend-exclude = ["tests/output_*", "src/betterproto2_compiler/lib"]
58
+ extend-exclude = ["tests/outputs", "src/betterproto2_compiler/lib"]
64
59
  target-version = "py310"
65
60
  line-length = 120
66
61
 
@@ -88,7 +83,8 @@ cmd = "pytest"
88
83
  help = "Run tests"
89
84
 
90
85
  [tool.poe.tasks.generate]
91
- sequence = ["_generate_tests", "_generate_tests_lib"]
86
+ # sequence = ["_generate_tests", "_generate_tests_lib"]
87
+ sequence = ["_generate_tests"]
92
88
  help = "Generate test cases"
93
89
 
94
90
  [tool.poe.tasks._generate_tests]
@@ -13,13 +13,14 @@ from .google_values import (
13
13
  UInt32Value,
14
14
  UInt64Value,
15
15
  )
16
+ from .struct import ListValue, Struct, Value
16
17
  from .timestamp import Timestamp
17
18
 
18
19
  # For each (package, message name), lists the methods that should be added to the message definition.
19
20
  # The source code of the method is read from the `known_types` folder. If imports are needed, they can be directly added
20
21
  # to the template file: they will automatically be removed if not necessary.
21
22
  KNOWN_METHODS: dict[tuple[str, str], list[Callable]] = {
22
- ("google.protobuf", "Any"): [Any.pack, Any.unpack, Any.to_dict],
23
+ ("google.protobuf", "Any"): [Any.pack, Any.unpack, Any.to_dict, Any.from_dict],
23
24
  ("google.protobuf", "Timestamp"): [
24
25
  Timestamp.from_datetime,
25
26
  Timestamp.to_datetime,
@@ -92,6 +93,18 @@ KNOWN_METHODS: dict[tuple[str, str], list[Callable]] = {
92
93
  BytesValue.from_wrapped,
93
94
  BytesValue.to_wrapped,
94
95
  ],
96
+ ("google.protobuf", "Struct"): [
97
+ Struct.from_dict,
98
+ Struct.to_dict,
99
+ ],
100
+ ("google.protobuf", "ListValue"): [
101
+ ListValue.from_dict,
102
+ ListValue.to_dict,
103
+ ],
104
+ ("google.protobuf", "Value"): [
105
+ Value.from_dict,
106
+ Value.to_dict,
107
+ ],
95
108
  }
96
109
 
97
110
  # A wrapped type is the type of a message that is automatically replaced by a known Python type.
@@ -8,7 +8,8 @@ default_message_pool = betterproto2.MessagePool() # Only for typing purpose
8
8
 
9
9
 
10
10
  class Any(VanillaAny):
11
- def pack(self, message: betterproto2.Message, message_pool: "betterproto2.MessagePool | None" = None) -> None:
11
+ @classmethod
12
+ def pack(cls, message: betterproto2.Message, message_pool: "betterproto2.MessagePool | None" = None) -> "Any":
12
13
  """
13
14
  Pack the given message in the `Any` object.
14
15
 
@@ -17,8 +18,10 @@ class Any(VanillaAny):
17
18
  """
18
19
  message_pool = message_pool or default_message_pool
19
20
 
20
- self.type_url = message_pool.type_to_url[type(message)]
21
- self.value = bytes(message)
21
+ type_url = message_pool.type_to_url[type(message)]
22
+ value = bytes(message)
23
+
24
+ return cls(type_url=type_url, value=value)
22
25
 
23
26
  def unpack(self, message_pool: "betterproto2.MessagePool | None" = None) -> betterproto2.Message | None:
24
27
  """
@@ -54,3 +57,21 @@ class Any(VanillaAny):
54
57
  output["value"] = value.to_dict(**kwargs)
55
58
 
56
59
  return output
60
+
61
+ # TODO typing
62
+ @classmethod
63
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
64
+ value = dict(value) # Make a copy
65
+
66
+ type_url = value.pop("@type", None)
67
+ msg_cls = default_message_pool.url_to_type.get(type_url, None)
68
+
69
+ if not msg_cls:
70
+ raise TypeError(f"Can't unpack unregistered type: {type_url}")
71
+
72
+ if not msg_cls.to_dict == betterproto2.Message.to_dict:
73
+ value = value["value"]
74
+
75
+ return cls(
76
+ type_url=type_url, value=bytes(msg_cls.from_dict(value, ignore_unknown_fields=ignore_unknown_fields))
77
+ )
@@ -30,7 +30,7 @@ class Duration(VanillaDuration):
30
30
 
31
31
  # TODO typing
32
32
  @classmethod
33
- def from_dict(cls, value):
33
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
34
34
  if isinstance(value, str):
35
35
  if not re.match(r"^\d+(\.\d+)?s$", value):
36
36
  raise ValueError(f"Invalid duration string: {value}")
@@ -38,7 +38,7 @@ class Duration(VanillaDuration):
38
38
  seconds = float(value[:-1])
39
39
  return Duration(seconds=int(seconds), nanos=int((seconds - int(seconds)) * 1e9))
40
40
 
41
- return super().from_dict(value)
41
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
42
42
 
43
43
  # TODO typing
44
44
  def to_dict(
@@ -24,10 +24,10 @@ class BoolValue(VanillaBoolValue):
24
24
  return self.value
25
25
 
26
26
  @classmethod
27
- def from_dict(cls, value):
27
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
28
28
  if isinstance(value, bool):
29
29
  return BoolValue(value=value)
30
- return super().from_dict(value)
30
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
31
31
 
32
32
  def to_dict(
33
33
  self,
@@ -48,10 +48,10 @@ class Int32Value(VanillaInt32Value):
48
48
  return self.value
49
49
 
50
50
  @classmethod
51
- def from_dict(cls, value):
51
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
52
52
  if isinstance(value, int):
53
53
  return Int32Value(value=value)
54
- return super().from_dict(value)
54
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
55
55
 
56
56
  def to_dict(
57
57
  self,
@@ -72,10 +72,10 @@ class Int64Value(VanillaInt64Value):
72
72
  return self.value
73
73
 
74
74
  @classmethod
75
- def from_dict(cls, value):
75
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
76
76
  if isinstance(value, int):
77
77
  return Int64Value(value=value)
78
- return super().from_dict(value)
78
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
79
79
 
80
80
  def to_dict(
81
81
  self,
@@ -96,10 +96,10 @@ class UInt32Value(VanillaUInt32Value):
96
96
  return self.value
97
97
 
98
98
  @classmethod
99
- def from_dict(cls, value):
99
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
100
100
  if isinstance(value, int):
101
101
  return UInt32Value(value=value)
102
- return super().from_dict(value)
102
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
103
103
 
104
104
  def to_dict(
105
105
  self,
@@ -120,10 +120,10 @@ class UInt64Value(VanillaUInt64Value):
120
120
  return self.value
121
121
 
122
122
  @classmethod
123
- def from_dict(cls, value):
123
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
124
124
  if isinstance(value, int):
125
125
  return UInt64Value(value=value)
126
- return super().from_dict(value)
126
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
127
127
 
128
128
  def to_dict(
129
129
  self,
@@ -144,10 +144,10 @@ class FloatValue(VanillaFloatValue):
144
144
  return self.value
145
145
 
146
146
  @classmethod
147
- def from_dict(cls, value):
147
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
148
148
  if isinstance(value, float):
149
149
  return FloatValue(value=value)
150
- return super().from_dict(value)
150
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
151
151
 
152
152
  def to_dict(
153
153
  self,
@@ -168,10 +168,10 @@ class DoubleValue(VanillaDoubleValue):
168
168
  return self.value
169
169
 
170
170
  @classmethod
171
- def from_dict(cls, value):
171
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
172
172
  if isinstance(value, float):
173
173
  return DoubleValue(value=value)
174
- return super().from_dict(value)
174
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
175
175
 
176
176
  def to_dict(
177
177
  self,
@@ -192,10 +192,10 @@ class StringValue(VanillaStringValue):
192
192
  return self.value
193
193
 
194
194
  @classmethod
195
- def from_dict(cls, value):
195
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
196
196
  if isinstance(value, str):
197
197
  return StringValue(value=value)
198
- return super().from_dict(value)
198
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
199
199
 
200
200
  def to_dict(
201
201
  self,
@@ -216,10 +216,10 @@ class BytesValue(VanillaBytesValue):
216
216
  return self.value
217
217
 
218
218
  @classmethod
219
- def from_dict(cls, value):
219
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
220
220
  if isinstance(value, bytes):
221
221
  return BytesValue(value=value)
222
- return super().from_dict(value)
222
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
223
223
 
224
224
  def to_dict(
225
225
  self,
@@ -0,0 +1,111 @@
1
+ import typing
2
+
3
+ import betterproto2
4
+
5
+ from betterproto2_compiler.lib.google.protobuf import (
6
+ ListValue as VanillaListValue,
7
+ NullValue,
8
+ Struct as VanillaStruct,
9
+ Value as VanillaValue,
10
+ )
11
+
12
+
13
+ class Struct(VanillaStruct):
14
+ # TODO typing
15
+ @classmethod
16
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
17
+ assert isinstance(value, dict)
18
+
19
+ fields: dict[str, Value] = {}
20
+
21
+ for key, val in value.items():
22
+ fields[key] = Value.from_dict(val)
23
+
24
+ return cls(fields=fields) # type: ignore[reportArgumentType]
25
+
26
+ # TODO typing
27
+ def to_dict(
28
+ self,
29
+ *,
30
+ output_format: betterproto2.OutputFormat = betterproto2.OutputFormat.PROTO_JSON,
31
+ casing: betterproto2.Casing = betterproto2.Casing.CAMEL,
32
+ include_default_values: bool = False,
33
+ ) -> dict[str, typing.Any] | typing.Any:
34
+ # If the output format is PYTHON, we should have kept the wrapped type without building the real class
35
+ assert output_format == betterproto2.OutputFormat.PROTO_JSON
36
+
37
+ return {
38
+ key: value.to_dict(
39
+ output_format=output_format, casing=casing, include_default_values=include_default_values
40
+ )
41
+ for key, value in self.fields.items()
42
+ }
43
+
44
+
45
+ # We can't use the unwrap mechanism to support directly using a Python object due to the None case: it would then be
46
+ # impossible to distinguish between the absence of the message and a None value.
47
+ class Value(VanillaValue):
48
+ # TODO typing
49
+ @classmethod
50
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
51
+ match value:
52
+ case bool() as b:
53
+ return cls(bool_value=b)
54
+ case int() | float() as num:
55
+ return cls(number_value=num)
56
+ case str() as s:
57
+ return cls(string_value=s)
58
+ case list() as l:
59
+ return cls(list_value=ListValue.from_dict(l))
60
+ case dict() as d:
61
+ return cls(struct_value=Struct.from_dict(d))
62
+ case None:
63
+ return cls(null_value=NullValue.NULL_VALUE)
64
+ raise ValueError(f"Unknown value type: {type(value)}")
65
+
66
+ # TODO typing
67
+ def to_dict(
68
+ self,
69
+ *,
70
+ output_format: betterproto2.OutputFormat = betterproto2.OutputFormat.PROTO_JSON,
71
+ casing: betterproto2.Casing = betterproto2.Casing.CAMEL,
72
+ include_default_values: bool = False,
73
+ ) -> dict[str, typing.Any] | typing.Any:
74
+ # If the output format is PYTHON, we should have kept the wrapped type without building the real class
75
+ assert output_format == betterproto2.OutputFormat.PROTO_JSON
76
+
77
+ match self:
78
+ case Value(null_value=NullValue.NULL_VALUE):
79
+ return None
80
+ case Value(bool_value=bool(b)):
81
+ return b
82
+ case Value(number_value=int(num)) | Value(number_value=float(num)):
83
+ return num
84
+ case Value(string_value=str(s)):
85
+ return s
86
+ case Value(list_value=ListValue(values=l)):
87
+ return [v.to_dict() for v in l]
88
+ case Value(struct_value=Struct(fields=f)):
89
+ return {k: v.to_dict() for k, v in f.items()}
90
+
91
+ raise ValueError("Invalid value")
92
+
93
+
94
+ class ListValue(VanillaListValue):
95
+ # TODO typing
96
+ @classmethod
97
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
98
+ return cls(values=[Value.from_dict(v) for v in value])
99
+
100
+ # TODO typing
101
+ def to_dict(
102
+ self,
103
+ *,
104
+ output_format: betterproto2.OutputFormat = betterproto2.OutputFormat.PROTO_JSON,
105
+ casing: betterproto2.Casing = betterproto2.Casing.CAMEL,
106
+ include_default_values: bool = False,
107
+ ) -> dict[str, typing.Any] | typing.Any:
108
+ # If the output format is PYTHON, we should have kept the wrapped type without building the real class
109
+ assert output_format == betterproto2.OutputFormat.PROTO_JSON
110
+
111
+ return [value.to_dict() for value in self.values]
@@ -55,13 +55,13 @@ class Timestamp(VanillaTimestamp):
55
55
 
56
56
  # TODO typing
57
57
  @classmethod
58
- def from_dict(cls, value):
58
+ def from_dict(cls, value, *, ignore_unknown_fields: bool = False):
59
59
  if isinstance(value, str):
60
60
  dt = dateutil.parser.isoparse(value)
61
61
  dt = dt.astimezone(datetime.timezone.utc)
62
62
  return Timestamp.from_datetime(dt)
63
63
 
64
- return super().from_dict(value)
64
+ return super().from_dict(value, ignore_unknown_fields=ignore_unknown_fields)
65
65
 
66
66
  # TODO typing
67
67
  def to_dict(
@@ -0,0 +1,12 @@
1
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
2
+ # sources: protobuf.proto
3
+ # plugin: python-betterproto2
4
+ # This file has been @generated
5
+
6
+ __all__ = ()
7
+
8
+
9
+ import betterproto2
10
+
11
+ _COMPILER_VERSION = "0.8.0"
12
+ betterproto2.check_compiler_version(_COMPILER_VERSION)