Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Overlays : A case for monkey Patching

I am trying to wrap/monkey patch modules in python. I am trying to develop a a clean means of implementing this that does not interfere with any existing code.

Problem

Given a script that imports some CLASS from a MODULE

from MODULE import CLASS 

I would like to replace MODULE with another _MODULE_. Where _MODULE_ is a patch for the original MODULE. The cleanest interface I can see for this is as follows.

from overlay import MODULE # Switches MODULE for _MODULE
from MODULE import CLASS   # Original import now uses _MODULE_

This is basically monkey patching modules in the same way one would monkey patch classes, functions and methods. I believe if this is done correctly one could consistently patch code in a project specific kind of way.

What is the best way of implementing this ?

like image 246
Carel Avatar asked Oct 22 '16 14:10

Carel


People also ask

What does monkey Patch_all () do?

A monkey patch is a way to change, extend, or modify a library, plugin, or supporting system software locally. This means applying a monkey patch to a 3rd party library will not change the library itself but only the local copy of the library you have on your machine.

What is monkey patching and is it ever a good idea?

Monkey patching is a technique used to dynamically update the behavior of a piece of code at run-time. A monkey patch (also spelled monkey-patch, MonkeyPatch) is a way to extend or modify the runtime code of dynamic languages (e.g. Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc.)

What is Gevent monkey patch?

gevent is a coroutine-based cooperative multitasking python framework that relies on monkey patching to make all code cooperative. Gevent actually draws its lineage from Eve Online which was implemented using Stackless Python which eventually evolved into eventlet which inspired gevent.


1 Answers

>>> import wrapt
>>> @wrapt.when_imported('collections')
... def hook(collections):
...     OldOrderedDict = collections.OrderedDict
...     class MyOrderedDict(OldOrderedDict):
...         def monkey(self):
...             print('ook ook')
...     collections.OrderedDict = MyOrderedDict
...     
>>> from collections import OrderedDict
>>> OrderedDict().monkey()
ook ook
like image 141
wim Avatar answered Sep 22 '22 20:09

wim