# Singletonize for Python
[](https://pypi.org/project/singletonize/)
[](https://opensource.org/licenses/MIT)
[](https://github.com/juans-castellanosr/singletonize/actions)
## Overview
**Singletonize** is a Python package providing a robust, thread-safe Singleton pattern implementation using metaclasses. It ensures strict singleton enforcement while offering useful utilities for instance management.
## Features
- **Strict Singleton Enforcement**: Ensures only one instance of a class exists.
- **Abstract Base Singleton Support**: Allows defining abstract singleton classes.
- **Thread-Safe Implementation**: Uses metaclasses for thread safety.
- **Instance Management Utilities**: Methods for checking, resetting, updating, and serializing instances.
- **Fully Typed with MyPy**: Ensures type safety.
- **Modern Package Management with Poetry**: Streamlined dependency and package management.
## Installation
Install using `pip`:
```sh
pip install singletonize
```
Or with `poetry`:
```sh
poetry add singletonize
```
## Usage
### Basic Singleton Example
```python
from singletonize import Singleton
class ExampleSingleton(Singleton):
def __init__(self, value: int):
self.value = value
# Creating an instance
instance1 = ExampleSingleton(10)
instance2 = ExampleSingleton.get_instance()
assert instance1 is instance2 # True
assert instance1.value == instance2.value == 10 # True
```
### Abstract Base Singleton
```python
from singletonize import SingletonABC
from abc import abstractmethod
class AbstractExample(SingletonABC):
@abstractmethod
def some_method(self):
pass
class ConcreteExample(AbstractExample):
def __init__(self, value: int):
self.a = value
def some_method(self):
return self.a
# Creating a singleton instance
singleton_instance = ConcreteExample(10)
assert singleton_instance.some_method() == 10
```
### Instance Management
```python
# Checking if an instance exists
assert ExampleSingleton.has_instance() # True
# Getting the instance or None
instance = ExampleSingleton.get_instance_or_none()
# Updating instance attributes
ExampleSingleton.update_instance(value=20)
assert instance.value == 20
# Converting instance to dictionary
instance_dict = ExampleSingleton.instance_as_dict()
print(instance_dict) # {'value': 20}
# Resetting the instance
ExampleSingleton.reset_instance(30)
assert ExampleSingleton.get_instance().value == 30
```
## Performance Benchmark
Singletonize has been benchmarked to evaluate its efficiency in both single-threaded and multi-threaded environments.
### Single-threaded Performance
#### Standard Singleton
| Name | Min (ns) | Max (ns) | Mean (ns) | StdDev (ns) | Median (ns) | IQR (ns) | Outliers | OPS (Mops/s) | Rounds | Iterations |
| -------------------------- | -------- | ----------- | --------- | ----------- | ----------- | -------- | --------- | ------------ | ------ | ---------- |
| test_singleton_performance | 493.0189 | 29,423.0122 | 566.5408 | 424.3932 | 535.0157 | 20.0234 | 2081;8156 | 1.7651 | 114969 | 1 |
#### SingletonABC
| Name | Min (ns) | Max (ns) | Mean (ns) | StdDev (ns) | Median (ns) | IQR (ns) | Outliers | OPS (Mops/s) | Rounds | Iterations |
| ------------------------------ | -------- | ---------- | --------- | ----------- | ----------- | -------- | ---------- | ------------ | ------ | ---------- |
| test_singleton_abc_performance | 418.9002 | 7,668.2001 | 461.9932 | 96.6991 | 445.9507 | 8.2495 | 3741;12382 | 2.1645 | 108425 | 20 |
### Multi-threaded Performance
#### SingletonABC with Multithreading
| Name | Min (ms) | Max (ms) | Mean (ms) | StdDev (ms) | Median (ms) | IQR (ms) | Outliers | OPS | Rounds | Iterations |
| --------------------------------------------- | -------- | -------- | --------- | ----------- | ----------- | -------- | -------- | ------- | ------ | ---------- |
| test_singleton_abc_multithreading_performance | 11.7924 | 25.3676 | 13.9574 | 3.3869 | 12.5568 | 1.0450 | 11;11 | 71.6466 | 70 | 1 |
#### Standard Singleton with Multithreading
| Name | Min (ms) | Max (ms) | Mean (ms) | StdDev (ms) | Median (ms) | IQR (ms) | Outliers | OPS | Rounds | Iterations |
| ----------------------------------------- | -------- | -------- | --------- | ----------- | ----------- | -------- | -------- | ------- | ------ | ---------- |
| test_singleton_multithreading_performance | 11.8365 | 22.9825 | 13.9596 | 3.3061 | 12.7048 | 1.2596 | 8;8 | 71.6355 | 53 | 1 |
These benchmarks indicate that `SingletonABC` has slightly better performance in single-threaded scenarios, while both implementations perform similarly under multi-threaded conditions.
## Development
### Setting Up the Project
1. Clone the repository:
```sh
git clone https://github.com/juans-castellanosr/singletonize.git
cd singletonize
```
2. Install dependencies using `poetry`:
```sh
poetry install
```
### Code Quality & Type Checking
This project enforces strict type checking and linting:
```sh
mypy singletonize
ruff check singletonize
```
### Running Tests
Tests are managed with `pytest`:
```sh
pytest tests/
```
Performance benchmarks can be run using:
```sh
pytest --benchmark-only
```
## Contributing
We welcome contributions! Follow these guidelines to ensure smooth collaboration:
### Forking and Branching Strategy
1. **Fork** the repository and clone it locally.
2. **Create a branch** from `development`:
```sh
git checkout -b feature/your-feature development
```
3. **Make your changes** and commit with meaningful messages.
4. **Push your branch** to your fork:
```sh
git push origin feature/your-feature
```
5. **Create a Pull Request (PR) to the `development` branch**.
6. **Wait for approval** and feedback before merging.
### Code Standards
- Follow PEP8 (`ruff` is used for linting).
- Use `mypy` for type checking.
- Ensure all tests pass before submitting PRs.
## License
This project is licensed under the MIT License. See [LICENSE](LICENSE) for details.
## Contact
For support, open an issue or contact the maintainers via GitHub Discussions.
---
Happy coding! 🚀
Raw data
{
"_id": null,
"home_page": null,
"name": "singletonize",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.0",
"maintainer_email": null,
"keywords": "singleton, design-patterns, singletonize, python, oop, metaclass, singleton-pattern",
"author": "Juan Sebastian Castellanos Rivillas",
"author_email": "59780501+juans-castellanosr@users.noreply.github.com",
"download_url": "https://files.pythonhosted.org/packages/6c/11/5f43253f6ed96b2cccb9df5f9abce001536aeb6939102fa2f31d8a0fd283/singletonize-1.1.1.tar.gz",
"platform": null,
"description": "# Singletonize for Python\n\n[](https://pypi.org/project/singletonize/)\n[](https://opensource.org/licenses/MIT)\n[](https://github.com/juans-castellanosr/singletonize/actions)\n\n## Overview\n\n**Singletonize** is a Python package providing a robust, thread-safe Singleton pattern implementation using metaclasses. It ensures strict singleton enforcement while offering useful utilities for instance management.\n\n## Features\n\n- **Strict Singleton Enforcement**: Ensures only one instance of a class exists.\n- **Abstract Base Singleton Support**: Allows defining abstract singleton classes.\n- **Thread-Safe Implementation**: Uses metaclasses for thread safety.\n- **Instance Management Utilities**: Methods for checking, resetting, updating, and serializing instances.\n- **Fully Typed with MyPy**: Ensures type safety.\n- **Modern Package Management with Poetry**: Streamlined dependency and package management.\n\n## Installation\n\nInstall using `pip`:\n\n```sh\npip install singletonize\n```\n\nOr with `poetry`:\n\n```sh\npoetry add singletonize\n```\n\n## Usage\n\n### Basic Singleton Example\n\n```python\nfrom singletonize import Singleton\n\nclass ExampleSingleton(Singleton):\n def __init__(self, value: int):\n self.value = value\n\n# Creating an instance\ninstance1 = ExampleSingleton(10)\ninstance2 = ExampleSingleton.get_instance()\n\nassert instance1 is instance2 # True\nassert instance1.value == instance2.value == 10 # True\n```\n\n### Abstract Base Singleton\n\n```python\nfrom singletonize import SingletonABC\nfrom abc import abstractmethod\n\nclass AbstractExample(SingletonABC):\n @abstractmethod\n def some_method(self):\n pass\n\nclass ConcreteExample(AbstractExample):\n def __init__(self, value: int):\n self.a = value\n\n def some_method(self):\n return self.a\n\n# Creating a singleton instance\nsingleton_instance = ConcreteExample(10)\nassert singleton_instance.some_method() == 10\n```\n\n### Instance Management\n\n```python\n# Checking if an instance exists\nassert ExampleSingleton.has_instance() # True\n\n# Getting the instance or None\ninstance = ExampleSingleton.get_instance_or_none()\n\n# Updating instance attributes\nExampleSingleton.update_instance(value=20)\nassert instance.value == 20\n\n# Converting instance to dictionary\ninstance_dict = ExampleSingleton.instance_as_dict()\nprint(instance_dict) # {'value': 20}\n\n# Resetting the instance\nExampleSingleton.reset_instance(30)\nassert ExampleSingleton.get_instance().value == 30\n```\n\n## Performance Benchmark\n\nSingletonize has been benchmarked to evaluate its efficiency in both single-threaded and multi-threaded environments.\n\n### Single-threaded Performance\n\n#### Standard Singleton\n\n| Name | Min (ns) | Max (ns) | Mean (ns) | StdDev (ns) | Median (ns) | IQR (ns) | Outliers | OPS (Mops/s) | Rounds | Iterations |\n| -------------------------- | -------- | ----------- | --------- | ----------- | ----------- | -------- | --------- | ------------ | ------ | ---------- |\n| test_singleton_performance | 493.0189 | 29,423.0122 | 566.5408 | 424.3932 | 535.0157 | 20.0234 | 2081;8156 | 1.7651 | 114969 | 1 |\n\n#### SingletonABC\n\n| Name | Min (ns) | Max (ns) | Mean (ns) | StdDev (ns) | Median (ns) | IQR (ns) | Outliers | OPS (Mops/s) | Rounds | Iterations |\n| ------------------------------ | -------- | ---------- | --------- | ----------- | ----------- | -------- | ---------- | ------------ | ------ | ---------- |\n| test_singleton_abc_performance | 418.9002 | 7,668.2001 | 461.9932 | 96.6991 | 445.9507 | 8.2495 | 3741;12382 | 2.1645 | 108425 | 20 |\n\n### Multi-threaded Performance\n\n#### SingletonABC with Multithreading\n\n| Name | Min (ms) | Max (ms) | Mean (ms) | StdDev (ms) | Median (ms) | IQR (ms) | Outliers | OPS | Rounds | Iterations |\n| --------------------------------------------- | -------- | -------- | --------- | ----------- | ----------- | -------- | -------- | ------- | ------ | ---------- |\n| test_singleton_abc_multithreading_performance | 11.7924 | 25.3676 | 13.9574 | 3.3869 | 12.5568 | 1.0450 | 11;11 | 71.6466 | 70 | 1 |\n\n#### Standard Singleton with Multithreading\n\n| Name | Min (ms) | Max (ms) | Mean (ms) | StdDev (ms) | Median (ms) | IQR (ms) | Outliers | OPS | Rounds | Iterations |\n| ----------------------------------------- | -------- | -------- | --------- | ----------- | ----------- | -------- | -------- | ------- | ------ | ---------- |\n| test_singleton_multithreading_performance | 11.8365 | 22.9825 | 13.9596 | 3.3061 | 12.7048 | 1.2596 | 8;8 | 71.6355 | 53 | 1 |\n\nThese benchmarks indicate that `SingletonABC` has slightly better performance in single-threaded scenarios, while both implementations perform similarly under multi-threaded conditions.\n\n## Development\n\n### Setting Up the Project\n\n1. Clone the repository:\n\n ```sh\n git clone https://github.com/juans-castellanosr/singletonize.git\n cd singletonize\n ```\n\n2. Install dependencies using `poetry`:\n\n ```sh\n poetry install\n ```\n\n### Code Quality & Type Checking\n\nThis project enforces strict type checking and linting:\n\n```sh\nmypy singletonize\nruff check singletonize\n```\n\n### Running Tests\n\nTests are managed with `pytest`:\n\n```sh\npytest tests/\n```\n\nPerformance benchmarks can be run using:\n\n```sh\npytest --benchmark-only\n```\n\n## Contributing\n\nWe welcome contributions! Follow these guidelines to ensure smooth collaboration:\n\n### Forking and Branching Strategy\n\n1. **Fork** the repository and clone it locally.\n2. **Create a branch** from `development`:\n ```sh\n git checkout -b feature/your-feature development\n ```\n3. **Make your changes** and commit with meaningful messages.\n4. **Push your branch** to your fork:\n ```sh\n git push origin feature/your-feature\n ```\n5. **Create a Pull Request (PR) to the `development` branch**.\n6. **Wait for approval** and feedback before merging.\n\n### Code Standards\n\n- Follow PEP8 (`ruff` is used for linting).\n- Use `mypy` for type checking.\n- Ensure all tests pass before submitting PRs.\n\n## License\n\nThis project is licensed under the MIT License. See [LICENSE](LICENSE) for details.\n\n## Contact\n\nFor support, open an issue or contact the maintainers via GitHub Discussions.\n\n---\n\nHappy coding! \ud83d\ude80\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A lightweight Python library for implementing the Singleton pattern efficiently.",
"version": "1.1.1",
"project_urls": {
"Documentation": "https://github.com/juans-castellanosr/singletonize#readme",
"GitHub": "https://github.com/juans-castellanosr/singletonize",
"PyPi": "https://pypi.org/project/singletonize/"
},
"split_keywords": [
"singleton",
" design-patterns",
" singletonize",
" python",
" oop",
" metaclass",
" singleton-pattern"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "eb37c6c6c80bca30ebb5235ceecb5d609ec9ec3ce29335466343a81e4d34d0a6",
"md5": "452edf04187980dfbabf6882fea9e518",
"sha256": "c85957984c03b9485946aa7b62799b702fb1a09bfc50ef3dda4968e21253491f"
},
"downloads": -1,
"filename": "singletonize-1.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "452edf04187980dfbabf6882fea9e518",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.0",
"size": 10512,
"upload_time": "2025-02-10T23:42:16",
"upload_time_iso_8601": "2025-02-10T23:42:16.217287Z",
"url": "https://files.pythonhosted.org/packages/eb/37/c6c6c80bca30ebb5235ceecb5d609ec9ec3ce29335466343a81e4d34d0a6/singletonize-1.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "6c115f43253f6ed96b2cccb9df5f9abce001536aeb6939102fa2f31d8a0fd283",
"md5": "06c5a95c160eeba6cd59f525bf0188db",
"sha256": "38e5f47c53412e99d095ea86ce0f3eed038e59cad05ddc0eb7130e78f35aa5a3"
},
"downloads": -1,
"filename": "singletonize-1.1.1.tar.gz",
"has_sig": false,
"md5_digest": "06c5a95c160eeba6cd59f525bf0188db",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.0",
"size": 7284,
"upload_time": "2025-02-10T23:42:18",
"upload_time_iso_8601": "2025-02-10T23:42:18.157747Z",
"url": "https://files.pythonhosted.org/packages/6c/11/5f43253f6ed96b2cccb9df5f9abce001536aeb6939102fa2f31d8a0fd283/singletonize-1.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-02-10 23:42:18",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "juans-castellanosr",
"github_project": "singletonize#readme",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "singletonize"
}