pip install -e.出現(xiàn)xxx module not found error的問題解決方案
問題說明與解決方案
在本地安裝wheeled_lab這個包的時候一直出現(xiàn)toml module找不到的錯誤,但是不管是conda的環(huán)境還是python的基本環(huán)境都已經安裝過了toml包,后來發(fā)現(xiàn)是Python包在構建時的構建標準問題。
Python 包安裝系統(tǒng)正在從舊的 setup.py 方式過渡到新的 PEP 517/518 標準(使用 pyproject.toml
)。
當在ubuntu22.04
運行 pip install -e .
時,pip
會嘗試使用現(xiàn)代的 PEP 517 標準來構建你的包。這個過程會創(chuàng)建一個臨時的、隔離的構建環(huán)境。你的項目的構建過程(即使只是為了獲取元數(shù)據(jù))依賴于 toml
這個包(通常是 setup.py
內部需要讀取 pyproject.toml
文件),但這個臨時的構建環(huán)境里并沒有預裝 toml
,因此導致了 ModuleNotFoundError
,整個安裝過程就失敗了。
添加 pyproject.toml
更長期的解決方案是為你的項目添加一個 pyproject.toml
文件。在項目根目錄(wheeledlab
目錄)創(chuàng)建 pyproject.toml
文件,內容如下:
[build-system] requires = ["setuptools>=64.0.0", "wheel"] build-backend = "setuptools.build_meta"
然后重新安裝:
pip install -e .
問題原因詳細解釋
這個方法很好地解決了我的問題,更詳細地解釋一下問題出現(xiàn)的原因:
pip
在構建你的包時,并不會使用你當前的 conda 環(huán)境 (WL)
,而是創(chuàng)建了一個臨時的、隔離的“構建環(huán)境”(Isolated Build Environment)。
詳細解釋:
1.過去的方式(你所預期的行為)
- 在舊版本的
pip
和setuptools
中,當你運行pip install
時,它會直接在你當前激活的環(huán)境中執(zhí)行setup.py
腳本。 - 如果
setup.py
需要某個包(比如toml
),它會期望這個包已經存在于你的當前環(huán)境中。 - 這就是為什么我們以前會說“請先安裝好所有構建依賴”。
2.現(xiàn)在的方式(實際發(fā)生的情況)
- 為了解決“構建依賴”和“運行時依賴”混淆不清、以及構建過程不穩(wěn)定的問題,
Python
社區(qū)引入了PEP 517
和PEP 518
標準。
這個新標準的核心思想就是 構建隔離 (Build Isolation)。
當你運行 pip install -e .
時,pip 會執(zhí)行以下步驟:
- 檢查
pyproject.toml
:pip
首先會尋找pyproject.toml
文件來獲取構建指令。 - 創(chuàng)建隔離環(huán)境:
pip
會在系統(tǒng)臨時目錄(比如/tmp/pip-build-env-xxxx/
)中創(chuàng)建一個全新的、非常迷你的虛擬環(huán)境。這個環(huán)境是完全獨立的,它不包含你WL conda
環(huán)境中的任何包(除了最基礎的Python
和pip
本身)。
安裝構建依賴:
- 沒有
pyproject.toml
時(你最初遇到的情況):pip
不知道這個隔離環(huán)境需要什么額外的包。它只安裝了最基礎的setuptools
和wheel
。因此,當你的setup.py
試圖import toml
時,在這個“干凈”的隔離環(huán)境里找不到它,從而報錯ModuleNotFoundError
。 - 有
pyproject.toml
時(你解決后的情況):pip
讀取了你的pyproject.toml
文件,看到了 [build-system] 下的requires = ["setuptools>=61.0", "toml"]
。pip
于是在那個隔離的構建環(huán)境中,首先執(zhí)行pip install setuptools toml
。 - 執(zhí)行構建:現(xiàn)在,隔離環(huán)境里已經有了
toml
包。pip
接著在這個準備好的環(huán)境中執(zhí)行構建后端(setuptools.build_meta),這個過程就不會再因為缺少toml
而失敗了。 - 安裝項目:構建成功獲取到元信息后,
pip
會將你的項目以可編輯模式安裝回你原來的 WL` 環(huán)境。 - 清理:臨時的隔離構建環(huán)境被刪除。
總結與類比
你可以把這個過程想象成去一個高科技實驗室做實驗:
- 你的 Conda 環(huán)境 (WL):是你自己的、堆滿各種工具和材料的個人工作室。你在里面安裝了 toml。
- 隔離的構建環(huán)境:是一個無菌操作臺(Clean Room)。你不能把你工作室里所有的東西都帶進去,只能帶清單上列出的必需品。
- pyproject.toml:就是那張必需品清單。
- 在你沒有提供清單 (pyproject.toml) 的時候,pip 只帶了最基礎的工具進入無菌操作臺。當實驗(構建)需要用到 toml 這個特殊工具時,發(fā)現(xiàn)沒帶,實驗失敗。當你提供了清單 (pyproject.toml) 后,pip 在進入無菌操作臺之前,先按照清單把 setuptools 和 toml 都準備好了。這樣實驗(構建)就能順利進行了。
所以,即使你的個人工作室 (WL 環(huán)境) 里有 toml,但無菌操作臺(隔離構建環(huán)境)里一開始是沒有的。pyproject.toml 的作用就是告訴 pip 該往這個無菌操作臺里準備些什么。
使用什么標準安裝取決于什么
那么到底是用setup.py安裝還是PEP 517/518標準安裝取決于什么呢,Ubuntu系統(tǒng)版本,Python版本,setuptools版本還是什么
在 Python 生態(tài)中,setup.py
安裝 vs. PEP 517/518 標準安裝的選擇取決于多個因素,但核心是由 pip
、setuptools
版本和項目配置共同決定的,而不是直接由 Ubuntu 系統(tǒng)版本或 Python 版本決定。
以下是詳細分析:
1. 關鍵決定因素
因素 | 影響方式 |
---|---|
pip 版本 | 現(xiàn)代 pip(≥19.0)默認啟用 PEP 517/518,舊版可能回退到 setup.py |
setuptools 版本 | 新版 setuptools(≥40.8.0)支持 PEP 517/518,舊版可能僅支持 setup.py |
項目配置 | 存在 pyproject.toml 時優(yōu)先用 PEP 517/518,否則回退到 setup.py |
Python 版本 | 間接影響(Python ≥3.7 原生支持 PEP 517/518,但舊版可通過工具鏈支持) |
系統(tǒng)環(huán)境 | 幾乎無直接影響(除非系統(tǒng)強制鎖定了 pip/setuptools 版本) |
2. 具體行為規(guī)則
(1) 當項目有pyproject.toml時
- pip ≥19.0:強制使用 PEP 517/518 構建(隔離環(huán)境)。
[build-system] requires = ["setuptools>=61.0", "wheel"] # 必須顯式聲明構建依賴 build-backend = "setuptools.build_meta" # 使用 setuptools 作為后端
- 如果缺少
toml
等依賴,會報錯(如你的案例)。 - 解決方案:在
pyproject.toml
的requires
中添加缺失的包。
(2) 當項目無pyproject.toml時
pip ≥19.0:回退到傳統(tǒng) setup.py
方式(非隔離環(huán)境)。
- 依賴主環(huán)境的包(可能引發(fā)沖突)。
- 逐步被棄用(會看到警告)。
3. 版本兼容性對照表
工具/配置 | 支持 PEP 517/518 的最低版本 | 備注 |
---|---|---|
pip | ≥19.0 (2019) | 舊版需升級:python -m pip install -U pip |
setuptools | ≥40.8.0 (2018) | 新版推薦 ≥61.0 |
Python | ≥3.7 (官方支持) | 更低版本可通過工具鏈支持 |
pyproject.toml | 無版本要求 | 文件存在即觸發(fā) PEP 517/518 |
4. 如何強制選擇安裝方式?
(1) 強制使用傳統(tǒng)setup.py(不推薦)
pip install -e . --no-use-pep517
- 繞過 PEP 517/518,直接運行
setup.py
(可能引發(fā)其他問題)。
(2) 強制使用 PEP 517/518
pip install -e . --use-pep517
- 即使無
pyproject.toml
也嘗試用 PEP 517(可能失?。?/li>
5. 為什么你的案例中toml在主環(huán)境無效?
根本原因:PEP 517/518 的隔離構建機制。
- 主環(huán)境的包(如已安裝的
toml
)不會自動繼承到臨時構建環(huán)境。 - 必須通過
pyproject.toml
的requires
顯式聲明依賴。
6. 最佳實踐建議
始終添加 pyproject.toml
- 即使項目簡單,也明確聲明構建依賴(未來兼容性)。
[build-system] requires = ["setuptools>=64.0", "wheel"] build-backend = "setuptools.build_meta"
升級工具鏈
python -m pip install -U pip setuptools wheel
避免混合使用新舊方式
- 不要同時依賴
setup.py
和pyproject.toml
的隱式行為。
總結
決定性因素:pyproject.toml
存在與否 + pip
/setuptools
版本。
系統(tǒng)/Python 版本:僅影響工具鏈的默認版本,不直接決定行為。
解決方案:顯式聲明依賴(pyproject.toml
)并保持工具鏈更新。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Python基于均值漂移算法和分水嶺算法實現(xiàn)圖像分割
圖像分割是將圖像分成若干具有獨特性質的區(qū)域并提取感興趣目標的技術和過程。這篇文章將詳細講解基于均值漂移算法和分水嶺算法的圖像分割,需要的可以參考一下2023-01-01python中zip和unzip數(shù)據(jù)的方法
這篇文章主要介紹了python中zip和unzip數(shù)據(jù)的方法,實例分析了Python中zlib模塊的相關使用技巧,需要的朋友可以參考下2015-05-05Python學習之.iloc與.loc的區(qū)別、聯(lián)系和用法
loc和iloc都是pandas工具中定位某一行的函數(shù),下面這篇文章主要給大家介紹了關于Python學習之.iloc與.loc的區(qū)別、聯(lián)系和用法的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-05-05django應用JWT(JSON?Web?Token)實戰(zhàn)教程
在前后端分離的項目中,JWT(JSON?Web?Token)作為一種廣泛使用的身份驗證和授權機制,提供了一種安全、高效的方式來保護RESTful?API,本文詳細介紹了JWT的概念、優(yōu)勢、在Django中的應用步驟和使用方法,是構建安全、高效Web應用的有效指南2024-10-10