Есть ли какая-то практическая причина, по которой у меня должна быть версия кода, встроенная в исходный код Python?

Есть ли практическая причина, по которой я должен иметь версию кода, встроенную в исходный код? Явно меня интересует setup.py, но также некоторые используют __version__. Под встраиванием в исходный код я имею в виду, должен ли я писать номер версии в виде текста в файле, а не заполнять поля python другими способами.

На других языках я настроил скрипты сборки так, чтобы они учитывали теги git, а затем полностью управлял номерами версий с помощью тегов. Это означает, что в репозитории никогда не будет фиксации для увеличения номера версии. Все, что мне нужно сделать, это пометить коммит для новой версии и запустить сборку.

Итак, в качестве теоретического примера я мог бы:

def _get_version()
    command = ['git', 'describe', '--tags', '--match' 'versions/[0-9]*.[0-9]*']
    result = subprocess.run(command, stdout=subprocess.PIPE).stdout.decode('utf-8')
    return result.replace('-', '+', 1).replace('versions/', '')

setuptools.setup(
    name="example-pkg-YOUR-USERNAME-HERE", # Replace with your own username
    version=_get_version(),
    author="Example Author",
    author_email="[email protected]",
    description="A small example package",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/pypa/sampleproject",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
)

Что мне не ясно, так это будет ли это работать. Анализируется ли результат setuptools.setup перед загрузкой в ​​репозиторий пакетов или когда он загружается третьей стороной? Конечно, репозиторий git доступен только до его загрузки, а не тогда, когда пакет загружен кем-то другим через pip.

Точно так же, правильно ли я думаю, что это совершенно не заполнится, если применить его к файлу __version__?


person Philip Couling    schedule 29.09.2020    source источник
comment
возможно, вы могли бы использовать действие github или эквивалентный рабочий процесс для создания файла verison.py, интересная идея   -  person bherbruck    schedule 30.09.2020
comment
Я думал, что действие сборки использует вашу версию для создания имени файла встроенного пакета? И я думал, что информация о версии во время загрузки или установки pip извлекается из имени файла? Не знаю, может я ошибаюсь?   -  person James Lin    schedule 30.09.2020
comment
Вас может заинтересовать проект setuptools_scm, который автоматизирует теги версий и git. Что касается встроенного в исходный код атрибута __version__, некоторые люди просто предпочитают эту простоту, и это также показано в примере в руководство по стилю, что, вероятно, способствовало популярности. Краткий ответ заключается в том, что атрибут __version__ уровня модуля для вашего пакета является просто общепринятым соглашением и на самом деле вообще не требуется.   -  person wim    schedule 30.09.2020
comment
@wim Да, я думаю, что это произошло немного раньше. До появления современных инструментов SCM было принято иметь журнал изменений в комментариях в начале каждого файла. Таким образом, в большинстве файлов будет записана версия кода. Без компиляции это усложняет тему, которая в противном случае обрабатывалась бы путем опроса атрибутов времени компиляции. Таким образом, Python, похоже, остановился на идее номеров версий в коде. :-(   -  person Philip Couling    schedule 30.09.2020


Ответы (1)


Технически вам не нужно встраивать версию в свой пакет. Передача версии в setuptools.setup() гарантирует, что она будет сохранить в пакете метаданные для обработки механизмом упаковки (например, setuptools, pip, поэзия и т. д.).

Считается хорошей практикой включать ее в пакет, так как это может быть полезно, когда вы пишете код, который должен проверять версию библиотеки (дандлер __version__ впервые упоминается в PEP 8 и уточнено в PEP 396), но это может больше не понадобиться, так как Python 3.8 встраивает importlib.metadata:

>>> from importlib.metadata import version
>>> version("wheel")
'0.35.1'

Таким образом, ваше решение будет работать нормально, но я бы рекомендовал вам вместо этого использовать setuptools-scm, который помешать вам самостоятельно управлять подпроцессом.

person jeremyr    schedule 30.09.2020