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

Python 增強提案 (Python Enhancement Proposals)

PEP 594 – 移除標準函式庫中過時的「電池」

作者:
Christian Heimes <christian at python.org>, Brett Cannon <brett at python.org>
討論於:
Discourse 討論串
狀態:
最終 (Final)
類型:
標準軌跡 (Standards Track)
建立日期:
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 的早期,解釋器隨附了大量有用的模組。這通常被稱為「電池內建」(batteries included) 哲學,也是 Python 成功故事的基石之一。使用者不必為了撰寫簡單的網頁伺服器或解析電子郵件,而去研究如何下載並安裝獨立的套件。

時代變了。隨著 PyPI (前身為 Cheeseshop)、setuptools 以及後來的 pip 出現,下載與安裝套件變得簡單直接。現今的 Python 擁有豐富且充滿活力的第三方套件生態系統。從 PyPI 安裝套件,或是使用眾多 Python 或 Linux 發行版中的套件,幾乎已成為常態。

另一方面,Python 的標準函式庫正堆積著冗餘程式碼、不必要的功能重複以及可有可無的特性。這在多個層面上都是不理想的。

  • 每個額外的模組都會增加 Python 核心開發團隊的維護成本。團隊資源有限,減少維護成本能釋放開發時間用於其他改進項目。
  • 標準函式庫中的模組通常被視為解決問題的預設首選。大多數使用者只有在有強烈理由時(例如使用 lxml 取代 xml),才會選擇第三方模組來替換標準函式庫模組。移除無人維護的標準函式庫模組,增加了社群貢獻模組被廣泛使用的機會。
  • 精簡的標準函式庫有利於資源受限的平台,例如儲存空間僅有幾百 KB 的裝置(如 BBC Micro:bit)。在 BeeWare 或 WebAssembly(如 pyodide)等行動平台上運行 Python 時,也能因下載大小減少而受惠。

本 PEP 中的模組被選為棄用對象,是因為移除它們最具爭議性最小或是最具效益。例如,爭議最小的是如 sunau 音訊格式等 30 年前的多媒體格式,這些格式在 1980 年代末期的 SPARC 與 NeXT 工作站上使用。而 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 版本,預計終止支援時間為 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 中的專家索引 (expert index)

資料編碼模組

uu 與 uu 編碼

uu 模組提供了 uuencode 格式,這是 1980 年代用於電子郵件的舊二進位編碼格式。uu 格式已被 MIME 取代。uu 編解碼器由 binascii 模組提供。另外還有 encodings/uu_codec.py,這是相同編碼的轉碼器,也應一併棄用。

xdrlib

xdrlib 模組支援 Sun 外部資料表示標準 (XDR)。XDR 是一種 1987 年的舊二進位序列化格式。現今除了 NFS 等特殊領域外,已很少使用。

多媒體模組

aifc

aifc 模組提供讀寫 AIFF 與 AIFF-C 檔案的支援。音訊交換檔案格式 (Audio Interchange File Format) 是一種基於 Amiga IFF、源自 1988 年的舊音訊格式。它最常使用於 Apple Macintosh 上。現今只有少數特殊應用程式仍使用 AIFF。

有使用者透露 [6],後期電影製作產業仍大量使用 AIFC 檔案格式。在首次發布此 PEP 前,aifc 模組在封閉原始碼與內部軟體中的使用狀況並不為人所知。這可能是保留 aifc 模組在標準函式庫中的強力理由。該檔案格式穩定,且模組無需太多維護。對 Python 而言,其戰略效益可能大於維護負擔。

audioop

audioop 模組包含用於操作原始音訊資料與自適應差分脈衝編碼調變 (ADPCM) 音訊資料的輔助函式。該模組以 C 語言實現,無需任何額外依賴。aifcsunauwave 模組在某些操作上依賴 audioop

wave 模組中的位元組交換操作可以透過少許額外工作取代。若 aifc 未被棄用,則 audioop 模組的簡化版本將轉換為私有的實作細節,例如 _audioop,包含 byteswapalaw2linulaw2linlin2alawlin2ulawlin2adpcm

chunk

chunk 模組提供讀寫 Electronic Arts 的交換檔案格式 (IFF) 的支援。IFF 是一種最初為 Commodore 與 Amiga 引入的舊音訊檔案格式。該格式已無關緊要。

imghdr

imghdr 模組是一個透過檔案或緩衝區的前 32 個位元組來推測影像檔案格式的簡單工具。它支援的格式有限,且既不回傳解析度也不回傳色彩深度。

ossaudiodev

ossaudiodev 模組支援 Open Sound System (OSS),這是一個用於聲音播放與捕捉裝置的介面。OSS 最初是自由軟體,但後來針對新聲音裝置的支援與改進變成了專有軟體。Linux 社群已轉向 ALSA [1]。部分如 OpenBSD 與 NetBSD 等作業系統提供了不完整的 OSS 模擬 [2]

據我所知,FreeBSD 是目前唯一廣泛使用 Open Sound System 的作業系統。ossaudiodev 自 2003 年以來未見任何改進或新功能。自 2003 年以來的所有提交僅限於專案整體的程式碼清理與少數錯誤修復。如果該模組由真正關心並使用它的人來維護與發布,對 FreeBSD 社群與核心開發者來說都是好事。

標準函式庫過去擁有更多與音訊相關的模組。其他音訊裝置介面(audiodev, linuxaudiodev, sunaudiodev)已於 2007 年作為 PEP 3108 標準函式庫重組的一部分被移除。

sndhdr

sndhdr 模組類似於 imghdr 模組,但用於音訊格式。它透過檔案或緩衝區的前 512 個位元組來推測檔案格式、聲道、取樣率與取樣寬度。該模組僅支援 AU、AIFF、HCOM、VOC、WAV 與其他古老的格式。

sunau

sunau 模組提供 Sun AU 聲音格式的支援。這是另一種古老且已淘汰的檔案格式。

網路模組

asynchat

asynchat 模組建構於 asyncore 之上,且自 Python 3.6 起已被棄用。

asyncore

asyncore 模組是第一個用於非同步 Socket 服務用戶端與伺服器的模組。它已被 asyncio 取代,並自 Python 3.6 起棄用。

asyncore 模組也用於標準函式庫的測試中。ftplib, logging, smptd, smtplibssl 的測試部分基於 asyncore。這些測試必須更新以使用 asyncio 或執行緒。

cgi

cgi 模組是通用閘道介面 (CGI) 指令碼的支援模組。CGI 被認為效率低下,因為每個傳入的請求都會在一個新的程序中處理。PEP 206 認為該模組:

「[...] 設計不良且現在已幾乎無法修復 (cgi) [...]」

cgi 中與執行程式碼無直接關聯的各部分的替代方案為:

  • parse 使用 urllib.parse.parse_qsparse 只是個封裝器)
  • parse_header 使用 email.message.Message(見下方範例)
  • parse_multipart 使用 email.message.Message(相同的 MIME RFC)
  • 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 模組的輔助工具,用於產生可設定的追蹤紀錄 (tracebacks)。

cgitb 模組並未被任何主要的 Python 網頁框架(Django, Pyramid, Plone, Flask, CherryPy, 或 Bottle)使用。只有 Paste 在一個可選的偵錯中介軟體 (middleware) 中使用它。

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 正確運作。這種情況導致在 buildbots 上出現不穩定的測試執行結果。

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 支援。網路資訊服務 / 黃頁 (Network Information Service / Yellow Pages) 是一種由 Sun Microsystems 開發的古老且已棄用的目錄服務協定。其設計繼承者 NIS+ (1992 年) 從未流行起來。長期以來,libc 的名稱服務切換 (NSS)、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 套件會讀取「郵件能力」(mail capability) 檔案,以協助處理電子郵件中的檔案附件。在大多數現代作業系統中,電子郵件用戶端本身就會處理對檔案附件的反應。作業系統也有自己根據檔案副檔名註冊處理方式的方法。最後,該模組被登記有 CVE-2015-20107,且沒有維護者協助修復。

msilib

msilib 套件僅限於 Windows。它支援 Microsoft Installer (MSI) 的建立。該套件還公開了建立 cabinet 檔案 (CAB) 的額外 API。該模組用於輔助 distutils 透過 bdist_msi 命令建立 MSI 安裝程式。過去它也曾用於建立 CPython 的官方 Windows 安裝程式。

Microsoft 正緩慢地從 MSI 轉向 Windows 10 Apps (AppX) 作為新的部署模型 [3]

pipes

pipes 模組提供將一個命令的輸入傳導 (pipe) 到另一個命令輸出的輔助工具。該模組建構於 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 模組仍被廣泛使用。該模組小巧、簡單,對於編寫簡單 Python 腳本的 C 開發者來說很方便。

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 儲存庫中,供有需要的人根據需要進行 vendoring (供應)。當之前的模組被棄用並移除時,也沒有採取類似的做法,且似乎這對社群並未構成過多的負擔。

更新紀錄

更新 1

  • 棄用 parser 模組
  • 保留 fileinput 模組
  • 闡述為何 cryptspwd 是危險且糟糕的
  • 改進 cgitb, colorsys, nntplibsmtpd 模組的章節
  • colorsys, crypt, imghdr, sndhdrspwd 章節現在列出了合適的替代方案
  • 提到 socketserver 將為 http.serverxmlrpc.server 保留
  • 未來維護部分現在說明已棄用的模組可能會由 Python 社群成員接手

更新 2

  • 保留 colorsys 模組
  • 加入專家列表
  • 將討論重新導向至 discuss.python.org
  • 棄用 telnetlib
  • 棄用 email 套件的 compat32 策略
  • 在概述表中加入建立年份
  • 提到 PEP 206PEP 3108
  • 更新 aifc, audioop, cgiwave 章節。

更新 3

  • 保留舊版 email 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