From da13bb91690e9eed4990c8629397d879a76474e1 Mon Sep 17 00:00:00 2001 From: Mirochill Date: Mon, 25 May 2026 20:33:27 +0200 Subject: [PATCH] Allow log reader to accept file objects --- hdrh/log.py | 22 +++++++++++++++++----- test/test_hdrhistogram.py | 12 ++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/hdrh/log.py b/hdrh/log.py index 2253e57..952a60f 100644 --- a/hdrh/log.py +++ b/hdrh/log.py @@ -147,9 +147,10 @@ class HistogramLogReader(): def __init__(self, input_file_name, reference_histogram): '''Constructs a new HistogramLogReader that produces intervals read - from the specified file name. + from the specified file name or file-like object. Params: - input_file_name The name of the file to read from + input_file_name The name of the file to read from, or a file-like + object with a readline() method reference_histogram a histogram instance used as a reference to create new instances for all subsequent decoded interval histograms @@ -158,7 +159,11 @@ def __init__(self, input_file_name, reference_histogram): self.observed_start_time = False self.base_time_sec = 0.0 self.observed_base_time = False - self.input_file = open(input_file_name, "r", encoding="utf-8") # pylint: disable=consider-using-with + self.input_file = input_file_name + self._close_input_file = False + if not hasattr(input_file_name, 'readline'): + self.input_file = open(input_file_name, "r", encoding="utf-8") # pylint: disable=consider-using-with + self._close_input_file = True self.reference_histogram = reference_histogram def get_start_time_sec(self): @@ -172,6 +177,12 @@ def get_start_time_sec(self): ''' return self.start_time_sec + def _readline(self): + line = self.input_file.readline() + if isinstance(line, bytes): + line = line.decode("utf-8") + return line + def _decode_next_interval_histogram(self, dest_histogram, range_start_time_sec=0.0, @@ -218,7 +229,7 @@ def _decode_next_interval_histogram(self, ValueError if there is a syntax error in one of the float fields ''' while 1: - line = self.input_file.readline() + line = self._readline() if not line: return None if line[0] == '#': @@ -402,4 +413,5 @@ def add_next_interval_histogram(self, absolute) def close(self): - self.input_file.close() + if self._close_input_file: + self.input_file.close() diff --git a/test/test_hdrhistogram.py b/test/test_hdrhistogram.py index 01ceb2f..d0e027a 100644 --- a/test/test_hdrhistogram.py +++ b/test/test_hdrhistogram.py @@ -641,6 +641,18 @@ def test_jHiccup_v2_log(): log_reader.close() +@pytest.mark.log +def test_jHiccup_v2_log_file_object(): + accumulated_histogram = HdrHistogram(LOWEST, HIGHEST, SIGNIFICANT) + with open(JHICCUP_V2_LOG_NAME, 'rb') as hdr_log: + log_reader = HistogramLogReader(hdr_log, accumulated_histogram) + decoded_histogram = log_reader.get_next_interval_histogram() + assert decoded_histogram + assert decoded_histogram.get_word_size() == 8 + log_reader.close() + assert not hdr_log.closed + + TAGGED_V2_LOG = 'test/tagged-Log.logV2.hlog' @pytest.mark.log def test_tagged_v2_log():