betterproto2-compiler 0.3.1__py3-none-any.whl → 0.4.0__py3-none-any.whl

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.
@@ -98,7 +98,7 @@ import betterproto2
98
98
 
99
99
  from ...message_pool import default_message_pool
100
100
 
101
- betterproto2.check_compiler_version("0.3.0")
101
+ betterproto2.check_compiler_version("0.4.0")
102
102
 
103
103
 
104
104
  class Edition(betterproto2.Enum):
@@ -22,7 +22,7 @@ import betterproto2
22
22
 
23
23
  from ....message_pool import default_message_pool
24
24
 
25
- betterproto2.check_compiler_version("0.3.0")
25
+ betterproto2.check_compiler_version("0.4.0")
26
26
 
27
27
 
28
28
  class CodeGeneratorResponseFeature(betterproto2.Enum):
@@ -129,7 +129,12 @@ def get_comment(
129
129
  # We don't add this space to the generated file.
130
130
  lines = [line[1:] if line and line[0] == " " else line for line in lines]
131
131
 
132
- return "\n".join(lines)
132
+ comment = "\n".join(lines)
133
+
134
+ # Escape backslashes and triple quotes
135
+ comment = comment.replace("\\", "\\\\").replace('"""', '\\"\\"\\"')
136
+
137
+ return comment
133
138
 
134
139
  return ""
135
140
 
@@ -14,7 +14,7 @@ from betterproto2_compiler.lib.google.protobuf.compiler import (
14
14
  CodeGeneratorResponseFeature,
15
15
  CodeGeneratorResponseFile,
16
16
  )
17
- from betterproto2_compiler.settings import Settings
17
+ from betterproto2_compiler.settings import ClientGeneration, Settings
18
18
 
19
19
  from .compiler import outputfile_compiler
20
20
  from .models import (
@@ -60,8 +60,24 @@ def traverse(
60
60
 
61
61
 
62
62
  def get_settings(plugin_options: list[str]) -> Settings:
63
+ # Synchronous clients are suitable for most users
64
+ client_generation = ClientGeneration.SYNC
65
+
66
+ for opt in plugin_options:
67
+ if opt.startswith("client_generation="):
68
+ name = opt.split("=")[1]
69
+
70
+ # print(ClientGeneration.__members__, file=sys.stderr)
71
+ # print([member.value for member in ClientGeneration])
72
+
73
+ try:
74
+ client_generation = ClientGeneration(name)
75
+ except ValueError:
76
+ raise ValueError(f"Invalid client_generation option: {name}")
77
+
63
78
  return Settings(
64
79
  pydantic_dataclasses="pydantic_dataclasses" in plugin_options,
80
+ client_generation=client_generation,
65
81
  )
66
82
 
67
83
 
@@ -1,6 +1,67 @@
1
+ import sys
1
2
  from dataclasses import dataclass
2
3
 
4
+ if sys.version_info >= (3, 11):
5
+ from enum import StrEnum
6
+ else:
7
+ from strenum import StrEnum
8
+
9
+
10
+ class ClientGeneration(StrEnum):
11
+ NONE = "none"
12
+ """Clients are not generated."""
13
+
14
+ SYNC = "sync"
15
+ """Only synchronous clients are generated."""
16
+
17
+ ASYNC = "async"
18
+ """Only asynchronous clients are generated."""
19
+
20
+ SYNC_ASYNC = "sync_async"
21
+ """Both synchronous and asynchronous clients are generated.
22
+
23
+ The asynchronous client is generated with the Async suffix."""
24
+
25
+ ASYNC_SYNC = "async_sync"
26
+ """Both synchronous and asynchronous clients are generated.
27
+
28
+ The synchronous client is generated with the Sync suffix."""
29
+
30
+ SYNC_ASYNC_NO_DEFAULT = "sync_async_no_default"
31
+ """Both synchronous and asynchronous clients are generated.
32
+
33
+ The synchronous client is generated with the Sync suffix, and the asynchronous client is generated with the Async
34
+ suffix."""
35
+
36
+ @property
37
+ def is_sync_generated(self) -> bool:
38
+ return self in {
39
+ ClientGeneration.SYNC,
40
+ ClientGeneration.SYNC_ASYNC,
41
+ ClientGeneration.ASYNC_SYNC,
42
+ ClientGeneration.SYNC_ASYNC_NO_DEFAULT,
43
+ }
44
+
45
+ @property
46
+ def is_async_generated(self) -> bool:
47
+ return self in {
48
+ ClientGeneration.ASYNC,
49
+ ClientGeneration.SYNC_ASYNC,
50
+ ClientGeneration.ASYNC_SYNC,
51
+ ClientGeneration.SYNC_ASYNC_NO_DEFAULT,
52
+ }
53
+
54
+ @property
55
+ def is_sync_prefixed(self) -> bool:
56
+ return self in {ClientGeneration.ASYNC_SYNC, ClientGeneration.SYNC_ASYNC_NO_DEFAULT}
57
+
58
+ @property
59
+ def is_async_prefixed(self) -> bool:
60
+ return self in {ClientGeneration.SYNC_ASYNC, ClientGeneration.SYNC_ASYNC_NO_DEFAULT}
61
+
3
62
 
4
63
  @dataclass
5
64
  class Settings:
6
65
  pydantic_dataclasses: bool
66
+
67
+ client_generation: ClientGeneration
@@ -21,7 +21,7 @@ __all__ = (
21
21
  import builtins
22
22
  import datetime
23
23
  import warnings
24
- from collections.abc import AsyncIterable, AsyncIterator, Iterable
24
+ from collections.abc import AsyncIterable, AsyncIterator, Iterable, Iterator
25
25
  import typing
26
26
  from typing import TYPE_CHECKING
27
27
 
@@ -33,10 +33,9 @@ from dataclasses import dataclass
33
33
  {% endif %}
34
34
 
35
35
  import betterproto2
36
- {% if output_file.services %}
37
36
  from betterproto2.grpc.grpclib_server import ServiceBase
37
+ import grpc
38
38
  import grpclib
39
- {% endif %}
40
39
 
41
40
  {# Import the message pool of the generated code. #}
42
41
  {% if output_file.package %}
@@ -0,0 +1,32 @@
1
+ class {% block class_name %}{% endblock %}({% block inherit_from %}{% endblock %}):
2
+ {% block service_docstring scoped %}
3
+ {% if service.comment %}
4
+ """
5
+ {{ service.comment | indent(4) }}
6
+ """
7
+ {% elif not service.methods %}
8
+ pass
9
+ {% endif %}
10
+ {% endblock %}
11
+
12
+ {% block class_content %}{% endblock %}
13
+
14
+ {% for method in service.methods %}
15
+ {% block method_definition scoped required %}{% endblock %}
16
+ {% block method_docstring scoped %}
17
+ {% if method.comment %}
18
+ """
19
+ {{ method.comment | indent(8) }}
20
+ """
21
+ {% endif %}
22
+ {% endblock %}
23
+
24
+ {% block deprecation_warning scoped %}
25
+ {% if method.deprecated %}
26
+ warnings.warn("{{ service.py_name }}.{{ method.py_name }} is deprecated", DeprecationWarning)
27
+ {% endif %}
28
+ {% endblock %}
29
+
30
+ {% block method_body scoped required %}{% endblock %}
31
+
32
+ {% endfor %}
@@ -0,0 +1,86 @@
1
+ {% extends "service_stub.py.j2" %}
2
+
3
+ {# Class definition #}
4
+ {% block class_name %}{{ service.py_name }}{% if output_file.settings.client_generation.is_async_prefixed %}Async{% endif %}Stub{% endblock %}
5
+ {% block inherit_from %}betterproto2.ServiceStub{% endblock %}
6
+
7
+ {# Methods definition #}
8
+ {% block method_definition %}
9
+ async def {{ method.py_name }}(self
10
+ {%- if not method.client_streaming -%}
11
+ , message:
12
+ {%- if method.is_input_msg_empty -%}
13
+ "{{ method.py_input_message_type }} | None" = None
14
+ {%- else -%}
15
+ "{{ method.py_input_message_type }}"
16
+ {%- endif -%}
17
+ {%- else -%}
18
+ {# Client streaming: need a request iterator instead #}
19
+ , messages: "AsyncIterable[{{ method.py_input_message_type }}] | Iterable[{{ method.py_input_message_type }}]"
20
+ {%- endif -%}
21
+ ,
22
+ *
23
+ , timeout: "float | None" = None
24
+ , deadline: "Deadline | None" = None
25
+ , metadata: "MetadataLike | None" = None
26
+ ) -> "{% if method.server_streaming %}AsyncIterator[{{ method.py_output_message_type }}]{% else %}{{ method.py_output_message_type }}{% endif %}":
27
+ {% endblock %}
28
+
29
+ {% block method_body %}
30
+ {% if method.server_streaming %}
31
+ {% if method.client_streaming %}
32
+ async for response in self._stream_stream(
33
+ "{{ method.route }}",
34
+ messages,
35
+ {{ method.py_input_message_type }},
36
+ {{ method.py_output_message_type }},
37
+ timeout=timeout,
38
+ deadline=deadline,
39
+ metadata=metadata,
40
+ ):
41
+ yield response
42
+ {% else %}
43
+ {% if method.is_input_msg_empty %}
44
+ if message is None:
45
+ message = {{ method.py_input_message_type }}()
46
+
47
+ {% endif %}
48
+ async for response in self._unary_stream(
49
+ "{{ method.route }}",
50
+ message,
51
+ {{ method.py_output_message_type }},
52
+ timeout=timeout,
53
+ deadline=deadline,
54
+ metadata=metadata,
55
+ ):
56
+ yield response
57
+
58
+ {% endif %}
59
+ {% else %}
60
+ {% if method.client_streaming %}
61
+ return await self._stream_unary(
62
+ "{{ method.route }}",
63
+ messages,
64
+ {{ method.py_input_message_type }},
65
+ {{ method.py_output_message_type }},
66
+ timeout=timeout,
67
+ deadline=deadline,
68
+ metadata=metadata,
69
+ )
70
+ {% else %}
71
+ {% if method.is_input_msg_empty %}
72
+ if message is None:
73
+ message = {{ method.py_input_message_type }}()
74
+
75
+ {% endif %}
76
+ return await self._unary_unary(
77
+ "{{ method.route }}",
78
+ message,
79
+ {{ method.py_output_message_type }},
80
+ timeout=timeout,
81
+ deadline=deadline,
82
+ metadata=metadata,
83
+ )
84
+ {% endif %}
85
+ {% endif %}
86
+ {% endblock %}
@@ -0,0 +1,72 @@
1
+ {% extends "service_stub.py.j2" %}
2
+
3
+ {# Class definition #}
4
+ {% block class_name %}{{ service.py_name }}{% if output_file.settings.client_generation.is_sync_prefixed %}Sync{% endif %}Stub{% endblock %}
5
+
6
+ {% block class_content %}
7
+ {# TODO move to parent class #}
8
+ def __init__(self, channel: grpc.Channel):
9
+ self._channel = channel
10
+ {% endblock %}
11
+
12
+ {# Methods definition #}
13
+ {% block method_definition %}
14
+ def {{ method.py_name }}(self
15
+ {%- if not method.client_streaming -%}
16
+ , message:
17
+ {%- if method.is_input_msg_empty -%}
18
+ "{{ method.py_input_message_type }} | None" = None
19
+ {%- else -%}
20
+ "{{ method.py_input_message_type }}"
21
+ {%- endif -%}
22
+ {%- else -%}
23
+ {# Client streaming: need a request iterator instead #}
24
+ , messages: "Iterable[{{ method.py_input_message_type }}]"
25
+ {%- endif -%}
26
+ ) -> "{% if method.server_streaming %}Iterator[{{ method.py_output_message_type }}]{% else %}{{ method.py_output_message_type }}{% endif %}":
27
+ {% endblock %}
28
+
29
+ {% block method_body %}
30
+ {% if method.server_streaming %}
31
+ {% if method.client_streaming %}
32
+ for response in self._channel.stream_stream(
33
+ "{{ method.route }}",
34
+ {{ method.py_input_message_type }}.SerializeToString,
35
+ {{ method.py_output_message_type }}.FromString,
36
+ )(iter(messages)):
37
+ yield response
38
+ {% else %}
39
+ {% if method.is_input_msg_empty %}
40
+ if message is None:
41
+ message = {{ method.py_input_message_type }}()
42
+
43
+ {% endif %}
44
+ for response in self._channel.unary_stream(
45
+ "{{ method.route }}",
46
+ {{ method.py_input_message_type }}.SerializeToString,
47
+ {{ method.py_output_message_type }}.FromString,
48
+ )(message):
49
+ yield response
50
+
51
+ {% endif %}
52
+ {% else %}
53
+ {% if method.client_streaming %}
54
+ return self._channel.stream_unary(
55
+ "{{ method.route }}",
56
+ {{ method.py_input_message_type }}.SerializeToString,
57
+ {{ method.py_output_message_type }}.FromString,
58
+ )(iter(messages))
59
+ {% else %}
60
+ {% if method.is_input_msg_empty %}
61
+ if message is None:
62
+ message = {{ method.py_input_message_type }}()
63
+
64
+ {% endif %}
65
+ return self._channel.unary_unary(
66
+ "{{ method.route }}",
67
+ {{ method.py_input_message_type }}.SerializeToString,
68
+ {{ method.py_output_message_type }}.FromString,
69
+ )(message)
70
+ {% endif %}
71
+ {% endif %}
72
+ {% endblock %}
@@ -85,103 +85,17 @@ default_message_pool.register_message("{{ output_file.package }}", "{{ message.p
85
85
 
86
86
 
87
87
  {% endfor %}
88
- {% for _, service in output_file.services|dictsort(by="key") %}
89
- class {{ service.py_name }}Stub(betterproto2.ServiceStub):
90
- {% if service.comment %}
91
- """
92
- {{ service.comment | indent(4) }}
93
- """
94
- {% elif not service.methods %}
95
- pass
96
- {% endif %}
97
-
98
- {% for method in service.methods %}
99
- async def {{ method.py_name }}(self
100
- {%- if not method.client_streaming -%}
101
- , message:
102
- {%- if method.is_input_msg_empty -%}
103
- "{{ method.py_input_message_type }} | None" = None
104
- {%- else -%}
105
- "{{ method.py_input_message_type }}"
106
- {%- endif -%}
107
- {%- else -%}
108
- {# Client streaming: need a request iterator instead #}
109
- , messages: "AsyncIterable[{{ method.py_input_message_type }}] | Iterable[{{ method.py_input_message_type }}]"
110
- {%- endif -%}
111
- ,
112
- *
113
- , timeout: "float | None" = None
114
- , deadline: "Deadline | None" = None
115
- , metadata: "MetadataLike | None" = None
116
- ) -> "{% if method.server_streaming %}AsyncIterator[{{ method.py_output_message_type }}]{% else %}{{ method.py_output_message_type }}{% endif %}":
117
- {% if method.comment %}
118
- """
119
- {{ method.comment | indent(8) }}
120
- """
121
- {% endif %}
122
88
 
123
- {% if method.deprecated %}
124
- warnings.warn("{{ service.py_name }}.{{ method.py_name }} is deprecated", DeprecationWarning)
125
- {% endif %}
126
-
127
- {% if method.server_streaming %}
128
- {% if method.client_streaming %}
129
- async for response in self._stream_stream(
130
- "{{ method.route }}",
131
- messages,
132
- {{ method.py_input_message_type }},
133
- {{ method.py_output_message_type }},
134
- timeout=timeout,
135
- deadline=deadline,
136
- metadata=metadata,
137
- ):
138
- yield response
139
- {% else %}{# i.e. not client streaming #}
140
- {% if method.is_input_msg_empty %}
141
- if message is None:
142
- message = {{ method.py_input_message_type }}()
143
-
144
- {% endif %}
145
- async for response in self._unary_stream(
146
- "{{ method.route }}",
147
- message,
148
- {{ method.py_output_message_type }},
149
- timeout=timeout,
150
- deadline=deadline,
151
- metadata=metadata,
152
- ):
153
- yield response
89
+ {% for _, service in output_file.services|dictsort(by="key") %}
154
90
 
155
- {% endif %}{# if client streaming #}
156
- {% else %}{# i.e. not server streaming #}
157
- {% if method.client_streaming %}
158
- return await self._stream_unary(
159
- "{{ method.route }}",
160
- messages,
161
- {{ method.py_input_message_type }},
162
- {{ method.py_output_message_type }},
163
- timeout=timeout,
164
- deadline=deadline,
165
- metadata=metadata,
166
- )
167
- {% else %}{# i.e. not client streaming #}
168
- {% if method.is_input_msg_empty %}
169
- if message is None:
170
- message = {{ method.py_input_message_type }}()
91
+ {% if output_file.settings.client_generation.is_sync_generated %}
92
+ {% include "service_stub_sync.py.j2" %}
93
+ {% endif %}
171
94
 
172
- {% endif %}
173
- return await self._unary_unary(
174
- "{{ method.route }}",
175
- message,
176
- {{ method.py_output_message_type }},
177
- timeout=timeout,
178
- deadline=deadline,
179
- metadata=metadata,
180
- )
181
- {% endif %}{# client streaming #}
182
- {% endif %}
95
+ {% if output_file.settings.client_generation.is_async_generated %}
96
+ {% include "service_stub_async.py.j2" %}
97
+ {% endif %}
183
98
 
184
- {% endfor %}
185
99
  {% endfor %}
186
100
 
187
101
  {% for i in output_file.imports_end %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: betterproto2_compiler
3
- Version: 0.3.1
3
+ Version: 0.4.0
4
4
  Summary: Compiler for betterproto2
5
5
  License: MIT
6
6
  Keywords: protobuf,gRPC,compiler
@@ -13,10 +13,10 @@ Classifier: Programming Language :: Python :: 3.10
13
13
  Classifier: Programming Language :: Python :: 3.11
14
14
  Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
- Requires-Dist: betterproto2 (>=0.3.1,<0.4.0)
17
- Requires-Dist: grpclib (>=0.4.1,<0.5.0)
16
+ Requires-Dist: betterproto2[grpclib] (>=0.4.0,<0.5.0)
18
17
  Requires-Dist: jinja2 (>=3.0.3)
19
18
  Requires-Dist: ruff (>=0.9.3,<0.10.0)
19
+ Requires-Dist: strenum (>=0.4.15,<0.5.0) ; python_version == "3.10"
20
20
  Requires-Dist: typing-extensions (>=4.7.1,<5.0.0)
21
21
  Project-URL: Documentation, https://betterproto.github.io/python-betterproto2-compiler/
22
22
  Project-URL: Repository, https://github.com/betterproto/python-betterproto2-compiler
@@ -9,23 +9,26 @@ betterproto2_compiler/known_types/duration.py,sha256=jy9GPnQTT9qhi12pQDG_ptdFAdm
9
9
  betterproto2_compiler/known_types/timestamp.py,sha256=dUfJmdrVg1NW-zkquAc8kxMH6nqdxQ2x_MKeP4N5ksY,2153
10
10
  betterproto2_compiler/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  betterproto2_compiler/lib/google/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- betterproto2_compiler/lib/google/protobuf/__init__.py,sha256=gjVdLGtwPhNVept742QqpSdf042sKltfZubb-4YYwoc,107931
13
- betterproto2_compiler/lib/google/protobuf/compiler/__init__.py,sha256=LfQnk85-q2R_mc1CmvqkobqHASqDCnG9xOFd0S-O3p4,8906
12
+ betterproto2_compiler/lib/google/protobuf/__init__.py,sha256=g41P4o4VkHjz8ko5ndwZ-1tUaNTMCT29c6Snd9XSoDI,107931
13
+ betterproto2_compiler/lib/google/protobuf/compiler/__init__.py,sha256=bxBif4bFkIAqRQ02lrx1n5Qjwkj_rgrFRogdLUeg-6Q,8906
14
14
  betterproto2_compiler/lib/message_pool.py,sha256=4-cRhhiM6bmfpUJZ8qxc8LEyqHBHpLCcotjbyZxl7JM,71
15
15
  betterproto2_compiler/plugin/__init__.py,sha256=L3pW0b4CvkM5x53x_sYt1kYiSFPO0_vaeH6EQPq9FAM,43
16
16
  betterproto2_compiler/plugin/__main__.py,sha256=vBQ82334kX06ImDbFlPFgiBRiLIinwNk3z8Khs6hd74,31
17
17
  betterproto2_compiler/plugin/compiler.py,sha256=3sPbCtdzjAGftVvoGe5dvxE8uTzJ78hABA-_f-1rEUo,2471
18
18
  betterproto2_compiler/plugin/main.py,sha256=gI2fSWc9U-fn6MOlkLg7iResr2YsXbdOge6SzNWxBAo,1302
19
- betterproto2_compiler/plugin/models.py,sha256=gF3pEBsrzleVRTr1vSYg17k5Ezbe3OSitV0oDsycVWA,20922
19
+ betterproto2_compiler/plugin/models.py,sha256=MIzmnekCuZrzixGthAw9B6p3hXAtk6YYjDLUVIsIs4o,21085
20
20
  betterproto2_compiler/plugin/module_validation.py,sha256=JnP8dSN83eJJVDP_UPJsHzq7E7Md3lah0PnKXDbFW5Q,4808
21
- betterproto2_compiler/plugin/parser.py,sha256=MIA5-pAIJsng59wk3KYEKBARNCsQEQeetnVZk_MhL0I,9349
21
+ betterproto2_compiler/plugin/parser.py,sha256=1u-EeDHH0lRMFIbeHvqpmWiqUVip16cW8eQIhKmevyI,9952
22
22
  betterproto2_compiler/plugin/plugin.bat,sha256=lfLT1WguAXqyerLLsRL6BfHA0RqUE6QG79v-1BYVSpI,48
23
23
  betterproto2_compiler/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- betterproto2_compiler/settings.py,sha256=FQwco5j9ViBXtDYoFqog7SlXhX2YcbgEnFP77znYiwc,94
25
- betterproto2_compiler/templates/header.py.j2,sha256=HrISX0IKmUsVpIlGIT6XlD9e3LgWWPN7jYRpws5_-CY,1609
26
- betterproto2_compiler/templates/template.py.j2,sha256=Wlif_PRN49Hmeh0e8RyYFvrNTcusugysP_sAgBaDA4A,8420
27
- betterproto2_compiler-0.3.1.dist-info/LICENSE.md,sha256=Pgl2pReU-2yw2miGeQ55UFlyzqAZ_EpYVyZ2nWjwRv4,1121
28
- betterproto2_compiler-0.3.1.dist-info/METADATA,sha256=QpKRNrkBszUpS7E08NgQpmEPqyY75urCm30w53ovCdU,1188
29
- betterproto2_compiler-0.3.1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
30
- betterproto2_compiler-0.3.1.dist-info/entry_points.txt,sha256=re3Qg8lLljbVobeeKH2f1FVQZ114wfZkGv3zCZTD8Ok,84
31
- betterproto2_compiler-0.3.1.dist-info/RECORD,,
24
+ betterproto2_compiler/settings.py,sha256=gbMgOQpUoKqxpW1HELnTUR6sntho5IuqWoktRrFNm1M,1871
25
+ betterproto2_compiler/templates/header.py.j2,sha256=u7pIz9DJsFl4CxIGIosd8qPfhOOv1v6XA7nuo__SKPM,1589
26
+ betterproto2_compiler/templates/service_stub.py.j2,sha256=r0AefgNbDCh-iDgFNV7aNx8fNe5kQY-8TNew-T_tUXc,929
27
+ betterproto2_compiler/templates/service_stub_async.py.j2,sha256=JNOAa8FPhzYS5D0zi0DPESVEwAjkdFsVQZ008Qi4JmE,2968
28
+ betterproto2_compiler/templates/service_stub_sync.py.j2,sha256=V7HJIQJEgivX8VEBt7Ju6cXG5FeeCY9QyYMy1kicElM,2642
29
+ betterproto2_compiler/templates/template.py.j2,sha256=-1fpTlu_DCIeios3CHZUzY3b28zcN2QKdkhGtSrFMbg,5344
30
+ betterproto2_compiler-0.4.0.dist-info/LICENSE.md,sha256=Pgl2pReU-2yw2miGeQ55UFlyzqAZ_EpYVyZ2nWjwRv4,1121
31
+ betterproto2_compiler-0.4.0.dist-info/METADATA,sha256=R4sJQ_oMrnS5wcdSq4LVoHhIud-paWgaoq3XAdiES20,1225
32
+ betterproto2_compiler-0.4.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
33
+ betterproto2_compiler-0.4.0.dist-info/entry_points.txt,sha256=re3Qg8lLljbVobeeKH2f1FVQZ114wfZkGv3zCZTD8Ok,84
34
+ betterproto2_compiler-0.4.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.1
2
+ Generator: poetry-core 2.1.2
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any