Вам больше не нужны poetry и pipenv - достаточно лишь pyproject.toml.
Долгое время создание своих Python-пакетов было довольно сложным процессом, требовавшим написания setup.py. А зависимости прописывались в requirements.txt. Позже появились утилиты типа pipenv и poetry , которые упростили этот процесс. Был предложен формат файла pyproject.toml, который в конце концов стал официальным.
pyproject.tomlот poetry отличается от формата PEP.
Для управления зависимостями больше не нужны сторонние утилиты типа poetry, pipenv, flit или «официальный» hatch. pip давно умеет устанавливать зависимости из это файла, а теперь и утилиты для сборки и публикации пакетов его поддерживают.
Пример pyproject.toml :
[build-system]
# Тут мы указываем сборщики
# setuptools-scm тут может и не очень нужен, но указан на будущее
requires = ["setuptools", "setuptools-scm"]
build-backend = "setuptools.build_meta"
[project]
name = "dummy_project"
authors = [{name = "John Doe", email="john.doe@gmail.com"}]
# Лежат в корне проекта
readme = "README.md"
license = {file = "LICENSE"}
# Требуемая версия python
requires-python = ">=3.11.7"
# См. категории на pypi:
# https://pypi.org/classifiers/
# Для примера укажем категорию к которой принадлежит лицензия
classifiers = [
"License :: OSI Approved :: Apache Software License"
]
# Зависимости пакета, можно указывать версии с помощью операторов == и >=
dependencies = [
"requests",
]
# тут указываются динамические "свойства" пакета
# см. [tool.setuptools.dynamic]
dynamic = ["version"]
# Необязательные зависимости можно установить из корня проекта:
# pip install -e '.[dev]'
# pip install -e '.[test]'
# флаг -e нужен для создания ссылки вместо непосредственной установки (лишнего копирования файлов)
[project.optional-dependencies]
# Зависимости для тестирования
test = [
"pytest",
]
# А это для разработки
dev = [
"black",
"pylint",
]
[project.urls]
# Тут можно указать ссылку на репозиторий на гитхаб
Repository = "https://github.com/user/dummy-project.git"
# Версию пакета можно вытаскивать из кода
[tool.setuptools.dynamic]
version = {attr = "dummy_project.__version__"}
# При установке будут автоматически созданы исполняемые файлы в ~/.local/bin или в /usr/bin
[project.scripts]
# <команда> = <модуль откуда импортируем функцию>:<имя функции>
dummy-project-cli = 'dummy-project.cli:cli'
- https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html
- Исходники должны находиться в текущем каталоге либо папке
src/dummy_project.
Примерная структура проекта:
.
├── pyproject.toml
├── LICENSE
├── README.md
└── src
└── dummmy_project
├── cli.py
├── __init__.py
└── lib.py
Можно еще набросать что-то простое для проверки CLI:
src/dummy_project/cli.py:
import argparse
def cli(argv: list[str] | None = None) -> None:
parser = argparse.ArgumentParser()
parser.add_argument('--name', default="World")
args = parser.parse_args(argv)
print(f"Hello, {args.name}!")
Естественно, вместо pipx можно использовать обычный pip. Первый просто автоматически создает виртуальное окружение. Это аналог npx из мира Node.js.
С помощью pipx можно произвести тестовую установку проекта:
pipx install .
Проверим cli:
$ dummy-project-cli --name "Dummy"
Hello, Dummy!
Даже если проект не содержит исполняемых скриптов, использование pipx предпочтительно. Пример запуска проекта на flask:
pipx run --pypackages flask run
Для публикации и загрузки на pypi потребуются пакеты build и twine:
# Всегда лучше использовать стандартный пакетный менеджер для установки пакетов, содержащих какие-то утилиты (но не надо через него ставить django!!!)
yay -S python-build twine
# В неполноценных дистрах используем тот же pipx
pipx install build
pipx install twine
Выполняем сборку:
pyproject-build
# Если установлено как-то неправильно и не работает pyproject-build, то можно попробовать
python -m build
В результате будет создан каталог dist/ (а еще <project>.egg-info и тд).
Теперь загружаем проект:
twine upload --skip-existing dist/*
--skip-existingпропускает загрузку уже загруженных версий.
Чтобы загрузить проект в PyPI, нужно зарегистрироваться на сайте и созданный в профиле api token (кнопка Add API token) сохранить в ~/.pypirc :
[pypi]
username = __token__
password = pypi-...
Эти команды можно выполнить вместе:
pyproject-build && twine upload --skip-existing dist/*
Официальная документация:


