python / python/mypy

Feature Request: Infer TypeVar Bounds from assert issubclass Statements

Offen
#17,676 1 Kommentar 1 Reaktion 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

feature
Vorherrschende Sprache
Python
Sterne
20.6k
Forks
3.3k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Feature

I would like to request an enhancement in mypy to allow it to infer TypeVar bounds from assert issubclass(...) statements. Currently, mypy uses such assertions for local type refinement within the scope of the assertion, but it does not propagate these refinements globally, particularly for type variables. This leads to cases where developers must manually specify TypeVar bounds, even though the bound could be logically inferred from the assertions in the code.

Use Case:

Consider a scenario where a function takes a Type[T] parameter, and an assert issubclass(cls, MyAbstractClass) check is used to ensure that cls is a subclass of MyAbstractClass. Despite this assertion, mypy does not infer that T is bound by MyAbstractClass, which can lead to type-checking issues where mypy cannot guarantee that cls has the necessary methods or attributes.

Example:

from typing import Type, TypeVar, BinaryIO
from abc import ABC, abstractmethod

class MyAbstractClass(ABC):
    @classmethod
    @abstractmethod
    def from_binary_io(cls, data: BinaryIO) -> 'MyAbstractClass':
        pass

T = TypeVar('T')

def create_instance(cls: Type[T], data: BinaryIO) -> T:
    assert issubclass(cls, MyAbstractClass)
    return cls.from_binary_io(data)

# Example subclass implementation
class MyConcreteClass(MyAbstractClass):
    def __init__(self, content: bytes):
        self.content = content

    @classmethod
    def from_binary_io(cls, data: BinaryIO) -> 'MyConcreteClass':
        content = data.read()
        return cls(content)

In this example, mypy does not infer that T is bound by MyAbstractClass, leading to type-checking issues when calling cls.from_binary_io(data).

Proposed Enhancement:

mypy should be able to infer the bound of T as MyAbstractClass based on the assert issubclass(cls, MyAbstractClass) statement. This enhancement would allow developers to avoid manually specifying bounds for TypeVar when they can be logically deduced from the code.

Pitch

Benefits:

  • Improved Type Inference: Reduces the need for explicit TypeVar bounds, leading to cleaner and more maintainable code.
  • Better Developer Experience: Simplifies code and reduces potential for type-related errors, especially in complex generic scenarios.

Potential Challenges:

  • Implementation Complexity: This feature would require mypy to track and propagate type refinements beyond the local scope, potentially increasing the complexity of type inference.
  • Performance Considerations: Careful consideration would be needed to ensure that this additional type inference does not negatively impact the performance of mypy.

I believe this feature would significantly improve mypy's type inference capabilities and make it even more powerful for developers working with generics and abstract base classes.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Der Issue nennt keine Implementierungsdateien oder Tests. Beginne damit, das create_instance-Beispiel mit mypy zu reproduzieren, und verfolge dann die Behandlung von assert issubclass(cls, MyAbstractClass) und die Verfeinerung von TypeVar; abgeschlossen ist die Aufgabe, wenn die behauptete Schranke ausreichend für cls.from_binary_io(data) weitergegeben wird, sodass die Typprüfung ohne einen manuell beschränkten TypeVar erfolgreich ist.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
compilers, devtools
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
25/100

Neue Issues direkt in Ihr Postfach

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