From ab36399005f03a4fda4129316fadf3076ec51403 Mon Sep 17 00:00:00 2001 From: BharatDeva <278575558+BharatDeva@users.noreply.github.com> Date: Sun, 19 Jul 2026 19:23:56 -0500 Subject: [PATCH] Replace direct type checks with isinstance Use isinstance() for direct type comparisons across the code paths listed in issue #2636. This keeps the behavior the same for the checked builtin and IntelMQ message types while following the preferred Python style and allowing subclasses where that is appropriate. The exact class equality check in Message.__eq__ is intentionally left as type(self) is type(other), because it distinguishes different Message subclasses after confirming that the other object is a Message instance. Signed-off-by: BharatDeva <278575558+BharatDeva@users.noreply.github.com> --- intelmq/bin/intelmqctl.py | 4 ++-- intelmq/bin/intelmqdump.py | 4 ++-- intelmq/bots/experts/filter/expert.py | 8 ++++---- intelmq/bots/experts/format_field/expert.py | 2 +- intelmq/bots/experts/rdap/expert.py | 6 +++--- intelmq/bots/parsers/generic/parser_csv.py | 2 +- intelmq/bots/parsers/html_table/parser.py | 4 ++-- intelmq/lib/bot.py | 5 ++--- intelmq/lib/harmonization.py | 2 +- intelmq/lib/message.py | 2 +- intelmq/lib/pipeline.py | 5 ++--- intelmq/lib/test.py | 6 +++--- intelmq/lib/upgrades.py | 4 ++-- intelmq/lib/utils.py | 6 +++--- 14 files changed, 29 insertions(+), 31 deletions(-) diff --git a/intelmq/bin/intelmqctl.py b/intelmq/bin/intelmqctl.py index 9668e0327c..0435f6c087 100644 --- a/intelmq/bin/intelmqctl.py +++ b/intelmq/bin/intelmqctl.py @@ -1118,7 +1118,7 @@ def upgrade_conf(self, previous=None, dry_run=None, function=None, result['traceback'] = traceback.format_exc() result['success'] = False else: - if type(retval) is str: + if isinstance(retval, str): self._logger.error('Upgrade %r failed: %s', function, retval) result['message'] = retval result['success'] = False @@ -1210,7 +1210,7 @@ def upgrade_conf(self, previous=None, dry_run=None, function=None, result['traceback'] = traceback.format_exc() result['success'] = False else: - if type(retval) is str: + if isinstance(retval, str): self._logger.error('%s: Upgrade failed: %s', docstring, retval) result['message'] = retval result['success'] = False diff --git a/intelmq/bin/intelmqdump.py b/intelmq/bin/intelmqdump.py index eb254d166d..ecdc7b1b15 100644 --- a/intelmq/bin/intelmqdump.py +++ b/intelmq/bin/intelmqdump.py @@ -131,7 +131,7 @@ def save_file(handle, content): def load_meta(dump): retval = [] for key, value in dump.items(): - if type(value['traceback']) is not list: + if not isinstance(value['traceback'], list): error = value['traceback'].splitlines()[-1] else: error = value['traceback'][-1].strip() @@ -410,7 +410,7 @@ def main(argv=None): len(value['message']['raw']) > args.truncate): value['message']['raw'] = value['message'][ 'raw'][:args.truncate] + '...[truncated]' - if type(value['traceback']) is not list: + if not isinstance(value['traceback'], list): value['traceback'] = value['traceback'].splitlines() pprint.pprint(value) elif answer[0] == 'e': diff --git a/intelmq/bots/experts/filter/expert.py b/intelmq/bots/experts/filter/expert.py index d42f6721a3..3ea8da74be 100644 --- a/intelmq/bots/experts/filter/expert.py +++ b/intelmq/bots/experts/filter/expert.py @@ -82,21 +82,21 @@ def process(self): except ValueError: self.logger.error("Could not parse time.source %s.", event.get('time.source')) else: - if type(self.not_after) is datetime and event_time > self.not_after: + if isinstance(self.not_after, datetime) and event_time > self.not_after: self.acknowledge_message() self.logger.debug("Filtered out event with time.source %s.", event.get('time.source')) return - if type(self.not_before) is datetime and event_time < self.not_before: + if isinstance(self.not_before, datetime) and event_time < self.not_before: self.acknowledge_message() self.logger.debug("Filtered out event with time.source %r.", event.get('time.source')) return now = datetime.now(tz=timezone.utc) - if type(self.not_after) is timedelta and event_time > (now - self.not_after): + if isinstance(self.not_after, timedelta) and event_time > (now - self.not_after): self.acknowledge_message() self.logger.debug("Filtered out event with time.source %r.", event.get('time.source')) return - if type(self.not_before) is timedelta and event_time < (now - self.not_before): + if isinstance(self.not_before, timedelta) and event_time < (now - self.not_before): self.acknowledge_message() self.logger.debug("Filtered out event with time.source %r.", event.get('time.source')) return diff --git a/intelmq/bots/experts/format_field/expert.py b/intelmq/bots/experts/format_field/expert.py index bc2a6a8b11..55198076b7 100644 --- a/intelmq/bots/experts/format_field/expert.py +++ b/intelmq/bots/experts/format_field/expert.py @@ -18,7 +18,7 @@ class FormatFieldExpertBot(ExpertBot): split_column = None def init(self): - if type(self.strip_columns) is str: + if isinstance(self.strip_columns, str): self.strip_columns = [column.strip() for column in self.strip_columns.split(",")] def process(self): diff --git a/intelmq/bots/experts/rdap/expert.py b/intelmq/bots/experts/rdap/expert.py index a786b87f8e..b8658fe003 100644 --- a/intelmq/bots/experts/rdap/expert.py +++ b/intelmq/bots/experts/rdap/expert.py @@ -46,15 +46,15 @@ def init(self): # get bootstrapped servers for service in self.rdap_bootstrapped_servers: - if type(self.rdap_bootstrapped_servers[service]) is str: + if isinstance(self.rdap_bootstrapped_servers[service], str): self.__rdap_directory[service] = {"url": self.rdap_bootstrapped_servers[service]} - elif type(self.rdap_bootstrapped_servers) is dict: + elif isinstance(self.rdap_bootstrapped_servers, dict): self.__rdap_directory[service] = self.rdap_bootstrapped_servers[service] def parse_entities(self, vcardArray) -> list: vcard = [] for vcardentry in vcardArray: - if type(vcardentry) is str: + if isinstance(vcardentry, str): continue for vcarddata in vcardentry: diff --git a/intelmq/bots/parsers/generic/parser_csv.py b/intelmq/bots/parsers/generic/parser_csv.py index bd9a442498..5ee0fe33a3 100644 --- a/intelmq/bots/parsers/generic/parser_csv.py +++ b/intelmq/bots/parsers/generic/parser_csv.py @@ -50,7 +50,7 @@ class GenericCsvParserBot(ParserBot): def init(self): # convert columns to an array - if type(self.columns) is str: + if isinstance(self.columns, str): self.columns = [column.strip() for column in self.columns.split(",")] if self.type_translation and isinstance(self.type_translation, str): # not-empty string diff --git a/intelmq/bots/parsers/html_table/parser.py b/intelmq/bots/parsers/html_table/parser.py index cfb7e39819..fcac998cb1 100644 --- a/intelmq/bots/parsers/html_table/parser.py +++ b/intelmq/bots/parsers/html_table/parser.py @@ -55,11 +55,11 @@ def init(self): raise MissingDependencyError("beautifulsoup4") # convert columns to an array - if type(self.columns) is str: + if isinstance(self.columns, str): self.columns = [column.strip() for column in self.columns.split(",")] if self.ignore_values is None: self.ignore_values = len(self.columns) * [''] - if type(self.ignore_values) is str: + if isinstance(self.ignore_values, str): self.ignore_values = [value.strip() for value in self.ignore_values.split(",")] if len(self.columns) != len(self.ignore_values): diff --git a/intelmq/lib/bot.py b/intelmq/lib/bot.py index 7c62502112..61f7befcd6 100644 --- a/intelmq/lib/bot.py +++ b/intelmq/lib/bot.py @@ -532,8 +532,7 @@ def __reset_total_path_stats(self): """Initially set destination paths to 0 to reset them in stats cache""" if not self.destination_queues: return - queues_type = type(self.destination_queues) - if queues_type is dict: + if isinstance(self.destination_queues, dict): for path in self.destination_queues.keys(): self.__message_counter["path_total"][path] = 0 else: @@ -1244,7 +1243,7 @@ def process(self): value = self.parse_line(line, report) if value is None: continue - elif type(value) is list or isinstance(value, types.GeneratorType): + elif isinstance(value, list) or isinstance(value, types.GeneratorType): # filter out None events: list[libmessage.Event] = list(filter(bool, value)) else: diff --git a/intelmq/lib/harmonization.py b/intelmq/lib/harmonization.py index 130acbaba1..05444e5659 100644 --- a/intelmq/lib/harmonization.py +++ b/intelmq/lib/harmonization.py @@ -101,7 +101,7 @@ def is_valid(value: str, sanitize: bool = False) -> bool: if not GenericType.is_valid(value): return False - if type(value) is not str: + if not isinstance(value, str): return False if len(value) == 0: diff --git a/intelmq/lib/message.py b/intelmq/lib/message.py index eeff508722..81cee28a32 100644 --- a/intelmq/lib/message.py +++ b/intelmq/lib/message.py @@ -499,7 +499,7 @@ def __eq__(self, other: dict) -> bool: Comparison with other types e.g. dicts does not check the harmonization_config. """ dict_eq = super().__eq__(other) - if dict_eq and issubclass(type(other), Message): + if dict_eq and isinstance(other, Message): type_eq = type(self) is type(other) harm_eq = self.harmonization_config == other.harmonization_config if hasattr(other, 'harmonization_config') else False if type_eq and harm_eq: diff --git a/intelmq/lib/pipeline.py b/intelmq/lib/pipeline.py index f439a20537..4ba7465f3a 100644 --- a/intelmq/lib/pipeline.py +++ b/intelmq/lib/pipeline.py @@ -116,10 +116,9 @@ def set_queues(self, queues: Optional[str], queues_type: str): self.internal_queue = None if queues is None else f'{queues}-internal' elif queues_type == "destination": - type_ = type(queues) - if type_ is list: + if isinstance(queues, list): q = {"_default": queues} - elif type_ is str: + elif isinstance(queues, str): q = {"_default": queues.split()} elif isinstance(queues, dict): q = queues diff --git a/intelmq/lib/test.py b/intelmq/lib/test.py index ae55f63d2d..d07f9a6211 100644 --- a/intelmq/lib/test.py +++ b/intelmq/lib/test.py @@ -171,7 +171,7 @@ def setUpClass(cls): 'time.observation': '2016-01-01T00:00:00+00:00'} elif cls.bot_type != 'collector' and cls.default_input_message == '': cls.default_input_message = {'__type': 'Event'} - if type(cls.default_input_message) is dict: + if isinstance(cls.default_input_message, dict): cls.default_input_message = \ utils.decode(json.dumps(cls.default_input_message)) @@ -268,9 +268,9 @@ def prepare_source_queue(self): self.input_message = [self.input_message] self.input_queue = [] for msg in self.input_message: - if type(msg) is dict: + if isinstance(msg, dict): self.input_queue.append(json.dumps(msg)) - elif issubclass(type(msg), message.Message): + elif isinstance(msg, message.Message): self.input_queue.append(msg.serialize()) else: self.input_queue.append(msg) diff --git a/intelmq/lib/upgrades.py b/intelmq/lib/upgrades.py index f5d4e66908..5f7a0eef56 100644 --- a/intelmq/lib/upgrades.py +++ b/intelmq/lib/upgrades.py @@ -202,7 +202,7 @@ def v100_dev7_modify_syntax(configuration, harmonization, dry_run, **kwargs): if bot["module"] == "intelmq.bots.experts.modify.expert": if "configuration_path" in bot["parameters"]: config = load_configuration(bot["parameters"]["configuration_path"]) - if type(config) is dict: + if isinstance(config, dict): new_config = modify_expert_convert_config(config) if len(config) != len(new_config): return 'Error converting modify expert syntax. Different size of configurations. Please report this.' @@ -529,7 +529,7 @@ def v221_feed_changes(configuration, harmonization, dry_run, **kwargs): continue columns = bot["parameters"]["columns"] # convert columns to an array - if type(columns) is str: + if isinstance(columns, str): columns = [column.strip() for column in columns.split(",")] if columns == ULRHAUS_OLD: changed = True diff --git a/intelmq/lib/utils.py b/intelmq/lib/utils.py index 0a4922d703..5a65198985 100644 --- a/intelmq/lib/utils.py +++ b/intelmq/lib/utils.py @@ -199,8 +199,8 @@ def flatten_queues(queues: Union[list, dict]) -> Iterator[str]: Returns: flattened_queues: queues without dictionaries as values, just lists with the values """ - return (item for sublist in (queues.values() if type(queues) is dict else queues) for item in - (sublist if type(sublist) is list else [sublist])) + return (item for sublist in (queues.values() if isinstance(queues, dict) else queues) for item in + (sublist if isinstance(sublist, list) else [sublist])) def load_configuration(configuration_filepath: str) -> dict: @@ -395,7 +395,7 @@ def log(name: str, log_path: Union[str, bool] = intelmq.DEFAULT_LOGGING_PATH, handler.setLevel(log_level) handler.setFormatter(logging.Formatter(LOG_FORMAT)) elif syslog: - if type(syslog) is tuple or type(syslog) is list: + if isinstance(syslog, (tuple, list)): handler = logging.handlers.SysLogHandler(address=tuple(syslog)) else: handler = logging.handlers.SysLogHandler(address=syslog)