Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Как собрать Package из кода Python?
Обзор процесса
Сборка Python пакета (package) — это процесс подготовки кода к распределению через PyPI или локально. Современный стандарт использует pyproject.toml с build backends (build, hatchling, poetry, setuptools).
Вариант 1: Современный подход (рекомендуемый)
Используем pyproject.toml с инструментом build.
Шаг 1: Структура проекта
my_package/
├── pyproject.toml
├── README.md
├── LICENSE
└── src/
└── my_package/
├── __init__.py
├── module1.py
└── module2.py
Шаг 2: pyproject.toml
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-package"
version = "0.1.0"
description = "Short description"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "Your Name", email = "you@example.com"}
]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
]
[project.urls]
Homepage = "https://github.com/yourname/my-package"
Documentation = "https://my-package.readthedocs.io"
Repository = "https://github.com/yourname/my-package.git"
Issues = "https://github.com/yourname/my-package/issues"
[project.optional-dependencies]
dev = ["pytest>=7.0", "pytest-cov", "black", "ruff"]
docs = ["sphinx", "sphinx-rtd-theme"]
[tool.hatch.version]
path = "src/my_package/__init__.py"
pattern = '__version__ = "(?P<version>[^"]+)"'
Шаг 3: init.py
__version__ = "0.1.0"
from .module1 import function1
from .module2 import function2
__all__ = ["function1", "function2"]
Шаг 4: Установить build
pip install build twine
Шаг 5: Собрать пакет
python -m build
Результат:
dist/
├── my_package-0.1.0.tar.gz # Source distribution (sdist)
└── my_package-0.1.0-py3-none-any.whl # Wheel (binary distribution)
Шаг 6: Проверить пакет
twine check dist/*
Шаг 7: Загрузить на PyPI
# На TestPyPI (для проверки)
twine upload --repository testpypi dist/*
# На PyPI (production)
twine upload dist/*
Вариант 2: С использованием setuptools
Это старый подход, но всё ещё распространённый.
setup.py
from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="my-package",
version="0.1.0",
author="Your Name",
author_email="you@example.com",
description="Short description",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/yourname/my-package",
packages=find_packages(where="src"),
package_dir={"": "src"},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.8",
install_requires=[
"requests>=2.25.0",
],
extras_require={
"dev": ["pytest", "black"],
},
)
Собрать
python setup.py sdist bdist_wheel
Вариант 3: С Poetry
Поэтичный и удобный способ.
pyproject.toml (Poetry)
[tool.poetry]
name = "my-package"
version = "0.1.0"
description = "Short description"
authors = ["Your Name <you@example.com>"]
readme = "README.md"
license = "MIT"
repository = "https://github.com/yourname/my-package"
[tool.poetry.dependencies]
python = "^3.8"
requests = "^2.25.0"
[tool.poetry.group.dev.dependencies]
pytest = "^7.0"
black = "^22.0"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Собрать
poetry build
Полный пример: практический пакет
Структура
my_calculator/
├── pyproject.toml
├── README.md
├── LICENSE
├── src/
│ └── my_calculator/
│ ├── __init__.py
│ ├── calculator.py
│ └── utils.py
└── tests/
├── test_calculator.py
└── test_utils.py
src/my_calculator/init.py
__version__ = "0.1.0"
__author__ = "Your Name"
from .calculator import Calculator
from .utils import format_result
__all__ = ["Calculator", "format_result"]
src/my_calculator/calculator.py
class Calculator:
"""Simple calculator class."""
@staticmethod
def add(a: float, b: float) -> float:
"""Add two numbers."""
return a + b
@staticmethod
def multiply(a: float, b: float) -> float:
"""Multiply two numbers."""
return a * b
src/my_calculator/utils.py
def format_result(value: float, decimals: int = 2) -> str:
"""Format number to string."""
return f"{value:.{decimals}f}"
pyproject.toml (полный пример)
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-calculator"
version = "0.1.0"
description = "Simple calculator package"
readme = "README.md"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "Your Name", email = "you@example.com"}
]
keywords = ["calculator", "math"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
]
[project.urls]
Homepage = "https://github.com/yourname/my-calculator"
Repository = "https://github.com/yourname/my-calculator.git"
Issues = "https://github.com/yourname/my-calculator/issues"
[project.optional-dependencies]
dev = ["pytest>=7.0", "pytest-cov", "black", "ruff", "mypy"]
[tool.hatch.version]
path = "src/my_calculator/__init__.py"
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--cov=src/my_calculator --cov-report=html"
[tool.black]
line-length = 88
target-version = ["py38"]
[tool.ruff]
line-length = 88
target-version = "py38"
select = ["E", "F", "W"]
Команды для сборки и публикации
Сборка
# Установить инструменты
pip install build twine
# Собрать
python -m build
# Проверить содержимое
ls -la dist/
# Проверить метаданные
twine check dist/*
Локальная установка для тестирования
# Установить в режиме разработки
pip install -e .
# Установить с доп. зависимостями
pip install -e ".[dev]"
# Тестировать
pytest
# Проверить линтинг
black --check src/
ruff check src/
Публикация
# Загрузить на TestPyPI
twine upload --repository testpypi dist/*
# Проверить на TestPyPI
pip install --index-url https://test.pypi.org/simple/ my-package==0.1.0
# Загрузить на PyPI
twine upload dist/*
Что входит в пакет
Wheel (.whl)
- Бинарный дистрибутив (быстро устанавливается)
- Платформозависимый (python, os, architecture)
- Предпочитается для установки
Source Distribution (.tar.gz)
- Исходный код
- Кроссплатформенный
- Требует компиляции при установке
Best Practices
- Используй pyproject.toml (PEP 517/518) вместо setup.py
- Структура src/ — разделение между кодом и тестами
- Версионирование: используй семантическое версионирование (MAJOR.MINOR.PATCH)
- Зависимости: указывай минимальные требования, не максимальные
- Тестирование: включи тесты перед публикацией
- Documentation: README.md, docstrings, примеры кода
- License: всегда указывай лицензию
- Type hints: добавляй py.typed маркер для типов
Вывод
Современный способ собрать пакет Python:
- Структурируй проект с
src/директорией - Напиши
pyproject.tomlс metadata - Запусти
python -m build - Проверь с
twine check - Загрузи на PyPI с
twine upload