CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-voluptuous

Python data validation library for validating nested data structures with comprehensive error reporting

Pending
Overview
Eval results
Files

type-validators.mddocs/

Type Coercion & Conversion

Type conversion and coercion with error handling, truth value validation, and human-readable boolean conversion. These validators handle type transformations and validate type-specific conditions.

Capabilities

Type Coercion

Convert values to specified types with graceful error handling.

class Coerce:
    def __init__(self, type, msg=None):
        """
        Convert value to specified type.
        
        Parameters:
        - type: Target type to convert to (int, float, str, etc.)
        - msg: Custom error message if coercion fails
        
        Returns:
        Value converted to target type
        
        Raises:
        CoerceInvalid: If conversion fails (ValueError/TypeError from type constructor)
        """

Usage Examples:

from voluptuous import Schema, Coerce, All, Range

# Convert strings to numbers
numeric_schema = Schema({
    'age': Coerce(int),           # "25" -> 25
    'price': Coerce(float),       # "19.99" -> 19.99
    'active': Coerce(bool),       # "true" -> True, "false" -> False
})

# Combined with validation
validated_age = Schema(All(
    Coerce(int),                  # Convert to int first
    Range(min=0, max=150),        # Then validate range
))

# Custom types
from decimal import Decimal
decimal_price = Schema(All(
    Coerce(Decimal),              # Convert to Decimal
    lambda x: x >= 0,             # Validate non-negative
))

Boolean Conversion

Convert human-readable values to boolean with comprehensive string recognition.

def Boolean(v):
    """
    Convert human-readable values to boolean.
    
    Parameters:
    - v: Value to convert to boolean
    
    Accepted truthy values: 
    '1', 'true', 'yes', 'on', 'enable', 1, True (case-insensitive for strings)
    
    Accepted falsy values:
    '0', 'false', 'no', 'off', 'disable', 0, False (case-insensitive for strings)
    
    Returns:
    True or False
    
    Raises:
    BooleanInvalid: If value cannot be converted to boolean
    """

Usage Examples:

from voluptuous import Schema, Boolean

# Flexible boolean conversion
settings_schema = Schema({
    'debug': Boolean,             # Accepts 'true', 'yes', '1', True, etc.
    'logging': Boolean,           # Accepts 'false', 'no', '0', False, etc.
    'ssl_enabled': Boolean,
})

# Valid inputs:
settings_schema({
    'debug': 'true',              # -> True
    'logging': 'no',              # -> False  
    'ssl_enabled': 1,             # -> True
})

settings_schema({
    'debug': 'YES',               # -> True (case-insensitive)
    'logging': 'disable',         # -> False
    'ssl_enabled': '0',           # -> False
})

Truth Value Validation

Validate whether values are truthy or falsy in Python's sense.

def IsTrue(v):
    """
    Assert value is truthy in Python sense.
    
    Parameters:
    - v: Value to test for truthiness
    
    Returns:
    Original value if truthy
    
    Raises:
    TrueInvalid: If value is falsy (False, None, 0, '', [], {}, etc.)
    """

def IsFalse(v):
    """
    Assert value is falsy in Python sense.
    
    Parameters:
    - v: Value to test for falsiness
    
    Returns:
    Original value if falsy
    
    Raises:
    FalseInvalid: If value is truthy
    """

Usage Examples:

from voluptuous import Schema, IsTrue, IsFalse, Any

# Validate required fields are not empty
data_schema = Schema({
    'name': IsTrue,               # Must be non-empty string
    'items': IsTrue,              # Must be non-empty list
    'settings': IsTrue,           # Must be non-empty dict
})

# Valid data
data_schema({
    'name': 'John',               # Truthy string
    'items': [1, 2, 3],          # Non-empty list
    'settings': {'debug': True},  # Non-empty dict
})

# Invalid data would fail:
# data_schema({'name': '', 'items': [], 'settings': {}})  # All falsy

# Validate disabled features
feature_schema = Schema({
    'legacy_mode': IsFalse,       # Must be disabled/falsy
    'deprecated_api': IsFalse,    # Must be disabled/falsy
})

# Accept various ways of expressing "disabled"
feature_schema({
    'legacy_mode': False,         # Explicitly False
    'deprecated_api': None,       # None is falsy
})

Truth Function Decorator

Convert arbitrary boolean functions into validators.

def truth(f):
    """
    Decorator to convert truth functions into validators.
    
    Parameters:
    - f: Function that returns True/False for validation
    
    Returns:
    Validator function that raises ValueError if f returns False
    
    Usage:
    Decorate any function that returns boolean to create a validator
    """

Usage Examples:

from voluptuous import Schema, truth
import os.path

# Convert existing boolean functions to validators
@truth
def is_file(path):
    return os.path.isfile(path)

@truth  
def is_even(n):
    return n % 2 == 0

@truth
def is_valid_email_domain(email):
    return email.split('@')[1] in ['company.com', 'partner.org']

# Use in schemas
file_schema = Schema(is_file)        # Validates file exists
number_schema = Schema(is_even)      # Validates even numbers
email_schema = Schema(is_valid_email_domain)  # Validates email domain

# Combined validation
config_schema = Schema({
    'log_file': is_file,            # Must be existing file
    'port': is_even,                # Must be even number  
    'admin_email': is_valid_email_domain,  # Must be company email
})

Type Checking Patterns

Common patterns for type validation and conversion.

Flexible Type Acceptance:

from voluptuous import Schema, Any, Coerce, All

# Accept multiple representations of the same data
flexible_id = Any(
    int,                          # Already an integer
    All(str, Coerce(int)),       # String representation of integer
    All(str, Match(r'^\d+$'), Coerce(int)),  # Ensure string is numeric first
)

# Flexible timestamp handling
timestamp_validator = Any(
    int,                          # Unix timestamp
    float,                        # Fractional timestamp
    All(str, Coerce(float)),     # String timestamp
    datetime.datetime,            # Datetime object
)

Safe Type Coercion:

from voluptuous import Schema, Coerce, All, message

@message("Invalid number format")
def safe_int(value):
    """Safely convert to int with better error messages."""
    if isinstance(value, int):
        return value
    if isinstance(value, str) and value.strip():
        try:
            return int(value.strip())
        except ValueError:
            # Try float first, then int
            try:
                float_val = float(value.strip())
                if float_val.is_integer():
                    return int(float_val)
            except ValueError:
                pass
    raise ValueError("Cannot convert to integer")

# Safer than plain Coerce(int)
safe_number_schema = Schema(safe_int)

Conditional Type Conversion:

from voluptuous import Schema, Any, All, Coerce

def smart_coerce(target_type):
    """Intelligently coerce values based on their current type."""
    def coercer(value):
        if isinstance(value, target_type):
            return value
        
        if target_type == bool:
            return Boolean(value)
        elif target_type in (int, float):
            if isinstance(value, str) and not value.strip():
                raise ValueError("Empty string cannot be converted to number")
            return target_type(value)
        else:
            return target_type(value)
    
    return coercer

# Smart coercion with fallbacks
smart_schema = Schema({
    'count': smart_coerce(int),
    'rate': smart_coerce(float), 
    'enabled': smart_coerce(bool),
})

Type Validation with Constraints:

from voluptuous import Schema, All, Coerce, Range, Length

# Ensure type and constraints in one step
constrained_string = All(
    str,                          # Must be string
    Length(min=1, max=100),      # Must have reasonable length
    lambda s: s.strip() == s,     # Must not have leading/trailing whitespace
)

constrained_number = All(
    Any(int, float, Coerce(float)),  # Accept various numeric types
    Range(min=0),                    # Must be non-negative
    lambda x: x == x,                # Must not be NaN (NaN != NaN)
)

# Use in schema
validated_schema = Schema({
    'name': constrained_string,
    'amount': constrained_number,
})

Install with Tessl CLI

npx tessl i tessl/pypi-voluptuous

docs

core-schema.md

error-handling.md

index.md

range-collection-validators.md

string-pattern-validators.md

type-validators.md

utility-transformers.md

validation-composers.md

tile.json