# function cleanup: <TEMP>/library/__init__.py
"""
Example library demonstrating @replace_me deprecation patterns.
This package shows various ways to deprecate functions, classes, and attributes
using the dissolve library.
"""
from .utils import add, multiply, old_add, old_multiply
from .models import DataProcessor, OldDataProcessor, User
from .config import API_BASE_URL, DEFAULT_TIMEOUT, OLD_API_URL, OLD_TIMEOUT
from .async_ops import fetch_data, old_fetch_data
from .processors import ProcessingEngine
__version__ = "2.1.0"
# Re-export the main functions for convenience
__all__ = [
# New API
"add", "multiply", "DataProcessor", "User", "fetch_data", "ProcessingEngine",
"API_BASE_URL", "DEFAULT_TIMEOUT",
# Deprecated API (will be removed in 3.0.0)
"old_add", "old_multiply", "OldDataProcessor", "old_fetch_data",
"OLD_API_URL", "OLD_TIMEOUT",
]
# function cleanup: <TEMP>/library/async_ops.py
"""
Async function examples demonstrating async deprecation patterns.
"""
import asyncio
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
async def fetch_data(url, timeout=30, headers=None):
"""
Fetch data from a URL with proper timeout and headers support (new API).
"""
if headers is None:
headers = {}
# Simulate async HTTP request
await asyncio.sleep(0.1) # Simulate network delay
return {
"url": url,
"timeout": timeout,
"headers": headers,
"data": f"Data from {url}",
"status": 200
}
async def fetch_json(url, timeout=30, parse_dates=False):
"""
Fetch and parse JSON data from a URL (new API).
"""
response = await fetch_data(url, timeout=timeout, headers={"Accept": "application/json"})
# Simulate JSON parsing
json_data = {"parsed": True, "content": response["data"]}
if parse_dates:
json_data["dates_parsed"] = True
return json_data
async def upload_file(file_path, destination_url, chunk_size=8192):
"""
Upload a file to a destination URL with chunked upload (new API).
"""
await asyncio.sleep(0.2) # Simulate upload
return {
"file_path": file_path,
"destination": destination_url,
"chunk_size": chunk_size,
"status": "uploaded"
}
# === DEPRECATED ASYNC FUNCTIONS ===
@replace_me(since="3.0.0", remove_in="4.0.0")
async def old_fetch_data(url):
"""
Fetch data from a URL (legacy version with hardcoded timeout).
.. deprecated:: 3.0.0
Use :func:`fetch_data` instead with explicit timeout parameter.
"""
return await fetch_data(url, timeout=30)
@replace_me(since="2.5.0")
async def get_json(endpoint):
"""
Legacy JSON fetcher with hardcoded settings.
.. deprecated:: 2.5.0
Use :func:`fetch_json` instead.
"""
return await fetch_json(f"https://api.example.com/{endpoint}", timeout=60, parse_dates=True)
@replace_me(since="1.0.0")
async def legacy_upload(path, url):
"""
Legacy file upload function.
.. deprecated:: 2.8.0
Use :func:`upload_file` instead.
"""
return await upload_file(path, url, chunk_size=4096)
# Complex async transformation
@replace_me(since="3.1.0")
async def old_batch_fetch(urls, delay=1):
"""
Fetch multiple URLs with a delay between requests (legacy version).
.. deprecated:: 3.1.0
Use :func:`batch_fetch` instead.
"""
return await batch_fetch(urls, delay_seconds=delay * 2, timeout=45)
async def batch_fetch(urls, delay_seconds=0.5, timeout=30):
"""
Fetch multiple URLs with configurable delay and timeout (new API).
"""
results = []
for url in urls:
result = await fetch_data(url, timeout=timeout)
results.append(result)
if delay_seconds > 0:
await asyncio.sleep(delay_seconds)
return results
# function cleanup: <TEMP>/library/config.py
"""
Configuration and attribute deprecation examples.
"""
try:
from dissolve import replace_me
except ModuleNotFoundError:
# Fallback for replace_me function calls (attribute deprecation)
def replace_me(value):
import warnings
warnings.warn(
"This attribute has been deprecated. Consider using dissolve migrate to update your code.",
DeprecationWarning,
stacklevel=2
)
return value
# === NEW API CONFIGURATION ===
API_BASE_URL = "https://api.example.com/v3"
API_VERSION = "v3"
DEFAULT_TIMEOUT = 60
MAX_RETRIES = 3
CACHE_EXPIRY_SECONDS = 3600
# Database configuration
DATABASE_HOST = "db.example.com"
DATABASE_PORT = 5432
DATABASE_NAME = "app_production"
# Feature flags
ENABLE_FEATURE_X = True
ENABLE_CACHING = True
DEBUG_MODE = False
# === DEPRECATED CONFIGURATION ===
# Module-level attribute deprecation examples
OLD_API_URL = replace_me("https://api.example.com/v3") # Migrates to literal value
OLD_TIMEOUT = replace_me(60) # Migrates to literal value
LEGACY_RETRIES = replace_me(3) # Migrates to literal value
# String configuration
DEPRECATED_VERSION = replace_me("v3")
OLD_HOST = replace_me("db.example.com")
# Boolean flags
OLD_DEBUG_FLAG = replace_me(False)
LEGACY_CACHE_ENABLED = replace_me(True)
# Complex values
OLD_DATABASE_CONFIG = replace_me({
"host": "db.example.com",
"port": 5432,
"name": "app_production"
})
# List configuration
LEGACY_ALLOWED_ORIGINS = replace_me([
"https://example.com",
"https://www.example.com",
"https://app.example.com"
])
class AppConfig:
"""
Application configuration class.
"""
# New configuration attributes
API_ENDPOINT = "https://api.example.com/v3"
DEFAULT_PAGE_SIZE = 25
ENABLE_LOGGING = True
LOG_LEVEL = "INFO"
# === DEPRECATED CLASS ATTRIBUTES ===
# Class attribute deprecation examples
OLD_ENDPOINT = replace_me("https://api.example.com/v3")
LEGACY_PAGE_SIZE = replace_me(25)
OLD_LOG_SETTING = replace_me(True)
DEPRECATED_LOG_LEVEL = replace_me("INFO")
# Complex class attributes
OLD_LIMITS = replace_me({
"requests_per_minute": 1000,
"max_file_size": 10485760, # 10MB
"timeout_seconds": 30
})
LEGACY_ENDPOINTS = replace_me([
"/api/v1/users",
"/api/v1/data",
"/api/v1/reports"
])
@classmethod
def get_database_url(cls):
"""Get the database connection URL."""
return f"postgresql://{DATABASE_HOST}:{DATABASE_PORT}/{DATABASE_NAME}"
@classmethod
def get_api_config(cls):
"""Get API configuration dictionary."""
return {
"base_url": cls.API_ENDPOINT,
"timeout": DEFAULT_TIMEOUT,
"max_retries": MAX_RETRIES
}
class FeatureFlags:
"""
Feature flag configuration.
"""
# Current feature flags
NEW_UI_ENABLED = True
BETA_FEATURES = False
PERFORMANCE_MONITORING = True
# === DEPRECATED FEATURE FLAGS ===
OLD_UI_FLAG = replace_me(True) # Will be migrated to literal True
LEGACY_BETA = replace_me(False) # Will be migrated to literal False
OLD_MONITORING = replace_me(True) # Will be migrated to literal True
# Nested configuration
DEPRECATED_SETTINGS = replace_me({
"ui": {"theme": "dark", "animations": True},
"api": {"rate_limit": 1000, "cache_ttl": 300},
"features": {"beta": False, "experimental": False}
})
# === ENVIRONMENT-SPECIFIC CONFIGURATION ===
class DevConfig:
"""Development environment configuration."""
DEBUG = True
API_URL = "https://dev-api.example.com"
# Deprecated dev settings
OLD_DEBUG_MODE = replace_me(True)
LEGACY_DEV_API = replace_me("https://dev-api.example.com")
class ProdConfig:
"""Production environment configuration."""
DEBUG = False
API_URL = "https://api.example.com"
# Deprecated prod settings
OLD_PROD_MODE = replace_me(False)
LEGACY_PROD_API = replace_me("https://api.example.com")
# function cleanup: <TEMP>/library/containers.py
"""
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
# function cleanup: <TEMP>/library/models.py
"""
Class and 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 DataProcessor:
"""
Modern data processing class (new API).
"""
def __init__(self, data_source, batch_size=100, enable_caching=True):
self.data_source = data_source
self.batch_size = batch_size
self.enable_caching = enable_caching
self._cache = {} if enable_caching else None
def process(self, data):
"""Process data with modern algorithms."""
if self._cache is not None and data in self._cache:
return self._cache[data]
# Simulate processing
result = f"Processed: {data} (batch_size={self.batch_size})"
if self._cache is not None:
self._cache[data] = result
return result
def batch_process(self, data_list):
"""Process multiple data items efficiently."""
return [self.process(item) for item in data_list]
def get_stats(self):
"""Get processing statistics."""
cache_size = len(self._cache) if self._cache else 0
return {
"data_source": self.data_source,
"batch_size": self.batch_size,
"caching_enabled": self.enable_caching,
"cache_size": cache_size
}
class User:
"""
User model with modern API design.
"""
def __init__(self, username, email, full_name=None, is_active=True):
self.username = username
self.email = email
self.full_name = full_name or username
self.is_active = is_active
self._profile = {}
def get_display_name(self):
"""Get the user's display name."""
return self.full_name or self.username
def update_profile(self, **kwargs):
"""Update user profile information."""
self._profile.update(kwargs)
return self._profile
def get_profile(self):
"""Get user profile information."""
return self._profile.copy()
@property
def status(self):
"""Get user status."""
return "active" if self.is_active else "inactive"
# === DEPRECATED CLASSES AND METHODS ===
@replace_me(since="2.0.0", remove_in="3.0.0")
class OldDataProcessor:
"""
Legacy data processing class.
.. deprecated:: 2.0.0
Use :class:`DataProcessor` instead.
"""
def __init__(self, data_source, cache_size=50):
"""Initialize with legacy parameter names."""
# Convert old parameters to new format
self._processor = DataProcessor(
data_source=data_source,
batch_size=cache_size * 2, # Old cache_size maps to batch_size * 2
enable_caching=True
)
def process(self, data):
"""Process data using the legacy interface."""
return self._processor.process(data)
def get_info(self):
"""Get processor info (legacy method)."""
return self._processor.get_stats()
class LegacyUser:
"""
User model with legacy method names.
"""
def __init__(self, name, email_address, active=True):
self._user = User(username=name, email=email_address, is_active=active)
@replace_me(since="1.5.0", remove_in="2.5.0")
def get_name(self):
"""
Get user name (legacy method).
.. deprecated:: 1.5.0
Use :meth:`get_display_name` instead.
"""
return self._user.get_display_name()
@replace_me(since="1.8.0")
def set_profile_data(self, data):
"""
Set profile data (legacy method).
.. deprecated:: 1.8.0
Use :meth:`update_profile` instead.
"""
return self._user.update_profile(**data)
def get_display_name(self):
"""Get the user's display name (new method)."""
return self._user.get_display_name()
def update_profile(self, **kwargs):
"""Update profile (new method)."""
return self._user.update_profile(**kwargs)
# Property deprecation example
@property
@replace_me(since="1.0.0")
def is_enabled(self):
"""
Check if user is enabled (legacy property).
.. deprecated:: 2.0.0
Use :attr:`status` instead.
"""
return self._user.status == "active"
@property
def status(self):
"""Get user status (new property)."""
return self._user.status
# Wrapper class demonstrating complex deprecation
@replace_me(since="1.0.0")
class SimpleProcessor:
"""
Simplified processor without caching (deprecated).
.. deprecated:: 2.2.0
Use :class:`DataProcessor` instead.
"""
def __init__(self, source):
self._processor = DataProcessor(source, batch_size=1, enable_caching=False)
def process_item(self, item):
"""Process a single item."""
return self._processor.process(item)
# function cleanup: <TEMP>/library/processors.py
"""
Class methods and static methods 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 ProcessingEngine:
"""
Modern processing engine with class and static methods.
"""
def __init__(self, engine_type="standard"):
self.engine_type = engine_type
self.processed_count = 0
@classmethod
def create_fast_engine(cls):
"""Create a high-performance processing engine."""
return cls("fast")
@classmethod
def create_memory_efficient_engine(cls):
"""Create a memory-efficient processing engine."""
return cls("memory_efficient")
@staticmethod
def validate_input(data):
"""Validate input data format."""
if not isinstance(data, (list, tuple, str)):
raise ValueError("Input must be a list, tuple, or string")
return True
@staticmethod
def normalize_text(text, lowercase=True, strip_whitespace=True):
"""Normalize text with configurable options."""
result = text
if strip_whitespace:
result = result.strip()
if lowercase:
result = result.lower()
return result
def process(self, data):
"""Process data using the configured engine."""
self.validate_input(data)
self.processed_count += 1
return f"Processed by {self.engine_type} engine: {data}"
# === DEPRECATED CLASS METHODS ===
@classmethod
@replace_me(since="2.0.0", remove_in="3.0.0")
def old_create_engine(cls, fast=False):
"""
Create a processing engine (legacy method).
.. deprecated:: 2.0.0
Use :meth:`create_fast_engine` or :meth:`create_memory_efficient_engine` instead.
"""
if fast:
return cls.create_fast_engine()
else:
return cls.create_memory_efficient_engine()
@classmethod
@replace_me(since="1.0.0")
def legacy_fast_processor(cls):
"""
Create a fast processor (legacy method).
.. deprecated:: 1.8.0
Use :meth:`create_fast_engine` instead.
"""
return cls.create_fast_engine()
# === DEPRECATED STATIC METHODS ===
@staticmethod
@replace_me(since="1.5.0", remove_in="2.5.0")
def old_validate_data(input_data):
"""
Validate data (legacy static method).
.. deprecated:: 1.5.0
Use :meth:`validate_input` instead.
"""
return ProcessingEngine.validate_input(input_data)
@staticmethod
@replace_me(since="2.1.0")
def legacy_clean_text(text_data):
"""
Clean text data (legacy method with hardcoded options).
.. deprecated:: 2.1.0
Use :meth:`normalize_text` instead.
"""
return ProcessingEngine.normalize_text(text_data, lowercase=True, strip_whitespace=True)
# Complex transformation example
@staticmethod
@replace_me(since="1.0.0")
def old_process_batch(items, uppercase=False, trim=True):
"""
Process a batch of items (legacy method with old parameter order).
.. deprecated:: 1.9.0
Use :meth:`process_text_batch` instead.
"""
return ProcessingEngine.process_text_batch(
text_items=items,
strip_whitespace=trim,
lowercase=not uppercase
)
@staticmethod
def process_text_batch(text_items, strip_whitespace=True, lowercase=True):
"""Process a batch of text items with new parameter names."""
results = []
for item in text_items:
processed = ProcessingEngine.normalize_text(
str(item),
lowercase=lowercase,
strip_whitespace=strip_whitespace
)
results.append(processed)
return results
class DataValidator:
"""
Data validation utilities.
"""
@staticmethod
def is_valid_email(email):
"""Check if email format is valid."""
return "@" in email and "." in email.split("@")[-1]
@staticmethod
def is_valid_phone(phone, country_code=None):
"""Check if phone number format is valid."""
cleaned = "".join(c for c in phone if c.isdigit())
if country_code:
return len(cleaned) >= 10 and cleaned.startswith(country_code.lstrip("+"))
return len(cleaned) >= 10
@classmethod
def create_validator(cls, strict=False):
"""Create a validator instance with configuration."""
validator = cls()
validator.strict_mode = strict
return validator
# === DEPRECATED VALIDATION METHODS ===
@staticmethod
@replace_me(since="1.3.0", remove_in="2.0.0")
def check_email(email_addr):
"""
Check email validity (legacy method).
.. deprecated:: 1.3.0
Use :meth:`is_valid_email` instead.
"""
return DataValidator.is_valid_email(email_addr)
@staticmethod
@replace_me(since="1.6.0")
def validate_phone_number(number):
"""
Validate phone number (legacy method without country code support).
.. deprecated:: 1.6.0
Use :meth:`is_valid_phone` instead.
"""
return DataValidator.is_valid_phone(number, country_code=None)
@classmethod
@replace_me(since="1.0.0")
def create_strict_validator(cls):
"""
Create a strict validator (legacy method).
.. deprecated:: 2.0.0
Use :meth:`create_validator` with strict=True instead.
"""
return cls.create_validator(strict=True)
# function cleanup: <TEMP>/library/utils.py
"""
Basic utility functions demonstrating function deprecation patterns.
"""
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
def add(a, b):
"""Add two numbers together (new API)."""
return a + b
def multiply(a, b, factor=1):
"""Multiply two numbers with an optional factor (new API)."""
return a * b * factor
def divide(dividend, divisor):
"""Divide two numbers (new API)."""
if divisor == 0:
raise ValueError("Cannot divide by zero")
return dividend / divisor
def power(base, exponent=2):
"""Raise base to the power of exponent (new API)."""
return base ** exponent
# === DEPRECATED FUNCTIONS ===
@replace_me(since="1.0.0", remove_in="3.0.0")
def old_add(a, b):
"""
Add two numbers together.
.. deprecated:: 1.0.0
Use :func:`add` instead.
"""
return add(a, b)
@replace_me(since="1.5.0", remove_in="3.0.0")
def old_multiply(x, y):
"""
Multiply two numbers (legacy version).
.. deprecated:: 1.5.0
Use :func:`multiply` instead for better performance.
"""
return multiply(x, y)
@replace_me(since="2.0.0")
def legacy_divide(numerator, denominator):
"""
Legacy division function with old parameter names.
.. deprecated:: 2.0.0
Use :func:`divide` instead.
"""
return divide(numerator, denominator)
@replace_me(since="1.8.0", remove_in="2.5.0")
def square(num):
"""
Square a number (legacy version).
.. deprecated:: 1.8.0
Use :func:`power` instead.
"""
return power(num, 2)
@replace_me(since="2.1.0")
def cube(num):
"""
Cube a number (legacy version).
.. deprecated:: 2.1.0
Use :func:`power` instead.
"""
return power(num, 3)
# Complex transformation example
@replace_me(since="1.2.0")
def old_format_string(template, *args, uppercase=False):
"""
Format a string with positional arguments.
.. deprecated:: 1.2.0
Use :func:`format_string` instead with reordered parameters.
"""
return format_string(uppercase, template, *args)
def format_string(uppercase, template, *args):
"""Format a string with optional uppercase conversion (new API)."""
result = template.format(*args)
return result.upper() if uppercase else result