{"id":4167,"library":"pebble","title":"Pebble","description":"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.","status":"active","version":"5.2.0","language":"python","source_language":"en","source_url":"https://github.com/noxdafox/pebble","tags":["concurrency","multiprocessing","threading","futures","pools","timeouts"],"install":[{"cmd":"pip install pebble","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"note":"While Pebble extends concurrent.futures, the main classes are exposed directly under the `pebble` namespace for convenience.","wrong":"from pebble.concurrent.futures import ProcessPoolExecutor","symbol":"ProcessPool","correct":"from pebble import ProcessPool"},{"note":"Main classes are exposed directly under the `pebble` namespace. `ThreadPool` is an alias for Pebble's enhanced `ThreadPoolExecutor`.","wrong":"from pebble.concurrent.futures import ThreadPoolExecutor","symbol":"ThreadPool","correct":"from pebble import ThreadPool"}],"quickstart":{"code":"from pebble import ProcessPool\nfrom concurrent.futures import TimeoutError\nimport os\nimport time\n\ndef my_task(data, delay):\n    # Simulate some work\n    time.sleep(delay)\n    return f\"Processed {data} after {delay}s on PID {os.getpid()}\"\n\nif __name__ == \"__main__\": # Essential for ProcessPool on Windows/macOS\n    print(\"--- Pebble ProcessPool Quickstart ---\")\n    with ProcessPool(max_workers=2) as pool:\n        print(\"Submitting tasks...\")\n        # schedule returns a future object, allowing timeout directly on the task\n        future1 = pool.schedule(my_task, args=(\"task A\", 1), timeout=2)\n        future2 = pool.schedule(my_task, args=(\"task B\", 3), timeout=2) # This task will intentionally timeout\n\n        print(\"\\nGetting results for task 1 (should succeed):\")\n        try:\n            result1 = future1.result() # blocks until result is ready or timeout/exception\n            print(f\"Result 1: {result1}\")\n        except TimeoutError:\n            print(\"Task 1 timed out!\")\n        except Exception as e:\n            print(f\"Task 1 raised an unexpected exception: {e}\")\n            # For remote exceptions, e.traceback can provide the remote stack trace\n\n        print(\"\\nGetting results for task 2 (should timeout):\")\n        try:\n            result2 = future2.result()\n            print(f\"Result 2: {result2}\")\n        except TimeoutError:\n            print(\"Task 2 timed out as expected!\")\n        except Exception as e:\n            print(f\"Task 2 raised an unexpected exception: {e}\")\n            # For remote exceptions, e.traceback can provide the remote stack trace\n\n    print(\"\\nAll tasks completed or processed in pool.\")","lang":"python","description":"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."},"warnings":[{"fix":"Always import `TimeoutError` from `concurrent.futures`.","message":"When 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`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Wrap your `ProcessPool` initialization and usage within `if __name__ == '__main__':` block.","message":"When 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.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Prefer `pool.schedule()` over `pool.submit()` to leverage Pebble's extended features, especially for robust error handling and timeouts.","message":"Pebble'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.","severity":"gotcha","affected_versions":"All versions"},{"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`.","message":"In 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.","severity":"breaking","affected_versions":">=5.1.0"}],"env_vars":null,"search_vec":"'5.2.0':36 'activ':40 'cadenc':42 'cleaner':18 'concurr':47 'concurrent.futures':9 'current':33 'enhanc':8 'featur':11 'frequent':44 'friend':30 'futur':50 'librari':6 'like':12 'maintain':38 'make':21 'manag':20 'minor':45 'multiprocess':24,48 'pebbl':1,2 'pool':19,51 'process':15 'python':5 'releas':41 'remot':14 'robust':26 'thread':22,49 'timeout':13,52 'traceback':16 'updat':46 'user':29 'user-friend':28 'version':35","created_at":"2026-04-12T03:43:49.573893+00:00","updated_at":"2026-04-16T17:57:45.183470+00:00","problems":[{"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.","cause":"A scheduled task in a `ProcessPool` or a function decorated with `@concurrent.process` exceeded its allotted execution time.","error":"concurrent.futures.TimeoutError"},{"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.","cause":"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.","error":"pebble.ProcessExpired: Process exited with return code X"},{"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.","cause":"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.","error":"multiprocessing.pool.MaybeEncodingError: Error sending result:"},{"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).","cause":"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).","error":"concurrent.futures.BrokenProcessPool"},{"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.","cause":"The `pebble` library is not installed in the Python environment where the code is being executed, or the Python environment is not correctly configured.","error":"ModuleNotFoundError: No module named 'pebble'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"5.2.1","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/noxdafox/pebble","docs":null,"changelog":null,"pypi":"https://pypi.org/project/pebble/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["workflow"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-29","next_check":"2026-07-28","install_tag":null}}