Tipo de sugerencia en Python 2

En PEP 484 , se agregaron sugerencias de tipo a Python 3 con la inclusión del módulo de typing . ¿Hay alguna manera de hacer esto en Python 2? Todo lo que puedo pensar es tener un decorador para agregar a los métodos para verificar tipos, pero esto fallaría en el tiempo de ejecución y no se detectaría antes, como permitirían las sugerencias.

De acuerdo con la syntax sugerida para Python 2.7 y el código que abarca la PEP 484 que definió las sugerencias de tipo, existe una syntax alternativa para la compatibilidad con Python 2.7. Sin embargo, no es obligatorio, así que no sé qué tan bien es su soporte, pero citando el PEP:

Es posible que algunas herramientas deseen admitir anotaciones de tipo en el código que debe ser compatible con Python 2.7. Para este propósito, este PEP tiene una extensión sugerida (pero no obligatoria) donde las anotaciones de funciones se colocan en un # tipo: comentario. Dicho comentario se debe colocar inmediatamente después del encabezado de la función (antes de la cadena de documentación). Un ejemplo: el siguiente código de Python 3:

 def embezzle(self, account: str, funds: int = 1000000, *fake_receipts: str) -> None: """Embezzle funds from account using fake receipts."""  

es equivalente a lo siguiente:

 def embezzle(self, account, funds=1000000, *fake_receipts): # type: (str, int, *str) -> None """Embezzle funds from account using fake receipts."""  

Para soporte de mypy , vea Escribir código Python 2 .

En este punto, la forma recomendada y compatible con python3 es seguir la guía de python2 to 3: http://python-future.org/func_annotations.html

 def embezzle(self, account: str, funds: int = 1000000, *fake_receipts: str) -> None: """Embezzle funds from account using fake receipts.""" pass 

Volverse:

 def embezzle(self, account, funds = 1000000, *fake_receipts): """Embezzle funds from account using fake receipts.""" pass embezzle.__annotations__ = {'account': str, 'funds': int, 'fake_receipts': str, 'return': None} 

Aquí hay una función que escribí para analizar el comentario de tipo Python 2 y obtener una tupla de tipos de entrada y el tipo de retorno. Se necesitaría algún trabajo para trabajar con definiciones de tipo complejo de la biblioteca de mecanografía (Cualquiera, Opcional, Lista, 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