Skip to content

encoding

pyvider.cty.exceptions.encoding

TODO: Add module docstring.

Classes

AttributePathError

AttributePathError(
    message: str,
    path: object = None,
    value: object = None,
    **kwargs: Any
)

Bases: CtyError

Raised when there's an error with an attribute path.

This exception occurs when a path operation fails, such as: - When a path cannot be applied to a value - When a path step refers to a non-existent attribute or index - When a path operation is applied to an incompatible value type

Attributes:

Name Type Description
message

A human-readable error description

path

The path that caused the error

value

The value the path was being applied to

Initializes the AttributePathError.

Parameters:

Name Type Description Default
message str

The base error message.

required
path object

The CtyPath or path representation that caused the error.

None
value object

The CtyValue to which the path was being applied.

None
Source code in pyvider/cty/exceptions/encoding.py
def __init__(self, message: str, path: object = None, value: object = None, **kwargs: Any) -> None:
    """
    Initializes the AttributePathError.

    Args:
        message: The base error message.
        path: The CtyPath or path representation that caused the error.
        value: The CtyValue to which the path was being applied.
    """
    self.path = path
    self.value = value

    # Add path operation context
    context: dict[str, Any] = kwargs.setdefault("context", {})
    context["cty.error_category"] = "path_operation"
    context["cty.operation"] = "attribute_path_access"

    if path is not None:
        context["cty.path"] = str(path)
        if hasattr(path, "steps"):
            steps = cast(list[Any], path.steps)
            context["cty.path_depth"] = len(steps)

    if value is not None:
        context["cty.value_type"] = type(value).__name__
        if hasattr(value, "type"):
            context["cty.cty_type"] = str(value.type)

    super().__init__(message, **kwargs)
Functions

DeserializationError

DeserializationError(
    message: str,
    data: object = None,
    format_name: str | None = None,
    **kwargs: Any
)

Bases: EncodingError

Raised when deserialization of data fails.

This exception occurs when serialized data cannot be converted back into a Cty value, such as when the data is corrupt or in an incompatible format.

Attributes:

Name Type Description
message

A human-readable error description

data

The data that failed to deserialize

format_name

The name of the format that was being used

Initializes the DeserializationError.

Parameters:

Name Type Description Default
message str

The base error message.

required
data object

The data that failed to deserialize.

None
format_name str | None

The name of the deserialization format.

None
Source code in pyvider/cty/exceptions/encoding.py
def __init__(
    self,
    message: str,
    data: object = None,
    format_name: str | None = None,
    **kwargs: Any,
) -> None:
    """
    Initializes the DeserializationError.

    Args:
        message: The base error message.
        data: The data that failed to deserialize.
        format_name: The name of the deserialization format.
    """
    # Add deserialization-specific context
    context: dict[str, Any] = kwargs.setdefault("context", {})
    context["cty.serialization_direction"] = "deserialize"

    if data is not None:
        if hasattr(data, "__len__"):
            data_with_len = cast(list[Any] | dict[Any, Any] | str | bytes, data)
            context["cty.deserialized_data_size"] = len(data_with_len)
        else:
            context["cty.deserialized_data_size"] = "unknown"

    super().__init__(message, data, format_name, **kwargs)
Functions

DynamicValueError

DynamicValueError(message: str, value: object = None)

Bases: SerializationError

Raised when there's an error encoding or decoding a DynamicValue.

This exception is specific to the handling of dynamic values in serialization contexts, where type information might be unknown or ambiguous.

Attributes:

Name Type Description
message

A human-readable error description

value

The dynamic value that caused the error

Initializes the DynamicValueError.

Parameters:

Name Type Description Default
message str

The base error message.

required
value object

The dynamic value that caused the error.

None
Source code in pyvider/cty/exceptions/encoding.py
def __init__(self, message: str, value: object = None) -> None:
    """
    Initializes the DynamicValueError.

    Args:
        message: The base error message.
        value: The dynamic value that caused the error.
    """
    super().__init__(message, value, "DynamicValue")
Functions

EncodingError

EncodingError(
    message: str,
    data: object = None,
    encoding: str | None = None,
    **kwargs: Any
)

Bases: CtyError

Base exception for all encoding/serialization errors.

This exception serves as the parent class for more specific errors related to serialization and deserialization of Cty values.

Attributes:

Name Type Description
message

A human-readable error description

data

The data that caused the encoding error

encoding

The name of the encoding format that was being used

Initializes the EncodingError.

Parameters:

Name Type Description Default
message str

The base error message.

required
data object

The data that was being encoded/decoded when the error occurred.

None
encoding str | None

The name of the encoding format (e.g., "json", "msgpack").

None
Source code in pyvider/cty/exceptions/encoding.py
def __init__(
    self,
    message: str,
    data: object = None,
    encoding: str | None = None,
    **kwargs: Any,
) -> None:
    """
    Initializes the EncodingError.

    Args:
        message: The base error message.
        data: The data that was being encoded/decoded when the error occurred.
        encoding: The name of the encoding format (e.g., "json", "msgpack").
    """
    self.data = data
    self.encoding = encoding
    # Store original message if subclasses want to modify it AFTER super call
    self._original_message = message

    # Add encoding context
    context: dict[str, Any] = kwargs.setdefault("context", {})
    context["cty.error_category"] = "encoding"
    context["cty.operation"] = "serialization"

    if encoding:
        context["cty.encoding_format"] = encoding
        context["encoding.format"] = encoding

    if data is not None:
        context["cty.data_type"] = type(data).__name__
        # Safe data representation for debugging
        try:
            data_repr = repr(data)
            context["encoding.data_preview"] = (
                data_repr[:100] + "..." if len(data_repr) > 100 else data_repr
            )
        except Exception:
            context["encoding.data_preview"] = f"<repr failed for {type(data).__name__}>"

    # Add format information to the message if available
    if encoding is not None and not message.strip().startswith(encoding.upper()):
        # Avoid double-prefixing if subclass already added it
        message = f"{encoding.upper()} encoding error: {message}"

    super().__init__(message, **kwargs)
Functions

InvalidTypeError

InvalidTypeError(
    message: str, invalid_type: object = None, **kwargs: Any
)

Bases: CtyError

Raised when an invalid type is used in a type definition.

This exception occurs when attempting to create a type with invalid parameters or constraints, such as using a non-CtyType instance when a CtyType is required.

Attributes:

Name Type Description
message

A human-readable error description

invalid_type

The invalid type that caused the error

Initializes the InvalidTypeError.

Parameters:

Name Type Description Default
message str

The base error message.

required
invalid_type object

The type object that was found to be invalid.

None
Source code in pyvider/cty/exceptions/encoding.py
def __init__(self, message: str, invalid_type: object = None, **kwargs: Any) -> None:
    """
    Initializes the InvalidTypeError.

    Args:
        message: The base error message.
        invalid_type: The type object that was found to be invalid.
    """
    self.invalid_type = invalid_type

    # Add type validation context
    context: dict[str, Any] = kwargs.setdefault("context", {})
    context["cty.error_category"] = "invalid_type"
    context["cty.validation_stage"] = "type_definition"

    if invalid_type is not None:
        context["cty.invalid_type"] = type(invalid_type).__name__
        context["cty.invalid_type_str"] = str(invalid_type)[:100]  # Truncated for safety

    super().__init__(message, **kwargs)
Functions

JsonEncodingError

JsonEncodingError(
    message: str,
    data: object = None,
    operation: str | None = None,
)

Bases: EncodingError

Raised when JSON encoding or decoding fails.

This exception provides specific context for JSON serialization errors, including details about the specific JSON operation that failed.

Attributes:

Name Type Description
message

A human-readable error description

data

The data that caused the encoding error

operation

The operation that failed (encode/decode)

Initializes the JsonEncodingError.

Parameters:

Name Type Description Default
message str

The base error message.

required
data object

The data involved in the JSON operation.

None
operation str | None

The JSON operation that failed (e.g., "encode", "decode").

None
Source code in pyvider/cty/exceptions/encoding.py
def __init__(self, message: str, data: object = None, operation: str | None = None) -> None:
    """
    Initializes the JsonEncodingError.

    Args:
        message: The base error message.
        data: The data involved in the JSON operation.
        operation: The JSON operation that failed (e.g., "encode", "decode").
    """
    self.operation = operation
    # Pass original message, data, and "json" as encoding to EncodingError
    super().__init__(message, data, "json")
    # Now, self.args[0] is "JSON encoding error: {message}"
    # Prepend operation part if it exists
    if operation and self.encoding:
        current_message = str(self.args[0]) if self.args else ""
        # Remove the "JSON encoding error: " part, add op, then re-add prefix
        base_message = current_message.replace(f"{self.encoding.upper()} encoding error: ", "", 1)
        formatted_message = f"{self.encoding.upper()} {operation} error: {base_message}"
        self.args = (formatted_message, *self.args[1:])
Functions

MsgPackEncodingError

MsgPackEncodingError(
    message: str,
    data: object = None,
    operation: str | None = None,
)

Bases: EncodingError

Raised when MessagePack encoding or decoding fails.

This exception provides specific context for MessagePack serialization errors, including details about the specific MessagePack operation that failed.

Attributes:

Name Type Description
message

A human-readable error description

data

The data that caused the encoding error

operation

The operation that failed (encode/decode)

Initializes the MsgPackEncodingError.

Parameters:

Name Type Description Default
message str

The base error message.

required
data object

The data involved in the MessagePack operation.

None
operation str | None

The MessagePack operation that failed (e.g., "encode", "decode").

None
Source code in pyvider/cty/exceptions/encoding.py
def __init__(self, message: str, data: object = None, operation: str | None = None) -> None:
    """
    Initializes the MsgPackEncodingError.

    Args:
        message: The base error message.
        data: The data involved in the MessagePack operation.
        operation: The MessagePack operation that failed (e.g., "encode", "decode").
    """
    self.operation = operation
    super().__init__(message, data, "msgpack")
    if operation and self.encoding:
        current_message = str(self.args[0]) if self.args else ""
        base_message = current_message.replace(f"{self.encoding.upper()} encoding error: ", "", 1)
        formatted_message = f"{self.encoding.upper()} {operation} error: {base_message}"
        self.args = (formatted_message, *self.args[1:])
Functions

SerializationError

SerializationError(
    message: str,
    value: object = None,
    format_name: str | None = None,
    **kwargs: Any
)

Bases: EncodingError

Raised when serialization of a value fails.

This exception occurs when a Cty value cannot be serialized to a particular format, such as when a value contains types that aren't supported by the serialization format.

Attributes:

Name Type Description
message

A human-readable error description

value

The value that failed to serialize

format_name

The name of the format that was being used

Initializes the SerializationError.

Parameters:

Name Type Description Default
message str

The base error message.

required
value object

The value that failed to serialize.

None
format_name str | None

The name of the serialization format.

None
Source code in pyvider/cty/exceptions/encoding.py
def __init__(
    self,
    message: str,
    value: object = None,
    format_name: str | None = None,
    **kwargs: Any,
) -> None:
    """
    Initializes the SerializationError.

    Args:
        message: The base error message.
        value: The value that failed to serialize.
        format_name: The name of the serialization format.
    """
    self.value = value

    # Add serialization-specific context
    context: dict[str, Any] = kwargs.setdefault("context", {})
    context["cty.serialization_direction"] = "serialize"

    if value is not None and hasattr(value, "type"):
        context["cty.serialized_cty_type"] = str(value.type)
        if hasattr(value, "is_null"):
            context["cty.serialized_is_null"] = value.is_null

    super().__init__(message, value, format_name, **kwargs)
Functions

TransformationError

TransformationError(
    message: str,
    schema: object = None,
    target_type: object = None,
    **kwargs: object
)

Bases: CtyError

Raised when a schema transformation fails.

This exception occurs when a schema cannot be transformed from one representation to another, such as during conversion between different schema formats or when applying schema transformations.

Attributes:

Name Type Description
message

A human-readable error description

schema

The schema that failed transformation

target_type

The intended target type of a transformation, if applicable

Initializes the TransformationError.

Parameters:

Name Type Description Default
message str

The base error message.

required
schema object

The schema object that was being transformed.

None
target_type object

The intended target type of the transformation.

None
**kwargs object

Additional keyword arguments for foundation error context.

{}
Source code in pyvider/cty/exceptions/encoding.py
def __init__(
    self,
    message: str,
    schema: object = None,
    target_type: object = None,
    **kwargs: object,
) -> None:
    """
    Initializes the TransformationError.

    Args:
        message: The base error message.
        schema: The schema object that was being transformed.
        target_type: The intended target type of the transformation.
        **kwargs: Additional keyword arguments for foundation error context.
    """
    self.schema = schema
    self.target_type = target_type

    # Add rich transformation context
    # kwargs.setdefault returns object, but we know it's dict[str, Any]
    context: dict[str, Any] = kwargs.setdefault("context", {})  # type: ignore[assignment]
    context["cty.operation"] = "schema_transformation"
    context["cty.error_category"] = "transformation"

    if schema is not None:
        context["transformation.schema_type"] = type(schema).__name__
        context["cty.source_schema_type"] = type(schema).__name__

    if target_type is not None:
        target_name = getattr(target_type, "__name__", str(target_type))
        context["transformation.target_type"] = target_name
        context["cty.target_type"] = target_name

    context_parts = []
    if schema is not None:
        context_parts.append(f"schema_type={type(schema).__name__}")
    if target_type is not None:
        target_type_name = getattr(target_type, "__name__", str(target_type))
        context_parts.append(f"target_type={target_type_name}")

    if context_parts:
        message = f"{message} ({', '.join(context_parts)})"

    super().__init__(message, **kwargs)
Functions

WireFormatError

WireFormatError(
    message: str,
    *,
    format_type: object = None,
    operation: str | None = None,
    **kwargs: object
)

Bases: TransformationError

Raised when wire format encoding or decoding fails.

This exception is specific to the wire format system and provides additional context about the operation that failed.

Attributes:

Name Type Description
message

A human-readable error description

format_type

The wire format type that encountered an error

operation

The operation that failed (marshal/unmarshal)

Initializes the WireFormatError.

Parameters:

Name Type Description Default
message str

The base error message.

required
format_type object

The wire format type that encountered the error.

None
operation str | None

The wire format operation that failed (e.g., "marshal", "unmarshal").

None
**kwargs object

Additional arguments for the parent TransformationError.

{}
Source code in pyvider/cty/exceptions/encoding.py
def __init__(
    self,
    message: str,
    *,
    format_type: object = None,
    operation: str | None = None,
    **kwargs: object,  # Catches schema, target_type for TransformationError
) -> None:
    """
    Initializes the WireFormatError.

    Args:
        message: The base error message.
        format_type: The wire format type that encountered the error.
        operation: The wire format operation that failed (e.g., "marshal", "unmarshal").
        **kwargs: Additional arguments for the parent TransformationError.
    """
    self.format_type = format_type
    self.operation = operation

    # Initialize TransformationError with the original message and its specific args
    super().__init__(message, schema=kwargs.get("schema"), target_type=kwargs.get("target_type"))

    # self.args[0] now contains message possibly formatted by TransformationError
    # Append WireFormatError specific details to it
    current_message = str(self.args[0]) if self.args else ""

    if format_type is not None:
        format_info = f" using {format_type}"
        if operation:
            format_info = f" during {operation}{format_info}"
        current_message = f"{current_message}{format_info}"
    elif operation:  # Only operation is present, no format_type
        current_message = f"{current_message} during {operation}"

    self.args = (current_message, *self.args[1:])
Functions