Python: How to type a function which takes a union of possible class names as input

Viewed 269

Consider the following:

class AbstractLanguageClass:
    @staticmethod
    def say_hello() -> None:
        raise Exception("Not implemented")


class French(AbstractLanguageClass):
    def __init__(self):
        pass

    @staticmethod
    def say_hello() -> None:
        print("Bonjour")


class English(AbstractLanguageClass):
    def __init__(self):
        pass

    @staticmethod
    def say_hello() -> None:
        print("Hello")


def hello_sayer(
    Language_Class: type,  # This type-hinting is what I'm unsure of
):
    Language_Class.say_hello()


hello_sayer(French)  # Correctly prints "Bonjour"
print(type(French))  # prints <class 'type'>

Running MyPy, I get the following error:

error: "type" has no attribute "say_hello"

What is the appropriate way to type-hint this use-case, where multiple classes implement a common static method, and we're not giving (as argument to some function) an instance of said classes, but rather the class name itself (to use their respective static methods) ?

PS: FYI, my real use-case is actually a generic caster function for a bunch of customized IntEnums, that have some common method mixins. This caster function can take a string, an int, or an enum instance; as well as such an IntEnum-derived class; then uses the class's from_str, deserialize, from_int, or constructor functions to cast, do nothing, or return an error. In the spirit of DRY code and type-safety, this is a very useful function to have in my case.

0 Answers
Related