04.30.2021 - By Jesús Cea
Resolución de Issue35930: Raising an exception raised in a "future" instance will create reference cycles https://podcast.jcea.es/python/13
Participantes:
Jesús Cea, email: [email protected], 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:
[email protected], conectando desde
Canarias.
Juan Carlos.
Plutarco, conectando desde Madrid.
Eduardo Castro, email:
[email protected]. 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.
[00:52] Presentaciones.
[03:24] Aviso legal de que se está grabando y objetivos de la
tertulia.
[06:22] Autoimport, ¿debería ser una funcionalidad del IDE?
PyCharm: https://www.jetbrains.com/pycharm/.
[12:52] Los IDEs y las inercias.
PyCharm: https://www.jetbrains.com/pycharm/.
Atajos de teclado.
vim: https://es.wikipedia.org/wiki/Vim.
Ubicuo y poder editar ficheros de forma remota.
Uso del teclado en vez del ratón.
Emacs: https://es.wikipedia.org/wiki/Emacs.
[19:22] Operador morsa (walrus). Sigue usándose muy poco.
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]
[25:57] Erratas en tertulias anteriores:
Migración de Python a Github fue en 2017.
No es "Steering committee" sino "Steering Council".
[27:02] Pablo Galindo forma parte del "council" tras las
últimas elecciones.
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.
[35:37] ¡Spoiler sobre la resolución del "Memory Leak"!
Issue35930: Raising an exception raised in a "future"
instance will create reference cycles
https://bugs.python.org/issue35930.
Traceback:
https://docs.python.org/3/library/traceback.html
Frame:
https://docs.python.org/3/library/traceback.html#traceback.FrameSummary.
Stack:
https://docs.python.org/3/library/traceback.html#stacksummary-objects.
[39:17] Usar una técnica similar para detectar las
características de quien te llama para poder mezclar de forma
más limpia código síncrono y asíncrono.
Biblioteca Unsync: https://pypi.org/project/unsync/.
[41:32] Sigo explicando detalles de la solución del "Memory
Leak".
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!
[47:22] No se está conectando gente desde Hispanoamérica. ¿Por
qué?
[50:07] Más erratas: Los "tracebacks" NO son inmutables.
[50:32] Nuevo método "with_traceback()" a la hora de crear
excepciones:
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 "", line 4, in
File "", line 2, in
File "", 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.
[01:01:52] Sobre el "nivel" de las tertulias y sus motivaciones.
[01:06:12] Referencia rápida a temas de la tertulia anterior:
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/.
[01:09:17] Diagnóstico exhaustivo del bug "Memory Leak", causa
raíz y propuestas de soluciones.
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!
[01:21:32] Ojo a la línea 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.
[01:31:32] Las partes relevantes en el hilo principal son:
https://github.com/python/cpython/blob/3.9/Lib/concurrent/futures/_base.py#L413.
https://github.com/python/cpython/blob/2fe408497e6838b6fb761e42e8f8ffc70bd6f3b1/Lib/concurrent/futures/_base.py#L387.
[01:37:02] ¡Brainstorming!
[01:42:42] try ... finally
Jejeje, alguien propone algo que funcionaría :-).
[01:43:57] Weakref:
https://docs.python.org/3/library/weakref.html. Hay
contertulios que no están familiarizados con el concepto,
Jesús Cea repasa qué son y para qué sirven las "Weakref".
Se pueden "resucitar" objetos.
[01:51:02] Volvemos al hilo, la corrección del bug.
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.
[01:55:12] Comprobar este bug con un test unitario.
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.
[01:59:22] Cuando recoge basura de objetos, podemos pedir que
los guarde en "gc.garbage" para revisarlos:
https://docs.python.org/3/library/gc.html#gc.garbage.
"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.
[02:03:42] Bola extra:
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/.
[02:09:52] Repaso del día para los que llegaron tarde.
[02:12:52] Weakref:
https://docs.python.org/3/library/weakref.html.
Jesús ofrece algunos ejemplos de su utilidad.
[02:19:22] Iteradores WSGI
https://www.python.org/dev/peps/pep-0333/.
[02:21:12] Weakref en caché de objetos Durus
https://www.mems-exchange.org/software/DurusWorks/DurusWorks-1.2.tar.gz/DurusWorks-1.2/doc/durus.html.
[02:23:52] El valor de la tertulia es llevarse algo que probar
en casa.
[02:25:22] La tertulia la hacen los asistentes.
[02:28:36] Final.