# 2to3 --- Automated Python 2 to 3 code translation

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.

Obsolète depuis la version 3.11, sera supprimé dans la version 3.13: The `lib2to3` module was marked pending for deprecation in Python 3.9 (raising `PendingDeprecationWarning` on import) and fully deprecated in Python 3.11 (raising `DeprecationWarning`). The `2to3` tool is part of that. It will be removed in Python 3.13.

## 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

Une comparaison avec le fichier source original est affichée. 2to3 peut aussi écrire les modifications nécessaires directement dans le fichier source. (Une sauvegarde du fichier d'origine est effectuée à moins que l'option `-n` soit également donnée.) L'écriture des modifications est activée avec l'option `-w` :

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

Par défaut, 2to3 exécute un ensemble de correcteurs prédéfinis. L'option `-l` énumère tous les correcteurs disponibles. Un ensemble explicite de correcteurs à exécuter peut être donné avec `-f`. De même, `-x` désactive explicitement un correcteur. L'exemple suivant exécute uniquement les `import` et les correcteurs `has_key` :

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

Puisque l'instruction `print` peut être analysée soit comme un appel de fonction soit comme une instruction, 2to3 ne peut pas toujours lire les fichiers contenant la fonction print. Lorsque 2to3 détecte la présence de la directive compilateur `from __future__ import print_function`, il modifie sa grammaire interne pour interpréter `print()` comme une fonction. Cette modification peut également être activée manuellement avec l'option `-p`. Utilisez `-p` pour exécuter des correcteurs sur du code dont les instructions d'affichage ont déjà été converties. Notez également l'usage de l'option `-e` pour transformer `exec()` en fonction.

L'option `-o` ou `--output-dir` permet de donner autre répertoire pour les fichiers de sortie en écriture. L'option `-n` est requise quand on les utilise comme fichiers de sauvegarde qui n'ont pas de sens si les fichiers d'entrée ne sont pas écrasés.

Nouveau dans la version 3.2.3: L'option `-o` a été ajoutée.

L'option `-W` ou `—write-unchanged-files` indique à 2to3 de toujours écrire des fichiers de sortie même si aucun changement du fichier n'était nécessaire. Ceci est très utile avec `-o` pour qu'un arbre des sources Python entier soit copié avec la traduction d'un répertoire à l'autre. Cette option implique `-w` sans quoi elle n'aurait pas de sens.

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

L'option `--add-suffix` spécifie une chaîne à ajouter à tous les noms de fichiers de sortie. L'option `-n` est nécessaire dans ce cas, puisque sauvegarder n'est pas nécessaire en écrivant dans des fichiers différents. Exemple :

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

Écrit un fichier converti nommé `example.py3`.

Nouveau dans la version 3.2.3: L'option `--add-suffix` est ajoutée.

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

## 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()`. De la même façon, `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 importations voisines et les convertit en importations relatives.

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

  Fixe les types dupliqués dans le second argument de `isinstance()`. Par exemple, `isinstance(x, (int, int))` est converti en `isinstance(x, int)` et `isinstance(x, (int, float, int))` est converti en `isinstance(x, (int, float))`.

itertools_imports

  Supprime les importations de `itertools.ifilter()`, `itertools.izip()` et `itertools.imap()`. Les importations de `itertools.ifilterfalse()` sont aussi changées 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

  Renames definitions of methods called `__nonzero__()` to `__bool__()`.

numliterals

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

operator

  Convertit les appels à diverses fonctions du module `operator` en appels d'autres fonctions équivalentes. Si besoin, les instructions `import` appropriées sont ajoutées, e.g. `import collections.abc`. Les correspondances suivantes sont appliquées :

  De | À
  --- | ---
  `operator.isCallable(obj)` | `callable(obj)`
  `operator.sequenceIncludes(obj)` | `operator.contains(obj)`
  `operator.isSequenceType(obj)` | `isinstance(obj, collections.abc.Sequence)`
  `operator.isMappingType(obj)` | `isinstance(obj, collections.abc.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 n-uplet, la conversion sera incorrecte puisque la substitution de n-uplets 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 à `importlib.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 n-uplet. 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.

## `lib2to3` --- 2to3's library

Code source: Lib/lib2to3/

Obsolète depuis la version 3.11, sera supprimé dans la version 3.13: Python 3.9 switched to a PEG parser (see PEP 617) while lib2to3 is using a less flexible LL(1) parser. Python 3.10 includes new language syntax that is not parsable by lib2to3's LL(1) parser (see PEP 634). The `lib2to3` module was marked pending for deprecation in Python 3.9 (raising `PendingDeprecationWarning` on import) and fully deprecated in Python 3.11 (raising `DeprecationWarning`). It will be removed from the standard library in Python 3.13. Consider third-party alternatives such as LibCST or parso.

Note

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