Repository: vacanza/python-holidays

Issue:
Isle of Man Code IM Doesn't Work
Setting country to IM in configuration.yaml results in the check configuration button reporting invalid country data. IM is in the list of support countries. 

Configuration invalid!

Invalid config for [binary_sensor.workday]: Country is not supported. for dictionary value @ data['country']. Got 'IM'. (See ?, line ?).

There is a note in GB section for Isle of Man to use IM. 


Discussion:
Well, that's a bug. Thanks for reporting this!

I looked into this briefly and here is what I found:
The available country list is filtered by `__base__` [undocumented Python?] attribute here https://github.com/dr-prodigy/python-holidays/blob/390f59c386b15485c78550a6b4c017b7a6e09f67/holidays/utils.py#L287

It works for usual cases (direct inheritance) and fails for more complex cases when country is derived from another `HolidayBase` based class.

Next step.
The `list_supported_countries` (and at least `list_supported_financial`) needs to be reworked to include all supported Alpha-2 country codes.

I'll file a fix for the issue later today.

Resolving patch:
diff --git a/holidays/countries/__init__.py b/holidays/countries/__init__.py
--- a/holidays/countries/__init__.py
+++ b/holidays/countries/__init__.py
@@ -51,7 +51,7 @@
 from .iceland import IS, ISL, Iceland
 from .india import IN, IND, India
 from .ireland import IE, IRL, Ireland
-from .isle_of_man import IM, IsleOfMan
+from .isle_of_man import IM, IMN, IsleOfMan
 from .israel import IL, ISR, Israel
 from .italy import IT, ITA, Italy
 from .jamaica import JAM, JM, Jamaica
diff --git a/holidays/countries/isle_of_man.py b/holidays/countries/isle_of_man.py
--- a/holidays/countries/isle_of_man.py
+++ b/holidays/countries/isle_of_man.py
@@ -38,3 +38,7 @@ def _populate(self, year: int) -> None:
 
 class IM(IsleOfMan):
     pass
+
+
+class IMN(IsleOfMan):
+    pass
diff --git a/holidays/utils.py b/holidays/utils.py
--- a/holidays/utils.py
+++ b/holidays/utils.py
@@ -280,11 +280,11 @@ def list_supported_countries() -> Dict[str, List[str]]:
         the value is a list of supported subdivision codes.
     """
     return {
-        obj.country: obj.subdivisions
-        for name, obj in inspect.getmembers(
+        cls.country: cls.subdivisions
+        for name, cls in inspect.getmembers(
             holidays.countries, inspect.isclass
         )
-        if obj.__base__ == HolidayBase
+        if len(name) == 2 and issubclass(cls, HolidayBase)
     }
 
 
@@ -297,11 +297,9 @@ def list_supported_financial() -> Dict[str, List[str]]:
         the value is a list of supported subdivision codes.
     """
     return {
-        obj.market: obj.subdivisions
-        for name, obj in inspect.getmembers(
-            holidays.financial, inspect.isclass
-        )
-        if obj.__base__ == HolidayBase
+        cls.market: cls.subdivisions
+        for _, cls in inspect.getmembers(holidays.financial, inspect.isclass)
+        if issubclass(cls, HolidayBase)
     }
 
 


Test patch:
diff --git a/test/test_holiday_base.py b/test/test_holiday_base.py
--- a/test/test_holiday_base.py
+++ b/test/test_holiday_base.py
@@ -9,6 +9,7 @@
 #  Website: https://github.com/dr-prodigy/python-holidays
 #  License: MIT (see LICENSE file)
 
+import pathlib
 import pickle
 import sys
 import unittest
@@ -331,13 +332,38 @@ def test_get_list(self):
         self.assertEqual(na.get_list(date(1969, 1, 3)), [])
 
     def test_list_supported_countries(self):
-        self.assertIn("AR", holidays.list_supported_countries())
-        self.assertIn("ZA", holidays.list_supported_countries())
-        self.assertIn("CA", holidays.list_supported_countries()["US"])
+        supported_countries = holidays.list_supported_countries()
+
+        countries_files = [
+            path
+            for path in pathlib.Path("holidays/countries").glob("*.py")
+            if not str(path).endswith("__init__.py")
+        ]
+        self.assertEqual(
+            len(countries_files),
+            len(supported_countries),
+        )
+
+        self.assertIn("AR", supported_countries)
+        self.assertIn("CA", supported_countries["US"])
+        self.assertIn("IM", supported_countries)
+        self.assertIn("ZA", supported_countries)
 
     def test_list_supported_financial(self):
-        self.assertIn("ECB", holidays.list_supported_financial())
-        self.assertIn("NYSE", holidays.list_supported_financial())
+        supported_financial = holidays.list_supported_financial()
+
+        financial_files = [
+            path
+            for path in pathlib.Path("holidays/financial").glob("*.py")
+            if not str(path).endswith("__init__.py")
+        ]
+        self.assertEqual(
+            len(financial_files),
+            len(supported_financial),
+        )
+
+        self.assertIn("ECB", supported_financial)
+        self.assertIn("NYSE", supported_financial)
 
     def test_radd(self):
         self.assertRaises(TypeError, lambda: 1 + holidays.US())