Spec-Zone.ru › Python 3.10

Примеры использования 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

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

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

соответствующий скрипт настройки будет

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

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

<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) should 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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/distutils/examples.html

Spec-Zone.ru

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