版本 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.py
和 setup.cfg
支持
在 26.x 版本中,setup.py
和 setup.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 系列中进行以下变更:
- 修复在启用
IgnoreUnknownEnumString
时 JSON 解析中的不一致行为。