Создание типизированного декоратора в качестве метода классов и импорт/использование его в другом файле

#python #python-decorators #type-hinting #mypy #python-typing

Вопрос:

Я пытаюсь добавить набор текста в свой проект. Я в значительной степени повторил шаблон для фабрик декораторов.

Это пример, приведенный в связанных документах:

 from typing import Any, Callable, TypeVar

F = TypeVar("F", bound=Callable[..., Any])

def route(url: str) -> Callable[[F], F]:
    ...

@route(url='/')
def index(request: Any) -> str:
    return 'Hello world'
 

Это мой настоящий код:

 from json import loads
from typing import TypeVar, Callable, Any, Optional, Dict, Union 


Handler = TypeVar("Handler", bound=Callable[[Any], None])

class Subscriber:
    """Decorate topic handlers. Must register the subscriber with register_subscriber."""

    def __init__(self) -> None:
        self.handlers: Dict[str, tuple] = dict()

    def topic(
        self, topic: str, 
        parse_func: Optional[Callable[[Union[str, bytes]], Any]] = loads
    ) -> Callable[[Handler], Handler]:
        """Subscribe to mqtt topic. by default the response is parsed with json.loads and passed into the handler.
        Override this with a custom parser or set it to None to receive the raw response."""

        def add_handler(handler: Handler) -> Handler:
            self.handlers[topic] = (handler, parse_func)
            return handler

        return add_handler
 

Я импортирую и использую этот класс в другом файле.

 from typing import Union
from from organization.namespace.package.mqtt.client import Subscriber

paho: Subscriber = Subscriber()

@paho.topic("test")
def test(payload: Union[dict, list]) -> None:
    print(payload)
 

Но я не могу избавиться от этой ошибки.

 Untyped decorator makes function "handler" untypedmypy(error)
 

Как мы выяснили с помощью @AlexWaygood, он не выдает эту ошибку при использовании из одного и того же файла. Но по какой-то причине это происходит при импорте в другой файл, как показано выше.

Мой проект имеет следующую структуру каталогов:

 organization
└── namespace
    └── package
        └── mqtt
            ├── client.py
            └── handler.py
 

В настоящее время у меня нет __init__.py файлов в моих каталогах или подкаталогах.

Ответ №1:

Эта проблема связана с системой модулей. Существует 2 различных решения этой проблемы:

  1. Создайте __init__.py в каждой папке.
  2. Используя параметры —пакеты пространства имен и —явные базы пакетов при запуске mypy.

Для получения более подробной информации см. Проблемы mypy, которые я создал здесь и здесь.