Nel caso sia necessario fare il backporting di un Python più recente su una distribuzione molto datata, c'è una alternativa rispetto a scaricare i sorgenti e procedere alla compilazione. Si tratta di pyenv, che si definisce in questo modo: pyenv lets you easily switch between multiple versions of Python. It's simple and unobtrusive.
Il tool pyenv è in grado di automatizzare gran parte del processo, che comunque prevede il download e la compilazione dei sorgenti. Quindi è necessario installare a livello di systema i tool di compilazione e le gli header delle librerie da cui dipende Python. L'installazione del Python 2.7 e delle librerie aggiuntive desiderate invece può risiedere nella $HOME di un utente, senza disturbare il resto del sistema.
Queste le installazioni da fare come root:
apt-get install curl git gcc build-essential \ libmysqlclient-dev libadns1-dev \ libreadline-dev libgdbm-dev zlib1g-dev libsqlite3-dev \ libssl-dev libbz2-dev libncurses5-dev libdb-dev
ATTENZIONE: Qui si installa pyenv nella directory utente $HOME/.pyenv/ che è sconsigliato se deve essere usata a livello di sistema (vedi più avanti):
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer \ > pyenv-installer export USE_GIT_URI='yes' cat pyenv-installer | bash
Più opportunamente si può usare una directory di sistema, pur eseguendo il tutto da utente non privilegiato. L'impostazione USE_GIT_URI serve ad utilizzre http invece di https per aggirare il problema di SSL su vecchie distribuzioni: tlsv1 alert protocol version.
ATTENZIONE: la directory destinazione (nell'esempio /usr/local/lib/pyenv
NON deve esistere, ma la directory parente deve essere scrivibile dall'utente che esegue il comando:
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer \ > pyenv-installer export USE_GIT_URI='yes' export PYENV_ROOT='/usr/local/lib/pyenv' cat pyenv-installer | bash
Dopo aver installato il tool pyenv è necessario inizializzare l'ambiente prima di usarlo (conviene aggiungere i comandi a .bashrc
o simili):
export PYENV_ROOT='/usr/local/lib/pyenv' export PYTHON_BUILD_CACHE_PATH=/usr/local/lib/pyenv/cache export PATH="/usr/local/lib/pyenv/bin:$PATH" eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)"
Per evitare il problema di download su https, si è scaricato da altro host il file Python-2.7.13.tar.xz e lo si è messo nella directory PYTHON_BUILD_CACHE_PATH (che va creata), a questo punto si può eseguire
pyenv install 2.7.13
Per selezionare l'ambiente Python 2.7.13 appena installato invece di quello di sistema, si deve aggiungere questa variabile d'ambiente (oltre a quelle viste in precedenza):
export PYENV_VERSION=2.7.13
Dopo avere settato queste variabili è possibile installare librerie con il gestore pip. Resta il problema del download automatico via https, per aggirarlo è necessario fare il download del pacchetto da un altro host e quindi eseguire pip install nomefile.tar.gz.
La directory $HOME/.pyenv/
non può essere spostata altrove. Molti degli eseguibili creati in $HOME/.pyenv/versions/2.7.13/ contengono hard-coded il percorso di installazione originale, ad esempio:
Con l'installazione di pyenv e di Python 2.7.13 comunque non si risolve il problema dell'SSL: Debian 6 fornisce una versione troppo vecchia della libreria, quindi il wget da siti https falisce. Ad esempio anche la ricerca della libreria openpyxl fallisce:
pip search openpyxl ... SSLError: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:661)
Ovviamente viene a mancare anche la gestione delle eventuali dipendenze (download e install automatico). La soluzione è scaricare gli archivi necessari e copiarli in una directory locale prima di fare l'installazione. Nel caso della libreria openpyxl gli archivi necessari sono prelevabili da pypi.org:
Gli archivi di tipo .tar.gz vanno scompattati, mentre i .whl (Python wheel) possono essere installati direttamente (ricordarsi sempre di settare le variabili di ambiente Pyenv):
pip install /usr/local/download/openpyxl/jdcal-1.4.1-py2.py3-none-any.whl pip install /usr/local/download/openpyxl/et_xmlfile-1.0.1/ pip install /usr/local/download/openpyxl/openpyxl-2.6.2/
L'operazione è del tutto analoga, salvo che i pacchetti per la compilazione si chiamano in modo diverso:
yum install gcc git readline-devel zlib-devel bzip2-devel libsq3-devel openssl-devel
Per fare pip install lxml servono anche i seguenti pacchetti (probabilmente è necessario solo il libxml2-devel):
yum install libxml2-python libxslt-python libxml2-devel libxslt-devel
Su Fedora 12 c'è il grave problema della libreria SSL obsoleta, per cui tutti i download su protocollo https falliscono. È necessario scaricare i file localmente per altra via (scp) e poi usare i trucchi sopra per eseguire le installazioni da file locali.
Un esempio pratico: si deve eseguire uno script Python che utilizza le librerie bs4, lxml e suds.
Avendo installato Python 2.7, si dovrà cercare le librerie marcate con cp27, che significa appunto CPython 2.7 (la versione ufficiale di Python distrinuita da python.org).
I suffissi cp27m e cp27mu si riferiscono ai tag ABI --enable-unicode=ucs2 e --enable-unicode=ucs4 rispettivamente. Per vedere quale ABI supporta il proprio Python si esegue il comando print sys.maxunicode; il valore restituito significa: 65535 = ucs2, 1114111 = ucs4.
I file con estensione .whl sono wheel distribution. Possono essere installati direttamente con pip install pacchetto.whl.
Se si desidera che eseguento genericamente python venga avviata la versione 2.7 invece che quella di sistema, basta creare uno script /usr/local/bin/python che contiene:
#!/bin/sh export PYENV_ROOT="/usr/local/lib/pyenv" export PATH="/usr/local/lib/pyenv/bin:$PATH" eval "$(pyenv init - --no-rehash)" eval "$(pyenv virtualenv-init -)" export PYENV_VERSION=2.7.13 exec python "$@"
L'opzione --no-rehash serve ad evitare l'errore causato dal tentativo di python di aggiornare la directory degli shim (script che intercettano le chiamate ai vari tool e le dirottano all'eseguibile opportuno):
pyenv: cannot rehash: /usr/local/lib/pyenv/shims isn't writable
Ricordarsi comunque che per eseguire pip e simili bisogna impostare le variabili d'ambiente.
Il comando pip può essere usato per installare le librerie necessarie nell'ambiente Python in uso. In caso di Python installato in backporting come illustrato sopra (pyenv, ecc.) è sufficiente impostare le variabili d'ambiente necessarie a pyenv prima di eseguire pip.
Alcuni comandi utili:
pip list | Elenca i pacchetti installati tramite il sistema pip. |
---|---|
pip freeze | Elenca i pacchetti installati tramite il sistema pip, in formato requirements. |
pip search package | Cerca un pacchetto disponibile nei repository pip. |
pip install package | Scarica un pacchetto dai repository e lo installa. |
pip install /src/pkg/dir/ | Installa un pacchetto dalla directory di installazione (deve contenere il file setup.py). |
pip uninstall package | Rimuove un pacchetto installato. Se si desidera disinstallare una specifica versione, usare la stringa prodotta da pip freeze (requirements format), ad esempio: pip uninstall Pillow==5.4.1 |
Per vedere quali moduli installati da pip sono disponibili in Pyton (e le rispettive versioni), eseguire in Python:
import pip pip.get_installed_distributions(local_only=True) [ setuptools 28.8.0 (/usr/local/lib/pyenv/versions/2.7.13/lib/python2.7/site-packages), pip 9.0.1 (/usr/local/lib/pyenv/versions/2.7.13/lib/python2.7/site-packages), openpyxl 2.4.9 (/usr/local/lib/pyenv/versions/2.7.13/lib/python2.7/site-packages), jdcal 1.3 (/usr/local/lib/pyenv/versions/2.7.13/lib/python2.7/site-packages), et-xmlfile 1.0.1 (/usr/local/lib/pyenv/versions/2.7.13/lib/python2.7/site-packages) ]
Si ottiene l'elenco delle librerie contenute in $PYTHONPATH/../lib/python2.7/site-packages/.
ATTENZIONE: L'elenco sopra riportato dovrebbe essere lo stesso riportato da list o freeze
pip list et-xmlfile (1.0.1) jdcal (1.3) openpyxl (2.6.2, /usr/local/download/openpyxl/openpyxl-2.6.2) Pillow (5.4.1, /usr/local/download/python-pil/Pillow-5.4.1/src) pip (9.0.1) setuptools (28.8.0)
pip freeze et-xmlfile==1.0.1 jdcal==1.3 openpyxl==2.6.2 Pillow==5.4.1
Se i due elenchi differiscono potrebbe dipendere dal fatto che il pyenv non ha impostato correttamente le variabili d'ambiente (vedi sopra il problema della rilocazione dei file dopo l'installazione).
È possibile installare una versione aggiornata di una libreria tramite pip, disinstallando eventualmente il pacchetto Debian che contiene la vecchia versione. Ad esempio:
dpkg --purge python-openpyxl pip install openpyxl