Python2, Python3: Comment faire ?
Changements importants
Syntaxiques
Certains mots-clés sont devenus des fonctions. C'est le cas de print, qui est devenue une fonction, et c'est tant mieux.
la syntaxe d'utilisation des try/except a aussi changé dans les cas ou on souhaite capturer plusieurs exception. la bonne manière de faire, indépendamment de la version est:
import random import logging logging.basicConfig() # Initialise logging with default config try: if random.random() > 0.5: raise ValueError('I am a cute as hell. I am the ValueError. ') else: raise IOError('Fear me.') except (ValueError, IOError) as e: logging.exception(e)
Changements dans la stdlib
Il y a eu plusieurs changements dans la stdlib, dont des changement de noms. Ainsi, le module SocketServer de python2 a été renommé en socketserver, dans un souci d'harmonisation des noms (On est en droit de se demander pourquoi ça n'avait pas été mis en place dès le départ).
Pour pallier à ces problèmes, nous n'avons pas le choix: essayer d'importer, puis intercepter l'ImportError qui en découlera si la version n'est pas bonne.
try: from socketserver import TCPServer except ImportError: from SocketServer import TCPServer
Et ça, c'est assez sale. Il n'y a pas d'autres moyens à ma connaissance de le faire sans utiliser de librairies supplémentaires permettant d'uniformiser les imports.
Compatibilité
Il y a plusieurs manières d'assurer la compatibilité.
__future__
__future__ est un module de la stdlib permettant d'utiliser certaines syntaxes et modes de fonctionnement de version futures. Il suffit d'ajouter en début de chaque fichier .py une ligne de la forme from __future__ import devision, unicode_literals, print_function. C'est la plupart du temps suffisant si on code proprement. Ainsi, le code suivant marchera en python2 et en python3, malgrès l'usage de printen tant que fonction:
"Simple module docstring" from __future__ import print_function print("Hello, world, but without newline", end='')
Fun Fact: la PEP-236 introduisant ce mécanisme se nomme "back to the __future__".
2to3
2to3 est l'outil fourni par CPython (la distribution python standard). Comme son nom l'indique, il permet de convertir statiquement du code python2 vers du code python3. Pour cela, il dispose d'un bibliothèque de motifs correspondant à du python2 , et de la façon dont ils sont exprimables en python3. Je vous invite à consulter la page de documentation pour avoir la liste des fixers disponible.
six
six est très complexe à bien maîtriser. Il s'agit d'une couche de compatibilité, installable via pip, qui permet au runtime de s'occuper de tout un tas de choses, comme de s'arranger pour importer les bons import, ou encore de s'abstraire des concepts poussés de python3.
modernize
modernize est un package disponible via pip se proposant de fusionner les fonctionnalités de 2to3 et de six. Il va à la fois corriger les erreurs statiques et ajouter la couche de compatibilité runtime de six, là ou nécessaire. C'est LA solution à utiliser pour convertir rapidement quelques fichiers, mais à n'utiliser en aucun cas pour de grandes bibliothèques.