`[Async]ContextDecorator.__call__` return type should depend on the underlying context manager's `_ExitT_co`

Aberta
#13,512 4 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

  • #14439 de @johnslavik — fechado sem integrar

Avaliação

Dificuldade
5/5
Tempo estimado
Mais de uma semana
Facilidade para iniciantes
35/100
Tipo de issue
Bug
Clareza
Precisa de esclarecimento
Status de atividade
Estagnada
Stack de tecnologia
python

Direção de pesquisa

Comece pela discussão vinculada sobre Python e pela implementação da biblioteca padrão em Lib/contextlib.py, concentrando-se em ContextDecorator.call e no _ExitT_co do gerenciador de contexto subjacente. Determine uma relação compatível em nível de tipo para o tipo de retorno do callable envolvido e, em seguida, verifique se a anotação reflete os casos em que a supressão pelo gerenciador de contexto retorna None.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

[!Important]
Please see https://discuss.python.org/t/support-suppressing-generator-context-managers/103615 first!

This is how ContextDecorator.__call__ is implemented in the Python standard library:

def __call__(self, func):
    @wraps(func)
    def inner(*args, **kwds):
        with self._recreate_cm():
            return func(*args, **kwds)
    return inner

In typeshed, ContextDecorator.__call__ currently has a return type of the original callable (func).
However, if the return value of self._recreate_cm().__call__ is truthy, the return type of ContextDecorator.__call__ can as well be None, like in the silly example below:

from collections.abc import Generator
from contextlib import contextmanager, suppress
from typing import reveal_type


@contextmanager
def zero_division_to_none() -> Generator[None]:
    with suppress(ZeroDivisionError):
        yield


@zero_division_to_none()
def div(a: int, b: int) -> float:
    return a / b


reveal_type(div(1, 0))
# mypy, pyright: Revealed type is "builtins.float"
# Runtime type is 'NoneType'

My first shot was to patch the proper __call__ functions to "extend" the return type with _ThrottledExcReturnT (a new type parameter of ContextDecorator), constrained by Never and None, with the default type Never for backward compatibility. To me, there's no way to declare the relationship symbolically, so it would have to be typed manually in classes implementing the context manager protocol.

Linguagem predominante
Python
Estrelas
5.1k
Forks
2.1k
Merge médio
2d 5h
PRs com merge (30d)
122

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de python/typeshed

Todas as issues de python/typeshed

Issues semelhantes

Mais issues de Python

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.