Вопрос: Непосредственно вызовите функцию setuptools distutils или setuptools () с именем / параметрами команды, без разбора командной строки?


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

В качестве примера предположим, что у меня в настоящее время есть файл setup.py, который выглядит так (снятый дословно из документов distutils docs - использование setuptools почти идентично):

from distutils.core import setup

setup(name='Distutils',
      version='1.0',
      description='Python Distribution Utilities',
      author='Greg Ward',
      author_email='gward@python.net',
      url='http://www.python.org/sigs/distutils-sig/',
      packages=['distutils', 'distutils.command'],
     )

Как правило, для создания только файла .spec для RPM этого модуля я мог бы запускать python setup.py bdist_rpm --spec-only, который анализирует командную строку и вызывает код «bdist_rpm» для обработки специфичных для RPM файлов. Файл .spec попадает в './dist'.

Как я могу изменить вызов setup (), чтобы он запускал команду «bdist_rpm» с опцией «только -специализация», БЕЗ анализа параметров командной строки? Могу ли я передать имя и параметры команды в качестве параметров для setup ()? Или я могу вручную создать командную строку и передать это как параметр?

ПРИМЕЧАНИЕ. Я уже знаю, что я мог бы вызвать сценарий в отдельном процессе с фактической командной строкой, используя os.system () или модуль подпроцесса или что-то подобное. Я пытаюсь избежать использования каких-либо внешних вызовов команд. Я ищу специально для решения, которое запускает setup () в текущем интерпретаторе.

Для фона я конвертирую некоторые сценарии оболочки релиза в одну программу Python. Одной из задач является «setup.py» для создания файла .spec для дальнейшего тестирования перед выпуском. Запуск «setup.py» в качестве внешней команды с ее собственными параметрами командной строки выглядит как неудобный метод, и это усложняет остальную часть программы. Я чувствую, что может быть более путинский путь.


8


источник


Ответы:


Никогда не пробовал это, но я действительно смотрел в distutils / core.py, где я замечаю это в начале setup():

if 'script_name' not in attrs:
    attrs['script_name'] = os.path.basename(sys.argv[0])
if 'script_args' not in attrs:
    attrs['script_args'] = sys.argv[1:]

Итак, похоже, что вы можете настроить «подделку» (), добавив:

setup(
    ...
    script_name = 'setup.py',
    script_args = ['bdist_rpm', '--spec-only']
)

11



Просто «подделайте» параметры командной строки - например, запустите сценарий с помощью

import sys

sys.argv[1:] = ['bdist_rpm', '--spec-only']

from distutils.core import setup

setup(name='Distutils',

и т. д. В конце концов, вот как distutils получает параметры командной строки: он выглядит sys.argv! Итак, просто установите sys.argv точно так же, как вы этого хотите, и всякая командная строка, введенная неверно введенным пользователем, будет полностью проигнорирована.

Фактически, вы можете проверить, является ли пользователь сделал  введите любой аргумент, который вы собираетесь игнорировать - len(sys.argv) > 1 перед изменением sys.argv - и дать предупреждение или избежать изменения sys.argv, или «слить» то, что пользователь набрал, и т. д., но это сильно отличается от того, что вы на самом деле просили, поэтому я собираюсь оставить его; -).


2