Nota

¡Ayúdanos a traducir la documentación oficial de Python al Español! Puedes encontrar más información en Como contribuir. Ayuda a acercar Python a más personas de habla hispana.

Novedades en Python 3.11

Versión

3.11.0

Fecha

diciembre 02, 2022

Editor

Pablo Galindo Salgado

Este artículo explica las nuevas características de Python 3.11, en comparación con 3.10.

Para obtener detalles completos, consulte changelog.

Resumen – Aspectos destacados de la versión

  • Python 3.11 es entre un 10 y un 60 % más rápido que Python 3.10. En promedio, medimos un aumento de velocidad de 1.25x en el conjunto de pruebas de referencia estándar. Ver CPython más rápido para más detalles.

Nuevas funciones de sintaxis:

Nuevas funciones integradas:

Nuevos módulos de biblioteca estándar:

Mejoras en el intérprete:

Nuevas funciones de escritura:

Importantes depreciaciones, eliminaciones y restricciones:

Nuevas características

PEP 657: Ubicaciones de errores detallados en rastreos

Al imprimir rastreos, el intérprete ahora señalará la expresión exacta que causó el error, en lugar de solo la línea. Por ejemplo:

Traceback (most recent call last):
  File "distance.py", line 11, in <module>
    print(manhattan_distance(p1, p2))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "distance.py", line 6, in manhattan_distance
    return abs(point_1.x - point_2.x) + abs(point_1.y - point_2.y)
                           ^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'x'

Las versiones anteriores del intérprete apuntaban solo a la línea, por lo que resultaba ambiguo qué objeto era None. Estos errores mejorados también pueden ser útiles cuando se trata de objetos dict profundamente anidados y múltiples llamadas a funciones:

Traceback (most recent call last):
  File "query.py", line 37, in <module>
    magic_arithmetic('foo')
  File "query.py", line 18, in magic_arithmetic
    return add_counts(x) / 25
           ^^^^^^^^^^^^^
  File "query.py", line 24, in add_counts
    return 25 + query_user(user1) + query_user(user2)
                ^^^^^^^^^^^^^^^^^
  File "query.py", line 32, in query_user
    return 1 + query_count(db, response['a']['b']['c']['user'], retry=True)
                               ~~~~~~~~~~~~~~~~~~^^^^^
TypeError: 'NoneType' object is not subscriptable

Además de expresiones aritméticas complejas:

Traceback (most recent call last):
  File "calculation.py", line 54, in <module>
    result = (x / y / z) * (a / b / c)
              ~~~~~~^~~
ZeroDivisionError: division by zero

Además, la información utilizada por la función de rastreo mejorada está disponible a través de una API general, que se puede usar para correlacionar bytecode instructions con la ubicación del código fuente. Esta información se puede recuperar usando:

Ver PEP 657 para más detalles. (Aportado por Pablo Galindo, Batuhan Taskaya y Ammar Askar en bpo-43950.)

Nota

Esta característica requiere almacenar las posiciones de las columnas en Objetos Código, lo que puede resultar en un pequeño aumento en el uso de la memoria del intérprete y el uso del disco para los archivos de Python compilados. Para evitar almacenar la información adicional y desactivar la impresión de la información de seguimiento adicional, utilice la opción de línea de comando -X no_debug_ranges o la variable de entorno PYTHONNODEBUGRANGES.

PEP 654: Grupos de excepción y except*

PEP 654 presenta funciones de lenguaje que permiten que un programa genere y maneje múltiples excepciones no relacionadas simultáneamente. Los tipos integrados ExceptionGroup y BaseExceptionGroup permiten agrupar excepciones y generarlas juntas, y la nueva sintaxis except* generaliza except para hacer coincidir subgrupos de grupos de excepciones.

Ver PEP 654 para más detalles.

(Aportado por Irit Katriel en bpo-45292. PEP escrito por Irit Katriel, Yury Selivanov y Guido van Rossum.)

PEP 678: Las excepciones se pueden enriquecer con notas

El método add_note() se agrega a BaseException. Se puede utilizar para enriquecer las excepciones con información de contexto que no está disponible en el momento en que se genera la excepción. Las notas añadidas aparecen en el rastreo predeterminado.

Ver PEP 678 para más detalles.

(Aportado por Irit Katriel en bpo-45607. PEP escrito por Zac Hatfield-Dodds).

Mejoras en el iniciador de Windows py.exe

La copia de Lanzador de Python para Windows incluida con Python 3.11 se ha actualizado significativamente. Ahora es compatible con la sintaxis de empresa/etiqueta tal como se define en PEP 514 utilizando el argumento -V:<company>/<tag> en lugar del -<major>.<minor> limitado. Esto permite lanzar distribuciones distintas a PythonCore, la que está alojada en python.org.

Al usar los selectores -V:, se puede omitir la empresa o la etiqueta, pero se buscarán todas las instalaciones. Por ejemplo, -V:OtherPython/ seleccionará la «mejor» etiqueta registrada para OtherPython, mientras que -V:3.11 o -V:/3.11 seleccionarán la «mejor» distribución con la etiqueta 3.11.

Al usar los argumentos heredados -<major>, -<major>.<minor>, -<major>-<bitness> o -<major>.<minor>-<bitness>, se debe conservar todo el comportamiento existente de las versiones anteriores y solo se seleccionarán las versiones de PythonCore. Sin embargo, el sufijo -64 ahora implica «no de 32 bits» (no necesariamente x86-64), ya que existen múltiples plataformas de 64 bits compatibles. Los tiempos de ejecución de 32 bits se detectan comprobando la etiqueta del tiempo de ejecución en busca de un sufijo -32. Todas las versiones de Python desde la 3.5 han incluido esto en sus compilaciones de 32 bits.

Otros cambios de idioma

  • Se agregó una opción de línea de comando -P y una variable de entorno PYTHONSAFEPATH, que deshabilitan la anteposición automática a sys.path del directorio del script cuando se ejecuta un script, o el directorio actual cuando se usa -c y -m. Esto garantiza que import solo recopile la biblioteca estándar y los módulos instalados, y evita el remedo involuntario o malicioso de los módulos con los de un directorio local (y normalmente el usuario puede escribir). (Aportado por Victor Stinner en gh-57684.)

  • Se agregó una opción "z" a Especificación de formato Mini-Lenguaje que cambia negativo a cero positivo después de redondear a la precisión del formato. Ver PEP 682 para más detalles. (Aportado por John Belmonte en gh-90153.)

  • Ya no se aceptan bytes en sys.path. El soporte se interrumpió en algún momento entre Python 3.2 y 3.6, y nadie se dio cuenta hasta después del lanzamiento de Python 3.10.0. Además, recuperar la compatibilidad sería problemático debido a las interacciones entre -b y sys.path_importer_cache cuando hay una combinación de claves str y bytes. (Aportado por Thomas Grainger en gh-91181.)

Otros cambios en la implementación de CPython

  • Los métodos especiales __complex__() para complex y __bytes__() para bytes se implementan para admitir los protocolos typing.SupportsComplex y typing.SupportsBytes. (Aportado por Mark Dickinson y Dong-hee Na en bpo-24234).

  • siphash13 se agrega como un nuevo algoritmo hash interno. Tiene propiedades de seguridad similares a siphash24, pero es un poco más rápido para entradas largas. str, bytes y algunos otros tipos ahora lo usan como algoritmo predeterminado para hash(). PEP 552 hash-based .pyc files ahora también usa siphash13. (Aportado por Inada Naoki en bpo-29410.)

  • Cuando una declaración raise sin parámetros vuelve a generar una excepción activa, el rastreo adjunto a esta excepción ahora siempre es sys.exc_info()[1].__traceback__. Esto significa que los cambios realizados en el rastreo en la cláusula except actual se reflejan en la excepción que se ha vuelto a generar. (Aportado por Irit Katriel en bpo-45711.)

  • La representación del estado del intérprete de las excepciones manejadas (también conocido como exc_info o _PyErr_StackItem) ahora solo tiene el campo exc_value; Se han eliminado exc_type y exc_traceback, ya que se pueden derivar de exc_value. (Aportado por Irit Katriel en bpo-45711.)

  • Se ha agregado un nuevo command line option, AppendPath, para el instalador de Windows. Se comporta de manera similar a PrependPath, pero agrega los directorios de instalación y scripts en lugar de anteponerlos. (Aportado por Bastian Neuburger en bpo-44934.)

  • El campo PyConfig.module_search_paths_set ahora debe establecerse en 1 para que la inicialización use PyConfig.module_search_paths para inicializar sys.path. De lo contrario, la inicialización volverá a calcular la ruta y reemplazará los valores agregados a module_search_paths.

  • La salida de la opción --help ahora cabe en 50 líneas/80 columnas. La información sobre las opciones Python environment variables y -X ahora está disponible utilizando los indicadores respectivos --help-env y --help-xoptions, y con el nuevo --help-all. (Contribución de Éric Araujo en bpo-46142.)

  • La conversión entre int y str en bases que no sean 2 (binario), 4, 8 (octal), 16 (hexadecimal) o 32 como base 10 (decimal) ahora genera un ValueError si el número de dígitos en forma de cadena es superior a un límite para evitar posibles ataques de denegación de servicio debido a la complejidad algorítmica. Esta es una mitigación para CVE-2020-10735. Este límite se puede configurar o deshabilitar mediante la variable de entorno, el indicador de línea de comando o las API sys. Consulte la documentación de integer string conversion length limitation. El límite predeterminado es de 4300 dígitos en forma de cadena.

Nuevos Módulos

Módulos mejorados

asíncio

contextlib

Se agregó un administrador de contexto chdir() no seguro en paralelo para cambiar el directorio de trabajo actual y luego restaurarlo al salir. Envoltorio simple alrededor de chdir(). (Aportación de Filipe Laíns en bpo-25625)

clases de datos

  • Cambie la verificación de mutabilidad predeterminada del campo, permitiendo solo los valores predeterminados que son hashable en lugar de cualquier objeto que no sea una instancia de dict, list o set. (Aportado por Eric V. Smith en bpo-44674.)

fecha y hora

enumeración

  • Cambió el nombre de EnumMeta a EnumType (EnumMeta se mantuvo como un alias).

  • Se agregó StrEnum, con miembros que se pueden usar como (y deben ser) cadenas.

  • Se agregó ReprEnum, que solo modifica el __repr__() de los miembros mientras devuelve sus valores literales (en lugar de nombres) para __str__() y __format__() (utilizados por str(), format() y f-strings).

  • Se cambiaron IntEnum, IntFlag y StrEnum para heredar ahora de ReprEnum, por lo que su salida str() ahora coincide con format() (tanto str(AnIntEnum.ONE) como format(AnIntEnum.ONE) devuelven '1', mientras que antes str(AnIntEnum.ONE) devolvía 'AnIntEnum.ONE'.

  • Se modificó Enum.__format__() (el valor predeterminado para format(), str.format() y f-strings) de enumeraciones con tipos combinados (por ejemplo, int, str) para incluir también el nombre de la clase en la salida, no solo la clave del miembro. Esto coincide con el comportamiento existente de enum.Enum.__str__(), devolviendo, p. 'AnEnum.MEMBER' para una enumeración AnEnum(str, Enum) en lugar de solo 'MEMBER'.

  • Se agregó un nuevo parámetro de clase boundary a las enumeraciones Flag y la enumeración FlagBoundary con sus opciones, para controlar cómo manejar los valores de marca fuera de rango.

  • Se agregó el decorador de enumeración verify() y la enumeración EnumCheck con sus opciones, para verificar las clases de enumeración contra varias restricciones específicas.

  • Se agregaron los decoradores member() y nonmember() para garantizar que el objeto decorado no se convierta en un miembro de enumeración.

  • Se agregó el decorador property(), que funciona como property() excepto para las enumeraciones. Use esto en lugar de types.DynamicClassAttribute().

  • Se agregó el decorador de enumeración global_enum(), que ajusta __repr__() y __str__() para mostrar valores como miembros de su módulo en lugar de la clase de enumeración. Por ejemplo, 're.ASCII' para el miembro ASCII de re.RegexFlag en lugar de 'RegexFlag.ASCII'.

  • Flag mejorado para admitir len(), iteración y in/not in en sus miembros. Por ejemplo, ahora funciona lo siguiente: len(AFlag(3)) == 2 and list(AFlag(3)) == (AFlag.ONE, AFlag.TWO)

  • Se cambiaron Enum y Flag para que los miembros ahora se definan antes de llamar a __init_subclass__(); dir() ahora incluye métodos, etc., de tipos de datos combinados.

  • Se modificó Flag para considerar solo los valores primarios (potencia de dos) canónicos, mientras que los valores compuestos (3, 6, 10, etc.) se consideran alias; las banderas invertidas son forzadas a su equivalente positivo.

fracciones

  • Compatibilidad con la inicialización al estilo PEP 515 de Fraction desde una cadena. (Aportado por Sergey B Kirpichev en bpo-44258.)

  • Fraction ahora implementa un método __int__, de modo que pasa una verificación isinstance(some_fraction, typing.SupportsInt). (Contribuido por Mark Dickinson en bpo-44547.)

herramientas funcionales

  • functools.singledispatch() ahora admite types.UnionType y typing.Union como anotaciones en el argumento de envío.:

    >>> from functools import singledispatch
    >>> @singledispatch
    ... def fun(arg, verbose=False):
    ...     if verbose:
    ...         print("Let me just say,", end=" ")
    ...     print(arg)
    ...
    >>> @fun.register
    ... def _(arg: int | float, verbose=False):
    ...     if verbose:
    ...         print("Strength in numbers, eh?", end=" ")
    ...     print(arg)
    ...
    >>> from typing import Union
    >>> @fun.register
    ... def _(arg: Union[list, set], verbose=False):
    ...     if verbose:
    ...         print("Enumerate this:")
    ...     for i, elem in enumerate(arg):
    ...         print(i, elem)
    ...
    

    (Aportado por Yurii Karabas en bpo-46014.)

hashlib

  • hashlib.blake2b() y hashlib.blake2s() ahora prefieren libb2 a la copia proporcionada por Python. (Aportado por Christian Heimes en bpo-47095.)

  • El módulo interno _sha3 con algoritmos SHA3 y SHAKE ahora usa tiny_sha3 en lugar de Keccak Code Package para reducir el código y el tamaño binario. El módulo hashlib prefiere implementaciones SHA3 y SHAKE optimizadas de OpenSSL. El cambio afecta solo a las instalaciones sin compatibilidad con OpenSSL. (Aportado por Christian Heimes en bpo-47098.)

  • Agregue hashlib.file_digest(), una función de ayuda para el hash eficiente de archivos u objetos similares a archivos. (Aportado por Christian Heimes en gh-89313.)

IDLE y libre de inactividad

  • Aplicar resaltado de sintaxis a archivos .pyi. (Aportado por Alex Waygood y Terry Jan Reedy en bpo-45447).

  • Incluya avisos al guardar Shell con entradas y salidas. (Aportado por Terry Jan Reedy en gh-95191.)

inspeccionar

lugar

Inicio sesión

Matemáticas

  • Suma math.exp2(): devuelve 2 elevado a la potencia de x. (Aportado por Gideon Mitchell en bpo-45917.)

  • Agregue math.cbrt(): devuelva la raíz cúbica de x. (Aportado por Ajith Ramachandran en bpo-44357.)

  • Se cambió el comportamiento de dos casos de esquina math.pow(), para mantener la coherencia con la especificación IEEE 754. Las operaciones math.pow(0.0, -math.inf) y math.pow(-0.0, -math.inf) ahora devuelven inf. Anteriormente plantearon ValueError. (Contribuido por Mark Dickinson en bpo-44339.)

  • El valor math.nan ahora está siempre disponible. (Aportado por Victor Stinner en bpo-46917.)

operador

  • Se ha añadido una nueva función operator.call, de forma que operator.call(obj, *args, **kwargs) == obj(*args, **kwargs). (Aportado por Antony Lee en bpo-44019.)

sistema operativo

  • En Windows, os.urandom() ahora usa BCryptGenRandom(), en lugar de CryptGenRandom(), que está en desuso. (Aportado por Dong-hee Na en bpo-44611.)

rutalib

re

  • La agrupación atómica ((?>...)) y los cuantificadores posesivos (*+, ++, ?+, {m,n}+) ahora son compatibles con las expresiones regulares. (Aportado por Jeffrey C. Jacobs y Serhiy Storchaka en bpo-433030).

cerrar

enchufe

  • Agregue compatibilidad con CAN Socket para NetBSD. (Aportado por Thomas Klausner en bpo-30512.)

  • create_connection() tiene una opción para generar, en caso de falla de conexión, un ExceptionGroup que contiene todos los errores en lugar de generar solo el último error. (Aportado por Irit Katriel en bpo-29980.)

sqlite3

cuerda

sistema

  • sys.exc_info() ahora deriva los campos type y traceback de value (la instancia de excepción), por lo que cuando se modifica una excepción mientras se gestiona, los cambios se reflejan en los resultados de las llamadas posteriores a exc_info(). (Aportado por Irit Katriel en bpo-45711.)

  • Agregue sys.exception() que devuelve la instancia de excepción activa (equivalente a sys.exc_info()[1]). (Aportado por Irit Katriel en bpo-46328.)

  • Agregue el indicador sys.flags.safe_path. (Aportado por Victor Stinner en gh-57684.)

configuración del sistema

  • Se agregaron tres nuevos installation schemes (posix_venv, nt_venv y venv) y se usan cuando Python crea nuevos entornos virtuales o cuando se ejecuta desde un entorno virtual. Los primeros dos esquemas (posix_venv y nt_venv) son específicos del sistema operativo para Windows y no Windows, el venv es esencialmente un alias para uno de ellos según el sistema operativo en el que se ejecuta Python. Esto es útil para los distribuidores posteriores que modifican sysconfig.get_preferred_scheme(). El código de terceros que crea nuevos entornos virtuales debe usar el nuevo esquema de instalación venv para determinar las rutas, al igual que venv. (Aportado por Miro Hrončok en bpo-45413.)

archivo temporal

  • Los objetos SpooledTemporaryFile ahora implementan completamente los métodos de io.BufferedIOBase o io.TextIOBase (según el modo de archivo). Esto les permite trabajar correctamente con API que esperan objetos similares a archivos, como módulos de compresión. (Aportado por Carey Metcalfe en gh-70363.)

enhebrar

  • En Unix, si la función sem_clockwait() está disponible en la biblioteca C (glibc 2.30 y posterior), el método threading.Lock.acquire() ahora usa el reloj monotónico (time.CLOCK_MONOTONIC) para el tiempo de espera, en lugar de usar el reloj del sistema (time.CLOCK_REALTIME), para no verse afectado por cambios en el reloj del sistema. (Aportado por Victor Stinner en bpo-41710.)

tiempo

  • En Unix, time.sleep() ahora usa la función clock_nanosleep() o nanosleep(), si está disponible, que tiene una resolución de 1 nanosegundo (10-9 segundos), en lugar de usar select() que tiene una resolución de 1 microsegundo (10-6 segundos). (Aportado por Benjamin Szőke y Victor Stinner en bpo-21302.)

  • En Windows 8.1 y posteriores, time.sleep() ahora usa un temporizador de espera basado en high-resolution timers que tiene una resolución de 100 nanosegundos (10-7 segundos). Anteriormente tenía una resolución de 1 milisegundo (10-3 segundos). (Aportado por Benjamin Szőke, Dong-hee Na, Eryk Sun y Victor Stinner en bpo-21302 y bpo-45429).

rastrear

mecanografía

Para conocer los cambios importantes, consulte Nuevas funciones relacionadas con las sugerencias de tipo.

  • Agregue typing.assert_never() y typing.Never. typing.assert_never() es útil para pedirle a un verificador de tipos que confirme que no se puede acceder a una línea de código. En tiempo de ejecución, genera un AssertionError. (Aportado por Jelle Zijlstra en gh-90633.)

  • Agregue typing.reveal_type(). Esto es útil para preguntarle a un verificador de tipos qué tipo ha inferido para una expresión dada. En tiempo de ejecución imprime el tipo del valor recibido. (Aportado por Jelle Zijlstra en gh-90572.)

  • Agregue typing.assert_type(). Esto es útil para pedirle a un verificador de tipos que confirme que el tipo que ha inferido para una expresión dada coincide con el tipo dado. En tiempo de ejecución, simplemente devuelve el valor recibido. (Aportado por Jelle Zijlstra en gh-90638.)

  • Los tipos typing.TypedDict ahora pueden ser genéricos. (Aportado por Samodya Abeysiriwardane en gh-89026.)

  • Los tipos NamedTuple ahora pueden ser genéricos. (Aportado por Serhiy Storchaka en bpo-43923.)

  • Permitir subclases de typing.Any. Esto es útil para evitar errores de verificación de tipos relacionados con clases altamente dinámicas, como simulacros. (Aportado por Shantanu Jain en gh-91154.)

  • El decorador typing.final() ahora establece el atributo __final__ en el objeto decorado. (Aportado por Jelle Zijlstra en gh-90500.)

  • La función typing.get_overloads() se puede utilizar para la introspección de las sobrecargas de una función. typing.clear_overloads() se puede utilizar para borrar todas las sobrecargas registradas de una función. (Aportado por Jelle Zijlstra en gh-89263.)

  • El método __init__() de las subclases Protocol ahora se conserva. (Aportado por Adrián García Badarasco en gh-88970.)

  • La representación de tipos de tuplas vacías (Tuple[()]) se simplifica. Esto afecta la introspección, p. get_args(Tuple[()]) ahora se evalúa como () en lugar de ((),). (Aportado por Serhiy Storchaka en gh-91137.)

  • Afloje los requisitos de tiempo de ejecución para las anotaciones de tipo eliminando la verificación invocable en la función privada typing._type_check. (Aportado por Gregory Beauregard en gh-90802.)

  • typing.get_type_hints() ahora admite la evaluación de cadenas como referencias directas en PEP 585 generic aliases. (Aportado por Niklas Rosenstein en gh-85542.)

  • typing.get_type_hints() ya no agrega Optional a los parámetros con None como predeterminado. (Aportado por Nikita Sobolev en gh-90353.)

  • typing.get_type_hints() ahora admite la evaluación de anotaciones ClassVar con cadenas desnudas. (Aportado por Gregory Beauregard en gh-90711.)

  • typing.no_type_check() ya no modifica clases y funciones externas. Ahora también marca correctamente los métodos de clase para que no se verifique el tipo. (Aportado por Nikita Sobolev en gh-90729.)

tkinter

  • Se agregó el método info_patchlevel() que devuelve la versión exacta de la biblioteca Tcl como una tupla con nombre similar a sys.version_info. (Aportado por Serhiy Storchaka en gh-91827.)

unicodedata

  • La base de datos Unicode se ha actualizado a la versión 14.0.0. (Aportado por Benjamin Peterson en bpo-45190).

prueba de unidad

venv

  • Cuando se crean nuevos entornos virtuales de Python, el venv sysconfig installation scheme se utiliza para determinar las rutas dentro del entorno. Cuando Python se ejecuta en un entorno virtual, el mismo esquema de instalación es el predeterminado. Eso significa que los distribuidores intermedios pueden cambiar el esquema de instalación de sysconfig predeterminado sin cambiar el comportamiento de los entornos virtuales. El código de terceros que también crea nuevos entornos virtuales debería hacer lo mismo. (Aportado por Miro Hrončok en bpo-45413.)

advertencias

archivo zip

  • Se agregó compatibilidad para especificar la codificación de nombres de miembros para leer metadatos en los encabezados de archivos y directorios de ZipFile. (Aportado por Stephen J. Turnbull y Serhiy Storchaka en bpo-28080).

  • Se agregó ZipFile.mkdir() para crear nuevos directorios dentro de archivos ZIP. (Aportado por Sam Ezeh en gh-49083.)

  • Se agregaron stem, suffix y suffixes a zipfile.Path. (Aportado por Miguel Brito en gh-88261.)

fcntl

  • En FreeBSD, se admiten las banderas F_DUP2FD y F_DUP2FD_CLOEXEC respectivamente, la primera equivale al uso de dup2 mientras que la última establece además la bandera FD_CLOEXEC.

Optimizaciones

Esta sección cubre optimizaciones específicas independientes del proyecto CPython más rápido, que se trata en su propia sección.

  • El compilador ahora optimiza printf-style % formatting simple en cadenas literales que contienen solo los códigos de formato %s, %r y %a y lo hace tan rápido como una expresión f-string correspondiente. (Aportado por Serhiy Storchaka en bpo-28307.)

  • La división de enteros (//) está mejor ajustada para la optimización por parte de los compiladores. Ahora es un 20 % más rápido en x86-64 cuando se divide un int por un valor menor que 2**30. (Aportado por Gregory P. Smith y Tim Peters en gh-90564.)

  • sum() ahora es casi un 30 % más rápido para números enteros más pequeños que 2**30. (Aportado por Stefan Behnel en gh-68264.)

  • El cambio de tamaño de las listas está simplificado para el caso común, acelerando list.append() en ≈15 % y list comprehensions simples hasta en un 20-30 % (Contribuido por Dennis Sweeney en gh-91165).

  • Los diccionarios no almacenan valores hash cuando todas las claves son objetos Unicode, lo que reduce el tamaño de dict. Por ejemplo, sys.getsizeof(dict.fromkeys("abcdefg")) se reduce de 352 bytes a 272 bytes (un 23 % más pequeño) en plataformas de 64 bits. (Aportado por Inada Naoki en bpo-46845.)

  • El uso de asyncio.DatagramProtocol ahora es mucho más rápido cuando se transfieren archivos grandes a través de UDP, con velocidades 100 veces más altas para un archivo de ≈60 MiB. (Aportado por msoxzw en gh-91487.)

  • Las funciones math comb() y perm() ahora son ≈10 veces más rápidas para argumentos grandes (con una aceleración mayor para k más grandes). (Aportado por Serhiy Storchaka en bpo-37295.)

  • Las funciones statistics mean(), variance() y stdev() ahora consumen iteradores en una sola pasada en lugar de convertirlos primero en list. Esto es el doble de rápido y puede ahorrar una cantidad considerable de memoria. (Aportado por Raymond Hettinger en gh-90415.)

  • unicodedata.normalize() ahora normaliza cadenas ASCII puras en tiempo constante. (Aportado por Dong-hee Na en bpo-44987.)

CPython más rápido

CPython 3.11 es en promedio 25% faster que CPython 3.10 cuando se mide con el conjunto de pruebas comparativas pyperformance y se compila con GCC en Ubuntu Linux. Dependiendo de su carga de trabajo, la aceleración podría ser hasta un 10-60 % más rápida.

Este proyecto se centra en dos áreas principales de Python: un inicio más rápido y un tiempo de ejecución más rápido. Otras optimizaciones que no pertenecen a este proyecto se enumeran en Optimizations.

Inicio más rápido

Importaciones congeladas / Objetos de código estático

Python almacena en caché el código de bytes en el directorio __pycache__ para acelerar la carga del módulo.

Previamente en 3.10, la ejecución del módulo de Python se veía así:

Read __pycache__ -> Unmarshal -> Heap allocated code object -> Evaluate

En Python 3.11, los módulos principales esenciales para el inicio de Python están «congelados». Esto significa que sus objetos de código (y bytecode) son asignados estáticamente por el intérprete. Esto reduce los pasos en el proceso de ejecución del módulo a esto:

Statically allocated code object -> Evaluate

El inicio del intérprete ahora es un 10-15 % más rápido en Python 3.11. Esto tiene un gran impacto para los programas de ejecución corta que usan Python.

(Aportado por Eric Snow, Guido van Rossum y Kumar Aditya en numerosos números).

Tiempo de ejecución más rápido

Marcos de Python más baratos y perezosos

Los marcos de Python se crean cada vez que Python llama a una función de Python. Este marco contiene información de ejecución. Las siguientes son nuevas optimizaciones de fotogramas:

  • Simplificó el proceso de creación de marcos.

  • Se evitó la asignación de memoria al reutilizar generosamente el espacio de marcos en la pila C.

  • Simplificó la estructura del marco interno para que contenga solo información esencial. Los marcos contenían previamente información adicional de gestión de memoria y depuración.

Los objetos de marco de estilo antiguo ahora se crean solo cuando lo solicitan los depuradores o las funciones de introspección de Python, como sys._getframe o inspect.currentframe. Para la mayoría de los códigos de usuario, no se crean objetos de marco en absoluto. Como resultado, casi todas las llamadas a funciones de Python se han acelerado significativamente. Medimos un 3-7% de aceleración en pyrendimiento.

(Aportado por Mark Shannon en bpo-44590.)

Llamadas a funciones de Python en línea

Durante una llamada de función de Python, Python llamará a una función C de evaluación para interpretar el código de esa función. Esto limita efectivamente la recursión pura de Python a lo que es seguro para la pila de C.

En 3.11, cuando CPython detecta código de Python que llama a otra función de Python, configura un nuevo marco y «salta» al nuevo código dentro del nuevo marco. Esto evita llamar a la función de interpretación de C por completo.

La mayoría de las llamadas a funciones de Python ahora no consumen espacio en la pila de C. Esto acelera la mayoría de tales llamadas. En funciones recursivas simples como fibonacci o factorial, se observó una aceleración de 1,7x. Esto también significa que las funciones recursivas pueden repetirse mucho más profundo (si el usuario aumenta el límite de recurrencia). Medimos una mejora del 1-3 % en el rendimiento.

(Aportado por Pablo Galindo y Mark Shannon en bpo-45256.)

PEP 659: Intérprete Adaptativo Especializado

PEP 659 es una de las partes clave del proyecto CPython más rápido. La idea general es que, si bien Python es un lenguaje dinámico, la mayoría del código tiene regiones donde los objetos y los tipos rara vez cambian. Este concepto se conoce como type stability.

En tiempo de ejecución, Python intentará buscar patrones comunes y escribir estabilidad en el código de ejecución. Python luego reemplazará la operación actual con una más especializada. Esta operación especializada usa rutas rápidas disponibles solo para esos casos/tipos de uso, que generalmente superan a sus contrapartes genéricas. Esto también trae otro concepto llamado inline caching, donde Python almacena en caché los resultados de operaciones costosas directamente en el código de bytes.

El especialista también combinará ciertos pares de instrucciones comunes en una superinstrucción. Esto reduce la sobrecarga durante la ejecución.

Python solo se especializará cuando vea un código «caliente» (ejecutado varias veces). Esto evita que Python pierda tiempo con el código de ejecución única. Python también puede dejar de especializarse cuando el código es demasiado dinámico o cuando cambia el uso. La especialización se intenta periódicamente y los intentos de especialización no son demasiado costosos. Esto permite que la especialización se adapte a las nuevas circunstancias.

(PEP escrito por Mark Shannon, con ideas inspiradas por Stefan Brunthaler. Consulte PEP 659 para obtener más información. Implementación por Mark Shannon y Brandt Bucher, con ayuda adicional de Irit Katriel y Dennis Sweeney).

Operación

Forma

Especialización

Aceleración de la operación (hasta)

Colaborador(es)

Operaciones binarias

x+x; x*x; x-x;

La suma, multiplicación y resta binaria para tipos comunes como int, float y str toman rutas rápidas personalizadas para sus tipos subyacentes.

10%

Mark Shannon, Dong-hee Na, Brandt Bucher, Dennis Sweeney

Subíndice

a[i]

Los tipos de contenedores de suscripción como list, tuple y dict indexan directamente las estructuras de datos subyacentes.

La suscripción personalizada __getitem__ también está en línea similar a Llamadas a funciones de Python en línea.

10-25%

Irit KatrielMark Shannon

Almacenar subíndice

a[i] = z

Similar a la especialización de subíndices anterior.

10-25%

dennis sweeney

Llamadas

f(arg) C(arg)

Las llamadas a funciones y tipos integrados (C) comunes, como len y str, llaman directamente a su versión C subyacente. Esto evita pasar por la convención de llamada interna.

20%

Mark ShannonKen Jin

Cargar variable global

print len

El índice del objeto en el espacio de nombres globales/integrados se almacena en caché. La carga de globales e integrados requiere cero búsquedas de espacios de nombres.

1

marca shannon

Cargar atributo

o.attr

Similar a cargar variables globales. El índice del atributo dentro del espacio de nombres de la clase/objeto se almacena en caché. En la mayoría de los casos, la carga de atributos requerirá cero búsquedas de espacios de nombres.

2

marca shannon

Cargar métodos para llamar

o.meth()

La dirección real del método se almacena en caché. La carga de métodos ahora no tiene búsquedas de espacio de nombres, incluso para clases con largas cadenas de herencia.

10-20%

Ken JinMark Shannon

Atributo de la tienda

o.attr = z

Similar a la optimización de atributos de carga.

2% en rendimiento

marca shannon

Secuencia de desempaquetado

*seq

Especializado para contenedores comunes como list y tuple. Evita la convención de llamadas internas.

8%

brandt bucher

1

Ya existía una optimización similar desde Python 3.8. 3.11 se especializa en más formularios y reduce algunos gastos generales.

2

Ya existía una optimización similar desde Python 3.10. 3.11 se especializa en más formularios. Además, bpo-45947 debería acelerar todas las cargas de atributos.

Varios

  • Los objetos ahora requieren menos memoria debido a los espacios de nombres de objetos creados con pereza. Sus diccionarios de espacio de nombres ahora también comparten claves más libremente. (Contribuido por Mark Shannon en bpo-45340 y bpo-40116).

  • Una representación más concisa de las excepciones en el intérprete redujo el tiempo necesario para detectar una excepción en aproximadamente un 10 %. (Aportado por Irit Katriel en bpo-45711.)

Preguntas más frecuentes

P: ¿Cómo debo escribir mi código para utilizar estas aceleraciones?

R: No tienes que cambiar tu código. Escriba código Pythonic que siga las mejores prácticas comunes. El proyecto Faster CPython optimiza los patrones de código comunes que observamos.


P: ¿CPython 3.11 usará más memoria?

R: Tal vez no. No esperamos que el uso de memoria supere el 20% más que 3.10. Esto se compensa con las optimizaciones de memoria para objetos de marco y diccionarios de objetos, como se mencionó anteriormente.


P: No veo ninguna aceleración en mi carga de trabajo. ¿Por qué?

R: Cierto código no tendrá beneficios notables. Si su código pasa la mayor parte de su tiempo en operaciones de E/S, o ya realiza la mayor parte de su cálculo en una biblioteca de extensión C como numpy, no habrá una aceleración significativa. Actualmente, este proyecto es el que más beneficia a las cargas de trabajo de Python puro.

Además, las cifras de pyperformance son una media geométrica. Incluso dentro de los puntos de referencia de pyrendimiento, ciertos puntos de referencia se han ralentizado ligeramente, mientras que otros se han acelerado casi 2 veces.


P: ¿Existe un compilador JIT?

R: No. Todavía estamos explorando otras optimizaciones.

Sobre

Faster CPython explora optimizaciones para CPython. El equipo principal está financiado por Microsoft para trabajar en esto a tiempo completo. Pablo Galindo Salgado también está financiado por Bloomberg LP para trabajar en el proyecto a tiempo parcial. Finalmente, muchos contribuyentes son voluntarios de la comunidad.

Cambios en el código de bytes de CPython

El código de bytes ahora contiene entradas de caché en línea, que toman la forma de las instrucciones CACHE recién agregadas. Muchos códigos de operación esperan ser seguidos por una cantidad exacta de cachés e indican al intérprete que los omita en tiempo de ejecución. Los cachés poblados pueden parecer instrucciones arbitrarias, por lo que se debe tener mucho cuidado al leer o modificar el código de bytes adaptativo sin procesar que contiene datos acelerados.

Nuevos códigos de operación

Códigos de operación reemplazados

Códigos de operación reemplazados

Nuevos códigos de operación

notas

BINARY_*
INPLACE_*

BINARY_OP

Reemplazó todos los códigos de operación numéricos binarios/en el lugar con un solo código de operación

CALL_FUNCTION
CALL_FUNCTION_KW
CALL_METHOD

Separa el cambio de argumentos para métodos del manejo de argumentos de palabras clave; permite una mejor especialización de las llamadas

DUP_TOP
DUP_TOP_TWO
ROT_TWO
ROT_THREE
ROT_FOUR
ROT_N

Instrucciones de manipulación de pilas

JUMP_IF_NOT_EXC_MATCH

Ahora realiza la comprobación pero no salta.

JUMP_ABSOLUTE
POP_JUMP_IF_FALSE
POP_JUMP_IF_TRUE

Ver 3; Variantes TRUE, FALSE, NONE y NOT_NONE para cada dirección

SETUP_WITH
SETUP_ASYNC_WITH

BEFORE_WITH

Configuración del bloque with

3

Todos los códigos de operación de salto ahora son relativos, incluidos los JUMP_IF_TRUE_OR_POP y JUMP_IF_FALSE_OR_POP existentes. El argumento ahora es un desplazamiento de la instrucción actual en lugar de una ubicación absoluta.

Códigos de operación cambiados/eliminados

  • Se cambiaron MATCH_CLASS y MATCH_KEYS para que ya no envíen un valor booleano adicional para indicar éxito/fracaso. En su lugar, se inserta None en caso de error en lugar de la tupla de valores extraídos.

  • Se cambiaron los códigos de operación que funcionan con excepciones para reflejarlas y ahora se representan como un elemento en la pila en lugar de tres (ver gh-89874).

  • Se eliminaron COPY_DICT_WITHOUT_KEYS, GEN_START, POP_BLOCK, SETUP_FINALLY y YIELD_FROM.

Obsoleto

Esta sección enumera las API de Python que han quedado obsoletas en Python 3.11.

Las API de C en desuso son listed separately.

Idioma/Construidos

  • El encadenamiento de descriptores classmethod (introducido en bpo-19072) ahora está en desuso. Ya no se puede usar para envolver otros descriptores como property. El diseño central de esta función tenía fallas y causó una serie de problemas posteriores. Para «transmitir» un classmethod, considere usar el atributo __wrapped__ que se agregó en Python 3.10. (Aportado por Raymond Hettinger en gh-89519.)

  • Los escapes octales en cadenas y bytes literales con valores mayores que 0o377 (255 en decimal) ahora producen un DeprecationWarning. En una futura versión de Python, generarán un SyntaxWarning y eventualmente un SyntaxError. (Aportado por Serhiy Storchaka en gh-81548.)

  • La delegación de int() a __trunc__() ahora está obsoleta. Llamar a int(a) cuando type(a) implementa __trunc__() pero no __int__() o __index__() ahora genera un DeprecationWarning. (Aportado por Zackery Spytz en bpo-44977).

Módulos

Biblioteca estándar

Eliminación pendiente en Python 3.12

Las siguientes API de Python han quedado obsoletas en versiones anteriores de Python y se eliminarán en Python 3.12.

Las API de C pendientes de eliminación son listed separately.

Remoto

Esta sección enumera las API de Python que se han eliminado en Python 3.12.

Las API C eliminadas son listed separately.

  • Se eliminó @asyncio.coroutine() decorator, lo que permite que las corrutinas basadas en generadores heredados sean compatibles con el código async/await. La función ha quedado obsoleta desde Python 3.8 y la eliminación se programó inicialmente para Python 3.10. Utilice async def en su lugar. (Aportado por Illia Volochii en bpo-43216.)

  • Se eliminó asyncio.coroutines.CoroWrapper utilizado para envolver objetos de corrutina basados ​​en generadores heredados en el modo de depuración. (Aportado por Illia Volochii en bpo-43216.)

  • Debido a importantes problemas de seguridad, el parámetro reuse_address de asyncio.loop.create_datagram_endpoint(), deshabilitado en Python 3.9, ahora se eliminó por completo. Esto se debe al comportamiento de la opción de socket SO_REUSEADDR en UDP. (Aportado por Hugo van Kemenade en bpo-45129.)

  • Se eliminó el módulo binhex, obsoleto en Python 3.9. También se eliminaron las funciones binascii relacionadas y obsoletas de manera similar:

    • binascii.a2b_hqx()

    • binascii.b2a_hqx()

    • binascii.rlecode_hqx()

    • binascii.rldecode_hqx()

    La función binascii.crc_hqx() permanece disponible.

    (Aportado por Victor Stinner en bpo-45085.)

  • Se eliminó el comando distutils bdist_msi en desuso en Python 3.9. Utilice bdist_wheel (paquetes de ruedas) en su lugar. (Aportado por Hugo van Kemenade en bpo-45124.)

  • Se eliminaron los métodos __getitem__() de xml.dom.pulldom.DOMEventStream, wsgiref.util.FileWrapper y fileinput.FileInput, obsoletos desde Python 3.9. (Aportado por Hugo van Kemenade en bpo-45132.)

  • Se eliminaron las funciones obsoletas gettext lgettext(), ldgettext(), lngettext() y ldngettext(). También se eliminó la función bind_textdomain_codeset(), los métodos NullTranslations.output_charset() y NullTranslations.set_output_charset(), y el parámetro codeset de translation() y install(), ya que solo se usan para las funciones l*gettext(). (Aportado por Dong-hee Na y Serhiy Storchaka en bpo-44235).

  • Eliminado del módulo inspect:

    (Aportado por Hugo van Kemenade en bpo-45320.)

  • Se eliminó el método __class_getitem__() de pathlib.PurePath, porque no se usó y se agregó por error en versiones anteriores. (Aportado por Nikita Sobolev en bpo-46483.)

  • Se eliminó la clase MailmanProxy en el módulo smtpd, ya que no se puede usar sin el paquete mailman externo. (Aportado por Dong-hee Na en bpo-35800.)

  • Se eliminó el método obsoleto split() de _tkinter.TkappType. (Aportado por Erlend E. Aasland en bpo-38371.)

  • Se eliminó la compatibilidad con el paquete de espacio de nombres del descubrimiento unittest. Se introdujo en Python 3.4 pero se rompió desde Python 3.7. (Aportado por Inada Naoki en bpo-23882.)

  • Se eliminó el método float.__set_format__() privado no documentado, anteriormente conocido como float.__setformat__() en Python 3.7. Su cadena de documentación decía: «Probablemente no desee utilizar esta función. Existe principalmente para ser utilizada en el conjunto de pruebas de Python». (Aportado por Victor Stinner en bpo-46852.)

  • El indicador de configuración --experimental-isolated-subinterpreters (y la macro EXPERIMENTAL_ISOLATED_SUBINTERPRETERS correspondiente) se han eliminado.

  • Pynche — El editor de tonos y colores naturales de Python — se ha sacado de Tools/scripts y es being developed independently del árbol de fuentes de Python.

Migración a Python 3.11

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

Las notas de portabilidad para la API de C son listed separately.

  • open(), io.open(), codecs.open() y fileinput.FileInput ya no aceptan 'U' («nueva línea universal») en el modo de archivo. En Python 3, el modo «nueva línea universal» se usa de forma predeterminada cada vez que se abre un archivo en modo de texto, y el indicador 'U' ha quedado obsoleto desde Python 3.3. El newline parameter para estas funciones controla cómo funcionan las nuevas líneas universales. (Aportado por Victor Stinner en bpo-37330.)

  • Las posiciones de los nodos ast.AST ahora se validan cuando se proporcionan a compile() y otras funciones relacionadas. Si se detectan posiciones no válidas, se generará un ValueError. (Aportado por Pablo Galindo en gh-93351)

  • Prohibido pasar ejecutores que no sean concurrent.futures.ThreadPoolExecutor a asyncio.loop.set_default_executor() luego de una obsolescencia en Python 3.8. (Aportado por Illia Volochii en bpo-43234.)

  • calendar: las clases calendar.LocaleTextCalendar y calendar.LocaleHTMLCalendar ahora usan locale.getlocale(), en lugar de usar locale.getdefaultlocale(), si no se especifica una configuración regional. (Aportado por Victor Stinner en bpo-46659.)

  • El módulo pdb ahora lee el archivo de configuración .pdbrc con la codificación 'UTF-8'. (Contribuido por Srinivas Reddy Thatiparthy (శ్రీనివాస్ రెడ్డి తాటిపర్తి) en bpo-41137.)

  • El parámetro population de random.sample() debe ser una secuencia y ya no se admite la conversión automática de sets a lists. Además, si el tamaño de la muestra es mayor que el tamaño de la población, se genera un ValueError. (Aportado por Raymond Hettinger en bpo-40465.)

  • Se eliminó el parámetro opcional random de random.shuffle(). Anteriormente, era una función aleatoria arbitraria para usar en la reproducción aleatoria; ahora, siempre se utilizará random.random() (su valor predeterminado anterior).

  • En re Sintaxis de expresiones regulares, las banderas en línea globales (por ejemplo, (?i)) ahora solo se pueden usar al comienzo de las expresiones regulares. Su uso en otros lugares ha quedado obsoleto desde Python 3.6. (Aportado por Serhiy Storchaka en bpo-47066.)

  • En el módulo re, se corrigieron varios errores antiguos que, en casos excepcionales, podían hacer que los grupos de captura obtuvieran un resultado incorrecto. Por lo tanto, esto podría cambiar la salida capturada en estos casos. (Contribuido por Ma Lin en bpo-35859.)

Construir cambios

  • CPython ahora tiene PEP 11 Tier 3 support para la compilación cruzada en las plataformas WebAssembly Emscripten (wasm32-unknown-emscripten, es decir, Python en el navegador) y WebAssembly System Interface (WASI) (wasm32-unknown-wasi). El esfuerzo está inspirado en trabajos anteriores como Pyodide. Estas plataformas proporcionan un subconjunto limitado de API POSIX; Las funciones y módulos de las bibliotecas estándar de Python relacionadas con redes, procesos, subprocesos, señales, mmap y usuarios/grupos no están disponibles o no funcionan. (Escritos aportados por Christian Heimes y Ethan Smith en gh-84461 y WASI aportados por Christian Heimes en gh-90473; plataformas promocionadas en gh-95085)

  • Construir Python ahora requiere:

    • Un compilador C11. Optional C11 features no son necesarios. (Aportado por Victor Stinner en bpo-46656.)

    • Compatibilidad con números de punto flotante IEEE 754. (Aportado por Victor Stinner en bpo-46917.)

    • Compatibilidad con floating point Not-a-Number (NaN), ya que se eliminó la macro Py_NO_NAN. (Aportado por Victor Stinner en bpo-46656.)

    • Un archivo de encabezado C99 <math.h> que proporciona las funciones copysign(), hypot(), isfinite(), isinf(), isnan() y round() (aportado por Victor Stinner en bpo-45440); y una constante NAN o la función __builtin_nan() (Aportado por Victor Stinner en bpo-46640).

  • El paquete tkinter ahora requiere Tcl/Tk versión 8.5.12 o posterior. (Aportado por Serhiy Storchaka en bpo-46996.)

  • Las dependencias de compilación, los indicadores del compilador y los indicadores del vinculador para la mayoría de los módulos de extensión stdlib ahora son detectados por configure. pkg-config detecta los indicadores libffi, libnsl, libsqlite3, zlib, bzip2, liblzma, libcrypt, Tcl/Tk y uuid (si están disponibles). tkinter ahora requiere un comando pkg-config para detectar configuraciones de desarrollo para encabezados y bibliotecas Tcl/Tk. (Aportado por Christian Heimes y Erlend Egeberg Aasland en bpo-45847, bpo-45747 y bpo-45763).

  • libpython ya no está vinculado con libcrypt. (Aportado por Mike Gilbert en bpo-45433.)

  • CPython ahora se puede compilar con la opción ThinLTO pasando thin a --with-lto, es decir, --with-lto=thin. (Aportado por Dong-hee Na y Brett Holman en bpo-44340).

  • Las listas libres para estructuras de objetos ahora se pueden deshabilitar. Se puede usar una nueva opción configure --without-freelists para deshabilitar todas las listas libres excepto el singleton de tupla vacío. (Aportado por Christian Heimes en bpo-45522.)

  • Modules/Setup y Modules/makesetup se han mejorado y atado. Los módulos de extensión ahora se pueden construir a través de makesetup. Todos, excepto algunos módulos de prueba, se pueden vincular estáticamente a una biblioteca o binario principal. (Aportado por Brett Cannon y Christian Heimes en bpo-45548, bpo-45570, bpo-45571 y bpo-43974).

    Nota

    Utilice las variables de entorno TCLTK_CFLAGS y TCLTK_LIBS para especificar manualmente la ubicación de los encabezados y bibliotecas Tcl/Tk. Se han eliminado las opciones configure --with-tcltk-includes y --with-tcltk-libs.

    En RHEL 7 y CentOS 7, los paquetes de desarrollo no proporcionan tcl.pc y tk.pc; usa TCLTK_LIBS="-ltk8.5 -ltkstub8.5 -ltcl8.5". El directorio Misc/rhel7 contiene archivos .pc e instrucciones sobre cómo compilar Python con Tcl/Tk y OpenSSL de RHEL 7 y CentOS 7.

  • CPython ahora usará dígitos de 30 bits de manera predeterminada para la implementación de Python int. Anteriormente, el valor predeterminado era usar dígitos de 30 bits en plataformas con SIZEOF_VOID_P >= 8 y dígitos de 15 bits en caso contrario. Todavía es posible solicitar explícitamente el uso de dígitos de 15 bits a través de la opción --enable-big-digits en el script de configuración o (para Windows) la variable PYLONG_BITS_IN_DIGIT en PC/pyconfig.h, pero es posible que esta opción se elimine en algún momento en el futuro. (Contribuido por Mark Dickinson en bpo-45569.)

Cambios en la API de C

Nuevas características

Migración a Python 3.11

  • Algunas macros se han convertido en funciones estáticas en línea para evitar macro pitfalls. El cambio debería ser en su mayoría transparente para los usuarios, ya que las funciones de reemplazo emitirán sus argumentos a los tipos esperados para evitar advertencias del compilador debido a comprobaciones de tipos estáticos. Sin embargo, cuando la API de C limitada se establece en >=3.11, estas conversiones no se realizan y las personas que llaman deberán convertir argumentos a sus tipos esperados. Ver PEP 670 para más detalles. (Aportado por Victor Stinner y Erlend E. Aasland en gh-89653.)

  • PyErr_SetExcInfo() ya no usa los argumentos type y traceback, el intérprete ahora deriva esos valores de la instancia de excepción (el argumento value). La función aún roba referencias de los tres argumentos. (Aportado por Irit Katriel en bpo-45711.)

  • PyErr_GetExcInfo() ahora deriva los campos type y traceback del resultado de la instancia de excepción (el campo value). (Aportado por Irit Katriel en bpo-45711.)

  • _frozen tiene un nuevo campo is_package para indicar si el módulo congelado es o no un paquete. Anteriormente, un valor negativo en el campo size era el indicador. Ahora solo se pueden usar valores no negativos para size. (Aportado por Kumar Aditya en bpo-46608.)

  • _PyFrameEvalFunction() ahora toma _PyInterpreterFrame* como su segundo parámetro, en lugar de PyFrameObject*. Consulte PEP 523 para obtener más detalles sobre cómo usar este tipo de puntero de función.

  • PyCode_New() y PyCode_NewWithPosOnlyArgs() ahora toman un argumento exception_table adicional. Debe evitarse el uso de estas funciones, en la medida de lo posible. Para obtener un objeto de código personalizado: cree un objeto de código usando el compilador, luego obtenga una versión modificada con el método replace.

  • PyCodeObject ya no tiene los campos co_code, co_varnames, co_cellvars y co_freevars. En su lugar, utilice PyCode_GetCode(), PyCode_GetVarnames(), PyCode_GetCellvars() y PyCode_GetFreevars() respectivamente para acceder a ellos a través de la API de C. (Aportado por Brandt Bucher en bpo-46841 y Ken Jin en gh-92154 y gh-94936).

  • Las antiguas macros de papelera (Py_TRASHCAN_SAFE_BEGIN/Py_TRASHCAN_SAFE_END) ahora están obsoletas. Deberían ser reemplazadas por las nuevas macros Py_TRASHCAN_BEGIN y Py_TRASHCAN_END.

    Una función tp_dealloc que tiene las macros antiguas, como:

    static void
    mytype_dealloc(mytype *p)
    {
        PyObject_GC_UnTrack(p);
        Py_TRASHCAN_SAFE_BEGIN(p);
        ...
        Py_TRASHCAN_SAFE_END
    }
    

    debe migrar a las nuevas macros de la siguiente manera:

    static void
    mytype_dealloc(mytype *p)
    {
        PyObject_GC_UnTrack(p);
        Py_TRASHCAN_BEGIN(p, mytype_dealloc)
        ...
        Py_TRASHCAN_END
    }
    

    Tenga en cuenta que Py_TRASHCAN_BEGIN tiene un segundo argumento que debería ser la función de desasignación en la que se encuentra.

    Para admitir versiones anteriores de Python en la misma base de código, puede definir las siguientes macros y usarlas en todo el código (crédito: se copiaron de la base de código mypy):

    #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 8
    #  define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_BEGIN(op, dealloc)
    #  define CPy_TRASHCAN_END(op) Py_TRASHCAN_END
    #else
    #  define CPy_TRASHCAN_BEGIN(op, dealloc) Py_TRASHCAN_SAFE_BEGIN(op)
    #  define CPy_TRASHCAN_END(op) Py_TRASHCAN_SAFE_END(op)
    #endif
    
  • La función PyType_Ready() ahora genera un error si un tipo se define con el indicador Py_TPFLAGS_HAVE_GC establecido pero no tiene función transversal (PyTypeObject.tp_traverse). (Aportado por Victor Stinner en bpo-44263.)

  • Los tipos de almacenamiento dinámico con el indicador Py_TPFLAGS_IMMUTABLETYPE ahora pueden heredar el protocolo vectorcall PEP 590. Anteriormente, esto solo era posible para static types. (Aportado por Erlend E. Aasland en bpo-43908)

  • Dado que Py_TYPE() se cambia a una función estática en línea, Py_TYPE(obj) = new_type debe reemplazarse por Py_SET_TYPE(obj, new_type): consulte la función Py_SET_TYPE() (disponible desde Python 3.9). Para compatibilidad con versiones anteriores, se puede usar esta macro:

    #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_TYPE)
    static inline void _Py_SET_TYPE(PyObject *ob, PyTypeObject *type)
    { ob->ob_type = type; }
    #define Py_SET_TYPE(ob, type) _Py_SET_TYPE((PyObject*)(ob), type)
    #endif
    

    (Aportado por Victor Stinner en bpo-39573.)

  • Dado que Py_SIZE() se cambia a una función estática en línea, Py_SIZE(obj) = new_size debe reemplazarse por Py_SET_SIZE(obj, new_size): consulte la función Py_SET_SIZE() (disponible desde Python 3.9). Para compatibilidad con versiones anteriores, se puede usar esta macro:

    #if PY_VERSION_HEX < 0x030900A4 && !defined(Py_SET_SIZE)
    static inline void _Py_SET_SIZE(PyVarObject *ob, Py_ssize_t size)
    { ob->ob_size = size; }
    #define Py_SET_SIZE(ob, size) _Py_SET_SIZE((PyVarObject*)(ob), size)
    #endif
    

    (Aportado por Victor Stinner en bpo-39573.)

  • <Python.h> ya no incluye los archivos de encabezado <stdlib.h>, <stdio.h>, <errno.h> y <string.h> cuando la macro Py_LIMITED_API se establece en 0x030b0000 (Python 3.11) o superior. Las extensiones de C deben incluir explícitamente los archivos de encabezado después de #include <Python.h>. (Aportado por Victor Stinner en bpo-45434.)

  • Los archivos de API no limitados cellobject.h, classobject.h, code.h, context.h, funcobject.h, genobject.h y longintrepr.h se han movido al directorio Include/cpython. Además, se eliminó el archivo de encabezado eval.h. Estos archivos no deben incluirse directamente, ya que ya están incluidos en Python.h: Include Files. Si se han incluido directamente, considere incluir Python.h en su lugar. (Aportado por Victor Stinner en bpo-35134.)

  • La macro PyUnicode_CHECK_INTERNED() se ha excluido de la API de C limitada. Nunca se pudo usar allí, porque usaba estructuras internas que no están disponibles en la API de C limitada. (Aportado por Victor Stinner en bpo-46007.)

  • Las siguientes funciones y tipos de cuadros ahora están disponibles directamente con #include <Python.h>, ya no es necesario agregar #include <frameobject.h>:

    (Aportado por Victor Stinner en gh-93937.)

  • Los miembros de la estructura PyFrameObject se han eliminado de la API de C pública.

    Si bien la documentación señala que los campos PyFrameObject están sujetos a cambios en cualquier momento, se han mantenido estables durante mucho tiempo y se usaron en varias extensiones populares.

    En Python 3.11, la estructura del marco se reorganizó para permitir optimizaciones de rendimiento. Algunos campos se eliminaron por completo, ya que eran detalles de la implementación anterior.

    Campos PyFrameObject:

    El objeto marco de Python ahora se crea de forma perezosa. Un efecto secundario es que no se debe acceder directamente al miembro f_back, ya que su valor ahora también se calcula de forma diferida. En su lugar, se debe llamar a la función PyFrame_GetBack().

    Los depuradores que accedieron a f_locals directamente must llaman a PyFrame_GetLocals() en su lugar. Ya no necesitan llamar a PyFrame_FastToLocalsWithError() o PyFrame_LocalsToFast(), de hecho, no deberían llamar a esas funciones. La actualización necesaria del marco ahora es administrada por la máquina virtual.

    Código que define PyFrame_GetCode() en Python 3.8 y anteriores:

    #if PY_VERSION_HEX < 0x030900B1
    static inline PyCodeObject* PyFrame_GetCode(PyFrameObject *frame)
    {
        Py_INCREF(frame->f_code);
        return frame->f_code;
    }
    #endif
    

    Código que define PyFrame_GetBack() en Python 3.8 y anteriores:

    #if PY_VERSION_HEX < 0x030900B1
    static inline PyFrameObject* PyFrame_GetBack(PyFrameObject *frame)
    {
        Py_XINCREF(frame->f_back);
        return frame->f_back;
    }
    #endif
    

    O use pythoncapi_compat project para obtener estas dos funciones en versiones anteriores de Python.

  • Cambios de los miembros de la estructura PyThreadState:

    Código que define PyThreadState_GetFrame() en Python 3.8 y anteriores:

    #if PY_VERSION_HEX < 0x030900B1
    static inline PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate)
    {
        Py_XINCREF(tstate->frame);
        return tstate->frame;
    }
    #endif
    

    Código que define PyThreadState_EnterTracing() y PyThreadState_LeaveTracing() en Python 3.10 y versiones anteriores:

    #if PY_VERSION_HEX < 0x030B00A2
    static inline void PyThreadState_EnterTracing(PyThreadState *tstate)
    {
        tstate->tracing++;
    #if PY_VERSION_HEX >= 0x030A00A1
        tstate->cframe->use_tracing = 0;
    #else
        tstate->use_tracing = 0;
    #endif
    }
    
    static inline void PyThreadState_LeaveTracing(PyThreadState *tstate)
    {
        int use_tracing = (tstate->c_tracefunc != NULL || tstate->c_profilefunc != NULL);
        tstate->tracing--;
    #if PY_VERSION_HEX >= 0x030A00A1
        tstate->cframe->use_tracing = use_tracing;
    #else
        tstate->use_tracing = use_tracing;
    #endif
    }
    #endif
    

    O use the pythoncapi_compat project para obtener estas funciones en funciones antiguas de Python.

  • Se alienta a los distribuidores a compilar Python con la biblioteca Blake2 optimizada libb2.

  • El campo PyConfig.module_search_paths_set ahora debe establecerse en 1 para que la inicialización use PyConfig.module_search_paths para inicializar sys.path. De lo contrario, la inicialización volverá a calcular la ruta y reemplazará los valores agregados a module_search_paths.

  • PyConfig_Read() ya no calcula la ruta de búsqueda inicial y no completará ningún valor en PyConfig.module_search_paths. Para calcular rutas predeterminadas y luego modificarlas, finalice la inicialización y use PySys_GetObject() para recuperar sys.path como un objeto de lista de Python y modificarlo directamente.

Obsoleto

Eliminación pendiente en Python 3.12

Las siguientes API de C quedaron obsoletas en versiones anteriores de Python y se eliminarán en Python 3.12.

Remoto

  • Se han eliminado PyFrame_BlockSetup() y PyFrame_BlockPop(). (Aportado por Mark Shannon en bpo-40222.)

  • Quite las siguientes macros matemáticas usando la variable errno:

    • Py_ADJUST_ERANGE1()

    • Py_ADJUST_ERANGE2()

    • Py_OVERFLOWED()

    • Py_SET_ERANGE_IF_OVERFLOW()

    • Py_SET_ERRNO_ON_MATH_ERROR()

    (Aportado por Victor Stinner en bpo-45412.)

  • Elimine las macros Py_UNICODE_COPY() y Py_UNICODE_FILL(), obsoletas desde Python 3.3. Utilice PyUnicode_CopyCharacters() o memcpy() (cadena wchar_t*) y las funciones PyUnicode_Fill() en su lugar. (Aportado por Victor Stinner en bpo-41123.)

  • Elimine el archivo de encabezado pystrhex.h. Solo contiene funciones privadas. Las extensiones C solo deben incluir el archivo de encabezado principal <Python.h>. (Aportado por Victor Stinner en bpo-45434.)

  • Quite la macro Py_FORCE_DOUBLE(). Fue utilizado por la macro Py_IS_INFINITY(). (Aportado por Victor Stinner en bpo-45440.)

  • Los siguientes elementos ya no están disponibles cuando se define Py_LIMITED_API:

    Estos no son parte del limited API.

    (Aportado por Victor Stinner en bpo-45474.)

  • Excluya PyWeakref_GET_OBJECT() de la API de C limitada. Nunca funcionó ya que la estructura PyWeakReference es opaca en la API de C limitada. (Aportado por Victor Stinner en bpo-35134.)

  • Quite la macro PyHeapType_GET_MEMBERS(). Fue expuesto en la API pública de C por error, solo debe ser utilizado por Python internamente. Utilice el miembro PyTypeObject.tp_members en su lugar. (Aportado por Victor Stinner en bpo-40170.)

  • Elimine la macro HAVE_PY_SET_53BIT_PRECISION (movida a la API de C interna). (Aportado por Victor Stinner en bpo-45412.)

  • Elimine las API del codificador Py_UNICODE, ya que han quedado obsoletas desde Python 3.3, se usan poco y son ineficientes en relación con las alternativas recomendadas.

    Las funciones eliminadas son:

    • PyUnicode_Encode()

    • PyUnicode_EncodeASCII()

    • PyUnicode_EncodeLatin1()

    • PyUnicode_EncodeUTF7()

    • PyUnicode_EncodeUTF8()

    • PyUnicode_EncodeUTF16()

    • PyUnicode_EncodeUTF32()

    • PyUnicode_EncodeUnicodeEscape()

    • PyUnicode_EncodeRawUnicodeEscape()

    • PyUnicode_EncodeCharmap()

    • PyUnicode_TranslateCharmap()

    • PyUnicode_EncodeDecimal()

    • PyUnicode_TransformDecimalToASCII()

    Ver PEP 624 para más detalles y migration guidance. (Aportado por Inada Naoki en bpo-44029.)