Richtige Typanmerkungen für die Generatorfunktion, die Schnitte der angegebenen Sequenz hervorruft?Python

Python-Programme
Anonymous
 Richtige Typanmerkungen für die Generatorfunktion, die Schnitte der angegebenen Sequenz hervorruft?

Post by Anonymous »

Ich verwende Python 3.13 und habe diese Funktion: < /p>

Code: Select all

def chunk(data, chunk_size: int):
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
Ich möchte ihm Annotationen geben, um anzuzeigen, dass es mit Bytes , bytearray oder einer allgemeinen Sammlung arbeiten kann. Ich möchte nicht, dass der Rückgabetyp ein Gewerkschaftstyp aller möglichen Eingaben (z. B. Bytes | Bytearray | Sequenz [t] ) ist, da dies übermäßig weit ist; Ich möchte, dass der genaue Typ, den ich zufällig einbringe, wieder am anderen Ende herauskommt. Aufrufen von Chunk auf einem Bytes sollte Generator [Bytes] usw. zurückgeben,
Da Bytes und Bytearray beide an die Sequenz [t] entsprechen, war mein erster Versuch:

Code: Select all

def chunk[T](data: Sequence[T], chunk_size: int) -> Generator[Sequence[T]]:
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
, aber dies hat eine Kovarianzprobleme- Der Rückgabetyp ist Sequenz [t] , nicht Bytes , und Pyright beschwert

Code: Select all

def print_bytes(b: bytes) -> None: ...
):

Code: Select all

error: Argument of type "Sequence[int]" cannot be assigned to parameter "b" of type "bytes" in function "print_bytes"
  "Sequence[int]" is not assignable to "bytes" (reportArgumentType)
< /code>
Dann habe ich versucht, eine Typ -Einschränkung zu verwenden: "chunk
kann eine beliebige Sequenz nehmen und einen Generator dieses Typs zurückgeben. "

Code: Select all

def chunk[T: Sequence](data: T, chunk_size: int) -> Generator[T]:
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
< /code>
Diesmal beschwert sich Pyright über die Funktion selbst: < /p>
error: Return type of generator function must be compatible with "Generator[Sequence[Unknown], Any, Any]"
  "Generator[Sequence[Unknown], None, Unknown]" is not assignable to "Generator[T@chunk, None, None]"
    Type parameter "_YieldT_co@Generator" is covariant, but "Sequence[Unknown]" is not a subtype of "T@chunk"
      Type "Sequence[Unknown]" is not assignable to type "T@chunk" (reportReturnType)
Ich gebe zu, die Beschwerde hier nicht vollständig zu verstehen. Wir haben über die Typ-Einschränkung festgelegt, dass t eine Sequenz ist, aber Pyright mag es nicht und ich gehe davon aus, dass mein Code schuld ist.

Code: Select all

@typing.overload
def chunk[T: bytes | bytearray](data: T, chunk_size: int) -> Generator[T]: ...

@typing.overload
def chunk[T](data: Sequence[T], chunk_size: int) -> Generator[Sequence[T]]: ...

def chunk(data, chunk_size: int):
yield from (data[i : i + chunk_size] for i in range(0, len(data), chunk_size))
In diesem Fall kann Pyright die richtige Überladung für alle meine Verwendungen auswählen, aber dies fühlt sich ein wenig albern an- es gibt 2x so viel Tippcode wie den tatsächlichen Implementierungscode!>

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post