Документация Python неофициальный перевод
Содержание страницы

ПримерыExamples

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

См. также

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

Дистрибутив чистого Python (по модулю)Pure Python distribution (by module)

Если распространяется всего несколько модулей, особенно если они не находятся в определённом пакете, их можно указать по отдельности с помощью опции 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'],
      )

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

Дистрибутив чистого Python (по пакету)Pure Python distribution (by package)

Если нужно распространять более нескольких модулей, особенно если они находятся в нескольких пакетах, вероятно, проще указать целые пакеты, а не отдельные модули. Это работает даже если модули не находятся в пакете; можно просто указать 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'],
      )

(И снова пустая строка в package_dir обозначает текущий каталог.)

Одиночный модуль расширенияSingle extension module

Модули расширения указываются с помощью опции 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'])],
      )