Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Версионирование (Versioning) в Python
Определение
Версионирование — это система обозначения релизов программного обеспечения. Каждый релиз получает уникальный номер (версию), который помогает:
- Отслеживать изменения
- Управлять совместимостью
- Вернуться на старую версию если нужно
- Общаться с пользователями о важности обновления
Семантическое версионирование (Semantic Versioning, SemVer)
Стандарт для версионирования: MAJOR.MINOR.PATCH
1.2.3
│ │ └─ PATCH (исправления ошибок)
│ └─── MINOR (новые фичи, обратно совместимо)
└───── MAJOR (breaking changes, несовместимо)
PATCH версия (1.2.3 → 1.2.4)
Исправление ошибок, НО совместимо с предыдущей версией:
# Version 1.2.3
def calculate_price(quantity: int, price: float) -> float:
return quantity * price
# Version 1.2.4 (PATCH fix)
def calculate_price(quantity: int, price: float) -> float:
# Исправили баг: забыли округлить результат
return round(quantity * price, 2) # <-- исправление
# Старый код продолжит работать:
result = calculate_price(5, 10.50) # Совместимо!
MINOR версия (1.2.3 → 1.3.0)
Новые фичи, но совместимо с предыдущей версией:
# Version 1.2.3
def calculate_price(quantity: int, price: float) -> float:
return quantity * price
# Version 1.3.0 (MINOR feature)
def calculate_price(
quantity: int,
price: float,
discount: float = 0.0 # <- новый опциональный параметр
) -> float:
discounted = price * (1 - discount)
return quantity * discounted
# Старый код продолжит работать:
result = calculate_price(5, 10.50) # Совместимо! (discount=0 по умолчанию)
# Новый код может использовать новую фичу:
result = calculate_price(5, 10.50, discount=0.1) # Со скидкой!
MAJOR версия (1.2.3 → 2.0.0)
Критические изменения, несовместимо с предыдущей версией:
# Version 1.2.3
def calculate_price(quantity: int, price: float) -> float:
return quantity * price
# Version 2.0.0 (MAJOR breaking change)
def calculate_price(
quantity: int,
unit_price: float, # <- ПЕРЕИМЕНОВАЛИ параметр!
apply_tax: bool = False # <- удалили discount, добавили tax
) -> float:
total = quantity * unit_price
if apply_tax:
total *= 1.07 # 7% налог
return total
# ❌ Старый код СЛОМАЕТСЯ:
result = calculate_price(5, 10.50, discount=0.1)
# Error: unexpected keyword argument 'discount'
Примеры версионирования известных проектов
Python: 3.11.4
3 = MAJOR (Python 3 вышла в 2008)
11 = MINOR
4 = PATCH
Django: 4.2.8
4 = MAJOR
2 = MINOR
8 = PATCH
NumPy: 1.24.3
1 = MAJOR
24 = MINOR
3 = PATCH
React: 18.2.0
18 = MAJOR
2 = MINOR
0 = PATCH
Версионирование в Python проектах
setup.py / pyproject.toml
# setup.py
from setuptools import setup
setup(
name="myproject",
version="1.2.3", # Семантическое версионирование
description="My awesome project",
author="Ivan",
packages=["myproject"],
)
# Или в pyproject.toml (современный стиль)
[project]
name = "myproject"
version = "1.2.3"
description = "My awesome project"
init.py
# myproject/__init__.py
__version__ = "1.2.3"
print(myproject.__version__) # "1.2.3"
Доступ к версии
import myproject
print(myproject.__version__) # "1.2.3"
Управление версиями с Git Tags
# Создать tag для версии
git tag v1.2.3
# Push tag на сервер
git push origin v1.2.3
# Просмотреть все tags
git tag
# Просмотреть какой tag на текущем коммите
git describe --tags
# Получить тег при clone
git clone https://github.com/user/repo.git
git checkout v1.2.3 # Перейти на версию 1.2.3
Requirement.txt и версионирование зависимостей
# requirements.txt
# Точная версия
django==4.2.8
# Минимальная версия
requests>=2.28.0
# Диапазон (совместимо)
flask>=2.0,<3.0
# Полная гибкость (не рекомендуется)
numpy
# Patch версия (обновления только patch)
celery~=5.3.0 # Зафиксировать 5.3.x
# Точная версия с comment
psycopg2==2.9.6 # PostgreSQL драйвер
poetry.lock для блокировки версий
# pyproject.toml
[tool.poetry.dependencies]
python = "^3.11"
django = "^4.2"
celery = "5.3.0"
# poetry.lock
# Автоматически блокирует ВСЕ зависимости, включая sub-dependencies
Changelog и версионирование
Каждый релиз должен иметь CHANGELOG.md:
# Changelog
## [2.0.0] - 2024-03-23
### Breaking Changes
- Удалён параметр `discount` из `calculate_price()`
- Функция `old_format()` удалена
### Added
- Новый параметр `apply_tax` для `calculate_price()`
- Поддержка ISO 8601 датирования
### Fixed
- Исправлена ошибка с рассчетом скидок
## [1.3.0] - 2024-03-20
### Added
- Добавлен параметр `discount` в `calculate_price()`
- Поддержка JSON экспорта
### Fixed
- Исправлена ошибка с округлением
## [1.2.3] - 2024-03-15
### Fixed
- Исправлена утечка памяти в конверторе
CI/CD и версионирование
# .github/workflows/release.yml
name: Release
on:
push:
tags:
- 'v*' # Запуск при tag вида v1.2.3
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# Получить версию из tag
- name: Get version from tag
id: tag_name
run: |
echo "::set-output name=version::${GITHUB_REF#refs/tags/v}"
# Обновить версию в коде
- name: Update version
run: |
echo '__version__ = "${{ steps.tag_name.outputs.version }}"' > myproject/__init__.py
# Собрать пакет
- name: Build package
run: python -m build
# Загрузить на PyPI
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
Запуск команды release
# 1. Обновить версию в коде
# 2. Обновить CHANGELOG.md
# 3. Коммит
git commit -m "Bump version to 1.3.0"
# 4. Создать tag
git tag v1.3.0
# 5. Push
git push origin main
git push origin v1.3.0
# GitHub Actions автоматически:
# - Запустит тесты
# - Соберет пакет
# - Загрузит на PyPI
Советы по версионированию
✓ Используйте семантическое версионирование — это стандарт ✓ Ведите CHANGELOG.md — пользователи должны знать что изменилось ✓ Не делайте MAJOR версию часто — она пугает пользователей ✓ Блокируйте точные версии в requirements.txt — для production ✓ Используйте диапазоны в pyproject.toml — для library разработки ✓ Тегируйте релизы в Git — для отслеживания истории ✓ Сначала small versions — 0.1.0, 0.2.0, затем 1.0.0 ✓ Не пропускайте версии — идите по порядку: 1.0.0 → 1.0.1 → 1.1.0
Итог
Версионирование — это стандартный способ управления релизами:
MAJOR.MINOR.PATCH (Semantic Versioning):
- MAJOR: breaking changes (требует обновления кода)
- MINOR: новые фичи (обновление опционально, обратно совместимо)
- PATCH: исправления (обновление рекомендуется)
Хорошее версионирование делает отношение между разработчиком и пользователем прозрачным и предсказуемым.