Descriptors don't work with `TypeGuard`

Offen
#16,828 5 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Anfängerfreundlichkeit
42/100
Issue-Typ
Bug
Klarheit
Größtenteils klar
Aktivitätsstatus
Veraltet
Tech-Stack
python
Bereich
devtools

Rechercherichtung

Beginne mit der verlinkten mypy-play-Reproduktion und vergleiche das TypeGuard-Verhalten in problem() mit dem funktionierenden direkten get-Aufruf in contrast(). Verfolge den auf Deskriptoren basierenden Narrowing-Pfad und überprüfe, dass instance im Wahrheitswert-true-Zweig auf DerivedClass eingegrenzt wird, während der false-Zweig BaseClass bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

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
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
Ø Merge
1 T. 18 Std.
Gemergte PRs (30 T.)
54

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus python/mypy

Alle Issues in python/mypy

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.