Python 專案的開發者目前大多數都會選擇 pip 或者 pipenv 作為套件相依性的管理工具,其中 pipenvPipenv: promises a lot, delivers very little 討論串中也得到不少負面評價,主要是 pipenv 一開始承諾的 features 遠多過於後來 release 的版本,而且有些反直覺的行為(e.g. Issue 3304 merge 之前 pipenv 每當安裝新套件就會強制更新 Pipfile.lock 內的所有套件版本)造成開發者困擾,雖然如此, pipenv 依然持續進化中,我們仍可對其抱持中立的態度。

不過前述的討論串中,蠻多人提到 Poetry 這套打包(packaging)與套件相依性管理系統,看來也是值得試試看的一個工具。因此本文特地介紹 Poetry 的使用方法。

本文環境

  • macOS 10.14
  • Python 3.6.5
  • Poetry

安裝指令:

$ curl -sSL https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py | python

環境設定

安裝完 Poetry 之後,預設還不會有 poetry 指令能夠使用,因為 poetry 的安裝路徑並不在環境變數 PATH 內,因此我們必須將其加入到 PATH 之中。

Poetry 在 Unix, Linux 等系統的安裝路徑如下:

$HOME/.poetry/bin

如需確定 PATH 中包含該路徑,可以使用以下指令:

$ echo $PATH
/Users/.../.poetry/bin:...

若未包含 Poetry 的安裝路徑可用以下指令加入:

export PATH=$PATH:$HOME/.poetry/bin

p.s. 可以寫入到 bashrc , zshrc 等設定檔中,節省每次都需要自行設定的麻煩

建立 pyproject.toml

使用 Poetry 的第 1 步,就是建立 pyproject.toml 檔案,該檔案內容如下所示,可依需求自行修改:

[tool.poetry]
name = "mypyproject"
version = "0.0.1"
description = "My Python project"
authors = ["Example <example@example.com>"]

[tool.poetry.dependencies]
python = "^3.6.5"

pyproject.toml 的存放位置通常在 Python 專案的最頂層,例如:

.
├── README.md
├── hello.py
└── pyproject.toml

新增套件

設置好 pyproject.toml 之後,就可以透過 poetry add <pacakge> 安裝套件,例如以下為安裝 requests 的指令:

$ poetry add requests

安裝好之後,會出現 1 個檔案 poetry.lock ,裡面記錄著 Python 專案需要的相依套件、版本以及 hash 等資訊,每次安裝或移除套件 poetry.lock 都會被更新,可以將其 commit 進行版本控制。

poetry.lock 的範例:

[[package]]
category = "main"
description = "Python HTTP for Humans."
name = "requests"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
version = "2.22.0"

[package.dependencies]
certifi = ">=2017.4.17"
chardet = ">=3.0.2,<3.1.0"
idna = ">=2.5,<2.9"
urllib3 = ">=1.21.1,<1.25.0 || >1.25.0,<1.25.1 || >1.25.1,<1.26"

[[package]]
category = "main"
description = "HTTP library with thread-safe connection pooling, file post, and more."
name = "urllib3"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4"
version = "1.25.6"

[metadata]
content-hash = "76ee42456d8f12982d1c477865b773f513024bee21d74891fb92583007559b1d"
python-versions = "^3.6.5"

如果有些套件是開發時才需要,例如 pytest ,可以在安裝時加入 --dev 參數,將該套件標記為 dev 環境才需要安裝。

$ poetry add --dev pytest

移除套件

移除套件的指令則是 poetry remove <package> ,例如:

$ poetry remove requests

更新套件

安裝套件之後,套件的版本相依性就會被記錄在 poetry.lock 檔案中,正常情況下版本都不會被更動,以確保不會因為套件版本升級而導致錯誤,但偶爾也會遇到需要升級的情況(例如安全性問題),這時就可以用指令 poetry update <package> 升級套件,例如:

$ poetry update requests

安裝 poetry.lock 內的套件

若要安裝 poetry.lock 內的所有套件(包含 dev 環境才需要的套件),可以直接使用指令:

$ poetry install

若是生產環境(Production)的安裝,則建議加上 --no-dev 參數,省去安裝 dev 套件的功夫,也不佔用額外的系統容量:

$ poetry install --no-dev

Poetry 與 Virtualenv

事實上,每次執行 install 指令時, Poetry 都會檢查是否正在使用 virtualenv 的環境,若未使用 virtualenv 則會自行建立 1 個全新的 virtualenv 後再進行安裝,避免污染系統的 Python 執行環境。

預設的 virtualenv 路徑,可使用以下指令查詢:

$ poetry config --list | grep settings.virtualenvs.path

而自動建立 virtualenv 的貼心行為,可以透過以下指令停用:

$ poetry config settings.virtualenvs.create false

或者修改設定檔 config.toml 也可以達到相同目的,設定檔的存放位置依不同作業系統而有不同,詳情可參閱文件 Configuration

總結

以上就是 Poetry 的使用方法,如果想了解更多可以參閱 Poetry 的官方網站。

References

https://poetry.eustace.io/