Type hinting in Python 2

后端 未结 3 1331
被撕碎了的回忆
被撕碎了的回忆 2020-11-27 05:09

In PEP 484, type hinting was added to Python 3 with the inclusion of the typing module. Is there any way to do this in Python 2? All I can think of is having a decorator to

3条回答
  •  南方客
    南方客 (楼主)
    2020-11-27 05:53

    Here is a function i wrote to parse the Python 2 type comment and get a tuple of input types and the return type. It would need some work to work with complex type definitions from the typing library (Any, Optional, List, etc.):

    class InvalidTypeHint(Exception):
        pass    
    
    PYTHON_2_TYPE_HINT_REGEX = "\s*#\s*type:\s*(\(.+\))\s*->\s*(.+)\s*"
    
    def parse_python_2_type_hint(typehint_string):
        # type: (str) -> (tuple, type)
        pattern = re.compile(PYTHON_2_TYPE_HINT_REGEX)
        search_results = pattern.search(typehint_string)
        if not search_results:
            raise InvalidTypeHint('%s does not match type hint spec regex %s' % (typehint_string, PYTHON_2_TYPE_HINT_REGEX))
        arg_types_str = search_results.group(1)
        return_type_str = search_results.group(2)
        try:
            arg_types_tuple = eval(arg_types_str)
            assert isinstance(arg_types_tuple, tuple)
            return_type = eval(return_type_str)
            assert isinstance(return_type, type)
        except Exception as e:
            raise InvalidTypeHint(e)
        return arg_types_tuple, return_type
    
    
    def parse_arg_types_for_callable(func):
        # type:(callable)->tuple
        """
    
        :param func:
        :return: list of parameter types if successfully parsed, else None
        """
    
        # todo make this compatible with python 3 type hints
        # python 2.7 type hint
        source_lines = inspect.getsource(func).split("\n")
        def_statements = 0
        for source_line in source_lines:
            try:
                arg_types_tuple, return_type = parse_python_2_type_hint(source_line)
                return arg_types_tuple
            except InvalidTypeHint:
                if source_line.strip().startswith("def "):
                    def_statements += 1
                if def_statements > 1:
                    return None
    

提交回复
热议问题