"""Standalone utilities for run-iocsh."""importloggingimporttimefromcollections.abcimportCallablefromrun_iocsh.iocimportDEFAULT_POLL_INTERVAL,DEFAULT_WAIT_FOR_TIMEOUT
[docs]defwait_for(predicate:Callable[[],bool],timeout:float=DEFAULT_WAIT_FOR_TIMEOUT,poll_interval:float=DEFAULT_POLL_INTERVAL,)->None:"""Poll ``predicate`` until it returns True or ``timeout`` elapses. Exceptions from ``predicate`` are caught and treated as a false result (polling continues until timeout). Args: predicate: Callable invoked repeatedly; success when it returns True. timeout: Maximum seconds to wait before giving up. poll_interval: Seconds to sleep between polls. Raises: TimeoutError: If the predicate never returns True within ``timeout``. """deadline=time.monotonic()+timeoutwhileTrue:try:ifpredicate():returnexceptException:# noqa: BLE001log.debug("wait_for: predicate raised, treating as False",exc_info=True)iftime.monotonic()>=deadline:raiseTimeoutError(f"Timed out after {timeout}s waiting for predicate")time.sleep(poll_interval)