Metadata-Version: 2.4
Name: ml3on-format-pydantic
Version: 0.0.1
Summary: ML3Seq Format
Author: macro
Requires-Python: <3.15,>=3.11
Description-Content-Type: text/markdown
Requires-Dist: ml3on-format-core<0.1.0,>=0.0.0
Requires-Dist: ml3macro-pydantic>=0.0.3
Requires-Dist: pydantic<3.0.0,>=2.11.0

# ML3Seq Format Pydantic Integration

Seamless integration between ML3Seq format and Pydantic models for type-safe serialization with unescaped multiline strings.

## Status: On the way out... to make way for the new.

See status notes in project [README.md#status](https://codeberg.org/gxyflow/ml3on-format/src/branch/main/README.md#status-on-the-way-out-to-make-way-for-the-new).

## Overview

This package provides two main integration approaches for using ML3Seq format with Pydantic models:

1. **ML3SeqItemBaseModel**: BaseModel subclass with built-in ML3Seq support
2. **ML3SeqTypeAdapter**: Flexible adapter for any Pydantic model
3. **ML3SeqBaseModel**: BaseModel for ML3Seqs

## Key Features

### Type-Based Serialization Control

The most important feature is **type-based control over serialization format**:

```python
from ml3on.pydantic import ML3SeqItemBaseModel, ML3SeqMultilineString

class Document(ML3SeqItemBaseModel):
    _ml3seq_kind = "DOCUMENT"
    title: str                    # Will be in JSON if no newlines
    content: ML3SeqMultilineString  # ALWAYS in multiline block

doc = Document(
    title="Guide",
    content="This will be serialized as a multiline block"
)

ml3seq_str = doc.to_ml3seq()
# Result:
# -~<§BEGIN:DOCUMENT
# {"title": "Guide"}
# -~<§content
# This will be serialized as a multiline block
# -~<§END:DOCUMENT
```

### Automatic Type Coercion

During serialization, string values are automatically wrapped in `ML3SeqMultilineString` when the field is typed as such:

```python
class Example(ML3SeqItemBaseModel):
    _ml3seq_kind = "EXAMPLE"
    text: ML3SeqMultilineString  # Type annotation controls format

example = Example(text="single line")  # String value
ml3seq_str = example.to_ml3seq()
# Still uses multiline block because of type annotation
```

## Installation

```bash
# Install from source
uv pip install packages/ml3seq-format-pydantic/dist/ml3seq-format-pydantic-*.whl

# Or install as development dependency
uv pip install -e packages/ml3seq-format-pydantic
```

## Usage Patterns

### 1. ML3SeqItemBaseModel (Recommended)

Best for most use cases - clean syntax and full integration:

```python
from ml3on.pydantic import ML3SeqItemBaseModel, ML3SeqMultilineString

class Article(ML3SeqItemBaseModel):
    _ml3seq_kind = "ARTICLE"
    title: str
    author: str
    content: ML3SeqMultilineString  # Always multiline
    tags: list[str] = []

# Create and serialize
article = Article(
    title="ML3Seq Guide",
    author="ML3Seq Team",
    content="This is a comprehensive guide\n\nSection 1: Basics\nSection 2: Advanced",
    tags=["guide", "ml3seq", "format"]
)

ml3seq_str = article.to_ml3seq()

# Deserialize
loaded_article = Article.from_ml3seq(ml3seq_str)
```

### 2. ML3SeqTypeAdapter (Flexible)

Best for working with existing models or when you need flexibility:

```python
from pydantic import BaseModel
from ml3on.pydantic import ML3SeqTypeAdapter

class LegacyModel(BaseModel):
    name: str
    data: str

# Create adapter
adapter = ML3SeqTypeAdapter(LegacyModel)

# Serialize
model = LegacyModel(name="test", data="Line 1\nLine 2")
ml3seq_str = adapter.to_ml3seq(model)

# Deserialize
loaded_model = adapter.from_ml3seq(ml3seq_str)
```

### 3. ML3SeqBaseModel (Sequences)

For working with sequences of items:

```python
from ml3on.pydantic import ML3SeqBaseModel, ML3SeqItemBaseModel

class Message(ML3SeqItemBaseModel):
    _ml3seq_kind = "MESSAGE"
    sender: str
    content: str

class MessageSequence(ML3SeqBaseModel[Message]):
    @classmethod
    def _kind_to_class_mapping(cls):
        return {"MESSAGE": Message}

# Create sequence
messages = [
    Message(sender="user1", content="Hello"),
    Message(sender="user2", content="Hi there!")
]

sequence = MessageSequence(items=messages)
ml3seq_str = sequence.to_ml3seq()

# Deserialize
loaded_sequence = MessageSequence.from_ml3seq(ml3seq_str)
```

## Configuration

### Custom Separator Prefix

```python
from ml3on.core import ML3SeqFormatConfig

# Using ML3SeqItemBaseModel
class ConfigurableModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "CONFIGURABLE"
    
    def _get_ml3seq_config(self):
        return ML3SeqFormatConfig(separator_prefix="CUSTOM|")

# Using ML3SeqTypeAdapter
config = ML3SeqFormatConfig(separator_prefix="BOOP|")
adapter = ML3SeqTypeAdapter(MyModel, config=config)
```

### Environment Variable

```bash
export ML3Seq_FORMAT_SEPARATOR_PREFIX="MY_PREFIX|"
```

## Advanced Usage

### Optional Multiline Fields

```python
from typing import Optional
from ml3on.pydantic import ML3SeqItemBaseModel, ML3SeqMultilineString

class Document(ML3SeqItemBaseModel):
    _ml3seq_kind = "DOCUMENT"
    title: str
    content: ML3SeqMultilineString
    summary: Optional[ML3SeqMultilineString] = None

# With summary
doc1 = Document(title="Guide", content="Main content", summary="Brief summary")

# Without summary
doc2 = Document(title="Guide", content="Main content")
```

### Nested Models

```python
class Author(ML3SeqItemBaseModel):
    _ml3seq_kind = "AUTHOR"
    name: str
    bio: ML3SeqMultilineString

class Article(ML3SeqItemBaseModel):
    _ml3seq_kind = "ARTICLE"
    title: str
    content: ML3SeqMultilineString
    author: Author

article = Article(
    title="Advanced ML3Seq",
    content="Detailed content here",
    author=Author(name="ML3Seq Team", bio="Experts in serialization formats")
)
```

### Complex Types

```python
from typing import List, Dict, Union

class ComplexModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "COMPLEX"
    
    # List of strings
    tags: List[str]
    
    # Dictionary
    metadata: Dict[str, Union[str, int]]
    
    # Optional field
    description: Optional[str] = None
    
    # Multiline content
    content: ML3SeqMultilineString
```

### Custom Validation

```python
from pydantic import field_validator

class ValidatedModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "VALIDATED"
    content: ML3SeqMultilineString
    
    @field_validator('content')
    def validate_content(cls, v):
        if len(v) > 1000:
            raise ValueError("Content too long")
        if "forbidden" in v.lower():
            raise ValueError("Forbidden content")
        return v
```

## Type System Integration

### Type Annotations Matter

The key insight: **type annotations control serialization format**

```python
class Example(ML3SeqItemBaseModel):
    _ml3seq_kind = "EXAMPLE"
    
    # Regular string - goes in JSON if no newlines
    regular_string: str
    
    # ML3SeqMultilineString - ALWAYS goes in multiline block
    multiline_string: ML3SeqMultilineString
    
    # Optional ML3SeqMultilineString
    optional_multiline: Optional[ML3SeqMultilineString] = None
```

### Union Types

```python
from typing import Union

class FlexibleModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "FLEXIBLE"
    
    # Can be either type
    flexible_field: Union[str, ML3SeqMultilineString]
    
    # Optional union
    optional_flexible: Optional[Union[str, ML3SeqMultilineString]] = None
```

## Error Handling

### Common Errors

```python
from pydantic import ValidationError

try:
    # Invalid ML3Seq format
    model = MyModel.from_ml3seq("invalid ml3seq format")
except ValueError as e:
    print(f"Format error: {e}")

try:
    # Type mismatch
    model = MyModel.from_ml3seq(ml3seq_for_different_type)
except ValueError as e:
    print(f"Type mismatch: {e}")

try:
    # Validation error
    model = MyModel(content=123)  # Wrong type
except ValidationError as e:
    print(f"Validation error: {e}")
```

### Graceful Fallbacks

```python
def safe_deserialize(ml3seq_str: str, fallback_model=None):
    """Safe deserialization with fallback"""
    try:
        return MyModel.from_ml3seq(ml3seq_str)
    except (ValueError, ValidationError) as e:
        logger.error(f"Deserialization failed: {e}")
        return fallback_model or create_default_model()
```

## Performance Considerations

### Large Models

```python
# Efficient handling of large models
class LargeModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "LARGE"
    
    # Large multiline content
    content: ML3SeqMultilineString
    
    # Many fields
    field1: str
    field2: str
    # ... many more fields

# Memory efficient processing
model = LargeModel(content="A" * 10000)  # 10k characters
ml3seq_str = model.to_ml3seq()
```

### Batch Processing

```python
def process_batch(models: list):
    """Process multiple models efficiently"""
    results = []
    for model in models:
        try:
            ml3seq_str = model.to_ml3seq()
            results.append(ml3seq_str)
        except Exception as e:
            results.append(f"Error: {e}")
    return results
```

## Integration Patterns

### File System Integration

```python
def save_to_file(model: ML3SeqItemBaseModel, filepath: str):
    """Save model to ML3Seq file"""
    with open(filepath, 'w', encoding='utf-8') as f:
        f.write(model.to_ml3seq())

def load_from_file(filepath: str, model_class: type):
    """Load model from ML3Seq file"""
    with open(filepath, 'r', encoding='utf-8') as f:
        return model_class.from_ml3seq(f.read())
```

### API Integration

```python
import requests

def send_to_api(model: ML3SeqItemBaseModel, url: str):
    """Send model via API"""
    headers = {'Content-Type': 'text/ml3seq'}
    response = requests.post(url, data=model.to_ml3seq(), headers=headers)
    return model.__class__.from_ml3seq(response.text)
```

### Database Integration

```python
def store_in_database(model: ML3SeqItemBaseModel, db_connection):
    """Store model in database"""
    cursor = db_connection.cursor()
    cursor.execute(
        "INSERT INTO documents (content) VALUES (%s)",
        (model.to_ml3seq(),)
    )
    db_connection.commit()
```

## Testing

### Running Tests

```bash
# Run all pydantic tests
just test packages/ml3seq-format-pydantic/tests/

# Run specific test file
just test packages/ml3seq-format-pydantic/tests/ml3seq/pydantic/test_base_item.py

# Run with verbose output
just test packages/ml3seq-format-pydantic/tests/ -v
```

### Test Structure

```
packages/ml3seq-format-pydantic/tests/
├── ml3seq/
│   ├── pydantic/
│   │   ├── test_base_item.py                # ML3SeqItemBaseModel tests
│   │   ├── test_base_item__edge_cases.py    # Edge case tests
│   │   ├── test_base_item__multiline_coercion.py # Multiline coercion tests
│   │   ├── test_base_sequence.py            # ML3SeqBaseModel tests
│   │   ├── test_base_sequence__core.py      # Core sequence tests
│   │   ├── test_config_handling.py          # Config tests
│   │   ├── test_optional_multiline__edge_cases.py # Optional multiline tests
│   │   ├── test_type_adapter.py             # ML3SeqTypeAdapter tests
│   │   ├── test_type_adapter__edge_cases.py # Adapter edge cases
│   │   └── test_type_adapter__integration.py # Integration tests
│   └── helpers/
│       └── base_test_item.py               # Test helpers
```

### Writing Tests

```python
import pytest
from ml3on.pydantic import ML3SeqItemBaseModel, ML3SeqMultilineString

class TestModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "TEST"
    content: ML3SeqMultilineString

def test_multiline_serialization():
    """Test multiline string serialization"""
    model = TestModel(content="Line 1\nLine 2")
    ml3seq_str = model.to_ml3seq()
    
    assert "-~<§content" in ml3seq_str
    assert "Line 1" in ml3seq_str
    assert "Line 2" in ml3seq_str

def test_round_trip():
    """Test serialization/deserialization"""
    original = TestModel(content="Test content")
    ml3seq_str = original.to_ml3seq()
    loaded = TestModel.from_ml3seq(ml3seq_str)
    
    assert str(loaded.content) == str(original.content)
```

## API Reference

### ML3SeqItemBaseModel

**Abstract Base Class** for ML3Seq-enabled Pydantic models.

**Abstract Properties:**
- `_ml3seq_kind: str` - Item type identifier (must be implemented)

**Methods:**
- `to_ml3seq(config=None) -> str` - Serialize to ML3Seq format
- `from_ml3seq(ml3seq_str: str) -> Self` - Deserialize from ML3Seq (classmethod)
- `_convert_to_ml3seq_item(model_dict) -> ML3SeqItem` - Convert to ML3Seq item
- `from_ml3seq_item(item) -> dict` - Convert ML3Seq item to dict (classmethod)
- `_get_ml3seq_config() -> ML3SeqFormatConfig` - Get configuration

**Properties:**
- `as_ml3seq_item: ML3SeqItem` - Cached ML3Seq item representation

### ML3SeqTypeAdapter

**Flexible adapter** for any Pydantic model.

**Methods:**
- `to_ml3seq(data) -> str` - Serialize model to ML3Seq
- `from_ml3seq(ml3seq_str) -> BaseModel` - Deserialize ML3Seq to model
- `_convert_to_ml3seq_item(model_dict) -> ML3SeqItem` - Convert to ML3Seq item
- `_convert_from_ml3seq_item(item) -> dict` - Convert ML3Seq item to dict

**Parameters:**
- `model_type: Type[BaseModel]` - Pydantic model class
- `config: Optional[ML3SeqFormatConfig]` - Configuration

### ML3SeqBaseModel

**Base class** for ML3Seqs.

**Abstract Methods:**
- `_kind_to_class_mapping() -> Mapping[str, Type]` - Kind to class mapping

**Methods:**
- `from_ml3seq_sequence(sequence) -> Self` - Create from ML3Seq (classmethod)
- `from_ml3seq(ml3seq_string) -> Self` - Create from ML3Seq string (classmethod)

**Properties:**
- `as_ml3seq_sequence: ML3Seq` - ML3Seq representation
- `to_ml3seq: str` - Serialized ML3Seq string

### ML3SeqMultilineString

**String subclass** for explicit multiline control.

**Inherits from:** `str`

**Methods:** All standard string methods

## Best Practices

### 1. Use Type Annotations for Control

```python
# Good: Explicit type control
class GoodModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "GOOD"
    title: str                    # JSON format
    content: ML3SeqMultilineString  # Multiline format

# Avoid: Ambiguous formatting
class BadModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "BAD"
    title: str  # Will this be JSON or multiline?
```

### 2. Choose Appropriate Integration

```python
# Use ML3SeqItemBaseModel for new models
class NewModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "NEW"
    # ... fields

# Use ML3SeqTypeAdapter for existing models
class ExistingModel(BaseModel):
    # ... existing fields

adapter = ML3SeqTypeAdapter(ExistingModel)
```

### 3. Handle Optional Fields Properly

```python
# Good: Explicit optional handling
class GoodModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "GOOD"
    required: ML3SeqMultilineString
    optional: Optional[ML3SeqMultilineString] = None

# Avoid: Implicit optional behavior
class BadModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "BAD"
    field: ML3SeqMultilineString  # Is this optional?
```

### 4. Validate Input Data

```python
# Good: Input validation
class ValidatedModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "VALIDATED"
    content: ML3SeqMultilineString
    
    @classmethod
    def from_ml3seq(cls, ml3seq_str: str):
        if len(ml3seq_str) > 1000000:  # 1MB limit
            raise ValueError("ML3Seq too large")
        return super().from_ml3seq(ml3seq_str)
```

### 5. Error Handling

```python
# Good: Comprehensive error handling
try:
    model = MyModel.from_ml3seq(user_input)
except ValueError as e:
    logger.error(f"ML3Seq parse error: {e}")
    return default_response()
except ValidationError as e:
    logger.error(f"Validation error: {e}")
    return error_response()
```

## Comparison with Other Approaches

### ML3Seq vs Pure JSON

**ML3Seq Advantages:**
- Unescaped multiline content
- Better readability for mixed data
- Explicit structure boundaries
- Type-based format control

**When to use JSON:**
- Pure structured data
- Browser compatibility
- Simple configurations

### ML3Seq vs Custom Serialization

**ML3Seq Advantages:**
- Standardized format
- Type safety
- Comprehensive error handling
- Integration with Pydantic
- Well-tested implementation

**When to use custom:**
- Very specific requirements
- Legacy system compatibility
- Performance-critical applications

## Migration Guide

### From JSON to ML3Seq

```python
from pydantic import BaseModel
from ml3on.pydantic import ML3SeqItemBaseModel, ML3SeqMultilineString

# JSON model
class JsonModel(BaseModel):
    title: str
    content: str

# ML3Seq model
class ML3SeqBaseModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "DOCUMENT"
    title: str
    content: ML3SeqMultilineString  # Explicit multiline

# Convert JSON to ML3Seq
def json_to_ml3seq(json_data: dict) -> ML3SeqBaseModel:
    return ML3SeqBaseModel(**json_data)
```

### From ML3Seq to JSON

```python
# Convert ML3Seq to JSON
def ml3seq_to_json(ml3seq_model: ML3SeqBaseModel) -> dict:
    return {
        "title": ml3seq_model.title,
        "content": str(ml3seq_model.content)  # Convert to regular string
    }
```

## Performance Optimization

### Caching

```python
from functools import lru_cache

class CachedModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "CACHED"
    
    @lru_cache(maxsize=100)
    def get_cached_ml3seq(self):
        """Cache ML3Seq representation"""
        return self.to_ml3seq()
```

### Batch Processing

```python
def process_batch_efficiently(models: list):
    """Process models in batches"""
    batch_size = 50
    results = []
    
    for i in range(0, len(models), batch_size):
        batch = models[i:i + batch_size]
        batch_results = [model.to_ml3seq() for model in batch]
        results.extend(batch_results)
    
    return results
```

### Memory Management

```python
def process_large_model(model: ML3SeqItemBaseModel):
    """Process large models efficiently"""
    # Use generators for large content
    def content_chunks(content, chunk_size=4096):
        for i in range(0, len(content), chunk_size):
            yield content[i:i + chunk_size]
    
    # Process in chunks
    for chunk in content_chunks(str(model.content)):
        process_chunk(chunk)
```

## Security Considerations

### Input Validation

```python
class SecureModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "SECURE"
    
    @classmethod
    def from_ml3seq(cls, ml3seq_str: str):
        # Size limit
        if len(ml3seq_str) > 100000:  # 100KB
            raise ValueError("ML3Seq too large")
        
        # Content validation
        if "malicious" in ml3seq_str.lower():
            raise ValueError("Potentially malicious content")
        
        return super().from_ml3seq(ml3seq_str)
```

### Field Sanitization

```python
def sanitize_model_data(data: dict) -> dict:
    """Sanitize data before creating models"""
    sanitized = {}
    for key, value in data.items():
        # Remove potentially dangerous characters
        safe_key = ''.join(c for c in key if c.isalnum() or c in '_-')
        if safe_key:
            sanitized[safe_key] = str(value)[:1000]  # Length limit
    return sanitized
```

## Troubleshooting

### Common Issues

**Issue**: Fields not appearing in multiline format
- **Cause**: Missing `ML3SeqMultilineString` type annotation
- **Solution**: Add proper type annotation to field

**Issue**: `ValidationError: Expected ML3SeqMultilineString`
- **Cause**: Providing wrong type to typed field
- **Solution**: Use `ML3SeqMultilineString(value)` or fix type annotation

**Issue**: Serialization much slower than expected
- **Cause**: Very large multiline strings
- **Solution**: Process in chunks or optimize content

### Debugging Tips

```python
# Debug serialization
def debug_model(model: ML3SeqItemBaseModel):
    print(f"Model kind: {model._ml3seq_kind}")
    print(f"Model fields: {model.model_dump()}")
    
    ml3seq_str = model.to_ml3seq()
    print(f"ML3Seq output:\n{ml3seq_str}")
    
    # Check field types
    for field_name, field_info in model.model_fields.items():
        value = getattr(model, field_name)
        print(f"{field_name}: {type(value)} = {repr(value)[:50]}...")
```

## Future Enhancements

### Planned Features

1. **Field-Level Configuration**: Per-field serialization control
2. **Streaming Support**: For very large models
3. **Schema Validation**: Integration with Pydantic validation
4. **Performance Optimizations**: For specific use cases
5. **Enhanced Type Support**: More complex type handling

### Potential Improvements

- **Binary Data**: Safe handling of binary content
- **Compression**: Built-in compression options
- **Encryption**: Secure serialization options
- **Versioning**: Model version management
- **Extensions**: Plugin system for custom features

## Documentation

- [Main README](../../README.md): Project overview
- [Core Package](../ml3seq-format-core/README.md): Core ML3Seq format
- [Build System](../../BUILD_README.md): Building and versioning

## Support

For issues, questions, or contributions:
- **GitHub Issues**: Report bugs and request features
- **Discussions**: Ask questions and share ideas
- **Pull Requests**: Contribute improvements

## License

MIT License - Open source and free to use.

## Changelog

See [VERSION](../../VERSION) file for version history.

## Contributing

Contributions are welcome! Please:
1. Follow existing code patterns
2. Add comprehensive tests
3. Update documentation
4. Maintain backward compatibility
5. Follow Pydantic best practices

## Examples

### Complete Example: Blog System

```python
from typing import Optional, List
from ml3on.pydantic import ML3SeqItemBaseModel, ML3SeqMultilineString

class Author(ML3SeqItemBaseModel):
    _ml3seq_kind = "AUTHOR"
    name: str
    bio: ML3SeqMultilineString
    email: Optional[str] = None

class BlogPost(ML3SeqItemBaseModel):
    _ml3seq_kind = "BLOG_POST"
    title: str
    content: ML3SeqMultilineString
    author: Author
    tags: List[str] = []
    published_date: Optional[str] = None

# Create a blog post
post = BlogPost(
    title="Getting Started with ML3Seq",
    content="""
# Introduction to ML3Seq

ML3Seq is a powerful serialization format that combines the best of JSON and multiline text.

## Key Features

- Unescaped multiline strings
- JSON compatibility
- Type safety
- LLM optimization
    """,
    author=Author(
        name="ML3Seq Team",
        bio="Experts in serialization formats and LLM integration."
    ),
    tags=["ml3seq", "serialization", "llm"],
    published_date="2024-01-01"
)

# Serialize to ML3Seq
ml3seq_str = post.to_ml3seq()
print(ml3seq_str)

# Deserialize from ML3Seq
loaded_post = BlogPost.from_ml3seq(ml3seq_str)
```

### Example: File Operations

```python
class FileOperation(ML3SeqItemBaseModel):
    _ml3seq_kind = "FILE_OP"
    operation: str  # "CREATE", "UPDATE", "DELETE"
    filepath: str
    content: Optional[ML3SeqMultilineString] = None
    metadata: Optional[dict] = None

# Create file operation
create_op = FileOperation(
    operation="CREATE",
    filepath="README.md",
    content="""
# Project Title

## Description

This is a sample project using ML3Seq format.

## Features

- Efficient serialization
- Type safety
- LLM optimization
    """,
    metadata={"created_by": "system", "timestamp": "2024-01-01"}
)

ml3seq_str = create_op.to_ml3seq()
```

### Example: Test Case Management

```python
class TestCase(ML3SeqItemBaseModel):
    _ml3seq_kind = "TEST_CASE"
    name: str
    description: str
    expected_output: ML3SeqMultilineString
    actual_output: ML3SeqMultilineString
    status: str = "PENDING"

test_case = TestCase(
    name="test_ml3seq_serialization",
    description="Test that ML3Seq serialization works correctly",
    expected_output="""
Expected result line 1
Expected result line 2
Expected result line 3
    """,
    actual_output="""
Actual result line 1
Actual result line 2
Actual result line 3
    """,
    status="PASSED"
)

ml3seq_str = test_case.to_ml3seq()
```

## Quick Reference

### Common Imports

```python
from ml3on.pydantic import (
    ML3SeqItemBaseModel,
    ML3SeqMultilineString,
    ML3SeqTypeAdapter,
    ML3SeqBaseModel
)
from ml3on.core import ML3SeqFormatConfig
```

### Common Patterns

```python
# Basic model
class MyModel(ML3SeqItemBaseModel):
    _ml3seq_kind = "MY_MODEL"
    field: ML3SeqMultilineString

# Serialization
model = MyModel(field="content")
ml3seq_str = model.to_ml3seq()

# Deserialization
loaded = MyModel.from_ml3seq(ml3seq_str)

# With custom config
config = ML3SeqFormatConfig(separator_prefix="CUSTOM|")
```

## Performance Benchmarks

### Serialization Speed

```python
import time

# Small model
small_model = MyModel(content="A" * 1000)
start = time.time()
for _ in range(1000):
    _ = small_model.to_ml3seq()
print(f"Small model: {time.time() - start:.4f}s for 1000 iterations")

# Large model
large_model = MyModel(content="A" * 100000)
start = time.time()
for _ in range(100):
    _ = large_model.to_ml3seq()
print(f"Large model: {time.time() - start:.4f}s for 100 iterations")
```

### Memory Usage

```python
import sys

# Memory usage
model = MyModel(content="A" * 10000)
ml3seq_str = model.to_ml3seq()

print(f"Model size: {sys.getsizeof(model)} bytes")
print(f"ML3Seq size: {sys.getsizeof(ml3seq_str)} bytes")
print(f"ML3Seq length: {len(ml3seq_str)} characters")
```

## Conclusion

The ML3Seq Format Pydantic integration provides a powerful way to work with structured data containing multiline strings, offering:

- **Type-based format control** through `ML3SeqMultilineString`
- **Seamless Pydantic integration** with familiar patterns
- **LLM optimization** with unescaped multiline content
- **Flexible approaches** for different use cases
- **Comprehensive error handling** and validation

This integration makes ML3Seq format accessible to Pydantic users while maintaining all the benefits of type safety and validation.
