
CPython 3.8.0a3 变更全解从空字典提速到 IDNA 安全加固的 80 余项改进【免费下载链接】cpythonThe Python programming language项目地址: https://gitcode.com/GitHub_Trending/cp/cpythonCPython 3.8.0a3第三个 Alpha 里程碑2019-03-25 发布是 3.8 开发周期中变更密度极高的一次快照它一次性引入了ast.parse(feature_version...)语法兼容开关、解释器级状态字典PyInterpreterState_GetDict()、statistics.NormalDist的分位数与重叠系数计算、tarfile 默认格式切换为 POSIX pax 等新功能同时修复了大量内存泄漏、崩溃与安全缺陷。本文以本仓库中的官方变更记录 Misc/NEWS.d/3.8.0a3.rst 为骨架逐节梳理这些变更并结合当前仓库源码Include/、Python/、Lib/等验证底层实现帮助读者理解每个条目背后的原理与影响面。一、如何读懂这份变更记录blurb 格式说明本文件位于 Misc/NEWS.d/3.8.0a3.rst采用 CPython 的blurb 格式每个条目由一组 RST 指令directive元数据加一段正文组成例如.. bpo: 36216 .. date: 2019-03-06-09-38-40 .. nonce: 6q1m4a .. release date: 2019-03-25 .. section: Security Changes urlsplit() to raise ValueError when ...各字段含义如下字段含义bpo对应的 bugs.python.org 问题编号后迁移至 GitHub issuedate变更合入主线的 UTC 时间戳nonce保证条目唯一性的随机标识release date该文件所属里程碑的正式发布日期3.8.0a3 为 2019-03-25section分类Security、Core and Builtins、Library、Documentation、Tests、Build、Windows、IDLE、Tools/Demos、C API整个 3.8 版本的 NEWS 最终由Misc/NEWS.d目录下所有此类文件合并生成。下文按 section 分类逐项解读条目编号即对应bpo号便于回溯原始 issue。二、安全修复Security2.1 urlsplit() 拒绝 IDNA 分解可改变解析结果的 URLbpo-36216urllib.parse.urlsplit()现在会在 URL 包含在 IDNA 编码NFKC 规范化下分解成会影响 URL 解析方式字符时抛出ValueError。这类字符经过 NFKC 规范化后可能变为/、、:等解析分隔符从而让攻击者构造出肉眼看起来安全、解析后却指向另一地址的 URL例如把字符全角斜杠混入主机名部分。该修复位于标准库urllib.parse的解析入口确保解析行为与浏览器、代理等下游组件的 IDNA 处理一致。2.2 cookiejar 域名后缀匹配不再串发 Cookiebpo-35121二次修复使用http.cookiejar.DefaultCookiePolicy时若域名 A 是域名 B 的后缀匹配例如example.com之于sub.example.com原先无Domain属性的 A 域 Cookie 可能会被错误地发送给 B 域。本次修复保证不带 Domain 属性的 Cookie 绝不因后缀匹配而跨域发送。同一问题的路径前缀匹配缺陷请求路径是 Cookie path 的前缀但未以/结尾时不应发送该 Cookie也在 Library 部分以 bpo-35121 二次合入补丁作者均为 Karthikeyan Singaravelan。三、核心与内建Core and Builtins本节共 24 项变更覆盖解释器初始化、内存管理、解析器、编译与数值转换是本次发布的技术重头。3.1 内存安全三处崩溃/泄漏修复bpo内容涉及代码36421修复_ctypes.c中PyCArrayType_new()可能的双重减引用double decrefModules/_ctypes36412修复创建新字典时可能的崩溃Objects/dictobject.c36398修复structseq_repr()可能的崩溃Objects/structseq.c36374修复merge_consts_recursive()可能的空指针解引用Zackery Spytz 补丁Python/compile.c其中 bpo-36398 与repr 长度限制相关联repr(structseq)原先被截断在 512 字节bpo-36365 已解除该限制而structseq_repr()的崩溃正是在构造超长 repr 字符串时暴露的缓冲区/引用处理缺陷。3.2 解释器初始化健壮性bpo-36236 / 36352 / 36301 / 36333bpo-36236初始化时若当前目录已被删除则不再把该目录前缀加到sys.path避免产生指向不存在路径的条目。bpo-36352初始化路径过长时由静默截断改为直接报错退出防止后续因路径被截断产生难以排查的行为。bpo-36301启动时若pybuilddir.txt配置文件解码失败初始化直接失败而非静默跳过保证构建目录信息错误能被尽早发现。bpo-36333修复_PyRuntimeState_Fini中的内存泄漏Stéphane Wirtel 贡献涉及运行时全局状态收尾时的资源释放。3.3 解析器与语法引擎的现代化bpo-35808 / 36332 / 35975bpo-35808 是 3.8 开发期的重要架构动作正式退役 pgen旧的 LL(1) 解析器生成器改用修改版 pgen2 生成解析器Pablo Galindo 补丁。这为后续 PEG 解析器3.9 全面启用铺平了道路本仓库Parser/目录中现已演进为 Parser/parser.c Grammar/python.gram 的 PEG 体系。bpo-35975 引入feature_version语法兼容开关ast.parse()公开与compile()隐藏参数新增feature_version可让解析器按旧版语法解析代码。尤其当feature_version为 5 或 6 时恢复 PEP 492 的async/await关键字兼容 hack为 7 及以上时两者无条件视为关键字但仍作为特殊 token 而非NAME由解析器驱动识别。当前主线中 Lib/ast.py 的实现如下def parse(source, filenameunknown, modeexec, *, type_commentsFalse, feature_versionNone, optimize-1, moduleNone): ... if feature_version is None: feature_version -1 elif isinstance(feature_version, tuple): major, minor feature_version # Should be a 2-tuple. if major ! 3: raise ValueError(fUnsupported major version: {major}) feature_version minor # Else it should be an int giving the minor version for 3.x. return compile(source, filename, mode, flags, _feature_versionfeature_version, optimizeoptimize, modulemodule)即feature_version可传整数如6或二元组如(3, 6)最终以 minor 版本号传入 C 层解析器。bpo-36332内建compile()现在能直接处理包含赋值表达式walrus:的 AST 对象——此前这类 AST 在compile阶段会出错因为赋值表达式语法是 3.8 新增特性PEP 572编译器对 AST 输入的语义分析路径需同步支持。3.4 字典空 dict 更小更快bpo-30040新创建的空字典不再过度分配此前{}会立即分配可扩容的条目表内存占用高于dict.clear()后的空字典。本变更统一了两者行为空 dict 创建/销毁速度约提升 2 倍Inada Naoki 补丁。这也解释了后续dictobject.c中空字典共享/惰性分配优化的起点相关实现位于 Objects/dictobject.c。3.5 数值与转换语义bpo-36262 / 36048 / 36218bpo-36262修复_Py_dg_strtod()David Gay 算法移植在字符串转浮点时极低概率的内存泄漏该函数被float(str)、complex(str)、pickle.load、marshal.load等广泛使用位于 Python/dtoa.h 对应的 dtoa 实现。bpo-36048隐式数字到 C 整数的转换改用__index__而非__int____int__用于隐式转换被弃用。这是__index__PEP 357语义的收口只有真正可索引的整数语义对象才应参与隐式 C 整数转换避免__int__返回非整数时的歧义。bpo-36218修复对异构值列表排序时的段错误Rémi Lapeyre 与 Elliot Gorokhovsky 补丁。当列表元素类型混杂如 int 与 str时比较操作会走对象协议并在某些对象布局下触发崩溃修复位于 Objects/listobject.c 的listsort实现。3.6 解释器级状态字典PyInterpreterState_GetDictbpo-36124新增解释器级interpreter-specific字典并通过 C-APIPyInterpreterState_GetDict()暴露与既有PyThreadState_GetDict()平行。两者的差异在于作用域粒度PyThreadState_GetDict()按线程状态隔离PyInterpreterState_GetDict()按解释器隔离同一解释器内多线程共享。当前主线的声明与实现分别在 Include/pystate.h 与 Python/pystate.cPyObject * PyInterpreterState_GetDict(PyInterpreterState *interp) { if (interp-dict NULL) { interp-dict PyDict_New(); if (interp-dict NULL) { PyErr_Clear(); } } /* Returning NULL means no per-interpreter dict is available. */ return interp-dict; }即按需惰性创建内存分配失败时返回 NULL 而不抛异常。NEWS 条目同时给出明确指引扩展模块应继续使用PyModule_GetState()管理各自的 per-interpreter 状态而非依赖该全局字典。3.7 其余核心修复bpo内容36256修复 parsermodule 在 DFA 中出现两条同标签弧时解析状态异常Pablo Galindo 补丁36365repr(structseq)不再限制为 512 字节36282若干内建函数位置参数过多的报错信息改进36252Unicode 数据库升级至12.0.0对应 Modules/unicodedata.c 依赖的 Objects/unicodetype_db.h 数据36188清理 Python 2 unbound method 在方法对象与文档中的遗留痕迹Martijn Pieters 补丁31904VxWorks 平台改用UTF-8 作为系统编码VxWorks 系列支持贯穿本版本 Build/Windows 多节四、标准库Library本节约 35 项是数量最多的分类。以下按主题聚类。4.1 统计学NormalDist 新增 inv_cdf 与 overlapbpo-36324 / 36169statistics.NormalDist新增两个实用方法当前实现位于 Lib/statistics.pyinv_cdf(p)逆累积分布函数又称百分点函数/分位数函数返回满足P(X x) p的xp必须满足0.0 p 1.0否则抛StatisticsError。quantiles()方法即基于它实现def inv_cdf(self, p): if p 0.0 or p 1.0: raise StatisticsError(p must be in the range 0.0 p 1.0) return _normal_dist_inv_cdf(p, self._mu, self._sigma) def quantiles(self, n4): return [self.inv_cdf(i / n) for i in range(1, n)]overlap(other)计算两个正态分布的重叠系数OVLoverlapping coefficient返回值在 0.01.0 之间度量两条概率密度函数曲线下的重叠面积。实现依据 Inman Bradley 的经典论文dx.doi.org/10.1080/03610928908830127并对other做类型检查、对 σ0 情形抛StatisticsError。文档示例 N1 NormalDist(2.4, 1.6) N2 NormalDist(3.2, 2.0) N1.overlap(N2) 0.80350506573302054.2 tarfile 默认格式切换为 POSIX paxbpo-36268写 tar 包的默认格式由 GNU 私有格式切换为 POSIX.1-2001 pax 标准C.A.M. Gerlach 贡献。这一改动影响所有未显式指定format的tarfile.open(..., w)调用。当前主线 Lib/tarfile.py 中PAX_FORMAT 2 # POSIX.1-2001 (pax) format DEFAULT_FORMAT PAX_FORMATpax 格式扩展为 GNU tar 的通用替代能记录超长文件名、超大文件与更丰富的元数据跨平台互操作性优于 GNU 格式也更符合 POSIX 标准族。4.3 模块与函数新能力pprintbpo-30670新增pprint.pp默认按字典插入顺序排序键进行美化打印同时为pprint.pprint、pprint.pformat、pprint.PrettyPrinter新增sort_dicts参数Rémi Lapeyre 贡献。unittest.mockbpo-21269mock call 对象新增args与kwargs属性便于直接取用调用参数。mock.create_autospecbpo-21478由create_autospec创建的子函数上的调用现在会传播到父 mock使child.call_args等断言在父级可观察。astbpo-36280ast.Constant新增kind字段字面量带u前缀Python 2 风格 unicode 字面量时为u否则为None。multiprocessingbpo-35493 / 35715multiprocessing.Pool改用multiprocessing.connection.wait替代每 0.2 秒轮询Pablo Galindo 补丁ProcessPoolExecutor._process_worker的返回值在使用后及时释放以回收内存。enumbpo-35899修复 Enum 处理空字符串与非拉丁字符如α、א时崩溃的问题。venvbpo-35661虚拟环境提示符prompt写入pyvenv.cfgactivate脚本据此设置 shell 提示符。pyclbrbpo-36298模块找不到时抛ModuleNotFoundError而非静默返回。mmapbpo-36139关闭mmap对象时释放 GIL避免大映射区域 munmap 阻塞其他线程。4.4 性能与 I/O 行为调整shutilbpo-36103shutil.copyfileobj()默认缓冲区由16 KiB 提升至 64 KiB非 Windows 平台降低系统调用开销Inada Naoki 贡献。当前主线 Lib/shutil.py 已进一步演进为COPY_BUFSIZE 1024 * 1024 if _WINDOWS else 256 * 1024可见该条目的优化方向在后续版本得到延续。shutil.copytreebpo-35652修复copy_function...被错误传入DirEntry而非路径字符串的问题。tarfile 之外ensurepip更新为pip 19.0.3 与 setuptools 40.8.0bpo-35807。4.5 Cookie、URL 与网络相关FileCookieJarbpo-36043支持 path-like 对象Stéphane Wirtel 贡献。bpo-35121请求路径是 Cookie path 属性的前缀匹配但未以/结尾时不再发送该 Cookie与前文 Security 节同号条目的路径维度互补。4.6 日志、调试器与警告loggingbpo-36272不再静默吞掉RecursionErrorRémi Lapeyre 补丁。pdbbpo-35931 / 36130debug命令优雅处理所有异常修复skip...进入无__name__全局变量的帧时出错Anthony Sottile 补丁。warningsbpo-35178自定义warnings.formatwarning可以接收line作为位置参数基于 Tashrif Billah 的补丁。rebpo-36251修复stderrprinter与re.Match的 repr 格式字符串Stephan Hohe 补丁。4.7 编码、类型与杂项编码移除unicode_internalcodec 正式移除3.3 起弃用Inada Naoki 补丁。typingbpo-36320typing.NamedTuple弃用_field_types改用承载相同信息的__annotations__两者均由 OrderedDict 改为普通 dict。collectionsbpo-36321namedtuple属性拼写错误_fields_defaults修正为_field_defaults与typing.NamedTuple一致为兼容旧代码两个拼写同时创建错误拼写未来可能移除。asynciobpo-34745修复 SSL 场景下循环引用导致的内存问题。arraybpo-36285修复整数溢出Stephan Hohe 补丁。distutilsbpo-36235customize_compiler()在CFLAGS环境变量已定义时不再用OPT覆盖它。math/信号bpo-36106消除与 libmsinpi()的潜在名称冲突Dmitrii Pasechnik 补丁。typesbpo-36091清理Lib/types中对 async generator 的过时引用。importlibbpo-35843为_NamespacePath实现__getitem__Anthony Sottile 补丁。osbpo-35802清理对恒存在的os.stat/os.lstat/os.chmod的存在性检查。VxWorksbpo-31904新增_signal模块支持。AIXbpo-35198修复 C 扩展编译。hashlibbpo-36179修复_hashopenssl两处仅在 OOM 时出现的引用泄漏。五、文档、测试与构建5.1 文档Documentationbpo-36329make -C Doc/ serve执行Tools/scripts/serve.py时声明 Python 解释器路径。bpo-36138改进datetime.timedelta转标量scalars的文档说明。bpo-21314Programming FAQ 核心语言部分新增条目解释函数签名中的斜杠/PEP 457 positional-only 参数标记用法。5.2 测试Testsbpo-36234test_posix.PosixUidGidTests新增无效 uid/gid 类型str的测试。bpo-29571修复test_re.test_locale_flag()改用locale.getpreferredencoding()获取 locale 编码某些 locale 下locale.getlocale()返回错误编码。bpo-36123修复test_socket中的竞态条件。5.3 构建Buildbpo-36356修复配置了 address sanitizer 时因泄漏导致的构建失败。bpo-36146setup.py新增TEST_EXTENSIONS常量可跳过_testcapi等测试扩展的构建同时修复 macOS 上/usr/include/ffi仅应加入_ctypes的 include 路径而非所有扩展。bpo-31904构建系统支持交叉编译 VxWorks RTOS。六、Windows 平台bpo-36312 / 36264 / 24643bpo-36312修复以下代码页的解码器50220、50221、50222、50225、50227、50229、5700257011、65000UTF-7与 42Symbol。bpo-36264os.path.expanduser在 Windows 上不再理会 POSIXHOME环境变量Anthony Sottile 补丁。bpo-24643修复 PC/pyconfig.h 中#define timezone _timezone导致的名称冲突。七、IDLE6 项bpo-36405idlelib 改用 dict unpacking。bpo-36396移除idlelib.config.GetHighlight()的fgBg参数仅两处使用且改变返回类型。bpo-36176修复自动补全与 calltip 弹窗颜色避免与 Linux 深色主题冲突同时略微加深 calltip 背景。bpo-23205grep 模块为findfiles增加测试、重构为模块级函数并改用os.walk。bpo-23216为 IDLE 搜索模块补充 docstring。bpo-36152移除colorizer.ColorDelegator.close_when_done及其close()对应参数自 2007 年以来恒为 None/False。bpo-32129修复 macOS Tk 8.6 下 IDLE 应用图标模糊问题。bpo-36096colorizer 中类变量重构为实例变量。bpo-30348idlelib.autocomplete测试覆盖率提升 30%。八、工具与演示Tools/Demosbpo-35132修复 gdb7 下python-gdb.py的py-list与py-bt命令。bpo-32217修复 Windows 上的 freeze 脚本。九、C API 层bpo-36381在未定义PY_SSIZE_T_CLEAN的情况下使用#格式构建/解析值时抛出DeprecationWarning。这是引导扩展作者为s#/y#等格式显式使用Py_ssize_t*接收长度的弃用信号最终在后续版本变为硬错误。bpo-36142整个coreconfig.h从Py_LIMITED_API中排除函数定义迁入新的内部头文件pycore_coreconfig.h。这明确了核心解释器配置结构PyConfig等属于内部 API不向受限 ABI 暴露相关演进可在当前 Include/internal 目录中观察。十、小结3.8.0a3 在 3.8 周期中的位置综合来看3.8.0a3 呈现三条主线为新语法铺路pgen 退役bpo-35808、compile()支持含赋值表达式的 ASTbpo-36332、feature_version语法兼容开关bpo-35975共同服务于 3.8 的 PEP 572 等语法革新内存与稳定性的系统加固字典空对象提速bpo-30040、_ctypes双重减引用bpo-36421、字符串转浮点泄漏bpo-36262、异构排序段错误bpo-36218等覆盖核心对象、解析器与 I/O 全链路标准库实用主义演进NormalDist统计分析能力、pax 默认格式、64 KiB 拷贝缓冲、pprint.pp与 mock 增强等直接提升日常开发体验。读者可对照 Misc/NEWS.d/3.8.0a3.rst 原文与文中给出的源码路径Include/pystate.h、Python/pystate.c、Lib/ast.py、Lib/statistics.py、Lib/tarfile.py、Lib/shutil.py 等逐条验证这些条目所代表的架构方向PEG 解析器、内部头文件隔离、解释器级状态在后续 3.93.13 版本中持续深化形成了今日 CPython 主线的关键骨架。【免费下载链接】cpythonThe Python programming language项目地址: https://gitcode.com/GitHub_Trending/cp/cpython创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考