Skip to content

Maybe functools._lru_cache_wrapper should be covariant #15139

@hannes-ucsc

Description

@hannes-ucsc
from functools import cache

class Fruit:
    pass

class Apple(Fruit):
    pass

class FruitFactory:
    def f(self) -> Fruit: return Fruit()

class AppleFactory(FruitFactory):
    def f(self) -> Apple: return Apple()

class CachedFruitFactory:
    @cache
    def f(self) -> Fruit: return Fruit()

class CachedAppleFactory(CachedFruitFactory):
    @cache
    def f(self) -> Apple: return Apple()

yields

main.py:21: error: Signature of "f" incompatible with supertype "CachedFruitFactory"  [override]
main.py:21: note:      Superclass:
main.py:21: note:          _lru_cache_wrapper[Fruit]
main.py:21: note:      Subclass:
main.py:21: note:          _lru_cache_wrapper[Apple]
Found 1 error in 1 file (checked 1 source file)

https://mypy-play.net/?mypy=latest&python=3.13&gist=f839b078e46a8239e5a50e2d8087d1b4

Note how the uncached version passes. Adding the @cache decorator shouldn't break the ability to specialize return values in overrides.

I'm aware that _lru_cache_wrapper probably exposes functionality for manipulating the cached value, which would break covariance, but I reckon that 99% of users don't use it that way, while the use case I present here seems very common and must surprise many users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    stubs: improvementImprove/refactor existing annotations, other stubs issues

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions