開發(fā)指南:環(huán)境搭建、Owned vs Vendored 代碼治理與測試體系全解析)
Pipenv 貢獻(xiàn)開發(fā)指南環(huán)境搭建、Owned vs Vendored 代碼治理與測試體系全解析【免費(fèi)下載鏈接】pipenvPython Development Workflow for Humans.項(xiàng)目地址: https://gitcode.com/gh_mirrors/pi/pipenvPipenv 是為人類設(shè)計(jì)的 Python 開發(fā)工作流工具它自動(dòng)管理虛擬環(huán)境與依賴并通過Pipfile/Pipfile.lock實(shí)現(xiàn)確定性構(gòu)建。本文以倉庫根目錄 CONTRIBUTING.md 與其完整正文 docs/dev/contributing.md 為核心骨架系統(tǒng)梳理向 Pipenv 提交代碼、文檔與 bug 報(bào)告的完整路徑并深入講解該項(xiàng)目極具特色的Owned項(xiàng)目自有vs Vendored供應(yīng)商內(nèi)置代碼治理策略、基于 towncrier 的變更日志機(jī)制以及依賴本地 pypiserver 的測試體系。讀完本文你將能獨(dú)立完成從克隆倉庫、搭建可編輯開發(fā)環(huán)境、編寫 news fragment、運(yùn)行全量測試到提交 Pull Request 的全過程并準(zhǔn)確判斷哪些代碼可以自由重構(gòu)、哪些代碼必須交給 vendoring 工具鏈處理。貢獻(xiàn)總覽與協(xié)作基本規(guī)則Pipenv 的貢獻(xiàn)指南按貢獻(xiàn)類型分為若干章節(jié)但所有貢獻(xiàn)者都需先遵守三條通用準(zhǔn)則Be Cordial保持友善這是項(xiàng)目創(chuàng)始人 Kenneth Reitz 定下的黃金法則——保持友善否則請離開。所有貢獻(xiàn)包括 bug 報(bào)告與特性請求都被歡迎前提是參與者彼此尊重。盡早獲取反饋Get Early Feedback不必等到貢獻(xiàn)完美無缺才提交。盡早提交未完成版本并不會降低被接受的概率反而能避免把大量工作投入到一個(gè)并不適合項(xiàng)目方向的貢獻(xiàn)上。貢獻(xiàn)適宜性Contribution Suitability項(xiàng)目維護(hù)者對貢獻(xiàn)是否適合 Pipenv 擁有最終決定權(quán)。所有貢獻(xiàn)都會被認(rèn)真考慮但若與項(xiàng)目當(dāng)前目標(biāo)或需求不符可能會被拒絕只要遵循了本指南下一次貢獻(xiàn)被接受的概率會更高。問題提問渠道GitHub Issue 追蹤器只用于 bug 報(bào)告與特性請求不用于提問。使用類問題應(yīng)發(fā)往 Stack Overflow 并打上pipenv標(biāo)簽以保證被及時(shí)且準(zhǔn)確地解答。開發(fā)環(huán)境搭建可編輯安裝與 pre-commit向 Pipenv 提交代碼前需要先把倉庫版本的 Pipenv 以**可編輯模式editable install**安裝覆蓋全局安裝的其它版本以避免pipenv文件夾被隱式加入sys.path后產(chǎn)生沖突。Pipenv 借鑒了 pip 的做法使用pre-commit 鉤子自動(dòng)應(yīng)用 lint 與代碼格式化構(gòu)建階段也會校驗(yàn)這些 lint 規(guī)則一旦檢測到未格式化的改動(dòng)構(gòu)建就會失敗。因此搭建環(huán)境的完整流程為$ python -m pip install -e .[tests,dev] $ pipenv install --dev $ pipenv run python -m pip install -e .[tests,dev] # 配置在每次 commit 開始時(shí)執(zhí)行 pre-commit 檢查 $ pre-commit install # 如需針對全部項(xiàng)目文件校驗(yàn) pre-commit 配置 $ pre-commit run --all-files --verbose其中[tests,dev]兩組可選依賴在 pyproject.toml 中定義dev組包含black當(dāng)前鎖定black26.3.1、flake8、invoke、parver、sphinx、towncrier等開發(fā)工具tests組包含pytest、pytest-rerunfailures、pytest-timeout、pytest-xdist等測試工具。格式化的具體規(guī)則也定義在 pyproject.toml 中blackline-length 90并顯式排除了pipenv/vendor、pipenv/patched、tests/pypi、tests/test_artifacts等目錄——這正是下文Owned vs Vendored策略在工具鏈層面的落地ruffline-length 137啟用了E/F/Wpyflakes/pycodestyle以及Iisort、UPpyupgrade、Bbugbear、PLpylint等幾十個(gè)規(guī)則集同樣排除了pipenv/patched/*與pipenv/vendor/*。也就是說lint 與格式化規(guī)則只約束自有代碼供應(yīng)商代碼由工具鏈單獨(dú)管理。這是理解 Pipenv 代碼庫組織方式的第一把鑰匙。代碼提交的標(biāo)準(zhǔn)流程文檔給出的提交流程是一份清晰的檢查清單在 GitHub 上 Fork 倉庫按上文搭建開發(fā)環(huán)境運(yùn)行測試確認(rèn)本機(jī)全部通過若失敗需自行排查無法定位時(shí)按 bug 報(bào)告規(guī)范提交 issue先編寫能夠演示該 bug 或新特性的測試并確認(rèn)它們當(dāng)前是失敗的做出代碼改動(dòng)再次運(yùn)行完整測試套件確認(rèn)全部通過包括你新加的測試向主倉庫的main分支發(fā)送 GitHub Pull Request。先寫失敗測試、再做實(shí)現(xiàn)的順序是項(xiàng)目明確要求的測試先行既證明了 bug 的存在也防止了沒有測試保護(hù)的改動(dòng)混入主干。此外貢獻(xiàn)在被合并前必須經(jīng)過Code Review實(shí)現(xiàn)者應(yīng)落實(shí)評審意見若強(qiáng)烈反對需冷靜說明理由若評審意見最終仍被判定有效則要么落實(shí)、要么撤回貢獻(xiàn)。Package Index測試用本地包源為加速測試依賴包索引用于 lock 與 install的測試都會使用 tests/pypi 目錄下自帶的供應(yīng)商包通過本地服務(wù)器提供。為某個(gè)包新增 release 時(shí)優(yōu)先使用.tar.gz或通用 wheel如py2.py3-none若兩者均不可用則需為所有可用的架構(gòu)與平臺分別添加 wheel。Owned vs Vendored代碼所有權(quán)治理策略這是 Pipenv 貢獻(xiàn)指南中最具技術(shù)深度、也是編輯代碼前必須理解的一節(jié)。pipenv/下的每個(gè) Python 文件都嚴(yán)格處于兩種狀態(tài)之一知道文件處于哪種狀態(tài)就決定了誰能編輯它、以及按什么規(guī)則編輯。不存在第三種狀態(tài)。狀態(tài)范圍編輯規(guī)則Owned自有pipenv/下除pipenv/patched/與pipenv/vendor/之外的所有代碼可自由重構(gòu)適用項(xiàng)目規(guī)范、lintruff check pipenv/與測試覆蓋要求沒有上游需要同步Vendored供應(yīng)商內(nèi)置pipenv/patched/pip 的補(bǔ)丁副本與pipenv/vendor/第三方包禁止手改由項(xiàng)目的 vendoring 工具鏈從上游重新同步更新通過vendor:前綴的提交驅(qū)動(dòng)工具鏈完成該策略的由來是項(xiàng)目用慘痛教訓(xùn)換來的最壞情況的中間態(tài)——多年前從上游庫復(fù)制粘貼、從未再同步、在保持別人的代碼不該動(dòng)的錯(cuò)覺下與上游靜默漂移——正是 Initiative B 清掃行動(dòng)耗費(fèi)五個(gè)工作單元才清理干凈的問題。Pipenv 沒有足夠的人力去追蹤已漂移的內(nèi)聯(lián)副本。因此如果一份上游代碼值得保留在倉庫內(nèi)要么重新 vendor 到pipenv/vendor/讓工具鏈跟蹤它要么正式收養(yǎng)為自有代碼讓項(xiàng)目擁有它二選一。從倉庫結(jié)構(gòu)看vendoring 工具鏈的痕跡清晰可見tasks/vendoring/patches/patched 目錄存放著作用于pipenv/patched/pip 補(bǔ)丁副本的補(bǔ)丁文件例如pipenv_import.patch、pip_specifier.patch、pip_tarfile_link_safety.patch等它們定義了 patched pip 相對上游的差異pyproject.toml 的 ruff/black 排除規(guī)則、以及 Makefile 中讀取pipenv/patched/pip/__init__.py版本號來構(gòu)建 wheel 的邏輯都印證了兩棵樹由工具管理、不手改的約定。例外刻意分叉Deliberate Forks自有代碼樹中保留上游函數(shù)的刻意分叉是允許的前提是分叉與上游行為有意不同且必須在 docstring 中攜帶Provenance來源聲明注明所分叉的上游符號并寫明刻意差異是什么。指南給出兩個(gè)隨 Initiative B Wave 1c 一起落地的范例讀者可以在源碼中直接驗(yàn)證pipenv/utils/requirements.py其中的redact_netloc與redact_auth_from_url是pip._internal.utils.misc.redact_netloc/redact_auth_from_url的刻意分叉差異在于保留環(huán)境變量占位符與標(biāo)準(zhǔn) SSH 用戶名而非改寫成****差異在 docstring 中逐條注明pipenv/utils/requirementslib.pyunpack_url與get_http_url是對pip._internal.operations.prepare.unpack_url與get_http_url的原樣收養(yǎng)docstring 點(diǎn)名了上游符號并標(biāo)注了patched-pip 副本是否可直接調(diào)用這一待決問題。當(dāng)你新增或大改一個(gè)分叉時(shí)請遵循同樣的約定在 docstring 中寫一段Provenance:段落點(diǎn)名上游符號與刻意差異。兩年后的讀者永遠(yuǎn)不該靠猜來判斷某個(gè)函數(shù)是過時(shí)副本還是刻意分叉。支撐該策略的逐符號審計(jì)報(bào)告見 docs/dev/initiative-b-triage.md進(jìn)一步了解項(xiàng)目現(xiàn)代化進(jìn)程還可參考 docs/dev 下的多份 initiative 設(shè)計(jì)文檔。News Fragments基于 towncrier 的變更日志機(jī)制Pipenv 使用 towncrier 管理變更日志。每個(gè)改變用戶可見行為的 Pull Request 都必須附帶一個(gè) news fragment以確保改動(dòng)被收錄進(jìn)下個(gè)版本的CHANGELOG.md。創(chuàng)建 News Fragmentfragment 文件放在 news/ 目錄下命名為news/issue-number.type.rst其中type取值如下表與 pyproject.toml 中[tool.towncrier.type]的配置一一對應(yīng)類型描述是否出現(xiàn)在 CHANGELOGfeature新特性或改進(jìn)是behavior既有行為的變更是bugfix缺陷修復(fù)是vendor供應(yīng)商內(nèi)置庫的更新是doc僅文檔改進(jìn)是removal棄用或移除是process開發(fā)/CI 流程變更是trivial拼寫修復(fù)、重構(gòu)或其他次要改動(dòng)否不顯示在 CHANGELOG例如為 issue #1234 的 bug 修復(fù)添加條目$ echo Fixed the frobnication logic when the widget is None. news/1234.bugfix.rst倉庫 news/ 目錄中的既有 fragment如6701.bugfix.rst、pip-26.2.vendor.rst正是這一約定的實(shí)例pip-*這類以開頭的文件名與vendor類型對應(yīng)由 vendoring 工具鏈驅(qū)動(dòng)的供應(yīng)商更新流程。Trivial Fragment 的特殊約定trivial類型用于不需要用戶可見變更日志條目的改動(dòng)內(nèi)部重構(gòu)、僅測試改動(dòng)、注釋拼寫修復(fù)等$ echo . news/1234.trivial.rst注意CI 強(qiáng)制要求 trivial fragment 存在以此確認(rèn)你已考慮過是否需要變更日志條目但它會被有意排除在生成的CHANGELOG.md之外——towncrier 會收集這些文件、刪除它們并在輸出中靜默省略。fragment 內(nèi)容無需多余文字單個(gè).即可。本地預(yù)覽變更日志在不改動(dòng)任何文件的前提下預(yù)覽下一個(gè)版本日志$ towncrier build --draft --version 9999.0.0該命令將草稿輸出到 stdout。towncrier 的完整行為由 pyproject.toml 配置directory news/、filename CHANGELOG.md、template news/towncrier_template.rst各類型按Features Improvements、Bug Fixes、Vendored Libraries、Trivial Changes等分組渲染其中trivial明確設(shè)置了showcontent false。Bug 報(bào)告規(guī)范Bug 報(bào)告同樣被視為重要貢獻(xiàn)記錄為 GitHub issue。提交時(shí)請注意避免重復(fù) issue務(wù)必先用 issue 搜索功能檢查歷史。若搜索標(biāo)題中的若干關(guān)鍵詞就能找到原有 issue重復(fù)報(bào)告通常會被立即關(guān)閉附上完整 traceback關(guān)于異常的報(bào)告必須包含完整回溯。只有異常文本或部分回溯沒有幫助缺失完整 traceback 的 issue 可能被直接關(guān)閉提供足夠信息至少包括四要素如何復(fù)現(xiàn)理想情況下是維護(hù)者可立即運(yùn)行的最小代碼樣本否則說明你的操作、發(fā)生頻率、運(yùn)行環(huán)境等預(yù)期結(jié)果運(yùn)行示例代碼后應(yīng)該發(fā)生什么、怎樣算成功實(shí)際結(jié)果具體如何失敗——拋異常掛起安裝的包不對實(shí)際與預(yù)期的差異是什么Pipenv 版本與安裝方式不同版本行為不同、bug 也不同且部分發(fā)行版會在官方代碼之上疊加補(bǔ)丁。若信息不全維護(hù)者會要求補(bǔ)充若始終不回應(yīng)澄清請求issue 會在未修復(fù)的情況下被關(guān)閉。運(yùn)行測試體系從 pytest 到本地 pypiserverPipenv 的測試采用pytest風(fēng)格基礎(chǔ)運(yùn)行方式極其簡單$ pytest但許多測試依賴運(yùn)行在localhost:8080上的私有 pypi 服務(wù)器。文檔提供了兩種啟動(dòng)方式使用項(xiàng)目腳本 run-tests.shLinux/macOS或 run-tests.batWindows它們會在調(diào)用 pytest 之前先啟動(dòng)pypiserver手動(dòng)啟動(dòng)后照常運(yùn)行 pytest# Linux 或 MacOS pipenv run pypi-server run -v --host0.0.0.0 --port8080 --hash-algosha256 --disable-fallback ./tests/pypi/ ./tests/fixtures # Windows cmd /c start pipenv run pypi-server run -v --host0.0.0.0 --port8080 --hash-algosha256 --disable-fallback ./tests/pypi/ ./tests/fixturespypiserver 的包源是 tests/pypi 與 tests/fixtures 目錄與上文Package Index一節(jié)的本地包策略互相印證run-tests.sh 中還能看到它使用臨時(shí)緩存目錄、用pipenv install --deploy --dev安裝依賴、并執(zhí)行g(shù)it submodule sync git submodule update --init --recursive等完整步驟。運(yùn)行子集標(biāo)準(zhǔn) pytest 過濾器全量測試耗時(shí)較長可按標(biāo)準(zhǔn) pytest 過濾器縮小范圍指定目錄或文件pytest tests/unit或pytest tests/unit/test_cmdparse.py關(guān)鍵字表達(dá)式pytest -k test_lock_editable_vcs_without_install指定 nodeidpytest tests/unit/test_cmdparse.py::test_parse指定標(biāo)記pytest -m lock項(xiàng)目在 pyproject.toml 中注冊了大量自定義 markerinstall、update、lock、sync、vcs、cli、needs_internet、flaky等pipenv run pytest --markers可列出全部同時(shí)通過norecursedirs顯式跳過vendor、patched、news、tasks、docs、tests/test_artifacts、tests/pypi等目錄。測試代碼按 tests/unit單元測試與 tests/integration集成測試分層組織。三種進(jìn)階運(yùn)行方式1. 測試腳本推薦在開 PR 前運(yùn)行run-tests.sh 復(fù)刻了 GitHub CI 工作流的全部步驟因此文檔明確建議在開 PR 之前運(yùn)行它??捎铆h(huán)境變量覆蓋默認(rèn)行為$ PYTHONpython3.8 PIPENV_PYTHONpython3.9 run-tests.sh $ PYTHON/opt/python/python3.10/python3 run-tests.sh其中PYTHON覆蓋 Python 二進(jìn)制名默認(rèn)python用于處理系統(tǒng)上不叫python的情況PIPENV_PYTHON覆蓋 Pipenv 實(shí)際使用的解釋器版本腳本默認(rèn)值為3.8。2. 手動(dòng)執(zhí)行重復(fù)腳本步驟$ git clone https://github.com/pypa/pipenv.git $ cd pipenv $ git submodule sync git submodule update --init --recursive $ python -m pip install -e .[tests,dev] $ pipenv install --dev $ pipenv run python -m pip install -e .[tests,dev] $ pipenv run pytest [--any optional arguments to pytest]第二種方式的前提是系統(tǒng)上已裝有 pipenv。文檔特別建議在Linux 容器或 FreeBSD Jail、VM中運(yùn)行測試以保證環(huán)境純凈、不破壞宿主機(jī)$ docker run --rm -v $(pwd):/usr/src -it python:3.7 bash # 容器內(nèi) # adduser --disabled-password debian # su debian cd /usr/src/ # bash run-tests.sh3. 使用 Makefile更細(xì)粒度的控制Makefile 自動(dòng)化了腳本中的全部任務(wù)并允許對每個(gè)步驟做更精細(xì)的控制$ make ramdisk # 創(chuàng)建內(nèi)存盤以保護(hù) SSD 壽命 $ make ramdisk-virtualenv $ make test suite-m not cli # 運(yùn)行除 cli 外的所有測試 $ make tests parallel suitetests/integration/test_cli.py::test_pipenv_check此外文檔還給出 macOS 環(huán)境下的注意事項(xiàng)確保測試能訪問 GitHub必要時(shí)啟動(dòng)ssh-agent并ssh-add、通過 brew 安裝 coreutils 后把 GNU 工具加入PATH、并取消設(shè)置PIP_FIND_LINKS它當(dāng)前會破壞test_uninstall.py。文檔貢獻(xiàn)文檔改進(jìn)同樣隨時(shí)歡迎。文檔源文件位于 docs 目錄采用 Markdown 編寫由 Sphinx 生成整套文檔。貢獻(xiàn)文檔時(shí)請注意遵循既有文檔風(fēng)格正文寬度軟限制79 字符采用半正式、友好且平易近人的散文風(fēng)格Python 代碼示例使用單引號字符串hello而非hello。小結(jié)給 Pipenv 貢獻(xiàn)者的行動(dòng)清單結(jié)合本文一次完整的貢獻(xiàn)之旅可以濃縮為**先讀 docs/dev/contributing.md → Fork 并可編輯安裝pip install -e .[tests,dev] pre-commit→ 判斷改動(dòng)落在 Owned 還是 Vendored 區(qū)域后者交給 vendoring 工具鏈不要手改→ 先寫失敗測試 → 實(shí)現(xiàn)改動(dòng)新分叉記得寫Provenance:docstring→ 為每個(gè)用戶可見改動(dòng)添加 news fragment → 用run-tests.sh跑通含本地 pypiserver 的全量測試 → 向main分支發(fā) Pull Request。把握住Owned 自由重構(gòu)、Vendored 絕不手改、刻意分叉必須聲明來源這一核心治理原則你就能在這個(gè)代碼庫中安全、高效地提交高質(zhì)量的貢獻(xiàn)?!久赓M(fèi)下載鏈接】pipenvPython Development Workflow for Humans.項(xiàng)目地址: https://gitcode.com/gh_mirrors/pi/pipenv創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考