Spec-Zone.ru › Python 3.8

Примеры Distutils

Примечание

Данный документ сохраняется только до тех пор, пока документация setuptools по адресу https://setuptools.readthedocs.io/en/latest/setuptools.html не будет содержать всю необходимую информацию, в настоящее время представленную здесь.

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

См. также

Руководство по distutils

Коллекция рецептов, показывающих, как получить больший контроль над distutils.

6.1. Распространение чистого Python-модуля (по модулям)

Если вы только распределяете несколько модулей, особенно если они не находятся в конкретном пакете, вы можете указать их индивидуально, используя параметр py_modules в скрипте настройки.

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

<root>/
        setup.py
        foo.py

(Во всех диаграммах в этом разделе <root> будет ссылаться на корневой каталог распространения.) Минимальный скрипт настройки для описания этой ситуации будет:

from distutils.core import setup
setup(name='foo',
      version='1.0',
      py_modules=['foo'],
      )

Обратите внимание, что имя распространения указывается независимо с помощью параметра name, и нет правила, гласящего, что оно должно совпадать с именем единственного модуля в распространении (хотя это, вероятно, хорошая соглашение). Однако имя распространения используется для генерации имен файлов, поэтому вы должны придерживаться букв, цифр, символов подчеркивания и дефисов.

Поскольку py_modules является списком, вы можете, конечно, указать несколько модулей, например, если вы распространяете модули foo и bar, ваша настройка может выглядеть так:

<root>/
        setup.py
        foo.py
        bar.py

и скрипт настройки может быть

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      py_modules=['foo', 'bar'],
      )

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

6.2. Распространение чистого Python-пакета

Если вам нужно распространить более нескольких модулей, особенно если они находятся в нескольких пакетах, скорее всего, проще указать целые пакеты, а не отдельные модули. Это работает даже если ваши модули не находятся в пакете; вы можете просто сказать distutils обрабатывать модули из корневого пакета, и это работает так же, как и с любым другим пакетом (за исключением того, что вам не нужно иметь файл __init__.py).

Скрипт настройки из предыдущего примера также можно записать так

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      packages=[''],
      )

(Пустая строка означает корневой пакет.)

Если эти два файла переместить в подкаталог, но сохранить в корневом пакете, например:

<root>/
        setup.py
        src/      foo.py
                  bar.py

тогда вы всё равно будете указывать корневой пакет, но должны указать distutils, где находятся исходные файлы в корневом пакете:

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      package_dir={'': 'src'},
      packages=[''],
      )

Однако чаще всего вы захотите распространить несколько модулей в одном пакете (или в подпакетах). Например, если модули foo и bar принадлежат пакету foobar, один способ размещения вашей структуры источников выглядит так

<root>/
        setup.py
        foobar/
                 __init__.py
                 foo.py
                 bar.py

Это, по сути, стандартная структура, ожидаемая от distutils, и та, которая требует наименьших усилий при описании в вашем скрипте настройки:

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      packages=['foobar'],
      )

Если вы хотите поместить модули в каталоги, не имеющие имен своих пакетов, вам нужно снова использовать параметр package_dir. Например, если каталог src содержит модули пакета foobar, подходящий скрипт настроек будет выглядеть так:

<root>/
        setup.py
        src/
                 __init__.py
                 foo.py
                 bar.py

Или же вы можете поместить модули своего основного пакета прямо в корневой каталог распространения:

<root>/
        setup.py
        __init__.py
        foo.py
        bar.py

В этом случае ваш скрипт настроек будет выглядеть так

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      package_dir={'foobar': ''},
      packages=['foobar'],
      )

(Пустая строка также обозначает текущую директорию.)

Если у вас есть подпакеты, они должны быть явно перечислены в packages, но любые записи в package_dir автоматически распространяются на подпакеты. (Другими словами, distutils не ищет в вашей структуре каталогов, пытаясь определить, какие каталоги соответствуют пакетам Python, проверяя наличие файлов __init__.py.) Таким образом, если стандартная структура расширится на подпакет:

<root>/
        setup.py
        foobar/
                 __init__.py
                 foo.py
                 bar.py
                 subfoo/
                           __init__.py
                           blah.py

соответствующий скрипт настроек будет выглядеть так

from distutils.core import setup
setup(name='foobar',
      version='1.0',
      packages=['foobar', 'foobar.subfoo'],
      )

6.3. Модуль единственного расширения

Модули расширений указываются с помощью параметра ext_modules. package_dir не влияет на расположение исходных файлов расширения; он влияет только на исходные файлы чистого Python. Самый простой случай, один модуль расширения в одном исходном файле C:

<root>/
        setup.py
        foo.c

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

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[Extension('foo', ['foo.c'])],
      )

Если расширение действительно принадлежит пакету, например, foopkg, то

При абсолютно такой же структуре исходного дерева это расширение может быть помещено в пакет foopkg просто путем изменения имени расширения:

from distutils.core import setup
from distutils.extension import Extension
setup(name='foobar',
      version='1.0',
      ext_modules=[Extension('foopkg.foo', ['foo.c'])],
      )

6.4. Проверка пакета

Команда check позволяет проверить, соответствуют ли метаданные вашего пакета минимальным требованиям для создания распространения.

Чтобы запустить его, просто вызовите его с помощью вашего скрипта setup.py. Если чего-то не хватает, check выведет предупреждение.

Давайте рассмотрим пример с простым скриптом:

from distutils.core import setup

setup(name='foobar')

Запуск команды check отобразит некоторые предупреждения:

$ python setup.py check
running check
warning: check: missing required meta-data: version, url
warning: check: missing meta-data: either (author and author_email) or
         (maintainer and maintainer_email) must be supplied

Если вы используете синтаксис reStructuredText в поле long_description и docutils установлен, вы можете проверить правильность синтаксиса с помощью команды check, используя параметр restructuredtext.

Например, если скрипт setup.py изменён следующим образом:

from distutils.core import setup

desc = """\
My description
==============

This is the description of the ``foobar`` package.
"""

setup(name='foobar', version='1', author='tarek',
    author_email='tarek@ziade.org',
    url='http://example.com', long_description=desc)

Где длинное описание разделено, check сможет определить это, используя парсер docutils.

$ python setup.py check --restructuredtext
running check
warning: check: Title underline too short. (line 2)
warning: check: Could not finish the parsing.

6.5. Чтение метаданных

Функция distutils.core.setup() предоставляет интерфейс командной строки, который позволяет вам получить доступ к полям метаданных проекта с помощью скрипта setup.py данного проекта:

$ python setup.py --name
distribute

Этот вызов считывает метаданные name, выполняя функцию distutils.core.setup(). Однако, когда с помощью Distutils создаётся исходное или двоичное распределение, поля метаданных записываются в статический файл, называемый PKG-INFO. При установке проекта, основанного на Distutils, в Python, файл PKG-INFO копируется вместе с модулями и пакетами распространения в NAME-VERSION-pyX.X.egg-info, где NAME - имя проекта, VERSION - его версия, определенная в метаданных, а pyX.X - основные и второстепенные версии Python, как 2.7 или 3.2.

Вы можете прочитать этот статический файл, используя класс distutils.dist.DistributionMetadata и его метод read_pkg_file().

>>> from distutils.dist import DistributionMetadata
>>> metadata = DistributionMetadata()
>>> metadata.read_pkg_file(open('distribute-0.6.8-py2.7.egg-info'))
>>> metadata.name
'distribute'
>>> metadata.version
'0.6.8'
>>> metadata.description
'Easily download, build, install, upgrade, and uninstall Python packages'

Обратите внимание, что класс также может быть инициализирован путем передачи пути к файлу метаданных для загрузки его значений:

>>> pkg_info_path = 'distribute-0.6.8-py2.7.egg-info'
>>> DistributionMetadata(pkg_info_path).name
'distribute'

© 2001–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/distutils/examples.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API