PEP 423 – 與打包相關的命名約定和方法
- 作者:
- Benoit Bryon <benoit at marmelune.net>
- 討論至:
- Distutils-SIG 郵件列表
- 狀態:
- 推遲
- 型別:
- 資訊性
- 主題:
- 打包
- 建立日期:
- 2012年5月24日
- 釋出歷史:
摘要
本文件涉及
- Python專案名稱,
- 正在分發的Python包或模組名稱,
- 名稱空間包。
它為分發作者提供了指南和方法
PEP 延期
本PEP的進一步審議已被推遲,至少要等到 PEP 426(軟體包元資料2.0)及相關更新解決之後。
術語
參考是Python文件中的打包術語。
與其他 PEP 的關係
概述
以下是選擇名稱時應遵循的指南摘要列表
- 理解並尊重新命名空間所有權.
- 如果您的專案與另一個專案或社群相關
- 在主專案文件中搜索約定,因為專案應該組織社群貢獻。
- 如果存在,請遵循特定專案或相關社群約定。
- 如果沒有約定,請遵循標準命名模式。
- 確保您的專案名稱是唯一的,即避免重複
- 確保分發包和模組名稱是唯一的,除非您明確希望分發現有包或模組的替代品。對包/模組名稱和專案名稱使用相同的值是實現此目的的推薦方式。
- 一次只分發一個包或模組,除非您知道自己在做什麼。這樣可以應用“使用單一名稱”規則,從而使名稱保持一致。
- 使您的專案易於發現和記住
- 避免深度巢狀。扁平化的東西比巢狀的更容易使用和記住
- 建議使用一到兩個名稱空間級別,因為它們幾乎總是足夠的。
- 即使不推薦,三層也實際上是常見的。
- 在大多數情況下,您不需要超過三個級別。
- 遵循PEP 8中包和模組名稱的語法。
- 如果您遵循了特定約定,或者您的專案旨在接收社群貢獻,請組織社群貢獻。
- 如果仍然有疑問,請諮詢.
如有疑問,請諮詢
如果您閱讀本文件後仍感到不確定,請在IRC或郵件列表上諮詢Python社群。
頂級名稱空間與程式碼所有權相關
這有助於避免專案名稱之間的衝突。
所有權可以是
- 個人。示例:gp.fileupload 由Gael Pasgrimaud擁有和維護。
- 組織。示例
- zest.releaser 由Zest Software擁有和維護。
- Django 由Django Software Foundation擁有和維護。
- 一個團體或社群。示例:sphinx 由Sphinx專案的開發人員維護,而不僅僅是其作者Georg Brandl。
- 與另一個包相關的團體或社群。示例:collective.recaptcha 由其作者David Glick,Groundwire擁有。但“collective”名稱空間由Plone社群擁有。
尊重所有權
在使用名稱空間之前,請了解其目的。
除非明確授權,否則不要插入您不擁有的名稱空間。
例如,不要插入“django.contrib”名稱空間,因為它由Django的核心貢獻者管理。
專案作者可以定義例外情況。參見下面的組織社群貢獻。
此外,此規則適用於非Python專案。
例如,不要使用“apache”作為頂級名稱空間:“Apache”是一個現有專案的名稱(在“Apache”的情況下,它也是一個商標)。
私有(包括閉源)專案使用名稱空間
...因為私有專案由某人擁有。因此,應用所有權規則。
對於內部/客戶專案,使用您的公司名稱作為名稱空間。
此規則適用於閉源專案。
例如,如果您正在為“Python Sport”公司建立一個“climbing”專案:使用“pythonsport.climbing”名稱,即使它是閉源的。
個人專案使用名稱空間
...因為它們由個人擁有。因此,應用所有權規則。
即使專案具有“內部”或“個人”名稱,將其作為開源專案釋出也無需羞愧。
如果專案發展到作者希望更改所有權的地步(即專案不再屬於個人),請記住重新命名專案很容易。
社群擁有的專案可以避免名稱空間包
如果您的專案足夠通用(即它不是另一個產品或框架的貢獻),您可以避免名稱空間包。基本條件通常是您的專案由專門從事此專案的團體(即開發團隊)擁有。
只有當您確實打算讓程式碼為社群所有時,才使用“共享”名稱空間。
例如,sphinx專案屬於Sphinx開發團隊。沒有必要擁有一個只有一個“sphinx.sphinx”專案的“sphinx”名稱空間包。
如有疑問,請使用個人/組織名稱空間
如果您的專案確實是實驗性的,最好的選擇是使用個人或組織名稱空間
- 它允許專案儘早釋出。
- 如果專案被廢棄,它不會佔用名稱。
- 它不會阻礙未來的變化。當專案成熟且沒有理由保留個人所有權時,仍然可以重新命名專案。
使用單一名稱
每個專案只分發一個包(或一個模組),並使用包(或模組)名稱作為專案名稱。
- 它避免了專案名稱與分發包或模組名稱之間可能產生的混淆。
- 它使名稱保持一致。
- 它是明確的:當看到專案名稱時,可以猜測包/模組名稱,反之亦然。
- 它還限制了包/模組名稱之間的隱式衝突。透過使用單一名稱,當您在PyPI上註冊專案名稱時,您也執行了基本的包/模組名稱可用性驗證。
例如,pipeline、python-pipeline 和 django-pipeline 都分發了一個名為“pipeline”的包或模組。因此,安裝其中兩個會導致錯誤。如果這些分發使用單一名稱,則不會發生此問題。
是
- 包名稱:“kheops.pyramid”,即
import kheops.pyramid - 專案名稱:“kheops.pyramid”,即
pip install kheops.pyramid
否
- 包名稱:“kheops”
- 專案名稱:“KheopsPyramid”
注意
由於歷史原因,PyPI 包含許多專案和分發包/模組名稱不同的分發。
多個包/模組應該很少見
從技術上講,Python 分發可以提供多個包和/或模組。有關詳細資訊,請參閱安裝指令碼參考。
有些分發確實如此。例如,setuptools 和 distribute 都聲明瞭“pkg_resources”、“easy_install”和“site”模組,此外還有各自的“setuptools”和“distribute”包。
將此用例視為例外。在大多數情況下,您不需要此功能。因此,一個分發應該一次只提供一個包或模組。
不同的名稱應該很少見
使用單一名稱規則的一個顯著例外是當您明確需要不同名稱時。
例如,Pillow 專案提供了原始 PIL 分發的替代方案。這兩個專案都分發一個“PIL”包。
將此用例視為例外。在大多數情況下,您不需要此功能。因此,分發包名稱應與專案名稱相同。
遵循PEP 8中包和模組名稱的語法
PEP 8 適用於 Python 包和模組的名稱。
選擇令人難忘的名稱
專案名稱的一件重要事情是它要令人難忘。
例如,celery 不是一個有意義的名稱。最初,它不明顯是關於訊息佇列的。但它令人難忘,部分原因是可以用來餵養一個RabbitMQ伺服器。
選擇有意義的名稱
問問自己“我將如何用一句話描述這個名稱的用途?”,然後“有人能透過檢視名稱來猜測嗎?”
例如,DateUtils 是一個有意義的名稱。它顯然是處理日期實用程式的。
當您使用名稱空間時,儘量使每個部分都具有意義。
使用打包元資料
將專案名稱視為 PyPI 上的唯一識別符號
- 重要的是這些識別符號保持人類可讀。
- 如果這些識別符號有意義,那就更好了。
- 但識別符號的主要目的不是對專案進行分類或描述。
分類器和關鍵詞元資料用於分發的分類。 摘要和描述元資料用於描述專案。
例如,有一個“Framework :: Twisted”分類器。即使名稱相當異構(它們不遵循特定模式),我們仍然可以獲得列表。
為了組織社群貢獻,關於名稱和名稱空間的約定很重要,但關於元資料的約定應該更重要。
例如,我們可以在許多地方找到 Plone 小部件
- plone.portlet.*
- collective.portlet.*
- collective.portlets.*
- collective.*.portlets
- 一些與供應商相關的專案,如“quintagroup.portlet.cumulus”
- 甚至名稱中沒有出現“portlet”模式的專案。
即使 Plone 社群有約定,使用名稱來分類分發也是不合適的。透過過濾名稱,無法獲得提供 Plone 小部件的所有分發的完整列表。但如果所有這些分發都使用“Framework :: Plone”分類器和“portlet”關鍵字,那將是可能的。
避免深度巢狀
Python之禪說“扁平優於巢狀”。
兩層幾乎總是足夠的
不要在深層巢狀的層次結構中定義所有內容:您最終會得到諸如“pythonsport.common.maps.forest”之類的專案和包。這種型別的名稱既冗長又笨重(例如,如果您從包中匯入很多內容)。
此外,大型層次結構往往會隨著時間的推移而崩潰,因為不同包之間的界限變得模糊不清。
共識是優先使用兩層巢狀。
例如,我們有 plone.principalsource 而不是 plone.source.principal 或類似的東西。名稱更短,包結構更簡單,並且在這裡擁有三層巢狀幾乎沒有任何好處。試圖將所有“核心 Plone”源(源是一種詞彙表)放入 plone.source.* 名稱空間是不切實際的,部分原因是一些源是其他包的一部分,部分原因是因為源已經存在於其他地方。如果我們建立了一個新的名稱空間,它從一開始就會被不一致地使用。
是:“pyranha”
是:“pythonsport.climbing”
是:“pythonsport.forestmap”
否:“pythonsport.maps.forest”
所有權只使用一層
不要使用3層來在社群名稱空間中設定個人/組織所有權。
例如,讓我們考慮
- 您正在插入一個社群名稱空間,例如“collective”。
- 您想新增一個更嚴格的“所有權”級別,以避免社群內部的衝突。
在這種情況下,您最好將最嚴格的所有權級別作為第一層。
例如,其中“collective”是“gergovie”所屬的主要社群名稱空間,“vercingetorix”是“gergovie”作者的名字
否:“collective.vercingetorix.gergovie”
是:“vercingetorix.gergovie”
不要使用名稱空間層進行分類
請改用打包元資料。
不要使用超過3層
從技術上講,您可以建立深度巢狀的層次結構。但是,在大多數情況下,您不應該需要它。
注意
即使是名稱空間是標準的社群,也不使用超過3層。
在PyPI上註冊名稱
PyPI 是 Python 社群中分發的中心位置。因此,它也是註冊專案和包名稱的地方。
有關詳細資訊,請參閱向包索引註冊。
方法
以下方法將幫助您遵循上述指南和約定。
如何檢查名稱可用性?
在選擇專案名稱之前,請確保它尚未在以下位置註冊
- PyPI
- 就是這樣。PyPI是唯一的官方場所。
例如,您也可以在各種位置(如流行的程式碼託管服務)進行檢查,但請記住,PyPI是您在Python社群中可以**註冊**名稱的唯一地方。
這就是為什麼在PyPI上註冊名稱很重要的原因。
還要確保已分發包或模組的名稱尚未註冊
- 在Python 標準庫中。
- 在
PyPI上的專案內部。目前沒有相關的輔助工具。請注意,遵循使用單一名稱規則的專案越多,驗證就越容易。 - 您可以諮詢社群。
使用單一名稱規則也有助於您避免與包名稱衝突:如果專案名稱可用,那麼包名稱也很可能可用。
如何重新命名專案?
重新命名專案是可能的,但請記住這會造成一些混淆。因此,請特別注意 README 和文件,以便使用者理解發生了什麼。
- 首先,不要從 PyPI 中刪除舊的分發。因為有些使用者可能正在使用它們。
- 複製舊專案,然後更改名稱(專案和包/模組)。至少要注意
- 打包檔案,
- 包含原始檔的資料夾名稱,
- 文件,包括 README,
- 程式碼中的匯入語句。
- 在 setup.cfg 檔案中為新分發分配
Obsoletes-Dist元資料。請參閱 PEP 345 關於 Obsolete-Dist 和 setup.cfg 規範。 - 釋出重新命名專案的新版本,然後釋出它。
- 編輯舊專案
- 新增對新專案的依賴,
- 刪除除打包內容之外的所有內容,
- 在安裝指令碼中新增
Development Status :: 7 - Inactive分類器, - 釋出新版本。
因此,舊包的使用者
- 可以繼續使用已棄用版本的舊分發,
- 可以升級到舊分發的最新版本,該版本是空的……
- ...並自動下載新的分發作為舊分發的依賴項。
發現舊專案的使用者會看到它處於非活動狀態。
改進PyPI上重新命名專案的處理
如果許多專案都遵循重新命名指南,那麼許多舊的分發將具有以下特徵
Development Status :: 7 - Inactive分類器。- 最新版本為空,除了打包內容。
- 最新版本“重定向”到另一個分發。例如,它對重新命名專案具有單一依賴關係。
- 在較新的分發中被引用為
Obsoletes-Dist。
因此,將能夠檢測重新命名的專案並提高 PyPI 的可讀性。這樣使用者就可以專注於活動分發。但目前不需要此功能。沒有緊迫性。本文件中將不涉及此內容。
如何將命名指南應用於現有專案?
現有專案沒有義務重新命名。出於顯而易見的原因,選擇權留給專案作者和維護者。
但是,邀請專案作者
- 至少,說明當前命名。
- 然後規劃並推廣遷移。
- 可選地實際重新命名現有專案或分發的包/模組。
關於當前命名的說明
首先,重要的是您要說明當前的選擇
- 問問自己“我為什麼選擇當前名稱?”,然後記錄下來。
- 如果與本文件中提供的指南有差異,您應該告知您的使用者。
- 如果可能,請在專案的錯誤跟蹤器中建立問題,至少作為記錄。然後您可以稍後解決它們,或者可能將其標記為“wontfix”。
旨在接收社群貢獻的專案也應該組織社群貢獻。
促進遷移
每個 Python 開發者都應儘可能遷移,或在其各自的社群中推廣遷移。
將這些指南應用於您的專案,然後社群就會看到它是安全的。
特別是,“領導者”,如流行專案的作者,具有影響力,他們擁有權力,因此對社群負有責任。
將這些指南應用於流行專案,然後社群也會採納這些約定。
專案應在釋出新(主要)版本時促進遷移,特別是如果此版本引入了對 Python 3.x、新標準庫的打包或名稱空間包的支援。
機會
隨著 Python 3.3 的開發
- 許多專案不相容 Python 3.x。這包括“大型”產品或框架。這意味著許多專案將不得不進行遷移以支援 Python 3.x。
- 打包(又稱 distutils2)正在啟動。釋出後,專案將被邀請遷移並使用新的打包。
- PEP 420 為 Python 帶來了名稱空間包的官方支援。
這意味著大多數活躍專案將在未來一年內遷移以支援 Python 3.x、新打包或新名稱空間包。
這樣的機會是獨一無二的,不會很快再次出現!所以讓我們儘快(即現在)引入和推廣命名約定。
參考資料
額外背景
- Martin Aspeli 關於名稱的文章。本文件的某些部分引用了這篇文章。
- 開發中的官方打包文件.
- 包裝徒步指南,其中有一個“命名規範”的空佔位符。
參考文獻和腳註
版權
本文件已置於公共領域。
來源:https://github.com/python/peps/blob/main/peps/pep-0423.rst