dissolve-python 0.3.0

A tool to dissolve deprecated calls in Python codebases
Documentation
"""
Magic method deprecation examples.
"""

try:
    from dissolve import replace_me
except ModuleNotFoundError:
    # Fallback implementation for when dissolve is not available
    import warnings

    def replace_me(since=None, remove_in=None, message=None):
        def decorator(func):
            def wrapper(*args, **kwargs):
                msg = f"{func.__name__} has been deprecated"
                if since:
                    msg += f" since {since}"
                if remove_in:
                    msg += f" and will be removed in {remove_in}"
                if message:
                    msg += f". {message}"
                else:
                    msg += ". Consider running 'dissolve migrate' to automatically update your code."
                warnings.warn(msg, DeprecationWarning, stacklevel=2)
                return func(*args, **kwargs)
            return wrapper
        return decorator


class DataContainer:
    """
    Modern data container with magic methods.
    """
    
    def __init__(self, data=None):
        self._data = data or []
        self._metadata = {}
    
    def __len__(self):
        """Return the length of the container."""
        return len(self._data)
    
    def __str__(self):
        """Return string representation."""
        return f"DataContainer({len(self._data)} items)"
    
    def __repr__(self):
        """Return detailed representation."""
        return f"DataContainer(data={self._data!r}, metadata={self._metadata!r})"
    
    def __getitem__(self, key):
        """Get item by index or key."""
        if isinstance(key, int):
            return self._data[key]
        elif isinstance(key, str):
            return self._metadata.get(key)
        else:
            raise TypeError("Key must be int or str")
    
    def __setitem__(self, key, value):
        """Set item by index or key."""
        if isinstance(key, int):
            self._data[key] = value
        elif isinstance(key, str):
            self._metadata[key] = value
        else:
            raise TypeError("Key must be int or str")
    
    def __iter__(self):
        """Iterate over data items."""
        return iter(self._data)
    
    def __contains__(self, item):
        """Check if item is in container."""
        return item in self._data
    
    def add(self, item):
        """Add an item to the container."""
        self._data.append(item)
    
    def remove(self, item):
        """Remove an item from the container."""
        self._data.remove(item)
    
    def get_size(self):
        """Get the size of the container."""
        return len(self._data)
    
    def to_string(self):
        """Convert container to string representation."""
        return str(self)


class LegacyContainer:
    """
    Legacy container with deprecated magic methods.
    """
    
    def __init__(self, items=None):
        self._items = items or []
        self._extra = {}
    
    def __len__(self):
        """Return length (new implementation)."""
        return len(self._items)
    
    def __str__(self):
        """Return string representation (new implementation)."""
        return f"LegacyContainer({len(self._items)} items)"
    
    # === DEPRECATED MAGIC METHODS ===
    
    @replace_me(since="2.0.0", remove_in="3.0.0")
    def __unicode__(self):
        """
        Return unicode representation (deprecated magic method).
        
        .. deprecated:: 2.0.0
            Use :meth:`__str__` instead.
        """
        return str(self)
    
    @replace_me(since="1.0.0")
    def size(self):
        """
        Get container size (deprecated method).
        
        .. deprecated:: 1.8.0
            Use ``len(container)`` instead.
        """
        return len(self)
    
    @replace_me(since="1.0.0")  
    def to_str(self):
        """
        Convert to string (deprecated method).
        
        .. deprecated:: 1.5.0
            Use ``str(container)`` instead.
        """
        return str(self)
    
    # Deprecated alternative to magic methods
    @replace_me(since="2.1.0")
    def get_item(self, index):
        """
        Get item by index (deprecated method).
        
        .. deprecated:: 2.1.0
            Use ``container[index]`` instead.
        """
        return self._items[index]
    
    @replace_me(since="2.1.0")
    def set_item(self, index, value):
        """
        Set item by index (deprecated method).
        
        .. deprecated:: 2.1.0
            Use ``container[index] = value`` instead.
        """
        self._items[index] = value
    
    @replace_me(since="1.9.0")
    def contains(self, item):
        """
        Check if container contains item (deprecated method).
        
        .. deprecated:: 1.9.0
            Use ``item in container`` instead.
        """
        return item in self._items
    
    # Magic methods implemented correctly (not deprecated)
    def __getitem__(self, key):
        """Get item by key."""
        return self._items[key]
    
    def __setitem__(self, key, value):
        """Set item by key."""
        self._items[key] = value
    
    def __contains__(self, item):
        """Check if item exists."""
        return item in self._items
    
    def __iter__(self):
        """Iterate over items."""
        return iter(self._items)


class SmartList:
    """
    Enhanced list with deprecated convenience methods.
    """
    
    def __init__(self, initial_data=None):
        self._data = list(initial_data or [])
    
    def __len__(self):
        return len(self._data)
    
    def __str__(self):
        return f"SmartList{self._data}"
    
    def __repr__(self):
        return f"SmartList({self._data!r})"
    
    def __getitem__(self, index):
        return self._data[index]
    
    def __setitem__(self, index, value):
        self._data[index] = value
    
    def __iter__(self):
        return iter(self._data)
    
    def __contains__(self, item):
        return item in self._data
    
    def append(self, item):
        """Add item to end of list."""
        self._data.append(item)
    
    def extend(self, items):
        """Add multiple items to end of list."""
        self._data.extend(items)
    
    def count(self):
        """Get the count of items."""
        return len(self._data)
    
    # === DEPRECATED CONVENIENCE METHODS ===
    
    @replace_me(since="1.0.0")
    def length(self):
        """
        Get list length (deprecated).
        
        .. deprecated:: 1.4.0
            Use ``len(smart_list)`` instead.
        """
        return len(self)
    
    @replace_me(since="1.0.0")  
    def get_count(self):
        """
        Get item count (deprecated).
        
        .. deprecated:: 1.6.0
            Use ``len(smart_list)`` instead.
        """
        return len(self)
    
    @replace_me(since="1.0.0")
    def is_empty(self):
        """
        Check if list is empty (deprecated).
        
        .. deprecated:: 2.0.0
            Use ``not bool(smart_list)`` or ``len(smart_list) == 0`` instead.
        """
        return len(self) == 0
    
    @replace_me(since="1.0.0")
    def has_item(self, item):
        """
        Check if list contains item (deprecated).
        
        .. deprecated:: 1.7.0
            Use ``item in smart_list`` instead.
        """
        return item in self