Metadata-Version: 2.4
Name: philiprehberger-singleton
Version: 0.2.0
Summary: Thread-safe singleton and multiton pattern decorators.
Project-URL: Homepage, https://github.com/philiprehberger/py-singleton#readme
Project-URL: Repository, https://github.com/philiprehberger/py-singleton
Project-URL: Issues, https://github.com/philiprehberger/py-singleton/issues
Project-URL: Changelog, https://github.com/philiprehberger/py-singleton/blob/main/CHANGELOG.md
Author: Philip Rehberger
License-Expression: MIT
License-File: LICENSE
Keywords: decorator,design-pattern,multiton,pattern,singleton
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# philiprehberger-singleton

[![Tests](https://github.com/philiprehberger/py-singleton/actions/workflows/publish.yml/badge.svg)](https://github.com/philiprehberger/py-singleton/actions/workflows/publish.yml)
[![PyPI version](https://img.shields.io/pypi/v/philiprehberger-singleton.svg)](https://pypi.org/project/philiprehberger-singleton/)
[![Last updated](https://img.shields.io/github/last-commit/philiprehberger/py-singleton)](https://github.com/philiprehberger/py-singleton/commits/main)

Thread-safe singleton and multiton pattern decorators.

## Installation

```bash
pip install philiprehberger-singleton
```

## Usage

### Singleton

The `@singleton` decorator ensures only one instance of a class exists:

```python
from philiprehberger_singleton import singleton

@singleton
class Database:
    def __init__(self, url: str) -> None:
        self.url = url

db1 = Database("postgres://localhost/mydb")
db2 = Database("postgres://localhost/other")

assert db1 is db2  # same instance
assert db1.url == "postgres://localhost/mydb"
```

#### Reset

Use `reset()` to discard the cached instance (useful in tests):

```python
Database.reset()
db3 = Database("postgres://localhost/new")
assert db3.url == "postgres://localhost/new"
```

### Multiton

The `@multiton(key=...)` decorator maintains one instance per unique key value:

```python
from philiprehberger_singleton import multiton

@multiton(key="name")
class Connection:
    def __init__(self, name: str, timeout: int = 30) -> None:
        self.name = name
        self.timeout = timeout

cache = Connection("cache", timeout=10)
db = Connection("db", timeout=60)
cache2 = Connection("cache")

assert cache is cache2       # same key -> same instance
assert cache is not db        # different key -> different instance
```

#### Reset

Use `reset()` to discard all cached instances:

```python
Connection.reset()
```

## API

| Function / Class | Description |
|------------------|-------------|
| `@singleton` | Thread-safe singleton decorator. Returns the same instance on every call. |
| `@multiton(key)` | Thread-safe multiton decorator factory. One instance per unique value of the named parameter. |
| `cls.reset()` | Discards cached instance(s), added by both decorators. |

## Development

```bash
pip install -e .
python -m pytest tests/ -v
```

## Support

If you find this project useful:

⭐ [Star the repo](https://github.com/philiprehberger/py-singleton)

🐛 [Report issues](https://github.com/philiprehberger/py-singleton/issues?q=is%3Aissue+is%3Aopen+label%3Abug)

💡 [Suggest features](https://github.com/philiprehberger/py-singleton/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement)

❤️ [Sponsor development](https://github.com/sponsors/philiprehberger)

🌐 [All Open Source Projects](https://philiprehberger.com/open-source-packages)

💻 [GitHub Profile](https://github.com/philiprehberger)

🔗 [LinkedIn Profile](https://www.linkedin.com/in/philiprehberger)

## License

[MIT](LICENSE)
