設定和使用您的開發環境#
建議的開發設定#
由於 NumPy 包含以 C 和 Cython 撰寫的部分,使用前需要編譯,請確保您已安裝必要的編譯器和 Python 開發標頭 - 請參閱從原始碼建置。從 2.0
版本開始建置 NumPy 需要符合 C11 和 C++17 標準的編譯器。
擁有編譯後的程式碼也意味著從開發原始碼匯入 NumPy 需要一些額外步驟,這將在下面說明。在本章的其餘部分,我們假設您已按照使用 scikit-image 原始碼中的說明設定了您的 git 儲存庫。
注意
如果您在從原始碼建置 NumPy 或設定本機開發環境時遇到問題,您可以嘗試使用 GitHub Codespaces 建置 NumPy。它允許您直接在瀏覽器中建立正確的開發環境,減少安裝本機開發環境和處理不相容依賴項的需求。
如果您有良好的網路連線並且想要臨時設定,在 Codespaces 環境中處理 NumPy 通常會更快。有關如何開始使用 Codespaces 的文件,請參閱Codespaces 文件。為 numpy/numpy
儲存庫建立程式碼空間時,預設的 2 核心機器類型即可運作;4 核心會建置和運作得更快一些(但當然會以減少一半的免費使用時數為代價)。一旦您的程式碼空間啟動,您可以執行 conda activate numpy-dev
,您的開發環境就完全設定好了 - 然後您可以按照 NumPy 文件的相關部分來建置、測試、開發、撰寫文件並貢獻 NumPy。
使用虛擬環境#
一個經常被問到的問題是「我如何在與我用於工作/研究的已發布版本並行設定 NumPy 的開發版本?」。
實現此目的的一種簡單方法是使用 pip 或 conda 等工具將已發布版本安裝在 site-packages 中,並在虛擬環境中設定開發版本。
如果您使用 conda,我們建議使用儲存庫根目錄中的 environment.yml
檔案為 numpy 開發建立一個單獨的虛擬環境(這將建立環境並一次安裝所有開發依賴項)
$ conda env create -f environment.yml # `mamba` works too for this command
$ conda activate numpy-dev
如果您使用 conda 以外的其他方式安裝 Python,請先安裝 virtualenv(可選使用 virtualenvwrapper),然後建立您的虛擬環境(在此命名為 numpy-dev
),啟動它,並使用以下命令安裝所有專案依賴項
$ virtualenv numpy-dev
$ source numpy-dev/bin/activate # activate virtual environment
$ python -m pip install -r requirements/all_requirements.txt
現在,每當您想要切換到虛擬環境時,您可以使用命令 source numpy-dev/bin/activate
,並使用 deactivate
從虛擬環境退出並返回到您之前的 shell。
從原始碼建置#
請參閱從原始碼建置。
測試建置#
在執行測試之前,請先安裝測試依賴項
$ python -m pip install -r requirements/test_requirements.txt
$ python -m pip install asv # only for running benchmarks
若要建置 NumPy 的開發版本並執行測試,請產生互動式 shell,並正確設定 Python 匯入路徑等,請使用 spin 工具。若要執行測試,請執行以下其中一項
$ spin test -v
$ spin test numpy/random # to run the tests in a specific module
$ spin test -v -t numpy/_core/tests/test_nditer.py::test_iter_c_order
這會先建置 NumPy,因此第一次可能需要幾分鐘。
您也可以使用 spin bench
進行基準測試。請參閱 spin --help
以取得更多命令列選項。
注意
如果以上命令導致 RuntimeError: Cannot parse version 0+untagged.xxxxx
,請執行 git pull upstream main --tags
。
額外的引數可以透過在空白 --
後面傳遞額外引數來轉發到 pytest
。例如,若要使用轉發到目標的 --pdb
旗標執行測試方法,請執行以下命令
$ spin test -t numpy/tests/test_scripts.py::test_f2py -- --pdb
您也可以透過將 -k
引數傳遞給 pytest,來使用 python 運算符號比對測試名稱
$ spin test -v -t numpy/_core/tests/test_multiarray.py -- -k "MatMul and not vector"
若要執行「doctests」 – 檢查文件中的程式碼範例是否正確 – 請使用 check-docs spin 命令。它依賴 scipy-docs 套件,該套件在標準函式庫 doctest
套件之上提供了一些額外功能。安裝 scipy-doctest
並執行以下其中一項
$ spin check-docs -v
$ spin check-docs numpy/linalg
$ spin check-docs -v -- -k 'det and not slogdet'
注意
請記住,在提交變更之前,NumPy 的所有測試都應通過。
注意
測試套件中的某些測試需要大量記憶體,如果您的系統記憶體不足,則會跳過這些測試。
其他建置選項#
如需更多選項,包括選擇編譯器、設定自訂編譯器旗標和控制平行處理,請參閱編譯器選擇和自訂建置(來自 SciPy 文件。)
執行測試#
除了使用 spin
之外,還有多種方法可以執行測試。在直譯器內,可以像這樣執行測試
>>> np.test()
>>> np.test('full') # Also run tests marked as slow
>>> np.test('full', verbose=2) # Additionally print test name/file
An example of a successful test :
``4686 passed, 362 skipped, 9 xfailed, 5 warnings in 213.99 seconds``
或從命令列以類似方式執行
$ python -c "import numpy as np; np.test()"
也可以使用 pytest numpy
執行測試,但是這樣就找不到 NumPy 特定的外掛程式,這會導致奇怪的副作用。
執行個別測試檔案可能很有用;它比執行整個測試套件或整個模組的測試套件快得多(範例:np.random.test()
)。這可以使用以下命令完成
$ python path_to_testfile/test_file.py
這也接受額外的引數,例如 --pdb
,當測試失敗或引發例外狀況時,它會將您放入 Python 除錯器中。
也支援使用 tox 執行測試。例如,若要建置 NumPy 並使用 Python 3.9 執行測試套件,請使用
$ tox -e py39
如需更詳細的資訊,請參閱測試指南。
注意:請勿在沒有 spin
的情況下從 numpy git 儲存庫的根目錄執行測試,這將導致奇怪的測試錯誤。
執行程式碼風格檢查#
可以對新加入的 Python 程式碼行執行程式碼風格檢查。
使用 pip 安裝所有依賴套件
$ python -m pip install -r requirements/linter_requirements.txt
若要在提交新程式碼之前執行程式碼風格檢查,請執行
$ python tools/linter.py
若要檢查目前分支中新加入的 Python 程式碼的所有變更與目標分支,請執行
$ python tools/linter.py --branch main
如果沒有錯誤,腳本將在沒有訊息的情況下退出。如果發生錯誤,請檢查錯誤訊息以了解詳細資訊
$ python tools/linter.py --branch main
./numpy/_core/tests/test_scalarmath.py:34:5: E303 too many blank lines (3)
1 E303 too many blank lines (3)
建議在將提交推送至遠端分支之前執行程式碼風格檢查,因為程式碼風格檢查器作為 CI 管道的一部分執行。
如需有關風格指南的更多詳細資訊
重建和清理工作區#
在變更編譯後的程式碼後重建 NumPy 可以使用與先前使用的相同的建置命令來完成 - 只會重建變更的檔案。執行完整建置(有時是必要的)需要先清理工作區。執行此操作的標準方法是(注意:刪除任何未提交的檔案!)
$ git clean -xdf
當您想要捨棄所有變更並返回儲存庫中的最後一次提交時,請使用以下其中一種方法
$ git checkout .
$ git reset --hard
除錯#
另一個經常被問到的問題是「我如何在 NumPy 內部除錯 C 程式碼?」。首先,確保您的系統上已安裝 gdb 以及 Python 擴充功能(通常是 Linux 上的預設設定)。您可以看到 gdb 內部正在執行的 Python 版本,以驗證您的設定
(gdb) python
>import sys
>print(sys.version_info)
>end
sys.version_info(major=3, minor=7, micro=0, releaselevel='final', serial=0)
大多數 python 建置不包含除錯符號,並且使用啟用的編譯器最佳化功能建置。為了獲得最佳除錯體驗,建議使用 Python 的除錯建置,請參閱進階除錯工具。
在除錯方面,NumPy 也需要在除錯模式下建置。您需要使用 debug
建置類型並停用最佳化,以確保在物件建置期間使用 -O0
旗標。請注意,在您使用 spin build
命令建置之前,不應在您的環境中安裝 NumPy。
若要在建置過程中產生原始碼層級的除錯資訊,請執行
$ spin build --clean -- -Dbuildtype=debug -Ddisable-optimization=true
注意
如果您正在使用 conda 環境,請注意 conda 會自動設定 CFLAGS
和 CXXFLAGS
,並且它們預設會包含 -O2
旗標。您可以安全地使用 unset CFLAGS && unset CXXFLAGS
來避免它們,或在 spin
命令的開頭提供它們:CFLAGS="-O0 -g" CXXFLAGS="-O0 -g"
。或者,若要更永久地控制這些變數,您可以在 <path-to-conda-envs>/numpy-dev/etc/conda/activate.d
目錄中建立 env_vars.sh
檔案。在此檔案中,您可以匯出 CFLAGS
和 CXXFLAGS
變數。如需完整說明,請參閱 https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#saving-environment-variables。
接下來,您需要編寫一個 Python 腳本,該腳本會調用您要除錯的 C 程式碼的執行。例如 mytest.py
import numpy as np
x = np.arange(5)
np.empty_like(x)
請注意,您的測試檔案需要位於您擁有的 NumPy 複製檔案之外。現在,您可以執行
$ spin gdb /path/to/mytest.py
如果您正在使用 clang 工具鏈
$ spin lldb /path/to/mytest.py
然後在除錯器中
(gdb) break array_empty_like
(gdb) run
lldb 對應項
(lldb) breakpoint set --name array_empty_like
(lldb) run
執行現在將在對應的 C 函數處停止,您可以像往常一樣逐步執行它。許多有用的 Python 特定命令可用。例如,若要查看您在 Python 程式碼中的位置,請使用 py-list
,若要查看 python 回溯,請使用 py-bt
。如需更多詳細資訊,請參閱 DebuggingWithGdb。以下是一些常用的命令
list
:列出指定的函數或行。next
:逐步執行程式,繼續執行子例程呼叫。step
:在訊號或斷點後,繼續執行正在除錯的程式。print
:列印運算式 EXP 的值。
對 Python 除錯的豐富支援要求與 Python 一起發行的 python-gdb.py
腳本安裝在 gdb 可以找到它的路徑中。如果您從系統套件管理器安裝了 Python 建置,您可能不需要手動執行任何操作。但是,如果您從原始碼建置了 Python,您可能需要在您的主目錄中建立一個 .gdbinit
檔案,將 gdb 指向您的 Python 安裝位置。例如,透過 pyenv 安裝的 python 版本需要一個具有以下內容的 .gdbinit
檔案
add-auto-load-safe-path ~/.pyenv
強烈建議使用以除錯支援建置的 Python 建置 NumPy(在 Linux 發行版上通常封裝為 python-dbg
)。
了解程式碼和入門#
更好地理解程式碼庫的最佳策略是選擇您想要變更的內容,並開始閱讀程式碼以了解其運作方式。如有疑問,您可以在郵件列表中提問。如果您的提取請求不完美,那也完全沒問題,社群始終樂於提供協助。作為一個志願者專案,事情有時會被擱置,如果某件事情在沒有回應的情況下擱置了約兩到四週,您可以隨時 ping 我們。
因此,繼續選擇一些關於 NumPy 讓您煩惱或困惑的事情,實驗程式碼,參與討論或瀏覽參考文件以嘗試修復它。事情會水到渠成,很快您就會對整個專案有一個相當好的理解。祝您好運!