貢獻方式#
本文旨在概述貢獻 SciPy 的方式。它嘗試回答常見問題,並深入了解社群流程在實務中如何運作。熟悉 SciPy 社群且經驗豐富的 Python 程式設計人員可以直接跳至SciPy 貢獻者指南。
您有很多種方式可以貢獻
貢獻新程式碼#
如果您使用科學 Python 工具堆疊已有一段時間,您可能有一些程式碼閒置在那裡,您認為「這對其他人也可能有用」。那麼,將其貢獻給 SciPy 或另一個開放原始碼專案可能是個好主意。首先要問的問題是,這段程式碼屬於哪裡?這個問題在這裡很難回答,所以我們先從一個更具體的問題開始:哪些程式碼適合放入 SciPy?幾乎所有添加到 SciPy 的新程式碼的共同點是,它在多個科學領域都可能有用,並且符合現有 SciPy 子套件的範圍(請參閱決定新功能)。原則上,也可以添加新的子套件,但這種情況較不常見。對於特定於單一應用程式的程式碼,可能會有現有的專案可以使用該程式碼。一些 SciKits(scikit-learn、scikit-image、statsmodels 等)是很好的例子;它們的重點更窄,因此比 SciPy 具有更多特定領域的程式碼。
現在,如果您有想要包含在 SciPy 中的程式碼,您該如何進行?在確認您的程式碼可以在相容的授權條款下於 SciPy 中發布後(請參閱授權考量),第一步是在 scipy-dev 論壇上討論它。所有新功能以及對現有程式碼的變更都在那裡討論和決定。您可以,而且可能應該在您的程式碼完成之前就開始這個討論。請記住,為了將您的程式碼添加到 SciPy,它需要由其他人審查,因此請嘗試找人願意在您進行的同時審查您的工作。
假設在論壇上的討論結果是正面的,並且您有一個函數或一段程式碼可以完成您需要它做的事情,接下來是什麼?在將程式碼添加到 SciPy 之前,它至少必須有良好的文件、單元測試、基準測試和正確的程式碼風格。
- 單元測試
原則上,您應該旨在建立單元測試,以測試您正在添加的所有程式碼。這在一定程度上讓您確信您的程式碼可以正確運行,即使在您自己沒有的 Python 版本、硬體或作業系統上也是如此。關於如何編寫單元測試的詳細描述,請參閱測試指南,而在本機執行 SciPy 測試文件說明了如何執行它們。
- 基準測試
單元測試檢查功能是否正確;基準測試衡量程式碼效能。並非所有現有的 SciPy 程式碼都有基準測試,但應該有:隨著 SciPy 的發展,監控執行時間以捕捉意外的衰退變得越來越重要。有關編寫和執行基準測試的更多資訊,請參閱使用 airspeed velocity 基準測試 SciPy。
- 文件
清晰且完整的文件對於使用者能夠找到並理解程式碼至關重要。個別函數和類別的文件——至少包括基本描述、所有參數和傳回值的類型和含義,以及 doctest 格式的使用範例——放在 docstrings 中。這些 docstrings 可以在直譯器中讀取,並編譯成 HTML 和 pdf 格式的參考指南。主要(領域)功能的高階文件以教學格式和/或模組 docstrings 提供。關於如何編寫文件的指南,請參閱文件風格,而使用 Sphinx 在本機呈現文件說明了如何預覽文件在線上顯示的樣子。
- 程式碼風格
統一的程式碼風格使其他人更容易閱讀您的程式碼。SciPy 遵循標準 Python 風格指南 PEP8,但建議的最大行長度為 88 個字元,而不是 PEP8 的 79 個字元。
我們提供了一個 git pre-commit hook,可以檢查您的每次提交是否具有正確的風格。從 SciPy 儲存庫的根目錄執行以下命令來安裝它(一次):
cp tools/pre-commit-hook.py .git/hooks/pre-commit
或者,您可以手動執行 linter
python dev.py lint
大多數 IDE 和文字編輯器也都有可以幫助您遵循 PEP8 的設定,例如將 Tab 轉換為四個空格。更多資訊請參閱PEP8 和 SciPy。
在開發工作流程範例的末尾,提供了一份檢查清單,其中包含這些和其他要求。
您可能有的另一個問題是:我應該將我的程式碼放在哪裡?為了回答這個問題,了解 SciPy 公開 API(應用程式介面)是如何定義的很有用。對於大多數模組,API 是兩層深的,這表示您的新函數應該顯示為 scipy.subpackage.my_new_func
。my_new_func
可以放在 /scipy/<subpackage>/
下的現有或新檔案中,其名稱會添加到該檔案中的 __all__
清單中(其中列出了檔案中的所有公開函數),然後這些公開函數會匯入到 /scipy/<subpackage>/__init__.py
中。任何私有函數/類別的名稱都應該以底線 (_
) 開頭。關於 SciPy 的公開 API 是什麼的更詳細描述,請參閱SciPy API。
一旦您認為您的程式碼已準備好包含在 SciPy 中,您就可以在 Github 上發送 pull request (PR)。我們在這裡不會詳細介紹如何使用 git,這在Git 開發和 Github 說明頁面上有很好的描述。當您為新功能發送 PR 時,請務必在 scipy-dev 論壇上提及此事。這可以促使感興趣的人幫助審查您的 PR。假設您之前已經對您的程式碼/功能的一般想法獲得了正面回饋,程式碼審查的目的是確保程式碼正確、有效率並符合上述要求。在許多情況下,程式碼審查發生得相對較快,但有可能會停滯。如果您已經處理了所有已給出的回饋,那麼在論壇上再次請求審查是完全可以的(在經過一段合理的時間,例如幾個星期之後)。一旦審查完成,PR 就會合併到 SciPy 的「main」分支中。
以上描述了將程式碼添加到 SciPy 的要求和流程。但它尚未回答決策究竟是如何做出的問題。基本答案是:決策是由共識決定的,由每個選擇參與 論壇討論的人決定。這包括開發人員、其他使用者和您自己。在討論中力求達成共識非常重要——SciPy 是一個由科學 Python 社群建立並為其服務的專案。在極少數無法達成協議的情況下,相關模組的維護者可以決定問題。
授權考量#
我的程式碼是基於我在網路上找到的現有 Matlab/R/… 程式碼,這樣可以嗎?
這取決於情況。SciPy 是在 BSD 授權條款下發布的,因此如果您程式碼所基於的程式碼也是 BSD 授權或具有 BSD 相容授權(例如 MIT、PSF),那麼就可以。具有 GPL 或 Apache 授權、沒有明確授權、要求引用或僅供學術用途免費的程式碼不能包含在 SciPy 中。因此,如果您複製了具有此類授權的現有程式碼或將其直接翻譯成 Python,則您的程式碼不能包含在內。如果您不確定,請在 scipy-dev 論壇上詢問。
為什麼 SciPy 使用 BSD 授權條款,而不是 GPL 等授權條款?
與 Python 一樣,SciPy 使用「寬鬆的」開放原始碼授權條款,允許專有重用。雖然這允許公司使用和修改軟體而無需回饋任何東西,但人們認為更大的使用者群會帶來更多的整體貢獻,而且公司通常無論如何都會發布他們的修改,而無需被要求這樣做。請參閱 John Hunter 的 BSD pitch。
有關 SciPy 授權條款的更多資訊,請參閱授權。
維護現有程式碼#
上一節專門討論了向 SciPy 添加新功能。該討論的很大一部分也適用於現有程式碼的維護。維護意味著修正錯誤、提高程式碼品質、更好地記錄現有功能、添加遺失的單元測試、添加效能基準測試、保持建置腳本最新等等。SciPy issue 清單包含所有已報告的錯誤、建置/文件問題等。修正 issue 有助於提高 SciPy 的整體品質,也是熟悉專案的好方法。您可能還想修正錯誤,因為您遇到了該錯誤,並且需要相關函數才能正常運作。
上面關於程式碼風格和單元測試的討論同樣適用於錯誤修正。通常最好從編寫一個單元測試開始,該測試顯示問題,即它應該通過但沒有通過。一旦您有了它,您就可以修正程式碼,使測試確實通過。這應該足以為此 issue 發送 PR。與添加新程式碼不同,在 論壇上討論這個可能不是必要的——如果程式碼的舊行為明顯不正確,則不會有人反對修正它。可能有必要為變更後的行為添加一些警告或棄用訊息。這應該是審查過程的一部分。
注意
僅變更程式碼風格的 pull requests,例如修正檔案中的一些 PEP8 問題,是不鼓勵的。此類 PR 通常不值得弄亂 git annotate 歷史記錄,並且會佔用審查人員的時間,而這些時間可能可以更好地用於其他方面。但是,作為功能變更一部分而接觸的程式碼的程式碼風格清理是可以的。
審查 pull requests#
非常歡迎審查開放的 pull requests (PR)。這是幫助提高專案向前發展速度的寶貴方法。如果您在特定領域(例如「最佳化演算法」或「特殊函數」)具有特定知識/經驗,那麼審查該領域的 PR 就特別有價值——有時包含技術程式碼的 PR 必須等待很長時間才能合併,因為缺乏合適的審查人員。
我們鼓勵所有人參與審查過程;這也是熟悉程式碼庫的好方法。審查人員應該問自己以下部分或全部問題:
此變更是否經過充分討論(與新功能和現有行為的變更相關)?
此功能在科學上是否合理?演算法可能基於文獻已知有效;否則,仔細檢查正確性很有價值。
在所有條件下(例如,空陣列或 nan/inf 值等意外輸入),預期行為是否清晰?
程式碼是否符合貢獻新程式碼下概述的品質、測試和文件期望?
如果我們還不認識您,請考慮自我介紹。
其他貢獻方式#
除了編寫程式碼之外,還有許多其他貢獻方式。
Issue 分流(調查錯誤報告的有效性和可能採取的措施)也是一項有用的活動。SciPy 有數百個開放 issue;關閉無效的 issue 並正確標記有效的 issue(最好在註解中寫下一些初步想法)可以優先處理維護工作,並在處理現有函數或子套件時輕鬆找到相關 issue。要閱讀有關 issue 分流的更多資訊,請參閱Issue 分流和管理。
參與 scipy-user 和 scipy-dev 論壇上的討論本身就是一種貢獻。每個向這些列表寫信提出問題或想法的人都希望得到回應,而編寫這些回應會使專案和社群運作得更好,並顯得更受歡迎。
scipy.org 網站包含大量關於 SciPy 專案和 SciPy 社群的資訊,並且總是需要新的幫手。該網站的原始碼位於其自己的獨立儲存庫中:scipy/scipy.org
開始入門#
感謝您對貢獻 SciPy 感興趣!如果您有興趣貢獻程式碼,我們希望您繼續閱讀SciPy 貢獻者指南,以了解如何設定您的開發環境、實作您的改進並提交您的第一個 PR!