{"id":483,"library":"events","title":"Events (pyeve)","description":"The 'events' library for Python, currently at version 0.5, aims to bring the elegance of C# EventHandler to Python. It provides a simple, lightweight mechanism for event subscription and firing, encapsulating the core functionality for attaching and invoking callback functions (event handlers) in sequence, thus facilitating event-driven programming patterns in a straightforward manner. The library is considered mature and stable, with its last release in July 2023, and sees infrequent updates.","status":"maintenance","version":"0.5","language":"python","source_language":"en","source_url":"http://github.com/pyeve/events","tags":["event-driven","publisher-subscriber","callback","observer-pattern","event-handler"],"install":[{"cmd":"pip install events","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"The primary class for creating event publishers.","symbol":"Events","correct":"from events import Events"}],"quickstart":{"code":"from events import Events\n\ndef my_event_handler(reason, data=None):\n    print(f\"Event fired: {reason}\")\n    if data:\n        print(f\"  Data: {data}\")\n\n# Create an Events instance\napp_events = Events()\n\n# Subscribe a handler to an event named 'on_change'\napp_events.on_change += my_event_handler\n\n# Fire the 'on_change' event\nprint(\"Firing event: 'initial change'\")\napp_events.on_change(\"initial change\", data={\"user\": \"admin\"})\n\n# Subscribe another handler to the same event\ndef another_handler(reason):\n    print(f\"Another handler received: {reason}\")\napp_events.on_change += another_handler\n\n# Fire the event again\nprint(\"\\nFiring event again: 'second change'\")\napp_events.on_change(\"second change\")\n\n# Unsubscribe a handler\napp_events.on_change -= my_event_handler\n\n# Fire the event one last time (only 'another_handler' will be invoked)\nprint(\"\\nFiring event after unsubscription: 'final change'\")\napp_events.on_change(\"final change\")\n","lang":"python","description":"Demonstrates how to create an `Events` object, subscribe multiple callback functions using `+=`, fire events, and unsubscribe callbacks using `-=`."},"warnings":[{"fix":"Ensure `event_instance.event_name -= handler_function` is called when the handler is no longer required or the associated object is being disposed of. Consider weak references for advanced scenarios if manual unsubscription is problematic.","message":"The `Events()` instance holds strong references to subscribed callback functions. If an event handler is a method of an object, and the `Events` instance outlives that object, it can prevent the object from being garbage collected, leading to memory leaks. Always explicitly unsubscribe handlers using `-=` when they are no longer needed, especially for object methods.","severity":"gotcha","affected_versions":"0.1 - 0.5"},{"fix":"To enforce predefined events, subclass `Events` and list event names in the class definition, or pass an iterator of event names to the `Events` constructor. Attempts to subscribe to or fire an undefined event will then raise an `EventsException`.","message":"By default, `Events` instances do not predefine event names. This means you can subscribe to and fire any arbitrary event name (e.g., `events.on_typo`). This flexibility can lead to subtle bugs due to typos in event names that might go unnoticed. For stricter validation, you can predefine events.","severity":"gotcha","affected_versions":"0.1 - 0.5"},{"fix":"Always import explicitly (e.g., `from events import Events`) and check the `events.__file__` to confirm you're using the correct package. Refer to documentation specific to `github.com/pyeve/events`.","message":"The package name 'events' is highly generic. There are several other Python libraries and standard library modules (e.g., `eventsourcing`, `pyventus`, `python-dispatch`, `threading.Event`) that deal with event-related patterns. Ensure you are installing and using `pyeve/events` if this is your intended library.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T14:12:40.074Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the library using pip: `pip install Events`. Ensure your import statement is `from events import Event`.","cause":"The 'events' package has not been installed in your Python environment or there is a typo in the import statement.","error":"ModuleNotFoundError: No module named 'events'"},{"fix":"Access event data using `event.sender`, `event.args`, or `event.kwargs`. If you intend to pass named data, use keyword arguments when firing the event and access them via `event.kwargs['your_key']`.","cause":"The base `events.Event` object does not automatically possess arbitrary attributes like 'name' or 'type'. Event data is typically accessed via `event.sender`, `event.args` (for positional arguments), or `event.kwargs` (for keyword arguments).","error":"AttributeError: 'Event' object has no attribute '...' (e.g., 'name', 'type')"},{"fix":"Ensure that the event handler function's parameters (`sender`, `*args`, `**kwargs`) correctly correspond to the arguments passed to `event.fire(sender, *args, **kwargs)`.","cause":"An event handler function was subscribed with a signature (parameters) that does not match the arguments provided when the event is fired.","error":"TypeError: handler_function() missing X required positional argument: 'Y'"}],"ecosystem":"pypi","meta_description":null,"install_score":80,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"17.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"19.7M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"11.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"11.2M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"17.3M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0,"mem_mb":0,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}