Python 3.8.0a1 变更日志精读:海象运算符、PEP 563 与 885 项变更的首个 Alpha 版本
【免费下载链接】cpythonThe Python programming language项目地址: https://gitcode.com/GitHub_Trending/cp/cpython
变更日志文件 记录了 CPython 3.8 开发线在 3.8.0a1(2019-02-03 发布)这个里程碑前落地的全部 885 项变更,覆盖语言新特性、安全修复、C API 调整与构建系统增强。本文以这份官方 NEWS 文档为主体骨架,逐节梳理其收录内容,并结合当前仓库中的源码路径印证各条目对应的真实实现位置,帮助你在追溯 Python 3.8 演进历史、理解 walrus 运算符与安全加固来龙去脉时,能直接定位到证据文件。
文档的定位与结构:NEWS.d 机制
CPython 的变更历史采用“一条记录一个条目”的结构化 NEWS 格式存放于 Misc/NEWS.d/ 目录。3.8.0a1 这一个版本就沉淀了约 8978 行、885 条记录,每个条目前部都带有四段机器可读的元数据:
.. bpo: 35746 .. date: 2019-01-15-18-16-05 .. nonce: nMSd0j .. section: Securitybpo:指向 bug 追踪编号;date:是条目创建时间戳,nonce:是防止重复合并的随机码;section:声明分类。统计本文件中的section标记可以还原该版本的变更画像:
| 分类 | 条目数 |
|---|---|
| Library | 428 |
| Core and Builtins | 159 |
| IDLE | 59 |
| Documentation | 57 |
| Tests | 49 |
| Windows | 40 |
| Build | 37 |
| C API | 22 |
| Security | 12 |
| Tools/Demos | 12 |
| macOS | 10 |
同目录下还存放着 3.5 至 3.15 各版本的 NEWS 归档以及待发布的 Misc/NEWS.d/next/ 暂存区,形成了完整的版本变更档案。而 Doc/whatsnew/3.8.rst 则明确写道:维护者会定期通读Misc/NEWS来撰写 What's New,完整性以 NEWS 为准。因此这份 a1 日志既是发布记录,也是研究 3.8 特性诞生的原始素材。
语言新特性:walrus 运算符与注解体系成形
PEP 572:赋值表达式(海象运算符)
本版本最重磅的语言特性是 PEP 572 的实现。变更日志 中写道:
Implement PEP 572 (assignment expressions). Patch by Emily Morehouse.
该条目(bpo: 35224,2018-11-13)引入了新的:=语法,允许在更大表达式内部完成赋值。后续条目继续打磨这一语法:bpo: 35877 让 while 语句中的命名表达式可以省略括号(Misc/NEWS.d/3.8.0a1.rst#L129-L135),即while chunk := f.read(8192):这类惯用写法在 a1 中已经可用。Doc/whatsnew/3.8.rst 的开头章节也确认了这一点,并把:=称为“the walrus operator”。解析侧的实现落在 Parser/pegen.c 及其配套的 Grammar/python.gram 中,从源码结构看,命名表达式作为 PEG 语法的一部分由该解析器统一处理。
PEP 563:注解延迟求值
Library 分类中包含 bpo: 42387 相关条目,引入 PEP 563 “Postponed Evaluation of Annotations”:注解在运行时不再被立即求值,而是保留为字符串形式(Misc/NEWS.d/3.8.0a1.rst#L4865)。这一改动让class A: x: "SomeForwardRef"这类前向引用写法得以成立,也为此后 typing 生态的前向引用支持打下基础。
AST 增强:type_comments 与完整位置信息
围绕语法分析能力,本版本有三条值得注意的记录:
- PEP 484 类型注释解析(bpo: 35766):
ast模块新增type_comments参数,可以解析x = 123 # type: int这类注释式类型标注,默认关闭。该条目明确说明这是将第三方 typed_ast 分支的核心功能合入标准库(Misc/NEWS.d/3.8.0a1.rst#L150-L157),对应的接口实现可见 Lib/ast.py 与 Parser/ 下的解析器代码。 - AST 节点增加 end_lineno / end_col_offset(bpo: 33416):所有 AST 节点补充了行尾、列尾信息,条目特别注明“这是 C 层面的不向后兼容变更”(Misc/NEWS.d/3.8.0a1.rst#L171-L177)。
- 位置信息修正:列表推导/生成式/元组的
lineno、col_offset现在指向开括号;被装饰函数与类的位置指向def/class关键字而非第一个装饰器,使 trace 报告更准确。
其他核心语言行为变更
- 注解赋值允许更宽的右侧表达式:
x: Tuple[int, int] = 1, 2(右侧不加括号)成为合法语法(Misc/NEWS.d/3.8.0a1.rst#L139-L146)。 **kwargs重复键报错:当kwargs是含重复键的 mapping 时,func(**kwargs)将抛错,与 3.6 起显式重复关键字参数的行为保持一致(Misc/NEWS.d/3.8.0a1.rst#L191-L199)。- 字面量上使用
is产生 SyntaxWarning:编译器对x is 1、x is "abc"这类身份比较发出SyntaxWarning,提示改用==(Misc/NEWS.d/3.8.0a1.rst#L598-L607),这是 CPython 向其他实现语义靠拢的一次重要护栏。 - f-string 语法错误信息改进:括号不匹配的 f-string 现在能给出更友好的报错(bpo: 35494)。
Security 分类:12 项安全加固逐条解读
本文件收录了 12 条.. section: Security记录,是理解 3.8 早期安全姿态的关键样本。按主题归纳如下。
SSL/TLS 相关(占安全条目的一半)
- CVE-2019-5010:证书解析器空指针解引用(bpo: 35746):SSL 模块的证书解析器未正确处理 CRL 分发点中为空的 DP 或 URI,恶意或有缺陷的证书可导致段错误。该漏洞由 Cisco 的 Colin Read 与 Nicolas Edet 报告(TALOS-2018-0758),见 Misc/NEWS.d/3.8.0a1.rst#L7-L10。修复落点即 Modules/_ssl.c 中调用 OpenSSL 证书解析的路径。
- _ssl 错误处理的线程安全(bpo: 32533):修复了 _ssl 中错误处理的线程安全问题。
- 加固 LibreSSL 侧 CVE-2018-8970 防御(bpo: 33136):调用
X509_VERIFY_PARAM_set1_host()时显式传入 namelen,并新增测试确保不允许 NULL 字节,防止主机名校验被绕过。 - Windows 构建升级 OpenSSL 1.1.0i(bpo: 34405):随附安全更新。
- SNI 允许用户自行做 IDN 编解码(bpo: 28414):ssl 模块允许使用者在使用 SNI(服务器名称指示)时自行处理国际化域名编解码,把 IDNA 策略的控制权交还给应用层。
XML 生态的环境变量与外部实体攻击面
- xml.sax / xml.dom 不再受环境变量劫持(bpo: 34791):当
-E或-I设置了sys.flags.ignore_environment时,xml.sax与xml.dom.domreg不再允许通过环境变量覆盖解析器实现,关闭了一个可被环境污染的攻击入口。 - 默认停止处理外部实体(bpo: 17239):
xml.sax与xml.dom.minidom的解析器默认不再处理外部实体,外部 DTD 与 ENTITY 声明不再加载文件或发起网络连接,直接削弱 XXE 攻击面。相关实现位于 Lib/xml/sax/ 与 Lib/xml/dom/。
哈希随机化与 ReDoS
- CVE-2018-14647:_elementtree 哈希盐(bpo: 34623):C 加速的
_elementtree模块现在从_Py_HashSecret初始化哈希随机化盐,而非使用 libexpat 默认的 CSPRNG,使 XML 属性名的哈希分布与解释器全局哈希种子一致(Misc/NEWS.d/3.8.0a1.rst#L48-L54)。实现位于 Modules/_elementtree.c。 - difflib 与 poplib 的灾难性回溯(bpo: 32981):两个模块中的正则曾存在 ReDoS 风险(CVE-2018-1060、CVE-2018-1061),已被重构,消除潜在 DOS 向量(Misc/NEWS.d/3.8.0a1.rst#L107-L115)。对应源码即 Lib/difflib.py 与 Lib/poplib.py。
隔离模式与系统调用
-I传播到子进程(bpo: 34812):隔离模式命令行选项现在也会在multiprocessing与distutils派生子进程时被复制;此前只有-E、-s(由-I隐含)会被传递(Misc/NEWS.d/3.8.0a1.rst#L19-L22)。这保证隔离语义在进程边界上不泄漏。- macOS
os.sendfile越界发送(bpo: 33871):使用trailers参数时可能从输入文件发送超出指定数量的字节,已修复。 - Windows
os.symlink缓冲区溢出(bpo: 33001):做了最小修复以防止越界。
Core and Builtins:解释器本体的 159 项修正
这一分类体量仅次于 Library,其中若干条目直接影响解释器可靠性:
- 元组哈希改用 xxHash(bpo: 34751):元组哈希函数改为基于 xxHash,改善了此前病态构造下的碰撞表现,64 位系统上整体哈希质量也有提升(Misc/NEWS.d/3.8.0a1.rst#L642-L650)。实现位于 Objects/tupleobject.c。
- 排序超长列表崩溃修复(bpo: 35623)与字节码窥孔优化器 off-by-one(bpo: 35193):后者指出该越界读取自 Python 3.6、3.7 所有版本一直存在,直到本版本修复——这类条目是回溯历史缺陷时间线的一手证据。
- 内存安全系列:bpo: 35436 修复多处内存分配错误处理;bpo: 35552 修复
PyUnicode_FromFormat的%s/%V与PyBytes_FromFormat的%s在指定 precision 时越界读内存;bpo: 35214 另一条目修复解析字符串末尾截断 unicode 转义(如'\N')时越界读一字节。 - 解释器初始化重构(bpo: 35713):重排 Python 初始化流程,使可用异常与
sys.stderr更早就绪;bpo: 35720 修复了 Modules/main.c 中pymain_parse_cmdline_impl的小内存泄漏——条目直接点名了实现文件。 - 子解释器与 fork(bpo: 34651):只允许主解释器 fork,避免子解释器 fork 波及主解释器运行时状态,这是对 3.8 多解释器(per-interpreter GIL 探索期)方向的防御性约束。
- PYTHONCOERCECLOCALE 行为修正(bpo: 35336):仅在
LC_CTYPE为 "C" 时才强制转换 C locale。 - 信号处理与 pending calls 分离(bpo: 35423):求值循环中的信号触发机制从“pending calls”机制中剥离,无语义变化、性能差异可忽略,但结构上更清晰。
- namedtuple 属性访问提速 1.6 倍(bpo: 32492):为命名元组字段描述符增加 C 快速路径。
此外还有zipimport对哈希 pyc 的处理修复(bpo: 34022,与 PEP 552 哈希基 pyc 配套)、contextvarsC API 改用PyObject*指针类型(bpo: 34762)、property_descr_get的缓存元组优化因在调试模式下可被sys.getobjects观察到并多次导致崩溃而被移除(bpo: 30156)等,均展示了 3.8 开发线对 C 层面正确性的高密度投入。
Build 与工具链:Memory Sanitizer 正式入场
Build 分类的 37 条中,bpo: 35214 的两条记录值得单独展开:
- 解释器与扩展模块补齐注解,使其在 clang Memory Sanitizer 下正常工作;
configure新增--with-memory-sanitizer开关以便构建 MSan 测试版本(Misc/NEWS.d/3.8.0a1.rst#L399-L407); - 针对 posix、socket、time、test_io、test_faulthandler 的 MSan 误报添加构建插桩绕过(Misc/NEWS.d/3.8.0a1.rst#L212-L218)。
从源码结构看,该开关的选项定义可在 configure.ac 中检索到with_memory_sanitizer,配套测试基础设施分布在 Lib/test/ 目录(共 1794 个文件)。同期 Library 分类中的 PEP 552 哈希基 pyc(-X pycache_prefix、-X use_hashed_pyc相关能力)也在本文件中有对应条目(Misc/NEWS.d/3.8.0a1.rst#L3921),二者共同构成 3.8 发布后“不可变 .pyc 部署”故事线的起点。
其他分类速览
- Windows(40 条)/ macOS(10 条):平台相关修复集中于 socket、subprocess、平台路径处理。
- IDLE(59 条):本文件还收录了 IDLE 的批量现代化条目,如 config_key 对话框改用 PEP 8 命名与 ttk 控件(Misc/NEWS.d/3.8.0a1.rst#L8138),对应源码在 Lib/idlelib/。
- C API(22 条):包含移除未使用的
PyParser_SimpleParseStringFilename(bpo: 34653)、修复PyStructSequence_NewType使其创建堆分配 StructSequence(bpo: 34784)等,C 扩展开发者应重点核对。 - Documentation(57 条):包括 PEP 角色化引用(
Replace PEP XYZ by the pep role,Misc/NEWS.d/3.8.0a1.rst#L6237-L6238)、contextvars 模块(PEP 567)文档补全等。 - Tests(49 条):测试框架持续演进,例如 asyncio 测试基础设施相关条目(PEP 567 文档与测试多处呼应)。
如何查阅与引用这份日志
- 全文位于 Misc/NEWS.d/3.8.0a1.rst,条目按
section分组、组内按日期倒序排列,可用grep '^\.\. bpo:'快速统计条目总数(本文件为 885 条),用grep '^\.\. section:'统计分类分布。 - 每条记录的
bpo:编号与 3.8.0a2 及后续版本的日志(如 Misc/NEWS.d/3.8.0a2.rst)首尾相接,可以拼出 3.8 整个开发周期的完整变更链。 - 若需要面向用户的特性叙事而非逐条记录,Doc/whatsnew/3.8.rst 提供了由维护者基于 NEWS 提炼的 3.8 特性总览,两者互为索引。
适用前提:本文所有结论以该 NEWS 文件与当前仓库源码为准;其中部分 C 层面描述(如解释器内部结构)在后续 3.8.x 与更高版本中可能已演进,引用时应注意所对应的确切版本号。
【免费下载链接】cpythonThe Python programming language项目地址: https://gitcode.com/GitHub_Trending/cp/cpython
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考