Metadata-Version: 2.4
Name: cacheprop
Version: 0.1.0
Summary: Typed cached property decorator with async support
Author-email: "Nikola T." <git@nikola.aleeas.com>
License-Expression: 0BSD
Project-URL: Homepage, https://gitlab.com/elrik/cacheprop
Project-URL: Repository, https://gitlab.com/elrik/cacheprop.git
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# cacheprop

[![PyPI](https://img.shields.io/pypi/v/cacheprop.svg)](https://pypi.python.org/pypi/cacheprop)

A typed cached property decorator with async support.

## Why?

- Makes caching of time or computation-expensive properties quick and easy.
- Provides proper type checking via PEP 695 generic syntax (`class cacheprop[T]`).
- Works with both sync and async methods — the return value is automatically awaited for async functions.
- Preserves `__doc__` and `__annotations__` from the wrapped function.

## Installation

```bash
pip install cacheprop
```

Requires **Python 3.12+** (uses PEP 695 type parameter syntax).

## Usage

### Sync methods

```python
from cacheprop import cacheprop


class MyClass:
    @cacheprop
    def expensive(self) -> str:
        return heavy_computation()


obj = MyClass()
print(obj.expensive)  # calls heavy_computation(), caches result
print(obj.expensive)  # returns cached value, no call
```

### Async methods

```python
class MyAsyncClass:
    @cacheprop
    async def fetch_data(self) -> dict:
        return await http_get("https://example.com/api")


async def main():
    obj = MyAsyncClass()
    data1 = await obj.fetch_data  # awaits and caches
    data2 = await obj.fetch_data  # returns cached value, no await needed
```

### Reusing an existing function

```python
def get_absolute_url(self):
    return f"/items/{self.id}"


class Item:
    url = cacheprop(get_absolute_url)
```

## Type checking

The generic parameter `T` lets type checkers infer the return type:

```python
@cacheprop
def size(self) -> int:
    return len(self.data)

reveal_type(obj.size)  # int (not object or Any)
```

## License

0BSD
