2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

Abstract WatchLog line buffering to a separate function

Move the line buffering functionality into _readline() to improve the
readability of code. This also allows reading the file contents from
other functions, since the line buffer is now an attribute of the class.
This commit is contained in:
Nicki Křížek
2025-06-16 15:35:43 +02:00
parent 9778068253
commit 67896ddde2

View File

@@ -100,6 +100,36 @@ class WatchLog(abc.ABC):
self._fd = None # type: Optional[TextIO] self._fd = None # type: Optional[TextIO]
self._path = path self._path = path
self._wait_function_called = False self._wait_function_called = False
self._linebuf = ""
def _readline(self) -> Optional[str]:
"""
Wrapper around io.readline() function to handle unfinished lines.
If a line ends with newline character, it's returned immediately.
If a line doesn't end with a newline character, the read contents are
buffered until the next call of this function and None is returned
instead.
"""
if not self._fd:
raise WatchLogException("file to watch isn't open")
read = self._fd.readline()
if not read.endswith("\n"):
self._linebuf += read
return None
read = self._linebuf + read
self._linebuf = ""
return read
def _readlines(self) -> Iterator[str]:
"""
Wrapper around io.readline() which only returns finished lines.
"""
while True:
line = self._readline()
if line is None:
return
yield line
def wait_for_line(self, string: str, timeout: int = 10) -> None: def wait_for_line(self, string: str, timeout: int = 10) -> None:
""" """
@@ -231,24 +261,15 @@ class WatchLog(abc.ABC):
if self._wait_function_called: if self._wait_function_called:
raise WatchLogException("wait_for_*() was already called") raise WatchLogException("wait_for_*() was already called")
self._wait_function_called = True self._wait_function_called = True
if not self._fd:
raise WatchLogException("No file to watch")
leftover = ""
assert timeout, "Do not use this class unless you want to WAIT for something." assert timeout, "Do not use this class unless you want to WAIT for something."
deadline = time.monotonic() + timeout deadline = time.monotonic() + timeout
while time.monotonic() < deadline: while time.monotonic() < deadline:
for line in self._fd.readlines(): for line in self._readlines():
if line[-1] != "\n": for string, retval in patterns.items():
# Line is not completely written yet, buffer and keep on waiting if isinstance(string, Pattern) and string.search(line):
leftover += line return retval
else: if isinstance(string, str) and string in line:
line = leftover + line return retval
leftover = ""
for string, retval in patterns.items():
if isinstance(string, Pattern) and string.search(line):
return retval
if isinstance(string, str) and string in line:
return retval
time.sleep(0.1) time.sleep(0.1)
raise TimeoutError( raise TimeoutError(
"Timeout reached watching {} for {}".format( "Timeout reached watching {} for {}".format(