當前位置:
首頁 > 知識 > 一次發布有多個發行版,為什麼Python發行包會這麼難?

一次發布有多個發行版,為什麼Python發行包會這麼難?

選自pydist

作者:Alex Becker

機器之心編譯

參與:王子嘉、思

雖然經常會使用pip,但你知道它是如何選擇不同的發行版么?在這篇文章中,作者介紹了Python中的發行包的一些基本概念,並討論了為什麼發行Python包會這麼難。

大多數編程語言包的生態系統都有兩個層級(level):每個包都有一個或多個發布(release),每一次發布都可以用版本號(version)進行區分。Python 有第三個層級:每個發布都有一個或多個發行版(distribution),下載安裝包時下載的實際文件就是這些發行版。在大多數語言中,這些文件都是發布的同義詞,但是在Python 中「一個發布有多個發行版」是很重要的,因為使用最廣泛的那些包,大多數發布實際上都有多個發行版。

為什麼會這樣呢?因為 Python 的特殊之處在於,它將 C 擴展(extension)視為該語言的一流特性,並試圖隔離包的使用與編譯 C 擴展。這意味著發行版需要包含編譯 C 擴展後的得到的二進位代碼,這種發行版(在其現代迭代中)被稱為 binary wheels。

但是 C 擴展通常需要針對特定的 Python 版本和操作系統進行編譯,因此需要使用多個 wheels 來實現普適性。此外,由於包的作者不能預測出所有的 Python 版本和操作系統,所以包含一個由包用戶負責編譯的源發行版也很重要。

儘管如此,用戶們和大多數工具考慮的仍然是發布版本(release),而不是特定的發行版(distribution)。這可能會引起極大的不協調。例如,在一台機器上安裝一個包可能需要幾秒鐘(因為存在匹配的二進位發行版),在另一台機器上可能需要幾分鐘甚至幾個小時。

即使兩台機器都能找到合適的二進位發行版來安裝,它們的哈希值也不匹配,檢測 MitM 攻擊也會因此變得更加困難。因為 pip 這樣的工具會自動找到在發布下「最合適」的發行版,當一個發行版與給定的系統兼容時會偏向於選擇 binary wheel,如果有多個發行版與此系統兼容,則選擇最合適的 binary wheel,如果不兼容,則返回到源發行版。

如果你已經安裝了發布下的一個發行版之後,該發布又有一個新的發行版,這時就會出現很大的問題。而且這個問題幾乎是不可避免的——因為 PyPI 一次只允許上傳一個發行版,並會創建一包含這個發行版的新發布,所以在你上傳最後一個發行版之前,一定會有人已經下載了第一個發行版。

在使用自動編譯程序(buildbot)並行構建不同的發行版之後,這個問題變得更加常見,二進位發行版一般要比源發行版花費更長的時間。當一個包的作者在發布後的幾個月或幾年裡,再去添加對新平台(或 python 的新版本)的支持時,這種情況就變得更糟糕了。當這種情況發生時,會有以下一些問題:

構建一個系統,期待在給定包中斷時產生一個特定的哈希值。

像 PyDist 這樣的 PyPI 鏡像不知道要查找新的發行版,並且無法同步。

你的系統(如開發機器)如果先前安裝了某發布的一個發行版,這個系統就不會獲得。

新的發行版,並且可能與安裝它的系統(如生產伺服器)的行為不同。

儘管 PyPI 維護者已經意識到了這些問題並討論了工具改進,但是在不顯著破壞生態系統的情況下解決這些問題的方法還是很難找到的。與此同時,Python 重度用戶和系統管理員也有責任了解 Python 包的分布方式以及 pip 如何選擇發行版。

本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。

------------------------------------------------

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 機器之心 的精彩文章:

獨家專訪 | 依圖憑什麼敢「賣房子」賭一顆AI芯?
GitHub最熱!碼代碼不得不知的所有定律法則

TAG:機器之心 |