46 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			46 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			Python
		
	
	
	
from __future__ import annotations
 | 
						|
 | 
						|
import time
 | 
						|
 | 
						|
 | 
						|
__all__ = ["Deadline"]
 | 
						|
 | 
						|
 | 
						|
class Deadline:
 | 
						|
    """
 | 
						|
    Manage timeouts across multiple steps.
 | 
						|
 | 
						|
    Args:
 | 
						|
        timeout: Time available in seconds or :obj:`None` if there is no limit.
 | 
						|
 | 
						|
    """
 | 
						|
 | 
						|
    def __init__(self, timeout: float | None) -> None:
 | 
						|
        self.deadline: float | None
 | 
						|
        if timeout is None:
 | 
						|
            self.deadline = None
 | 
						|
        else:
 | 
						|
            self.deadline = time.monotonic() + timeout
 | 
						|
 | 
						|
    def timeout(self, *, raise_if_elapsed: bool = True) -> float | None:
 | 
						|
        """
 | 
						|
        Calculate a timeout from a deadline.
 | 
						|
 | 
						|
        Args:
 | 
						|
            raise_if_elapsed: Whether to raise :exc:`TimeoutError`
 | 
						|
                if the deadline lapsed.
 | 
						|
 | 
						|
        Raises:
 | 
						|
            TimeoutError: If the deadline lapsed.
 | 
						|
 | 
						|
        Returns:
 | 
						|
            Time left in seconds or :obj:`None` if there is no limit.
 | 
						|
 | 
						|
        """
 | 
						|
        if self.deadline is None:
 | 
						|
            return None
 | 
						|
        timeout = self.deadline - time.monotonic()
 | 
						|
        if raise_if_elapsed and timeout <= 0:
 | 
						|
            raise TimeoutError("timed out")
 | 
						|
        return timeout
 |