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

2to3 es un programa de Python que lee el código fuente de Python 2.x y
aplica una serie de *fixers* para transformarlo en un código válido de
Python 3.x. La biblioteca estándar contiene un amplio conjunto de
arreglos que manejarán casi todo el código. Biblioteca de soporte 2to3
"lib2to3" es, sin embargo, una biblioteca flexible y genérica, por lo
que es posible escribir sus propios arreglos para 2to3.


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, "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.

Dado que algunas declaraciones de impresión se pueden analizar como
llamadas a funciones o declaraciones, 2to3 no siempre puede leer
archivos que contienen la función de impresión. Cuando 2to3 detecta la
presencia de la directiva del compilador "from __future__ import
print_function", modifica su gramática interna para interpretar
"print()" como una función. Este cambio también se puede habilitar
manualmente con la opción "-p". Utilice "-p" para ejecutar correctores
en el código que ya tiene sus declaraciones de impresión convertidas.
También "-e" puede usarse para hacer "exec()" una función.

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

   Renames definitions of methods called "__nonzero__()" to
   "__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/

======================================================================

Obsoleto desde la versión 3.10: Python 3.9 cambiará a un analizador
PEG (ver **PEP 617**), y Python 3.10 puede incluir una nueva sintaxis
de lenguaje que no es analizable por el analizador LL(1) de lib2to3.
El módulo "lib2to3" puede eliminarse de la biblioteca estándar en una
versión futura de Python. Considere alternativas de terceros como
LibCST o parso.

Nota:

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