backcall

0.2.0 · maintenance · verified Sun Apr 05

backcall is a Python module designed to create backwards-compatible callback APIs. It enables developers to add new parameters to API calls without breaking existing third-party callback functions that may not be aware of these new parameters. The library is currently at version 0.2.0, last released on June 9, 2020, and appears to be in a maintenance state with infrequent updates.

Warnings

Install

Imports

Quickstart

To use `backcall`, define a 'callback prototype' function using the `@callback_prototype` decorator. This prototype's signature specifies all parameters that your API might pass. Then, use the `prototype.adapt(callback)` method to inspect and potentially wrap user-provided callback functions. If a callback takes fewer arguments than the prototype, `adapt` creates a wrapper that discards the extra arguments. If a callback takes *more* arguments than the prototype, `adapt` will raise a `TypeError`.

from backcall import callback_prototype

@callback_prototype
def my_prototype_handler(sender, message, detail=None):
    # This function defines the expected signature for callbacks.
    # Positional parameters without defaults, keyword-only with defaults (Python 3).
    pass

def register_event_handler(callback_func):
    # The adapt method inspects the callback and wraps it if necessary
    # to discard extra arguments not in the prototype.
    adapted_callback = my_prototype_handler.adapt(callback_func)
    print(f"Registered adapted callback: {adapted_callback.__name__}")
    return adapted_callback

# Example callbacks
def simple_callback(sender, message):
    print(f"Simple: {sender} says '{message}'")

def detailed_callback(sender, message, detail):
    print(f"Detailed: {sender} says '{message}' with detail: {detail}")

def super_detailed_callback(sender, message, detail, extra_arg='default'):
    print(f"Super Detailed: {sender} says '{message}' with detail: {detail} and extra: {extra_arg}")

# Registering and calling
print("--- Registering simple_callback ---")
adapted_simple = register_event_handler(simple_callback)
adapted_simple('System', 'Hello world!')

print("--- Registering detailed_callback ---")
adapted_detailed = register_event_handler(detailed_callback)
adapted_detailed('System', 'Another message', 'Important info')

# This would normally raise TypeError if passed to .adapt directly, 
# but backcall will raise it because the callback has *more* arguments than prototype.
print("\n--- Attempting to register super_detailed_callback (expecting TypeError) ---")
try:
    register_event_handler(super_detailed_callback)
except TypeError as e:
    print(f"Caught expected error: {e}")

view raw JSON →