Advanced Type Validation
Complex Type Validation Techniques
1. Custom Type Validation Decorator
def validate_types(*type_args, **type_kwargs):
def decorator(func):
def wrapper(*args, **kwargs):
## Validate positional arguments
for arg, expected_type in zip(args, type_args):
if not isinstance(arg, expected_type):
raise TypeError(f"Expected {expected_type}, got {type(arg)}")
## Validate keyword arguments
for key, value in kwargs.items():
expected_type = type_kwargs.get(key)
if expected_type and not isinstance(value, expected_type):
raise TypeError(f"Argument {key} must be {expected_type}")
return func(*args, **kwargs)
return wrapper
return decorator
## LabEx advanced type validation example
@validate_types(int, str, age=int)
def create_user(user_id, name, age):
return {"id": user_id, "name": name, "age": age}
2. Advanced Type Checking Strategies
Strategy |
Description |
Use Case |
Structural Typing |
Check object structure |
Complex data validation |
Protocol Checking |
Verify method signatures |
Interface compliance |
Duck Typing |
Check capabilities |
Flexible type validation |
Type Validation Flow
graph TD
A[Input Data] --> B{Structural Check}
B --> |Validate Structure| C{Protocol Compliance}
C --> |Method Signature| D{Type Constraints}
D --> |Type Validation| E[Process Data]
E --> F[Return Result]
B --> |Fail| G[Raise Validation Error]
3. Runtime Type Inspection
from typing import Protocol, runtime_checkable
@runtime_checkable
class Drawable(Protocol):
def draw(self) -> None:
"""Protocol for drawable objects"""
pass
def validate_drawable(obj):
"""Advanced type validation using Protocol"""
if not isinstance(obj, Drawable):
raise TypeError("Object must implement Drawable protocol")
obj.draw()
class Circle:
def draw(self):
print("Drawing circle")
class Rectangle:
def render(self):
print("Rendering rectangle")
4. Generic Type Validation
from typing import TypeVar, Generic, List
T = TypeVar('T')
class TypeSafeContainer(Generic[T]):
def __init__(self):
self._items: List[T] = []
def add(self, item: T):
"""Type-safe addition with generic constraint"""
if not isinstance(item, type(self._items[0]) if self._items else type(item)):
raise TypeError("Inconsistent type in container")
self._items.append(item)
def get_items(self) -> List[T]:
return self._items
## Usage example
int_container = TypeSafeContainer[int]()
int_container.add(1)
int_container.add(2)
5. Advanced Type Checking Libraries
Library |
Features |
Performance |
mypy |
Static type checking |
Compile-time |
typeguard |
Runtime type checking |
Moderate overhead |
pydantic |
Data validation |
High-performance |
Complex Validation Example
from typing import Union, List, Dict, Any
def advanced_type_validator(
data: Union[List[Any], Dict[str, Any]],
schema: Dict[str, type]
) -> bool:
"""
Comprehensive type validation for complex data structures
"""
if isinstance(data, list):
return all(
isinstance(item, schema.get(type(item).__name__))
for item in data
)
if isinstance(data, dict):
return all(
isinstance(data.get(key), type_check)
for key, type_check in schema.items()
)
return False
## LabEx advanced validation demonstration
validation_schema = {
'int': int,
'str': str,
'float': float
}
test_data = [1, 'hello', 3.14]
print(advanced_type_validator(test_data, validation_schema))
Best Practices
- Use type hints for documentation
- Implement runtime type checking judiciously
- Balance between type safety and performance
- Leverage static type checking tools
- Create flexible validation mechanisms
By mastering these advanced type validation techniques, developers can create more robust, type-safe Python applications with comprehensive type checking strategies.