昨天我們談到了 Poetry 是一個現代化的套件管理工具,它不僅可以幫助我們管理套件的依賴,還提供了一個虛擬環境的解決方案。Poetry 使用一個 toml 檔 pyproject.toml
文件來管理專案配置和依賴,這符合 – Specifying Minimum Build System Requirements for Python Projects 所提倡的現代 Python 專案的依賴項管理。今天我們就來詳解這個 toml 檔吧!
如果有在寫當代 JavaScript 的朋友,應該很熟悉 package.json
,pyproject.toml 和 package.json 是很相近的概念。他們都是專案配置和依賴管理的核心,提供了一個中心化的地方來存儲專案的 metadata 和 dependancy,使得開發流程更加順暢和一致。
在 pyproject.toml 中,開發者可以指定專案的各種 metadata,包括但不限於專案名稱、版本、作者和描述。例如:
[tool.poetry]
name = "ironman2023"
version = "0.1.0"
description = "2023 鐵人賽"
authors = ["KoKo Mexcelsa <qqkerk@hotmail.com>"]
readme = "README.md"
開發者可以列出專案的依賴,並指定其版本要求。這不僅包括運行時依賴,也包括 dev 模式時依賴。例如下面兩段:
[tool.poetry.dependencies]
python = "3.11"
numpy = "^1.21.0"
[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
black = "^23.9.1"
你也可以在 pyproject.toml 文件中指定用於 build 專案的工具。這一段往往會自動添加上去,所以不太需要管,除非你要客製化。
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
在 pyproject.toml 中,可以指定專案的依賴及其版本。指定版本時有多種方式可以表示想要使用的版本或版本範圍。下面是一些常見的方法和它們的說明:
指定一個精確的版本,意味著只有該特定版本會被接受。
[tool.poetry.dependencies]
numpy = "1.21.0"
可以使用比較運算符來指定一個版本範圍:
[tool.poetry.dependencies]
numpy = ">=1.21.0, <2.0.0"
在上面的範例中,任何版本從 1.21.0
(含) 到 2.0.0
(不含) 都是可以接受的。
使用星號(*
)是允許任何兼容的版本:
[tool.poetry.dependencies]
numpy = "1.21.*"
在上面的範例中,任何 1.21
系列的版本都是可以接受的。如
使用Caret(^
)可以指定一個允許任何相容的版本,但不會改變最左邊的非零數字:
[tool.poetry.dependencies]
numpy = "^1.21.0"
這將允許 1.21.0
以及任何更高但低於 2.0.0
的版本。
使用波浪號(~
)可以指定一個允許在特定範圍內的版本:
[tool.poetry.dependencies] numpy = "~1.21.0"
這會允許 1.21.0
以及任何更高但低於 1.22.0
的版本。
你也可以指定多個版本,並且只要符合其中一個條件就可以:
[tool.poetry.dependencies]
numpy = [ ">=1.20.0, <1.21.0", ">=1.22.0, <1.23.0" ]
總之,pyproject.toml 是當代 Python 開發的新規範,而且功能相當強大,正在逐漸取代傳統的 requirements.txt 文件。
poetry.lock
也是一種 toml 格式,這個文件是由 Poetry 自動生成的,通常不需要手動編輯。當你運行像 poetry add 或 poetry install 這樣的命令時,它會根據 pyproject.toml 中的指示來創建或更新 poetry.lock。
除了會定義 package 之外,還有定義 package 的 dependencies,還有 package.Extras 是定義額外的依賴。這裡的額外的依賴是指不用這些 package,核心功能依然可以用運作。
常見的 package 與其依賴,在 poetry.lock 裡的顯示如下:
[[package]]
name = "fastapi"
version = "0.101.1"
description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
optional = false
python-versions = ">=3.7"
files = [
{file = "fastapi-0.101.1-py3-none-any.whl", hash = "sha256:aef5f8676eb1b8389952e1fe734abe20f04b71f6936afcc53b320ba79b686a4b"},
{file = "fastapi-0.101.1.tar.gz", hash = "sha256:7b32000d14ca9992f7461117b81e4ef9ff0c07936af641b4fe40e67d5f9d63cb"},
]
[package.dependencies]
pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0"
starlette = ">=0.27.0,<0.28.0"
typing-extensions = ">=4.5.0"
[package.extras]
all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.5)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"]
此外,上面可以看到 file 和 hash 值。在 poetry.lock 文件中,files 段落列出了不同package distribution,並提供了每個文件的哈希值來確保文件的完整性和安全性。
file: 這是該 package distribution name。上面例子中,有兩個 distribution:一個是 wheel 格式(.whl),另一個是程式碼封裝格式(.tar.gz)。 Wheel 是 Python 的二進制分發格式,而 .tar.gz 文件包含原始程式碼。
Hash: 這是文件的 SHA-256 哈希值。當 Poetry 下載一個 package 時,它會計算下載文件的哈希值並與 poetry. Lock 文件中指定的哈希值進行比較,以確保文件沒有被篡改並且是你期望的確切版本。
以上就是 peotry 裡兩個重要的元件的介紹了。明天我們來學 poetry 的其他重要指令,包含今天改了 pyproject.toml 之後該怎麼做。