Spec-Zone.ru › Python 3.11

Примеры Distutils

Примечание

Этот документ сохраняется только до тех пор, пока документация setuptools по адресу https://setuptools.readthedocs.io/en/latest/setuptools.html самостоятельно не покроет всю актуальную информацию, включённую сюда.

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

См. также

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

Сборник рецептов, демонстрирующих, как получить больший контроль над distutils.

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

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

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

<root>/
        setup.py
        foo.py

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

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

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

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

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

и скрипт setup может быть таким:

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

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

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

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

Скрипт setup из предыдущего примера также можно переписать следующим образом:

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, и та, которая требует наименьших усилий при описании в скрипте setup:

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

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

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

в этом случае ваш скрипт setup будет таким:

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

то соответствующий скрипт setup будет следующим:

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 принадлежит корневому пакету, скрипт setup для этого может быть таким:

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.11/distutils/examples.html

Spec-Zone.ru

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