2024 年 11 月 7 日宣布的变更

于 2024 年 11 月 7 日宣布的 Protocol Buffers 相关变更。

以下章节涵盖了计划在 v30 版本(预计 2025 年第一季度发布)中进行的破坏性变更。此外,还包括一些非破坏性但可能需要您采取行动的变更。这些是10 月 2 日新闻文章中提到的变更之外的补充。

这些内容描述了我们预期的变更实现方式,但由于软件的灵活性,其中一些变更可能最终不会落地,或者可能与本文中的描述有所不同。

在 Arena 上清除 Oneof 消息后引入 ASAN Poisoning

此项变更增加了一项强化检查,会影响使用 Arena 的 C++ protobuf。在 protobuf Arena 上分配的 Oneof 消息现在将在调试模式下被清除,并在 ASAN 模式下被“投毒”(poisoned)。调用 clear 后,未来尝试使用该内存区域将在 ASAN 中导致崩溃,并报告为 use-after-free 错误。

此实现需要 C++17

Python map 字段的 setdefault 行为变更

从 v30 开始,setdefault 对于 ScalarMap 的行为将与 dict 类似,但键和值都必须设置。对于 MessageMapssetdefault 将被拒绝。

移除已弃用的 py_proto_library 宏

protobuf.bzl 中已弃用的内部 Bazel 宏 py_proto_library 将在 v30.x 中被移除。

它应被官方的 py_proto_library 替代,后者将从 v29.x 开始移至 protobuf 的 bazel/py_proto_library 中。在 v29.x 之前,此实现位于 rules_python 中。

Python 嵌套消息类的 __qualname__ 包含外部消息名称

Python 嵌套消息类的 __qualname__ 现在包含外部消息的名称。在 v30 之前,对于嵌套消息,__qualname____name__ 的结果相同,即不包含外部消息的名称。

例如:

message Foo {
  message Bar {
    bool bool_field = 1;
  }
}
nested = test_pb2.Foo.Bar()
self.assertEqual('Bar', nested.__class__.__name__)
self.assertEqual('Foo.Bar', nested.__class__.__qualname__) # It was 'Bar' before

停止发布 C++ CocoaPods 版本

在 v30 中,我们将停止发布 C++ CocoaPods 版本,该版本自 v4.x.x 起就已损坏。C++ 用户应直接使用我们的 GitHub release

Ruby 和 PHP 在 JSON 解析中的错误

v30 修复了 JSON 解析中对数字字段内字符串的不合规行为,使其符合 JSON 规范

此修复不会伴随主版本号的提升,但 Ruby 和 PHP 现在将对数字字段中的非数字字符串(例如“”、“12abc”、“abc”)引发错误。v29.x 将针对这些错误情况包含一个警告。