Skip to content

Commit

Permalink
Merge pull request #19 from jaraco/feature/annotate-method-cache
Browse files Browse the repository at this point in the history
Add type annotations for method_cache.
  • Loading branch information
jaraco committed Dec 20, 2021
2 parents 9fe43da + 6e1cc50 commit 7016908
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
v3.5.0
======

Add type annotations to ``method_cache``.

v3.4.0
======

Expand Down
24 changes: 19 additions & 5 deletions jaraco/functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

import more_itertools

from typing import Callable, TypeVar


CallableT = TypeVar("CallableT", bound=Callable[..., object])


def compose(*funcs):
"""
Expand Down Expand Up @@ -92,7 +97,12 @@ def wrapper(*args, **kwargs):
return wrapper


def method_cache(method, cache_wrapper=functools.lru_cache()):
def method_cache(
method: CallableT,
cache_wrapper: Callable[
[CallableT], CallableT
] = functools.lru_cache(), # type: ignore[assignment]
) -> CallableT:
"""
Wrap lru_cache to support storing the cache data in the object instances.
Expand Down Expand Up @@ -160,17 +170,21 @@ def method_cache(method, cache_wrapper=functools.lru_cache()):
for another implementation and additional justification.
"""

def wrapper(self, *args, **kwargs):
def wrapper(self: object, *args: object, **kwargs: object) -> object:
# it's the first call, replace the method with a cached, bound method
bound_method = types.MethodType(method, self)
bound_method: CallableT = types.MethodType( # type: ignore[assignment]
method, self
)
cached_method = cache_wrapper(bound_method)
setattr(self, method.__name__, cached_method)
return cached_method(*args, **kwargs)

# Support cache clear even before cache has been created.
wrapper.cache_clear = lambda: None
wrapper.cache_clear = lambda: None # type: ignore[attr-defined]

return _special_method_cache(method, cache_wrapper) or wrapper
return ( # type: ignore[return-value]
_special_method_cache(method, cache_wrapper) or wrapper
)


def _special_method_cache(method, cache_wrapper):
Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ skip-string-normalization = true
[pytest.enabler.black]
addopts = "--black"

[pytest.enabler.mypy]
addopts = "--mypy"
# disabled for pytest-dev/pytest#8332 (see #19)
# [pytest.enabler.mypy]
# addopts = "--mypy"

[pytest.enabler.flake8]
addopts = "--flake8"
Expand Down

0 comments on commit 7016908

Please sign in to comment.