Пользовательские команды distutils

У меня есть библиотека под названием "example", которую я устанавливаю в мой каталог глобальных пакетов сайтов. Тем не менее, я хотел бы иметь возможность устанавливать две версии: одну для производства и одну для тестирования (у меня есть веб-приложение и другие вещи, которые версируются таким образом).

Есть ли способ указать, скажем, "python setup.py stage", который не только установит другое яйцо в пакеты сайта, но и переименует модуль из "example" в "example_stage" или что-то подобное?

Если distutils не может этого сделать, есть ли другой инструмент, который может?

Ответ 1

Конечно, вы можете расширить distutils новыми командами. В файле конфигурации distutil добавьте:

 [global]
 command-packages=foo.bar

это может быть в distutils.cfg в самом пакете distutils, ..pydistutils.cfg в вашем домашнем каталоге (без ведущей точки в Windows) или setup.cfg в текущем каталоге.

Затем вам понадобится пакет foo.bar в каталоге Python-сайтов.

Затем в этом пакете вы добавляете классы, реализующие ваши новые желаемые команды, такие как stage, subclassing distutils.cmd - документы являются слабыми, но примеров много, поскольку все существующие команды distutils также построены таким образом.

Ответ 2

Это легко можно сделать с distutils путем подклассификации distutils.core.Command внутри setup.py.

Например:

from distutils.core import setup, Command
import os, sys

class CleanCommand(Command):
    description = "custom clean command that forcefully removes dist/build directories"
    user_options = []
    def initialize_options(self):
        self.cwd = None
    def finalize_options(self):
        self.cwd = os.getcwd()
    def run(self):
        assert os.getcwd() == self.cwd, 'Must be in package root: %s' % self.cwd
        os.system('rm -rf ./build ./dist')  

Чтобы включить команду, вы должны ссылаться на нее в setup():

setup(
     # stuff omitted for conciseness.
     cmdclass={
        'clean': CleanCommand
}

Обратите внимание, что вы также можете переопределить встроенные команды, например, то, что я сделал с "clean". (Мне не понравилось, как встроенная версия оставила каталоги dist и build.)

% python setup.py --help-commands | grep clean
  clean            custom clean command that forcefully removes dist/build dirs.

Существует несколько соглашений:

  • Вы указываете любые аргументы командной строки с user_options.
  • Вы объявляете какие-либо переменные, которые вы использовали бы с помощью метода initialize_options(), который вызывается после инициализации, чтобы настроить собственное пространство имен для подкласса.
  • Метод finalize_options() вызывается непосредственно перед run().
  • Отбросы самой команды будут выполняться в run(), поэтому перед этим обязательно выполняйте любую другую подготовительную работу.

Лучшим примером для использования является просто посмотреть исходный код для одной из команд по умолчанию, найденных в команде PYTHON_DIR/distutils/, например install.py или build.py.

Ответ 3

Если вы хотите использовать несколько версий, то virtualenv с virtualenvwrapper.

Ответ 4

Смотрите Alex answer, если вы хотите сделать это с distutils, но я нахожу Paver, чтобы быть лучше для такого рода вещей. Это упрощает создание пользовательских команд или отмену существующих. Кроме того, переход не является ужасно трудным, если вы привыкли к distutils или setuptools.