1. 程式人生 > 程式設計 >迴應《也談「不要用 Pipenv」》

迴應《也談「不要用 Pipenv」》

看了董偉明老師(

董偉明 )的《也談「不要用 Pipenv」》,這篇文章對其中的一些觀點做出一些迴應和解釋。

也看了 Frost Ming 老師(

豈不美哉 )的《Pipenv 有什麼問題》,很感謝他做出的努力,祝 Pipenv 早日脫離 Kenneth Retiz 的影響,越來越好。

(Kenneth Retiz 下文簡稱 KR)

KR 有沒有借 PyPA 之名來做背書?

所以作者並沒有想著用來背書。

我仍然認為 KR 有利用 PyPA 做背書,甚至在誤導別人 Pipenv 是 Python 官方(混淆 PyPA 和 Python 官方的概念)推薦的工具。

證據 1

2017 年 8 月 29 號,在 Pipenv 還不夠成熟的時候,PyPA 成員 Thea Flowers 建立了

一個 PR 要把 Pipenv 新增到 PyPA 的打包教程裡,介紹使用 Pipenv 安裝和管理依賴(注意這時候 Pipenv 根據教程的內容在 Windows 上是沒法正常使用的,具體見 9 月 2 號的這個 issue)。

2017 年 8 月 31 號,Thea Flowers 自己合併了 PR。注意這個教程頁面是臨時的單獨頁面,還沒有正式放到打包教程的頁面裡。

2017 年 9 月 1 號,KR 在 Pipenv 的 README 里加了這樣一行介紹語:「Pipenv — the officially recommended Python packaging tool from Python.org

,free (as in freedom).」(commit

其中的關鍵內容翻譯過來大概是「官方推薦的 Python 打包工具,來自 Python.org」。

僅僅因為在 PyPA 的打包檔案里加入了一個短教程(其中介紹了使用 Pipenv 安裝和管理依賴),然後 KR 就在 Pipenv 的介紹裡宣傳這是「官方推薦」,而註明的官方來源則是「http://Python.org」,這兩個關鍵詞背後的超連結都是 PyPA 打包檔案的 Pipenv 介紹。packaging.python.org(PyPA) 和 python.org(Python 官方) 的區別很大,很明顯,他清楚兩者的區別,但又故意沒有表達清楚。

退一步講,不管他的意圖是什麼,這樣的措辭都會讓人以為是 Python 官方推薦的打包工具,尤其是對 PyPA 這個組織不瞭解的人,看到 Python.org 都會認為是 Python 官方。

證據 2

在 PyCon 2018(五月),KR 在演講《Pipenv: The Future of Python Dependency Management》裡介紹 Pipenv 的賣點的時候,列在第一條的仍然是上面那一句「Officially recommended tool from http://python.org」:

和在 README 裡不同的是,這次在演講上別人沒法去點那個 python.org 的連結去甄別究竟是 python.org(Python 官方) 還是 packaging.python.org(PyPA)。而 KR 在介紹這裡的時候沒有任何說明,直接說是「來自 Python.org 的官方推薦」。

至於 KR 和 PyPA 或者說和 Thea Flowers 有什麼關係?把 Pipenv 的介紹加到打包檔案是 Thea Flowers 的個人意願?還是 PyPA 的 35 個成員全部同意的結果?是什麼促使 PyPA 在 Pipenv 還不成熟、甚至教程裡的內容沒法在 Windows 上正常操作的情況下新增到打包教程裡?這些問題我暫時找不到答案。

(注:PyPA 指的是 Python Packaging Authority,一個負責維護 Python 打包相關的庫(比如 pip、virtualenv 等)和檔案的組織。)

從 0 升到 18 的措辭問題

而所謂的18.X.X是 calver versioning(基於日曆的版本)

在上一篇文章裡,我引用了一段 HN 上的評論來概括 Pipenv 在推廣方式上的問題:

Kenneth Retiz 濫用他在 PyPA 的位置(而且快速把一個實際上是 beta 狀態的產品的版本號從 0 升到 18)來暗示 Pipenv 已經非常穩定,受到大力支援並且非常官方,但事實卻並不是這樣。

這句話的英文原文是:

However,Kenneth abused his position with PyPA (and quickly bumped a what is a beta product to version 18) to imply Pipenv was more stable,more supported and more official than it really was.

其中關於版本的部分是「and quickly bumped a what is a beta product to version 18」,可能是我亂翻譯造成了誤解……我認為原文裡的 18 就是一個誇張的表達方式,把這裡的數字換成 100 也可以表達同樣的意思(也可能是指 0.3.0 跳到 3.0.1 那次)。換用日期版本號(CalVer)那次看起來沒什麼問題(11.10.4 -> 2018.05.12),所以我認為這裡的 18 和日期版本號沒關係。

Lockfile 只要過期就重新生成是合理的嗎?

> Kenneth Reitz 先是說 lockfile 只要是過期了就總是會被重新生成
這是對的,Pipfile和Pipfile.lock是對應的,當執行pipenv install後改了Pipfile,對應的Pipfile.lock就一定會改。錯誤的是,不應該改那些不相關包的版本: 既然已經是==的了,就表明確定了具體版本呀。
這些問題,其實源於 Pipfile對應依賴在一開始沒指定具體版本,也就是Pipfile對標requirements.txt,而Pipfile.lock只是當前環境的一個「快照」,如果Pipfile沒有明確版本就用Pipfile.lock裡面指定的。

我的主要想法是這樣的功能實現是不合理的。Pipenv 在安裝一個包的時候預設就使用萬用字元(*)版本寫到 Pipfile 是不合理的設計。這樣的設計不符合正常的開發流程和使用習慣。如果我在安裝一個包的時候就要明確自己要安裝哪個版本,以便在 Pipfile 裡固定版本,這樣會很不方便,而且讓 Pipfile.lock 的存在意義變得很弱。

按照 KR 自己的解釋,Pipfile 對標的是 http://requirements.in,Pipfile.lock 對標的是 requirements.txt:

按照大部分人的理解,Pipfile 是所有不固定版本的高層依賴的列表(unpinned),而 Pipfile.lock 是固定安裝時採用版本的詳細依賴列表(pinned),用來複現程式具體的依賴環境;除非我主動執行 update 命令更新某個依賴,否則 Pipfile.lock 不應該被改動。但實際的 Pipenv 並不是這樣,更新 Pipfile.lock 變成了頻繁發生(install/uninstall/update)的預設行為。

Poetry 分析依賴慢

Resolving dependencies... (422.9s)
安裝個包7分鐘,這... 誰能忍?你們試試把bluelog專案的依賴用poetry add加一遍需要多久?我反正體驗不下去了

實際測試安裝 Flask-SQLAlchemy,解析依賴花了 42 秒(Windows+代理),沒有 7 分鐘那麼誇張。因為解析依賴的結果會被快取,我就在另一臺 Mac(代理)上也試了一遍,結果只花了 8.3 秒。可能是網路狀況的問題?

另外我試了把 Bluelog 的所有依賴一次性安裝(Windows+代理),其中解析依賴只花了 16.8 秒(因為解析結果快取的原因,實際也許會稍久一點):

$ poetry add flask flask-ckeditor flask-mail flask-sqlalchemy flask-wtf flask-moment python-dotenv bootstrap-flask flask-login flask-debu gtoolbar gunicorn psycopg2 flask-migrate
Using version ^1.1 for flask
Using version ^0.4.3 for flask-ckeditor
Using version ^0.9.1 for flask-mail
Using version ^2.4 for flask-sqlalchemy
Using version ^0.14.2 for flask-wtf
Using version ^0.9.0 for flask-moment
Using version ^0.10.3 for python-dotenv
Using version ^1.0 for bootstrap-flask
Using version ^0.4.1 for flask-login
Using version ^0.10.1 for flask-debugtoolbar
Using version ^19.9 for gunicorn
Using version ^2.8 for psycopg2
Using version ^2.5 for flask-migrate

Updating dependencies
Resolving dependencies... (16.8s)複製程式碼

所以 Poetry 或許沒那麼糟糕(當然我還沒深入使用過)。

星星

雖然不是決定性的,但是對於這Star不到6K的專案來說我是不敢用的

Pipenv 的 Star 的確很多(而且 README、檔案甚至程式碼裡到處都是星星✨),KR 可是個營銷專家,但專案質量卻並沒有那麼好。反正我現在一看見星星和蛋糕就有點頭疼。

✨?✨

另外,順便說一句,pip(5627)、virtualenv(3189)和 setuptools(883) 的 Star 數量都沒到六千……

好吧,我承認最後這兩段是在抬槓 :D