advanced

Monkey Patching in Python

6 min read

Overview

Monkey Patching is a technique where you dynamically update, override, or extend a module, class, or function at runtime without modifying the original source code file.

Learning Objectives

  • Learn how Python functions and methods are dynamic attributes.
  • Use monkey patching to replace third-party or API calls during unit tests.
  • Understand dangerous side-effects of monkey patching in production environments.

Concept Explanation

In Python, classes and functions are mutable objects. You can reassign a class method or module function at runtime:

text
Original Class (DBClient.fetch)  --->  Reassign Function at Runtime  --->  Patched Mock Method (MockFetch)

In simple words: You swap out a real function with your custom function while the program is running!

Code Examples

Example 1 — Basic Monkey Patching Demonstration

python
import time

class PaymentProcessor:
    def process_transaction(self, amount):
        print("Connecting to live bank gateway...")
        time.sleep(3) # Slow network operation
        return f"Paid ${amount} successfully"

# Define a fast mock function for testing
def mock_fast_payment(self, amount):
    return f"[MOCK] Paid ${amount} instantly"

# Perform Monkey Patching by reassigning the method
PaymentProcessor.process_transaction = mock_fast_payment

processor = PaymentProcessor()
# Invokes mock_fast_payment without network delay!
print(processor.process_transaction(100))

Example 2 — Safe Monkey Patching with Unit Tests (unittest.mock)

python
from unittest.mock import patch

class Database:
    def query(self):
        return "Real DB Data"

def run_app():
    db = Database()
    return db.query()

# Safely patch Database.query only within the test context
with patch.object(Database, 'query', return_value="Mock Data"):
    print("Inside patch:", run_app()) # Mock Data

# Original function is automatically restored outside the context
print("Outside patch:", run_app()) # Real DB Data

Common Mistakes

  • Monkey Patching in Production Code: Swapping methods globally in live application code makes debugging nearly impossible because stack traces won't match source files.
  • Forgetting to Restore Original Methods: If you monkey patch without unittest.mock.patch or cleanup, other tests running in the same process will inherit the patched behavior.

Best Practices

  • Use monkey patching exclusively inside unit tests to isolate external network services, databases, or APIs.
  • Use unittest.mock.patch or pytest monkeypatch fixture to guarantee automatic cleanup.