python / python/typeshed

cachetools: Subclassing TTLCache[KT, VT] loses generic type inference on instantiation

Offen
#15,798 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

stubs: false positive
Vorherrschende Sprache
Python
Sterne
5.1k
Forks
2.1k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
82

Beschreibung

Description

When subclassing TTLCache[KT, VT] with explicit generic parameters,
type checkers (tested with Pyright and mypy) fail to infer the correct
type on instantiation, reporting _SubClass[Any, Any, float] instead
of _SubClass[KT, VT].

Reproduction

from typing import Any
from cachetools import TTLCache

class _TrackedTTLCache[KT, VT](TTLCache[KT, VT]):
    def popitem(self) -> tuple[KT, VT]:
        key, value = super().popitem()
        return key, value

cache: _TrackedTTLCache[str, int] = _TrackedTTLCache(maxsize=128, ttl=600)
#     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# Error: Expected type '_TrackedTTLCache[str, int]',
#        got '_TrackedTTLCache[Any, Any, float]' instead

Expected behavior

_TrackedTTLCache(maxsize=128, ttl=600) should be inferred as
_TrackedTTLCache[str, int] — consistent with how the explicit
annotation on the left-hand side is declared.

Root cause

The stub signature for TTLCache.__init__ likely includes float
as a third implicit type parameter (from the timer argument),
which leaks into subclass inference and overrides the declared
generic parameters.

Workaround

from typing import cast

cache = cast(
    "_TrackedTTLCache[str, int]",
    _TrackedTTLCache(maxsize=128, ttl=600),
)

Environment

  • cachetools version: 7.1.1
  • PyCharm linter
  • Python: 3.12

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

Beginne damit, das typeshed-Stub für TTLCache.init und alle zugehörigen Type-Checker-Tests zu finden; untersuche, wie das timer-Argument zur generischen Inferenz beiträgt. Reproduziere das Subclass-Beispiel mit mypy und Pyright und überprüfe anschließend, dass die Instanziierung von _TrackedTTLCache(maxsize=128, ttl=600) als _TrackedTTLCache[str, int] inferiert wird, ohne den cast-Workaround.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
developer-experience
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
52/100

Neue Issues direkt in Ihr Postfach

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