{"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,"search_vec":"'0.5':11 '2023':71 'aim':12 'attach':38 'bring':14 'c':18 'callback':41,82 'consid':61 'core':35 'current':8 'driven':51,78 'eleg':16 'encapsul':33 'event':1,4,29,43,50,77,87 'event-driven':49,76 'event-handl':86 'eventhandl':19 'facilit':48 'fire':32 'function':36,42 'handler':44,88 'infrequ':74 'invok':40 'juli':70 'last':67 'librari':5,59 'lightweight':26 'manner':57 'matur':62 'mechan':27 'observ':84 'observer-pattern':83 'pattern':53,85 'program':52 'provid':23 'publish':80 'publisher-subscrib':79 'pyev':2 'python':7,21 'releas':68 'see':73 'sequenc':46 'simpl':25 'stabl':64 'straightforward':56 'subscrib':81 'subscript':30 'thus':47 'updat':75 'version':10","created_at":"2026-03-28T15:15:32.824902+00:00","updated_at":"2026-04-16T14:52:22.403094+00:00","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,"quickstart_score":80,"quickstart_tag":"verified","pypi_latest":"0.5","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"http://github.com/pyeve/events","docs":null,"changelog":null,"pypi":"https://pypi.org/project/events/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["communication"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-27","next_check":"2026-07-28","install_tag":"verified"}}