func-timeout
`func-timeout` is a Python module that enables setting timeouts for arbitrary function calls, preventing them from running indefinitely. It achieves this by executing the function in a separate thread and forcefully terminating it if the specified duration is exceeded. The latest version is 4.3.6, with a historically sporadic release cadence, recently updated to support newer Python versions.
Warnings
- gotcha Thread Termination Safety: `func-timeout` achieves timeouts by forcefully terminating a separate thread. This is inherently unsafe in Python, as threads cannot be reliably or gracefully stopped. This can lead to resource leaks (e.g., open files, network connections), corrupted shared state, or deadlocks if the timed-out function was holding locks or critical resources.
- gotcha Unpredictable Tracebacks and Cleanup: In versions prior to 4.1.0, tracebacks might have been less clear, and explicit thread cleanup might not have occurred reliably, potentially leading to zombie threads or resource issues. Version 4.0.0 also fixed issues where tracebacks could be printed to stderr outside the normal exception handling.
- gotcha Decorator Metadata Loss (pre-4.3.0): When using the `@func_set_timeout` decorator in versions prior to 4.3.0, the decorated function might lose its original metadata (e.g., `__name__`, `__doc__`). This can affect introspection tools or other decorators in a chain.
- gotcha Python Version Compatibility: Older versions of `func-timeout` might use deprecated threading API calls (e.g., `isA` instead of `is_alive` in versions before 4.3.4) or have less robust support for newer Python interpreters.
Install
-
pip install func-timeout
Imports
- func_timeout
from func_timeout import func_timeout
- func_set_timeout
from func_timeout import func_set_timeout
- FunctionTimedOut
from func_timeout import FunctionTimedOut
Quickstart
import time
from func_timeout import func_timeout, FunctionTimedOut, func_set_timeout
def long_running_function(duration):
print(f"Starting long_running_function for {duration} seconds...")
time.sleep(duration)
print("long_running_function completed.")
return "Done"
# Example 1: Using func_timeout for a direct call
try:
print("\n--- Using func_timeout ---")
result = func_timeout(1, long_running_function, args=(5,))
print(f"Result: {result}")
except FunctionTimedOut:
print("Function timed out after 1 second!")
except Exception as e:
print(f"An unexpected error occurred: {e}")
# Example 2: Using func_set_timeout decorator
@func_set_timeout(1)
def decorated_function(duration):
print(f"Starting decorated_function for {duration} seconds...")
time.sleep(duration)
print("decorated_function completed.")
return "Decorated Done"
try:
print("\n--- Using func_set_timeout decorator ---")
result = decorated_function(5)
print(f"Result from decorator: {result}")
except FunctionTimedOut:
print("Decorated function timed out after 1 second!")
except Exception as e:
print(f"An unexpected error occurred: {e}")