{"id":3500,"library":"forbiddenfruit","title":"Forbiddenfruit: Patch Python Built-in Objects","description":"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.","status":"active","version":"0.1.4","language":"en","source_language":"en","source_url":"https://github.com/clarete/forbiddenfruit","tags":["monkey-patching","built-ins","runtime-modification","testing","patching","cpython"],"install":[{"cmd":"pip install forbiddenfruit","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"note":"Used to add or replace an attribute on a built-in type.","symbol":"curse","correct":"from forbiddenfruit import curse"},{"note":"Used to remove an attribute added by `curse`.","symbol":"reverse","correct":"from forbiddenfruit import reverse"},{"note":"A context manager/decorator (added in 0.1.4) that applies a curse and automatically reverses it upon exit.","symbol":"cursed","correct":"from forbiddenfruit import cursed"}],"quickstart":{"code":"from forbiddenfruit import curse, cursed, reverse\n\ndef words_of_wisdom(self):\n    return self * \" blah \"\n\ndef temporary_method(self):\n    return f\"I am a temporary string: {self}\"\n\n# --- Using curse() and reverse() ---\n# Add a new method to the int class\ncurse(int, \"words_of_wisdom\", words_of_wisdom)\nassert (2).words_of_wisdom() == \" blah  blah \"\nprint(f\"int(2).words_of_wisdom(): {(2).words_of_wisdom()}\")\n\n# Remove the added method\nreverse(int, \"words_of_wisdom\")\ntry:\n    (2).words_of_wisdom()\nexcept AttributeError as e:\n    print(f\"Method removed: {e}\")\n\n# --- Using cursed() as a context manager ---\nprint(\"\\n--- Using cursed() as a context manager ---\")\nwith cursed(str, \"temp_str_method\", temporary_method):\n    s = \"hello\"\n    assert s.temp_str_method() == \"I am a temporary string: hello\"\n    print(f\"Inside context: {s.temp_str_method()}\")\n\ntry:\n    \"test\".temp_str_method()\nexcept AttributeError as e:\n    print(f\"Outside context, method removed: {e}\")\n\n# --- Using cursed() as a decorator ---\nprint(\"\\n--- Using cursed() as a decorator ---\")\n@cursed(list, \"first_element\", lambda self: self[0] if self else None)\ndef demonstrate_list_patch():\n    my_list = [1, 2, 3]\n    assert my_list.first_element() == 1\n    print(f\"Inside decorated function: {my_list.first_element()}\")\n\ndemonstrate_list_patch()\n\ntry:\n    [4, 5].first_element()\nexcept AttributeError as e:\n    print(f\"Outside decorated function, method removed: {e}\")","lang":"python","description":"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."},"warnings":[{"fix":"Restrict usage to test suites or isolated development environments. Avoid deploying code that uses `forbiddenfruit` to modify built-ins in shared libraries or critical production systems.","message":"Forbiddenfruit directly modifies Python's built-in types, which is generally discouraged for production code. This can lead to unpredictable behavior, global state corruption, and difficult-to-debug issues, especially when used in complex or shared environments. It is primarily intended for testing or highly isolated development scenarios.","severity":"breaking","affected_versions":"All versions"},{"fix":"Carefully track which attributes are being replaced versus merely added. If replacing an existing attribute, you may need a manual mechanism to re-assign the original method/value if restoration is critical for subsequent operations.","message":"The `reverse()` function only removes attributes previously added by `curse()`. If `curse()` was used to *replace* an existing built-in attribute (e.g., `str.__add__`), `reverse()` will delete the replacement but *not* restore the original built-in attribute, potentially leaving the type without its original functionality.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Only use `forbiddenfruit` with CPython. Do not attempt to use it in environments running alternative Python interpreters, as this will lead to errors or crashes.","message":"Forbiddenfruit is fundamentally dependent on the CPython C API and is therefore incompatible with other Python implementations such as Jython or PyPy. It is tested and designed to work exclusively with CPython.","severity":"breaking","affected_versions":"All versions"},{"fix":"Exercise extreme caution and thoroughly test when attempting to patch dunder methods. Prioritize patching non-dunder methods or consider alternative approaches if dunder method modification proves unstable.","message":"Patching certain dunder (magic) methods, particularly rich comparison methods (e.g., `__le__`) or `__hash__`, can lead to `KeyError` or outright interpreter crashes, especially on specific operating systems (like Windows) or with newer Python versions (e.g., Python 3.13 has reported crashes related to dunder method patching).","severity":"gotcha","affected_versions":"All versions, but issues may be more apparent in specific Python versions or environments."},{"fix":"Only modify built-in objects in ways explicitly demonstrated in `forbiddenfruit`'s official examples. Avoid attempting to alter internal type flags, C-API slots, or cache mechanisms unless you possess a deep understanding of CPython's internal structure and behavior.","message":"Due to its low-level manipulation of Python's internals, improper or undocumented use of `forbiddenfruit` can easily lead to Python interpreter segfaults (crashes) or place the interpreter into an inconsistent state where expected operations break unexpectedly.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}