{"id":484,"library":"execnet","title":"execnet: Distributed Python Deployment and Communication","description":"execnet is a Python library that provides carefully tested means to ad-hoc interact with Python interpreters across different versions, platforms, and network barriers. It offers a minimal and fast API for distributing tasks to local or remote processes, writing hybrid multi-process applications, and administering multiple hosts. The project is currently in maintenance-only mode, with a focus on bug fixes, and is not recommended for new projects. The current stable version is 2.1.2, with releases driven by bug fixes and Python version compatibility updates.","status":"maintenance","version":"2.1.2","language":"python","source_language":"en","source_url":"https://github.com/pytest-dev/execnet","tags":["remote execution","multi-process","distributed computing","inter-process communication","python interpreter","pytest-xdist"],"install":[{"cmd":"pip install execnet","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"While `from execnet import makegateway` might work, the official examples consistently use `execnet.makegateway()`, implying a preference for accessing it through the main `execnet` module object.","wrong":"from execnet import makegateway","symbol":"makegateway","correct":"import execnet\ngateway = execnet.makegateway()"},{"note":"Accessed directly from a `Gateway` object returned by `execnet.makegateway()`.","symbol":"remote_exec","correct":"channel = gateway.remote_exec(source_code)"}],"quickstart":{"code":"import execnet\n\ngateway = execnet.makegateway()\nchannel = gateway.remote_exec(\"channel.send('hello from remote!')\")\nmessage = channel.receive()\nprint(f\"Received from remote: {message}\")\nchannel.send('hello from local!')\nchannel.waitclose()\ngateway.exit()","lang":"python","description":"This quickstart demonstrates creating a local subprocess gateway, executing code on it, and establishing bidirectional communication using a channel. The remote code sends a message, which is received locally, and then a message is sent back to the remote before closing the connection."},"warnings":[{"fix":"For new projects, consider alternatives like multiprocessing, concurrent.futures, or dedicated message queues (e.g., Celery, RabbitMQ) depending on your use case.","message":"execnet is in maintenance-only mode and should not be used for new projects. Modern Python's capabilities for inter-interpreter communication often make `execnet` unnecessary. It is primarily maintained because it serves as the backend for `pytest-xdist`.","severity":"deprecated","affected_versions":"All versions"},{"fix":"Upgrade your Python interpreter to 3.8 or newer. If you need to support older Python versions, you must use an older `execnet` release (e.g., <2.0.0 for Python <3.7).","message":"Version 2.0.0 dropped support for Python versions older than 3.7. Ensure your environment meets the minimum Python requirement of >=3.8.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Ensure your Python environment is 2.7 (for older series) or 3.4+ (for 1.5.x to <2.0.0 series). For current versions, refer to the Python >=3.8 requirement.","message":"Version 1.5.0 removed support for Python 2.6 and 3.3. Earlier versions of Python 3.x (e.g., 3.3) are no longer supported.","severity":"breaking","affected_versions":">=1.5.0"},{"fix":"Avoid spaces in Python interpreter pathnames if possible. If unavoidable, thoroughly test your gateway specifications with quoted or escaped paths, or consider using a wrapper script on the remote end to call the desired interpreter.","message":"When using `python=` in a gateway specification, especially with `popen` or `ssh` gateways, pathnames containing spaces can lead to potential regressions or unexpected behavior due to the internal use of `shlex.split`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always use `execnet.dumps` and `execnet.loads` for reliable cross-interpreter serialization. Ensure all communicating `execnet` instances are running compatible versions, ideally the same version, especially regarding serialization.","message":"The `execnet.dumps` and `execnet.loads` API for cross-interpreter compatible serialization of Python builtin types was introduced in version 1.1. Using serialization mechanisms across different `execnet` versions or without these explicit functions might lead to incompatibility issues.","severity":"gotcha","affected_versions":"<1.1 (for missing API), All versions (for general serialization compatibility)"},{"fix":"Investigate the remote process for unhandled exceptions, explicit channel closures, or issues preventing it from processing messages. Ensure the remote end properly manages its channel lifecycle and does not close it before all expected communication from the local side is complete. Implement robust error handling on both ends to manage channel state gracefully.","message":"Attempting to send data over an `execnet` channel that has already been closed results in an `OSError: cannot send to <Channel id=... closed>`. This often indicates that the remote peer closed its end of the channel prematurely, possibly due to an unhandled exception, explicit closure, or a communication breakdown.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-05-12T14:12:56.756Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the 'execnet' library using pip: `pip install execnet`","cause":"The 'execnet' package is not installed in the Python environment where the code is being run.","error":"ModuleNotFoundError: No module named 'execnet'"},{"fix":"Ensure 'execnet' is correctly installed. If bundling with PyInstaller, explicitly include 'execnet.rsync' as a hidden import: `pyinstaller --hidden-import=execnet.rsync your_script.py`","cause":"This specific sub-module, often used by 'pytest-xdist', cannot be found. This can occur if 'execnet' is not fully or correctly installed, or if there are issues with bundling applications (e.g., with PyInstaller) that prevent sub-modules from being properly included.","error":"ModuleNotFoundError: No module named 'execnet.rsync'"},{"fix":"Ensure that the 'execnet' version is consistent across both the local and remote Python environments. If explicitly setting `execmodel`, try removing it or checking for compatibility with the target Python interpreter and 'execnet' version.","cause":"This error typically arises from an incompatibility in 'execnet's internal communication, often when connecting to a remote Python interpreter with an older or different 'execnet' version that does not recognize or expect the 'execmodel' keyword argument during gateway bootstrapping.","error":"execnet.gateway_base.RemoteError: Traceback (most recent call last): ... TypeError: __init__() got an unexpected keyword argument 'execmodel'."},{"fix":"Verify that an SSH server is running on the remote machine and is configured to accept connections. Check firewall rules on both the local and remote machines to ensure the necessary ports are open. Confirm that the remote host's IP address/hostname is correct and reachable.","cause":"The 'execnet' gateway could not establish a connection to the specified remote host because the connection was actively refused. This often indicates that an SSH server is not running on the remote machine, or firewall rules are blocking the connection.","error":"Error 111: Connection Refused"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","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.04,"mem_mb":2.1,"disk_size":"18.1M"},{"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.03,"mem_mb":2.1,"disk_size":"19M"},{"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.08,"mem_mb":2.5,"disk_size":"20.0M"},{"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.06,"mem_mb":2.5,"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.09,"mem_mb":2.5,"disk_size":"11.9M"},{"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.07,"mem_mb":2.5,"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.06,"mem_mb":2.7,"disk_size":"11.5M"},{"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.06,"mem_mb":2.5,"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.04,"mem_mb":2,"disk_size":"17.6M"},{"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.03,"mem_mb":2,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}