{"id":681,"library":"pyee","title":"pyee: Python Event Emitter Library","description":"pyee is a Python library that provides an EventEmitter implementation, heavily inspired by Node.js's EventEmitter. It supports synchronous, asynchronous (asyncio, Twisted, Trio), and threaded event handling. The library is currently in version 13.0.1 and maintains a regular release cadence with major updates roughly annually and patch releases in between.","status":"active","version":"13.0.1","language":"python","source_language":"en","source_url":"https://github.com/jfhbrook/pyee","tags":["event emitter","async","events","node.js","event_emitter"],"install":[{"cmd":"pip install pyee","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Requires Python 3.8 or higher.","package":"python","optional":false}],"imports":[{"symbol":"EventEmitter","correct":"from pyee import EventEmitter"},{"note":"Top-level imports for specific emitters were removed in v12.0.0. Import from respective submodules (e.g., pyee.asyncio).","wrong":"from pyee import AsyncIOEventEmitter","symbol":"AsyncIOEventEmitter","correct":"from pyee.asyncio import AsyncIOEventEmitter"}],"quickstart":{"code":"import asyncio\nfrom pyee import EventEmitter\nfrom pyee.asyncio import AsyncIOEventEmitter\n\n# Synchronous EventEmitter\nsync_ee = EventEmitter()\n\n@sync_ee.on('sync_event')\ndef handle_sync_event(data):\n    print(f\"Synchronous event received: {data}\")\n\nsync_ee.emit('sync_event', 'Hello from sync!')\n\n# Asynchronous AsyncIOEventEmitter\nasync_ee = AsyncIOEventEmitter()\n\n@async_ee.on('async_event')\nasync def handle_async_event(data):\n    print(f\"Asynchronous event received: {data}\")\n    await asyncio.sleep(0.1) # Simulate async work\n    print(\"Async handler finished.\")\n\n@async_ee.on('error')\ndef on_async_error(e):\n    print(f\"Async error caught: {e}\")\n\nasync def main():\n    print(\"Emitting async event...\")\n    async_ee.emit('async_event', 'Hello from async!')\n    # Wait for all handlers to complete (new in v12.1.0)\n    await async_ee.wait_for_complete()\n    print(\"All async handlers completed.\")\n\n    print(\"Emitting an error (async)...\")\n    async_ee.emit('error', ValueError(\"Something went wrong in async!\"))\n\nif __name__ == '__main__':\n    asyncio.run(main())\n","lang":"python","description":"This quickstart demonstrates both the synchronous `EventEmitter` and the `AsyncIOEventEmitter` for handling events. It shows how to register listeners using the `@on` decorator and emit events using the `emit` method. For `AsyncIOEventEmitter`, it includes an example of waiting for handlers to complete and basic error handling."},"warnings":[{"fix":"Import the specific emitters from their respective submodules. For example, change `from pyee import AsyncIOEventEmitter` to `from pyee.asyncio import AsyncIOEventEmitter`.","message":"Direct top-level imports of specific EventEmitter subclasses (e.g., `pyee.AsyncIOEventEmitter`, `pyee.TwistedEventEmitter`, `pyee.ExecutorEventEmitter`, `pyee.TrioEventEmitter`) were removed in version 12.0.0.","severity":"breaking","affected_versions":">=12.0.0"},{"fix":"Use `PyeeError` instead of `PyeeException`. `PyeeError` inherits from `PyeeException`.","message":"The `PyeeException` class was deprecated in version 12.0.0.","severity":"deprecated","affected_versions":">=12.0.0"},{"fix":"Review type checking configurations and potentially update Twisted versions or adjust type ignore rules if encountering new type errors related to `twisted.python.Failure`.","message":"Type stub for `twisted.python.Failure` was removed in version 13.0.0, primarily to address typing issues in unsupported Twisted versions. This might affect projects relying on specific type checking behavior.","severity":"breaking","affected_versions":">=13.0.0"},{"fix":"Always attach an `error` listener (`@ee.on('error')`) to `EventEmitter` instances if unhandled exceptions are a concern, especially for synchronous handlers. For `AsyncIOEventEmitter`, be prepared to handle `error` events for exceptions originating in async handlers.","message":"Error handling differs between `EventEmitter` and its asynchronous counterparts. The base `EventEmitter` does not automatically catch or emit exceptions from its handlers; they must be handled explicitly or an `error` listener provided. `AsyncIOEventEmitter` (and other async emitters) *do* automatically emit exceptions on the 'error' event.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-05-12T17:46:54.437Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the library using pip: `pip install pyee`","cause":"The `pyee` library is not installed in the Python environment, or the environment where it's installed is not the one being used.","error":"ModuleNotFoundError: No module named 'pyee'"},{"fix":"Import `EventEmitter` from `pyee.base` for the basic emitter, or from specific submodules like `pyee.asyncio` for an asyncio-compatible emitter: `from pyee.base import EventEmitter` (for synchronous) or `from pyee.asyncio import AsyncIOEventEmitter` (for asyncio).","cause":"In newer versions of `pyee` (post-8.x, specifically since version 9.0.0), the core `EventEmitter` class and its specialized asynchronous/threaded variants are located in submodules like `pyee.base`, `pyee.asyncio`, `pyee.twisted`, etc., rather than directly under the top-level `pyee` package.","error":"ImportError: cannot import name 'EventEmitter' from 'pyee'"},{"fix":"Replace `from pyee import EventEmitter` with `from pyee.base import EventEmitter` for a basic synchronous emitter, or use a specialized emitter like `from pyee.asyncio import AsyncIOEventEmitter` if working with `asyncio`.","cause":"The direct import and usage of `pyee.EventEmitter` as the primary event emitter class is deprecated. Users are encouraged to use the more specific and often more robust emitter types available in dedicated submodules, especially when working with asynchronous or threaded contexts.","error":"DeprecationWarning: pyee.EventEmitter is deprecated and will be removed in a future major version; you should instead use either pyee.AsyncIOEventEmitter, pyee.TwistedEventEmitter, pyee.ExecutorEventEmitter, pyee.TrioEventEmitter, or pyee.BaseEventEmitter."},{"fix":"Upgrade `pyee` to a version that officially supports Python 3.12. For example, `pyee` version 12.0.0 and above addresses this compatibility issue. Use `pip install --upgrade pyee`.","cause":"This error occurs when using `pyee` with Python 3.12 due to a change in how `TypeVar` (a feature used internally by `pyee` for type hinting) handles its 'constraints' argument in Python 3.12. Older `pyee` versions passed `constraints` as a single type, but Python 3.12 requires it to be a tuple.","error":"TypeError: constraints must be a tuple"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":"13.0.1","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":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.7,"disk_size":"18.2M"},{"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.01,"mem_mb":0.7,"disk_size":"18.2M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.6,"import_time_s":0.01,"mem_mb":0.7,"disk_size":"19M"},{"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.01,"mem_mb":0.7,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.8,"disk_size":"20.1M"},{"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.02,"mem_mb":0.8,"disk_size":"20.1M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.7,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"21M"},{"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.02,"mem_mb":1.1,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.8,"disk_size":"12.0M"},{"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.02,"mem_mb":0.8,"disk_size":"12.0M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.02,"mem_mb":0.8,"disk_size":"12M"},{"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.02,"mem_mb":0.8,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.9,"disk_size":"11.7M"},{"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.02,"mem_mb":0.9,"disk_size":"11.6M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.5,"import_time_s":0.01,"mem_mb":0.8,"disk_size":"12M"},{"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.01,"mem_mb":0.8,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"17.7M"},{"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.01,"mem_mb":0.6,"disk_size":"17.7M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":" $EXIT -eq 0 ","exit_code":0,"wheel_type":"wheel","failure_reason":null,"install_time_s":1.9,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"18M"},{"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.01,"mem_mb":0.6,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-24","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}]}}