Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 594 – 从标准库中移除废弃的电池

作者:
Christian Heimes <christian at python.org>, Brett Cannon <brett at python.org>
讨论至:
Discourse 帖子
状态:
最终版
类型:
标准跟踪
创建日期:
2019年5月20日
Python 版本:
3.11
发布历史:
2019年5月21日,2022年2月4日
决议:
Discourse 消息

目录

摘要

本 PEP 提出了一个从标准库中移除的模块列表。这些模块大多是历史数据格式(例如 Commodore 和 SUN 文件格式)、早已被取代的 API 和操作系统(例如 Mac OS 9),或者存在安全隐患且有更好替代方案的模块(例如密码和登录)。

本 PEP 遵循了其他 PEP 的脚步,例如 PEP 3108。《标准库重组》提案从 Python 3.0 中移除了大量模块。2007 年,该 PEP 将维护负担描述为

“多年来,某些模块已成为 python-dev 维护的沉重负担。在这种情况下,最好将模块交给社区维护,以使 python-dev 能够更专注于语言支持和标准库中不占用过多时间和精力的其他模块。”

2000 年撤回的 PEP 206 以一种不加修饰、直截了当的方式表达了 Python 标准库的问题

“[……]标准库模块并非总是工作的最佳选择。一些库模块是快速的修补程序(例如 calendarcommands),一些设计不佳,现在几乎无法修复(cgi),还有一些已被其他更完整的模块取代[……]。”

基本原理

在 Python 的早期,解释器带有一大套有用的模块。这通常被称为“内置电池”哲学,也是 Python 成功故事的基石之一。用户不必费心下载和安装单独的包就能编写一个简单的 Web 服务器或解析电子邮件。

时代变了。随着 PyPI(曾名 Cheeseshop)、setuptools 以及后来的 pip 的引入,下载和安装包变得简单而直接。如今,Python 拥有一个丰富而充满活力的第三方包生态系统。从 PyPI 安装包或使用众多 Python 或 Linux 发行版之一已是相当标准的操作。

另一方面,Python 的标准库中堆积了大量无用代码、不必要的功能重复和可有可无的特性。这出于几个原因是不受欢迎的。

  • 任何额外的模块都会增加 Python 核心开发团队的维护成本。团队资源有限,维护成本的降低可以腾出开发时间用于其他改进。
  • 标准库中的模块通常受到青睐,并被视为解决问题的实际解决方案。大多数用户只有在有充分理由时才会选择第三方模块来替换标准库模块,例如使用 lxml 代替 xml。移除未维护的标准库模块会增加社区贡献模块被广泛使用的机会。
  • 精简的标准库有利于资源有限的平台,例如只有几百 KB 存储空间的设备(例如 BBC Micro:bit)。在 BeeWare 或 WebAssembly(例如 pyodide)等移动平台上,Python 也能从减小的下载大小中受益。

本 PEP 中选择废弃的模块,是因为它们的移除要么争议最小,要么最有益。例如,争议最小的是 30 年前的多媒体格式,如 20 世纪 80 年代末在 SPARC 和 NeXT 工作站上使用的 sunau 音频格式。crypt 模块存在根本缺陷,最好在标准库之外解决。

本 PEP 还将一些模块指定为不计划移除。有些模块已经废弃了几个版本,或者乍一看似乎没有必要。然而,将这些模块保留在标准库中是有益的,主要适用于无法从 PyPI 安装包的环境。这可能是企业环境或不允许未经法律批准使用外部代码的教室。

  • FTP 的使用正在下降,但有些文件仍然通过 FTP 协议提供,或者主机提供 FTP 上传内容。因此,ftplib 将会保留。
  • optparsegetopt 模块被广泛使用。它们是成熟的模块,维护开销非常低。
  • 根据 David Beazley [5] 的说法,wave 模块易于教授给孩子们,并且可以制作出奇妙的声音。让计算机生成声音对于一个九岁的有抱负的开发者来说,是一个强大而富有激励性的练习。这是一个值得保留的有趣电池。

废弃时间表

3.11

从 Python 3.11 开始,废弃的模块将开始发出 DeprecationWarning。Python 3.10(最后一个没有警告的版本)的预计 EOL 是 2026 年 10 月。

3.12

与 Python 3.11 相比,应该没有具体变化。这是包含废弃模块的最后一个 Python 版本,预计 EOL 为 2028 年 10 月。

3.13

本 PEP 废弃的所有模块都将从 CPython 仓库的 main 分支中移除,并且不再作为 Python 的一部分发布。

已废弃的模块

这些模块被分为数据编码、多媒体、网络、操作系统接口和杂项模块。大多数模块是针对旧数据格式或旧 API 的。其他一些模块很少有用,并且在 PyPI 上有更好的替代品,例如用于图像处理的 Pillow 或基于 NumPy 的音频处理项目。

表 1:拟议的模块废弃
模块 在...中废弃 将被移除 添加于 有维护者吗? 替代品
aifc 3.11 (3.0*) 3.13 1993 是(不活跃) -
asynchat 3.6 (3.0*) 3.12 1999 asyncio
asyncore 3.6 (3.0*) 3.12 1999 asyncio
audioop 3.11 (3.0*) 3.13 1992 -
cgi 3.11 (2.0**) 3.13 1995 -
cgitb 3.11 (2.0**) 3.13 1995 -
chunk 3.11 3.13 1999 -
crypt 3.11 3.13 1994 是(不活跃) legacycrypt, bcrypt, argon2-cffi, hashlib, passlib
imghdr 3.11 3.13 1992 filetype, puremagic, python-magic
mailcap 3.11 3.13 1995 -
msilib 3.11 3.13 2006 -
nntplib 3.11 3.13 1992 -
nis 3.11 (3.0*) 3.13 1992 -
ossaudiodev 3.11 3.13 2002 -
pipes 3.11 3.13 1992 subprocess
smtpd 3.4.7, 3.5.4 3.12 2001 aiosmtpd
sndhdr 3.11 3.13 1994 filetype, puremagic, python-magic
spwd 3.11 3.13 2005 python-pam
sunau 3.11 (3.0*) 3.13 1993 -
telnetlib 3.11 (3.0*) 3.13 1997 telnetlib3, Exscript
uu 3.11 3.13 1994 -
xdrlib 3.11 3.13 1992/1996 -

PEP 3108 为 3.0 提议的一些模块废弃和 PEP 206 为 2.0 提议的一些模块废弃。“添加于”列说明了模块最初设计并添加到标准库的时间。“有维护者”列指的是 DevGuide 中的 专家索引,一个领域专家和维护者列表。

数据编码模块

uu 和 uu 编码

uu 模块提供了 uuencode 格式,这是一种 1980 年代用于电子邮件的旧二进制编码格式。uu 格式已被 MIME 取代。uu 编解码器由 binascii 模块提供。还有一个 encodings/uu_codec.py,它是同一编码的编解码器;它也应该被废弃。

xdrlib

xdrlib 模块支持 Sun 外部数据表示标准。XDR 是一种 1987 年的旧二进制序列化格式。如今,除了 NFS 等专业领域外,它很少使用。

多媒体模块

aifc

aifc 模块支持读写 AIFF 和 AIFF-C 文件。音频交换文件格式是一种基于 Amiga IFF 的 1988 年的旧音频格式。它最常用于 Apple Macintosh。如今只有少数专业应用程序使用 AIFF。

一位用户透露 [6],电影后期制作行业大量使用 AIFC 文件格式。在发布本 PEP 之前,aifc 模块在闭源和内部软件中的使用情况尚不清楚。这可能是一个有说服力的论据,可以保留 aifc 模块在标准库中。文件格式稳定,模块不需要太多维护。Python 的战略优势可能超过了负担。

audioop

audioop 模块包含用于操作原始音频数据和自适应差分脉冲编码调制音频数据的辅助函数。该模块是用 C 语言实现的,没有任何额外的依赖。 aifcsunauwave 模块在某些操作上依赖于 audioop

wave 模块中的字节交换操作只需少量额外工作即可替换。如果 aifc 也没有被废弃,那么 audioop 模块的一个精简版本将转换为私有实现细节,例如带有 byteswapalaw2linulaw2linlin2alawlin2ulawlin2adpcm_audioop

chunk

chunk 模块支持读写电子艺界 (Electronic Arts) 的交换文件格式 (IFF)。IFF 是一种最初为 Commodore 和 Amiga 引入的旧音频文件格式。该格式已不再相关。

imghdr

imghdr 模块是一个简单的工具,用于从文件或缓冲区的最前 32 个字节猜测图像文件格式。它只支持有限数量的格式,并且不返回分辨率和颜色深度。

ossaudiodev

ossaudiodev 模块提供了对 Open Sound System 的支持,这是一个用于声音播放和捕获设备的接口。OSS 最初是免费软件,但后来对新声音设备的支援和改进都是专有的。Linux 社区放弃了 OSS,转而支持 ALSA [1]。一些操作系统,如 OpenBSD 和 NetBSD,提供了不完整的 [2] OSS 模拟。

据我所知,FreeBSD 是目前唯一广泛使用 Open Sound System 的操作系统。ossaudiodev 自 2003 年以来没有看到任何改进或新功能。自 2003 年以来的所有提交都是项目范围的代码清理和几个错误修复。如果该模块由关心并使用它的人员维护和分发,那将对 FreeBSD 社区和核心开发都有益。

标准库曾经拥有更多与音频相关的模块。其他音频设备接口(audiodevlinuxaudiodevsunaudiodev)已于 2007 年作为 PEP 3108 标准库重组的一部分被移除。

sndhdr

sndhdr 模块与 imghdr 模块类似,但用于音频格式。它从文件或缓冲区的最初 512 字节猜测文件格式、声道、帧率和采样宽度。该模块仅支持 AU、AIFF、HCOM、VOC、WAV 和其他古老格式。

sunau

sunau 模块提供对 Sun AU 声音格式的支持。这是另一种旧的、过时的文件格式。

网络模块

asynchat

asynchat 模块建立在 asyncore 之上,自 Python 3.6 起已废弃。

asyncore

asyncore 模块是第一个用于异步套接字服务客户端和服务器的模块。它已被 asyncio 取代,自 Python 3.6 起已废弃。

asyncore 模块也用于 stdlib 测试。ftplibloggingsmptdsmtplibssl 的测试部分基于 asyncore。这些测试必须更新以使用 asyncio 或 threading。

cgi

cgi 模块是通用网关接口 (CGI) 脚本的支持模块。CGI 被认为效率低下,因为每个传入请求都在一个新进程中处理。PEP 206 将该模块视为

“[……]设计不佳,现在几乎无法修复(cgi)[……]”

与执行代码不直接相关的 cgi 各部分的替代品是:

  • parse 替换为 urllib.parse.parse_qsparse 只是一个包装器)
  • parse_header 替换为 email.message.Message(参见下面的示例)
  • parse_multipart 替换为 email.message.Message(相同的 MIME RFCs)
  • FieldStorage/MiniFieldStorage 没有直接的替代品,但通常可以通过使用 multipart(用于 POSTPUT 请求)或 urllib.parse.parse_qsl(用于 GETHEAD 请求)来替换
  • valid_boundary (未文档化) 替换为 re.compile("^[ -~]{0,200}[!-~]$")

作为 parse_headeremail.message.Message 之间紧密联系的明确示例:

>>> from cgi import parse_header
>>> from email.message import Message
>>> parse_header(h)
('application/json', {'charset': 'utf8'})
>>> m = Message()
>>> m['content-type'] = h
>>> m.get_params()
[('application/json', ''), ('charset', 'utf8')]
>>> m.get_param('charset')
'utf8'

cgitb

cgitb 模块是 cgi 模块的辅助模块,用于可配置的追溯。

所有主流 Python Web 框架(Django、Pyramid、Plone、Flask、CherryPy 或 Bottle)均未使用 cgitb 模块。只有 Paste 在可选的调试中间件中使用了它。

smtpd

smtpd 模块提供了 SMTP 邮件服务器的简单实现。模块文档将该模块标记为已废弃,并建议使用 aiosmtpd。废弃消息已在 3.4.7、3.5.4 和 3.6.1 版本中添加。

nntplib

nntplib 模块实现了网络新闻传输协议 (nntp) 的客户端。新闻组曾是在线讨论的主要平台。在过去的二十年里,新闻组已逐渐被邮件列表和基于网络的讨论平台取代。Twisted 也计划废弃 NNTP 支持,而 pynntp 自 2014 年以来一直没有活动。这很好地表明公众对 NNTP 支持的兴趣正在下降。

nntplib 测试在最近一直额外的工作量。Python 只包含 NNTP 的客户端,因此测试连接到外部新闻服务器。这些服务器有时不可用,太慢,或者在 IPv6 上无法正常工作。这种情况导致构建机器人上的测试运行不稳定。

telnetlib

telnetlib 模块提供了一个实现 Telnet 协议的 Telnet 类。

操作系统接口

crypt

crypt 模块基于类 Unix 平台上的 libcryptlibxcryptcrypt(3) 函数实现密码哈希。这些算法大多老旧、质量差且不安全。不鼓励用户使用它们。

  • 该模块在 Windows 上不可用。跨平台应用程序无论如何都需要替代实现。
  • 只有 DES 加密保证可用。DES 的密钥空间极其有限,仅为 2**56。
  • MD5、加盐 SHA256、加盐 SHA512 和 Blowfish 是可选扩展。SSHA256 和 SSHA512 是 glibc 扩展。Blowfish (bcrypt) 是唯一仍然安全的算法。然而,它在 glibc 中,因此在 Linux 上不常见。
  • 根据平台的不同,crypt 模块不是线程安全的。只有带有 crypt_r(3) 的实现才是线程安全的。
  • 该模块从未被用于与系统用户和密码数据库交互。在 BSD、macOS 和 Linux 上,所有用户认证和密码修改操作都必须通过 PAM(可插拔认证模块);请参阅 spwd 废弃。

nis

nis 模块提供 NIS/YP 支持。网络信息服务/黄页是 Sun Microsystems 开发的一种旧的、已废弃的目录服务协议。其设计继承者 NIS+(1992 年推出)从未成功。长期以来,libc 的命名服务切换、LDAP 和 Kerberos/GSSAPI 被认为是 NIS 更强大、更安全的替代品。

spwd

spwd 模块使用非标准 API 提供对 Unix 影子密码数据库的直接访问。

通常,使用 spwd 是一个坏主意。它规避了系统安全策略,不使用 PAM 堆栈,并且只与本地用户帐户兼容,因为它忽略了 NSS。spwd 模块用于访问控制必须被视为一个_安全漏洞_,因为它绕过了 PAM 的访问控制。

此外,spwd 模块使用 shadow(3) API。像 getspnam(3) 这样的函数直接访问 /etc/shadow 文件。这很危险,对于带有 SELinux 或 AppArmor 等安全引擎的系统上的受限服务来说甚至是被禁止的。

杂项模块

mailcap

mailcap 包读取 邮件能力 文件以协助处理电子邮件中的文件附件。在大多数现代操作系统中,电子邮件客户端本身会处理对文件附件的响应。操作系统也有自己的方式通过文件扩展名注册处理文件。最后,该模块存在 CVE-2015-20107 漏洞,但没有维护者来帮助修复它。

msilib

msilib 包是一个仅适用于 Windows 的包。它支持创建 Microsoft 安装程序 (MSI)。该包还公开了额外的 API 来创建 Cabinet 文件 (CAB)。该模块用于协助 distutils 使用 bdist_msi 命令创建 MSI 安装程序。过去它也用于创建 CPython 的官方 Windows 安装程序。

微软正在慢慢放弃 MSI,转而采用 Windows 10 应用程序 (AppX) 作为新的部署模型 [3]

pipes

pipes 模块提供了将一个命令的输入管道连接到另一个命令的输出的辅助函数。该模块建立在 os.popen 之上。鼓励用户使用 subprocess 模块。

保留的模块

有些模块最初被提议废弃,但在此 PEP 中不再列出。

表 2:撤回的废弃
模块 在...中废弃 替代品
colorsys - colormath, colour, colorspacious, Pillow
fileinput - argparse
getopt - argparse, optparse
optparse 3.2 argparse
wave -

colorsys

colorsys 模块定义了 RGB、YIQ、HSL 和 HSV 坐标系之间的颜色转换函数。

Walter Dörwald、Petr Viktorin 和其他人要求保留 colorsys。该模块对于在坐标系之间转换 CSS 颜色很有用。其实现简单、成熟,并且不会给核心开发带来维护负担。

PyPI 包 colormathcolourcolorspacious 提供了更多高级功能。Pillow 库更适合在颜色系统之间转换图像。

fileinput

fileinput 模块实现了辅助函数,用于遍历 sys.argv 中的文件列表。该模块早于 optparseargparse 模块。相同的功能可以通过 argparse 模块实现。

几位核心开发者表示他们有兴趣将该模块保留在标准库中,因为它对于快速脚本很方便。

getopt

getopt 模块模拟了 C 语言的 getopt() 选项解析器。

尽管鼓励用户改用 argparse,但 getopt 模块仍然被广泛使用。该模块小巧、简单,对于 C 开发者编写简单的 Python 脚本很方便。

optparse

optparse 模块是 argparse 模块的前身。

尽管它已经被废弃多年,但它的使用范围仍然太广,无法移除。

wave

wave 模块提供对 WAV 声音格式的支持。

该模块没有被废弃,因为 WAV 格式至今仍然相关。wave 模块也用于教育,例如向孩子们展示如何用计算机制造声音。

该模块使用 audioop 模块中的一个简单函数来执行小端和大端格式之间的字节交换。在添加 24 位 WAV 支持之前,字节交换通常使用 array 模块实现。为了消除 waveaudioop 的依赖,字节交换函数可以移到另一个模块(例如 operator),或者 array 模块可以支持 24 位(3 字节)数组。

讨论

  • Elana Hashman 和 Alyssa Coghlan 建议保留 getopt 模块。
  • Berker Peksag 提议废弃并移除 msilib
  • Brett Cannon 建议推迟活跃的废弃警告和移除 imp 等模块,直到 Python 3.10。版本 3.8 将在 Python 2 结束生命周期前不久发布。延迟可以减少从 Python 2 迁移到 3.8 的用户的麻烦。
  • 有一次,distutils 与这个 PEP 在同一个句子中被提及。为了避免冗长的讨论和 PEP 的延迟,我决定不处理 distutils。distutils 包的废弃将由另一个 PEP 处理。
  • 多人(Gregory P. Smith、David Beazley、Alyssa Coghlan 等)说服我保留 wave 模块。[4]
  • Gregory P. Smith 提议废弃 nntplib[4]
  • Andrew Svetlov 提到 socketserver 模块值得商榷。然而,它用于实现 http.serverxmlrpc.server。标准库目前还没有这些服务器的替代品。

被拒绝的想法

为废弃模块创建/维护一个单独的仓库

此前曾提议创建一个单独的仓库,其中包含打包用于安装的废弃模块。其中一位 PEP 作者甚至创建了一个演示仓库。然而,最终决定,创建和维护这样一个官方仓库所增加的工作量是不合理的,因为源代码将继续在 CPython 仓库中可用,供人们根据需要进行供应商化。在之前的模块被废弃和移除时,也没有进行类似的工作,这似乎没有给社区带来不必要的负担。

更新历史

更新 1

  • 废弃 parser 模块
  • 保留 fileinput 模块
  • 阐述 cryptspwd 为什么危险和糟糕
  • 改进 cgitbcolorsysnntplibsmtpd 模块部分
  • colorsyscryptimghdrsndhdrspwd 部分现在列出了合适的替代品
  • 提到 socketserver 将保留用于 http.serverxmlrpc.server
  • 未来的维护部分现在声明废弃的模块可能由 Python 社区成员采用

更新 2

  • 保留 colorsys 模块
  • 添加专家
  • 将讨论重定向到 discuss.python.org
  • 废弃 telnetlib
  • 废弃 email 包的 compat32 策略
  • 在概述表中添加创建年份
  • 提及 PEP 206PEP 3108
  • 更新 aifcaudioopcgiwave 部分。

更新 3

  • 保留遗留的电子邮件 API 模块。内部废弃将单独处理。

更新 4

  • 将 Brett 添加为合著者。
  • 将 PEP 重新定为 Python 3.11。
  • 如何替换 cgi 相关部分的示例(感谢 Martijn Pieters)。

参考资料


来源:https://github.com/python/peps/blob/main/peps/pep-0594.rst

最后修改:2024-05-25 13:48:58 GMT