Python en español #13: Tertulia 2020-12-29

30/04/2021 2h 29min

Escuchar "Python en español #13: Tertulia 2020-12-29"

Síntesis del Episodio


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




[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.