Resolución de Issue35930: Raising an exception raised in a "future" instance will create reference cycles
Autor: Jesús Cea & Otros - Contacto: python2021@podcast.jcea.es
Fecha de grabación: 2020/12/29 - Duración: 02:29:27
Fecha de publicación: 2021/04/30
Palabras clave: Tertulia
Descarga el audio: M4A (39064301 bytes) - OPUS (19300576 bytes)
Participantes:
Jesús Cea, email: jcea@jcea.es, twitter: @jcea, https://blog.jcea.es/, https://www.jcea.es/. Conectando desde Madrid.
Víctor Ramírez, twitter: @virako, programador python y amante de vim, conectando desde Huelva.
Miguel Sánchez, email: msanchez@uninet.edu, conectando desde Canarias.
Juan Carlos.
Plutarco, conectando desde Madrid.
Eduardo Castro, email: info@ecdesign.es. Conectando desde A Guarda.
Julio, conectando desde Chile.
Audio editado por Pablo Gómez, twitter: @julebek.
La música de la entrada y la salida es "Lightning Bugs", de Jason Shaw. Publicada en https://audionautix.com/ con licencia - Creative Commons Attribution 4.0 International License.
PyCharm: https://www.jetbrains.com/pycharm/.
Atajos de teclado.
vim: https://es.wikipedia.org/wiki/Vim.
Uso del teclado en vez del ratón.
Python va complicando la sintaxis más y más.
Se habló en una tertulia anterior.
Jesús solo ha encontrado este caso útil:
Pasar de:
buf = f.read(1000)
while buf:
[Hace el procesamiento]
buf = f.read(1000)
A lo siguiente:
while buf := f.read(1000):
[Hace el procesamiento]
Migración de Python a Github fue en 2017.
No es "Steering committee" sino "Steering Council".
Charla de Pablo Galindo en la PyconES 2019 sobre el mundo de los Core Developers de Python: https://www.youtube.com/watch?v=qcvZOaY1emk.
Algunos proyectos Python están usando Rust. Por ejemplo: https://cryptography.io/, con cierta polémica. Mercurial también usa Rust https://www.mercurial-scm.org/.
Las variables locales pueden ser modificadas a través de su "closure", en funciones hijas o en otros hilos. Es una barbaridad, pero la posibilidad existe.
Esto es lo que hace, por ejemplo, un debugger.
Issue35930: Raising an exception raised in a "future" instance will create reference cycles https://bugs.python.org/issue35930.
Frame: https://docs.python.org/3/library/traceback.html#traceback.FrameSummary.
Stack: https://docs.python.org/3/library/traceback.html#stacksummary-objects.
Issue35930: Raising an exception raised in a "future" instance will create reference cycles https://bugs.python.org/issue35930.
Estamos continuando una conversación que ha durado varias tertulias.
Jesús Cea pone un ejemplo de cómo generar un ciclo con una excepcion.
La caja y media de cervezas se las lleva... ¡Jesús!
https://docs.python.org/3/library/exceptions.html#BaseException.with_traceback.
Puedes generar una excepción con un "traceback" arbitrario.
El caballo de batalla del bug es que el "future" https://docs.python.org/3/library/concurrent.futures.html levanta una excepción y esa excepción debe "transportarse" a otro hilo.
Explicando cómo se visualizan los "traceback" si un "future" https://docs.python.org/3/library/concurrent.futures.html muere con una excepción.
def a():
1/0
try:
a()
except Exception as e:
raise e
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in a
ZeroDivisionError: division by zero
Cuando un "future" https://docs.python.org/3/library/concurrent.futures.html lanza una excepción, se ven "frames" repetidos.
Hay varias formas de solucionar el bug. Ahora hay que pensar en cual elegir, que sea la más simple e intuitiva.
Dataclasses: https://docs.python.org/3/library/dataclasses.html. Se hablo mucho sobre ellas en la tertulia de la semana pasada.
Pydantic: https://pypi.org/project/pydantic/.
FastAPI: https://pypi.org/project/fastapi/.
Issue35930: Raising an exception raised in a "future" instance will create reference cycles https://bugs.python.org/issue35930.
Exploración del propio código fuente de Python.
Repaso detallado del funcionamiento de un "future" https://docs.python.org/3/library/concurrent.futures.html.
Uno de los problemas fundamentales de trabajar con hilos es cómo notificar excepciones a otros hilos. La gran ventaja de los "futures" es gestionar esto de forma trivial.
Este "transporte" es lo que está ocasionando el "Memory Leak".
¡Agárrate que vienen curvas!
self = None
. Aquí se rompe el
ciclo en la excepción original:
https://github.com/python/cpython/blob/3.9/Lib/concurrent/futures/thread.py#L47.
Closures: https://es.wikipedia.org/wiki/Clausura_(inform%C3%A1tica).
"Pool" de "workers". De forma estándar, Python te proporciona dos ejecutores: el ejecutor de hilos y el ejecutor de procesos https://docs.python.org/3/library/concurrent.futures.html#executor-objects.
try ... finally
Jejeje, alguien propone algo que funcionaría :-).
Se pueden "resucitar" objetos.
El gráfico de antes, con ciclos: https://lists.es.python.org/pipermail/general/attachments/20201229/0c14bc58/attachment-0002.png.
El gráfico de después, sin ciclos: https://lists.es.python.org/pipermail/general/attachments/20201229/0c14bc58/attachment-0003.png.
Por sus características... complicado.
"sys.getrefcount()": https://docs.python.org/3/library/sys.html#sys.getrefcount.
"sys.exc_info()": https://docs.python.org/3/library/sys.html#sys.exc_info.
"Race conditions": https://es.wikipedia.org/wiki/Condici%C3%B3n_de_carrera.
"gc.DEBUG_SAVEALL": https://docs.python.org/3/library/gc.html#gc.DEBUG_SAVEALL.
Se puede limpiar "gc.garbage" antes de la ejecución del código que nos interesa analizar.
Editar los audios.
Machine learning para el procesado de audio.
El problema del cocktail: https://en.wikipedia.org/wiki/Cocktail_party_effect y una solución aplicando inteligencia artificial: https://www.technologyreview.com/2015/04/29/168316/deep-learning-machine-solves-the-cocktail-party-problem/.
RNNoise https://jmvalin.ca/demo/rnnoise/.
Jesús ofrece algunos ejemplos de su utilidad.