CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pykwalify

Python lib/cli for JSON/YAML schema validation

Pending
Overview
Eval results
Files

compatibility.mddocs/

Compatibility Layer

PyKwalify provides cross-version compatibility utilities to ensure consistent behavior across Python 2/3 and different YAML library versions. The compatibility layer abstracts differences between Python versions and provides unified interfaces for string handling and YAML processing.

Capabilities

YAML Processing

yml: ruamel.yaml.YAML  # Global YAML loader/dumper instance

String Type Compatibility

basestring: type  # Base string type (str in Python 3, basestring in Python 2)
unicode: type     # Unicode string type (str in Python 3, unicode in Python 2)
bytes: type       # Bytes type (consistent across versions)

String Conversion Utilities

def u(x):
    """
    Convert string to unicode.
    
    Args:
        x (str): String to convert
    
    Returns:
        str: Unicode string (Python 3) or unicode (Python 2)
    """

def b(x):
    """
    Convert string to bytes.
    
    Args:
        x (str): String to convert
    
    Returns:
        bytes: Byte string
    """

def nativestr(x):
    """
    Convert to native string type for the current Python version.
    
    Args:
        x: Object to convert
    
    Returns:
        str: Native string representation
    """

Usage Examples

YAML Processing

from pykwalify.compat import yml

# Load YAML content (works across ruamel.yaml versions)
yaml_content = """
name: Test
values:
  - item1
  - item2
"""

data = yml.load(yaml_content)
print(f"Loaded data: {data}")

# Save YAML content
import io
output = io.StringIO()
yml.dump(data, output)
print(f"YAML output: {output.getvalue()}")

Cross-Version String Handling

from pykwalify.compat import basestring, unicode, u, b, nativestr

# Check if value is any string type (works in Python 2 and 3)
def is_string_like(value):
    return isinstance(value, basestring)

# Examples
test_values = ["hello", u"unicode", b"bytes"]
for value in test_values:
    print(f"'{value}' is string-like: {is_string_like(value)}")

# String conversion utilities
text = "Hello, World!"
unicode_text = u(text)      # Ensure unicode
byte_text = b(text)         # Convert to bytes
native_text = nativestr(text)  # Native string type

print(f"Original: {text}")
print(f"Unicode: {unicode_text}")
print(f"Bytes: {byte_text}")
print(f"Native: {native_text}")

Type Checking Across Versions

from pykwalify.compat import basestring, unicode

def validate_string_input(value):
    """Validate string input that works across Python versions."""
    if not isinstance(value, basestring):
        raise TypeError(f"Expected string, got {type(value)}")
    
    # Convert to unicode for consistent processing
    if not isinstance(value, unicode):
        value = value.decode('utf-8')
    
    return value

# Test with different string types
test_strings = ["ascii", u"unicode", "utf-8 text"]
for s in test_strings:
    try:
        result = validate_string_input(s)
        print(f"Validated: {result}")
    except Exception as e:
        print(f"Error: {e}")

Integration with Core Validation

from pykwalify.core import Core
from pykwalify.compat import yml
import io

# Create YAML content programmatically using compatible YAML handler
schema_dict = {
    "type": "map",
    "mapping": {
        "name": {"type": "str", "required": True},
        "version": {"type": "str"}
    }
}

data_dict = {
    "name": "MyProject",
    "version": "1.0.0"
}

# Convert to YAML strings using compatibility layer
schema_stream = io.StringIO()
data_stream = io.StringIO()

yml.dump(schema_dict, schema_stream)
yml.dump(data_dict, data_stream)

schema_yaml = schema_stream.getvalue()
data_yaml = data_stream.getvalue()

print("Generated schema:")
print(schema_yaml)
print("Generated data:")
print(data_yaml)

# Use with Core validation
c = Core(source_data=data_dict, schema_data=schema_dict)
try:
    c.validate(raise_exception=True)
    print("Validation successful with compatibility layer!")
except Exception as e:
    print(f"Validation failed: {e}")

Advanced Usage

Custom YAML Processing

from pykwalify.compat import yml

# The yml object is a configured ruamel.yaml.YAML instance
# You can access its properties and methods

# Configure YAML processing
yml.width = 4096  # Set line width
yml.preserve_quotes = True  # Preserve quotes in output

# Load with custom handling
def load_yaml_safely(content):
    """Load YAML with error handling."""
    try:
        return yml.load(content)
    except Exception as e:
        print(f"YAML loading failed: {e}")
        return None

# Test YAML loading
yaml_content = '''
# Configuration file
app:
  name: "MyApp"
  debug: true
  features:
    - feature1
    - feature2
'''

config = load_yaml_safely(yaml_content)
if config:
    print(f"Loaded config: {config}")

Error Handling in Compatibility Context

from pykwalify.compat import basestring, unicode, nativestr
from pykwalify.errors import CoreError

def safe_string_conversion(value, target_type="unicode"):
    """Safely convert strings with proper error handling."""
    try:
        if target_type == "unicode":
            if isinstance(value, unicode):
                return value
            elif isinstance(value, bytes):
                return value.decode('utf-8')
            else:
                return unicode(str(value))
                
        elif target_type == "native":
            return nativestr(value)
            
        else:
            raise ValueError(f"Unknown target type: {target_type}")
            
    except UnicodeDecodeError as e:
        raise CoreError(f"String encoding error: {e}")
    except Exception as e:
        raise CoreError(f"String conversion error: {e}")

# Test conversion
test_values = ["ascii", u"unicode", b"bytes", 123, None]
for value in test_values:
    try:
        result = safe_string_conversion(value)
        print(f"Converted '{value}' -> '{result}' (type: {type(result)})")
    except Exception as e:
        print(f"Failed to convert '{value}': {e}")

Internal Implementation Notes

The compatibility layer handles the following version differences:

  • Python 2/3 String Types: Provides unified basestring and unicode types
  • YAML Library: Uses ruamel.yaml for consistent YAML 1.2 support
  • Encoding Handling: Provides utilities for safe string encoding/decoding
  • Type Checking: Ensures isinstance() checks work across versions

This layer is primarily used internally by PyKwalify but is exposed for advanced users who need cross-version compatibility in their validation extensions or custom code.

Install with Tessl CLI

npx tessl i tessl/pypi-pykwalify

docs

cli.md

compatibility.md

core-validation.md

error-handling.md

index.md

schema-rules.md

type-system.md

tile.json