版本 26.x 新闻公告

Protocol Buffers 26.x 版本变更公告。

以下公告特定于 2024 年 3 月 13 日发布的 26.x 版本。有关按时间顺序排列的信息,请参阅新闻

常规变更

JSON 格式化程序选项变更

从 26.x 系列开始,用于打印具有默认值字段的 JSON 格式化程序选项将被一种固定的方式取代,以一致地处理 proto2 和 proto3 的 optional 字段。

  • Java:includingDefaultValueFields() 被替换为 alwaysPrintFieldsWithNoPresence()
  • C++:always_print_default_values 被替换为 always_print_fields_with_no_presence=True
  • Py:including_default_value_fields=True 被替换为 always_print_fields_with_no_presence=True

新标志在 proto3 消息上的行为与旧标志完全相同,但不再适用于 proto2 的 optional 字段。旧标志适用于 proto2 的 optional 字段,但不适用于 proto3 的 optional 字段。

对生成代码/运行时不匹配进行“投毒”

根据我们的跨版本运行时保证,Protobuf 不支持跨主版本边界混合使用生成的代码和运行时,也不支持在单个主运行时版本内将较新版本的 protoc 生成的代码与较旧的运行时混合使用。我们计划引入“毒丸”(poison pills)来检测和强制执行这些不允许的不匹配情况。

这不被视为一项重大变更,因为它只是增加了对现有策略的执行,但可能需要用户更新其生成的代码。

C++ 重大变更

在 v26 中,我们计划根据我们的重大变更政策版本支持政策对 C++ 进行主版本升级。

以下各节概述了我们计划在 Protocol Buffers 26.0 版本中包含的一系列重大变更。请注意,计划可能会发生变化。这些是需要注意的潜在重大变更,但它们可能不会在这个特定版本中发生,或者根本不会发生。

移除 repeated 字段上已废弃的 clear API

以下已废弃的方法将被移除:

  • RepeatedPtrField::ReleaseCleared()
  • RepeatedPtrField::ClearedCount()
  • RepeatedPtrField::AddCleared()

移除 C++ 旧版语法描述符 API

随着版本(editions)的发布,语法不再支持用于业务逻辑。相反,应使用定义在 descriptor.h 中的各种特性辅助函数来查询更具针对性的行为,例如在 C++ 中使用 has_presence 来查询特性。

移除已废弃的语法访问器

我们计划在 v26 中移除已废弃的语法访问器 FileDescriptor::Syntax。我们建议改用 FileDescriptor::edition 的 getter 方法。

移除已废弃的 SupportsUnknownEnumValues 方法

SupportsUnknownEnumValues 方法已于 2023 年 3 月被废弃。我们计划在 v26 中移除它。

移除 std::string 错误收集器重载

我们计划移除错误收集器中已废弃的 std::string 方法。

Java 重大变更

在 v26 中,我们计划根据我们的重大变更政策版本支持政策对 Java 进行主版本升级。

以下各节概述了我们计划在 Protocol Buffers 26.0 版本中包含的一系列重大变更。请注意,计划可能会发生变化。这些是需要注意的潜在重大变更,但它们可能不会在这个特定版本中发生,或者根本不会发生。

与旧版生成代码的兼容性中断

v26.x 将中断与旧主版本生成的代码的兼容性。用户应重新生成旧代码,使其与当前版本一致。

例如,最初为兼容 v3.x.x 运行时与 v2.x.x 生成的代码而引入的 GeneratedMessageV3,将被重命名为 GeneratedMessage。运行时将被更新以支持版本(Editions),这将与旧的生成代码不兼容。

这符合我们现有的跨版本运行时保证,并且是一项重大变更。

移除已废弃的方法/变量

v26.x 将移除对已废弃方法和变量的访问。这些通常在之前的版本中已经被标记为 @Deprecated

这将移除对以下(非详尽)列表的访问:

  • 描述符语法 API,应替换为相应的特性访问器(例如 FieldDescriptor.hasPresence()EnumDescriptor.isClosed())。

  • TextFormat 的 print 方法,应替换为相应的 TextFormat.printer() 方法。

  • PARSER 变量,应替换为 parser() 方法。

  • 用于兼容旧版 v2.x.x 生成代码的运行时方法。根据我们的跨版本运行时保证,这已不再受支持。

更多细节将在相应的版本说明中提供。

PHP 重大变更

计划在 26.x 系列中进行以下变更:

  • 在 setter 中验证字符串字段的 UTF-8 编码。
  • 移除通用服务。(提交 40ad3fa

Python 重大变更

在 v26 中,我们计划根据我们的重大变更政策版本支持政策对 Python 进行主版本升级。

计划在 26.x 系列中进行以下变更:

  • 使 str(msg) 对字符串字段中的任何无效 UTF-8 进行转义。
  • 使 text_format.MessageToString() 默认输出原始 UTF-8,同时对任何无效的 UTF-8 序列进行转义。
  • 修复时间戳边界问题。(提交 1250d5f

移除已废弃的 API

在 26.x 版本中,以下已废弃的 API 将被移除:

拒绝使用非迭代对象扩展 repeated 字段

从 26.x 版本开始,使用 None 可迭代对象扩展 repeated 字段将被拒绝(将引发 TypeError)。例如,m.repeated_int32.extend(None) 将被拒绝。

移除 message 类中的 RegisterExtension

从 26.x 版本开始,RegisterExtension 将被移除。您可以在 Python 中使用消息对象上的 Extensions 属性来访问扩展。

这会影响纯 Python 和 Python 的 C++ 实现,但不影响 upb Python。

从 GitHub 中移除 setup.pysetup.cfg 支持

在 26.x 版本中,setup.pysetup.cfg 将不再存在于GitHub 仓库python/ 目录或 GitHub 发布压缩包中。这意味着将无法再直接从 GitHub 仓库或发布压缩包构建 Python 包。

发布在 PyPI 上的 Python 源码包的顶层目录中仍将包含一个 setup.py。对于不想使用我们在 PyPI 上分发的二进制包的用户,这是构建 Python 二进制包所支持和推荐的方式。

更多信息,请参阅 #15671

时间戳会进行有效性检查

在 v26 中,系统将检查 Timestamp 值是否有效。秒数必须在 [-62135596800, 253402300799] 范围内,纳秒数必须在 [0, 999999999] 范围内。超出这些范围的值将引发异常。

移除已废弃的语法访问器

我们计划在 v26 中移除已废弃的语法访问器 FileDescriptor.syntax,并计划用 FileDescriptor.edition 取而代之。

移除 UnknownFields 支持

在 v25 中,message.UnknownFields() 在纯 Python 和 C++ 扩展中被废弃。我们计划在 v26 中将其移除。请使用 unknown_fields.py 中新的 UnknownFieldSet(message) 支持作为替代。

有关所有这些变更的更多细节将在相应的版本说明中提供。

Ruby 重大变更

  • 修复 RepeatedField#each_index 以使其具有正确的语义。(#11767
  • 移除 Ruby DSL 及相关的兼容性代码,这将完成四月份宣布的迁移
  • Message#to_h 修复:
    • 移除未设置的 oneof 字段。(#6167
    • 移除未设置的子消息字段。
  • encode_json/decode_json 使用消息的池。
  • 移除已废弃的语法访问器 FileDescriptor.syntax,并用语义检查取而代之:
    • FieldDescriptor.has_presence 用于测试字段是否存在。
    • FieldDescriptor.is_packed 用于测试 repeated 字段是否为 packed。
    • FieldDescriptor.requires_utf8_validation 用于测试字符串字段是否需要 UTF-8 验证。
    • EnumDescriptor.is_closed 用于测试枚举是否为 closed。

Ruby 中的 Freeze 现在是递归的

从 26.x 系列开始,当应用 freeze 时,它将递归应用,影响所有子消息、map 和 repeated 字段。

upb 重大变更

计划在 26.x 系列中进行以下变更: