2013-03-17 8 views
5

Ho un software Python che include un file di configurazione e una manpage. Per installare questi, ho la seguente riga nel mio setup.py (come descritto a http://docs.python.org/2/distutils/setupscript.html#installing-additional-files):Come verificare se Python è in esecuzione da un virtualenv durante l'installazione del pacchetto

data_files = [('/etc/foo', ['foo.conf']), ('/usr/share/man/man1', ['foo.1'])] 

Questo funziona bene quando voglio installare il software come root con python setup.py install, ma ovviamente non riesce in un virtualenv, poiché l'utente non è autorizzato a scrivere su /etc e /usr/share/man.

Qual è la procedura migliore per risolverlo? Controllare l'VIRTUAL_ENV nell'ambiente corrente e non installare affatto quei file? Il software cercherà foo.conf nella directory locale, quindi non dovrebbe esserci alcun problema. L'utente mancherebbe la manpage, ma non esiste un modo corretto di installarlo comunque, poiché man non lo cercherà da nessuna parte vicino alla virtualenv.

+3

Non ho una risposta completa alla domanda, ma il controllo di VIRTUAL_ENV non è affidabile poiché si può anche eseguire esplicitamente il binario "python" dalla directory bin di virtualenv per ottenere lo stesso effetto. –

+0

@MartinAtkins sicuro? L'attuale binario è identico: 'md5sum/tmp/bar/bin/python/usr/bin/python b35da8492c4ddb3e3413411e574db63a/tmp/bar/bin/python b35da8492c4ddb3e3413411e574db63a/usr/bin/python'. E la mia comprensione era che * dovevo * attivare l'env tramite l'acquisizione di 'bin/activate'. – zhenech

+1

No, non è necessario attivare l'env. Puoi 'cd/path/to/virtualenv' quindi' bin/python' va bene. –

risposta

9

Alla fine sembra che la tua domanda riguardi davvero come rilevare se Python è in esecuzione in un virtualenv. Per arrivare alla fine di questo dobbiamo capire come funziona davvero virtualenv.

Quando si esegue lo script activate all'interno di un virtualenv, che fa due cose:

  • aggiorna la variabile PATH ambiente per includere la directory bin dalla virtualenv, in modo che quando si esegue python il binario dal verrà eseguito virtualenv.
  • imposta una variabile VIRTUAL_ENV in modo che lo script di attivazione stesso possa tenere traccia dell'attivazione.

è perfettamente accettabile per eseguire direttamente il python dalla virtualenv, e in fase di esecuzione python non usa la variabile VIRTUAL_ENV affatto. Determina invece la directory contenente il binario python in esecuzione e utilizza la directory superiore come "prefisso".

È possibile determinare il prefisso del sistema importando il modulo sys e consultando sys.prefix. Tuttavia, sarebbe una cattiva idea dipendere dal valore di questo quando un virtualenv è non attivato perché questa è un'impostazione di tempo per Python che può essere facilmente personalizzata e che sicuramente varierà tra le piattaforme.

Tuttavia, Python ha uno leggera differenza di runtime quando si va da un virtualenv prefisso contro il suo prefisso compilato-in: il pacchetto sys ha una variabile aggiuntiva real_prefix che restituisce il prefisso che viene compilato in binario Python. Pertanto si potrebbe usare questo per riconoscere che Python è in esecuzione in una posizione non predefinita, che è ragionevolmente probabile che significa che è in esecuzione da un virtualenv:

import sys 

if getattr(sys, "real_prefix", None) is not None: 
    print "Maybe in a virtualenv" 
else: 
    print "Probably not in a virtualenv" 

Tuttavia, anche questo non è una scienza esatta. Tutto questo ti dice che il binario python non si trova nella posizione specificata al momento della compilazione.Esso non dice se l'utente corrente ha accesso a scrivere a /usr/share/man - ci sono alcuni casi (possibilmente bordo) in cui questo non vi darà la risposta giusta:

  • Se l'utente ha compilato il proprio Python dalla sorgente nella sua home directory e il suo prefisso compilato è /home/johnd/local-python quindi non sarà impostato real_prefix ma l'utente ha ancora accesso in scrittura alla sua directory Python lib, e probabilmente non accesso in scrittura a /etc o /usr/share/man

  • Allo stesso modo , su alcuni sistemi che l'amministratore può avere ha concesso i privilegi di scrittura di gruppo su /usr/lib/python2.7 a un determinato gruppo di sviluppatori di app in modo che possano installare i moduli Python, ma non hanno concesso loro l'accesso in scrittura ad altri file di sistema.

Quindi penso alla fine il migliore che si può fare è un'euristica e potrebbe essere meglio invece solo evitare l'uso di percorsi assoluti in data_files per qualsiasi modulo che ci si aspetta per essere utilizzato all'interno di un virtualenv. Un compromesso potrebbe essere quello di dividere semplicemente il modulo in due distribuzioni, una che rappresenta i file di origine localizzabili e un'altra che rappresenta la configurazione a livello di sistema per farlo funzionare. Quest'ultimo può dipendere dal primo in modo che gli utenti possano ancora installarlo facilmente, ma quelli che usano virtualenv hanno la possibilità di usare direttamente l'altro.

Problemi correlati