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.
- 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.
Install using pip
:
pip install singletonize
Or with poetry
:
poetry add singletonize
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
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
# 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
Singletonize has been benchmarked to evaluate its efficiency in both single-threaded and multi-threaded environments.
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 |
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 |
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 |
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.
-
Clone the repository:
git clone /~https://github.com/juans-castellanosr/singletonize.git cd singletonize
-
Install dependencies using
poetry
:poetry install
This project enforces strict type checking and linting:
mypy singletonize
ruff check singletonize
Tests are managed with pytest
:
pytest tests/
Performance benchmarks can be run using:
pytest --benchmark-only
We welcome contributions! Follow these guidelines to ensure smooth collaboration:
- Fork the repository and clone it locally.
- Create a branch from
development
:git checkout -b feature/your-feature development
- Make your changes and commit with meaningful messages.
- Push your branch to your fork:
git push origin feature/your-feature
- Create a Pull Request (PR) to the
development
branch. - Wait for approval and feedback before merging.
- Follow PEP8 (
ruff
is used for linting). - Use
mypy
for type checking. - Ensure all tests pass before submitting PRs.
This project is licensed under the MIT License. See LICENSE for details.
For support, open an issue or contact the maintainers via GitHub Discussions.
Happy coding! 🚀