Forbiddenfruit is a Python library designed to extend or modify built-in types at runtime. It achieves this by patching built-in objects that are declared in C through Python's C API. While powerful, it is primarily intended for scenarios like advanced testing or profiling, rather than general production use due to its potential for unexpected side effects. The current version, 0.1.4, was released in January 2021, and the project has an infrequent release cadence.
Install & Compatibility
Where this runs
tested against v0.1.4 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.925 runs
installs and imports cleanly · install 0.0s · import 0.035s · 19.2MB
glibcpy 3.10–3.925 runs
installs and imports cleanly · install 2.4s · import 0.041s · 20MB
17MB installed
● package 17MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Used to add or replace an attribute on a built-in type.
from forbiddenfruit import curse
Used to remove an attribute added by `curse`.
from forbiddenfruit import reverse
A context manager/decorator (added in 0.1.4) that applies a curse and automatically reverses it upon exit.
from forbiddenfruit import cursed
This quickstart demonstrates how to add new methods to built-in types (`int`, `str`, `list`) using `curse()` and `cursed()`. It also shows how to remove modifications using `reverse()` or by leveraging the automatic cleanup of `cursed()` as a context manager or decorator.
from forbiddenfruit import curse, cursed, reverse
def words_of_wisdom(self):
return self * " blah "
def temporary_method(self):
return f"I am a temporary string: {self}"
# --- Using curse() and reverse() ---
# Add a new method to the int class
curse(int, "words_of_wisdom", words_of_wisdom)
assert (2).words_of_wisdom() == " blah blah "
print(f"int(2).words_of_wisdom(): {(2).words_of_wisdom()}")
# Remove the added method
reverse(int, "words_of_wisdom")
try:
(2).words_of_wisdom()
except AttributeError as e:
print(f"Method removed: {e}")
# --- Using cursed() as a context manager ---
print("\n--- Using cursed() as a context manager ---")
with cursed(str, "temp_str_method", temporary_method):
s = "hello"
assert s.temp_str_method() == "I am a temporary string: hello"
print(f"Inside context: {s.temp_str_method()}")
try:
"test".temp_str_method()
except AttributeError as e:
print(f"Outside context, method removed: {e}")
# --- Using cursed() as a decorator ---
print("\n--- Using cursed() as a decorator ---")
@cursed(list, "first_element", lambda self: self[0] if self else None)
def demonstrate_list_patch():
my_list = [1, 2, 3]
assert my_list.first_element() == 1
print(f"Inside decorated function: {my_list.first_element()}")
demonstrate_list_patch()
try:
[4, 5].first_element()
except AttributeError as e:
print(f"Outside decorated function, method removed: {e}")
Upgrade
Version history
Breaking-change detection hasn't run for this library yet.
Audit
Security & dependencies
CVE tracking and dependency tree are planned for a later release.