Saturday, March 30, 2019

Shyama Sankar Vellore: Monkey Patching in Python: Explained with Examples

In this post, we will learn about monkey patching, i.e., how to dynamically update code behavior at runtime. We will also see some useful examples of monkey patching in Python.

Table of contents

Monkey patching

What is monkey patching?

Monkey patching is a technique used to dynamically update the behavior of a piece of code at run-time.

Why use monkey patching?

It allows us to modify or extend the behavior of libraries, modules, classes or methods at runtime without actually modifying the source code.

When is monkey patching used?

Some common applications of monkey patching are:
  • To extend or modify the behavior of third-party or built-in libraries or methods at runtime without touching the original code.
  • During testing to mock the behavior of libraries, modules, classes or any objects.
  • To quickly fix some issues if we do not have the time or resources to roll-out a proper fix to the original software.

Cautionary note: Why monkey patching should be used carefully

Monkey patching should be used very carefully, especially if used in production software (would not recommend unless absolutely necessary). Some of the reasons are:
  • If we change the behavior of a method by monkey patching, it no longer behaves the way it was documented. So unless every client or user is aware of this change, it could cause their code to behave unexpectedly.
  • It makes it harder to troubleshoot issues.
  • If we are monkey patching a method in one module and another module is using that same method after the patch is applied, then the second module will also end up seeing the monkey patched method instead of its original version. This can lead to unwanted bugs.

Monkey patching in Python

In Python, modules or classes are just like any other mutable objects like lists, i.e., we can modify them or their attributes including functions or methods at runtime. Let us go through some examples to understand this clearly and learn how to monkey patch in Python.

Example 1: Monkey patching the value of a module's attribute

As a basic example, let us see how we could update a module's attribute. We will be updating the value of "pi" in the "math" module so that its precision is reduced to 3.14.

Note how we took a backup of the original value before our computation and then removed the patch at the end. This is a good practice, especially in tests, to avoid messing up the whole test suite.

Example 2: Monkey patching to extend the behavior of a method

In this example, we will see how to extend the behavior of a method using monkey patching. We will take a look at how to update the builtin print method in Python3 to include a timestamp.

Example 3: Monkey patching to change the behavior of a method

Now let us see how to completely change the behavior of a method. This can be particularly useful in unit tests to mock complex methods, with external dependencies (network, database, etc). Here, we will take a look at how to replace a method with another.

Example 4: Monkey patching class attributes

So far, we have been updating attributes or methods at the module level. Now let us take a look at how to monkey patch a class attribute. Note that this modifies the attribute for the class itself, all of its instances will see the patched attribute.

Example 5: Monkey patching a specific instance's attributes

The previous example showed how to monkey patch a class attribute. Here we will see how to patch just a specific instance's attribute.

Note that we made use of the MethodType method from types module in Python to bind the patched method to just one instance. This assures that other instances of the class are not affected.

Example 6: Monkey patching a class

Now let us see how we would monkey patch a class. Since a class is also just an object, we can monkey patch it with any other object. Here we will see an example of patching it with another class.

Example 7: Monkey patching a module

As the last example, let us see how we can patch an entire module. This works the same way as any other Python object.

Conclusion

Monkey patching is a cool technique and now we have learned how to do that in Python. However, as we discussed, it has its own drawbacks and should be used carefully.


from Planet Python
via read more

No comments:

Post a Comment

TestDriven.io: Working with Static and Media Files in Django

This article looks at how to work with static and media files in a Django project, locally and in production. from Planet Python via read...