Registry / workflow / pebble

pebble

JSON →
library5.2.1pypypi✓ verified 22d ago

Pebble is a Python library that enhances `concurrent.futures` with features like timeouts, remote process tracebacks, and cleaner pool management, making threading and multiprocessing more robust and user-friendly. It is currently at version 5.2.0 and maintains an active release cadence with frequent minor updates.

pip install pebble
INSTALL
IMPORT
SIG · PEBBLE
P
pebble
workflowpythonv5.2.1
Install
1.5s avg
Import
335ms
Disk
16MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
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
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 0.356s · 18.1MB
glibc
py 3.103.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.")
Debug
Known issues
gotchaWhen handling timeouts with `ProcessPool` or `ThreadPool`, the `TimeoutError` exception is from `concurrent.futures`, not directly from `pebble`. Ensure you import it correctly: `from concurrent.futures import TimeoutError`.
fix
Always import `TimeoutError` from `concurrent.futures`.
affects: All versions
gotchaWhen using `ProcessPool`, especially on Windows and macOS, the code that creates the pool must be guarded by `if __name__ == '__main__':`. Failure to do so can lead to `RuntimeError` or infinite recursion when child processes try to re-import the main script.
fix
Wrap your `ProcessPool` initialization and usage within `if __name__ == '__main__':` block.
affects: All versions
gotchaPebble's `schedule()` method provides direct timeout handling and returns futures that can expose the remote traceback of exceptions via `future.exception().traceback`. If you use `concurrent.futures.submit()`, you won't get these enhanced features.
fix
Prefer `pool.schedule()` over `pool.submit()` to leverage Pebble's extended features, especially for robust error handling and timeouts.
affects: All versions
breakingIn version 5.1.0, `Pebble` changed its default `SIGTERM` handling to reset it to the default handler for child processes. If you had custom `SIGTERM` handlers in child processes that relied on Pebble not interfering, this behavior might have changed.
fix
Review `SIGTERM` handling in child processes if you rely on custom signals. The change was intended to fix issues where explicit signal handling was broken by `Pebble`.
affects: >=5.1.0
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.
fix
Increase 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.
fix
Debug 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.
fix
Ensure 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).
fix
Address 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.
fix
Install 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.

Agent activity
21 hits · last 30 days
node
16
Amazon
1
OpenAI (training)
1
Resources
pebble — pip install pebble · libregistry