2010-05-17 13 views
7

Chciałbym nazwać Python's distutils lub setuptools w funkcji setup() w nieco niekonwencjonalny sposób, ale nie jestem pewien, czy distutils są przeznaczone do tego rodzaju użycia.Bezpośrednio wywołuje funkcję setup() distutils lub setuptools za pomocą nazwy polecenia/opcji, bez parsowania wiersza poleceń?

Jako przykład, powiedzmy, że obecnie mają „setup.py” plik, który wygląda tak (podnoszone verbatim z distutils docs - korzystanie setuptools jest niemal identyczna):

from distutils.core import setup 

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

Normalnie , aby zbudować tylko plik .spec dla RPM tego modułu, mógłbym uruchomić python setup.py bdist_rpm --spec-only, który parsuje wiersz poleceń i wywołuje kod "bdist_rpm", aby obsłużyć specyficzne dla RPM rzeczy. Plik .spec kończy się na './dist'.

Jak zmienić moje wywołanie setup(), aby uruchamiało polecenie "bdist_rpm" z opcją "--spec-only", BEZ analizowania parametrów wiersza polecenia? Czy mogę przekazać nazwę polecenia i opcje jako parametry do ustawienia()? Czy mogę ręcznie utworzyć wiersz polecenia i przekazać go jako parametr?

UWAGA: Wiem już, że mógłbym wywołać skrypt w oddzielnym procesie z rzeczywistą linią poleceń, używając os.system() lub modułu podprocesowego lub czegoś podobnego. Próbuję unikać używania jakichkolwiek zewnętrznych wywołań poleceń. Szukam specjalnie dla rozwiązania, które uruchamia setup() w bieżącym interpretera.

W tle konwertuję niektóre skrypty powłoki zarządzania wersjami do jednego programu w języku Python. Jednym z zadań jest uruchomienie "setup.py" w celu wygenerowania pliku .spec do dalszych testów wstępnych. Uruchamianie "setup.py" jako zewnętrznego polecenia z własnymi opcjami wiersza poleceń wydaje się być niewygodną metodą, która komplikuje resztę programu. Czuję, że może być bardziej Pythonicznie.

+0

Podoba mi się pytanie. Wydaje mi się, że 'setup()' jest źle zaprojektowany - powinien przynajmniej wziąć argument 'sys.argv' jako argument zamiast wykonywać magię. Parametr może nawet domyślnie "sys.argv" (jak w argparse), ale powinien być zarówno udokumentowany, jak i widoczny w sygnaturze funkcji. – abukaj

Odpowiedz

9

Nigdy nie próbowałem, ale nie stało się spojrzeć w distutils/core.py, gdzie ja to zauważyć w pobliżu początku 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:] 

Tak, to wygląda tak, jakby można „fałszywe-out "setup(), dodając:

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

@ ig0775: Dzięki, właśnie to chciałem zrobić. Właśnie to przetestowałem i działa dobrze. Całkiem czysty wygląd. –

1

tylko "fake" parametry wiersza poleceń - np zacząć Ci skrypt

import sys 

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

from distutils.core import setup 

setup(name='Distutils', 

itd. W końcu tak to distutils otrzymuje parametry wiersza poleceń: wygląda na sys.argv! Tak więc ustaw sys.argv tak, aby był dokładnie taki, jak chcesz, a jakakolwiek linia poleceń, którą błędnie wpisał użytkownik, zostanie całkowicie zignorowana.

Faktycznie, warto sprawdzić, czy użytkownik zrobił wprowadzić żadnego argumentu masz zamiar ignorować - len(sys.argv) > 1 przed modyfikować sys.argv - i dać ostrzeżenie, lub uniknąć zmianę sys.argv lub "scalaj" to, co wpisał użytkownik, itd ... ale to coś zupełnie innego niż to, o co prosiłeś, więc zamierzam to zostawić ;-).

+0

Przyszło mi to do głowy, ale wydawało mi się, że jest trochę nieporządny.Ale gdyby nie metoda @ ig0774, prawdopodobnie tak bym sobie z tym poradził. –

+0

@ RyanB.Lynch: * wydawało się trochę nieporządne * - Smutne, smutne jest to: rutyna Distutils i Setup Tools 'run_setup' robi dokładnie to, tylko z odrobiną oblodzenia na górze. Możesz to zobaczyć np. [Tutaj] (http://github.com/pypa/setuptools/blob/master/setuptools/sandbox.py) w źródłach (szukaj 'run_setup'). – Wrzlprmft

Powiązane problemy