Descriptors don't work with `TypeGuard`

Aberta
#16,828 5 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
4/5
Tempo estimado
3-5 dias
Facilidade para iniciantes
42/100
Tipo de issue
Bug
Clareza
Razoavelmente clara
Status de atividade
Estagnada
Stack de tecnologia
python
Domínio
devtools

Direção de pesquisa

Comece com a reprodução vinculada no mypy-play e compare o comportamento de TypeGuard em problem() com a chamada direta funcional a get em contrast(). Rastreie o caminho de narrowing baseado em descritor e verifique se instance é reduzido a DerivedClass no ramo verdadeiro, enquanto o ramo falso permanece BaseClass.

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

Descrição

bug

Bug Report

The tool doesn't correctly interpret TypeGuard in the context of a descriptor.

To Reproduce

mypy-play.net gist

from __future__ import annotations

from typing import *
from typing_extensions import (
        TypeGuard,
        )

class SomeDescriptor:
    # simplified: no @overload for obj=None, klass=<type ...>
    def __get__(
            self, obj: object, klass: Optional[Type[object]] = None
            ) -> TypeGuard[DerivedClass]:
        return isinstance(obj, DerivedClass)

class BaseClass:
    described = SomeDescriptor()

class DerivedClass(BaseClass): pass


def problem(instance: BaseClass) -> None:

    if instance.described:
        reveal_type(instance)  # BaseClass      (expected: DerivedClass)
    else:
        reveal_type(instance)  # BaseClass      (correct)


def contrast(descr: SomeDescriptor, instance: BaseClass) -> None:

    if descr.__get__(instance):
        reveal_type(instance)  # DerivedClass   (correct)
    else:
        reveal_type(instance)  # BaseClass      (correct)

Expected Behavior

In problem(), the type of instance should be narrowed when instance.described is truthy.

Actual Behavior

While mypy understands that a TypeGuard returns a bool, it doesn't narrow the type when the TypeGuard returns True.

Your Environment

  • Mypy version used: 1.8.0
  • Mypy command-line flags: none
  • Mypy configuration options from mypy.ini (and other config files): none
  • Python version used: 3.8, 3.12
Linguagem predominante
Python
Estrelas
20.6k
Forks
3.3k
Merge médio
1d 18h
PRs com merge (30d)
54

Guia de contribuição

Abrir o guia de contribuição

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/mypy

Todas as issues de python/mypy

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.