# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
-from typing import Iterator, Optional, TextIO, Any, List, Union, Pattern, Match
+from typing import Any, Iterator, List, Match, Optional, Pattern, TextIO, TypeVar, Union
import abc
import os
FlexPattern = Union[str, Pattern]
+T = TypeVar("T")
+OneOrMore = Union[T, List[T]]
class WatchLogException(Exception):
return
yield line
- def _prepare_patterns(
- self, strings: Union[FlexPattern, List[FlexPattern]]
- ) -> List[Pattern]:
+ def _setup_wait(self, patterns: OneOrMore[FlexPattern]) -> List[Pattern]:
+ self._wait_function_called = True
+ self._deadline = time.monotonic() + self._timeout
+ return self._prepare_patterns(patterns)
+
+ def _prepare_patterns(self, strings: OneOrMore[FlexPattern]) -> List[Pattern]:
"""
Convert a mix of string(s) and/or pattern(s) into a list of patterns.
)
return patterns
- def wait_for_line(self, patterns: Union[FlexPattern, List[FlexPattern]]) -> Match:
+ def _wait_for_match(self, regexes: List[Pattern]) -> Match:
+ while time.monotonic() < self._deadline:
+ for line in self._readlines():
+ for regex in regexes:
+ match = regex.search(line)
+ if match:
+ return match
+ time.sleep(0.1)
+ raise WatchLogTimeout(
+ f"Timeout reached watching {self._path} for "
+ f"{' | '.join([regex.pattern for regex in regexes])}"
+ )
+
+ def wait_for_line(self, patterns: OneOrMore[FlexPattern]) -> Match:
"""
Block execution until any line of interest appears in the log file.
>>> print(match2.group(0))
qux
"""
- regexes = self._prepare_patterns(patterns)
- self._wait_function_called = True
- self._deadline = time.monotonic() + self._timeout
+ regexes = self._setup_wait(patterns)
return self._wait_for_match(regexes)
...
isctest.log.watchlog.WatchLogTimeout: ...
"""
- regexes = self._prepare_patterns(patterns)
- self._wait_function_called = True
- self._deadline = time.monotonic() + self._timeout
+ regexes = self._setup_wait(patterns)
matches = []
for regex in regexes:
...
isctest.log.watchlog.WatchLogTimeout: ...
"""
- regexes = self._prepare_patterns(patterns)
- self._wait_function_called = True
- self._deadline = time.monotonic() + self._timeout
+ regexes = self._setup_wait(patterns)
unmatched_regexes = set(regexes)
matches = []
return matches
- def _wait_for_match(self, regexes: List[Pattern]) -> Match:
- while time.monotonic() < self._deadline:
- for line in self._readlines():
- for regex in regexes:
- match = regex.search(line)
- if match:
- return match
- time.sleep(0.1)
- raise WatchLogTimeout(
- f"Timeout reached watching {self._path} for "
- f"{' | '.join([regex.pattern for regex in regexes])}"
- )
-
def __enter__(self) -> Any:
self._fd = open(self._path, encoding="utf-8")
self._seek_on_enter()