Создание атрибута __version__ для пакетов python без проблем

После чтения документации python (http://www.python.org/dev/peps/pep-0396/) я был более смущен, чем раньше, о том, как правильно установить атрибут __version__ для пакетов. Упоминается, чтобы помещать их в файл setup.py, что меня смущает: он не будет доступен как my_package.__version__, не так ли?

Я закончил импорт атрибута версии из отдельного файла.

Итак, мой файл "версия" обычно

my_package/
    __init__.py
    my_module1/
        ...
    my_module2/
        ...
    my_module3/
        ...
    info/
        __init__.py
        version.py
            __version__ = '0.1.0'

и в самом верхнем __init__.py я импортирую атрибут __version__ от info.version:

import __version__

чтобы получить номер версии через

my_package.__version__

Мне просто интересно, подходит ли это "хорошо", и если что-то говорит против этого? Я с нетерпением жду ваших мнений и предложений!

Ответ 1

Одним из решений является определение __version__ в вашем файле __init__.py и чтение этого с помощью setup.py. Это означает, что вам нужно только изменить версию в одном месте. Я написал небольшую функцию, которая сделает это:

from setuptools import setup
import re

def get_property(prop, project):
    result = re.search(r'{}\s*=\s*[\'"]([^\'"]*)[\'"]'.format(prop), open(project + '/__init__.py').read())
    return result.group(1)

project_name = 'YOUR PROJECT'
setup(
    ...,
    version = get_property('__version__', project_name),
    ...,
)

вы также можете использовать это для получения таких вещей, как __author__ или что-либо еще, определенное в файле __init__.py

Ответ 2

Вы не сказали, как вы получите номер версии в setup.py, но не пытайтесь импортировать его с помощью обычного подхода import my_package. Пакет не был установлен при запуске setup.py!

Мой обычный подход - определить номер версии в файле setup.py и setup.py(re) сгенерировать файл верхнего уровня __init__.py пакета при изменении номера версии. Это легко сделать, если файл __init__.py не содержит другого кода.