Skip to content
This repository was archived by the owner on Feb 23, 2026. It is now read-only.

Commit ac98abe

Browse files
committed
Address review feedback
1 parent 0fff4e5 commit ac98abe

1 file changed

Lines changed: 40 additions & 23 deletions

File tree

proto/message.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -377,12 +377,12 @@ def to_json(
377377
instance,
378378
*,
379379
use_integers_for_enums=True,
380-
including_default_value_fields=True,
380+
including_default_value_fields=None,
381381
preserving_proto_field_name=False,
382382
sort_keys=False,
383383
indent=2,
384384
float_precision=None,
385-
always_print_fields_with_no_presence=True,
385+
always_print_fields_with_no_presence=None,
386386
) -> str:
387387
"""Given a message instance, serialize it to json
388388
@@ -395,8 +395,8 @@ def to_json(
395395
including_default_value_fields (Optional(bool)): Deprecated. Use argument
396396
`always_print_fields_with_no_presence` instead. An option that
397397
determines whether the default field values should be included in the results.
398-
Default is True. If `always_print_fields_with_no_presence` is set to False, this
399-
option has no effect.
398+
This value must match `always_print_fields_with_no_presence`,
399+
if both arguments are explictly set.
400400
preserving_proto_field_name (Optional(bool)): An option that
401401
determines whether field name representations preserve
402402
proto case (snake_case) or use lowerCamelCase. Default is False.
@@ -410,18 +410,30 @@ def to_json(
410410
always_print_fields_with_no_presence (Optional(bool)): If True, fields without
411411
presence (implicit presence scalars, repeated fields, and map fields) will
412412
always be serialized. Any field that supports presence is not affected by
413-
this option (including singular message fields and oneof fields). If
414-
`including_default_value_fields` is set to False, this option has no effect.
413+
this option (including singular message fields and oneof fields).
414+
This value must match `including_default_value_fields`,
415+
if both arguments are explictly set.
415416
Returns:
416417
str: The json string representation of the protocol buffer.
417418
"""
419+
418420
# For backwards compatibility of this breaking change in protobuf 5.x which is specific to proto2
419421
# https://github.com/protocolbuffers/protobuf/commit/26995798757fbfef5cf6648610848e389db1fecf
422+
if always_print_fields_with_no_presence is not None and including_default_value_fields is not None and always_print_fields_with_no_presence != including_default_value_fields:
423+
raise ValueError("Arguments `always_print_fields_with_no_presence` and `including_default_value_fields` must match")
424+
425+
# By default, fields with no presense will be included in the results
426+
# when both `always_print_fields_with_no_presence` and `including_default_value_fields` are not set
427+
if always_print_fields_with_no_presence is None and including_default_value_fields is None:
428+
print_fields = True
429+
else:
430+
print_fields = always_print_fields_with_no_presence or including_default_value_fields
431+
420432
if PROTOBUF_VERSION[0] in ("3", "4"):
421433
return MessageToJson(
422434
cls.pb(instance),
423435
use_integers_for_enums=use_integers_for_enums,
424-
including_default_value_fields=including_default_value_fields,
436+
including_default_value_fields=print_fields,
425437
preserving_proto_field_name=preserving_proto_field_name,
426438
sort_keys=sort_keys,
427439
indent=indent,
@@ -435,10 +447,7 @@ def to_json(
435447
return MessageToJson(
436448
cls.pb(instance),
437449
use_integers_for_enums=use_integers_for_enums,
438-
always_print_fields_with_no_presence=(
439-
including_default_value_fields
440-
and always_print_fields_with_no_presence
441-
),
450+
always_print_fields_with_no_presence=print_fields,
442451
preserving_proto_field_name=preserving_proto_field_name,
443452
sort_keys=sort_keys,
444453
indent=indent,
@@ -468,15 +477,15 @@ def to_dict(
468477
*,
469478
use_integers_for_enums=True,
470479
preserving_proto_field_name=True,
471-
including_default_value_fields=True,
480+
including_default_value_fields=None,
472481
float_precision=None,
473-
always_print_fields_with_no_presence=True,
482+
always_print_fields_with_no_presence=None,
474483
) -> "Message":
475484
"""Given a message instance, return its representation as a python dict.
476485
477486
Args:
478487
instance: An instance of this message type, or something
479-
compatible (accepted by the type's constructor).
488+
compatible (accepted by the type's constructor).
480489
use_integers_for_enums (Optional(bool)): An option that determines whether enum
481490
values should be represented by strings (False) or integers (True).
482491
Default is True.
@@ -486,27 +495,38 @@ def to_dict(
486495
including_default_value_fields (Optional(bool)): Deprecated. Use argument
487496
`always_print_fields_with_no_presence` instead. An option that
488497
determines whether the default field values should be included in the results.
489-
Default is True. If `always_print_fields_with_no_presence` is set to False, this
490-
option has no effect.
498+
This value must match `always_print_fields_with_no_presence`,
499+
if both arguments are explictly set.
491500
float_precision (Optional(int)): If set, use this to specify float field valid digits.
492501
Default is None.
493502
always_print_fields_with_no_presence (Optional(bool)): If True, fields without
494503
presence (implicit presence scalars, repeated fields, and map fields) will
495504
always be serialized. Any field that supports presence is not affected by
496-
this option (including singular message fields and oneof fields). If
497-
`including_default_value_fields` is set to False, this option has no effect.
505+
this option (including singular message fields and oneof fields). This value
506+
must match `including_default_value_fields`, if both arguments are explictly set.
498507
499508
Returns:
500509
dict: A representation of the protocol buffer using pythonic data structures.
501510
Messages and map fields are represented as dicts,
502511
repeated fields are represented as lists.
503512
"""
513+
504514
# For backwards compatibility of this breaking change in protobuf 5.x which is specific to proto2
505515
# https://github.com/protocolbuffers/protobuf/commit/26995798757fbfef5cf6648610848e389db1fecf
516+
if always_print_fields_with_no_presence is not None and including_default_value_fields is not None and always_print_fields_with_no_presence != including_default_value_fields:
517+
raise ValueError("Arguments `always_print_fields_with_no_presence` and `including_default_value_fields` must match")
518+
519+
# By default, fields with no presense will be included in the results
520+
# when both `always_print_fields_with_no_presence` and `including_default_value_fields` are not set
521+
if always_print_fields_with_no_presence is None and including_default_value_fields is None:
522+
print_fields = True
523+
else:
524+
print_fields = always_print_fields_with_no_presence or including_default_value_fields
525+
506526
if PROTOBUF_VERSION[0] in ("3", "4"):
507527
return MessageToDict(
508528
cls.pb(instance),
509-
including_default_value_fields=including_default_value_fields,
529+
including_default_value_fields=print_fields,
510530
preserving_proto_field_name=preserving_proto_field_name,
511531
use_integers_for_enums=use_integers_for_enums,
512532
float_precision=float_precision,
@@ -518,10 +538,7 @@ def to_dict(
518538
# The old flag accidentally had inconsistent behavior between proto2 optional and proto3 optional fields
519539
return MessageToDict(
520540
cls.pb(instance),
521-
always_print_fields_with_no_presence=(
522-
including_default_value_fields
523-
and always_print_fields_with_no_presence
524-
),
541+
always_print_fields_with_no_presence=print_fields,
525542
preserving_proto_field_name=preserving_proto_field_name,
526543
use_integers_for_enums=use_integers_for_enums,
527544
float_precision=float_precision,

0 commit comments

Comments
 (0)