lee-pai-long
12/10/2016 - 3:31 AM

simple-type-checker-example.py

# source: http://stackoverflow.com/questions/32557920/what-are-type-hints-in-python-3-5

def check_type_hinter(function):
    """
        Make sure you follow what you said.
        How to use:

        @check_type_hinter
        def length(arg: str) -> int:
            return len(arg)

        length('hello')
        length(5) # TypeError

        @cth
        def error() -> bool:
            return 'an error'
        error() # TypeError

        By math2001
    """

    def class_name(el):
        return el.__class__.__name__

    def caller(*args, **kwargs):
        annots = function.__annotations__
        i = -1
        for arg_name, required_type in annots.items():
            if arg_name == 'return':
                continue
            else:
                i += 1

            if i >= len(args):
                break

            if not isinstance(args[i], required_type):
                raise TypeError("The argument '{}' should be a '{}' "
                                "('{}' given)"
                                .format(arg_name, required_type.__name__,
                                        class_name(args[i])))

        result = function(*args, **kwargs)
        if (annots.get('return', False) and
                not isinstance(result, annots['return'])):
            raise TypeError("This function does not return what it should "
                            "('{}' instead of '{}')".format(class_name(result),
                                                            annots['return']
                                                            .__name__))

        return result
    caller.__annotations__ = function.__annotations__
    return caller


def cth(*args, **kwargs):
    # for the lazy ones (like me)
    return check_type_hinter(*args, **kwargs)


class SomethingCool:

    def __str__(self):
        return "Python's awesome! Let's make it better. ;)"


@cth
def hello(name: str='you', end='') -> SomethingCool:
    msg = 'Hello {}!{}'.format(name, end)
    print(msg)
    return SomethingCool()


print(hello())