Skip to content

Commit

Permalink
Find all converter subclasses / descendants
Browse files Browse the repository at this point in the history
  • Loading branch information
rlskoeser committed Feb 6, 2025
1 parent a33e43b commit f6c4382
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
17 changes: 11 additions & 6 deletions src/undate/converters/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def available_converters(cls) -> Dict[str, Type["BaseDateConverter"]]:
return {c.name: c for c in cls.subclasses()} # type: ignore

@classmethod
def subclasses(cls) -> list[Type["BaseDateConverter"]]:
def subclasses(cls) -> set[Type["BaseDateConverter"]]:
"""
List of available converters classes. Includes calendar convert
subclasses.
Expand All @@ -123,11 +123,16 @@ def subclasses(cls) -> list[Type["BaseDateConverter"]]:
cls.import_converters()

# find all direct subclasses, excluding base calendar converter
subclasses = cls.__subclasses__()
subclasses.remove(BaseCalendarConverter)
# add all subclasses of calendar converter base class
subclasses.extend(BaseCalendarConverter.__subclasses__())
return subclasses
direct_subclasses = cls.__subclasses__()
all_subclasses = set(direct_subclasses)
# recurse to find nested subclasses
for subc in direct_subclasses:
# print(f"class subclasses: {subc.name} {subc.subclasses()}")
all_subclasses |= subc.subclasses()

# omit the calendar converter base class, which is not itself a converter
all_subclasses -= {BaseCalendarConverter}
return all_subclasses


class BaseCalendarConverter(BaseDateConverter):
Expand Down
17 changes: 17 additions & 0 deletions tests/test_converters/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

import pytest
from undate.converters.base import BaseDateConverter, BaseCalendarConverter
from undate.converters.calendars import (
GregorianDateConverter,
HebrewDateConverter,
HijriDateConverter,
)


class TestBaseDateConverter:
Expand Down Expand Up @@ -29,6 +34,18 @@ def test_parse_to_string(self):
with pytest.raises(NotImplementedError):
BaseDateConverter().to_string(1991)

def test_subclasses(self):
# define a nested subclass
class SubSubConverter(HijriDateConverter):
pass

subclasses = BaseDateConverter.subclasses()
assert BaseCalendarConverter not in subclasses
assert HijriDateConverter in subclasses
assert HebrewDateConverter in subclasses
assert GregorianDateConverter in subclasses
assert SubSubConverter in subclasses


def test_import_converters_import_only_once(caplog):
# clear the cache, since any instantiation of an Undate
Expand Down

0 comments on commit f6c4382

Please sign in to comment.