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
87 lines
2.8 KiB
Python
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
|