or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/pypi-singleton-decorator

A testable singleton decorator that allows easily creating singleton objects by adding a decorator to class definitions while maintaining testability.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/singleton-decorator@1.0.x

To install, run

npx @tessl/cli install tessl/pypi-singleton-decorator@1.0.0

index.mddocs/

Singleton Decorator

A testable singleton decorator that allows easily creating singleton objects by adding a decorator to class definitions while maintaining testability. Unlike traditional singleton implementations that make direct class access impossible in unit tests, this decorator uses a wrapper object that stores the original class in a __wrapped__ attribute, allowing developers to access the decorated class directly for isolated testing.

Package Information

  • Package Name: singleton-decorator
  • Language: Python
  • Installation: pip install singleton-decorator

Core Imports

from singleton_decorator import singleton

Version information:

from singleton_decorator import __version__

Basic Usage

from singleton_decorator import singleton

@singleton
class DatabaseConnection:
    def __init__(self, host, port):
        self.host = host
        self.port = port
        print(f"Connecting to {host}:{port}")
    
    def query(self, sql):
        return f"Executing: {sql}"

# First call creates the instance
db1 = DatabaseConnection("localhost", 5432)
# Subsequent calls return the same instance (constructor args ignored)
db2 = DatabaseConnection("ignored", 9999)
db3 = DatabaseConnection("also_ignored", 1111)

# All variables reference the same instance
assert db1 is db2 is db3
print(db1.host)  # "localhost"
print(db2.host)  # "localhost" (not "ignored")

Capabilities

Singleton Decorator

Creates a singleton wrapper for any class, ensuring only one instance exists while maintaining testability through the __wrapped__ attribute.

def singleton(cls):
    """
    A singleton decorator that returns a wrapper object. A call on that object
    returns a single instance object of decorated class. Use the __wrapped__
    attribute to access decorated class directly in unit tests.
    
    Args:
        cls: The class to decorate as a singleton
        
    Returns:
        _SingletonWrapper: Wrapper object that manages singleton instance
    """

Testing Access

Access the original class for isolated unit testing without singleton behavior.

# Access pattern for testing
decorated_class.__wrapped__  # Original class for direct method calls

Usage in Tests:

from unittest import TestCase, mock
from singleton_decorator import singleton

@singleton
class MyService:
    def __init__(self, config):
        self.config = config
    
    def process_data(self, data):
        return f"Processing {data} with {self.config}"

class TestMyService(TestCase):
    def test_process_data(self):
        # Use __wrapped__ to test method in isolation
        mock_self = mock.MagicMock()
        mock_self.config = "test_config"
        
        result = MyService.__wrapped__.process_data(mock_self, "test_data")
        
        assert result == "Processing test_data with test_config"

Types and Implementation Details

class _SingletonWrapper:
    """
    Internal wrapper class created for each decorated class.
    Manages singleton instance lifecycle.
    """
    
    def __init__(self, cls):
        """
        Initialize wrapper with the decorated class.
        
        Args:
            cls: The class to wrap
        """
    
    def __call__(self, *args, **kwargs):
        """
        Returns singleton instance of wrapped class.
        Creates instance on first call, returns existing instance thereafter.
        
        Args:
            *args: Constructor arguments (only used on first call)
            **kwargs: Constructor keyword arguments (only used on first call)
            
        Returns:
            object: Single instance of the wrapped class
        """
    
    __wrapped__: type  # Original decorated class for testing access
    _instance: object  # Singleton instance (None until first call)

__version__: str  # Package version constant ("1.0.0")

Important Notes

Constructor Behavior

  • The __init__ method is called only once with arguments from the first instantiation
  • All subsequent instantiation attempts ignore their arguments and return the existing instance
  • This behavior ensures true singleton semantics but requires careful consideration of constructor arguments

Testing Guidelines

  • Use ClassName.__wrapped__ to access the original class in unit tests
  • Pass mock objects as self to test methods in complete isolation
  • This approach avoids constructor dependencies and maintains test isolation
  • The __wrapped__ attribute provides direct access to all class methods and attributes

Thread Safety

This implementation does not provide thread-safety guarantees. In multi-threaded environments, consider additional synchronization mechanisms if concurrent access to the singleton creation is possible.