2to3 - Traducción de código Python 2 a 3

2to3 es un programa hecho en Python que lee código fuente en Python 2.x y aplica una serie de fixers para transformarlo en código Python 3.x válido. La librería estándar contiene un buen conjunto de fixers que se encargarán de casi todo el código. La librería soporte de 2to3 lib2to3 es, de todas maneras, una librería flexible y genérica. Por lo cual es posible escribir sus propios fixers para 2to3. lib2to3 también puede adaptarse a aplicaciones propias en las cuales el código en Python necesite editarse automáticamente.

Usando 2to3

2to3 generalmente estará instalada con el interprete de Python como un script. También se encuentra ubicada en el directorio Tools/scripts en la raíz de Python.

Los argumentos básicos de 2to3 son una lista de archivos o directorios a convertir. Los directorios se recorren recursivamente en búsqueda de archivos en Python.

Este es un ejemplo de un archivo en Python 2.x, :file: example.py:

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

Puede ser convertido a Python 3.x vía 2to3 desde la línea de comandos:

$ 2to3 example.py

Se imprime un diff del archivo fuente original. 2to3 también puede escribir las modificaciones necesarias directamente en el archivo fuente. (Se hace una copia de respaldo del archivo original a menos que se proporcione -n.) La escritura de los cambios se habilita con la opción -w:

$ 2to3 -w example.py

Después de la conversión, example.py se ve de la siguiente manera:

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

Los comentarios y la identación exacta se conservan durante todo el proceso de conversión.

Por defecto, 2to3 corre un conjunto de fixers predefinidos. La opción -l lista todos los fixers posibles. Se puede pasar un conjunto explícito de fixers con la opción -x. Asimismo la opción -x deshabilita el fixer que se explicita. El siguiente ejemplo corre solo solo los fixers imports y has_key:

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

Este comando corre todos los fixers excepto el apply fixer:

$ 2to3 -x apply example.py

Algunos fixers son explícitos, esto quiere decir que no corren por defecto y deben ser listados en la línea de comando para que se ejecuten. Acá, además de los fixers por defectos, se ejecuta el fixer idioms:

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

Puede observarse que pasar all habilita todos los fixers por defecto.

Algunas veces 2to3 va a encontrar algo en su código que necesita ser modificado, pero 2to3 no puede hacerlo automáticamente. En estos casos, 2to3 va a imprimir una advertencia debajo del diff del archivo. Deberá tomar nota de la advertencia para obtener un código compatible con 3.x.

2to3 también puede refactorizar doctest. Para habilitar este modo, use la opción -d. Tenga en cuenta que solo los doctest serán refactorizados. Esto tampoco requiere que el módulo sea válido en Python. Por ejemplo, doctest de ejemplo en un documento reST también pueden ser refactorizados con esta opción.

La opción -v habilita la salida de más información en el proceso de conversión.

Como algunas declaraciones print pueden ser pasadas como llamadas a funciones o declaraciones, 2to3 no siempre lee archivos que contienen la función print. Cuando 2to3 detecta la presencia de la directiva de compilación from __future__ import print_function, modifica su gramática interna para interpretar print() como una función. Este cambio también puede habilitarse manualmente con la opción -p. Use la opción -p para ejecutar los fixers en el código al que ya se le han convertido sus declaraciones print.

La opción -o o la opción --output-dir permiten designar un directorio alternativo para que se guarden los archivos procesados. La opción -n es necesaria ya que los archivos de respaldo no tienen sentido cuando no se sobreescriben los archivos originales.

Nuevo en la versión 3.2.3: Se agregó la opción :option:` !-o`.

La opción -W o --write-unchanged-files le dice a 2to3 que siempre escriba archivos de salida, incluso si no se requieren hacer cambios en el archivo. Esto es muy útil con la opción -o para que copie el árbol completo de código Python con su conversión de un directorio a otro. Esta opción incluye a la opción -w ya que no tendría sentido de otra manera.

Nuevo en la versión 3.2.3: Se agregó la opción -W.

La opción --add-suffix agrega un texto al final de todos los nombres de archivo. La opción -n es necesaria, ya que las copias de respaldo no son necesarias cuando escribimos a un archivo con distinto nombre. Ejemplo:

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

Hará que se escriba una archivo convertido con el nombre example.py3.

Nuevo en la versión 3.2.3: Se agrega la opción --add-suffix.

Para convertir un proyecto entero de un árbol de directorios a otro use:

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

Fixers

Cada paso de la transformación del código es encapsulado en un fixer. El comando 2to3 -l los lista. Como se explicó arriba, cada uno de estos puede habilitarse o deshabilitarse individualmente. En esta sección se los describe más detalladamente.

apply

Elimina el uso de apply(). Por ejemplo apply(function, *args, **kwargs) es convertido a function(*args, **kwargs).

asserts

Reemplaza los nombre de método unittest en desuso por los correctos.

De

A

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

Convierte basestring a str.

buffer

Convierte buffer a memoryview. Este fixer es opcional porque la API memoryview es similar pero no exactamente la misma que la del buffer.

dict

Corrige los métodos de iteración del diccionario, dict.iteritems() es convertido a dict.items(), dict.iterkeys() a dict.keys(), y dict.itervalues() a dict.values(). Del mismo modo, dict.viewitems(), dict.viewkeys() y dict.viewvalues() son convertidos respectivamente a dict.items(), dict.keys() y dict.values(). También incluye los usos existentes de dict.items(), dict.keys(), y dict.values() en una llamada a list.

except

Convierte except X, T a except X as T.

exec

Convierte la declaración exec a la función exec().

execfile

Elimina el uso de la función execfile(). El argumento para execfile() es encapsulado para las funciones open(), compile(), y exec().

exitfunc

Cambia la declaración de sys.exitfunc para usar el módulo atexit.

filter

Encapsula la función filter() usando una llamada para la clase list.

funcattrs

Corrige los atributos de la función que fueron renombrados. Por ejemplo, my_function.func_closure es convertido a my_function.__closure__.

future

Elimina la declaración from __future__ import new_feature.

getcwdu

Renombra la función os.getcwdu() a os.getcwd().

has_key

Cambia dict.has_key(key) a key in dict.

idioms

Este fixer opcional ejecuta varias transformaciones que tornan el código Python más idiomático. Comparaciones de tipo como type(x) is SomeClass y type(x) == SomeClass son convertidas a isinstance(x, SomeClass).``while 1`` cambia a while True. Este fixer también intenta hacer uso de sorted() en los lugares apropiados. Por ejemplo, en este bloque:

L = list(some_iterable)
L.sort()

es convertido a

L = sorted(some_iterable)
import

Detecta las importaciones entre hermanos y las convierte en importaciones relativas.

imports

Maneja los cambios de nombre de módulo en la librería estándar.

imports2

Maneja otros cambios de nombre de módulo en la biblioteca estándar. Está separada del fixer imports solo por motivos de limitaciones técnicas.

input

Convierte input(prompt) a eval(input(prompt)).

intern

Convierte intern() a sys.intern().

isinstance

Corrige tipos duplicados en el segundo argumento de isinstance(). Por ejemplo,``isinstance(x, (int, int))`` es convertido a isinstance(x, int) y isinstance(x, (int, float, int)) es convertido a isinstance(x, (int, float)).

itertools_imports

Elimina importaciones de itertools.ifilter(), itertools.izip(), y itertools.imap(). Importación de itertools.ifilterfalse() también se cambian a itertools.filterfalse().

itertools

Cambia el uso de itertools.ifilter(), itertools.izip(), y itertools.imap() para sus equivalentes integrados itertools.ifilterfalse() es cambiado a itertools.filterfalse().

long

Renombra long a int.

map

Encapsula map() en una llamada a list. También cambia map(None, x) a list(x). Usando``from future_builtins import map`` se deshabilita este fixer.

metaclass

Convierte la vieja sintaxis de metaclase (__metaclass__ = Meta en el cuerpo de la clase) a la nueva sintaxis (class X(metaclass=Meta)).

methodattrs

Corrige nombres de atributos de métodos antiguos. Por ejemplo, meth.im_func is convertido a meth.__func__.

ne

Convierte la antigua sintaxis no-igual, <>, a !=.

next

Convierte el uso de métodos iteradores next() para la función next(). También renombra métodos next() a __next__().

nonzero

Renombra el método __nonzero__() a __bool__().

numliterals

Convierte literales octales a la nueva sintaxis.

operator

Convierte llamadas para varias funciones en el módulo operator a otras, pero equivalentes, llamadas de funciones. Cuando es necesario, se agregan las declaraciones import apropiadas, por ejemplo import collections.abc. Se realizan los siguientes mapeos:

De

A

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

Agrega los paréntesis extra donde sean necesarios en las listas de comprensión. Por ejemplo [x for x in 1, 2] se convierte en [x for x in (1, 2)].

print

Convierte la declaración print en la función print().

raise

Convierte raise E, V a raise E(V), y raise E, V, T a raise E(V).with_traceback(T). SI E es una tupla, la conversión será incorrecta porque sustituir tuplas por excepciones fue eliminado en Python 3.0.

raw_input

Conviertes raw_input() to input().

reduce

Maneja el movimiento de reduce() a functools.reduce().

reload

Convierte reload() a importlib.reload().

renames

Cambia sys.maxint a sys.maxsize.

repr

Sustituye el backtick repr por la función repr().

set_literal

Sustituye el uso de la clase constructora set por su literal. Este fixer es opcional.

standarderror

Renombra StandardError a Exception.

sys_exc

Cambia los sys.exc_value, sys.exc_type, sys.exc_traceback en desuso para usar la función sys.exc_info().

throw

Corrige el cambio de la API en el método generador throw().

tuple_params

Elimina el desempaquetamiento implícito del parámetro de tupla. Este fixer inserta variables temporarias.

types

Corrige el código roto por la remoción de algunos miembros en el módulo types.

unicode

Renombra unicode a str.

urllib

Maneja el renombramiento de los módulos urllib y urllib2 para el paquete urllib.

ws_comma

Remueve el exceso de espacios blancos de los ítems separados por coma. Este fixer es opcional.

xrange

Renombra xrange() a range() y encapsula la llamada a la función existente range() con list.

xreadlines

Cambia for x in file.xreadlines() por for x in file.

zip

Encapsula el uso de la función zip() en una llamada a la clase list. Esto está deshabilitado cuando from future_builtins import zip aparece.

lib2to3 - librería 2to3

Código fuente: Lib/lib2to3/


Nota

La API del módulo lib2to3 debe considerarse inestable y puede cambiar drásticamente en el futuro.