Table of Contents

Backport di Python 2.7

Su Debian 6 Squeeze

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

Installazione in $HOME utente

:!: 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

Installazione in /usr/local/lib/

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

Utilizzo di pyenv

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.

Ricollocazione dell'installazione di pyenv

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:

Problema con pip e ssl

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/

Su Fedora 12

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.

Archivi da installare

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.

Installazione con pip

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).

Aggiornamento libreria con pip

È 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