betterproto2-compiler 0.6.0__tar.gz → 0.7.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 (146) hide show
  1. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/.gitignore +3 -2
  2. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/PKG-INFO +2 -2
  3. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/pyproject.toml +19 -4
  4. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/compile/importing.py +62 -30
  5. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/known_types/google_values.py +18 -18
  6. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/lib/google/protobuf/__init__.py +1 -1
  7. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py +1 -1
  8. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/plugin/models.py +88 -5
  9. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/plugin/parser.py +23 -8
  10. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/settings.py +1 -0
  11. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/templates/header.py.j2 +9 -1
  12. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/templates/service_stub_sync.py.j2 +4 -6
  13. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/templates/template.py.j2 +34 -1
  14. betterproto2_compiler-0.7.1/tests/generate.py +180 -0
  15. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/any/any.proto +2 -0
  16. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/deprecated/deprecated.proto +3 -0
  17. betterproto2_compiler-0.7.1/tests/inputs/enum/enum.proto +45 -0
  18. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/example_service/example_service.proto +4 -0
  19. betterproto2_compiler-0.7.1/tests/inputs/google/google.proto +12 -0
  20. betterproto2_compiler-0.7.1/tests/inputs/grpc_reflection_v1/reflection.proto +146 -0
  21. betterproto2_compiler-0.7.1/tests/inputs/grpclib_reflection/example_service.proto +24 -0
  22. betterproto2_compiler-0.7.1/tests/inputs/grpclib_reflection/reflection.proto +146 -0
  23. betterproto2_compiler-0.7.1/tests/util.py +45 -0
  24. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/uv.lock +89 -94
  25. betterproto2_compiler-0.6.0/tests/generate.py +0 -143
  26. betterproto2_compiler-0.6.0/tests/inputs/empty_repeated/empty_repeated.proto +0 -11
  27. betterproto2_compiler-0.6.0/tests/inputs/enum/enum.proto +0 -25
  28. betterproto2_compiler-0.6.0/tests/util.py +0 -47
  29. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/pytest.ini +0 -0
  30. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/__init__.py +0 -0
  31. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/casing.py +0 -0
  32. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/compile/__init__.py +0 -0
  33. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/compile/naming.py +0 -0
  34. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/known_types/__init__.py +0 -0
  35. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/known_types/any.py +0 -0
  36. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/known_types/duration.py +0 -0
  37. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/known_types/timestamp.py +0 -0
  38. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/lib/__init__.py +0 -0
  39. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/lib/google/__init__.py +0 -0
  40. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/lib/message_pool.py +0 -0
  41. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/plugin/__init__.py +0 -0
  42. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/plugin/__main__.py +0 -0
  43. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/plugin/compiler.py +0 -0
  44. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/plugin/main.py +0 -0
  45. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/plugin/module_validation.py +0 -0
  46. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/plugin/plugin.bat +0 -0
  47. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/py.typed +0 -0
  48. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/templates/service_stub.py.j2 +0 -0
  49. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/src/betterproto2_compiler/templates/service_stub_async.py.j2 +0 -0
  50. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/__init__.py +0 -0
  51. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/bool/bool.proto +0 -0
  52. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/bytes/bytes.proto +0 -0
  53. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/casing/casing.proto +0 -0
  54. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/casing_inner_class/casing_inner_class.proto +0 -0
  55. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/casing_message_field_uppercase/casing_message_field_uppercase.proto +0 -0
  56. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/documentation/documentation.proto +0 -0
  57. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/double/double.proto +0 -0
  58. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/empty_service/empty_service.proto +0 -0
  59. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/encoding_decoding/encoding_decoding.proto +0 -0
  60. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/entry/entry.proto +0 -0
  61. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/example/example.proto +0 -0
  62. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/features/features.proto +0 -0
  63. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/field_name_identical_to_type/field_name_identical_to_type.proto +0 -0
  64. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/fixed/fixed.proto +0 -0
  65. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/float/float.proto +0 -0
  66. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/google_impl_behavior_equivalence/google_impl_behavior_equivalence.proto +0 -0
  67. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/googletypes/googletypes.proto +0 -0
  68. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/googletypes_request/googletypes_request.proto +0 -0
  69. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/googletypes_response/googletypes_response.proto +0 -0
  70. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/googletypes_response_embedded/googletypes_response_embedded.proto +0 -0
  71. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/googletypes_service_returns_empty/googletypes_service_returns_empty.proto +0 -0
  72. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/googletypes_service_returns_googletype/googletypes_service_returns_googletype.proto +0 -0
  73. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/googletypes_struct/googletypes_struct.proto +0 -0
  74. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/googletypes_value/googletypes_value.proto +0 -0
  75. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_capitalized_package/capitalized.proto +0 -0
  76. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_capitalized_package/test.proto +0 -0
  77. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_child_package_from_package/child.proto +0 -0
  78. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_child_package_from_package/import_child_package_from_package.proto +0 -0
  79. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_child_package_from_package/package_message.proto +0 -0
  80. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_child_package_from_root/child.proto +0 -0
  81. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_child_package_from_root/import_child_package_from_root.proto +0 -0
  82. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_child_scoping_rules/child.proto +0 -0
  83. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_child_scoping_rules/import_child_scoping_rules.proto +0 -0
  84. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_child_scoping_rules/package.proto +0 -0
  85. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_circular_dependency/import_circular_dependency.proto +0 -0
  86. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_circular_dependency/other.proto +0 -0
  87. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_circular_dependency/root.proto +0 -0
  88. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_cousin_package/cousin.proto +0 -0
  89. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_cousin_package/test.proto +0 -0
  90. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_cousin_package_same_name/cousin.proto +0 -0
  91. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_cousin_package_same_name/test.proto +0 -0
  92. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_nested_child_package_from_root/child.proto +0 -0
  93. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_nested_child_package_from_root/import_nested_child_package_from_root.proto +0 -0
  94. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_packages_same_name/import_packages_same_name.proto +0 -0
  95. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_packages_same_name/posts_v1.proto +0 -0
  96. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_packages_same_name/users_v1.proto +0 -0
  97. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_parent_package_from_child/import_parent_package_from_child.proto +0 -0
  98. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_parent_package_from_child/parent_package_message.proto +0 -0
  99. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_root_package_from_child/child.proto +0 -0
  100. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_root_package_from_child/root.proto +0 -0
  101. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_root_sibling/import_root_sibling.proto +0 -0
  102. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_root_sibling/sibling.proto +0 -0
  103. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_service_input_message/child_package_request_message.proto +0 -0
  104. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_service_input_message/import_service_input_message.proto +0 -0
  105. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/import_service_input_message/request_message.proto +0 -0
  106. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/int32/int32.proto +0 -0
  107. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/invalid_field/invalid_field.proto +0 -0
  108. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/manual_validation/manual_validation.proto +0 -0
  109. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/map/map.proto +0 -0
  110. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/mapmessage/mapmessage.proto +0 -0
  111. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/message_wrapping/message_wrapping.proto +0 -0
  112. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/namespace_builtin_types/namespace_builtin_types.proto +0 -0
  113. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/namespace_keywords/namespace_keywords.proto +0 -0
  114. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/nested/nested.proto +0 -0
  115. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/nested2/nested2.proto +0 -0
  116. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/nested2/package.proto +0 -0
  117. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/nestedtwice/nestedtwice.proto +0 -0
  118. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/oneof/oneof.proto +0 -0
  119. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/oneof_default_value_serialization/oneof_default_value_serialization.proto +0 -0
  120. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/oneof_empty/oneof_empty.proto +0 -0
  121. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/oneof_enum/oneof_enum.proto +0 -0
  122. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/pickling/pickling.proto +0 -0
  123. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/proto3_field_presence/proto3_field_presence.proto +0 -0
  124. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/proto3_field_presence_oneof/proto3_field_presence_oneof.proto +0 -0
  125. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/recursivemessage/recursivemessage.proto +0 -0
  126. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/ref/ref.proto +0 -0
  127. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/ref/repeatedmessage.proto +0 -0
  128. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/regression_387/regression_387.proto +0 -0
  129. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/regression_414/regression_414.proto +0 -0
  130. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/repeated/repeated.proto +0 -0
  131. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/repeated_duration_timestamp/repeated_duration_timestamp.proto +0 -0
  132. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/repeatedmessage/repeatedmessage.proto +0 -0
  133. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/repeatedpacked/repeatedpacked.proto +0 -0
  134. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/rpc_empty_input_message/rpc_empty_input_message.proto +0 -0
  135. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/service/service.proto +0 -0
  136. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/service_separate_packages/messages.proto +0 -0
  137. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/service_separate_packages/service.proto +0 -0
  138. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/service_uppercase/service.proto +0 -0
  139. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/signed/signed.proto +0 -0
  140. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/simple_service/simple_service.proto +0 -0
  141. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/stream_stream/stream_stream.proto +0 -0
  142. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/timestamp_dict_encode/timestamp_dict_encode.proto +0 -0
  143. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/unwrap/unwrap.proto +0 -0
  144. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/inputs/validation/validation.proto +0 -0
  145. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/test_casing.py +0 -0
  146. {betterproto2_compiler-0.6.0 → betterproto2_compiler-0.7.1}/tests/test_module_validation.py +0 -0
@@ -6,7 +6,8 @@
6
6
  .pytest_cache
7
7
  .python-version
8
8
  build/
9
- tests/output_*
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.6.0
3
+ Version: 0.7.1
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.7,>=0.6.0
11
+ Requires-Dist: betterproto2[grpclib]<0.8,>=0.7.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.6.0"
3
+ version = "0.7.1"
4
4
  description = "Compiler for betterproto2"
5
5
  authors = [
6
6
  { name = "Adrien Vannson", email = "adrien.vannson@protonmail.com" },
@@ -15,7 +15,7 @@ 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.6.0,<0.7",
18
+ "betterproto2[grpclib]>=0.7.0,<0.8",
19
19
  "ruff~=0.9.3",
20
20
  "jinja2>=3.0.3",
21
21
  "typing-extensions>=4.7.1,<5",
@@ -60,7 +60,7 @@ requires = ["hatchling"]
60
60
  build-backend = "hatchling.build"
61
61
 
62
62
  [tool.ruff]
63
- extend-exclude = ["tests/output_*", "src/betterproto2_compiler/lib"]
63
+ extend-exclude = ["tests/outputs", "src/betterproto2_compiler/lib"]
64
64
  target-version = "py310"
65
65
  line-length = 120
66
66
 
@@ -88,7 +88,8 @@ cmd = "pytest"
88
88
  help = "Run tests"
89
89
 
90
90
  [tool.poe.tasks.generate]
91
- sequence = ["_generate_tests", "_generate_tests_lib"]
91
+ # sequence = ["_generate_tests", "_generate_tests_lib"]
92
+ sequence = ["_generate_tests"]
92
93
  help = "Generate test cases"
93
94
 
94
95
  [tool.poe.tasks._generate_tests]
@@ -122,6 +123,20 @@ python -m grpc.tools.protoc \
122
123
  google/protobuf/timestamp.proto \
123
124
  google/protobuf/type.proto \
124
125
  google/protobuf/wrappers.proto
126
+
127
+ python -m grpc.tools.protoc \
128
+ --python_betterproto2_out=tests/output_betterproto_descriptor \
129
+ --python_betterproto2_opt=google_protobuf_descriptors \
130
+ google/protobuf/any.proto \
131
+ google/protobuf/api.proto \
132
+ google/protobuf/duration.proto \
133
+ google/protobuf/empty.proto \
134
+ google/protobuf/field_mask.proto \
135
+ google/protobuf/source_context.proto \
136
+ google/protobuf/struct.proto \
137
+ google/protobuf/timestamp.proto \
138
+ google/protobuf/type.proto \
139
+ google/protobuf/wrappers.proto
125
140
  """
126
141
 
127
142
  [tool.poe.tasks.typecheck]
@@ -55,6 +55,32 @@ def parse_source_type_name(field_type_name: str, request: PluginRequestCompiler)
55
55
  raise ValueError(f"can't find type name: {field_type_name}")
56
56
 
57
57
 
58
+ def get_symbol_reference(
59
+ *,
60
+ package: str,
61
+ imports: set,
62
+ source_package: str,
63
+ symbol: str,
64
+ ) -> tuple[str, str | None]:
65
+ """
66
+ Return a Python symbol within a proto package. Adds the import if
67
+ necessary and returns it as well for usage. Unwraps well known type if required.
68
+ """
69
+ current_package: list[str] = package.split(".") if package else []
70
+ py_package: list[str] = source_package.split(".") if source_package else []
71
+
72
+ if py_package == current_package:
73
+ return (reference_sibling(symbol), None)
74
+
75
+ if py_package[: len(current_package)] == current_package:
76
+ return reference_descendent(current_package, imports, py_package, symbol)
77
+
78
+ if current_package[: len(py_package)] == py_package:
79
+ return reference_ancestor(current_package, imports, py_package, symbol)
80
+
81
+ return reference_cousin(current_package, imports, py_package, symbol)
82
+
83
+
58
84
  def get_type_reference(
59
85
  *,
60
86
  package: str,
@@ -73,30 +99,25 @@ def get_type_reference(
73
99
  if wrap and (source_package, source_type) in WRAPPED_TYPES:
74
100
  return WRAPPED_TYPES[(source_package, source_type)]
75
101
 
76
- current_package: list[str] = package.split(".") if package else []
77
- py_package: list[str] = source_package.split(".") if source_package else []
78
102
  py_type: str = pythonize_class_name(source_type)
79
-
80
- if py_package == current_package:
81
- return reference_sibling(py_type)
82
-
83
- if py_package[: len(current_package)] == current_package:
84
- return reference_descendent(current_package, imports, py_package, py_type)
85
-
86
- if current_package[: len(py_package)] == py_package:
87
- return reference_ancestor(current_package, imports, py_package, py_type)
88
-
89
- return reference_cousin(current_package, imports, py_package, py_type)
103
+ (ref, _) = get_symbol_reference(
104
+ package=package,
105
+ imports=imports,
106
+ source_package=source_package,
107
+ symbol=py_type,
108
+ )
109
+ return ref
90
110
 
91
111
 
92
- def reference_absolute(imports: set[str], py_package: list[str], py_type: str) -> str:
112
+ def reference_absolute(imports: set[str], py_package: list[str], py_type: str) -> tuple[str, str]:
93
113
  """
94
114
  Returns a reference to a python type located in the root, i.e. sys.path.
95
115
  """
96
116
  string_import = ".".join(py_package)
97
117
  string_alias = "__".join([safe_snake_case(name) for name in py_package])
98
- imports.add(f"import {string_import} as {string_alias}")
99
- return f"{string_alias}.{py_type}"
118
+ import_to_add = f"import {string_import} as {string_alias}"
119
+ imports.add(import_to_add)
120
+ return (f"{string_alias}.{py_type}", import_to_add)
100
121
 
101
122
 
102
123
  def reference_sibling(py_type: str) -> str:
@@ -106,7 +127,9 @@ def reference_sibling(py_type: str) -> str:
106
127
  return f"{py_type}"
107
128
 
108
129
 
109
- def reference_descendent(current_package: list[str], imports: set[str], py_package: list[str], py_type: str) -> str:
130
+ def reference_descendent(
131
+ current_package: list[str], imports: set[str], py_package: list[str], py_type: str
132
+ ) -> tuple[str, str]:
110
133
  """
111
134
  Returns a reference to a python type in a package that is a descendent of the
112
135
  current package, and adds the required import that is aliased to avoid name
@@ -116,15 +139,19 @@ def reference_descendent(current_package: list[str], imports: set[str], py_packa
116
139
  string_from = ".".join(importing_descendent[:-1])
117
140
  string_import = importing_descendent[-1]
118
141
  if string_from:
119
- string_alias = "_".join(importing_descendent)
120
- imports.add(f"from .{string_from} import {string_import} as {string_alias}")
121
- return f"{string_alias}.{py_type}"
142
+ string_alias = f"{'_'.join(importing_descendent)}"
143
+ import_to_add = f"from .{string_from} import {string_import} as {string_alias}"
144
+ imports.add(import_to_add)
145
+ return (f"{string_alias}.{py_type}", import_to_add)
122
146
  else:
123
- imports.add(f"from . import {string_import}")
124
- return f"{string_import}.{py_type}"
147
+ import_to_add = f"from . import {string_import}"
148
+ imports.add(import_to_add)
149
+ return (f"{string_import}.{py_type}", import_to_add)
125
150
 
126
151
 
127
- def reference_ancestor(current_package: list[str], imports: set[str], py_package: list[str], py_type: str) -> str:
152
+ def reference_ancestor(
153
+ current_package: list[str], imports: set[str], py_package: list[str], py_type: str
154
+ ) -> tuple[str, str]:
128
155
  """
129
156
  Returns a reference to a python type in a package which is an ancestor to the
130
157
  current package, and adds the required import that is aliased (if possible) to avoid
@@ -137,15 +164,19 @@ def reference_ancestor(current_package: list[str], imports: set[str], py_package
137
164
  string_import = py_package[-1]
138
165
  string_alias = f"_{'_' * distance_up}{string_import}__"
139
166
  string_from = f"..{'.' * distance_up}"
140
- imports.add(f"from {string_from} import {string_import} as {string_alias}")
141
- return f"{string_alias}.{py_type}"
167
+ import_to_add = f"from {string_from} import {string_import} as {string_alias}"
168
+ imports.add(import_to_add)
169
+ return (f"{string_alias}.{py_type}", import_to_add)
142
170
  else:
143
171
  string_alias = f"{'_' * distance_up}{py_type}__"
144
- imports.add(f"from .{'.' * distance_up} import {py_type} as {string_alias}")
145
- return string_alias
172
+ import_to_add = f"from .{'.' * distance_up} import {py_type} as {string_alias}"
173
+ imports.add(import_to_add)
174
+ return (string_alias, import_to_add)
146
175
 
147
176
 
148
- def reference_cousin(current_package: list[str], imports: set[str], py_package: list[str], py_type: str) -> str:
177
+ def reference_cousin(
178
+ current_package: list[str], imports: set[str], py_package: list[str], py_type: str
179
+ ) -> tuple[str, str]:
149
180
  """
150
181
  Returns a reference to a python type in a package that is not descendent, ancestor
151
182
  or sibling, and adds the required import that is aliased to avoid name conflicts.
@@ -161,5 +192,6 @@ def reference_cousin(current_package: list[str], imports: set[str], py_package:
161
192
  + "__".join([safe_snake_case(name) for name in py_package[len(shared_ancestry) :]])
162
193
  + "__"
163
194
  )
164
- imports.add(f"from {string_from} import {string_import} as {string_alias}")
165
- return f"{string_alias}.{py_type}"
195
+ import_to_add = f"from {string_from} import {string_import} as {string_alias}"
196
+ imports.add(import_to_add)
197
+ return (f"{string_alias}.{py_type}", import_to_add)
@@ -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,
@@ -80,7 +80,7 @@ import dateutil.parser
80
80
 
81
81
  from ...message_pool import default_message_pool
82
82
 
83
- betterproto2.check_compiler_version("0.6.0")
83
+ betterproto2.check_compiler_version("0.7.0")
84
84
 
85
85
 
86
86
  class FieldCardinality(betterproto2.Enum):
@@ -17,7 +17,7 @@ import betterproto2
17
17
 
18
18
  from ....message_pool import default_message_pool
19
19
 
20
- betterproto2.check_compiler_version("0.6.0")
20
+ betterproto2.check_compiler_version("0.7.0")
21
21
 
22
22
 
23
23
  class CodeGeneratorResponseFeature(betterproto2.Enum):
@@ -34,10 +34,10 @@ from dataclasses import (
34
34
 
35
35
  from betterproto2 import unwrap
36
36
 
37
+ from betterproto2_compiler import casing
37
38
  from betterproto2_compiler.compile.importing import get_type_reference, parse_source_type_name
38
39
  from betterproto2_compiler.compile.naming import (
39
40
  pythonize_class_name,
40
- pythonize_enum_member_name,
41
41
  pythonize_field_name,
42
42
  pythonize_method_name,
43
43
  )
@@ -53,6 +53,7 @@ from betterproto2_compiler.lib.google.protobuf import (
53
53
  MethodDescriptorProto,
54
54
  OneofDescriptorProto,
55
55
  ServiceDescriptorProto,
56
+ SourceCodeInfo,
56
57
  )
57
58
  from betterproto2_compiler.lib.google.protobuf.compiler import CodeGeneratorRequest
58
59
  from betterproto2_compiler.settings import Settings
@@ -216,6 +217,33 @@ class OutputTemplate:
216
217
  """
217
218
  return sorted([f.name for f in self.input_files])
218
219
 
220
+ def get_descriptor_name(self, source_file: FileDescriptorProto):
221
+ return f"{source_file.name.replace('/', '_').replace('.', '_').upper()}_DESCRIPTOR"
222
+
223
+ @property
224
+ def descriptors(self):
225
+ """Google protobuf library descriptors.
226
+
227
+ Returns
228
+ -------
229
+ str
230
+ A list of pool registrations for proto descriptors.
231
+ """
232
+ descriptors: list[str] = []
233
+
234
+ for f in self.input_files:
235
+ # Remove the source_code_info field since it is not needed at runtime.
236
+ source_code_info: SourceCodeInfo | None = f.source_code_info
237
+ f.source_code_info = None
238
+
239
+ descriptors.append(
240
+ f"{self.get_descriptor_name(f)} = default_google_proto_descriptor_pool.AddSerializedFile({bytes(f)})"
241
+ )
242
+
243
+ f.source_code_info = source_code_info
244
+
245
+ return "\n".join(descriptors)
246
+
219
247
 
220
248
  @dataclass(kw_only=True)
221
249
  class MessageCompiler(ProtoContentBase):
@@ -223,6 +251,7 @@ class MessageCompiler(ProtoContentBase):
223
251
 
224
252
  output_file: OutputTemplate
225
253
  proto_obj: DescriptorProto
254
+ prefixed_proto_name: str
226
255
  fields: list["FieldCompiler"] = field(default_factory=list)
227
256
  oneofs: list["OneofCompiler"] = field(default_factory=list)
228
257
  builtins_types: set[str] = field(default_factory=set)
@@ -233,7 +262,7 @@ class MessageCompiler(ProtoContentBase):
233
262
 
234
263
  @property
235
264
  def py_name(self) -> str:
236
- return pythonize_class_name(self.proto_name)
265
+ return pythonize_class_name(self.prefixed_proto_name)
237
266
 
238
267
  @property
239
268
  def deprecated(self) -> bool:
@@ -266,6 +295,17 @@ class MessageCompiler(ProtoContentBase):
266
295
 
267
296
  return methods_source
268
297
 
298
+ @property
299
+ def descriptor_name(self) -> str:
300
+ """Google protobuf library descriptor name.
301
+
302
+ Returns
303
+ -------
304
+ str
305
+ The Python name of the descriptor to reference.
306
+ """
307
+ return self.output_file.get_descriptor_name(self.source_file)
308
+
269
309
 
270
310
  def is_map(proto_field_obj: FieldDescriptorProto, parent_message: DescriptorProto) -> bool:
271
311
  """True if proto_field_obj is a map, otherwise False."""
@@ -562,6 +602,7 @@ class EnumDefinitionCompiler(ProtoContentBase):
562
602
 
563
603
  output_file: OutputTemplate
564
604
  proto_obj: EnumDescriptorProto
605
+ prefixed_proto_name: str
565
606
  entries: list["EnumDefinitionCompiler.EnumEntry"] = field(default_factory=list)
566
607
 
567
608
  @dataclass(unsafe_hash=True, kw_only=True)
@@ -569,32 +610,74 @@ class EnumDefinitionCompiler(ProtoContentBase):
569
610
  """Representation of an Enum entry."""
570
611
 
571
612
  name: str
613
+ proto_name: str
572
614
  value: int
573
615
  comment: str
574
616
 
575
617
  def __post_init__(self) -> None:
576
- # Get entries/allowed values for this Enum
577
618
  self.entries = [
578
619
  self.EnumEntry(
579
- name=pythonize_enum_member_name(entry_proto_value.name, self.proto_obj.name),
620
+ name=entry_proto_value.name,
621
+ proto_name=entry_proto_value.name,
580
622
  value=entry_proto_value.number,
581
623
  comment=get_comment(proto_file=self.source_file, path=self.path + [2, entry_number]),
582
624
  )
583
625
  for entry_number, entry_proto_value in enumerate(self.proto_obj.value)
584
626
  ]
585
627
 
628
+ if not self.entries:
629
+ return
630
+
631
+ # Remove enum prefixes
632
+ enum_name: str = self.proto_obj.name
633
+
634
+ enum_name_reduced = enum_name.replace("_", "").lower()
635
+
636
+ first_entry = self.entries[0].name
637
+
638
+ # Find the potential common prefix
639
+ enum_prefix = ""
640
+ for i in range(len(first_entry)):
641
+ if first_entry[: i + 1].replace("_", "").lower() == enum_name_reduced:
642
+ enum_prefix = f"{first_entry[: i + 1]}_"
643
+ break
644
+
645
+ should_rename = enum_prefix and all(entry.name.startswith(enum_prefix) for entry in self.entries)
646
+
647
+ if should_rename:
648
+ for entry in self.entries:
649
+ entry.name = entry.name[len(enum_prefix) :]
650
+
651
+ for entry in self.entries:
652
+ entry.name = casing.sanitize_name(entry.name)
653
+
586
654
  @property
587
655
  def proto_name(self) -> str:
588
656
  return self.proto_obj.name
589
657
 
590
658
  @property
591
659
  def py_name(self) -> str:
592
- return pythonize_class_name(self.proto_name)
660
+ return pythonize_class_name(self.prefixed_proto_name)
593
661
 
594
662
  @property
595
663
  def deprecated(self) -> bool:
596
664
  return bool(self.proto_obj.options and self.proto_obj.options.deprecated)
597
665
 
666
+ @property
667
+ def descriptor_name(self) -> str:
668
+ """Google protobuf library descriptor name.
669
+
670
+ Returns
671
+ -------
672
+ str
673
+ The Python name of the descriptor to reference.
674
+ """
675
+ return self.output_file.get_descriptor_name(self.source_file)
676
+
677
+ @property
678
+ def has_renamed_entries(self) -> bool:
679
+ return any(entry.proto_name != entry.name for entry in self.entries)
680
+
598
681
 
599
682
  @dataclass(kw_only=True)
600
683
  class ServiceCompiler(ProtoContentBase):
@@ -35,20 +35,21 @@ from .models import (
35
35
 
36
36
  def traverse(
37
37
  proto_file: FileDescriptorProto,
38
- ) -> Generator[tuple[EnumDescriptorProto | DescriptorProto, list[int]], None, None]:
38
+ ) -> Generator[tuple[EnumDescriptorProto | DescriptorProto, list[int], str], None, None]:
39
39
  # Todo: Keep information about nested hierarchy
40
40
  def _traverse(
41
41
  path: list[int],
42
42
  items: list[EnumDescriptorProto] | list[DescriptorProto],
43
43
  prefix: str = "",
44
- ) -> Generator[tuple[EnumDescriptorProto | DescriptorProto, list[int]], None, None]:
44
+ ) -> Generator[tuple[EnumDescriptorProto | DescriptorProto, list[int], str], None, None]:
45
45
  for i, item in enumerate(items):
46
46
  # Adjust the name since we flatten the hierarchy.
47
- # Todo: don't change the name, but include full name in returned tuple
48
47
  should_rename = not isinstance(item, DescriptorProto) or not item.options or not item.options.map_entry
49
48
 
50
- item.name = next_prefix = f"{prefix}.{item.name}" if prefix and should_rename else item.name
51
- yield item, [*path, i]
49
+ # Record prefixed name but *do not* mutate original file.
50
+ # We use this prefixed name to create pythonized names.
51
+ prefixed_name = next_prefix = f"{prefix}.{item.name}" if prefix and should_rename else item.name
52
+ yield item, [*path, i], prefixed_name
52
53
 
53
54
  if isinstance(item, DescriptorProto):
54
55
  # Get nested types.
@@ -81,6 +82,7 @@ def get_settings(plugin_options: list[str]) -> Settings:
81
82
 
82
83
  return Settings(
83
84
  pydantic_dataclasses="pydantic_dataclasses" in plugin_options,
85
+ google_protobuf_descriptors="google_protobuf_descriptors" in plugin_options,
84
86
  client_generation=client_generation,
85
87
  server_generation=server_generation,
86
88
  )
@@ -109,12 +111,13 @@ def generate_code(request: CodeGeneratorRequest) -> CodeGeneratorResponse:
109
111
  # get the references to input/output messages for each service
110
112
  for output_package_name, output_package in request_data.output_packages.items():
111
113
  for proto_input_file in output_package.input_files:
112
- for item, path in traverse(proto_input_file):
114
+ for item, path, prefixed_proto_name in traverse(proto_input_file):
113
115
  read_protobuf_type(
114
116
  source_file=proto_input_file,
115
117
  item=item,
116
118
  path=path,
117
119
  output_package=output_package,
120
+ prefixed_proto_name=prefixed_proto_name,
118
121
  )
119
122
 
120
123
  # Read Services
@@ -168,6 +171,15 @@ def generate_code(request: CodeGeneratorRequest) -> CodeGeneratorResponse:
168
171
  )
169
172
  )
170
173
 
174
+ if settings.google_protobuf_descriptors:
175
+ response.file.append(
176
+ CodeGeneratorResponseFile(
177
+ name="google_proto_descriptor_pool.py",
178
+ content="from google.protobuf import descriptor_pool\n\n"
179
+ + "default_google_proto_descriptor_pool = descriptor_pool.DescriptorPool()\n",
180
+ )
181
+ )
182
+
171
183
  for output_package_name in sorted(output_paths.union(init_files)):
172
184
  print(f"Writing {output_package_name}", file=sys.stderr)
173
185
 
@@ -179,6 +191,7 @@ def read_protobuf_type(
179
191
  path: list[int],
180
192
  source_file: "FileDescriptorProto",
181
193
  output_package: OutputTemplate,
194
+ prefixed_proto_name: str,
182
195
  ) -> None:
183
196
  if isinstance(item, DescriptorProto):
184
197
  if item.options and item.options.map_entry:
@@ -188,10 +201,11 @@ def read_protobuf_type(
188
201
  message_data = MessageCompiler(
189
202
  source_file=source_file,
190
203
  output_file=output_package,
204
+ prefixed_proto_name=prefixed_proto_name,
191
205
  proto_obj=item,
192
206
  path=path,
193
207
  )
194
- output_package.messages[message_data.proto_name] = message_data
208
+ output_package.messages[message_data.prefixed_proto_name] = message_data
195
209
 
196
210
  for index, field in enumerate(item.field):
197
211
  if is_map(field, item):
@@ -243,10 +257,11 @@ def read_protobuf_type(
243
257
  enum = EnumDefinitionCompiler(
244
258
  source_file=source_file,
245
259
  output_file=output_package,
260
+ prefixed_proto_name=prefixed_proto_name,
246
261
  proto_obj=item,
247
262
  path=path,
248
263
  )
249
- output_package.enums[enum.proto_name] = enum
264
+ output_package.enums[enum.prefixed_proto_name] = enum
250
265
 
251
266
 
252
267
  def read_protobuf_service(
@@ -68,6 +68,7 @@ class ServerGeneration(StrEnum):
68
68
  @dataclass
69
69
  class Settings:
70
70
  pydantic_dataclasses: bool
71
+ google_protobuf_descriptors: bool
71
72
 
72
73
  client_generation: ClientGeneration
73
74
  server_generation: ServerGeneration
@@ -32,12 +32,19 @@ import betterproto2
32
32
  from betterproto2.grpc.grpclib_server import ServiceBase
33
33
  import grpc
34
34
  import grpclib
35
+ from google.protobuf.descriptor import Descriptor, EnumDescriptor
35
36
 
36
37
  {# Import the message pool of the generated code. #}
37
38
  {% if output_file.package %}
38
39
  from {{ "." * output_file.package.count(".") }}..message_pool import default_message_pool
40
+ {% if output_file.settings.google_protobuf_descriptors %}
41
+ from {{ "." * output_file.package.count(".") }}..google_proto_descriptor_pool import default_google_proto_descriptor_pool
42
+ {% endif %}
39
43
  {% else %}
40
44
  from .message_pool import default_message_pool
45
+ {% if output_file.settings.google_protobuf_descriptors %}
46
+ from .google_proto_descriptor_pool import default_google_proto_descriptor_pool
47
+ {% endif %}
41
48
  {% endif %}
42
49
 
43
50
  if TYPE_CHECKING:
@@ -45,4 +52,5 @@ if TYPE_CHECKING:
45
52
  from betterproto2.grpc.grpclib_client import MetadataLike
46
53
  from grpclib.metadata import Deadline
47
54
 
48
- betterproto2.check_compiler_version("{{ version }}")
55
+ _COMPILER_VERSION="{{ version }}"
56
+ betterproto2.check_compiler_version(_COMPILER_VERSION)