• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

deepset-ai / haystack / 9568249476

18 Jun 2024 03:52PM UTC coverage: 89.872% (-0.1%) from 89.995%
9568249476

push

github

web-flow
ci: Add code formatting checks  (#7882)

* ruff settings

enable ruff format and re-format outdated files

feat: `EvaluationRunResult` add parameter to specify columns to keep in the comparative `Dataframe`  (#7879)

* adding param to explictily state which cols to keep

* adding param to explictily state which cols to keep

* adding param to explictily state which cols to keep

* updating tests

* adding release notes

* Update haystack/evaluation/eval_run_result.py

Co-authored-by: Madeesh Kannan <shadeMe@users.noreply.github.com>

* Update releasenotes/notes/add-keep-columns-to-EvalRunResult-comparative-be3e15ce45de3e0b.yaml

Co-authored-by: Madeesh Kannan <shadeMe@users.noreply.github.com>

* updating docstring

---------

Co-authored-by: Madeesh Kannan <shadeMe@users.noreply.github.com>

add format-check

fail on format and linting failures

fix string formatting

reformat long lines

fix tests

fix typing

linter

pull from main

* reformat

* lint -> check

* lint -> check

6957 of 7741 relevant lines covered (89.87%)

0.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.58
haystack/utils/type_serialization.py
1
# SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
2
#
3
# SPDX-License-Identifier: Apache-2.0
4

5
import importlib
1✔
6
import inspect
1✔
7
import sys
1✔
8
import typing
1✔
9
from typing import Any, get_args, get_origin
1✔
10

11
from haystack import DeserializationError
1✔
12

13

14
def serialize_type(target: Any) -> str:
1✔
15
    """
16
    Serializes a type or an instance to its string representation, including the module name.
17

18
    This function handles types, instances of types, and special typing objects.
19
    It assumes that non-typing objects will have a '__name__' attribute and raises
20
    an error if a type cannot be serialized.
21

22
    :param target:
23
        The object to serialize, can be an instance or a type.
24
    :return:
25
        The string representation of the type.
26
    :raises ValueError:
27
        If the type cannot be serialized.
28
    """
29
    # If the target is a string and contains a dot, treat it as an already serialized type
30
    if isinstance(target, str) and "." in target:
1✔
31
        return target
1✔
32

33
    # Determine if the target is a type or an instance of a typing object
34
    is_type_or_typing = isinstance(target, type) or bool(get_origin(target))
1✔
35
    type_obj = target if is_type_or_typing else type(target)
1✔
36
    type_obj_repr = repr(type_obj)
1✔
37

38
    if type_obj_repr.startswith("typing."):
1✔
39
        # e.g., typing.List[int] -> List[int], we'll add the module below
40
        type_name = type_obj_repr.split(".", 1)[1]
1✔
41
    elif origin := get_origin(type_obj):  # get the origin (base type of the parameterized generic type)
1✔
42
        # get the arguments of the generic type
43
        args = get_args(type_obj)
×
44
        args_repr = ", ".join(serialize_type(arg) for arg in args)
×
45
        type_name = f"{origin.__name__}[{args_repr}]"
×
46
    elif hasattr(type_obj, "__name__"):
1✔
47
        type_name = type_obj.__name__
1✔
48
    else:
49
        # If type cannot be serialized, raise an error
50
        raise ValueError(f"Could not serialize type: {type_obj_repr}")
×
51

52
    module = inspect.getmodule(type_obj)
1✔
53
    if module and hasattr(module, "__name__"):
1✔
54
        if module.__name__ == "builtins":
1✔
55
            # omit the module name for builtins, it just clutters the output
56
            # e.g. instead of 'builtins.str', we'll just return 'str'
57
            full_path = type_name
1✔
58
        else:
59
            full_path = f"{module.__name__}.{type_name}"
1✔
60
    else:
61
        full_path = type_name
×
62

63
    return full_path
1✔
64

65

66
def deserialize_type(type_str: str) -> Any:
1✔
67
    """
68
    Deserializes a type given its full import path as a string, including nested generic types.
69

70
    This function will dynamically import the module if it's not already imported
71
    and then retrieve the type object from it. It also handles nested generic types like
72
    `typing.List[typing.Dict[int, str]]`.
73

74
    :param type_str:
75
        The string representation of the type's full import path.
76
    :returns:
77
        The deserialized type object.
78
    :raises DeserializationError:
79
        If the type cannot be deserialized due to missing module or type.
80
    """
81

82
    type_mapping = {
1✔
83
        list: typing.List,
84
        dict: typing.Dict,
85
        set: typing.Set,
86
        tuple: typing.Tuple,
87
        frozenset: typing.FrozenSet,
88
    }
89

90
    def parse_generic_args(args_str):
1✔
91
        args = []
1✔
92
        bracket_count = 0
1✔
93
        current_arg = ""
1✔
94

95
        for char in args_str:
1✔
96
            if char == "[":
1✔
97
                bracket_count += 1
1✔
98
            elif char == "]":
1✔
99
                bracket_count -= 1
1✔
100

101
            if char == "," and bracket_count == 0:
1✔
102
                args.append(current_arg.strip())
1✔
103
                current_arg = ""
1✔
104
            else:
105
                current_arg += char
1✔
106

107
        if current_arg:
1✔
108
            args.append(current_arg.strip())
1✔
109

110
        return args
1✔
111

112
    if "[" in type_str and type_str.endswith("]"):
1✔
113
        # Handle generics
114
        main_type_str, generics_str = type_str.split("[", 1)
1✔
115
        generics_str = generics_str[:-1]
1✔
116

117
        main_type = deserialize_type(main_type_str)
1✔
118
        generic_args = tuple(deserialize_type(arg) for arg in parse_generic_args(generics_str))
1✔
119

120
        # Reconstruct
121
        if sys.version_info >= (3, 9) or repr(main_type).startswith("typing."):
1✔
122
            return main_type[generic_args]
1✔
123
        else:
124
            return type_mapping[main_type][generic_args]  # type: ignore
×
125

126
    else:
127
        # Handle non-generics
128
        parts = type_str.split(".")
1✔
129
        module_name = ".".join(parts[:-1]) or "builtins"
1✔
130
        type_name = parts[-1]
1✔
131

132
        module = sys.modules.get(module_name)
1✔
133
        if not module:
1✔
134
            try:
×
135
                module = importlib.import_module(module_name)
×
136
            except ImportError as e:
×
137
                raise DeserializationError(f"Could not import the module: {module_name}") from e
×
138

139
        deserialized_type = getattr(module, type_name, None)
1✔
140
        if not deserialized_type:
1✔
141
            raise DeserializationError(f"Could not locate the type: {type_name} in the module: {module_name}")
×
142

143
        return deserialized_type
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc