Skip to content

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

Description

@esolment

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions