CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-eth-utils

Common utility functions for python code that interacts with Ethereum

Pending
Overview
Eval results
Files

type-checking.mddocs/

Type Checking

Comprehensive type validation utilities for common Python and Ethereum-specific data types. Provides reliable type checking for data validation pipelines.

Capabilities

Basic Type Checking

Check for fundamental Python data types.

def is_integer(value) -> bool:
    """
    Check if value is integer type (excluding boolean).
    
    Args:
        value: Value to check
        
    Returns:
        bool: True if value is int but not bool
    """

def is_boolean(value) -> bool:
    """
    Check if value is boolean type.
    
    Args:
        value: Value to check
        
    Returns:
        bool: True if value is bool
    """

def is_string(value) -> bool:
    """
    Check if value is string-like (str, bytes, or bytearray).
    
    Args:
        value: Value to check
        
    Returns:
        bool: True if value is any string type
    """

def is_text(value) -> bool:
    """
    Check if value is text string (str only).
    
    Args:
        value: Value to check
        
    Returns:
        bool: True if value is str type
    """

def is_bytes(value) -> bool:
    """
    Check if value is bytes-like object (bytes or bytearray).
    
    Args:
        value: Value to check
        
    Returns:
        bool: True if value is bytes or bytearray
    """

Numeric Type Checking

Specialized numeric type validation.

def is_number(obj) -> bool:
    """
    Check if object is numeric type (int, float, Decimal, but not bool).
    
    Args:
        obj: Object to check
        
    Returns:
        bool: True if object is numeric
    """

def is_null(obj) -> bool:
    """
    Check if object is None.
    
    Args:
        obj: Object to check
        
    Returns:
        bool: True if object is None
    """

Collection Type Checking

Check for collection and sequence types.

def is_dict(obj) -> bool:
    """
    Check if object is mapping type (dict or dict-like).
    
    Args:
        obj: Object to check
        
    Returns:
        bool: True if object implements mapping protocol
    """

def is_list(obj) -> bool:
    """
    Check if object is list type.
    
    Args:
        obj: Object to check
        
    Returns:
        bool: True if object is list
    """

def is_tuple(obj) -> bool:
    """
    Check if object is tuple type.
    
    Args:
        obj: Object to check
        
    Returns:
        bool: True if object is tuple
    """

def is_list_like(obj) -> bool:
    """
    Check if object is sequence-like (list, tuple, etc. but not string).
    
    Args:
        obj: Object to check
        
    Returns:
        bool: True if object is sequence but not string type
    """

Usage Examples

Input Validation

from eth_utils import is_integer, is_string, is_bytes, is_boolean

def validate_transaction_input(value, input_type):
    """Validate transaction input based on expected type."""
    if input_type == "uint256":
        if not is_integer(value):
            raise TypeError(f"Expected integer for uint256, got {type(value)}")
        if value < 0 or value >= 2**256:
            raise ValueError("uint256 value out of range")
    
    elif input_type == "address":
        if not is_string(value):
            raise TypeError(f"Expected string for address, got {type(value)}")
        # Additional address validation would go here
    
    elif input_type == "bytes":
        if not is_bytes(value) and not is_string(value):
            raise TypeError(f"Expected bytes or hex string, got {type(value)}")
    
    elif input_type == "bool":
        if not is_boolean(value):
            raise TypeError(f"Expected boolean, got {type(value)}")
    
    return True

# Usage examples
validate_transaction_input(12345, "uint256")           # Valid
validate_transaction_input("0x123...", "address")     # Valid
validate_transaction_input(True, "bool")               # Valid
# validate_transaction_input("123", "uint256")        # Raises TypeError

Data Processing Pipeline

from eth_utils import is_list_like, is_dict, is_string, is_integer

def process_mixed_data(data):
    """Process data based on its type."""
    if is_dict(data):
        return {k: process_mixed_data(v) for k, v in data.items()}
    
    elif is_list_like(data):
        return [process_mixed_data(item) for item in data]
    
    elif is_string(data):
        return data.strip().lower()
    
    elif is_integer(data):
        return abs(data)  # Ensure positive
    
    else:
        return str(data)  # Convert to string as fallback

# Examples
result1 = process_mixed_data({"key": "  VALUE  "})  # {"key": "value"}
result2 = process_mixed_data([1, -2, "  Text  "])  # [1, 2, "text"]
result3 = process_mixed_data(-42)                   # 42

Type-Safe Function Parameters

from eth_utils import is_integer, is_string, is_bytes, is_list_like

def encode_function_call(function_name, parameters):
    """Encode function call with type validation."""
    if not is_string(function_name):
        raise TypeError("Function name must be string")
    
    if not is_list_like(parameters):
        raise TypeError("Parameters must be list-like")
    
    encoded_params = []
    for i, param in enumerate(parameters):
        if is_integer(param):
            # Encode integer parameter
            encoded_params.append(f"uint256:{param}")
        elif is_string(param):
            # Encode string parameter
            encoded_params.append(f"string:{param}")
        elif is_bytes(param):
            # Encode bytes parameter
            encoded_params.append(f"bytes:{param.hex()}")
        else:
            raise TypeError(f"Unsupported parameter type at index {i}: {type(param)}")
    
    return f"{function_name}({','.join(encoded_params)})"

# Usage
call = encode_function_call("transfer", ["0x123...", 1000])
print(call)  # transfer(string:0x123...,uint256:1000)

Contract ABI Validation

from eth_utils import is_dict, is_list_like, is_string

def validate_abi_element(abi_element):
    """Validate ABI element structure."""
    if not is_dict(abi_element):
        raise TypeError("ABI element must be dictionary")
    
    required_fields = ["type", "name"]
    for field in required_fields:
        if field not in abi_element:
            raise ValueError(f"Missing required field: {field}")
        if not is_string(abi_element[field]):
            raise TypeError(f"Field {field} must be string")
    
    # Validate inputs if present
    if "inputs" in abi_element:
        inputs = abi_element["inputs"]
        if not is_list_like(inputs):
            raise TypeError("ABI inputs must be list")
        
        for i, input_param in enumerate(inputs):
            if not is_dict(input_param):
                raise TypeError(f"Input parameter {i} must be dictionary")
            if "type" not in input_param:
                raise ValueError(f"Input parameter {i} missing type")
    
    return True

# Example ABI validation
abi_element = {
    "type": "function",
    "name": "transfer",
    "inputs": [
        {"name": "to", "type": "address"},
        {"name": "amount", "type": "uint256"}
    ]
}

validate_abi_element(abi_element)  # Returns True

Safe Type Conversion

from eth_utils import is_integer, is_string, is_bytes, is_number

def safe_to_int(value):
    """Safely convert value to integer."""
    if is_integer(value):
        return value
    elif is_string(value):
        try:
            return int(value, 0)  # Auto-detect base (0x for hex)
        except ValueError:
            raise ValueError(f"Cannot convert string to int: {value}")
    elif is_number(value):
        return int(value)
    else:
        raise TypeError(f"Cannot convert {type(value)} to int")

def safe_to_string(value):
    """Safely convert value to string."""
    if is_string(value):
        return value if is_text(value) else value.decode('utf-8')
    elif is_bytes(value):
        return value.decode('utf-8')
    else:
        return str(value)

# Examples
print(safe_to_int("123"))      # 123
print(safe_to_int("0x123"))    # 291
print(safe_to_int(123.7))      # 123
print(safe_to_string(b"test")) # "test"

Configuration Validation

from eth_utils import is_dict, is_string, is_integer, is_boolean

def validate_config(config):
    """Validate application configuration."""
    if not is_dict(config):
        raise TypeError("Configuration must be dictionary")
    
    # Required string fields
    string_fields = ["network_url", "contract_address"]
    for field in string_fields:
        if field not in config:
            raise ValueError(f"Missing required field: {field}")
        if not is_string(config[field]):
            raise TypeError(f"Field {field} must be string")
    
    # Required integer fields
    if "block_confirmation_count" in config:
        if not is_integer(config["block_confirmation_count"]):
            raise TypeError("block_confirmation_count must be integer")
        if config["block_confirmation_count"] < 1:
            raise ValueError("block_confirmation_count must be positive")
    
    # Optional boolean fields
    if "debug_mode" in config:
        if not is_boolean(config["debug_mode"]):
            raise TypeError("debug_mode must be boolean")
    
    return True

# Example configuration
config = {
    "network_url": "https://mainnet.infura.io/v3/...",
    "contract_address": "0x123...",
    "block_confirmation_count": 12,
    "debug_mode": False
}

validate_config(config)  # Returns True

Type Constants

The module provides type tuples for isinstance checks:

bytes_types = (bytes, bytearray)
integer_types = (int,)
text_types = (str,)
string_types = (bytes, str, bytearray)
from eth_utils import bytes_types, string_types, integer_types

# Use constants for isinstance checks
def is_bytes_like(value):
    return isinstance(value, bytes_types)

def is_string_like(value):
    return isinstance(value, string_types)

# Examples
print(is_bytes_like(b"test"))      # True
print(is_bytes_like(bytearray()))  # True
print(is_string_like("test"))      # True
print(is_string_like(b"test"))     # True

Common Validation Patterns

Comprehensive Input Validation

from eth_utils import (
    is_string, is_integer, is_bytes, is_boolean, 
    is_list_like, is_dict, is_null
)

def validate_smart_contract_call(contract_address, function_name, parameters):
    """Validate smart contract call parameters."""
    # Address validation
    if is_null(contract_address) or not is_string(contract_address):
        raise TypeError("Contract address must be non-null string")
    
    # Function name validation
    if is_null(function_name) or not is_string(function_name):
        raise TypeError("Function name must be non-null string")
    
    # Parameters validation
    if is_null(parameters):
        parameters = []
    elif not is_list_like(parameters):
        raise TypeError("Parameters must be list-like or None")
    
    # Validate each parameter
    for i, param in enumerate(parameters):
        if is_null(param):
            continue  # Allow null parameters
        elif not (is_string(param) or is_integer(param) or 
                 is_bytes(param) or is_boolean(param)):
            raise TypeError(f"Parameter {i} has unsupported type: {type(param)}")
    
    return True

Install with Tessl CLI

npx tessl i tessl/pypi-eth-utils

docs

abi-processing.md

address-operations.md

crypto-functions.md

currency-units.md

data-conversions.md

data-formatting.md

functional-programming.md

hexadecimal-utilities.md

index.md

logging-debugging.md

network-information.md

type-checking.md

tile.json