Files
2026-07-13 13:17:40 +08:00

53 lines
1.9 KiB
Python

import inspect
from google.protobuf.json_format import MessageToDict, MessageToJson
"""
This module provides a compatibility layer for different versions of the protobuf
library.
"""
_protobuf_has_old_arg_name_cached = None
def _protobuf_has_old_arg_name():
"""Cache the inspect result to avoid doing it for every single message."""
global _protobuf_has_old_arg_name_cached
if _protobuf_has_old_arg_name_cached is None:
params = inspect.signature(MessageToDict).parameters
_protobuf_has_old_arg_name_cached = "including_default_value_fields" in params
return _protobuf_has_old_arg_name_cached
def rename_always_print_fields_with_no_presence(kwargs):
"""
Protobuf version 5.26.0rc2 renamed argument for `MessageToDict` and `MessageToJson`:
`including_default_value_fields` -> `always_print_fields_with_no_presence`.
See https://github.com/protocolbuffers/protobuf/commit/06e7caba58ede0220b110b89d08f329e5f8a7537#diff-8de817c14d6a087981503c9aea38730b1b3e98f4e306db5ff9d525c7c304f234L129 # noqa: E501
We choose to always use the new argument name. If user used the old arg, we raise an
error.
If protobuf does not have the new arg name but have the old arg name, we rename our
arg to the old one.
"""
old_arg_name = "including_default_value_fields"
new_arg_name = "always_print_fields_with_no_presence"
if old_arg_name in kwargs:
raise ValueError(f"{old_arg_name} is deprecated, please use {new_arg_name}")
if new_arg_name in kwargs and _protobuf_has_old_arg_name():
kwargs[old_arg_name] = kwargs.pop(new_arg_name)
return kwargs
def message_to_dict(*args, **kwargs):
kwargs = rename_always_print_fields_with_no_presence(kwargs)
return MessageToDict(*args, **kwargs)
def message_to_json(*args, **kwargs):
kwargs = rename_always_print_fields_with_no_presence(kwargs)
return MessageToJson(*args, **kwargs)