CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-varname

Dark magics about variable names in python

Overall
score

90%

Overview
Eval results
Files

config-exceptions.mddocs/

Configuration and Exceptions

Configuration options and comprehensive exception hierarchy for error handling in varname operations. Understanding these components is essential for robust error handling and debugging.

Configuration

Global Configuration

Central configuration object for controlling varname behavior across the application.

class config:
    """Global configurations for varname."""
    
    debug: bool = False
    """Show debug information for frames being ignored.
    
    When True, varname will print detailed information about which frames
    are being skipped during the ignore process. Useful for debugging
    complex ignore scenarios or when varname is not finding the expected frame.
    
    Example output when debug=True:
        VARNAME DEBUG: Ignored frame: <frame at 0x...> (file: decorator.py, func: wrapper)
        VARNAME DEBUG: Target frame found: <frame at 0x...> (file: main.py, func: <module>)
    """

Usage Examples

from varname import config, varname

# Enable debug mode
config.debug = True

def logged(func):
    def wrapper(*args, **kwargs):
        # With debug=True, will show ignored frames
        name = varname(ignore=logged)
        print(f"Calling {name}")
        return func(*args, **kwargs)
    return wrapper

@logged
def process_data():
    return "processed"

# This will show debug output about ignored frames
result = process_data()

# Disable debug mode
config.debug = False

Exception Hierarchy

Varname provides a comprehensive exception hierarchy for different types of errors that can occur during variable name retrieval and introspection.

Base Exception

class VarnameException(Exception):
    """Root exception for all varname-related errors.
    
    All other varname exceptions inherit from this base class, allowing
    for unified exception handling when needed.
    """

Core Exceptions

Variable Name Retrieval Errors

class VarnameRetrievingError(VarnameException):
    """Raised when failed to retrieve the variable name.
    
    This is the most common exception raised by varname functions when
    they cannot determine the variable name due to:
    - AST node retrieval failures
    - Unsupported calling contexts  
    - Frame analysis problems
    - Source code unavailability
    
    Common scenarios:
    - Using varname in REPL without source code
    - Complex call chains that confuse frame analysis
    - Missing or corrupted AST information
    - Calling from unsupported contexts (e.g., some decorators)
    """

Improper Usage Errors

class ImproperUseError(VarnameException):
    """Raised when varname functions are used improperly.
    
    This exception indicates incorrect usage patterns that violate
    varname's assumptions or requirements:
    
    For varname():
    - Multiple target assignment when multi_vars=False
    - Non-direct assignment when strict=True (e.g., a = [func()])
    - Using in contexts where variable assignment detection is impossible
    
    For will():
    - Not followed by attribute access
    - Used in contexts where next attribute cannot be determined
    
    For argname():
    - Called from functions that cannot be analyzed
    - Requesting non-existent arguments
    - Invalid argument specifications
    """

Qualified Name Errors

class QualnameNonUniqueError(VarnameException):
    """Raised when a qualified name refers to multiple objects.
    
    This occurs in the ignore system when a qualified name (module.function)
    is used as an ignore element but matches multiple different objects,
    making it ambiguous which one should be ignored.
    
    Example:
    - import math; from math import sin
    - Using "math.sin" as ignore element is ambiguous
    """

Exception Usage Examples

from varname import (
    varname, will, argname, nameof,
    VarnameException, 
    VarnameRetrievingError,
    ImproperUseError,
    QualnameNonUniqueError
)

# Catching specific varname errors
def safe_varname():
    try:
        return varname()
    except VarnameRetrievingError as e:
        print(f"Could not retrieve variable name: {e}")
        return "unknown"
    except ImproperUseError as e:
        print(f"Improper varname usage: {e}")
        return "improper"

# Usage in unsupported context
try:
    # This will raise VarnameRetrievingError in REPL
    name = safe_varname() 
except Exception as e:
    print(f"Error: {e}")

# Catching all varname exceptions
def robust_operation():
    try:
        a, b = varname(multi_vars=False)  # Will raise ImproperUseError
        return a, b
    except VarnameException as e:
        print(f"Varname operation failed: {type(e).__name__}: {e}")
        return None, None

# Example with improper will() usage  
class BadWillUsage:
    def method(self):
        try:
            attr = will()
            # Not followed by attribute access - will cause issues
            return attr
        except ImproperUseError as e:
            print(f"Will() used improperly: {e}")
            return None

obj = BadWillUsage()
result = obj.method()  # Direct call, no attribute access

# Example with argname errors
def analyze_function():
    try:
        # Requesting non-existent argument
        name = argname('nonexistent_arg')
        return name
    except VarnameRetrievingError as e:
        print(f"Argument analysis failed: {e}")
        return None

def caller():
    return analyze_function()

result = caller()

Warning System

Varname includes warnings for situations that are not errors but may indicate potential issues or unexpected behavior.

Warning Hierarchy

class VarnameWarning(Warning):
    """Root warning for all varname-related warnings."""

class MultiTargetAssignmentWarning(VarnameWarning):
    """Warning for multiple target assignments like a = b = func().
    
    Issued when varname() detects multiple assignment targets, which can
    lead to ambiguous variable name detection. The warning helps identify
    potential issues in complex assignment patterns.
    
    Example triggering code:
        def create(): return varname()
        a = b = create()  # Triggers warning
    """

class MaybeDecoratedFunctionWarning(VarnameWarning):  
    """Warning when suspicious decorated function used as ignore directly.
    
    Issued when a function that appears to be decorated is used directly
    in the ignore parameter instead of using proper ignore handling for
    decorated functions.
    
    Example:
        @decorator
        def func(): pass
        
        varname(ignore=func)  # May trigger warning
        # Should use: varname(ignore=(func, 1)) for decorated functions
    """

class UsingExecWarning(VarnameWarning):
    """Warning when exec is used to retrieve function name for argname().
    
    Issued when argname() needs to use exec with temporary files to analyze
    function calls in environments where source code is not directly available.
    This indicates a fallback mechanism is being used.
    """

Warning Configuration

import warnings
from varname import VarnameWarning

# Control varname warnings
warnings.filterwarnings('ignore', category=VarnameWarning)  # Suppress all
warnings.filterwarnings('error', category=VarnameWarning)   # Make them errors
warnings.filterwarnings('always', category=VarnameWarning)  # Always show

# Filter specific warning types
from varname import MultiTargetAssignmentWarning

warnings.filterwarnings('ignore', category=MultiTargetAssignmentWarning)

Error Handling Best Practices

Graceful Degradation

from varname import varname, VarnameRetrievingError

def create_with_fallback(default_name="object"):
    """Create object with varname, falling back to default name."""
    try:
        name = varname()
    except VarnameRetrievingError:
        name = default_name
    
    return {
        'name': name,
        'created_at': '2023-01-01',
        'data': []
    }

# Works in normal contexts
user_data = create_with_fallback()  # name='user_data'

# Works in problematic contexts  
items = [create_with_fallback() for _ in range(3)]  # name='object' (fallback)

Context-Aware Error Handling

from varname import argname, nameof, ImproperUseError, VarnameRetrievingError

def smart_debug_function(*args, **kwargs):
    """Debug function that adapts to available context."""
    try:
        # Try to get argument names
        if args:
            arg_names = nameof(*args)
            print(f"Arguments: {arg_names}")
    except VarnameRetrievingError:
        # Fall back to positions
        print(f"Arguments: {len(args)} positional args")
    except ImproperUseError:
        # Handle complex expressions
        print(f"Arguments: complex expressions ({len(args)} args)")
    
    try:
        # Try to get keyword argument names
        if kwargs:
            kwarg_info = argname('kwargs')
            print(f"Keyword args: {kwarg_info}")
    except (VarnameRetrievingError, ImproperUseError):
        print(f"Keyword args: {list(kwargs.keys())}")

# Usage examples
x, y = 1, 2
smart_debug_function(x, y, debug=True)  # Will try name detection

smart_debug_function(x + 1, y * 2, mode="test")  # Will handle expressions gracefully

Production-Ready Error Handling

import logging
from varname import VarnameException, config

# Set up logging for varname issues
logger = logging.getLogger('varname_ops')

def production_varname_operation():
    """Example of production-ready varname usage."""
    try:
        # Enable debug only in development
        if __debug__:
            config.debug = True
            
        name = varname()
        logger.debug(f"Retrieved variable name: {name}")
        return name
        
    except VarnameException as e:
        # Log the specific error type and context
        logger.warning(
            f"Varname operation failed: {type(e).__name__}: {e}",
            exc_info=True
        )
        # Return sensible default
        return "unnamed_variable"
        
    finally:
        # Clean up debug mode
        config.debug = False

# Usage
try:
    result_data = production_varname_operation()
    logger.info(f"Created {result_data}")
except Exception as e:
    logger.error(f"Unexpected error: {e}", exc_info=True)

Install with Tessl CLI

npx tessl i tessl/pypi-varname

docs

advanced-functions.md

config-exceptions.md

core-functions.md

helper-functions.md

index.md

tile.json