if final is None:
            final = chunk
        else:
            final = final + chunk
    return final
[docs]class ConfigurableField(NamedTuple):
    """A field that can be configured by the user."""
    id: str
    name: Optional[str] = None
    description: Optional[str] = None
    annotation: Optional[Any] = None
    is_shared: bool = False
    def __hash__(self) -> int:
        return hash((self.id, self.annotation))
[docs]class ConfigurableFieldSingleOption(NamedTuple):
    """A field that can be configured by the user with a default value."""
    id: str
    options: Mapping[str, Any]
    default: str
    name: Optional[str] = None
    description: Optional[str] = None
    is_shared: bool = False
    def __hash__(self) -> int:
        return hash((self.id, tuple(self.options.keys()), self.default))
[docs]class ConfigurableFieldMultiOption(NamedTuple):
    """A field that can be configured by the user with multiple default values."""
    id: str
    options: Mapping[str, Any]
    default: Sequence[str]
    name: Optional[str] = None
    description: Optional[str] = None
    is_shared: bool = False
    def __hash__(self) -> int:
        return hash((self.id, tuple(self.options.keys()), tuple(self.default)))
AnyConfigurableField = Union[
    ConfigurableField, ConfigurableFieldSingleOption, ConfigurableFieldMultiOption
]
[docs]class ConfigurableFieldSpec(NamedTuple):
    """A field that can be configured by the user. It is a specification of a field."""
    id: str
    annotation: Any