Un monkey patch, como se define en wikipedia, es una forma para que un programa extienda o modifique localmente el software del sistema de soporte (que afecta solo a la instancia en ejecución del programa).

¿Por qué es importante el monkey patching? Debido a que nos permite ajustar interfaces y modificar comportamientos para nuestras clases y objetos en tiempo de ejecución, lo que facilita el soporte (y parcheo) de problemas que surgen con los cambios de API entre bibliotecas.

Para explicarlo mejor, usaremos un ejemplo concreto Usar pyppeteer en python 3.5.2 no es compatible, porque el módulo de typings no contiene la clase Coroutine. Más tarde se agregó, por lo que Python 3.5.6 lo admite. Sin embargo, ubuntu 16 solo se envía con python 3.5.2 de forma predeterminada.
En nuestro caso, necesitamos ejecutar la aplicación en varios servidores, para que podamos configurar Python a una versión diferente a la predeterminada, o parchear la aplicación para admitir la versión que tenemos.

El error es simple y está presente en el github de pypeteer. Python no puede importar la clase Coroutine desde el módulo de typings.
En pypi, sin embargo, podemos encontrar un módulo que proporciona las definiciones de las clases que faltan: typing extensions.

La idea detrás del monkey patching es modificar sus módulos en tiempo de ejecución, por lo que la lógica subyacente no se da cuenta de que faltan cosas. Parcheas todo a medida que avanzas, para asegurarte de que todo esté en el estado que necesita cuando es necesario. En este caso específico, inyectamos la clase Coroutine de la siguiente manera:

try:
    from pyppeteer import launch
except ImportError:
    from typing_extensions import Coroutine
    typing.Coroutine = Coroutine
    from pyppeteer import launch

El código es bastante sencillo. Intentamos importar el módulo que no es compatible con Python 3.5.2. Esto fallará. En este caso, detectamos el error, importamos la clase que necesitamos y la colocamos dentro del módulo de typings. Una vez que lo hagamos, podremos importar el módulo que originalmente queríamos, porque ahora el módulo tiene su componente definido.

LEER
Análisis de código estático para Python

Esto puede verse como algo “hacky”, y de hecho lo es. Estamos adjuntando elementos extraños al módulo solo para poder ejecutarlo en algunas circunstancias. Esto debe evitarse siempre que sea posible. Codificar explícitamente sus clases y módulos para comportarse como deberían es la mejor manera de hacerlo.
Sin embargo, hay casos válidos en los que un simple monkey patch puede ahorrarle mucho esfuerzo para admitir casos extremos. Esta es otra herramienta útil para tener en tu cinturón cuando tienes que atacar un problema … úsala sabiamente.


Comentarios