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 标准库的担忧:
“[…] 标准库模块并不总是特定任务的最佳选择。一些库模块是快速拼凑出来的(例如calendar
、commands
),一些设计得很差,现在几乎不可能修复 (cgi
),还有一些被其他更完整的模块取代了 […]。”
理由
在 Python 的早期,解释器包含了一组有用的模块。这通常被称为“自带电池”理念,也是 Python 成功故事的基石之一。用户不必费心去下载和安装独立的包就能编写简单的 Web 服务器或解析电子邮件。
时代在变。随着 PyPI(原名 Cheeseshop)、setuptools 和后来的 pip 的出现,下载和安装包变得简单而直接。如今,Python 拥有丰富的第三方包生态系统。从 PyPI 安装包或使用众多 Python 或 Linux 发行版中的一个已经成为一种标准做法。
另一方面,Python 的标准库正在积攒大量垃圾代码、不必要的重复功能和可有可无的功能。这会导致很多问题。
- 任何额外的模块都会增加 Python 核心开发团队的维护成本。团队的资源有限,降低维护成本可以为其他改进腾出开发时间。
- 标准库中的模块通常会被优先考虑,并被视为特定问题的首选解决方案。大多数用户只有在有充分理由的情况下才会选择第三方模块来替换标准库模块,例如使用
lxml
而不是xml
。移除不再维护的标准库模块会增加社区贡献的模块得到广泛使用的机会。 - 精简的标准库有利于资源有限的平台,例如存储空间只有几百 KB 的设备(例如 BBC Micro:bit)。Python 在移动平台(例如 BeeWare 或 WebAssembly,如 pyodide)上的使用也受益于更小的下载尺寸。
本 PEP 中的模块被选中弃用,因为它们的移除要么争议最小,要么收益最大。例如,争议最小的可能是 30 年前的多媒体格式,例如 sunau
音频格式,它曾在 1980 年代后期用于 SPARC 和 NeXT 工作站。crypt
模块存在根本缺陷,最好在标准库之外解决。
本 PEP 还指定了一些模块不计划移除。一些模块已经被弃用几个版本了,或者乍一看似乎没有必要。但是,将这些模块保留在标准库中是有益的,尤其是在无法从 PyPI 安装包的环境中。这可能是企业环境或教室,在那里,未经法律许可不允许使用外部代码。
- FTP 的使用正在下降,但一些文件仍然通过 FTP 协议提供,或者主机提供 FTP 来上传内容。因此,
ftplib
将保留。 optparse
和getopt
模块被广泛使用。它们是成熟的模块,维护成本非常低。- 据 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 的项目。
模块 | 弃用版本 | 移除版本 | 添加版本 | 有维护者? | 替代方案 |
---|---|---|---|---|---|
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 文件的支持。音频交换文件格式是一种 1988 年的旧音频格式,基于 Amiga IFF。它在 Apple Macintosh 上最常使用。如今,只有很少的专业应用程序使用 AIFF。
一位用户披露 [6],电影后期制作行业大量使用 AIFC 文件格式。在第一次发布本 PEP 之前,尚不知道在闭源软件和内部软件中使用 aifc
模块的情况。这可能是将 aifc
模块保留在标准库中的一个有力论据。文件格式是稳定的,并且该模块不需要太多维护。对 Python 的战略益处可能超过负担。
audioop
audioop
模块包含用于操作原始音频数据和自适应差分脉冲编码调制音频数据的辅助函数。该模块是用 C 语言实现的,没有任何额外的依赖项。aifc、sunau 和 wave 模块依赖于 audioop 来执行某些操作。
在 wave
模块中,字节交换操作可以通过少量额外的工作来替代。如果 aifc
也没有被弃用,那么 audioop
模块的简化版本将转换为私有实现细节,例如 _audioop
,其中包含 byteswap
、alaw2lin
、ulaw2lin
、lin2alaw
、lin2ulaw
和 lin2adpcm
。
chunk
chunk
模块提供对读取和写入 Electronic Arts 的 Interchange File Format 的支持。 IFF 是一种古老的音频文件格式,最初是在 Commodore 和 Amiga 上引入的。这种格式现在已经不再相关。
imghdr
imghdr
模块是一个简单的工具,用于从文件的头 32 字节或缓冲区中猜测图像文件格式。它只支持有限数量的格式,既不返回分辨率也不返回颜色深度。
ossaudiodev
ossaudiodev
模块提供对 Open Sound System 的支持,Open Sound System 是一个用于声音播放和捕获设备的接口。OSS 最初是免费软件,但后来对较新的声音设备的支持和改进都是专有的。Linux 社区放弃了 OSS,转而支持 ALSA [1]。一些操作系统,如 OpenBSD 和 NetBSD,提供了不完整的 OSS 模拟 [2]。
据我所知,FreeBSD 是目前唯一使用 Open Sound System 的广泛操作系统。从 2003 年起,ossaudiodev
就没有再进行任何改进或新增功能。从 2003 年以来的所有提交都是项目范围内的代码清理以及一些错误修复。如果该模块能够得到关心它并使用它的人的维护和分发,对 FreeBSD 社区和核心开发都将有利。
标准库曾经包含更多与音频相关的模块。其他音频设备接口(audiodev
、linuxaudiodev
、sunaudiodev
)在 2007 年被删除,作为 PEP 3108 标准库重组的一部分。
sndhdr
sndhdr
模块类似于 imghdr 模块,但针对的是音频格式。它从文件的头 512 字节或缓冲区中猜测文件格式、声道、帧速率和样本宽度。该模块只支持 AU、AIFF、HCOM、VOC、WAV 和其他古老的格式。
sunau
sunau
模块提供对 Sun AU 声音格式的支持。它又是另一个古老的、过时的文件格式。
网络模块
asynchat
asyncore
asyncore
模块是第一个用于异步套接字服务客户端和服务器的模块。它已被 asyncio 替代,并且自 Python 3.6 起已弃用。
asyncore
模块也用于标准库测试。ftplib
、logging
、smptd
、smtplib
和 ssl
的测试部分基于 asyncore
。这些测试必须更新以使用 asyncio 或线程。
cgi
cgi
模块是通用网关接口 (CGI) 脚本的支持模块。CGI 被认为效率低下,因为每个传入的请求都在一个新进程中处理。PEP 206 认为该模块
“[…] 设计很差,现在几乎不可能修复(cgi
)[…]”
对于 cgi
的各个部分,如果与执行代码没有直接关系,则可以用以下内容代替
parse
用urllib.parse.parse_qs
代替(parse
只是一个包装器)parse_header
用email.message.Message
代替(见下面的示例)parse_multipart
用email.message.Message
代替(相同的 MIME RFC)FieldStorage
/MiniFieldStorage
没有直接的替代品,但通常可以使用 multipart(用于POST
和PUT
请求)或urllib.parse.parse_qsl
(用于GET
和HEAD
请求)来代替valid_boundary
(未记录)用re.compile("^[ -~]{0,200}[!-~]$")
代替
作为 parse_header
和 email.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) 的客户端。新闻组曾经是在线讨论的主要平台。在过去的二十年中,新闻正在缓慢但稳步地被邮件列表和基于 Web 的讨论平台所取代。Twisted 也计划弃用 NNTP 支持,pynntp 自 2014 年以来就没有更新。这是一个很好的迹象,表明公众对 NNTP 支持的兴趣正在下降。
nntplib
测试在最近一段时间内一直是额外工作的原因。Python 只包含 NNTP 的客户端,因此测试连接到外部新闻服务器。这些服务器有时不可用、速度太慢或无法在 IPv6 上正常工作。这种情况导致 buildbots 上的测试运行不稳定。
telnetlib
telnetlib
模块提供了一个 Telnet 类,它实现了 Telnet 协议。
操作系统接口
crypt
crypt
模块实现了基于 Unix 类平台上的 libcrypt
或 libxcrypt
中的 crypt(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 开发的古老且已弃用的目录服务协议。它设计的继任者,1992 年的 NIS+,从未流行起来。长期以来,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 以创建内阁文件 (CAB)。该模块用于简化 distutils 使用bdist_msi
命令创建 MSI 安装程序。过去,它也被用来创建 CPython 的官方 Windows 安装程序。
微软正在慢慢地从 MSI 转向 Windows 10 应用 (AppX) 作为新的部署模型[3].
pipes
pipes
模块提供帮助程序将一个命令的输入管道到另一个命令的输出。该模块建立在os.popen
之上。鼓励用户使用subprocess
模块代替。
保留的模块
一些模块最初被提议弃用,但不再列在这个 PEP 中。
模块 | 弃用版本 | 替代方案 |
---|---|---|
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 包colormath
、colour
和colorspacious
提供了更多更高级的功能。Pillow 库更适合在颜色系统之间转换图像。
fileinput
fileinput
模块实现帮助程序,用于迭代来自sys.argv
的文件列表。该模块早于optparse
和argparse
模块。可以使用argparse
模块实现相同的功能。
一些核心开发人员表达了他们对保留该模块在标准库中的兴趣,因为它对快速脚本很有用。
getopt
getopt
模块模仿 C 的getopt()
选项解析器。
虽然鼓励用户使用argparse
代替,但getopt
模块仍然被广泛使用。该模块小巧、简单,方便 C 开发人员编写简单的 Python 脚本。
optparse
optparse
模块是argparse
模块的前身。
虽然它已经弃用多年,但它仍然被广泛使用,无法将其删除。
wave
wave
模块提供对 WAV 声音格式的支持。
该模块没有被弃用,因为 WAV 格式在今天仍然相关。wave
模块也用于教育,例如,向孩子们展示如何用计算机发出噪音。
该模块使用audioop模块中的一个简单函数来执行小端和大端格式之间的字节交换。在添加 24 位 WAV 支持之前,字节交换是使用array
模块实现的。为了删除wave
对audioop
的依赖,字节交换函数可以移动到另一个模块(例如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.server
和xmlrpc.server
。stdlib 还没有服务器的替代品。
被拒绝的想法
为弃用的模块创建/维护单独的仓库
以前曾提议创建一个单独的存储库,其中包含用于安装的已弃用模块。PEP 作者之一甚至创建了一个演示存储库。但最终,人们决定创建和维护此类存储库的额外工作量是不可取的,因为源代码将继续在 CPython 存储库中提供,供人们根据需要进行供应商。类似的工作在以前的模块被弃用和删除时也没有完成,它似乎并没有给社区带来过度的负担。
更新历史
更新 1
更新 2
更新 3
- 保留旧的电子邮件 API 模块。内部弃用将单独处理。
更新 4
- 添加 Brett 作为共同作者。
- 将 PEP 的目标重新定位到 Python 3.11。
- 有关如何替换
cgi
相关部分的示例(感谢 Martijn Pieters)。
参考资料
版权
本文件放置在公有领域或 CC0-1.0-Universal 许可下,以更具许可性的为准。
来源:https://github.com/python/peps/blob/main/peps/pep-0594.rst
最后修改时间:2024-05-25 13:48:58 GMT