Repository: vacanza/python-holidays

Issue:
Flake8 6.1.0 errors: "`do not compare types`"
Here are some errors as output by the new `Flake8` version as done on `beta` branch:
>flake8...................................................................Failed
>- hook id: flake8
>- exit code: 1
>holidays/helpers.py:20:32: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
>holidays/holiday_base.py:525:12: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
>holidays/holiday_base.py:528:14: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
>tests/common.py:203:12: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
>tests/common.py:281:12: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
>tests/common.py:338:27: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()`
>tests/common.py:339:42: E721 do not compare types, for exact checks use `is` / `is not`, for instance checks use `isinstance()``


Discussion:

Resolving patch:
diff --git a/holidays/helpers.py b/holidays/helpers.py
--- a/holidays/helpers.py
+++ b/holidays/helpers.py
@@ -17,4 +17,4 @@ def _normalize_tuple(data):
         An unchanged object for tuple of tuples, e.g., ((JAN, 10), (DEC, 31)).
         An object put into a tuple otherwise, e.g., ((JAN, 10),).
     """
-    return data if not data or type(data[0]) == tuple else (data,)
+    return data if not data or isinstance(data[0], tuple) else (data,)
diff --git a/holidays/holiday_base.py b/holidays/holiday_base.py
--- a/holidays/holiday_base.py
+++ b/holidays/holiday_base.py
@@ -522,28 +522,32 @@ def __keytransform__(self, key: DateLike) -> date:
         to :class:`datetime.date`, which is how it's stored by the class."""
 
         # Try to catch `date` and `str` type keys first.
-        if type(key) == date:  # Key has `date` type.
+        # Using type() here to skip date subclasses.
+        # Key is `date`.
+        if type(key) is date:
             dt = key
 
-        elif type(key) == str:  # Key has `str` type.
+        # Key is `str` instance.
+        elif isinstance(key, str):
             try:
                 dt = parse(key).date()
             except (OverflowError, ValueError):
                 raise ValueError(f"Cannot parse date from string '{key}'")
 
-        # Check all other types.
-        elif isinstance(key, datetime):  # Key type is derived from `datetime`.
+        # Key is `datetime` instance.
+        elif isinstance(key, datetime):
             dt = key.date()
 
-        # Must go after the `isinstance(key, datetime)` check
-        # as datetime is derived from `date`.
-        elif isinstance(key, date):  # Key type is derived from `date`.
+        # Must go after the `isinstance(key, datetime)` check as datetime is `date` subclass.
+        elif isinstance(key, date):
             dt = key
 
-        elif isinstance(key, (float, int)):  # Key type is derived from `float` or `int`.
+        # Key is `float` or `int` instance.
+        elif isinstance(key, (float, int)):
             dt = datetime.fromtimestamp(key, timezone.utc).date()
 
-        else:  # Key type is not supported.
+        # Key is not supported.
+        else:
             raise TypeError(f"Cannot convert type '{type(key)}' to date.")
 
         # Automatically expand for `expand=True` cases.


Test patch:
diff --git a/tests/common.py b/tests/common.py
--- a/tests/common.py
+++ b/tests/common.py
@@ -91,7 +91,7 @@ def _parse_arguments(
         items = []
         if expand_items:
             for item_arg in item_args:
-                if type(item_arg) in {list, set, tuple}:
+                if isinstance(item_arg, (list, set, tuple)):
                     items.extend(item_arg)
                 elif isinstance(item_arg, (Generator, range)):
                     items.extend(tuple(item_arg))
@@ -200,7 +200,7 @@ def _assertHolidayName(self, name, instance_name, *args):
         holidays, items = self._parse_arguments(args, instance_name=instance_name)
 
         arg = items[0]
-        if type(arg) == int:  # A holiday name check for a specific year.
+        if isinstance(arg, int):  # A holiday name check for a specific year.
             holiday_years = {dt.year for dt in holidays.get_named(name, lookup="exact")}
             self.assertTrue(set(items).issubset(holiday_years), name)
         elif isinstance(arg, date) or parse(arg):  # Exact date check.
@@ -278,7 +278,7 @@ def _assertNoHolidayName(self, name, instance_name, *args):
             return None
 
         arg = items[0]
-        if type(arg) == int:  # A holiday name check for a specific year.
+        if isinstance(arg, int):  # A holiday name check for a specific year.
             holiday_years = {dt.year for dt in holidays.get_named(name, lookup="exact")}
             self.assertEqual(0, len(holiday_years.intersection(items)), name)
         elif isinstance(arg, date) or parse(arg):  # Exact date check.
@@ -335,8 +335,10 @@ def _assertLocalizedHolidays(self, localized_holidays, language=None):
     def assertLocalizedHolidays(self, *args):
         """Helper: assert localized holidays match expected names."""
         arg = args[0]
-        language = arg if type(arg) == str else None
-        localized_holidays = args[1:] if type(arg) == str else args
+        is_string = isinstance(arg, str)
+
+        language = arg if is_string else None
+        localized_holidays = args[1:] if is_string else args
 
         if language:
             self.set_language(language)