Стандартный способ встроить версию в пакет Python?

239
задан tshepang 19 April 2014 в 10:38
поделиться

7 ответов

Не непосредственно ответ на Ваш вопрос, но необходимо рассмотреть именование его __version__, не version.

Это - почти квазистандарт. Много модулей в стандартном использовании библиотеки __version__, и это также используется в партии из сторонних модулей, таким образом, это - квазистандарт.

Обычно, __version__ строка, но иногда это - также плавание или кортеж.

Редактирование: как упомянуто S.Lott (Спасибо!), PEP 8 говорит это явно:

Бухгалтерия Версии

, Если у Вас должна быть Подрывная деятельность, CVS или свернувшееся молоко RCS в Вашем исходном файле, делает это следующим образом.

    __version__ = "$Revision: 63990 $"
    # $Source$

Эти строки должны быть включены после docstring модуля, перед любым другим кодом, разделенным пустой строкой выше и ниже.

необходимо также удостовериться, что номер версии соответствует формату, описанному в PEP 440 ( PEP 386 предыдущая версия этого стандарта).

117
ответ дан me_and 23 November 2019 в 03:21
поделиться

Если это имеет значение, если Вы используете NumPy distutils, numpy.distutils.misc_util.Configuration имеет make_svn_version_py() метод, который встраивает число пересмотра в package.__svn_version__ в переменной version.

-1
ответ дан Matt 23 November 2019 в 03:21
поделиться

Кажется, нет стандартного способа встроить строку версии в пакет Python. Большинство пакетов, которые я видел, использует некоторый вариант Вашего решения, т.е. любой

  1. Встраивают версию в setup.py и имеют setup.py, генерируют модуль (например, version.py) содержащий только информацию о версии, это импортируется Вашим пакетом, или

  2. реверс: поместите информацию о версии в свой пакет сам и импортируйте что для установки версии в setup.py

5
ответ дан dF. 23 November 2019 в 03:21
поделиться

Также стоящий замечания то, что, а также __version__ являющийся полустанд. в Python так __version_info__, который является кортежем в простых случаях, как которые можно просто сделать что-то:

__version__ = '1.2.3'
__version_info__ = tuple([ int(num) for num in __version__.split('.')])

... и можно добраться эти __version__ строка из файла, или что бы то ни было.

6
ответ дан Craig McQueen 23 November 2019 в 03:21
поделиться

При использовании Мерзавца для VCS

лучшее решение я нашел, когда использование Мерзавца для VCS/SCM должно использовать setuptools с pbr расширение. Это позволит Мерзавцу быть Вашим основным источником истины для некоторых метаданных, включая версию, авторов, журналы изменений, и т.д., таким образом, у Вас не будет дублированной информации, которая выходит из синхронизации, и devs может работать непосредственно в Мерзавце.

, Поскольку PBR вытянет версию, автора, журнал изменений и другую информацию непосредственно от Вашего мерзавца repo, таким образом, много метаданных в setup.cfg сможет быть не учтено и автоматическое сгенерированный.

PBR вытянет последнюю информацию в режиме реального времени с помощью setup.py команды, например:

py setup.py --version

Это вытянет последнюю версию от мерзавца repo, на основе последней фиксации, которая была сделана. Это не обновляет версию в распределении все же. При создании распределения с setup.py (т.е. py setup.py sdist, например), тогда вся текущая информация будет извлечена и сохранена в распределении.

можно получить доступ к метаданным от текущей сборки в рамках сценариев Python в самом пакете. Для версии, например, существует несколько способов сделать это, я нашел до сих пор:

import pkg_resources  # part of setuptools

# I don't like this one because the version method is hidden
v1 = pkg_resources.require("md2mat")[0].version
print('v1 {}'.format(v1))

# This is my favorite - the output without .version is just a longer string with
# both the package name, a space, and the version string
v2 = pkg_resources.get_distribution('md2mat').version
print('v2 {}'.format(v2))

from pbr.version import VersionInfo

# This one seems to be slower, and with pyinstaller makes the exe a lot bigger
v3 = VersionInfo('md2mat').release_string()
print('v3 {}'.format(v3))

можно поместить один из них непосредственно в Вашем __init__.py, чтобы пакет извлек информацию о версии следующим образом, подобный некоторым другим ответам:

__all__ = (
    '__version__',
    'my_package_name'
)

import pkg_resources  # part of setuptools

__version__ = pkg_resources.get_distribution("md2mat").version
-1
ответ дан 23 November 2019 в 03:21
поделиться

Хотя это, вероятно, уже слишком поздно, есть немного более простая альтернатива предыдущему ответу:

__version_info__ = ('1', '2', '3')
__version__ = '.'.join(__version_info__)

(И было бы довольно просто преобразовать автоматически увеличивающиеся части номеров версий в строка с использованием str () .)

Конечно, из того, что я видел, люди склонны использовать что-то вроде ранее упомянутой версии при использовании __ version_info __ и как таковые сохранить его как кортеж целых чисел; однако я не совсем вижу в этом смысл, так как сомневаюсь, что есть ситуации, когда вы будете выполнять математические операции, такие как сложение и вычитание частей номеров версий, для любых целей, кроме любопытства или автоматического увеличения (и даже тогда, int () и str () могут использоваться довольно легко). (С другой стороны, есть вероятность того, что чей-то другой код ожидает числовой кортеж, а не строковый кортеж, и, таким образом, потерпит неудачу.)

Это, конечно, мое собственное мнение, и я с радостью хотел бы узнать мнение других об использовании числового кортежа.


Как Шези напомнил мне, (лексические) сравнения числовых строк не обязательно дают тот же результат, что и прямые числовые сравнения; Для этого потребуются начальные нули. Так что, в конце концов, сохранение __ version_info __ (или как бы он там ни назывался) в виде кортежа целочисленных значений позволило бы более эффективно сравнивать версии.

(лексические) сравнения числовых строк не обязательно дают тот же результат, что и прямые числовые сравнения; Для этого потребуются начальные нули. Так что, в конце концов, сохранение __ version_info __ (или как бы он там ни назывался) в виде кортежа целочисленных значений позволило бы более эффективно сравнивать версии.

(лексические) сравнения числовых строк не обязательно дают тот же результат, что и прямые числовые сравнения; Для этого потребуются начальные нули. Так что, в конце концов, сохранение __ version_info __ (или как бы он там ни назывался) в виде кортежа целочисленных значений позволило бы более эффективно сравнивать версии.

21
ответ дан 23 November 2019 в 03:21
поделиться

Еще я видел другой стиль:

>>> django.VERSION
(1, 1, 0, 'final', 0)
4
ответ дан 23 November 2019 в 03:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: