26.7. 2to3 — Traduction automatique de code en Python 2 vers Python 3

2to3 est un programme Python qui lit du code source en Python 2.x et applique une suite de correcteurs pour le transformer en code Python 3.x valide. La bibliothèque standard contient un ensemble riche de correcteurs qui gèreront quasiment tout le code. La bibliothèque lib2to3 utilisée par 2to3 est cependant une bibliothèque flexible et générique, il est donc possible d’écrire vos propres correcteurs pour 2to3. lib2to3 pourrait aussi être adaptée à des applications personnalisées dans lesquelles le code Python doit être édité automatiquement.

26.7.1. Utilisation de 2to3

2to3 sera généralement installé avec l’interpréteur Python en tant que script. Il est également situé dans le dossier Tools/scripts à racine de Python.

Les arguments de base de 2to3 sont une liste de fichiers et de répertoires à transformer. Les répertoires sont parcourus récursivement pour trouver les sources Python.

Voici un exemple de fichier source Python 2.x, example.py :

def greet(name):
    print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)

Il peut être converti en code Python 3.x par 2to3 en ligne de commande :

$ 2to3 example.py

A diff against the original source file is printed. 2to3 can also write the needed modifications right back to the source file. (A backup of the original file is made unless -n is also given.) Writing the changes back is enabled with the -w flag:

$ 2to3 -w example.py

Après transformation, example.py ressemble à :

def greet(name):
    print("Hello, {0}!".format(name))
print("What's your name?")
name = input()
greet(name)

Les commentaires et les retraits sont préservés tout au long du processus de traduction.

By default, 2to3 runs a set of predefined fixers. The -l flag lists all available fixers. An explicit set of fixers to run can be given with -f. Likewise the -x explicitly disables a fixer. The following example runs only the imports and has_key fixers:

$ 2to3 -f imports -f has_key example.py

Cette commande exécute tous les correcteurs, sauf le correcteurs apply :

$ 2to3 -x apply example.py

Certains correcteurs sont explicites, ce qui signifie qu’ils ne sont pas exécutés par défaut et doivent être énumérés sur la ligne de commande à exécuter. Ici, en plus des correcteurs par défaut, le correcteur idioms est exécuté :

$ 2to3 -f all -f idioms example.py

Notez que passer all active tous les correcteurs par défaut.

Parfois, 2to3 trouvera un endroit dans votre code source qui doit être changé, mais qu’il ne peut pas résoudre automatiquement. Dans ce cas, 2to3 affiche un avertissement sous la comparaison d’un fichier. Vous devez traiter l’avertissement afin d’avoir un code conforme à Python 3.x.

2to3 peut également réusiner les doctests. Pour activer ce mode, utilisez -d. Notez que seul les doctests seront réusinés. Cela ne nécessite pas que le module soit du Python valide. Par exemple, des doctests tels que des exemples dans un document reST peuvent également être réusinés avec cette option.

L’option -v augmente la quantité de messages générés par le processus de traduction.

Since some print statements can be parsed as function calls or statements, 2to3 cannot always read files containing the print function. When 2to3 detects the presence of the from __future__ import print_function compiler directive, it modifies its internal grammar to interpret print() as a function. This change can also be enabled manually with the -p flag. Use -p to run fixers on code that already has had its print statements converted.

The -o or --output-dir option allows specification of an alternate directory for processed output files to be written to. The -n flag is required when using this as backup files do not make sense when not overwriting the input files.

Nouveau dans la version 3.2.3: The -o option was added.

The -W or --write-unchanged-files flag tells 2to3 to always write output files even if no changes were required to the file. This is most useful with -o so that an entire Python source tree is copied with translation from one directory to another. This option implies the -w flag as it would not make sense otherwise.

Nouveau dans la version 3.2.3: L’option -W a été ajoutée.

The --add-suffix option specifies a string to append to all output filenames. The -n flag is required when specifying this as backups are not necessary when writing to different filenames. Example:

$ 2to3 -n -W --add-suffix=3 example.py

Écrit un fichier converti nommé example.py3.

Nouveau dans la version 3.2.3: The --add-suffix option was added.

Pour traduire un projet entier d’une arborescence de répertoires à une autre, utilisez :

$ 2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode

26.7.2. Correcteurs

Chaque étape de la transformation du code est encapsulée dans un correcteur. La commande 2to3 -l les énumère. Comme documenté ci-dessus, chacun peut être activé ou désactivé individuellement. Ils sont décrits plus en détails ici.

apply

Supprime l’usage d”apply(). Par exemple, apply(function, *args, **kwargs) est converti en function(*args, **kwargs).

asserts

Remplace les noms de méthodes obsolètes du module unittest par les bons.

De À
failUnlessEqual(a, b) assertEqual(a, b)
assertEquals(a, b) assertEqual(a, b)
failIfEqual(a, b) assertNotEqual(a, b)
assertNotEquals(a, b) assertNotEqual(a, b)
failUnless(a) assertTrue(a)
assert_(a) assertTrue(a)
failIf(a) assertFalse(a)
failUnlessRaises(exc, cal) assertRaises(exc, cal)
failUnlessAlmostEqual(a, b) assertAlmostEqual(a, b)
assertAlmostEquals(a, b) assertAlmostEqual(a, b)
failIfAlmostEqual(a, b) assertNotAlmostEqual(a, b)
assertNotAlmostEquals(a, b) assertNotAlmostEqual(a, b)
basestring

Convertit une basestring en str.

buffer

Convertit un buffer en memoryview. Ce correcteur est optionnel car l’API memoryview est similaire mais pas exactement pareil que celle de buffer.

dict

Fixe les méthodes d’itération sur les dictionnaires. dict.iteritems() est converti en dict.items(), dict.iterkeys() en dict.keys() et dict.itervalues() en dict.values(). Similarly, dict.viewitems(), dict.viewkeys() et dict.viewvalues() sont convertis respectivement en dict.items(), dict.keys() et dict.values(). Il encapsule également les usages existants de dict.items(), dict.keys() et dict.values() dans un appel à list.

except

Convertit except X, T en except X as T.

exec

Convertit l’instruction exec en fonction exec().

execfile

Supprime l’usage de execfile(). L’argument de execfile() est encapsulé dans des appels à open(), compile() et exec().

exitfunc

Change l’affectation de sys.exitfunc pour utiliser le module atexit.

filter

Encapsule l’usage de filter() dans un appel à list.

funcattrs

Fixe les attributs de fonction ayant été renommés. Par exemple, my_function.func_closure est converti en my_function.__closure__.

future

Supprime les instructions from __future__ import new_feature.

getcwdu

Renomme os.getcwdu() en os.getcwd().

has_key

Change dict.has_key(key) en key in dict.

idioms

Ce correcteur optionnel effectue plusieurs transformations rendant le code Python plus idiomatique. Les comparaisons de types telles que type(x) is SomeClass et type(x) == SomeClass sont converties en isinstance(x, SomeClass). while 1 devient while True. Ce correcteur essaye aussi d’utiliser sorted() aux endroits appropriés. Par exemple, ce bloc

L = list(some_iterable)
L.sort()

est transformé en :

L = sorted(some_iterable)
import

Détecte les imports voisins et les convertis en imports relatifs.

imports

Gère les renommages de modules dans la bibliothèque standard.

imports2

Gères d’autres renommages de modules dans la bibliothèque standard. Il est distinct de imports seulement en raison de limitations techniques.

input

Convertit input(prompt) en eval(input(prompt)).

intern

Convertit intern() en sys.intern().

isinstance

Fixes duplicate types in the second argument of isinstance(). For example, isinstance(x, (int, int)) is converted to isinstance(x, (int)).

itertools_imports

Supprime les imports de itertools.ifilter(), itertools.izip() et itertools.imap(). Les imports de itertools.ifilterfalse() sont aussi changés en itertools.filterfalse().

itertools

Change l’usage de itertools.ifilter(), itertools.izip() et itertools.imap() en leurs équivalents intégrés. itertools.ifilterfalse() est changé en itertools.filterfalse().

long

Renomme long en int.

map

Encapsule map() dans un appel à list. Change aussi map(None, x) en list(x). L’usage de from future_builtins import map désactive ce correcteur.

metaclass

Convertit l’ancienne syntaxe de métaclasse (__metaclass__ = Meta dans le corps de la classe) à la nouvelle (class X(metaclasse=Meta)).

methodattrs

Fixe les anciens noms d’attributs de méthodes. Par exemple, meth.im_func est converti en meth.__func__.

ne

Convertit l’ancienne syntaxe d’inégalité, <>, en !=.

next

Convertit l’usage des méthodes next() de l” itérateur en next(). Renomme également les méthodes next() en __next__().

nonzero

Renomme __nonzero__() en __bool__().

numliterals

Convertit les nombres écrits littéralement en octal dans leur nouvelle syntaxe.

operator

Converts calls to various functions in the operator module to other, but equivalent, function calls. When needed, the appropriate import statements are added, e.g. import collections. The following mapping are made:

De À
operator.isCallable(obj) hasattr(obj, '__call__')
operator.sequenceIncludes(obj) operator.contains(obj)
operator.isSequenceType(obj) isinstance(obj, collections.Sequence)
operator.isMappingType(obj) isinstance(obj, collections.Mapping)
operator.isNumberType(obj) isinstance(obj, numbers.Number)
operator.repeat(obj, n) operator.mul(obj, n)
operator.irepeat(obj, n) operator.imul(obj, n)
paren

Ajoute des parenthèses supplémentaires lorsqu’elles sont nécessaires dans les listes en compréhension. Par exemple, [x for x in 1, 2] devient [x for x in (1, 2)].

print

Convertit l’instruction print en fonction print().

raise

Convertit raise E, V en raise E(V) et raise E, V, T en raise E(V).with_traceback(T). Si E est un tuple, la conversion sera incorrecte puisque la substitution de tuples aux exceptions a été supprimée en 3.0.

raw_input

Convertit raw_input() en input().

reduce

Gère le déplacement de reduce() à functools.reduce().

reload

Convertit les appels à reload() en appels à imp.reload().

renames

Change sys.maxint en sys.maxsize.

repr

Remplace les accents graves utilisés comme repr par des appels à repr().

set_literal

Remplace l’usage du constructeur de set par les ensembles littéraux. Ce correcteur est optionnel.

standarderror

Renomme StandardError en Exception.

sys_exc

Change les sys.exc_value, sys.exc_type, sys.exc_traceback dépréciés en sys.exc_info().

throw

Fixe le changement de l’API dans la méthode throw() du générateur.

tuple_params

Supprime la décompression implicite des paramètres d’un tuple. Ce correcteur ajoute des variables temporaires.

types

Fixe le code cassé par la suppression de certains membres du module types.

unicode

Renomme unicode en str.

urllib

Gère le renommage des paquets urllib et urllib2 en urllib.

ws_comma

Supprime l’espace excédentaire des éléments séparés par des virgules. Ce correcteur est optionnel.

xrange

Renomme la fonction xrange() en range() et encapsule les appels à la fonction range() avec des appels à list.

xreadlines

Change for x in file.xreadlines() en for x in file.

zip

Encapsule l’usage de zip() dans un appel à list. Ceci est désactivé lorsque from future_builtins import zip apparaît.

26.7.3. lib2to3 — la bibliothèque de 2to3

Code source: Lib/lib2to3/


Note

L’API de lib2to3 devrait être considérée instable et peut changer drastiquement dans le futur.