Напрямую вызывать функцию setup () distutils или setuptools с именем / опциями команды, без разбора командной строки? - PullRequest
8 голосов
/ 17 мая 2010

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

В качестве примераскажем, у меня в настоящее время есть файл 'setup.py', который выглядит следующим образом (дословно поднял из документации по distutils - использование 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» с опцией «--spec-only», БЕЗ анализапараметры командной строки?Могу ли я передать имя команды и параметры в качестве параметров в setup ()?Или я могу вручную создать командную строку и передать ее вместо параметра?

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

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

Ответы [ 2 ]

11 голосов
/ 17 мая 2010

Никогда не пробовал, но я случайно заглянул в 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 (), добавив:

setup(
    ...
    script_name = 'setup.py',
    script_args = ['bdist_rpm', '--spec-only']
)
2 голосов
/ 18 мая 2010

Просто "подделайте" параметры командной строки - например, запустите ваш скрипт с

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, либо "объединяйте" то, что набрал пользователь, и т. д ...но это сильно отличается от того, что вы на самом деле просили, так что я собираюсь на этом остановиться; -).

...