Skip to content

types

pyvider.hcl.factories.types

HCL type string parsing for Terraform type syntax.

Classes

HclTypeParsingError

Bases: ValueError

Custom exception for errors during HCL type string parsing.

Functions

parse_hcl_type_string

parse_hcl_type_string(type_str: str) -> CtyType[Any]

Parse HCL type string into CTY type.

Supports: - Primitives: string, number, bool, any - Lists: list(element_type) - Maps: map(element_type) - Objects: object({attr=type, ...})

Parameters:

Name Type Description Default
type_str str

HCL type string (e.g., "list(string)", "object({name=string})")

required

Returns:

Type Description
CtyType[Any]

Corresponding CTY type

Raises:

Type Description
HclTypeParsingError

If type string is malformed

Example

parse_hcl_type_string("list(string)") CtyList(element_type=CtyString())

Source code in pyvider/hcl/factories/types.py
def parse_hcl_type_string(type_str: str) -> CtyType[Any]:  # noqa: C901
    """Parse HCL type string into CTY type.

    Supports:
    - Primitives: string, number, bool, any
    - Lists: list(element_type)
    - Maps: map(element_type)
    - Objects: object({attr=type, ...})

    Args:
        type_str: HCL type string (e.g., "list(string)", "object({name=string})")

    Returns:
        Corresponding CTY type

    Raises:
        HclTypeParsingError: If type string is malformed

    Example:
        >>> parse_hcl_type_string("list(string)")
        CtyList(element_type=CtyString())
    """
    type_str = type_str.strip()

    if type_str.lower() in PRIMITIVE_TYPE_MAP:
        return PRIMITIVE_TYPE_MAP[type_str.lower()]

    match = COMPLEX_TYPE_REGEX.match(type_str)
    if not match:
        raise HclTypeParsingError(f"Unknown or malformed type string: '{type_str}'")

    type_keyword = match.group(1).lower()
    inner_content = match.group(2).strip()

    if type_keyword == "list":
        if not inner_content:
            raise HclTypeParsingError("List type string is empty, e.g., 'list()'")
        element_type = parse_hcl_type_string(inner_content)
        return CtyList(element_type=element_type)

    if type_keyword == "map":
        if not inner_content:
            raise HclTypeParsingError("Map type string is empty, e.g., 'map()'")
        element_type = parse_hcl_type_string(inner_content)
        return CtyMap(element_type=element_type)

    if type_keyword == "object":
        if not inner_content.startswith("{") or not inner_content.endswith("}"):
            raise HclTypeParsingError(
                f"Object type string content must be enclosed in {{}}, got: '{inner_content}'"
            )
        if inner_content == "{}":
            return CtyObject({})

        attrs_str = inner_content[1:-1].strip()
        if not attrs_str:
            return CtyObject({})

        attributes = _parse_object_attributes_str(attrs_str)
        return CtyObject(attributes)

    raise HclTypeParsingError(f"Unhandled type keyword: '{type_keyword}'")