Как я могу переопределить команду setuptools из зависимости setup_require? - PullRequest
0 голосов
/ 26 ноября 2018

Контекст:

Чтобы иметь возможность преобразовывать файлы gettext po из GNU в mo во время сборки в setuptools, я создал подкласс setuptools.command.build_py, который их компилирует (через копию pymsgfmt)перед вызовом его базового класса:

from setuptools.command.build_py import build_py as _build_py

class build_py(_build_py):
    parent = _build_py
    def run(self):
        self.compile_po_files()  # internal implementation
        self.parent.run(self)

    def get_outputs(self):  # overriden to produce a correct list of installed files
        build_mo = self.get_finalized_command("build_mo")
        return _build_py.get_outputs(self) + self.outputs

Затем мне нужно только объявить его в параметре cmdclass setup:

setup(
    ...
    cmdclass = {"build_py", mypgk.build_py},
)

Пока все хорошо, когда моймодуль устанавливается и импортируется в сценарий setup.py, фаза сборки setuptools корректно обрабатывает мои po-файлы.

Проблема:

Цель состоит в том, чтобы обеспечить простую установку исходного дистрибутива.с пип.Все выглядит хорошо, потому что pip заботится о любой зависимости, если она объявлена ​​в параметре install_requires или setup_requires.И в этом заключается проблема курицы и яйца: зависимость устанавливается при запуске setup.py, но не может работать без установки mypkg.

Текущее исследование:

Iпытался использовать магию entry_points для объявления переопределения build_py в сценарии mypkg setup.py:

...
entry_points = {
    "distutils.commands": [
        "build_py = mypkg:build_py",
        ],
}

, но он не имеет никаких эффектов, хотя я могу объявить рабочую новую build_moвведите команду таким образом:

entry_points = {
    "distutils.commands": [
        "build_mo = mypkg:build_py",
        ],
}

Короче говоря, python setup.py build_mo вызывает мое переопределение, в то время как python setup.py build_py вызывает версию setuptools.

Вопрос:

Почему моя попыткапереопределить команду build_py объявлением entry_points не работает, и как я могу это сделать?

1 Ответ

0 голосов
/ 26 ноября 2018

Объясняя проблему

Я был близок к решению.После еще нескольких исследований в setuptools документах и ​​источниках я наконец понял, что он уже использовал механизм entry_points для переопределения distutils команд своими собственными.

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

Теперь я могу сказать, что из-за этого только команды из distutils, которые не переопределяются в setuptools, могут быть обработаны таким образом.Хорошей новостью является то, что build не переопределяется и что при обычном использовании build_py всегда вызывается из build.

Возможное решение:

Поскольку команда buildне переопределяется setuptools, его легко заменить на entry_point.Затем пользовательский класс команды build может обновить каталог cmdclass, чтобы объявить пользовательский класс build_py, потому что база build загружает его.Код может быть:

from distutils.command.build import build as _build

class build(_build):
    parent = _build
    def run(self):
        self.distribution.cmdclass["build_py"] = build_py
        self.parent.run(self)

В моем тесте достаточно, чтобы setuptools использовал пользовательский класс build_py с простым

setup(
    ...
    setup_requires = ["mypkg"],
)
...