1
\$\begingroup\$

I've been working in statically typed languages for awhile, and I've had to write some Python utilities recently. As part of those tools, I needed a semi-sane way to implement type checking to make it easier to understand the target type I'm working with.

    def type_of(val: Any, target_type: Any) -> bool:
        """
        Safely check to see if a value is typeOf(type).
        :param val: Value or variable to check.
        :param target_type: Type you want to check. It's important to know booleans are a subclass of integers, so t(False, (int,bool)) -> True
        :return:
        """
        try:
            if isinstance(val, bool) and cast_to(val, bool):
                return True
            if isinstance(val, target_type):
                return True
            else:
                return False
        except ValueError:
            return False


    def cast_to(val: Any, target_type: [int, bool, str, list]) -> (bool, [int, bool, str, list]):
        """
        If a value can be cast as that type, it will be.
        :param val: Value to be cast.
        :param target_type: Destination type.
        :return bool, [int, bool, str, list]: Returns True if it can be base with the proper type; False if not, with the value type.
        """
        try:
            # if it's an int and greater than 1 or less than zero, it can't be a bool
            if (isinstance(val, int) and ((val > 1) or (val < 0))) and target_type is bool:
                return False, val
            nval = target_type(val)
            if isinstance(nval, target_type):
                return True, nval
            else:
                return False, val
        except ValueError:
            return False, val

It generally works as intended until I get to booleans, which I recently learned are a subclass of integers, and I've had problems consistently determining if something is a boolean. How can I improve my type check to properly handle booleans?

\$\endgroup\$
  • 1
    \$\begingroup\$ Just an FYI there's another way to check type, but it doesn't care about inheritance. isinstance(True, int), type(True) is int -> (True, False). \$\endgroup\$ – Peilonrayz May 13 '19 at 17:19
  • \$\begingroup\$ For my edification: WHY would you do that? \$\endgroup\$ – Christoph Frings May 14 '19 at 15:33

Browse other questions tagged or ask your own question.