Files
deepset-ai--haystack/haystack/components/agents/state/state_utils.py
T
wehub-resource-sync c56bef871b
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
Docker image release / Build base image (push) Has been cancelled
Sync docs with Docusaurus / sync (push) Has been cancelled
Tests / Check if changed (push) Has been cancelled
Tests / format (push) Has been cancelled
Tests / check-imports (push) Has been cancelled
Tests / Unit / macos-latest (push) Has been cancelled
Tests / Unit / ubuntu-latest (push) Has been cancelled
Tests / Unit / windows-latest (push) Has been cancelled
Tests / mypy (push) Has been cancelled
Tests / Integration / ubuntu-latest (push) Has been cancelled
Tests / Integration / macos-latest (push) Has been cancelled
Tests / Integration / windows-latest (push) Has been cancelled
Tests / notify-slack-on-failure (push) Has been cancelled
Tests / Mark tests as completed (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:22:28 +08:00

87 lines
2.8 KiB
Python

# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
#
# SPDX-License-Identifier: Apache-2.0
import inspect
from typing import Any, TypeVar, Union, get_origin
from haystack.utils.type_serialization import _is_union_type
T = TypeVar("T")
def _is_valid_type(obj: Any) -> bool:
"""
Check if an object is a valid type annotation.
Valid types include:
- Normal classes (str, dict, CustomClass)
- Generic types (list[str], dict[str, int])
- Union types (Union[str, int], Optional[str], str | int, str | None)
:param obj: The object to check
:return: True if the object is a valid type annotation, False otherwise
Example usage:
# >> _is_valid_type(str)
# >> True
# >> _is_valid_type(list[int])
# >> True
# >> _is_valid_type(Union[str, int])
# >> True
# >> _is_valid_type(str | int)
# >> True
# >> _is_valid_type(42)
# >> False
"""
# Handle Union types (including Optional)
if (origin := get_origin(obj)) and _is_union_type(origin):
return True
# Bare Union type (without parameters) is not a valid type annotation
# Previously handled by inspect.isclass(obj) but in python 3.14 this returns True for typing.Union
if obj == Union:
return False
# Handle normal classes and generic types
return inspect.isclass(obj) or type(obj).__name__ in {"_GenericAlias", "GenericAlias"}
def _is_list_type(type_hint: Any) -> bool:
"""
Check if a type hint represents a list type.
:param type_hint: The type hint to check
:return: True if the type hint represents a list, False otherwise
"""
return type_hint == list or (hasattr(type_hint, "__origin__") and get_origin(type_hint) == list)
def merge_lists(current: Union[list[T], T, None], new: Union[list[T], T]) -> list[T]:
"""
Merges two values into a single list.
If either `current` or `new` is not already a list, it is converted into one.
The function ensures that both inputs are treated as lists and concatenates them.
If `current` is None, it is treated as an empty list.
:param current: The existing value(s), either a single item or a list.
:param new: The new value(s) to merge, either a single item or a list.
:return: A list containing elements from both `current` and `new`.
"""
current_list = [] if current is None else current if isinstance(current, list) else [current]
new_list = new if isinstance(new, list) else [new]
return current_list + new_list
def replace_values(current: Any, new: Any) -> Any: # noqa: ARG001
"""
Replace the `current` value with the `new` value.
:param current: The existing value
:param new: The new value to replace
:return: The new value
"""
return new