Qué hay de nuevo en Python 3.2
******************************

Autor:
   Raymond Hettinger

Este artículo explica las nuevas características de Python 3.2 en
comparación con 3.1. Python 3.2 se lanzó el 20 de febrero de 2011. Se
centra en algunos aspectos destacados y ofrece algunos ejemplos. Para
obtener detalles completos, consulte el archivo Misc/NEWS.

Ver también: **PEP 392** - Calendario de Publicación Python 3.2


PEP 384: Definición de un ABI estable
=====================================

En el pasado, los módulos de extensión creados para una versión de
Python a menudo no se podían usar con otras versiones de Python.
Particularmente en Windows, cada lanzamiento de funciones de Python
requería reconstruir todos los módulos de extensión que uno quería
usar. Este requisito fue el resultado del acceso gratuito a los
componentes internos del intérprete de Python que los módulos de
extensión podían usar.

Con Python 3.2, está disponible un enfoque alternativo: los módulos de
extensión que se restringen a una API limitada (al definir
Py_LIMITED_API) no pueden usar muchas de las funciones internas, pero
están restringidos a un conjunto de funciones API que se promete serán
estables para varias versiones. Como consecuencia, los módulos de
extensión creados para 3.2 en ese modo también funcionarán con 3.3,
3.4, etc. Los módulos de extensión que hacen uso de los detalles de
las estructuras de memoria aún se pueden construir, pero deberán
recompilarse para cada lanzamiento de funciones.

Ver también:

  **PEP 384** - Definición de un ABI estable
     PEP escrito por Martin von Löwis.


PEP 389: Módulo de análisis sintáctico (*Parser*) de línea de comandos Argparse
===============================================================================

Se introdujo un nuevo módulo para el análisis de la línea de comandos,
"argparse", para superar las limitaciones de "optparse" que no
brindaba soporte para argumentos posicionales (no solo opciones),
subcomandos, opciones requeridas y otros patrones comunes para
especificar y validar opciones.

Este módulo ya ha tenido un éxito generalizado en la comunidad como
módulo de terceros. Con más funciones que su predecesor, el módulo
"argparse" es ahora el módulo preferido para el procesamiento de la
línea de comandos. El módulo más antiguo todavía se mantiene
disponible debido a la gran cantidad de código heredado que depende de
él.

Aquí hay un analizador de ejemplo comentado que muestra
características de cómo limitar los resultados a un conjunto de
opciones, especificar un *metavar* en la pantalla de ayuda, validar
que uno o más argumentos posicionales están presentes y hacer una
opción requerida:­:

   import argparse
   parser = argparse.ArgumentParser(
   description = 'Administrar servidores', # descripción principal de la ayuda
   epilog = 'Probado en Solaris y Linux') # mostrado después de la ayuda
   parser.add_argument('action', # nombre del argumento
   choices = ['deploy', 'start', 'stop'], # tres valores permitidos
   help = 'action on each target') # mensaje de ayuda
   parser.add_argument('targets',
   metavar = 'HOSTNAME', # nombre de la variable usada en el mensaje de ayuda
   nargs = '+', # requiere uno o más objetivos
   help = 'url para las máquinas de destino') # explicación del mensaje de ayuda
   parser.add_argument('-u', '--user', # opción -u o --user
   required = True, # haz que sea un argumento obligatorio
   help = 'iniciar sesión como usuario')

Ejemplo de llamada al analizador en una cadena de caracteres de
comandos:

   >>> cmd = 'implementar estornudos.ejemplo.com sueño.ejemplo.com -u skycaptain'
   >>> resultado = parser.parse_args(cmd.split())
   >>> resultado.acción
   'implementar'
   >>> resultado.objetivos
   ['estornudos.ejemplo.com', 'sueño.ejemplo.com']
   >>> resultado.usuario
   'skycaptain'

Ejemplo de ayuda generada automáticamente por el analizador:

   >>> parser.parse_args('-h'.split())

   uso: manage_cloud.py [-h] -u USER
   {deploy,start,stop} HOSTNAME [HOSTNAME ...]

   Administrar servidores

   argumentos posicionales:
   {deploy,start,stop} acción en cada destino
   HOSTNAME url para las máquinas de destino

   argumentos opcionales:
   -h, --help mostrar este mensaje de ayuda y salir
   -u USER, --user USER iniciar sesión como usuario

   Probado en Solaris y Linux

Una característica especialmente agradable de "argparse" es la
capacidad de definir sub-analizadores (*subparsers*), cada uno con sus
propios patrones de argumentos y pantallas de ayuda:

   import argparse
   parser = argparse.ArgumentParser(prog='HELM')
   subparsers = parser.add_subparsers()

   parser_l = subparsers.add_parser('launch', help='Launch Control') # primer subgrupo
   parser_l.add_argument('-m', '--missiles', action='store_true')
   parser_l.add_argument('-t', '--torpedos', action='store_true')

   parser_m = subparsers.add_parser('move', help='Move Vessel', # segundo subgrupo
   aliases=('steer', 'turn')) # nombres equivalentes
   parser_m.add_argument('-c', '--course', type=int, requerido=Verdadero)
   parser_m.add_argument('-s', '--speed', tipo=int, valor predeterminado=0)

   $ ./helm.py --help # ayuda de nivel superior (lanzamiento y movimiento)
   $ ./helm.py launch --help # ayuda para las opciones de lanzamiento
   $ ./helm.py launch --missiles # establece misiles=True y torpedos=False
   $ ./helm.py steer --course 180 --speed 5 # establece parámetros de movimiento

Ver también:

  **PEP 389** - Nuevo módulo de análisis de línea de comandos
     PEP escrito por Steven Bethard.

  Migrating optparse code to argparse para obtener detalles sobre las
  diferencias con "optparse".


PEP 391: Configuración basada en diccionario para Logging
=========================================================

El módulo "logging" proporcionaba dos tipos de configuración: un
estilo con llamadas de función para cada opción u otro estilo
controlado por un archivo externo guardado en formato "configparser".
Esas opciones no proporcionaban la flexibilidad necesaria para crear
configuraciones a partir de archivos JSON o YAML, ni tampoco admitían
la configuración incremental, que es necesaria para especificar las
opciones del registrador desde una línea de comandos.

Para permitir un estilo más flexible, el módulo ahora ofrece
"logging.config.dictConfig()" para especificar la configuración de
logging con diccionarios simples de Python. Las opciones de
configuración incluyen formateadores, gestores, filtros y loggers.
Aquí hay un ejemplo funcional de un diccionario de configuración:

   {"versión": 1,
   "formateadores": {"breve": {"formato": "%(nombrenivel)-8s: %(nombre)-15s: %(mensaje)s"},
   "completo": {"formato": "%(tiempoasc)s %(nombre)-15s %(nombrenivel)-8s %(mensaje)s"}
   },
   "controladores": {"consola": {
   "clase": "registro.StreamHandler",
   "formateador": "breve",
   "nivel": "INFO",
   "flujo": "ext://sys.stdout"},
   "prioridad_consola": {
   "clase": "registro.StreamHandler",
   "formateador": "completo",
   "nivel": "ERROR",
   "flujo": "ext://sys.stderr"}
   },
   "raíz": {"nivel": "DEBUG", "controladores": ["consola", "prioridad_de_consola"]}}

Si ese diccionario está almacenado en un archivo llamado "conf.json",
se puede cargar y llamar con un código como este:

   >>> import json, logging.config
   >>> with open('conf.json') as f:
   ... conf = json.load(f)
   ...
   >>> logging.config.dictConfig(conf)
   >>> logging.info("Transacción completada normalmente")
   INFO : root : Transacción completada normalmente
   >>> logging.critical("Terminación anormal")
   2011-02-17 11:14:36,694 root CRITICAL Terminación anormal

Ver también:

  **PEP 391** - Configuración basada en diccionario para Logging
     PEP escrito por Vinay Sajip.


PEP 3148: El módulo "concurrent.futures"
========================================

El código para crear y administrar la concurrencia se está recopilando
en un nuevo espacio de nombres de nivel superior, *concurrent*. Su
primer miembro es un paquete *futures* que proporciona una interfaz
uniforme de alto nivel para administrar hilos y procesos.

El diseño de "concurrent.futures" se inspiró en el paquete
*java.util.concurrent*. En ese modelo, una llamada en ejecución y su
resultado están representados por un objeto "Future" que abstrae
características comunes a hilos, procesos y llamadas a procedimientos
remotos. Ese objeto admite verificaciones de estado (en ejecución o
terminadas), tiempos de espera, cancelaciones, agregar devoluciones de
llamada y acceso a resultados o excepciones.

El agregado principal del nuevo módulo es un par de clases ejecutoras
para lanzar y administrar llamadas. El objetivo de los ejecutores es
facilitar el uso de las herramientas existentes para realizar llamadas
en paralelo. Ahorran el esfuerzo necesario para configurar un grupo de
recursos, lanzar las llamadas, crear una cola de resultados, agregar
gestión de tiempo de espera y limitar la cantidad total de hilos,
procesos o llamadas a procedimientos remotos.

Idealmente, cada aplicación debería compartir un solo ejecutor en
varios componentes para que los límites de procesos e hilos se puedan
administrar de forma centralizada. Esto resuelve el desafío de diseño
que surge cuando cada componente tiene su propia estrategia
competitiva para la gestión de recursos.

Ambas clases comparten una interfaz común con tres métodos: "submit()"
para programar un invocable y retornar un objeto "Future" "map()" para
programar muchas llamadas asincrónicas a la vez, y "shutdown()" para
liberar recursos. La clase es un *context manager* y se puede usar en
una declaración "with" para asegurar que los recursos se liberen
automáticamente cuando los futuros actualmente pendientes terminan de
ejecutarse.

Un ejemplo simple de "ThreadPoolExecutor" es un lanzamiento de cuatro
hilos paralelos para copiar archivos:

   importar concurrente.futures, shutil
   con concurrente.futures.ThreadPoolExecutor(max_workers=4) como e:
   e.submit(shutil.copy, 'src1.txt', 'dest1.txt')
   e.submit(shutil.copy, 'src2.txt', 'dest2.txt')
   e.submit(shutil.copy, 'src3.txt', 'dest3.txt')
   e.submit(shutil.copy, 'src3.txt', 'dest4.txt')

Ver también:

  **PEP 3148** - Futuros -- Ejecutar Cómputos Asincrónicos
     PEP escrito por Brian Quinlan.

  Código para lecturas de URL en paralelo con grupos de hilos, un
  ejemplo que usa hilos para buscar varias páginas web en paralelo.

  Código para calcular números primos en paralelo, un ejemplo
  demostrando "ProcessPoolExecutor".


PEP 3147: Directorios del repositorio de PYC
============================================

El esquema de Python para almacenar en caché bytecode en archivos
*.pyc* no funcionó bien en entornos con múltiples intérpretes de
Python. Si un intérprete encontrara un archivo en caché creado por
otro intérprete, volvería a compilar la fuente y sobrescribiría el
archivo en caché, perdiendo así los beneficios del almacenamiento en
caché.

El problema de las "peleas de pyc" se ha vuelto más pronunciado a
medida que se ha convertido en un lugar común para las distribuciones
de Linux enviadas con múltiples versiones de Python. Estos conflictos
también surgen con alternativas de CPython como *Unladen Swallow*.

Para resolver este problema, el mecanismo de importación de Python se
ha ampliado para utilizar nombres de archivo distintos para cada
intérprete. En lugar de que Python 3.2 y Python 3.3 y *Unladen
Swallow* compitan por un archivo llamado "mymodule.pyc", ahora
buscarán "mymodule.cpython-32.pyc", "mymodule.cpython-33.pyc" y
"mymodule .unladen10.pyc". Y para evitar que todos estos nuevos
archivos abarroten los directorios de origen, los archivos *pyc* ahora
se recopilan en un directorio "__pycache__" almacenado en el
directorio del paquete.

Aparte de los nombres de archivo y directorios de destino, el nuevo
esquema tiene algunos aspectos que son visibles para el programador:

* Imported modules now have a "__cached__" attribute which stores the
  name of the actual file that was imported:

  >>> import collections
  >>> collections.__cached__
  'c:/py32/lib/__pycache__/collections.cpython-32.pyc'

* La etiqueta que es única para cada intérprete es accesible desde el
  módulo "imp":

  >>> import imp
  >>> imp.get_tag()
  'cpython-32'

* Los scripts que intentan deducir el nombre del archivo de origen a
  partir del archivo importado ahora deben ser más inteligentes. Ya no
  basta con quitar la "c" de un nombre de archivo ".pyc". En su lugar,
  utilice las nuevas funciones del módulo "imp":

  >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc')
  'c:/py32/lib/collections.py'
  >>> imp.cache_from_source('c:/py32/lib/collections.py')
  'c:/py32/lib/__pycache__/collections.cpython-32.pyc'

* Los módulos "py_compile" y "compileall" se han actualizado para
  reflejar la nueva convención de nomenclatura y el directorio de
  destino. La invocación por línea de comandos de *compileall* tiene
  nuevas opciones: "-i" para especificar una lista de archivos y
  directorios para compilar y "-b" que hace que los archivos bytecode
  se escriban en su ubicación heredada en lugar de *__pycache__*.

* El módulo "importlib.abc" se ha actualizado con el nuevo módulo
  *abstract base classes* para cargar archivos de bytecode. Los ABC
  obsoletos, "PyLoader" y "PyPycLoader", han quedado obsoletos (las
  instrucciones sobre cómo mantener la compatibilidad con Python 3.1
  se incluyen en la documentación).

Ver también:

  **PEP 3147** - Directorio del repositorio PYC
     PEP escrito por Barry Warsaw.


PEP 3149: Archivos .so con etiquetado de versión para ABI
=========================================================

El directorio del repositorio PYC permite la ubicación conjunta de
varios archivos de cache bytecode. Este PEP implementa un mecanismo
similar para los archivos de objetos compartidos dándoles un
directorio común y nombres distintos para cada versión.

El directorio común es "pyshared" y los nombres de los archivos se
diferencian identificando la implementación de Python (como CPython,
PyPy, Jython, etc.), los números de versión principal y secundaria, y
las banderas de compilación opcionales (como "d" para debug, "m" para
pymalloc, "u" para ancho-unicode). Para un paquete arbitrario "foo",
se verán estos archivos cuando se instala el paquete de distribución:

   /usr/share/pyshared/foo.cpython-32m.so
   /usr/share/pyshared/foo.cpython-33md.so

En Python mismo, las etiquetas son accesibles desde funciones en el
módulo "sysconfig":

   >>> import sysconfig
   >>> sysconfig.get_config_var('SOABI') # encuentra la etiqueta de versión
   'cpython-32mu'
   >>> sysconfig.get_config_var('EXT_SUFFIX') # encuentra la extensión completa del nombre de archivo
   '.cpython-32mu.so'

Ver también:

  **PEP 3149** - PEP 3149: Archivos .so con etiquetado de versión para
  ABI
     PEP escrito por Barry Warsaw.


PEP 3333: Interfaz de puerta de enlace del servidor web Python v1.0.1
=====================================================================

Este PEP informativo aclara cómo el protocolo WSGI debe gestionar los
problemas de bytes/texto. El desafío es que el manejo de cadenas de
caracteres en Python 3 se maneja de manera más conveniente con el tipo
"str" aunque el protocolo HTTP está orientado a bytes.

El PEP diferencia las llamadas *cadenas nativas* que se utilizan para
los encabezados y metadatos de solicitud/respuesta
(*request/response*) frente a las *cadenas de bytes* que se utilizan
para los cuerpos de las solicitudes y respuestas.

Los *native strings* son siempre del tipo "str", pero están
restringidos a puntos de código entre *U+0000* y *U+00FF* que se
pueden traducir a bytes mediante la codificación *Latin-1*. Estas
cadenas se utilizan para las claves y los valores en el diccionario de
entorno y para los encabezados de respuesta y los estados en la
función "start_response()". Deben seguir a **RFC 2616** con respecto a
la codificación. Es decir, deben ser caracteres *ISO-8859-1* o
utilizar la codificación MIME **RFC 2047**.

Para los desarrolladores que portan aplicaciones WSGI desde Python 2,
estos son los puntos destacados:

* Si la aplicación ya usó cadenas para encabezados en Python 2, no es
  necesario ningún cambio.

* Si, en cambio, la aplicación codificó encabezados de salida o
  decodificó encabezados de entrada, entonces los encabezados deberán
  volver a codificarse en Latin-1. Por ejemplo, un encabezado de
  salida codificado en utf-8 usaba "h.encode('utf-8')", ahora se
  necesita convertir de bytes a cadenas nativas usando
  "h.encode('utf-8').decode('latin-1')".

* Los valores generados por una aplicación o enviados mediante el
  método "write()" deben ser cadenas de bytes. La función
  "start_response()" y el entorno deben utilizar cadenas nativas. No
  se pueden mezclar.

Para los implementadores de servidores que escriben rutas de CGI a
WSGI u otros protocolos de estilo CGI, los usuarios deben poder
acceder al entorno utilizando cadenas nativas, aunque la plataforma
subyacente pueda tener una convención diferente. Para salvar esta
brecha, el módulo "wsgiref" tiene una nueva función,
"wsgiref.handlers.read_environ()", para transcodificar variables CGI
de "os.environ" en cadenas nativas y devolver un nuevo diccionario.

Ver también:

  **PEP 3333** - Interfaz de puerta de enlace del servidor web Python
  v1.0.1
     PEP escrito por Phillip Eby.


Otros cambios de lenguaje
=========================

Algunos cambios más pequeños realizados en el lenguaje central de
Python son:

* El formato de cadena de caracteres para "format()" y "str.format()"
  obtuvo nuevas capacidades para el carácter de formato **#**.
  Anteriormente, para enteros en binario, octal o hexadecimal, hacía
  que la salida tuviera el prefijo '0b', '0o' o '0x' respectivamente.
  Ahora también puede manejar flotantes, complejos y decimales, lo que
  hace que la salida siempre tenga un punto decimal, incluso cuando no
  le siguen dígitos.

  >>> format(20, '#o')
  '0o24'
  >>> format(12.34, '#5.0f')
  '  12.'

  (Sugerido por Mark Dickinson e implementado por Eric Smith en
  bpo-7094.)

* There is also a new "str.format_map()" method that extends the
  capabilities of the existing "str.format()" method by accepting
  arbitrary *mapping* objects.  This new method makes it possible to
  use string formatting with any of Python's many dictionary-like
  objects such as "defaultdict", "Shelf", "ConfigParser", or "dbm".
  It is also useful with custom "dict" subclasses that normalize keys
  before look-up or that supply a "__missing__()" method for unknown
  keys:

     >>> import shelve
     >>> d = shelve.open('tmp.shl')
     >>> 'El estado de {project_name} es {status} a partir de {date}'.format_map(d)
     'El estado del proyecto de prueba es verde a partir del 15 de febrero de 2011'

     >>> class LowerCasedDict(dict):
     ... def __getitem__(self, key):
     ... return dict.__getitem__(self, key.lower())
     ...
     >>> lcd = LowerCasedDict(part='widgets', quantity=10)
     >>> 'Hay {QUANTITY} {Part} en stock'.format_map(lcd)
     'Hay 10 widgets en stock'

     >>> class PlaceholderDict(dict):
     ... def __missing__(self, key):
     ... return '<{}>'.format(key)
     ...
     >>> 'Hola {nombre}, bienvenido a {ubicación}'.format_map(PlaceholderDict())
     'Hola <nombre>, bienvenido a <ubicación>'

   (Sugerido por Raymond Hettinger e implementado por Eric Smith en
   bpo-6081.)

* Ahora es posible iniciar el intérprete con una opción silenciosa,
  "-q", para evitar que la información de copyright y de versión se
  muestre en el modo interactivo. La opción se puede analizar mediante
  el atributo "sys.flags":

     $ python -q
     >>> sys.flags
     sys.flags(depuración=0, advertencia_de_división=0, inspección=0, interactivo=0,
     optimización=0, no_escribir_código_de_bytes=0, sin_sitio_de_usuario=0, sin_sitio=0,
     ignorar_entorno=0, verbose=0, advertencia_de_bytes=0, silencioso=1)

  (Contribución de Marcin Wojdyr en bpo-1772833).

* La función "hasattr()" funciona llamando a "getattr()" y detectando
  si se genera una excepción. Esta técnica le permite detectar métodos
  creados dinámicamente por "__getattr__()" o "__getattribute__()"
  que, de otro modo, no estarían en el diccionario de clases.
  Anteriormente, *hasattr* capturaba cualquier excepción, posiblemente
  enmascarando errores genuinos. Ahora, *hasattr* se ha ajustado para
  que solo capture "AttributeError" y permita que pasen otras
  excepciones:

     >>> class A:
     ... @property
     ... def f(self):
     ... return 1 // 0
     ...
     >>> a = A()
     >>> hasattr(a, 'f')
     Traceback (última llamada más reciente):
     ...
     ZeroDivisionError: división entera o módulo por cero

  (Descubierto por Yury Selivanov y arreglado por Benjamin Peterson;
  bpo-9666.)

* La "str()" de un número flotante o complejo ahora es el mismo que su
  "repr()". Anteriormente, el formulario "str()" era más corto, pero
  eso solo causaba confusión y ya no es necesario ahora que el más
  corto posible "repr()" se muestra por defecto:

  >>> import math
  >>> repr(math.pi)
  '3.141592653589793'
  >>> str(math.pi)
  '3.141592653589793'

  (Propuesto e implementado por Mark Dickinson; bpo-9337.)

* Los objetos "memoryview" ahora tienen un método "release()" y
  también admiten el protocolo de administración de contexto. Esto
  permite la liberación oportuna de cualquier recurso que se haya
  adquirido al solicitar un búfer del objeto original.

  >>> with memoryview(b'abcdefgh') as v:
  ...     print(v.tolist())
  [97, 98, 99, 100, 101, 102, 103, 104]

  (Añadido por Antoine Pitrou; bpo-9757.)

* Anteriormente, era ilegal eliminar un nombre del espacio de nombres
  local si aparece como una variable libre en un bloque anidado:

     def exterior(x):
     def interior():
     return x
     interior()
     del x

  Esto ahora está permitido. Recuerde que el objetivo de una cláusula
  "except" se borra, por lo que este código que solía funcionar con
  Python 2.6, lanza un "SyntaxError" con Python 3.1 y ahora funciona
  nuevamente:

     def f():
     def print_error():
     print(e)
     try:
     something
     except Exception as e:
     print_error()
     # "del e" implícito aquí

  (Ver bpo-4617.)

* Struct sequence types ahora son subclases de tuplas. Esto significa
  que las estructuras de C como las devueltas por "os.stat()",
  "time.gmtime()" y "sys.version_info" ahora funcionan como *named
  tuple* y funcionan con funciones y métodos que esperan una tupla
  como argumento. Este es un gran paso adelante para hacer que las
  estructuras de C sean tan flexibles como sus contrapartes de Python
  puro:

  >>> import sys
  >>> isinstance(sys.version_info, tuple)
  True
  >>> 'Version %d.%d.%d %s(%d)' % sys.version_info
  'Version 3.2.0 final(0)'

  (Sugerido por Arfrever Frehtes Taifersar Arahesis e implementado por
  Benjamin Peterson en bpo-8413.)

* Las *Warnings* ahora son más fáciles de controlar usando la variable
  de entorno "PYTHONWARNINGS" como alternativa al uso de "-W" en la
  línea de comando:

     $ export PYTHONWARNINGS='ignore::Advertencia en tiempo de ejecución::,once::Advertencia Unicode::'

  (Sugerido por Barry Warsaw e implementado por Philip Jenvey en
  bpo-7301.)

* Se ha agregado una nueva categoría de advertencia,
  "ResourceWarning". Se emite cuando se detectan problemas potenciales
  con el consumo de recursos o la limpieza. Está silenciado de forma
  predeterminada en las versiones de lanzamiento normales, pero se
  puede habilitar a través de los medios proporcionados por el módulo
  "warnings" o en la línea de comandos.

  Se emite un "ResourceWarning" al apagar el intérprete si la lista
  "gc.garbage" no está vacía y, si está configurado
  "gc.DEBUG_UNCOLLECTABLE", se imprimen todos los objetos que no se
  pueden recolectar. Esto tiene como objetivo que el programador sepa
  que su código contiene problemas de finalización de objetos.

  Un "ResourceWarning" también se emite cuando un *file object* se
  destruye sin haber sido cerrado explícitamente. Si bien el
  desasignador de dicho objeto asegura que cierra el recurso del
  sistema operativo subyacente (generalmente, un descriptor de
  archivo), la demora en desasignar el objeto podría producir varios
  problemas, especialmente en Windows. A continuación, se muestra un
  ejemplo de cómo habilitar la advertencia desde la línea de comando:

     $ python -q -Wdefault
     >>> f = open("foo", "wb")
     >>> del f
     __main__:1: ResourceWarning: archivo sin cerrar <_io.BufferedWriter name='foo'>

  (Agregado por Antoine Pitrou y Georg Brandl en bpo-10093 y
  bpo-477863.)

* Los objetos "range" ahora admiten los métodos *index* y *count*.
  Esto es parte de un esfuerzo por lograr que más objetos implementen
  completamente los métodos "collections.Sequence" y *abstract base
  class*. Como resultado, el lenguaje tendrá una API más uniforme.
  Además, los objetos "range" ahora admiten segmentación e índices
  negativos, incluso con valores mayores que "sys.maxsize". Esto hace
  que *range* sea más interoperable con las listas:

     >>> rango(0, 100, 2).count(10)
     1
     >>> rango(0, 100, 2).index(10)
     5
     >>> rango(0, 100, 2)[5]
     10
     >>> rango(0, 100, 2)[0:5]
     rango(0, 10, 2)

  (Contribuido por Daniel Stutzbach en bpo-9213, por Alexander
  Belopolsky en bpo-2690, y por Nick Coghlan en bpo-10889.)

* Se resucitó la función incorporada "callable()" de Py2.x.
  Proporciona una alternativa concisa y legible al uso de una
  *abstract base class* en una expresión como "isinstance(x,
  collections.Callable)":

  >>> callable(max)
  True
  >>> callable(20)
  False

  (Ver bpo-10518.)

* El mecanismo de importación de Python ahora puede cargar módulos
  instalados en directorios con caracteres no ASCII en el nombre de la
  ruta. Esto resolvió un problema agravante con los directorios de
  inicio para los usuarios con caracteres no ASCII en sus nombres de
  usuario.

   (Trabajo extenso requerido por Victor Stinner en bpo-9425.)


Módulos nuevos, mejorados y obsoletos
=====================================

La biblioteca estándar de Python ha sido objeto de importantes
esfuerzos de mantenimiento y mejoras de calidad.

La novedad más importante de Python 3.2 es que el paquete "email", el
módulo "mailbox" y los módulos "nntplib" ahora funcionan correctamente
con el modelo bytes/texto en Python 3. Por primera vez, hay un manejo
correcto de mensajes con codificaciones mixtas.

En toda la biblioteca estándar, se ha prestado más atención a las
codificaciones y los problemas de texto frente a bytes. En particular,
las interacciones con el sistema operativo ahora son más capaces de
intercambiar datos que no son ASCII mediante la codificación MBCS de
Windows, codificaciones con reconocimiento de configuración regional o
UTF-8.

Otro logro importante es la adición de un soporte sustancialmente
mejor para conexiones *SSL* y certificados de seguridad.

Además, más clases ahora implementan *context manager* para soportar
una conveniente y confiable limpieza de recursos usando una
declaración "with".


email
-----

La usabilidad del paquete "email" en Python 3 se ha solucionado
principalmente gracias a los amplios esfuerzos de R. David Murray. El
problema era que los correos electrónicos generalmente se leen y
almacenan en forma de "bytes" en lugar de texto "str", y pueden
contener múltiples codificaciones dentro de un solo correo
electrónico. Por lo tanto, el paquete email tuvo que ampliarse para
analizar y generar mensajes de correo electrónico en formato de bytes.

* Nuevas funciones "message_from_bytes()" y
  "message_from_binary_file()", y nuevas clases "BytesFeedParser" y
  "BytesParser" permiten mensajes de datos en binario para ser
  analizados (*parsed*) en objetos modelados.

* Dada la entrada de bytes al modelo, "get_payload()" decodificará por
  defecto un cuerpo de mensaje que tiene un *Content-Transfer-
  Encoding* de *8bit* usando el juego de caracteres especificado en el
  encabezados MIME y retorna la cadena de caracteres resultante.

* Dada la entrada de bytes al modelo, "Generator" convertirá los
  cuerpos de los mensajes que tengan un *Content-Transfer-Encoding* de
  *8bit* para tener en su lugar un *7bit**Content-Transfer-Encoding*.

  Los encabezados con bytes no codificados que no sean ASCII se
  consideran **RFC 2047**-codificados utilizando el juego de
  caracteres *unknown-8bit*.

* Una nueva clase "BytesGenerator" produce bytes como salida,
  conservando cualquier dato no ASCII sin cambios que estuviera
  presente en la entrada utilizada para construir el modelo, incluidos
  los cuerpos de los mensajes con un *Content-Transfer-Encoding* de
  *8bit*.

* La clase "smtplib""SMTP" ahora acepta una cadena de bytes para el
  argumento *msg* para el método "sendmail()", y un nuevo método,
  "send_message()" acepta un objeto "Message" y opcionalmente puede
  obtener las direcciones *from_addr* y *to_addrs* directamente del
  objeto.

(Propuesto e implementado por R. David Murray, bpo-4661 y bpo-10321.)


elementtree
-----------

El paquete "xml.etree.ElementTree" y su contraparte
"xml.etree.cElementTree" se han actualizado a la versión 1.3.

Se han agregado varias nuevas y útiles funciones y métodos:

* "xml.etree.ElementTree.fromstringlist()" que crea un documento XML a
  partir de una secuencia de fragmentos

* "xml.etree.ElementTree.register_namespace()" para registrar un
  prefijo de espacio de nombres global

* "xml.etree.ElementTree.tostringlist()" para la representación de
  cadenas de caracteres, incluidas todas las sublistas

* "xml.etree.ElementTree.Element.extend()" para agregar una secuencia
  de cero o más elementos

* "xml.etree.ElementTree.Element.iterfind()" busca un elemento y
  subelementos

* "xml.etree.ElementTree.Element.itertext()" crea un iterador de texto
  sobre un elemento y sus subelementos

* "xml.etree.ElementTree.TreeBuilder.end()" cierra el elemento actual

* "xml.etree.ElementTree.TreeBuilder.doctype()" gestiona la
  declaración *doctype*

Dos métodos que han sido deprecados:

* "xml.etree.ElementTree.getchildren()" usa "list(elem)" en su lugar.

* "xml.etree.ElementTree.getiterator()" usa "Element.iter" en su
  lugar.

Para obtener más información sobre la actualización, consulte
Introducing ElementTree en el sitio web de Fredrik Lundh.

(Contribución de Florent Xicluna y Fredrik Lundh, bpo-6472.)


functools
---------

* El módulo "functools" incluye un nuevo decorador para almacenar en
  caché las llamadas a funciones. "functools.lru_cache()" puede
  guardar consultas repetidas en un recurso externo siempre que se
  espere que los resultados sean los mismos.

  Por ejemplo, agregar un decorador de almacenamiento en caché a una
  función de consulta de base de datos puede ahorrar accesos a la base
  de datos para búsquedas populares:

  >>> import functools
  >>> @functools.lru_cache(maxsize=300)
  ... def get_phone_number(name):
  ...     c = conn.cursor()
  ...     c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))
  ...     return c.fetchone()[0]

  >>> for name in user_requests:
  ...     get_phone_number(name)        # cached lookup

  Para ayudar a elegir un tamaño de caché efectivo, la función
  encapsulada está instrumentada para rastrear estadísticas de caché:

  >>> get_phone_number.cache_info()
  CacheInfo(hits=4805, misses=980, maxsize=300, currsize=300)

  Si la tabla *phonelist* se actualiza, el contenido desactualizado de
  la caché se puede borrar con:

  >>> get_phone_number.cache_clear()

  (Contribuido por Raymond Hettinger e incorporando ideas de diseño de
  Jim Baker, Miki Tebeka y Nick Coghlan; consulte recipe 498245,
  recipe 577479, bpo-10586 y bpo-10593).

* El decorador "functools.wraps()" ahora agrega un atributo
  "__wrapped__" que apunta a la función invocable original. Esto
  permite que se puedan introspeccionar las funciones encapsuladas.
  También copia "__annotations__" si está definido. Y ahora también
  omite con elegancia los atributos faltantes, como "__doc__", que
  podrían no estar definidos para la función encapsulada.

  En el ejemplo anterior, la caché se puede eliminar recuperando la
  función original:

  >>> get_phone_number = get_phone_number.__wrapped__    # uncached function

  (Por Nick Coghlan y Terrence Cole; bpo-9567, bpo-3445, y bpo-8814.)

* Para ayudar a escribir clases con métodos de comparación
  enriquecidos, un nuevo decorador "functools.total_ordering()" usará
  métodos de igualdad y desigualdad existentes para completar los
  métodos restantes.

  Por ejemplo, suministrar *__eq__* y *__lt__* permitirá que
  "total_ordering()" complete *__le__*, *__gt__* and *__ge__*:

     @total_ordering
     clase Estudiante:
     def __eq__(self, other):
     return ((self.apellido.inferior(), self.nombre.inferior()) ==
     (other.apellido.inferior(), other.nombre.inferior()))

     def __lt__(self, other):
     return ((self.apellido.inferior(), self.nombre.inferior()) <
     (other.apellido.inferior(), other.nombre.inferior()))

  Con el decorador *total_ordering*, los métodos de comparación
  restantes se completan automáticamente.

  (Contribución por Raymond Hettinger.)

* Para ayudar en la migración de programas desde Python 2, la función
  "functools.cmp_to_key()" convierte una función de comparación de
  estilo antiguo en la nueva *key function*:

  >>> # locale-aware sort order
  >>> sorted(iterable, key=cmp_to_key(locale.strcoll))

  Para obtener ejemplos de ordenación y un breve tutorial, consulte el
  tutorial Sorting HowTo.

  (Contribución por Raymond Hettinger.)


itertools
---------

* El módulo "itertools" tiene una nueva función "accumulate()"
  modelada en el operador *scan* de APL y la función *accumulate* de
  Numpy:

  >>> from itertools import accumulate
  >>> list(accumulate([8, 2, 50]))
  [8, 10, 60]

  >>> prob_dist = [0.1, 0.4, 0.2, 0.3]
  >>> list(accumulate(prob_dist))      # cumulative probability distribution
  [0.1, 0.5, 0.7, 1.0]

  Para un ejemplo usando "accumulate()", vea los ejemplos para el
  módulo aleatorio.

  (Contribución de Raymond Hettinger e incorporando sugerencias de
  diseño de Mark Dickinson.)


collections
-----------

* La clase "collections.Counter" ahora tiene dos formas de resta in
  situ, el operador existente *-=* para saturación de resta y el nuevo
  método "subtract()" para la resta regular. El primero es adecuado
  para muticonjunto que solo tienen recuentos positivos, y el último
  es más adecuado para casos de uso que permiten recuentos negativos:

  >>> from collections import Counter
  >>> tally = Counter(dogs=5, cats=3)
  >>> tally -= Counter(dogs=2, cats=8)    # saturating subtraction
  >>> tally
  Counter({'dogs': 3})

  >>> tally = Counter(dogs=5, cats=3)
  >>> tally.subtract(dogs=2, cats=8)      # regular subtraction
  >>> tally
  Counter({'dogs': 3, 'cats': -5})

  (Contribución por Raymond Hettinger.)

* La clase "collections.OrderedDict" tiene un nuevo método
  "move_to_end()" que toma una clave existente y mueve a la primera o
  última posición de la secuencia ordenada.

  El valor predeterminado es mover un elemento a la última posición.
  Esto es equivalente a renovar una entrada con "od[k] = od.pop(k)".

  Una operación de mover al final rápida es útil para volver a
  secuenciar entradas. Por ejemplo, se puede usar un diccionario
  ordenado para rastrear el orden de acceso a las entradas por
  antigüedad desde la más antigua hasta la más reciente.

  >>> from collections import OrderedDict
  >>> d = OrderedDict.fromkeys(['a', 'b', 'X', 'd', 'e'])
  >>> list(d)
  ['a', 'b', 'X', 'd', 'e']
  >>> d.move_to_end('X')
  >>> list(d)
  ['a', 'b', 'd', 'e', 'X']

  (Contribución por Raymond Hettinger.)

* La clase "collections.deque" desarrolló dos métodos nuevos "count()"
  y "reverse()" que los hacen más intercambiables con los objetos
  "list" :

  >>> from collections import deque
  >>> d = deque('simsalabim')
  >>> d.count('s')
  2
  >>> d.reverse()
  >>> d
  deque(['m', 'i', 'b', 'a', 'l', 'a', 's', 'm', 'i', 's'])

  (Contribución por Raymond Hettinger.)


threading
---------

El módulo "threading" tiene una nueva clase "Barrier" de
sincronización para hacer que varios hilos esperen hasta que todos
hayan alcanzado un punto de barrera común. Las barreras son útiles
para asegurarse de que una tarea con múltiples condiciones previas no
se ejecute hasta que se completen todas las tareas predecesoras.

Las barreras pueden trabajar con un número arbitrario de hilos. Esto
es una generalización de barrera informática que se define solo para
dos hilos.

Implementado como una barrera cíclica de dos fases, los objetos
"Barrier" son adecuados para su uso en bucles. Las fases separadas de
*llenado* y *drenaje* aseguran que todos los hilos se liberen (drenan)
antes de que cualquiera de ellos pueda retornar y volver a entrar en
la barrera. La barrera se restablece completamente después de cada
ciclo.

Ejemplo de uso de barreras:

   de threading import Barrier, Thread

   def get_votes(site):
   ballots = conduct_election(site)
   all_polls_closed.wait() # no contar hasta que se cierren todas las encuestas
   totals = summary(ballots)
   publish(site, totals)

   all_polls_closed = Barrier(len(sites))
   for site in sites:
   Thread(target=get_votes, args=(site,)).start()

En este ejemplo, la barrera impone una regla de que los votos no se
pueden contar en ningún lugar de votación hasta que se cierren todas
las urnas. Observe cómo una solución con una barrera es similar a una
con "threading.Thread.join()", pero los hilos se mantienen vivos y
continúan trabajando (resumiendo las papeletas) después de que se
cruza el punto de la barrera.

Si alguna de las tareas predecesoras puede bloquearse o retrasarse, se
puede crear una barrera con un parámetro opcional *timeout*. Luego, si
el período de tiempo de espera transcurre antes de que todas las
tareas predecesoras alcancen el punto de barrera, se liberan todos los
hilos en espera y se lanza una excepción "BrokenBarrierError":

   def get_votes(sitio):
   votos = realizar_elecciones(sitio)
   try:
   all_polls_closed.wait(timeout=midnight - time.now())
   except BrokenBarrierError:
   lockbox = sellar_votos(votos)
   queue.put(lockbox)
   else:
   totales = resumir(votos)
   publish(sitio, totales)

En este ejemplo, la barrera impone una regla más sólida. Si algunos
sitios electorales no terminan antes de la medianoche, la barrera
expira y las boletas se sellan y se depositan en una cola para su
posterior manejo.

Consulte Barrier Synchronization Patterns para obtener más ejemplos de
cómo se pueden usar las barreras en la computación paralela. Además,
hay una explicación simple pero completa de las barreras en The Little
Book of Semaphores, *section 3.6*.

(Contribución de Kristján Valur Jónsson con una revisión de API de
Jeffrey Yasskin en bpo-8777.)


datetime and time
-----------------

* El módulo "datetime" tiene un nuevo tipo "timezone" que implementa
  la interfaz "tzinfo" retornando un desplazamiento fijo desde UTC y
  un nombre de zona horaria. Esto hace que sea más fácil crear objetos
  de fecha y hora que tengan en cuenta la zona horaria:

     >>> import datetime as dt

     >>> dt.datetime.now(dt.timezone.utc)
     datetime.datetime(2010, 12, 8, 21, 4, 2, 923754, tzinfo=datetime.timezone.utc)

     >>> dt.datetime.strptime("01/01/2000 12:00 +0000", "%m/%d/%Y %H:%M %z")
     datetime.datetime(2000, 1, 1, 12, 0, tzinfo=datetime.timezone.utc)

* Además, los objetos "timedelta" ahora pueden ser multiplicados por
  objetos "float" y divididos por objetos "float" e "int". Y los
  objetos "timedelta" ahora se pueden dividir entre sí.

* El método "datetime.date.strftime()" ya no está restringido a años
  posteriores a 1900. El nuevo rango de años admitido es de 1000 a
  9999 inclusive.

* Siempre que se utiliza un año de dos dígitos en una tupla de tiempo,
  la interpretación se rige por "time.accept2dyear". El valor
  predeterminado es "True", lo que significa que, para un año de dos
  dígitos, el siglo se calcula de acuerdo con las reglas POSIX que
  rigen el formato strptime "%y".

  A partir de Py3.2, el uso de la heurística de estimación del siglo
  emitirá un "DeprecationWarning". En cambio, se recomienda que
  "time.accept2dyear" se configure en "False" para que se puedan usar
  rangos de fechas grandes sin necesidad de realizar conjeturas:

     >>> import time, Warnings
     >>> Warnings.resetwarnings() # eliminar los filtros de advertencia predeterminados

     >>> time.accept2dyear = True # adivinar si 11 significa 11 o 2011
     >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))
     Advertencia (del módulo de advertencias):
     ...
     Advertencia de desuso: información del siglo supuesta para un año de 2 dígitos.
     'Fri Jan 1 12:34:56 2011'

     >>> time.accept2dyear = False # usar el rango completo de fechas permitidas
     >>> time.asctime((11, 1, 1, 12, 34, 56, 4, 1, 0))
     'Fri Jan 1 12:34:56 11'

  Varias funciones ahora tienen rangos de fechas significativamente
  ampliados. Cuando "time.accept2dyear" es falso, la función
  "time.asctime()" aceptará cualquier año que quepa en un int de C,
  mientras que las funciones "time.mktime()" y "time.strftime()"
  aceptarán el rango completo admitido por las funciones del sistema
  operativo correspondientes.

(Contribución de Alexander Belopolsky y Victor Stinner en bpo-1289118,
bpo-5094, bpo-6641, bpo-2706, bpo-1777412, bpo-8013, y bpo-10827.)


math
----

El módulo "math" se ha actualizado con seis nuevas funciones
inspiradas en el estándar C99.

La función "isfinite()" proporciona una forma rápida y fiable de
detectar valores especiales. Retorna "True" para números regulares y
"False" para *Nan* o *Infinity*:

>>> from math import isfinite
>>> [isfinite(x) for x in (123, 4.56, float('Nan'), float('Inf'))]
[True, True, False, False]

La función "expm1()" calcula "e**x-1" para valores pequeños de *x* sin
incurrir en la pérdida de precisión que generalmente acompaña a la
resta de cantidades casi iguales:

>>> from math import expm1
>>> expm1(0.013671875)   # more accurate way to compute e**x-1 for a small x
0.013765762467652909

La función "erf()" calcula una integral de probabilidad o función de
error gaussiano. La función de error complementaria, "erfc()", es "1 -
erf(x)":

   >>> from math import erf, erfc, sqrt
   >>> erf(1.0/sqrt(2.0)) # porción de distribución normal dentro de 1 desviación estándar
   0.682689492137086
   >>> erfc(1.0/sqrt(2.0)) # porción de distribución normal fuera de 1 desviación estándar
   0.31731050786291404
   >>> erf(1.0/sqrt(2.0)) + erfc(1.0/sqrt(2.0))
   1.0

La función "gamma()" es una extensión continua de la función
factorial. Consulte https://es.wikipedia.org/wiki/Funci%C3%B3n_gamma
para obtener más detalles. Debido a que la función está relacionada
con factoriales, crece incluso para valores pequeños de *x*, por lo
que también hay una función "lgamma()" para calcular el logaritmo
natural de la función gamma:

>>> from math import gamma, lgamma
>>> gamma(7.0)           # six factorial
720.0
>>> lgamma(801.0)        # log(800 factorial)
4551.950730698041

(Contribución de Mark Dickinson.)


abc
---

El módulo "abc" ahora admite "abstractclassmethod()" y
"abstractstaticmethod()".

Estas herramientas permiten definir una *abstract base class* que
requiere un "classmethod()" o "staticmethod()" particular para ser
implementado:

   clase Temperatura(metaclase=abc.ABCMeta):
   @abc.abstractclassmethod
   def from_fahrenheit(cls, t):
   ...
   @abc.abstractclassmethod
   def from_celsius(cls, t):
   ...

(Parche enviado por Daniel Urban; bpo-5867.)


io
--

La clase "io.BytesIO" tiene un nuevo método, "getbuffer()", que
proporciona una funcionalidad similar a "memoryview()". Crea una vista
editable de los datos sin hacer una copia. El acceso aleatorio del
búfer y la compatibilidad con la notación de sectores son adecuados
para la edición in situ:

   >>> REC_LEN, LOC_START, LOC_LEN = 34, 7, 11

   >>> def change_location(buffer, record_number, location):
   ... start = record_number * REC_LEN + LOC_START
   ... buffer[start: start+LOC_LEN] = location

   >>> import io

   >>> byte_stream = io.BytesIO(
   ... b'G3805 almacén Chasis principal '
   ... b'X7899 envío Piñón de reserva '
   ... b'L6988 recepción Piñón primario'
   ... )
   >>> buffer = byte_stream.getbuffer()
   >>> change_location(buffer, 1, b'almacén ')
   >>> change_location(buffer, 0, b'sala de exposición ')
   >>> print(byte_stream.getvalue())
   b'G3805 sala de exposición Chasis principal '
   b'X7899 piñón de reserva de almacén '
   b'L6988 piñón de recepción primario'

(Contribución de Antoine Pitrou en bpo-5506.)


reprlib
-------

Al escribir un método "__repr__()" para un contenedor personalizado,
es fácil olvidarse de manejar el caso en el que un miembro hace
referencia al propio contenedor. Los objetos integrados de Python,
como "list" y "set", manejan la autorreferencia mostrando "..." en la
parte recursiva de la cadena de representación.

Para ayudar a escribir dichos métodos "__repr__()", el módulo
"reprlib" tiene un nuevo decorador, "recursive_repr()", para detectar
llamadas recursivas a "__repr__()" y sustituir una cadena de marcador
de posición en su lugar:

   >>> clase MiLista(lista):
   ... @recursive_repr()
   ... def __repr__(self):
   ... return '<' + '|'.join(map(repr, self)) + ">'
   ...
   >>> m = MiLista('abc')
   >>> m.append(m)
   >>> m.append('x')
   >>> print(m)
   <'a'|'b'|'c'|...|'x'>

(Contribución de Raymond Hettinger en bpo-9826 y bpo-9840.)


logging
-------

Además de la configuración basada en diccionario descrita
anteriormente, el paquete "logging" tiene muchas otras mejoras.

La documentación de logging se ha aumentado con un tutorial básico, un
tutorial avanzado, y un libro de recetas. Estos documentos son la
forma más rápida de aprender sobre logging.

La función de configuración "logging.basicConfig()" adquirió un
argumento *style* para admitir tres tipos diferentes de formato de
cadena de caracteres. Su valor predeterminado es "%" para el formato %
tradicional, se puede establecer en "{" para el nuevo estilo
"str.format()", o se puede establecer en "$" para el formato de estilo
shell proporcionado por "string.Template". Las siguientes tres
configuraciones son equivalentes:

   >>> desde el registro, importe basicConfig
   >>> basicConfig(style='%', format="%(nombre)s -> %(nombrenivel)s: %(mensaje)s")
   >>> basicConfig(style='{', format="{nombre} -> {nombrenivel} {mensaje}")
   >>> basicConfig(style='$', format="$nombre -> $nombrenivel: $mensaje")

Si no se configura ninguna configuración antes de que se produzca un
evento de registro, ahora hay una configuración predeterminada que
utiliza un "StreamHandler" dirigido a "sys.stderr" para eventos de
nivel "WARNING" o superior. Anteriormente, un evento que se producía
antes de que se estableciera una configuración generaba una excepción
o descartaba el evento de forma silenciosa según el valor de
"logging.raiseExceptions". El nuevo controlador predeterminado se
almacena en "logging.lastResort".

El uso de filtros ha sido simplificado. En lugar de crear un objeto
"Filter", la declaración puede ser cualquier invocable Python que
retorna "True" o "False".

Hubo una serie de otras mejoras que agregan flexibilidad y simplifican
la configuración. Consulte la documentación del módulo para obtener
una lista completa de los cambios en Python 3.2.


csv
---

El módulo "csv" ahora admite un nuevo dialecto, "unix_dialect", que
aplica comillas para todos los campos y un estilo Unix tradicional con
"'\n'" como terminador de línea. El nombre del dialecto registrado es
"unix".

La clase "csv.DictWriter" tiene un nuevo método, "writeheader()" para
escribir una fila inicial para documentar los nombres de los campos:

   >>> import csv, sys
   >>> w = csv.DictWriter(sys.stdout, ['nombre', 'dept'], dialect='unix')
   >>> w.writeheader()
   "nombre", "dept"
   >>> w.writerows([
   ... {'nombre': 'tom', 'dept': 'contabilidad'},
   ... {'nombre': 'susan', 'dept': 'Ventas'}])
   "tom", "contabilidad"
   "susan", "ventas"

(Nuevo dialecto sugerido por Jay Talbot en bpo-5975, y el nuevo método
sugerido por Ed Abraham en bpo-1537721.)


contextlib
----------

Hay una nueva y ligeramente alucinante herramienta "ContextDecorator"
que es útil para crear un *context manager* que cumple una doble
función como decorador de funciones.

Para su comodidad, esta nueva funcionalidad es utilizada por
"contextmanager()" de modo que no se necesita ningún esfuerzo
adicional para admitir ambos roles.

La idea básica es que tanto los gestores de contexto como los
decoradores de funciones se pueden usar para envoltorios (*wrappers*)
previos y posteriores a la acción. Los gestores de contexto envuelven
un grupo de declaraciones usando la declaración "with" y los
decoradores de funciones envuelven un grupo de declaraciones
encerradas en una función. Por lo tanto, ocasionalmente es necesario
escribir un envoltorio de acción previa o posterior que se pueda usar
en cualquiera de los roles.

Por ejemplo, a veces es útil envolver funciones o grupos de
declaraciones con un logger que pueda rastrear el tiempo de entrada y
el tiempo de salida. En lugar de escribir tanto un decorador de
funciones como un gestor de contexto para la tarea, "contextmanager()"
proporciona ambas capacidades en una sola definición:

   de contextlib import contextmanager
   import logging

   logging.basicConfig(level=logging.INFO)

   @contextmanager
   def track_entry_and_exit(name):
   logging.info('Entrando: %s', nombre)
   yield
   logging.info('Saliendo: %s', nombre)

Anteriormente, esto solo se podía usar como gestor de contexto:

   con track_entry_and_exit('cargador de widgets'):
   print('Aquí se realiza una actividad que consume mucho tiempo')
   load_widget()

Ahora, también se puede usar como decorador:

   @track_entry_and_exit('cargador de widgets')
   def activity():
   print('Aquí se realiza una actividad que consume mucho tiempo')
   load_widget()

Tratar de cumplir dos roles a la vez impone algunas limitaciones a la
técnica. Los gestores de contexto normalmente tienen la flexibilidad
de retornar un argumento utilizable por una instrucción "with", pero
no hay paralelo para los decoradores de funciones.

En el ejemplo anterior, no hay una forma limpia para que el gestor de
contexto *track_entry_and_exit* retorne una instancia de logging para
usar en el cuerpo de las declaraciones adjuntas.

(Contribución de Michael Foord en bpo-9110.)


decimal and fractions
---------------------

Mark Dickinson diseñó un esquema elegante y eficiente para asegurar
que diferentes tipos de datos numéricos tendrán el mismo valor hash
siempre que sus valores reales sean iguales (bpo-8188):

   afirmar hash(Fracción(3, 2)) == hash(1.5) == \
   hash(Decimal("1.5")) == hash(complejo(1.5, 0))

Algunos de los detalles del hash se exponen a través de un nuevo
atributo, "sys.hash_info", que describe el ancho de bits del valor
hash, el módulo primo, los valores hash para *infinity* y *nan*, y el
multiplicador utilizado para la parte imaginaria de un número:

>>> sys.hash_info
sys.hash_info(width=64, modulus=2305843009213693951, inf=314159, nan=0, imag=1000003)

Se ha relajado una decisión temprana de limitar la interoperabilidad
de varios tipos numéricos. Todavía no se admite (y no es aconsejable)
la mezcla implícita en expresiones aritméticas como "Decimal('1.1') +
float('1.1')" porque esta última pierde información en el proceso de
construcción del flotante binario. Sin embargo, dado que los valores
de punto flotante existentes se pueden convertir sin pérdida a una
representación decimal o racional, tiene sentido agregarlos al
constructor y admitir comparaciones de tipos mixtos.

* El constructor "decimal.Decimal" ahora acepta objetos "float"
  directamente, por lo que ya no es necesario utilizar el método
  "from_float()" (bpo-8257).

* Las comparaciones de tipos mixto ahora son totalmente compatibles,
  de modo que los objetos "Decimal" se pueden comparar directamente
  con "float" y "fractions.Fraction" (bpo-2531 y bpo-8188).

Se realizaron cambios similares en "fractions.Fraction", por lo que
los métodos "from_float()" y "from_decimal()" ya no son necesarios
(bpo-8294):

>>> from decimal import Decimal
>>> from fractions import Fraction
>>> Decimal(1.1)
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)

Otro cambio útil para el módulo "decimal" es que el atributo
"Context.clamp" ahora es público. Esto resulta útil para crear
contextos que corresponden a los formatos de intercambio decimal
especificados en IEEE 754 (consulte bpo-8540).

(Contribución de Mark Dickinson y Raymond Hettinger.)


ftp
---

La clase "ftplib.FTP" ahora admite el protocolo de gestor de contexto
para consumir incondicionalmente las excepciones "socket.error" y
cerrar la conexión FTP cuando haya terminado:

   >>> de ftplib import FTP
   >>> con FTP("ftp1.at.proftpd.org") como ftp:
   ftp.login()
   ftp.dir()

   '230 Inicio de sesión anónimo correcto, se aplican restricciones.'
   dr-xr-xr-x 9 ftp ftp 154 ​​6 de mayo 10:43 .
   dr-xr-xr-x 9 ftp ftp 154 ​​6 de mayo 10:43 ..
   dr-xr-xr-x 5 ftp ftp 4096 6 de mayo 10:43 CentOS
   dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora

Otros objetos similares a archivos como "mmap.mmap" y
"fileinput.input()" también adquirieron gestores de contexto de cierre
automático:

   con fileinput.input(files=('log1.txt', 'log2.txt')) como f:
   para línea en f:
   proceso(línea)

(Contribución de Tarek Ziadé y Giampaolo Rodolà en bpo-4972, y por
Georg Brandl en bpo-8046 y bpo-1286.)

La clase "FTP_TLS" ahora acepta un parámetro *context*, que es un
objeto "ssl.SSLContext" que permite agrupar opciones de configuración
SSL, certificados y claves privadas en una sola (y potencialmente de
larga duración) estructura.

(Contribución de Giampaolo Rodolà; bpo-8806.)


popen
-----

Las funciones "os.popen()" y "subprocess.Popen()" ahora admiten
declaraciones "with" para el cierre automático de los descriptores de
archivo.

(Contribución de Antoine Pitrou y Brian Curtin en bpo-7461 y
bpo-10554.)


select
------

El módulo "select" ahora expone un nuevo atributo constante,
"PIPE_BUF", que proporciona la cantidad mínima de bytes que se
garantiza que no se bloquearán cuando "select.select()" indica que una
tubería está lista para escribir.

>>> import select
>>> select.PIPE_BUF
512

(Disponible en sistemas Unix. Parche de Sébastien Sablé en bpo-9862)


gzip y zipfile
--------------

"gzip.GzipFile" ahora implementa "io.BufferedIOBase" *clase base
abstracta* (excepto para "truncate()"). También tiene un método
"peek()" y admite objetos de archivo con rellenos de ceros y que no se
pueden buscar.

El módulo "gzip" también obtiene las funciones "compress()" y
"decompress()" para facilitar la compresión y descompresión en
memoria. Tenga en cuenta que el texto debe codificarse como "bytes"
antes de comprimir y descomprimir:

>>> import gzip
>>> s = 'Three shall be the number thou shalt count, '
>>> s += 'and the number of the counting shall be three'
>>> b = s.encode()                        # convert to utf-8
>>> len(b)
89
>>> c = gzip.compress(b)
>>> len(c)
77
>>> gzip.decompress(c).decode()[:42]      # decompress and convert to text
'Three shall be the number thou shalt count'

(Contribución de Anand B. Pillai en bpo-3488; y de Antoine Pitrou, Nir
Aides y Brian Curtin en bpo-9962, bpo-1675951, bpo-7471 y bpo-2846.)

Además, la clase "zipfile.ZipExtFile" se modificó internamente para
representar archivos almacenados dentro de un archivo. La nueva
implementación es significativamente más rápida y se puede incluir en
un objeto "io.BufferedReader" para lograr más velocidad. También
resuelve un problema en el que las llamadas intercaladas a *read* y
*readline* arrojaban resultados incorrectos.

(Parche enviado por Nir Aides en bpo-7610.)


tarfile
-------

La clase "TarFile" ahora se puede usar como gestor de contexto.
Además, su método "add()" tiene una nueva opción, *filter*, que
controla qué archivos se agregan y permite editar los metadatos del
archivo.

La nueva opción *filter* reemplaza el parámetro anterior y menos
flexible *exclude* que ahora está deprecado. Si se especifica, el
parámetro opcional *filter* debe ser un *keyword argument*. La función
*filter* proporcionada por el usuario acepta un objeto "TarInfo" y
retorna un objeto "TarInfo" actualizado, o si desea que el archivo sea
excluido, la función puede retornar "None":

   >>> import tarfile, glob

   >>> def myfilter(tarinfo):
   ... if tarinfo.isfile(): # solo guardar archivos reales
   ... tarinfo.uname = 'monty' # redactar el nombre de usuario
   ... return tarinfo

   >>> with tarfile.open(name='myarchive.tar.gz', mode='w:gz') as tf:
   ... for filename in glob.glob('*.txt'):
   ... tf.add(filename, filter=myfilter)
   ... tf.list()
   -rw-r--r-- monty/501 902 2011-01-26 17:59:11 annotations.txt
   -rw-r--r-- monty/501 123 2011-01-26 17:59:11 preguntas_generales.txt
   -rw-r--r-- monty/501 3514 2011-01-26 17:59:11 prion.txt
   -rw-r--r-- monty/501 124 2011-01-26 17:59:11 py_todo.txt
   -rw-r--r-- monty/501 1399 2011-01-26 17:59:11 notas_semáforo.txt

(Propuesto por Tarek Ziadé e implementado por Lars Gustäbel en
bpo-6856.)


hashlib
-------

El módulo "hashlib" tiene dos nuevos atributos constantes que enumeran
los algoritmos hash garantizados para estar presentes en todas las
implementaciones y los disponibles en la implementación actual:

   >>> importar hashlib

   >>> hashlib.algoritmos_garantizados
   {'sha1', 'sha224', 'sha384', 'sha256', 'sha512', 'md5'}

   >>> hashlib.algoritmos_disponibles
   {'md2', 'SHA256', 'SHA512', 'dsaWithSHA', 'mdc2', 'SHA224', 'MD4', 'sha256',
   'sha512', 'ripemd160', 'SHA1', 'MDC2', 'SHA', 'SHA384', 'MD2',
   'ecdsa-with-SHA1','md4', 'md5', 'sha1', 'DSA-SHA', 'sha224',
   'dsaEncryption', 'DSA', 'RIPEMD160', 'sha', 'MD5', 'sha384'}

(Sugerido por Carl Chenet en bpo-7418.)


ast
---

El módulo "ast" tiene una maravillosa herramienta de propósito general
para evaluar cadenas de expresión de forma segura utilizando la
sintaxis literal de Python. La función "ast.literal_eval()" sirve como
una alternativa segura a la función incorporada "eval()" la cual se
abusa fácilmente. Python 3.2 agrega "bytes" y "set" literales a la
lista de tipos admitidos: cadenas de caracteres, bytes, números,
tuplas, listas, diccionarios, sets, valores booleanos y "None".

   >>> from ast import literal_eval

   >>> request = "{'req': 3, 'func': 'pow', 'args': (2, 0.5)}"
   >>> literal_eval(request)
   {'args': (2, 0.5), 'req': 3, 'func': 'pow'}

   >>> request = "os.system('do something dangerous')"
   >>> literal_eval(request)
   Traceback (última llamada más reciente):
   ...
   ValueError: nodo o cadena con formato incorrecto: <_ast.Call object at 0x101739a10>

(Implementado por Benjamin Peterson y Georg Brandl.)


os
--

Los diferentes sistemas operativos utilizan varias codificaciones para
los nombres de archivo y las variables de entorno. El módulo "os"
proporciona dos funciones nuevas, "fsencode()" y "fsdecode()", para
codificar y decodificar nombres de archivo:

>>> import os
>>> filename = 'Sehenswürdigkeiten'
>>> os.fsencode(filename)
b'Sehensw\xc3\xbcrdigkeiten'

Algunos sistemas operativos permiten el acceso directo a bytes
codificados en el entorno. En ese caso, la constante
"os.supports_bytes_environ" será verdadera.

Para acceder directamente a las variables de entorno codificadas (si
está disponible), utilice la nueva función "os.getenvb()" o utilice
"os.environb", que es una versión en bytes de "os.environ".

(Contribución de Victor Stinner.)


shutil
------

La función "shutil.copytree()" tiene dos nuevas opciones:

* *ignore_dangling_symlinks*: cuando "symlinks=False" para que la
  función copie un archivo apuntado por un enlace simbólico, no el
  enlace simbólico en sí. Esta opción silenciará el error lanzado si
  el archivo no existe.

* *copy_function*: es un invocable que se utilizará para copiar
  archivos. "shutil.copy2()" se usa por defecto.

(Contribución de Tarek Ziadé.)

Además, el módulo "shutil" ahora admite operaciones de archivado para
archivos zip, archivos tar sin comprimir, archivos tar comprimidos con
gzip y archivos tar bzip. Y hay funciones para registrar formatos de
archivado de archivo adicionales (como archivos tar comprimidos xz o
formatos personalizados).

Las funciones principales son "make_archive()" y "unpack_archive()".
Por defecto, ambas operan en el directorio actual (que puede ser
configurado por "os.chdir()") y en cualquier subdirectorio. El nombre
del archivo de almacenamiento debe especificarse con una ruta
completa. El paso de archivado no es destructivo (los archivos
originales no se modifican).

   >>> import shutil, pprint

   >>> os.chdir('mydata') # cambiar al directorio de origen
   >>> f = shutil.make_archive('/var/backup/mydata',
   ... 'zip') # archivar el directorio actual
   >>> f # mostrar el nombre del archivo
   '/var/backup/mydata.zip'
   >>> os.chdir('tmp') # cambiar a un desempaquetado
   >>> shutil.unpack_archive('/var/backup/mydata.zip') # recuperar los datos

   >>> pprint.pprint(shutil.get_archive_formats()) # mostrar formatos conocidos
   [('bztar', "archivo tar comprimido con bzip2"),
   ('gztar', "archivo tar comprimido con gzip"),
   ('tar', 'archivo tar sin comprimir'),
   ('zip', 'ZIP file')]

   >>> shutil.register_archive_format( # registrar un nuevo formato de archivo
   ... name='xz',
   ... function=xz.compress, # función de archivado invocable
   ... extra_args=[('level', 8)], # argumentos para la función
   ... description='xz compression'
   ... )

(Contribución de Tarek Ziadé.)


sqlite3
-------

El módulo "sqlite3" se actualizó a la versión 2.6.0 de pysqlite. Tiene
dos nuevas capacidades.

* El atributo "sqlite3.Connection.in_transit" es verdadero si hay una
  transacción activa para cambios no confirmados.

* Los métodos "sqlite3.Connection.enable_load_extension()" y
  "sqlite3.Connection.load_extension()" le permiten cargar extensiones
  SQLite desde archivos ".so". Una extensión conocida es la extensión
  de búsqueda de texto completo distribuida con SQLite.

(Contribución de R. David Murray y Shashwat Anand; bpo-8845.)


html
----

Se introdujo un nuevo módulo "html" con una sola función, "escape()",
que se usa para escapar caracteres reservados del marcado HTML:

>>> import html
>>> html.escape('x > 2 && x < 7')
'x &gt; 2 &amp;&amp; x &lt; 7'


socket
------

El módulo "socket" tiene dos nuevas mejoras.

* Los objetos de socket ahora tienen un método "detach()" que pone el
  socket en estado cerrado sin cerrar realmente el descriptor de
  archivo subyacente. Este último puede reutilizarse para otros fines.
  (Agregado por Antoine Pitrou; bpo-8524.)

* "socket.create_connection()" ahora admite el protocolo de
  administración de contexto para consumir incondicionalmente las
  excepciones "socket.error" y cerrar el socket cuando haya terminado.
  (Contribución de Giampaolo Rodolà; bpo-9794.)


ssl
---

El módulo "ssl" agregó una serie de características para satisfacer
los requisitos comunes para conexiones a Internet seguras
(encriptadas, autenticadas):

* Una nueva clase, "SSLContext", sirve como contenedor para datos SSL
  persistentes, como configuraciones de protocolo, certificados,
  claves privadas y varias opciones más. Incluye un "wrap_socket()"
  para crear un socket SSL a partir de un contexto SSL.

* Una nueva función, "ssl.match_hostname()", admite la verificación de
  identidad del servidor para protocolos de nivel superior mediante la
  implementación de las reglas de HTTPS (de **RFC 2818**) que también
  son adecuadas para otros protocolos.

* La función constructora "ssl.wrap_socket()" ahora acepta un
  argumento *ciphers*. La cadena *ciphers* enumera los algoritmos de
  cifrado permitidos utilizando el formato descrito en OpenSSL
  documentation.

* Cuando se vincula con versiones recientes de OpenSSL, el módulo
  "ssl" ahora admite la extensión de Server Name Indication (SNI, en
  español: Indicador del nombre del servidor) para el protocolo TLS,
  lo que permite que varios" hosts virtuales "utilicen diferentes
  certificados en un solo puerto IP. Esta extensión solo es compatible
  en modo cliente y se activa pasando el argumento *server_hostname* a
  "ssl.SSLContext.wrap_socket()".

* Se han agregado varias opciones al módulo "ssl", como "OP_NO_SSLv2"
  que deshabilita el protocolo SSLv2 inseguro y obsoleto.

* La extensión ahora carga todos los algoritmos de resumen y cifrados
  OpenSSL. Si algunos certificados SSL no se pueden verificar, se
  notifican como un error de "algoritmo desconocido".

* La versión de OpenSSL que se está utilizando ahora es accesible
  mediante los atributos del módulo "ssl.OPENSSL_VERSION" (una
  cadena), "ssl.OPENSSL_VERSION_INFO" (una tupla de 5) y
  "ssl.OPENSSL_VERSION_NUMBER" (un entero).

(Contribución de Antoine Pitrou en bpo-8850, bpo-1589, bpo-8322,
bpo-5639, bpo-4870, bpo-8484, y bpo-8321.)


nntp
----

El módulo "nntplib" tiene una implementación renovada con una mejor
semántica de bytes y texto, así como API más prácticas. Estas mejoras
rompen la compatibilidad con la versión nntplib en Python 3.1, que en
parte era disfuncional en sí misma.

También se ha agregado soporte para conexiones seguras a través de TLS
implícito (usando "nntplib.NNTP_SSL") y explícito (usando
"nntplib.NNTP.starttls()").

(Contribución de Antoine Pitrou en bpo-9360 y Andrew Vant en
bpo-1926.)


certificados
------------

"http.client.HTTPSConnection", "urllib.request.HTTPSHandler" y
"urllib.request.urlopen()" ahora toman argumentos opcionales para
permitir la comprobación del certificado del servidor con un conjunto
de Autoridades de Certificación recomendado en usos públicos de HTTPS.

(Agregado por Antoine Pitrou, bpo-9003.)


imaplib
-------

Se ha agregado soporte para TLS explícito en conexiones IMAP4 estándar
a través del nuevo método "imaplib.IMAP4.starttls".

(Contribución de Lorenzo M. Catucci y Antoine Pitrou, bpo-4471.)


http.client
-----------

Hubo una serie de pequeñas mejoras de API en el módulo "http.client".
Las respuestas simples HTTP 0.9 de estilo antiguo ya no son
compatibles y el parámetro *strict* está obsoleto en todas las clases.

Las clases "HTTPConnection" y "HTTPSConnection" ahora tienen un
parámetro *source_address* para una tupla (host, port) que indica
desde dónde se realiza la conexión HTTP.

Se agregó soporte para verificación de certificados y hosts virtuales
HTTPS a "HTTPSConnection".

El método "request()" en los objetos de conexión permitía un argumento
*body* opcional para que un *file object* pudiera usarse para
proporcionar el contenido de la solicitud. Convenientemente, el
argumento *body* ahora también acepta un objeto *iterable* siempre que
incluya un encabezado explícito "Content-Length". Esta interfaz
ampliada es mucho más flexible que antes.

Para establecer una conexión HTTPS a través de un servidor proxy,
existe un nuevo método "set_tunnel()" que establece el host y el
puerto para el túnel HTTP Connect.

Para que coincida con el comportamiento de "http.server", la
biblioteca de cliente HTTP ahora también codifica encabezados con
codificación ISO-8859-1 (Latin-1). Ya lo estaba haciendo para los
encabezados entrantes, por lo que ahora el comportamiento es coherente
para el tráfico entrante y saliente. (Véase el trabajo de Armin
Ronacher en bpo-10980)


unittest
--------

El módulo unittest tiene una serie de mejoras con soporte para
descubrimiento de pruebas para paquetes, una experimentación más
sencilla en el indicador interactivo, nuevos métodos de casos de
prueba, mensajes de diagnóstico mejorados para fallas en las pruebas y
mejores nombres de métodos.

* La llamada de línea de comandos "python -m unittest" ahora puede
  aceptar rutas de archivo en lugar de nombres de módulos para
  ejecutar pruebas específicas (bpo-10620). El nuevo descubrimiento de
  pruebas puede encontrar pruebas dentro de los paquetes, localizando
  cualquier prueba que se pueda importar desde el directorio de nivel
  superior. El directorio de nivel superior se puede especificar con
  la opción "-t", un patrón para hacer coincidir archivos con "-p" y
  un directorio para iniciar el descubrimiento con "-s":

     $ python -m unittest discover -s mi_directorio_del_proyecto -p _test.py

  (Contribución de Michael Foord.)

* La experimentación en el indicador interactivo ahora es más sencilla
  porque la clase "unittest.TestCase" ahora se puede instanciar sin
  argumentos:

  >>> from unittest import TestCase
  >>> TestCase().assertEqual(pow(2, 3), 8)

  (Contribución de Michael Foord.)

* El módulo "unittest" tiene dos métodos nuevos, "assertWarns()" y
  "assertWarnsRegex()" para verificar que un tipo de advertencia dado
  es activado por el código bajo prueba:

     con self.assertWarns(Advertencia de desuso):
     legacy_function('XYZ')

  (Contribución de Antoine Pitrou, bpo-9754.)

  Otro método nuevo, "assertCountEqual()" se usa para comparar dos
  iterables para determinar si sus conteos de elementos son iguales
  (si los mismos elementos están presentes con el mismo número de
  ocurrencias independientemente del orden):

     def test_anagram(self):
     self.assertCountEqual('algoritmo', 'logaritmo')

  (Contribución por Raymond Hettinger.)

* Una característica principal del módulo unittest es un esfuerzo por
  producir diagnósticos significativos cuando falla una prueba. Cuando
  es posible, la falla se registra junto con una diferencia de la
  salida. Esto es especialmente útil para analizar archivos de
  registro de ejecuciones de prueba fallidas. Sin embargo, dado que
  las diferencias en ocasiones pueden ser voluminosas, hay un nuevo
  atributo "maxDiff" que establece la longitud máxima de las
  diferencias mostradas.

* Además, los nombres de los métodos en el módulo se han sometido a
  una serie de limpiezas.

  Por ejemplo, "assertRegex()" es el nuevo nombre de
  "assertRegexpMatches()", que se nombró incorrectamente porque la
  prueba usa "re.search()", no "re.match()". Otros métodos que usan
  expresiones regulares ahora se nombran usando la forma corta "Regex"
  en lugar de "Regexp"; esto coincide con los nombres usados ​​en
  otras implementaciones de pruebas unitarias, coincide con el nombre
  antiguo de Python para el módulo "re" y tiene un uso inequívoco de
  mayúsculas y minúsculas.

  (Contribución de Raymond Hettinger e implementado por Ezio Melotti.)

* Para mejorar la coherencia, algunos alias de métodos antiguos se
  están deprecando en favor de los nombres preferidos:

     +---------------------------------+--------------------------------+
     | Old Name                        | Preferred Name                 |
     |=================================|================================|
     | "assert_()"                     | "assertTrue()"                 |
     +---------------------------------+--------------------------------+
     | "assertEquals()"                | "assertEqual()"                |
     +---------------------------------+--------------------------------+
     | "assertNotEquals()"             | "assertNotEqual()"             |
     +---------------------------------+--------------------------------+
     | "assertAlmostEquals()"          | "assertAlmostEqual()"          |
     +---------------------------------+--------------------------------+
     | "assertNotAlmostEquals()"       | "assertNotAlmostEqual()"       |
     +---------------------------------+--------------------------------+

  Asimismo, se espera que los métodos "TestCase.fail*" obsoletos en
  Python 3.1 se eliminen en Python 3.3.

  (Contribución de Ezio Melotti; bpo-9424.)

* El método "assertDictContainsSubset()" quedó obsoleto porque se
  implementó incorrectamente con los argumentos en el orden
  incorrecto. Esto generó ilusiones ópticas difíciles de depurar donde
  fallaban pruebas como "TestCase().assertDictContainsSubset({'a':1,
  'b':2}, {'a':1})".

  (Contribución por Raymond Hettinger.)


random
------

Los métodos enteros en el módulo "random" ahora hacen un mejor trabajo
al producir distribuciones uniformes. Anteriormente, calculaban las
selecciones con "int(n*random())" que tenía un ligero sesgo siempre
que *n* no era una potencia de dos. Ahora, se realizan selecciones
múltiples desde un rango hasta la siguiente potencia de dos y una
selección se mantiene solo cuando cae dentro del rango "0 <= x < n".
Las funciones y métodos afectados son "randrange()", "randint()",
"choice()", "shuffle()" y "sample()".

(Contribución de Raymond Hettinger; bpo-9025.)


poplib
------

"POP3_SSL" la clase ahora acepta un parámetro *context*, que es un
objeto "ssl.SSLContext" que permite agrupar opciones de configuración
SSL, certificados y claves privadas en una única estructura
(potencialmente de larga duración) .

(Contribución de Giampaolo Rodolà; bpo-8807.)


asyncore
--------

"asyncore.dispatcher" ahora proporciona un método "handle_accepted()"
que devuelve un par "(sock, addr)" que se llama cuando se ha
establecido una conexión con un nuevo punto final remoto. Se supone
que esto se usa como reemplazo del antiguo "handle_accept()" y evita
que el usuario llame directamente a "accept()".

(Contribución de Giampaolo Rodolà; bpo-6706.)


tempfile
--------

El módulo "tempfile" tiene un nuevo gestor de contexto,
"TemporaryDirectory" que proporciona una limpieza determinista fácil
de directorios temporales

   con tempfile.TemporaryDirectory() como tmpdirname:
   print('directorio temporal creado:', tmpdirname)

(Contribución de Neil Schemenauer y Nick Coghlan; bpo-5178.)


inspect
-------

* El módulo "inspect" tiene una nueva función "getgeneratorstate()"
  para identificar fácilmente el estado actual de un generador
  iterador:

     >>> de inspeccionar importar obtenergeneratorstate
     >>> def gen():
     ... rendimiento 'demo'
     ...
     >>> g = gen()
     >>> obtenergeneratorstate(g)
     'GEN_CREATED'
     >>> siguiente(g)
     'demo'
     >>> obtenergeneratorstate(g)
     'GEN_SUSPENDED'
     >>> siguiente(g, None)
     >>> obtenergeneratorstate(g)
     'GEN_CLOSED'

  (Contribución de Rodolpho Eckhardt y Nick Coghlan, bpo-10220.)

* Para admitir búsquedas sin la posibilidad de activar un atributo
  dinámico, el módulo "inspect" tiene una nueva función,
  "getattr_static()". A diferencia de "hasattr()", esta es una
  verdadera búsqueda de solo lectura, garantizada que no cambiará de
  estado mientras está buscando:

     >>> clase A:
     ... @property
     ... def f(self):
     ... print('En ejecución')
     ... return 10
     ...
     >>> a = A()
     >>> getattr(a, 'f')
     En ejecución
     10
     >>> inspect.getattr_static(a, 'f')
     <objeto de propiedad en 0x1022bd788>

   (Contribución de Michael Foord.)


pydoc
-----

El módulo "pydoc" ahora proporciona una interfaz de servidor web muy
mejorada, así como una nueva opción de línea de comandos "-b" para
abrir automáticamente una ventana del navegador para mostrar ese
servidor:

   $pydoc3.2-b

(Contribución de Ron Adam; bpo-2001.)


dis
---

El módulo "dis" obtuvo dos nuevas funciones para inspeccionar código,
"code_info()" y "show_code()". Ambas proporcionan información
detallada del objeto de código para la función, método, cadena de
código fuente o objeto de código suministrados. El primero retorna una
cadena de caracteres y el segundo la imprime:

   >>> import dis, random
   >>> dis.show_code(random.choice)
   Nombre: choice
   Nombre de archivo: /Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/random.py
   Número de argumentos: 2
   Argumentos solo de Kw: 0
   Número de variables locales: 3
   Tamaño de pila: 11
   Indicadores: OPTIMIZED, NEWLOCALS, NOFREE
   Constantes:
   0: 'Elija un elemento aleatorio de una secuencia no vacía'.
   1: 'No se puede elegir de una secuencia vacía'
   Nombres:
   0: _randbelow
   1: len
   2: ValueError
   3: IndexError
   Nombres de variables:
   0: self
   1: seq
   2: i

Además, la función "dis()" ahora acepta argumentos de cadena para que
el modismo común "dis(compile(s, '', 'eval'))" se pueda abreviar a
"dis(s)":

   >>> dis('3*x+1 si x%2==1 sino x//2')
   1 0 CARGAR_NOMBRE 0 (x)
   3 CARGAR_CONST 0 (2)
   6 MÓDULO_BINARIO
   7 CARGAR_CONST 1 (1)
   10 COMPARAR_OP 2 (==)
   13 POP_SALTAR_SI_FALSO 28
   16 CARGAR_CONST 2 (3)
   19 CARGAR_NOMBRE 0 (x)
   22 MULTIPLICACIÓN_BINARIA
   23 CARGAR_CONST 1 (1)
   26 SUMA_BINARIA
   27 VALOR_DEVUELTO
   >> 28 CARGAR_NOMBRE 0 (x)
   31 CARGAR_CONST 0 (2)
   34 DIVISIÓN_PISO_BINARIO
   35 VALOR_DEVUELTO

En conjunto, estas mejoras facilitan explorar cómo se implementa
CPython y ver por sí mismo qué hace la sintaxis del lenguaje bajo el
capó.

(Contribución de Nick Coghlan en bpo-9147.)


dbm
---

Todos los módulos de base de datos ahora admiten los métodos "get()" y
"setdefault()".

(Sugerido por Ray Allen en bpo-9523.)


ctypes
------

Un nuevo tipo, "ctypes.c_ssize_t" representa el tipo de datos C
"ssize_t".


site
----

El módulo "site" tiene tres nuevas funciones útiles para informar
sobre los detalles de una determinada instalación de Python.

* "getsitepackages()" enumera todos los directorios de paquetes de
  sitios globales.

* "getuserbase()" informa sobre el directorio base del usuario donde
  se pueden almacenar los datos.

* "getusersitepackages()" revela la ruta del directorio de paquetes de
  sitio específico del usuario.

   >>> importar sitio
   >>> site.getsitepackages()
   ['/Library/Frameworks/Python.framework/Versions/3.2/lib/python3.2/site-packages',
   '/Library/Frameworks/Python.framework/Versions/3.2/lib/site-python',
   '/Library/Python/3.2/site-packages']
   >>> site.getuserbase()
   '/Usuarios/raymondhettinger/Library/Python/3.2'
   >>> site.getusersitepackages()
   '/Usuarios/raymondhettinger/Library/Python/3.2/lib/python/site-packages'

Convenientemente, se puede acceder a algunas de las funciones del
sitio directamente desde la línea de comandos:

   $ python -m site --user-base
   /Usuarios/raymondhettinger/.local
   $ python -m site --user-site
   /Usuarios/raymondhettinger/.local/lib/python3.2/site-packages

(Contribución de Tarek Ziadé en bpo-6693.)


sysconfig
---------

El nuevo módulo "sysconfig" hace que sea sencillo descubrir rutas de
instalación y variables de configuración que varían entre plataformas
e instalaciones.

El módulo ofrece acceso a funciones de acceso simple para información
de plataforma y versión:

* "get_platform()" retornando valores como *linux-i586* o
  *macosx-10.6-ppc*.

* "get_python_version()" retorna una cadena de versión de Python como"
  3.2 ".

También proporciona acceso a las rutas y variables correspondientes a
uno de los siete esquemas con nombre utilizados por "distutils", entre
los que se incluyen *posix_prefix*, *posix_home*, *posix_user*, *nt*,
*nt_user*, *os2* y *os2_home*:

* "get_paths()" crea un diccionario que contiene las rutas de
  instalación para el esquema de instalación actual.

* "get_config_vars()" retorna un diccionario de variables específicas
  de la plataforma.

También hay una conveniente interfaz de línea de comandos:

   C:\Python32>python -m sysconfig
   Plataforma: "win32"
   Versión de Python: "3.2"
   Esquema de instalación actual: "nt"

   Rutas:
   data = "C:\Python32"
   include = "C:\Python32\Include"
   platinclude = "C:\Python32\Include"
   platlib = "C:\Python32\Lib\site-packages"
   platstdlib = "C:\Python32\Lib"
   purelib = "C:\Python32\Lib\site-packages"
   scripts = "C:\Python32\Scripts"
   stdlib = "C:\Python32\Lib"

   Variables:
   BINDIR = "C:\Python32"
   BINLIBDEST = "C:\Python32\Lib"
   EXE = ".exe"
   INCLUDEPY = "C:\Python32\Include"
   LIBDEST = "C:\Python32\Lib"
   SO = ".pyd"
   VERSION = "32"
   abiflags = ""
   base = "C:\Python32"
   exec_prefix = "C:\Python32"
   platbase = "C:\Python32"
   prefix = "C:\Python32"
   projectbase = "C:\Python32"
   py_version = "3.2"
   py_version_nodot = "32"
   py_version_short = "3.2"
   srcdir = "C:\Python32"
   userbase = "C:\Documentos y configuraciones\Raymond\Datos de aplicación\Python"

(Sacado de Distutils por Tarek Ziadé.)


pdb
---

El módulo depurador "pdb" obtuvo una serie de mejoras de usabilidad:

* "pdb.py" ahora tiene una opción "-c" que ejecuta comandos como se
  indica en un archivo de script ".pdbrc".

* Un archivo de secuencia de comandos ".pdbrc" puede contener comandos
  "continue" y "next" que continúan depurando.

* El constructor de la clase "Pdb" ahora acepta un argumento
  *nosigint*.

* Nuevos comandos: "l(list)", "ll(long list)" y "source" para enumerar
  el código fuente.

* Nuevos comandos: "display" y "undisplay" para mostrar u ocultar el
  valor de una expresión si ha cambiado.

* Nuevo comando: "interact" para iniciar un intérprete interactivo que
  contiene los nombres globales y locales que se encuentran en el
  alcance actual.

* Los puntos de interrupción se pueden borrar por número de punto de
  interrupción.

(Contribución de Georg Brandl, Antonio Cuni e Ilya Sandler.)


configparser
------------

El módulo "configparser" se modificó para mejorar la usabilidad y la
previsibilidad del analizador predeterminado y su sintaxis INI
compatible. La antigua clase "ConfigParser" se eliminó en favor de
"SafeConfigParser", que a su vez se renombró como "ConfigParser". La
compatibilidad con comentarios en línea ahora está desactivada de
manera predeterminada y no se permiten secciones u opciones duplicadas
en una única fuente de configuración.

Los analizadores de configuración obtuvieron una nueva API basada en
el protocolo de mapeo:

   >>> parser = ConfigParser()
   >>> parser.read_string("""
   ... [PREDETERMINADO]
   ... ubicación = esquina superior izquierda
   ... visible = sí
   ... editable = no
   ... color = azul
   ...
   ... [principal]
   ... título = Menú principal
   ... color = verde
   ...
   ... [opciones]
   ... título = Opciones
   ... """)
   >>> parser['main']['color']
   'verde'
   >>> parser['main']['editable']
   'no'
   >>> sección = parser['opciones']
   >>> sección['título']
   'Opciones'
   >>> sección['título'] = 'Opciones (editables: %(editables)s)'
   >>> sección['título']
   'Opciones (editables: no)'

La nueva API se implementa sobre la API clásica, por lo que las
subclases de analizadores personalizados deberían poder usarla sin
modificaciones.

La estructura de archivos INI aceptada por los analizadores de
configuración ahora se puede personalizar. Los usuarios pueden
especificar opciones alternativas/delimitadores de valores y prefijos
de comentarios, cambiar el nombre de la sección *DEFAULT* o cambiar la
sintaxis de interpolación.

Hay soporte para la interpolación conectable que incluye un
controlador de interpolación adicional "ExtendedInterpolation":

   >>> parser = ConfigParser(interpolation=ExtendedInterpolation())
   >>> parser.read_dict({'buildout': {'directorio': '/home/ambv/zope9'},
   ... 'personalizado': {'prefijo': '/usr/local'}})
   >>> parser.read_string("""
   ... [buildout]
   ... partes =
   ... zope9
   ... instancia
   ... enlaces-de-busqueda =
   ... ${buildout:directorio}/descargas/dist
   ...
   ... [zope9]
   ... receta = plone.recipe.zope9install
   ... ubicación = /opt/zope
   ...
   ... [instancia]
   ... receta = plone.recipe.zope9instance
   ... ubicación-zope9 = ${zope9:ubicación}
   ... configuración-zope = ${personalizado:prefijo}/etc/zope.conf
   ... """)
   >>> parser['buildout']['find-links']
   '\n/home/ambv/zope9/downloads/dist'
   >>> parser['instancia']['zope-conf']
   '/usr/local/etc/zope.conf'
   >>> instancia = parser['instancia']
   >>> instancia['zope-conf']
   '/usr/local/etc/zope.conf'
   >>> instancia['zope9-location']
   '/opt/zope'

También se introdujeron una serie de características más pequeñas,
como soporte para especificar codificación en operaciones de lectura,
especificar valores de respaldo para funciones de obtención o leer
directamente desde diccionarios y cadenas.

(Todos los cambios aportados por Łukasz Langa.)


urllib.parse
------------

Se realizaron varias mejoras de usabilidad para el módulo
"urllib.parse".

La función "urlparse()" ahora admite direcciones IPv6 como se describe
en **RFC 2732**:

>>> import urllib.parse
>>> urllib.parse.urlparse('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/')
ParseResult(scheme='http',
            netloc='[dead:beef:cafe:5417:affe:8FA3:deaf:feed]',
            path='/foo/',
            params='',
            query='',
            fragment='')

La función "urldefrag()" ahora devuelve un *named tuple*:

   >>> r = urllib.parse.urldefrag('http://python.org/about/#target')
   >>> r
   DefragResult(url='http://python.org/about/', fragment='target')
   >>> r[0]
   'http://python.org/about/'
   >>> r.fragment
   'target'

Y, la función "urlencode()" ahora es mucho más flexible, aceptando un
tipo de cadena o bytes para el argumento *query*. Si es una cadena,
entonces los parámetros *safe*, *encoding* y *error* se envían a
"quote_plus()" para codificar:

   >>> urllib.parse.urlencode([
   ... ('tipo', 'telenovela'),
   ... ('nombre', '¿Dónde Está Elisa?')],
   ... codificación = 'latin-1')
   'tipo=telenovela&nombre=%BFD%F3nde+Est%E1+Elisa%3F'

Como se detalla en Análisis de bytes codificados ASCII, todas las
funciones "urllib.parse" ahora aceptan cadenas de bytes codificadas en
ASCII como entrada, siempre que no estén mezcladas con cadenas
normales. Si se proporcionan cadenas de bytes codificadas en ASCII
como parámetros, los tipos de retorno también serán cadenas de bytes
codificadas en ASCII:

>>> urllib.parse.urlparse(b'http://www.python.org:80/about/')
ParseResultBytes(scheme=b'http', netloc=b'www.python.org:80',
                 path=b'/about/', params=b'', query=b'', fragment=b'')

(Trabajo de Nick Coghlan, Dan Mahn y Senthil Kumaran en bpo-2987,
bpo-5468, y bpo-9873.)


mailbox
-------

Gracias a un esfuerzo concertado de R. David Murray, el módulo
"mailbox" se ha corregido para Python 3.2. El desafío era que el buzón
había sido diseñado originalmente con una interfaz de texto, pero los
mensajes de correo electrónico se representan mejor con "bytes" porque
varias partes de un mensaje pueden tener diferentes codificaciones.

La solución aprovechó el soporte binario de los paquete "email" para
analizar mensajes de correo electrónico arbitrarios. Además, la
solución requirió una serie de cambios en la API.

Como era de esperar, el método "add()" para los objetos
"mailbox.Mailbox" ahora acepta entrada binaria.

"StringIO" y la entrada del archivo de texto están en desuso. Además,
la entrada de cadenas fallará antes si se utilizan caracteres que no
sean ASCII. Anteriormente, fallaba cuando el correo electrónico se
procesaba en un paso posterior.

También hay soporte para salida binaria. El método "get_file()" ahora
devuelve un archivo en modo binario (donde solía configurar
incorrectamente el archivo en modo texto). También hay un nuevo método
"get_bytes()" que devuelve una representación "bytes" de un mensaje
correspondiente a una *key* dada.

Todavía es posible obtener una salida no binaria usando el método de
la API anterior "get_string()", pero ese enfoque no es muy útil. En su
lugar, es mejor extraer mensajes de un objeto "Message" o cargarlos
desde una entrada binaria.

(Contribuido por R. David Murray, con esfuerzos de Steffen Daode
Nurpmeso y un parche inicial de Victor Stinner en bpo-9124.)


turtledemo
----------

El código de demostración del módulo "turtle" se trasladó del
directorio *Demo* a la biblioteca principal. Incluye más de una docena
de scripts de muestra con visualizaciones dinámicas. Al estar en
"sys.path", ahora se puede ejecutar directamente desde la línea de
comandos:

   $ python -m turtledemo

(Movido del directorio Demo por Alexander Belopolsky en bpo-10199.)


Multi-threading
===============

* Se ha reescrito el mecanismo para serializar la ejecución de
  subprocesos de Python que se ejecutan simultáneamente (generalmente
  conocido como *GIL* o Global Interpreter Lock). Entre los objetivos
  se encontraban intervalos de conmutación más predecibles y una
  reducción de la sobrecarga debido a la contención de bloqueos y la
  cantidad de llamadas al sistema resultantes. Se ha abandonado la
  noción de un "intervalo de verificación" para permitir cambios de
  subproceso y se ha reemplazado por una duración absoluta expresada
  en segundos. Este parámetro se puede ajustar a través de
  "sys.setswitchinterval()". Actualmente, el valor predeterminado es 5
  milisegundos.

  Se pueden leer detalles adicionales sobre la implementación en un
  mensaje de lista de correo python-dev mailing-list message (sin
  embargo, "prioridad las solicitudes" como se expone en este mensaje
  no se han mantenido para su inclusión).

  (Contribución de Antoine Pitrou.)

* Los bloqueos regulares y recursivos ahora aceptan un argumento
  opcional *timeout* para su método "acquire()" . (Contribución de
  Antoine Pitrou; bpo-7316.)

* De manera similar, "threading.Semaphore.acquire()" también ganó un
  argumento *timeout*. (Contribución de Torsten Landschoff;
  bpo-850728.)

* Las adquisiciones de bloqueos regulares y recursivas ahora pueden
  ser interrumpidas por señales en plataformas que usan Pthreads. Esto
  significa que los programas de Python que se bloquean mientras
  adquieren bloqueos pueden eliminarse con éxito enviando
  repetidamente SIGINT al proceso (presionando "Ctrl"+"C" en la
  mayoría de los shells). (Contribuido por Reid Kleckner; bpo-8844.)


Optimizations
=============

Se han agregado una serie de pequeñas mejoras de rendimiento:

* El optimizador de mirilla de Python ahora reconoce patrones como "x
  in {1, 2, 3}" como una prueba de pertenencia a un conjunto de
  constantes. El optimizador reformula "set" como "frozenset" y
  almacena la constante preconstruida.

  Ahora que la penalización de velocidad se ha ido, es práctico
  comenzar a escribir pruebas de membresía usando notación de
  conjuntos. Este estilo es semánticamente claro y operativamente
  rápido:

     extensión = nombre.rpartition('.')[2]
     si extensión en {'xml', 'html', 'xhtml', 'css'}:
     handle(nombre)

  (Parche y pruebas adicionales aportadas por Dave Malcolm; bpo-6690).

* Serializar y deserializar datos usando el módulo "pickle" ahora es
  varias veces más rápido.

  (Contribución de Alexandre Vassalotti, Antoine Pitrou y el equipo de
  Unladen Swallow en bpo-9410 y bpo-3873.)

* El algoritmo Timsort algorithm usado en "list.sort()" y "sorted()"
  ahora se ejecuta más rápido y usa menos memoria cuando se llama con
  *key function*. Anteriormente, cada elemento de una lista se
  envolvía con un objeto temporal que recordaba el valor clave
  asociado con cada elemento. Ahora, dos matrices de claves y valores
  se ordenan en paralelo. Esto ahorra la memoria consumida por los
  contenedores de clasificación y ahorra el tiempo perdido al delegar
  comparaciones.

  (Parche de Daniel Stutzbach en bpo-9915.)

* El rendimiento de la decodificación JSON mejora y el consumo de
  memoria se reduce siempre que se repite la misma cadena para varias
  claves. Además, la codificación JSON ahora usa las aceleraciones de
  C cuando el argumento "sort_keys" es verdadero.

  (Contribución de Antoine Pitrou en bpo-7451 y Raymond Hettinger y
  Antoine Pitrou en bpo-10314.)

* Los bloqueos recursivos (creados con la API "threading.RLock()")
  ahora se benefician de una implementación de C que los hace tan
  rápidos como los bloqueos normales, y entre 10 y 15 veces más
  rápidos que su anterior implementación pura de Python.

  (Contribución de Antoine Pitrou; bpo-3001.)

* El algoritmo de búsqueda rápida de stringlib ahora lo utilizan los
  métodos "split()", "rsplit()", "splitlines()" y "replace()" en los
  objetos "bytes", "bytearray" y "str". Asimismo, el algoritmo también
  lo utilizan "rfind()", "rindex()", "rsplit()" y "rpartition()".

  (Parche de Florent Xicluna en bpo-7622 y bpo-7462.)

* Las conversiones de enteros a cadenas de caracteres ahora funcionan
  con dos "dígitos" a la vez, lo que reduce el número de operaciones
  de división y módulo.

  (bpo-6713 de Gawain Bolton, Mark Dickinson y Victor Stinner.)

Se realizaron otras optimizaciones menores. La diferenciación de
conjuntos ahora se ejecuta más rápido cuando un operando es mucho más
grande que el otro (parche de Andress Bennetts en bpo-8685). El método
"array.repeat()" tiene una implementación más rápida (bpo-1569291 de
Alexander Belopolsky). El "BaseHTTPRequestHandler" tiene un
almacenamiento en búfer más eficiente (bpo-3709 de Andrew Schaaf). La
función "operator.attrgetter()" se ha acelerado (bpo-10160 de Christos
Georgiou). Y "ConfigParser" carga argumentos de varias líneas un poco
más rápido (bpo-7113 de Łukasz Langa).


Unicode
=======

Python se ha actualizado a Unicode 6.0.0. La actualización del
estándar agrega más de 2000 caracteres nuevos, incluidos los símbolos
emoji que son importantes para los teléfonos móviles.

Además, el estándar actualizado modificó las propiedades de dos
caracteres de Kannada (U+0CF1, U+0CF2) y un carácter numérico New Tai
Lue (U+19DA), lo que hace que el primero sea elegible para su uso en
identificadores y descalifica al segundo. Para obtener más
información, consulte Unicode Character Database Changes.


Codecs
======

Se agregó soporte para *cp720* codificación DOS árabe (bpo-1616979).

La codificación MBCS ya no ignora el argumento del controlador de
errores. En el modo estricto predeterminado, genera un
"UnicodeDecodeError" cuando encuentra una secuencia de bytes no
codificable y un "UnicodeEncodeError" para un carácter no codificable.

El códec MBCS admite los controladores de errores "'strict'" e
"'ignore'" para la decodificación y "'strict'" y "'replace'" para la
codificación.

Para emular la codificación Python3.1 MBCS, seleccione el controlador
"'ignore'" para decodificar y el controlador "'replace'" para
codificar.

En Mac OS X, Python decodifica los argumentos de la línea de comandos
con "'utf-8'" en lugar de la codificación local.

De forma predeterminada, "tarfile" usa la codificación "'utf-8'" en
Windows (en lugar de "'mbcs'") y el controlador de errores
"'surrogateescape'" en todos los sistemas operativos.


Documentación
=============

La documentación sigue mejorando.

* Se ha agregado una tabla de enlaces rápidos en la parte superior de
  secciones largas como Funciones incorporadas. En el caso de
  "itertools", los enlaces están acompañados de tablas de resúmenes al
  estilo de una hoja de trucos para proporcionar una descripción
  general y un cambio de memoria sin tener que leer todos los
  documentos.

* En algunos casos, el código fuente puro de Python puede ser un
  complemento útil de la documentación, por lo que ahora muchos
  módulos incluyen enlaces rápidos a la última versión del código
  fuente. Por ejemplo, la documentación del módulo "functools" tiene
  un enlace rápido en la parte superior etiquetado:

     **Código fuente** Lib/functools.py.

  (Contribuido por Raymond Hettinger; ver rationale.)

* Los documentos ahora contienen más ejemplos y recetas. En
  particular, el módulo "re" tiene una sección extensa, Regular
  expression examples. Asimismo, el módulo "itertools" continúa siendo
  actualizado con nuevo Fórmulas con itertools.

* El módulo "datetime" ahora tiene una implementación auxiliar en
  Python puro. No se modificó ninguna funcionalidad. Esto solo
  proporciona una implementación alternativa más fácil de leer.

  (Contribuido por Alexander Belopolsky en bpo-9528.)

* Se ha eliminado el directorio no mantenido "Demo". Algunas
  demostraciones se integraron en la documentación, otras se movieron
  al directorio "Tools/demo" y otras se eliminaron por completo.

  (Contribución de Georg Brandl en bpo-7962.)


IDLE
====

* El menú de formato ahora tiene una opción para limpiar archivos de
  origen eliminando los espacios en blanco finales.

  (Contribución de Raymond Hettinger; bpo-5150.)

* IDLE en Mac OS X ahora funciona con Carbon AquaTk y Cocoa AquaTk.

  (Contribución de Kevin Walzer, Ned Deily y Ronald Oussoren;
  bpo-6075.)


Repositorio de código
=====================

Además del repositorio de código Subversion existente en
https://svn.python.org, ahora hay un repositorio Mercurial en
https://hg.python.org/.

Después de la versión 3.2, hay planes para cambiar a Mercurial como
repositorio principal. Este sistema de control de versiones
distribuido debería facilitar a los miembros de la comunidad la
creación y el intercambio de conjuntos de cambios externos. Consulte
**PEP 385** para obtener más detalles.

Para aprender a utilizar el nuevo sistema de control de versiones,
consulte el Quick Start o la Guide to Mercurial Workflows.


Cambios en la API de construcción y C
=====================================

Los cambios en el proceso de compilación de Python y en la API de C
incluyen:

* Los scripts *idle*, *pydoc* y *2to3* ahora están instalados con un
  sufijo específico de la versión en "make altinstall" (bpo-10679).

* Las funciones C que acceden a la base de datos Unicode ahora aceptan
  y retornan caracteres del rango Unicode completo, incluso en
  compilaciones Unicode estrechas (Py_UNICODE_TOLOWER,
  Py_UNICODE_ISDECIMAL, y otras). Una diferencia visible en Python es
  que "unicodedata.numeric()" ahora devuelve el valor correcto para
  puntos de código grandes y "repr()" puede considerar más caracteres
  como imprimibles.

  (Informado por Bupjoe Lee y corregido por Amaury Forgeot D'Arc;
  bpo-5127.)

* Los gotos calculados ahora están habilitados de forma predeterminada
  en los compiladores compatibles (que son detectados por el script de
  configuración). Todavía se pueden desactivar de forma selectiva
  especificando "--without-computed-gotos".

  (Contribución de Antoine Pitrou; bpo-9203.)

* Se eliminó la opción "--with-wctype-functions". La base de datos
  unicode incorporada ahora se usa para todas las funciones.

  (Contribución de Amaury Forgeot D'Arc; bpo-9210.)

* Los valores hash ahora son valores de un nuevo tipo, "Py_hash_t",
  que se define como del mismo tamaño que un puntero. Anteriormente
  eran del tipo long, que en algunos sistemas operativos de 64 bits
  todavía tiene una longitud de solo 32 bits. Como resultado de esta
  corrección, "set" y "dict" ahora pueden contener más de "2**32"
  entradas en compilaciones con punteros de 64 bits (anteriormente,
  podían crecer hasta ese tamaño pero su desempeño se degradaba
  catastróficamente).

  (Sugerido por Raymond Hettinger e implementado por Benjamin
  Peterson; bpo-9778.)

* Una nueva macro "Py_VA_COPY" copia el estado de la lista de
  argumentos de la variable. Es equivalente a C99 *va_copy* pero está
  disponible en todas las plataformas Python (bpo-2443).

* Una nueva función API C "PySys_SetArgvEx()" permite que un
  intérprete integrado configure "sys.argv" sin modificar también
  "sys.path" (bpo-5753).

* "PyEval_CallObject()" ahora solo está disponible en formato macro.
  La declaración de función, que se mantuvo por razones de
  compatibilidad con versiones anteriores, se ha eliminado: la macro
  se introdujo en 1997 (bpo-8276).

* Hay una nueva función "PyLong_AsLongLongAndOverflow()" que es
  análoga a "PyLong_AsLongAndOverflow()". Ambos sirven para convertir
  Python "int" en un tipo nativo de ancho fijo al tiempo que brindan
  detección de casos en los que la conversión no encaja (bpo-7767).

* La función "PyUnicode_CompareWithASCIIString()" ahora devuelve *not
  equal* si la cadena de Python es *NUL* terminada.

* Hay una nueva función "PyErr_NewExceptionWithDoc()" que es como
  "PyErr_NewException()" pero permite especificar una cadena de
  documentos. Esto permite que las excepciones de C tengan las mismas
  capacidades de auto-documentación que sus contrapartes de Python
  puro (bpo-7033).

* Cuando se compila con la opción "--with-valgrind", el asignador de
  pymalloc se desactivará automáticamente cuando se ejecute en
  Valgrind. Esto brinda una detección mejorada de fugas de memoria
  cuando se ejecuta en Valgrind, mientras se aprovecha pymalloc en
  otros momentos (bpo-2422).

* Se eliminó el formato "O?" De las funciones *PyArg_Parse*. El
  formato ya no se usa y nunca se había documentado (bpo-8837).

Hubo una serie de otros pequeños cambios en la C-API. Consulte el
archivo Misc/NEWS para obtener una lista completa.

Además, se realizaron varias actualizaciones en la compilación de Mac
OS X; consulte Mac/BuildScript/README.txt para obtener más detalles.
Para los usuarios que ejecutan una compilación de 32/64 bits, existe
un problema conocido con el Tcl/Tk predeterminado en Mac OS X 10.6. En
consecuencia, recomendamos instalar una alternativa actualizada como
ActiveState Tcl/Tk 8.5.9. Consulte
https://www.python.org/download/mac/tcltk/ para obtener más detalles.


Portar a Python 3.2
===================

Esta sección enumera los cambios descritos anteriormente y otras
correcciones de errores que pueden requerir cambios en su código:

* El módulo "configparser" tiene una serie de mejoras. El cambio
  principal es reemplazar la antigua clase "ConfigParser" por la
  alternativa preferida de larga data "SafeConfigParser". Además, hay
  una serie de incompatibilidades menores:

  * La sintaxis de interpolación ahora está validada en las
    operaciones "get()" y "set()". En el esquema de interpolación
    predeterminado, solo dos tokens con signos de porcentaje son
    válidos: "%(name)s" y "%%", siendo este último un signo de
    porcentaje de escape.

  * Los métodos "set()" y "add_section()"  ahora verifican que los
    valores sean cadenas reales. Anteriormente, los tipos no admitidos
    podían introducirse involuntariamente.

  * Las secciones u opciones duplicadas de una sola fuente ahora
    generan "DuplicateSectionError" o "DuplicateOptionError".
    Anteriormente, los duplicados sobrescribían silenciosamente una
    entrada anterior.

  * Los comentarios en línea ahora están deshabilitados de forma
    predeterminada, por lo que ahora el carácter **;** se puede usar
    de forma segura en los valores.

  * Los comentarios ahora se pueden sangrar. En consecuencia, para que
    **;** o **#** aparezcan al principio de una línea en valores
    multilínea, debe interpolarse. Esto evita que los caracteres de
    prefijo de comentario en valores se confundan con comentarios.

  * """" ahora es un valor válido y ya no se convierte automáticamente
    en una cadena vacía. Para cadenas vacías, use ""option ="" en una
    línea.

* El módulo "nntplib" fue rediseñado ampliamente, lo que significa que
  sus API a menudo son incompatibles con las API 3.1.

* "bytearray" ya no se pueden usar como nombres de archivo; en su
  lugar, deben convertirse a "bytes".

* Los nombres "array.tostring()" y "array.fromstring()" se han
  cambiado a "array.tobytes()" y "array.frombytes()" para mayor
  claridad. Los nombres antiguos han quedado obsoletos. (Consulte
  bpo-8990).

* Funciones "PyArg_Parse*()":

  * Se ha eliminado el formato "t#": utilice "s#" o "s*" en su lugar

  * Se han eliminado los formatos "w" y "w #": utilice "w*" en su
    lugar

* Se ha eliminado el tipo "PyCObject", que quedó obsoleto en la
  versión 3.1. Para encapsular punteros C opacos en objetos Python, se
  debe utilizar la API "PyCapsule"; el nuevo tipo tiene una interfaz
  bien definida para pasar información de seguridad de tipado y una
  firma menos complicada para llamar a un destructor.

* La función "sys.setfilesystemencoding()" se eliminó porque tenía un
  diseño defectuoso.

* La función y el método "random.seed()" ahora saltan semillas de
  cadenas con una función hash sha512. Para acceder a la versión
  anterior de *seed* para reproducir secuencias de Python 3.1,
  establezca el argumento *version* en *1*, "random.seed(s,
  version=1)".

* La función "string.maketrans()", que anteriormente estaba en desuso,
  se ha eliminado en favor de los métodos estáticos
  "bytes.maketrans()" y "bytearray.maketrans()". Este cambio resuelve
  la confusión sobre qué tipos eran compatibles con el módulo
  "string". Ahora, "str", "bytes" y "bytearray" tienen sus propios
  métodos **maketrans** y **translate** con tablas de traducción
  intermedias del tipo adecuado.

  (Contribución de Georg Brandl; bpo-5675.)

* La función "contextlib.nested()", que anteriormente estaba en
  desuso, se ha eliminado en favor de una declaración "with" simple
  que puede aceptar múltiples administradores de contexto. La última
  técnica es más rápida (porque está incorporada) y hace un mejor
  trabajo al finalizar múltiples administradores de contexto cuando
  uno de ellos genera una excepción:

     con open('mylog.txt') como archivo de entrada, open('a.out', 'w') como archivo de salida:
     para línea en archivo de entrada:
     si '<critical>' está en línea:
     archivo de salida.write(línea)

  (Contribución de Georg Brandl y Mattias Brändström; appspot issue
  53094.)

* "struct.pack()" ahora permite bytes para el código del paquete de
  cadenas "s". Anteriormente, aceptaba argumentos de texto y los
  codificaba implícitamente en bytes usando UTF-8. Esto era
  problemático porque hacía suposiciones sobre la codificación
  correcta y porque una codificación de longitud variable puede fallar
  al escribir en un segmento de longitud fija de una estructura.

  El código como "struct.pack('<6sHHBBB', 'GIF87a', x, y)" debe
  reescribirse para usar bytes en lugar de texto,
  "struct.pack('<6sHHBBB', b'GIF87a', x, y)".

  (Descubierto por David Beazley y corregido por Victor Stinner;
  bpo-10783.)

* La clase "xml.etree.ElementTree" ahora genera un
  "xml.etree.ElementTree.ParseError" cuando falla un análisis.
  Anteriormente generaba un "xml.parsers.expat.ExpatError".

* El nuevo valor más largo de "str()" en flotantes puede romper las
  pruebas de documentación que se basan en el formato de salida
  anterior.

* En "subprocess.Popen", el valor predeterminado para *close_fds* es
  ahora "True" en Unix; en Windows, es "True" si los tres flujos
  estándar están configurados como "None", o "False" en caso
  contrario. Anteriormente, *close_fds* siempre era "False" de forma
  predeterminada, lo que producía errores difíciles de resolver o
  condiciones de carrera cuando los descriptores de archivos abiertos
  se filtraban en el proceso hijo.

* Se ha eliminado la compatibilidad con HTTP 0.9 heredado de
  "urllib.request" y "http.client". Dicho soporte todavía está
  presente en el lado del servidor (en "http.server").

  (Contribución de Antoine Pitrou, bpo-10711.)

* Los sockets SSL en modo de tiempo de espera ahora generan
  "socket.timeout" cuando ocurre un tiempo de espera, en lugar de un
  genérico "SSLError".

  (Contribución de Antoine Pitrou, bpo-10272.)

* Las funciones engañosas "PyEval_AcquireLock()" y
  "PyEval_ReleaseLock()" han quedado oficialmente obsoletas. En su
  lugar, se deben utilizar las API que reconocen el estado del
  subproceso (como "PyEval_SaveThread()" y "PyEval_RestoreThread()").

* Debido a riesgos de seguridad, "asyncore.handle_accept()" ha quedado
  obsoleto y se agregó una nueva función,
  "asyncore.handle_accepted()", para reemplazarlo.

  (Contribución de Giampaolo Rodola en bpo-6706.)

* Debido a la nueva implementación de *GIL*, ya no se puede llamar a
  "PyEval_InitThreads()" antes que a "Py_Initialize()".
