Запустить функцию установки из setuptools, только если __name__ == "__main__"? - PullRequest
0 голосов
/ 21 января 2020

Я хотел бы запустить setup () в setup.py, только если модуль действительно запущен. Поэтому я хочу сделать что-то вроде:

from setuptools import setup

def somefunction():
    ...

if __name__ == "__main__":
    setup(...)

(я хочу использовать некоторые из определенных функций в файле, которые используются в вызове setup (), в другом скрипте python, который используется в процессе сборки документации)

Возможно ли это? Недопустимое? Обескураженный? Почему?

Я не смог найти никакой документации по этому поводу, но, как ни странно, во всех примерах НЕ используется тест для " main ", поэтому мне интересно, есть ли что-то, что делает использование этой проблемы c.

Ответы [ 3 ]

2 голосов
/ 21 января 2020

Охрана вокруг вызова setup() обычно не видна на практике, потому что этот файл обычно не импортируется . Хорошо известно, что это установщик script , предназначенный для непосредственного выполнения.

Однако вы можете добавить охрану по указанной причине (" Я хочу использовать некоторые определенных функций в файле") и все, что находится в distutils / setuptools, все равно должно работать нормально. Для сценария setup.py довольно необычно определять библиотечные функции внутри, поэтому вы можете спросить себя, есть ли лучший дом для таких функций, вместо того, чтобы писать их непосредственно в самом скрипте установщика.

Возможно ли это?

Да.

Запрещено?

Нет.

Обескуражен?

Отчасти основанный на мнении. Лично я бы сказал да: не одобряйте это.

Почему?

Задача setup.py состоит в установке вашего кода из исходного кода , период Обычно это не место для других случайных задач, таких как документирование процесса сборки. Этот файл даже не будет включен в дистрибутив wheel , который, вероятно, является наиболее типичным способом развертывания кода Python в наши дни.

В качестве заключительного замечания: если и когда вы переедете к современным Python методам упаковки, использующим pyproject.toml, с декларативной системой сборки, сценарий setup.py не будет. Тогда вам все равно придется искать новый дом для таких вспомогательных функций.

0 голосов
/ 21 января 2020

Вы можете go по другому маршруту и ​​добавить все интересующие вас функции в отдельный модуль, который обычно импортируется остальной частью вашей программы. Я бы не рекомендовал помещать функции пакета в setup.py, поскольку файл установки предназначен для использования вне вашего пакета. Вам может понадобиться служебная функция для импорта модуля по пути в setup.py. Я обычно использую что-то похожее на это:

def import_file(name, location):
    """
    Imports the specified python file as a module, without explicitly
    registering it to `sys.modules`.
    """
    if sys.version_info[0] == 2:
        # Python 2.7-
        from imp import load_source
        mod = load_source(name, location)
    elif sys.version_info < (3, 5, 0):
        # Python 3.4-
        from importlib.machinery import SourceFileLoader
        mod = SourceFileLoader(name, location).load_module()
    else:
        # Python 3.5+
        from importlib.util import spec_from_file_location, module_from_spec
        spec = spec_from_file_location(name, location)
        mod = module_from_spec(spec)
        spec.loader.exec_module(mod)
    return mod
0 голосов
/ 21 января 2020

Не должно быть проблемой. Я бы рекомендовал всегда использовать условие if __name__ == "__main__":, даже если там модуль никогда не импортируется. С другой стороны, я бы не рекомендовал делиться кодом между сценарием установки и кодом самого проекта.

...