betterproto2-compiler 0.5.1__tar.gz → 0.7.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.
- betterproto2_compiler-0.7.0/.gitignore +21 -0
- betterproto2_compiler-0.7.0/PKG-INFO +15 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/pyproject.toml +55 -43
- betterproto2_compiler-0.7.0/pytest.ini +5 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/compile/importing.py +62 -30
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/lib/google/protobuf/__init__.py +1 -1
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/lib/google/protobuf/compiler/__init__.py +1 -1
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/plugin/compiler.py +14 -4
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/plugin/models.py +89 -4
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/plugin/parser.py +23 -8
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/settings.py +1 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/templates/header.py.j2 +12 -10
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/templates/service_stub.py.j2 +1 -1
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/templates/template.py.j2 +27 -4
- betterproto2_compiler-0.7.0/tests/__init__.py +0 -0
- betterproto2_compiler-0.7.0/tests/generate.py +168 -0
- betterproto2_compiler-0.7.0/tests/inputs/any/any.proto +8 -0
- betterproto2_compiler-0.7.0/tests/inputs/bool/bool.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/bytes/bytes.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/casing/casing.proto +20 -0
- betterproto2_compiler-0.7.0/tests/inputs/casing_inner_class/casing_inner_class.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/casing_message_field_uppercase/casing_message_field_uppercase.proto +9 -0
- betterproto2_compiler-0.7.0/tests/inputs/deprecated/deprecated.proto +24 -0
- betterproto2_compiler-0.7.0/tests/inputs/documentation/documentation.proto +62 -0
- betterproto2_compiler-0.7.0/tests/inputs/double/double.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/empty_repeated/empty_repeated.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/empty_service/empty_service.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/encoding_decoding/encoding_decoding.proto +15 -0
- betterproto2_compiler-0.7.0/tests/inputs/entry/entry.proto +20 -0
- betterproto2_compiler-0.7.0/tests/inputs/enum/enum.proto +25 -0
- betterproto2_compiler-0.7.0/tests/inputs/example/example.proto +911 -0
- betterproto2_compiler-0.7.0/tests/inputs/example_service/example_service.proto +24 -0
- betterproto2_compiler-0.7.0/tests/inputs/features/features.proto +107 -0
- betterproto2_compiler-0.7.0/tests/inputs/field_name_identical_to_type/field_name_identical_to_type.proto +13 -0
- betterproto2_compiler-0.7.0/tests/inputs/fixed/fixed.proto +10 -0
- betterproto2_compiler-0.7.0/tests/inputs/float/float.proto +14 -0
- betterproto2_compiler-0.7.0/tests/inputs/google_impl_behavior_equivalence/google_impl_behavior_equivalence.proto +22 -0
- betterproto2_compiler-0.7.0/tests/inputs/googletypes/googletypes.proto +16 -0
- betterproto2_compiler-0.7.0/tests/inputs/googletypes_request/googletypes_request.proto +29 -0
- betterproto2_compiler-0.7.0/tests/inputs/googletypes_response/googletypes_response.proto +23 -0
- betterproto2_compiler-0.7.0/tests/inputs/googletypes_response_embedded/googletypes_response_embedded.proto +26 -0
- betterproto2_compiler-0.7.0/tests/inputs/googletypes_service_returns_empty/googletypes_service_returns_empty.proto +13 -0
- betterproto2_compiler-0.7.0/tests/inputs/googletypes_service_returns_googletype/googletypes_service_returns_googletype.proto +18 -0
- betterproto2_compiler-0.7.0/tests/inputs/googletypes_struct/googletypes_struct.proto +9 -0
- betterproto2_compiler-0.7.0/tests/inputs/googletypes_value/googletypes_value.proto +15 -0
- betterproto2_compiler-0.7.0/tests/inputs/grpc_reflection_v1/reflection.proto +146 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_capitalized_package/capitalized.proto +8 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_capitalized_package/test.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_child_package_from_package/child.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_child_package_from_package/import_child_package_from_package.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_child_package_from_package/package_message.proto +9 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_child_package_from_root/child.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_child_package_from_root/import_child_package_from_root.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_child_scoping_rules/child.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_child_scoping_rules/import_child_scoping_rules.proto +9 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_child_scoping_rules/package.proto +13 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_circular_dependency/import_circular_dependency.proto +30 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_circular_dependency/other.proto +8 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_circular_dependency/root.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_cousin_package/cousin.proto +6 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_cousin_package/test.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_cousin_package_same_name/cousin.proto +6 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_cousin_package_same_name/test.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_nested_child_package_from_root/child.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_nested_child_package_from_root/import_nested_child_package_from_root.proto +9 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_packages_same_name/import_packages_same_name.proto +13 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_packages_same_name/posts_v1.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_packages_same_name/users_v1.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_parent_package_from_child/import_parent_package_from_child.proto +12 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_parent_package_from_child/parent_package_message.proto +6 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_root_package_from_child/child.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_root_package_from_child/root.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_root_sibling/import_root_sibling.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_root_sibling/sibling.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_service_input_message/child_package_request_message.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_service_input_message/import_service_input_message.proto +25 -0
- betterproto2_compiler-0.7.0/tests/inputs/import_service_input_message/request_message.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/int32/int32.proto +10 -0
- betterproto2_compiler-0.7.0/tests/inputs/invalid_field/invalid_field.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/manual_validation/manual_validation.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/map/map.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/mapmessage/mapmessage.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/message_wrapping/message_wrapping.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/namespace_builtin_types/namespace_builtin_types.proto +40 -0
- betterproto2_compiler-0.7.0/tests/inputs/namespace_keywords/namespace_keywords.proto +46 -0
- betterproto2_compiler-0.7.0/tests/inputs/nested/nested.proto +26 -0
- betterproto2_compiler-0.7.0/tests/inputs/nested2/nested2.proto +21 -0
- betterproto2_compiler-0.7.0/tests/inputs/nested2/package.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/nestedtwice/nestedtwice.proto +40 -0
- betterproto2_compiler-0.7.0/tests/inputs/oneof/oneof.proto +23 -0
- betterproto2_compiler-0.7.0/tests/inputs/oneof_default_value_serialization/oneof_default_value_serialization.proto +30 -0
- betterproto2_compiler-0.7.0/tests/inputs/oneof_empty/oneof_empty.proto +17 -0
- betterproto2_compiler-0.7.0/tests/inputs/oneof_enum/oneof_enum.proto +20 -0
- betterproto2_compiler-0.7.0/tests/inputs/pickling/pickling.proto +43 -0
- betterproto2_compiler-0.7.0/tests/inputs/proto3_field_presence/proto3_field_presence.proto +26 -0
- betterproto2_compiler-0.7.0/tests/inputs/proto3_field_presence_oneof/proto3_field_presence_oneof.proto +22 -0
- betterproto2_compiler-0.7.0/tests/inputs/recursivemessage/recursivemessage.proto +15 -0
- betterproto2_compiler-0.7.0/tests/inputs/ref/ref.proto +9 -0
- betterproto2_compiler-0.7.0/tests/inputs/ref/repeatedmessage.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/regression_387/regression_387.proto +12 -0
- betterproto2_compiler-0.7.0/tests/inputs/regression_414/regression_414.proto +9 -0
- betterproto2_compiler-0.7.0/tests/inputs/repeated/repeated.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/repeated_duration_timestamp/repeated_duration_timestamp.proto +12 -0
- betterproto2_compiler-0.7.0/tests/inputs/repeatedmessage/repeatedmessage.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/repeatedpacked/repeatedpacked.proto +9 -0
- betterproto2_compiler-0.7.0/tests/inputs/rpc_empty_input_message/rpc_empty_input_message.proto +13 -0
- betterproto2_compiler-0.7.0/tests/inputs/service/service.proto +35 -0
- betterproto2_compiler-0.7.0/tests/inputs/service_separate_packages/messages.proto +31 -0
- betterproto2_compiler-0.7.0/tests/inputs/service_separate_packages/service.proto +12 -0
- betterproto2_compiler-0.7.0/tests/inputs/service_uppercase/service.proto +16 -0
- betterproto2_compiler-0.7.0/tests/inputs/signed/signed.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/simple_service/simple_service.proto +21 -0
- betterproto2_compiler-0.7.0/tests/inputs/stream_stream/stream_stream.proto +7 -0
- betterproto2_compiler-0.7.0/tests/inputs/timestamp_dict_encode/timestamp_dict_encode.proto +9 -0
- betterproto2_compiler-0.7.0/tests/inputs/unwrap/unwrap.proto +11 -0
- betterproto2_compiler-0.7.0/tests/inputs/validation/validation.proto +20 -0
- betterproto2_compiler-0.7.0/tests/test_casing.py +32 -0
- betterproto2_compiler-0.7.0/tests/test_module_validation.py +105 -0
- betterproto2_compiler-0.7.0/tests/util.py +57 -0
- betterproto2_compiler-0.7.0/uv.lock +1241 -0
- betterproto2_compiler-0.5.1/LICENSE.md +0 -22
- betterproto2_compiler-0.5.1/PKG-INFO +0 -36
- betterproto2_compiler-0.5.1/README.md +0 -11
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/__init__.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/casing.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/compile/__init__.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/compile/naming.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/known_types/__init__.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/known_types/any.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/known_types/duration.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/known_types/google_values.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/known_types/timestamp.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/lib/__init__.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/lib/google/__init__.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/lib/message_pool.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/plugin/__init__.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/plugin/__main__.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/plugin/main.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/plugin/module_validation.py +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/plugin/plugin.bat +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/py.typed +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/templates/service_stub_async.py.j2 +0 -0
- {betterproto2_compiler-0.5.1 → betterproto2_compiler-0.7.0}/src/betterproto2_compiler/templates/service_stub_sync.py.j2 +0 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
.coverage
|
2
|
+
.DS_Store
|
3
|
+
.env
|
4
|
+
.vscode/settings.json
|
5
|
+
.mypy_cache
|
6
|
+
.pytest_cache
|
7
|
+
.python-version
|
8
|
+
build/
|
9
|
+
*/tests/output_*
|
10
|
+
**/__pycache__
|
11
|
+
dist
|
12
|
+
**/*.egg-info
|
13
|
+
output
|
14
|
+
.idea
|
15
|
+
.DS_Store
|
16
|
+
.tox
|
17
|
+
.venv
|
18
|
+
.asv
|
19
|
+
venv
|
20
|
+
.devcontainer
|
21
|
+
.ruff_cache
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: betterproto2_compiler
|
3
|
+
Version: 0.7.0
|
4
|
+
Summary: Compiler for betterproto2
|
5
|
+
Project-URL: Documentation, https://betterproto.github.io/python-betterproto2/
|
6
|
+
Project-URL: Repository, https://github.com/betterproto/python-betterproto2
|
7
|
+
Author-email: Adrien Vannson <adrien.vannson@protonmail.com>, "Daniel G. Taylor" <danielgtaylor@gmail.com>
|
8
|
+
License-Expression: MIT
|
9
|
+
Keywords: compiler,gRPC,protobuf
|
10
|
+
Requires-Python: <4.0,>=3.10
|
11
|
+
Requires-Dist: betterproto2[grpclib]<0.8,>=0.7.0
|
12
|
+
Requires-Dist: jinja2>=3.0.3
|
13
|
+
Requires-Dist: ruff~=0.9.3
|
14
|
+
Requires-Dist: strenum<0.5,>=0.4.15; python_version == '3.10'
|
15
|
+
Requires-Dist: typing-extensions<5,>=4.7.1
|
@@ -1,54 +1,63 @@
|
|
1
1
|
[project]
|
2
2
|
name = "betterproto2_compiler"
|
3
|
-
version = "0.
|
3
|
+
version = "0.7.0"
|
4
4
|
description = "Compiler for betterproto2"
|
5
5
|
authors = [
|
6
6
|
{ name = "Adrien Vannson", email = "adrien.vannson@protonmail.com" },
|
7
7
|
{ name = "Daniel G. Taylor", email = "danielgtaylor@gmail.com" },
|
8
8
|
]
|
9
|
-
readme = "README.md"
|
10
|
-
keywords = ["protobuf", "gRPC", "compiler"]
|
11
9
|
license = "MIT"
|
10
|
+
keywords = [
|
11
|
+
"protobuf",
|
12
|
+
"gRPC",
|
13
|
+
"compiler",
|
14
|
+
]
|
12
15
|
requires-python = ">=3.10,<4.0"
|
13
|
-
|
16
|
+
dependencies = [
|
17
|
+
# TODO use the version from the current repo?
|
18
|
+
"betterproto2[grpclib]>=0.7.0,<0.8",
|
19
|
+
"ruff~=0.9.3",
|
20
|
+
"jinja2>=3.0.3",
|
21
|
+
"typing-extensions>=4.7.1,<5",
|
22
|
+
"strenum>=0.4.15,<0.5 ; python_version == '3.10'",
|
23
|
+
]
|
14
24
|
|
15
25
|
[project.urls]
|
16
|
-
Documentation = "https://betterproto.github.io/python-betterproto2
|
17
|
-
Repository = "https://github.com/betterproto/python-betterproto2
|
26
|
+
Documentation = "https://betterproto.github.io/python-betterproto2/"
|
27
|
+
Repository = "https://github.com/betterproto/python-betterproto2"
|
18
28
|
|
19
29
|
[project.scripts]
|
20
30
|
protoc-gen-python_betterproto2 = "betterproto2_compiler.plugin:main"
|
21
31
|
|
22
|
-
[
|
23
|
-
|
24
|
-
|
32
|
+
[dependency-groups]
|
33
|
+
dev = [
|
34
|
+
"pre-commit>=2.17.0,<3",
|
35
|
+
"grpcio-tools>=1.54.2,<2",
|
36
|
+
"poethepoet>=0.32.2,<0.33",
|
37
|
+
"pyright>=1.1.391,<2",
|
38
|
+
"ipykernel>=6.29.5,<7",
|
25
39
|
]
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
betterproto2 = { version = "^0.5.1", extras = ["grpclib"] }
|
30
|
-
# betterproto2 = { git="https://github.com/betterproto/python-betterproto2" }
|
31
|
-
# betterproto2 = { path = "../python-betterproto2", extras = ["grpclib"] }
|
32
|
-
# The Ruff version is pinned. To update it, also update it in .pre-commit-config.yaml
|
33
|
-
ruff = "~0.9.3"
|
34
|
-
jinja2 = ">=3.0.3"
|
35
|
-
typing-extensions = "^4.7.1"
|
36
|
-
strenum = [
|
37
|
-
{version = "^0.4.15", python = "=3.10"},
|
40
|
+
test = [
|
41
|
+
"pytest>=8.3.4,<9",
|
42
|
+
"protobuf>=5.29.3,<6",
|
38
43
|
]
|
39
44
|
|
40
|
-
[tool.
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
[tool.uv]
|
46
|
+
package = true
|
47
|
+
default-groups = "all"
|
48
|
+
|
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"
|
48
57
|
|
49
|
-
[
|
50
|
-
|
51
|
-
|
58
|
+
[build-system]
|
59
|
+
requires = ["hatchling"]
|
60
|
+
build-backend = "hatchling.build"
|
52
61
|
|
53
62
|
[tool.ruff]
|
54
63
|
extend-exclude = ["tests/output_*", "src/betterproto2_compiler/lib"]
|
@@ -71,12 +80,9 @@ select = [
|
|
71
80
|
"I",
|
72
81
|
]
|
73
82
|
|
74
|
-
|
75
83
|
[tool.ruff.lint.isort]
|
76
84
|
combine-as-imports = true
|
77
85
|
|
78
|
-
# Dev workflow tasks
|
79
|
-
|
80
86
|
[tool.poe.tasks.test]
|
81
87
|
cmd = "pytest"
|
82
88
|
help = "Run tests"
|
@@ -116,6 +122,20 @@ python -m grpc.tools.protoc \
|
|
116
122
|
google/protobuf/timestamp.proto \
|
117
123
|
google/protobuf/type.proto \
|
118
124
|
google/protobuf/wrappers.proto
|
125
|
+
|
126
|
+
python -m grpc.tools.protoc \
|
127
|
+
--python_betterproto2_out=tests/output_betterproto_descriptor \
|
128
|
+
--python_betterproto2_opt=google_protobuf_descriptors \
|
129
|
+
google/protobuf/any.proto \
|
130
|
+
google/protobuf/api.proto \
|
131
|
+
google/protobuf/duration.proto \
|
132
|
+
google/protobuf/empty.proto \
|
133
|
+
google/protobuf/field_mask.proto \
|
134
|
+
google/protobuf/source_context.proto \
|
135
|
+
google/protobuf/struct.proto \
|
136
|
+
google/protobuf/timestamp.proto \
|
137
|
+
google/protobuf/type.proto \
|
138
|
+
google/protobuf/wrappers.proto
|
119
139
|
"""
|
120
140
|
|
121
141
|
[tool.poe.tasks.typecheck]
|
@@ -146,14 +166,6 @@ help = "Check that the source code is formatted"
|
|
146
166
|
cmd = "ruff check src tests"
|
147
167
|
help = "Check the code with the Ruff linter"
|
148
168
|
|
149
|
-
[tool.poe.tasks.serve-docs]
|
150
|
-
cmd = "mkdocs serve"
|
151
|
-
help = "Serve the documentation locally"
|
152
|
-
|
153
|
-
[build-system]
|
154
|
-
requires = ["poetry-core>=2.0.0,<3"]
|
155
|
-
build-backend = "poetry.core.masonry.api"
|
156
|
-
|
157
169
|
# python -m grpc.tools.protoc \
|
158
170
|
# --python_betterproto2_out=src/lib2 \
|
159
171
|
# google/protobuf/any.proto \
|
@@ -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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
99
|
-
|
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(
|
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 = "_
|
120
|
-
|
121
|
-
|
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
|
-
|
124
|
-
|
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(
|
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
|
-
|
141
|
-
|
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
|
-
|
145
|
-
|
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(
|
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
|
-
|
165
|
-
|
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)
|
@@ -33,17 +33,27 @@ def outputfile_compiler(output_file: OutputTemplate) -> str:
|
|
33
33
|
loader=jinja2.FileSystemLoader(templates_folder),
|
34
34
|
undefined=jinja2.StrictUndefined,
|
35
35
|
)
|
36
|
-
|
36
|
+
|
37
|
+
# List of the symbols that should appear in the `__all__` variable of the file
|
38
|
+
all: list[str] = []
|
39
|
+
|
40
|
+
def add_to_all(name: str) -> str:
|
41
|
+
all.append(name)
|
42
|
+
return name
|
43
|
+
|
44
|
+
env.filters["add_to_all"] = add_to_all
|
45
|
+
|
37
46
|
body_template = env.get_template("template.py.j2")
|
38
47
|
header_template = env.get_template("header.py.j2")
|
39
48
|
|
49
|
+
# Load the body first do know the symbols defined in the file
|
40
50
|
code = body_template.render(output_file=output_file)
|
41
|
-
code = header_template.render(output_file=output_file, version=version) + "\n" + code
|
51
|
+
code = header_template.render(output_file=output_file, version=version, all=all) + "\n" + code
|
42
52
|
|
43
53
|
try:
|
44
|
-
# Sort imports, delete unused ones
|
54
|
+
# Sort imports, delete unused ones, sort __all__
|
45
55
|
code = subprocess.check_output(
|
46
|
-
["ruff", "check", "--select", "I,F401,
|
56
|
+
["ruff", "check", "--select", "I,F401,TC005,RUF022", "--fix", "--silent", "-"],
|
47
57
|
input=code,
|
48
58
|
encoding="utf-8",
|
49
59
|
)
|
@@ -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.
|
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."""
|
@@ -353,8 +393,7 @@ class FieldCompiler(ProtoContentBase):
|
|
353
393
|
|
354
394
|
@property
|
355
395
|
def field_type(self) -> FieldType:
|
356
|
-
|
357
|
-
return FieldType(self.proto_obj.type)
|
396
|
+
return self.proto_obj.type
|
358
397
|
|
359
398
|
@property
|
360
399
|
def packed(self) -> bool:
|
@@ -411,12 +450,46 @@ class FieldCompiler(ProtoContentBase):
|
|
411
450
|
def unwrapped_py_type(self) -> str:
|
412
451
|
return self._py_type(wrap=False)
|
413
452
|
|
453
|
+
@property
|
454
|
+
def annotations(self) -> list[str]:
|
455
|
+
"""List of the Pydantic annotation to add to the field."""
|
456
|
+
assert self.output_file.settings.pydantic_dataclasses
|
457
|
+
|
458
|
+
annotations = []
|
459
|
+
|
460
|
+
if self.proto_obj.type in (FieldType.TYPE_INT32, FieldType.TYPE_SFIXED32, FieldType.TYPE_SINT32):
|
461
|
+
annotations.append("pydantic.Field(ge=-2**31, le=2**31 - 1)")
|
462
|
+
|
463
|
+
elif self.proto_obj.type in (FieldType.TYPE_UINT32, FieldType.TYPE_FIXED32):
|
464
|
+
annotations.append("pydantic.Field(ge=0, le=2**32 - 1)")
|
465
|
+
|
466
|
+
elif self.proto_obj.type in (FieldType.TYPE_INT64, FieldType.TYPE_SFIXED64, FieldType.TYPE_SINT64):
|
467
|
+
annotations.append("pydantic.Field(ge=-2**63, le=2**63 - 1)")
|
468
|
+
|
469
|
+
elif self.proto_obj.type in (FieldType.TYPE_UINT64, FieldType.TYPE_FIXED64):
|
470
|
+
annotations.append("pydantic.Field(ge=0, le=2**64 - 1)")
|
471
|
+
|
472
|
+
elif self.proto_obj.type == FieldType.TYPE_FLOAT:
|
473
|
+
annotations.append("pydantic.AfterValidator(betterproto2.validators.validate_float32)")
|
474
|
+
|
475
|
+
elif self.proto_obj.type == FieldType.TYPE_STRING:
|
476
|
+
annotations.append("pydantic.AfterValidator(betterproto2.validators.validate_string)")
|
477
|
+
|
478
|
+
return annotations
|
479
|
+
|
414
480
|
@property
|
415
481
|
def annotation(self) -> str:
|
416
482
|
py_type = self.py_type
|
417
483
|
|
418
484
|
if self.use_builtins:
|
419
485
|
py_type = f"builtins.{py_type}"
|
486
|
+
|
487
|
+
# Add the pydantic annotation if needed
|
488
|
+
if self.output_file.settings.pydantic_dataclasses:
|
489
|
+
annotations = self.annotations
|
490
|
+
if annotations:
|
491
|
+
py_type = f"typing.Annotated[{py_type}, {', '.join(annotations)}]"
|
492
|
+
|
420
493
|
if self.repeated:
|
421
494
|
return f"list[{py_type}]"
|
422
495
|
if self.optional:
|
@@ -529,6 +602,7 @@ class EnumDefinitionCompiler(ProtoContentBase):
|
|
529
602
|
|
530
603
|
output_file: OutputTemplate
|
531
604
|
proto_obj: EnumDescriptorProto
|
605
|
+
prefixed_proto_name: str
|
532
606
|
entries: list["EnumDefinitionCompiler.EnumEntry"] = field(default_factory=list)
|
533
607
|
|
534
608
|
@dataclass(unsafe_hash=True, kw_only=True)
|
@@ -556,12 +630,23 @@ class EnumDefinitionCompiler(ProtoContentBase):
|
|
556
630
|
|
557
631
|
@property
|
558
632
|
def py_name(self) -> str:
|
559
|
-
return pythonize_class_name(self.
|
633
|
+
return pythonize_class_name(self.prefixed_proto_name)
|
560
634
|
|
561
635
|
@property
|
562
636
|
def deprecated(self) -> bool:
|
563
637
|
return bool(self.proto_obj.options and self.proto_obj.options.deprecated)
|
564
638
|
|
639
|
+
@property
|
640
|
+
def descriptor_name(self) -> str:
|
641
|
+
"""Google protobuf library descriptor name.
|
642
|
+
|
643
|
+
Returns
|
644
|
+
-------
|
645
|
+
str
|
646
|
+
The Python name of the descriptor to reference.
|
647
|
+
"""
|
648
|
+
return self.output_file.get_descriptor_name(self.source_file)
|
649
|
+
|
565
650
|
|
566
651
|
@dataclass(kw_only=True)
|
567
652
|
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
|
-
|
51
|
-
|
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.
|
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.
|
264
|
+
output_package.enums[enum.prefixed_proto_name] = enum
|
250
265
|
|
251
266
|
|
252
267
|
def read_protobuf_service(
|