You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+64-7Lines changed: 64 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -168,19 +168,75 @@ Both serializing and parsing are supported to/from JSON and Python dictionaries
168
168
169
169
Sometimes it is useful to be able to determine whether a message has been sent on the wire. This is how the Google wrapper types work to let you know whether a value is unset, set as the default (zero value), or set as something else, for example.
170
170
171
-
Use `Message().serialized_on_wire` to determine if it was sent. This is a little bit different from the official Google generated Python code:
171
+
Use `betterproto.serialized_on_wire(message)` to determine if it was sent. This is a little bit different from the official Google generated Python code, and it lives outside the generated `Message` class to prevent name clashes. Note that it **only** supports Proto 3 and thus can **only** be used to check if `Message` fields are set. You cannot check if a scalar was sent on the wire.
Protobuf supports grouping fields in a `oneof` clause. Only one of the fields in the group may be set at a given time. For example, given the proto:
184
+
185
+
```protobuf
186
+
syntax = "proto3";
187
+
188
+
message Test {
189
+
oneof foo {
190
+
bool on = 1;
191
+
int32 count = 2;
192
+
string name = 3;
193
+
}
194
+
}
195
+
```
196
+
197
+
You can use `betterproto.which_one_of(message, group_name)` to determine which of the fields was set. It returns a tuple of the field name and value, or a blank string and `None` if unset.
198
+
199
+
```py
200
+
>>> test = Test()
201
+
>>> betterproto.which_one_of(test, "foo")
202
+
["", None]
203
+
204
+
>>> test.on =True
205
+
>>> betterproto.which_one_of(test, "foo")
206
+
["on", True]
207
+
208
+
# Setting one member of the group resets the others.
209
+
>>> test.count =57
210
+
>>> betterproto.which_one_of(test, "foo")
211
+
["count", 57]
212
+
>>> test.on
213
+
False
214
+
215
+
# Default (zero) values also work.
216
+
>>> test.name =""
217
+
>>> betterproto.which_one_of(test, "foo")
218
+
["name", ""]
219
+
>>> test.count
220
+
0
221
+
>>> test.on
222
+
False
223
+
```
224
+
225
+
Again this is a little different than the official Google code generator:
226
+
227
+
```py
228
+
# Old way (official Google protobuf package)
229
+
>>> message.WhichOneof("group")
230
+
"foo"
231
+
232
+
# New way (this project)
233
+
>>> betterproto.which_one_of(message, "group")
234
+
["foo", "foo's value"]
179
235
```
180
236
181
237
## Development
182
238
183
-
First, make sure you have Python 3.7+ and `pipenv` installed:
239
+
First, make sure you have Python 3.7+ and `pipenv` installed, along with the official [Protobuf Compiler](https://github.com/protocolbuffers/protobuf/releases) for your platform. Then:
184
240
185
241
```sh
186
242
# Get set up with the virtual env & dependencies
@@ -224,10 +280,10 @@ $ pipenv run tests
224
280
-[x] Refs to nested types
225
281
-[x] Imports in proto files
226
282
-[x] Well-known Google types
227
-
-[] OneOf support
283
+
-[x] OneOf support
228
284
-[x] Basic support on the wire
229
-
-[] Check which was set from the group
230
-
-[] Setting one unsets the others
285
+
-[x] Check which was set from the group
286
+
-[x] Setting one unsets the others
231
287
-[ ] JSON that isn't completely naive.
232
288
-[x] 64-bit ints as strings
233
289
-[x] Maps
@@ -236,14 +292,15 @@ $ pipenv run tests
236
292
-[ ] Any support
237
293
-[x] Enum strings
238
294
-[ ] Well known types support (timestamp, duration, wrappers)
295
+
-[ ] Support different casing (orig vs. camel vs. others?)
239
296
-[ ] Async service stubs
240
297
-[x] Unary-unary
241
298
-[x] Server streaming response
242
299
-[ ] Client streaming request
243
300
-[ ] Renaming messages and fields to conform to Python name standards
244
301
-[ ] Renaming clashes with language keywords and standard library top-level packages
0 commit comments