Monkey patching changes what an object, class, module, or name does while a Python program is running, without changing its original source definition. It is a technique, not a Python keyword or one particular library. A common, relatively safe use is a narrowly scoped test that substitutes a dependency—such as an environment variable or API call—and restores the original state afterward.
What is monkey patching in Python?
A monkey patch changes or replaces behavior at runtime. You might assign a different function to a module attribute, replace a class method, alter a mapping, or bind a name to a substitute. The term describes the general technique; it is not limited to tests and does not refer to one specific Python feature.
For example, suppose a module reads the current working directory through an imported function:
# mymodule.py
from os import getcwd
def current_folder():
return getcwd()
A test can replace the name that mymodule looks up while the test runs. That replacement is a monkey patch. It need not modify mymodule.py on disk.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →#1 Best Overall
- Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
- Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
- Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
- Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
- 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
When is monkey patching useful?
Its strongest everyday use is controlling dependencies in tests. A test can avoid a real network request, database connection, filesystem operation, or machine-specific setting by substituting predictable behavior. That makes the test faster or more isolated and lets it check a particular condition reliably.
- Set or remove an environment variable for one test.
- Replace a function or property with a controlled implementation.
- Change a dictionary or module attribute temporarily.
- Set a test-specific working directory or import path.
- Use a mock when the test also needs to assert how a dependency was called.
For production code, a global runtime patch is usually a poor way to make a durable customization. If you control the code, pass the dependency in explicitly where practical. That makes the dependency visible and replaceable without silently changing shared state.
Patch the name the code actually looks up
Python names can refer to the same original object without remaining the same binding. In the example above, mymodule.getcwd is a name imported into that module. Replacing os.getcwd later does not necessarily replace the already-imported name that current_folder() calls.
Rank #2
- 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
- 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
- Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
- 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
- What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
Patch the lookup site used by the code under test:
import mymodule
def fake_getcwd():
return "/test/folder"
# Replace the name current_folder() resolves.
mymodule.getcwd = fake_getcwd
assert mymodule.current_folder() == "/test/folder"
This direct assignment demonstrates the idea, but it leaves the changed binding in place until something restores it. For tests, use a scoped tool so cleanup happens even if an assertion fails.
Free tools Windows power users keep installed
One-click scans. No signup required.
Use pytest monkeypatch for scoped test changes
pytest provides a fixture named monkeypatch. pytest automatically undoes its changes at test teardown. Its methods cover common operations including setting attributes, dictionary entries, environment variables, the working directory, and the import path.
Replace a function attribute
def test_current_folder(monkeypatch):
import mymodule
monkeypatch.setattr(mymodule, "getcwd", lambda: "/test/folder")
assert mymodule.current_folder() == "/test/folder"
The patch targets mymodule.getcwd, the name the function uses. By default, setattr expects the attribute to exist; use raising=False only when creating a previously absent attribute is intentional.
Rank #3
- Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
- Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
- Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
- Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
- What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.
Set an environment variable
import os
def read_mode():
return os.environ.get("APP_MODE", "default")
def test_read_mode(monkeypatch):
monkeypatch.setenv("APP_MODE", "test")
assert read_mode() == "test"
pytest restores the prior environment after the test, including removing the variable if it did not exist before. To remove a variable for a test, use monkeypatch.delenv("APP_MODE", raising=False); the flag avoids an error if the variable is already absent.
Other common pytest operations
def test_configuration(monkeypatch, tmp_path):
settings = {"mode": "production"}
monkeypatch.setitem(settings, "mode", "test")
assert settings["mode"] == "test"
monkeypatch.chdir(tmp_path)
assert Path.cwd() == tmp_path
For this example, add from pathlib import Path. pytest also supports deleting attributes or mapping entries, changing sys.path, and temporarily changing the current directory. Use the fixture’s corresponding method so teardown can undo the change.
Limit a risky patch to a smaller block
If a patch should last for only part of a test, use monkeypatch.context():
Rank #4
- Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
- Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
- Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
- Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
- Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft
def test_one_operation(monkeypatch):
import mymodule
with monkeypatch.context() as patch:
patch.setattr(mymodule, "getcwd", lambda: "/temporary")
assert mymodule.current_folder() == "/temporary"
# The original binding has been restored here.
Use unittest.mock.patch when you need interaction assertions
unittest.mock.patch temporarily rebinds a target, usually to a mock, and restores it when its context exits or its decorated function finishes. A mock records calls, so the test can assert that the code used the dependency as expected.
from unittest.mock import patch
import mymodule
def test_current_folder_calls_getcwd():
with patch("mymodule.getcwd", return_value="/test/folder") as getcwd:
assert mymodule.current_folder() == "/test/folder"
getcwd.assert_called_once_with()
The target string names the object to patch where it is looked up. Like pytest’s fixture, patch should generally target the consumer’s namespace, not automatically the module where a function was first defined.
pytest monkeypatch or unittest.mock.patch?
| Need | Useful choice | Why |
|---|---|---|
| Change an attribute, mapping, environment variable, import path, or working directory and undo it automatically | pytest monkeypatch |
The fixture has methods for these common test changes and undoes them at teardown. |
| Replace a target with a mock and assert calls or arguments | unittest.mock.patch |
It can create a mock that records how tested code interacted with it. |
| Keep an unusual or risky patch limited to a small block | monkeypatch.context() or a patch() context manager |
Both bound the change and restore it when the block exits. |
These tools are not competing definitions of monkey patching: both can temporarily alter bindings. Choose according to the operation and whether you need call assertions. If a mock’s flexibility might hide a changed interface, use spec or autospec where appropriate and retain integration tests for the way components connect.
Best Value
- 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
- Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
- Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
- HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
- What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
How to keep patches safe
- Target the consumer’s namespace. Follow the name resolution used by the function under test, especially when code imported a name directly.
- Keep scope narrow. Use pytest’s automatic teardown, a smaller
monkeypatch.context()block, or apatch()context manager. - Avoid patching builtins casually. Replacing builtins such as
openorcompilecan disrupt pytest itself or libraries used by the test runner. If it is unavoidable, isolate it in the smallest practical block. - Prefer explicit dependencies in code you own. Passing a dependency into a function or object makes it easier to substitute deliberately than changing a global binding.
- Do not let mocks conceal API drift. A permissive mock can let a test pass after the real interface changes. Add an appropriate spec and test important component connections.
Or skip the browser setup
If a Python test needs a website screenshot rather than a locally controlled browser, ScreenshotNeo offers a screenshot API: a GET request with a URL can return an image or PDF. Its API call is separate from Python monkey patching, but can substitute for setting up a browser capture dependency.
ScreenshotNeo API documentation
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
Cookie and consent banners, newsletter popups, and chat widgets are removed before capture; each removal step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status. An MCP server provides screenshot tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000.
Sign up for ScreenshotNeo’s free plan.
Frequently Asked Questions
Does monkey patching require changing a Python source file?
No. A patch changes runtime behavior or a binding while the program runs; it does not require editing the original source definition.
Can pytest monkeypatch and unittest.mock.patch be used in the same project?
Yes. They serve overlapping purposes, and a project can use either or both where each fits the test.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




