Install & Compatibility
Where this runs
tested against v5.2.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.356s · 18.1MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.5s · import 0.314s · 19MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
ProcessPool
✓ from pebble import ProcessPool
✗ from pebble.concurrent.futures import ProcessPoolExecutor
While Pebble extends concurrent.futures, the main classes are exposed directly under the `pebble` namespace for convenience.
ThreadPool
✓ from pebble import ThreadPool
✗ from pebble.concurrent.futures import ThreadPoolExecutor
Main classes are exposed directly under the `pebble` namespace. `ThreadPool` is an alias for Pebble's enhanced `ThreadPoolExecutor`.
This quickstart demonstrates how to use Pebble's `ProcessPool` to execute functions in separate processes with built-in timeouts. It covers scheduling tasks, retrieving results, and handling `TimeoutError` as well as other exceptions. The `if __name__ == '__main__':` block is crucial for `ProcessPool` on Windows and macOS.
from pebble import ProcessPool
from concurrent.futures import TimeoutError
import os
import time
def my_task(data, delay):
# Simulate some work
time.sleep(delay)
return f"Processed {data} after {delay}s on PID {os.getpid()}"
if __name__ == "__main__": # Essential for ProcessPool on Windows/macOS
print("--- Pebble ProcessPool Quickstart ---")
with ProcessPool(max_workers=2) as pool:
print("Submitting tasks...")
# schedule returns a future object, allowing timeout directly on the task
future1 = pool.schedule(my_task, args=("task A", 1), timeout=2)
future2 = pool.schedule(my_task, args=("task B", 3), timeout=2) # This task will intentionally timeout
print("\nGetting results for task 1 (should succeed):")
try:
result1 = future1.result() # blocks until result is ready or timeout/exception
print(f"Result 1: {result1}")
except TimeoutError:
print("Task 1 timed out!")
except Exception as e:
print(f"Task 1 raised an unexpected exception: {e}")
# For remote exceptions, e.traceback can provide the remote stack trace
print("\nGetting results for task 2 (should timeout):")
try:
result2 = future2.result()
print(f"Result 2: {result2}")
except TimeoutError:
print("Task 2 timed out as expected!")
except Exception as e:
print(f"Task 2 raised an unexpected exception: {e}")
# For remote exceptions, e.traceback can provide the remote stack trace
print("\nAll tasks completed or processed in pool.")
Errors
Common errors & fixes
concurrent.futures.TimeoutError
A scheduled task in a `ProcessPool` or a function decorated with `@concurrent.process` exceeded its allotted execution time.
fixIncrease the `timeout` parameter when scheduling the task or decorating the function, or optimize the task function to complete within the specified duration. Ensure your code handles this exception gracefully.
pebble.ProcessExpired: Process exited with return code X
A worker process in the `ProcessPool` died unexpectedly during execution, often due to an unhandled exception within the worker function, a segmentation fault, or being terminated by the operating system.
fixDebug the worker function to identify and fix unhandled exceptions or resource issues. The `ProcessExpired` object often contains `exitcode` and `traceback` attributes which can provide more details for debugging.
multiprocessing.pool.MaybeEncodingError: Error sending result:
This error occurs when objects passed as arguments to a worker process or returned from a worker process are not 'picklable' (cannot be serialized by Python's `pickle` module), which `pebble` uses for inter-process communication.
fixEnsure that all data (arguments and return values) exchanged with functions executed in a `ProcessPool` are picklable. Avoid passing unpicklable objects like locks, file handles, or complex custom objects without a `__reduce__` method.
concurrent.futures.BrokenProcessPool
The `ProcessPool` became unusable because one or more worker processes crashed or were terminated abruptly, often due to unhandled exceptions, memory exhaustion, or issues related to the multiprocessing start method (e.g., `fork` with multithreaded code).
fixAddress the root cause of worker crashes. If working on Unix-like systems and mixing threads with processes, explicitly set the multiprocessing start method to `spawn` or `forkserver` (e.g., `multiprocessing.set_start_method('spawn')` at the beginning of your main script). ModuleNotFoundError: No module named 'pebble'
The `pebble` library is not installed in the Python environment where the code is being executed, or the Python environment is not correctly configured.
fixInstall the `pebble` library using pip: `pip install pebble`. If using virtual environments, ensure the correct environment is activated before installation and running your script.
Upgrade
Version history
5.2.1latest on PyPI · released Jul 19, 2026
Audit
Dependencies
No dependency data recorded yet.