← Назад к вопросам

Что такое версионирование?

2.0 Middle🔥 61 комментариев
#Python Core#Soft Skills

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Версионирование (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: исправления (обновление рекомендуется)

Хорошее версионирование делает отношение между разработчиком и пользователем прозрачным и предсказуемым.