Skip to content

Commit 5f3c37d

Browse files
abdokasebanakin87
andauthored
chore: adopt PEP 585 type hints (#9678)
* chore(lint): enforce and apply PEP 585 type hinting * Run fmt fixes * Fix all typing imports using some regex * Fix all typing written in string in tests * undo changes in the e2e tests * make e2e test use list instead of List * type fixes * remove type:ignore * pylint * Remove typing from Usage example comments * Remove typing from most of comments * try to fix e2e tests on comm PRs * fix * Add tests typing.List in to adjust test compatiplity - test/components/agents/test_state_class.py - test/components/converters/test_output_adapter.py - test/components/joiners/test_list_joiner.py * simplify pyproject * improve relnote --------- Co-authored-by: anakin87 <stefanofiorucci@gmail.com>
1 parent 4b9fb20 commit 5f3c37d

227 files changed

Lines changed: 2092 additions & 2005 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/utils/check_imports.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
import sys
44
import traceback
55
from pathlib import Path
6-
from typing import List, Optional
6+
from typing import Optional
77

88
from haystack import logging # pylint: disable=unused-import # this is needed to avoid circular imports
99

1010

11-
def validate_module_imports(root_dir: str, exclude_subdirs: Optional[List[str]] = None) -> tuple[list, list]:
11+
def validate_module_imports(root_dir: str, exclude_subdirs: Optional[list[str]] = None) -> tuple[list, list]:
1212
"""
1313
Recursively search for all Python modules and attempt to import them.
1414

.github/utils/delete_outdated_docs.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import os
44
import re
55
from pathlib import Path
6-
from typing import List
76

87
import requests
98
import yaml
@@ -30,7 +29,7 @@ def create_headers(version: str):
3029
return {"authorization": f"Basic {readme_token()}", "x-readme-version": version}
3130

3231

33-
def get_docs_in_category(category_slug: str, version: str) -> List[str]:
32+
def get_docs_in_category(category_slug: str, version: str) -> list[str]:
3433
"""
3534
Returns the slugs of all documents in a category for the specific version.
3635
"""

e2e/pipelines/test_dense_doc_search.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
from haystack.document_stores.in_memory import InMemoryDocumentStore
1616

1717

18-
def test_dense_doc_search_pipeline(tmp_path, samples_path):
18+
def test_dense_doc_search_pipeline(tmp_path, samples_path, monkeypatch):
19+
monkeypatch.delenv("HF_API_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
20+
monkeypatch.delenv("HF_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
21+
1922
# Create the indexing pipeline
2023
indexing_pipeline = Pipeline()
2124
indexing_pipeline.add_component(

e2e/pipelines/test_evaluation_pipeline.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
# SPDX-License-Identifier: Apache-2.0
44

55
import os
6-
from typing import List
76

87
import pytest
98

@@ -30,7 +29,7 @@
3029
EMBEDDINGS_MODEL = "sentence-transformers/all-MiniLM-L6-v2"
3130

3231

33-
def indexing_pipeline(documents: List[Document]):
32+
def indexing_pipeline(documents: list[Document]):
3433
"""Indexing the documents"""
3534
document_store = InMemoryDocumentStore()
3635
doc_writer = DocumentWriter(document_store=document_store, policy=DuplicatePolicy.SKIP)

e2e/pipelines/test_extractive_qa_pipeline.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
from haystack.document_stores.in_memory import InMemoryDocumentStore
99

1010

11-
def test_extractive_qa_pipeline(tmp_path):
11+
def test_extractive_qa_pipeline(tmp_path, monkeypatch):
12+
monkeypatch.delenv("HF_API_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
13+
monkeypatch.delenv("HF_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
14+
1215
# Create the pipeline
1316
qa_pipeline = Pipeline()
1417
qa_pipeline.add_component(instance=InMemoryBM25Retriever(document_store=InMemoryDocumentStore()), name="retriever")

e2e/pipelines/test_hybrid_doc_search_pipeline.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
from haystack.document_stores.in_memory import InMemoryDocumentStore
1212

1313

14-
def test_hybrid_doc_search_pipeline(tmp_path):
14+
def test_hybrid_doc_search_pipeline(tmp_path, monkeypatch):
15+
monkeypatch.delenv("HF_API_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
16+
monkeypatch.delenv("HF_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
17+
1518
# Create the pipeline
1619
document_store = InMemoryDocumentStore()
1720
hybrid_pipeline = Pipeline()

e2e/pipelines/test_named_entity_extractor.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ def spacy_annotations():
4747
]
4848

4949

50-
def test_ner_extractor_init():
50+
def test_ner_extractor_init(monkeypatch):
51+
monkeypatch.delenv("HF_API_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
52+
monkeypatch.delenv("HF_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
53+
5154
extractor = NamedEntityExtractor(backend=NamedEntityExtractorBackend.HUGGING_FACE, model="dslim/bert-base-NER")
5255

5356
with pytest.raises(RuntimeError, match=r"not warmed up"):
@@ -59,7 +62,10 @@ def test_ner_extractor_init():
5962

6063

6164
@pytest.mark.parametrize("batch_size", [1, 3])
62-
def test_ner_extractor_hf_backend(raw_texts, hf_annotations, batch_size):
65+
def test_ner_extractor_hf_backend(raw_texts, hf_annotations, batch_size, monkeypatch):
66+
monkeypatch.delenv("HF_API_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
67+
monkeypatch.delenv("HF_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
68+
6369
extractor = NamedEntityExtractor(backend=NamedEntityExtractorBackend.HUGGING_FACE, model="dslim/bert-base-NER")
6470
extractor.warm_up()
6571

@@ -87,7 +93,10 @@ def test_ner_extractor_spacy_backend(raw_texts, spacy_annotations, batch_size):
8793

8894

8995
@pytest.mark.parametrize("batch_size", [1, 3])
90-
def test_ner_extractor_in_pipeline(raw_texts, hf_annotations, batch_size):
96+
def test_ner_extractor_in_pipeline(raw_texts, hf_annotations, batch_size, monkeypatch):
97+
monkeypatch.delenv("HF_API_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
98+
monkeypatch.delenv("HF_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
99+
91100
pipeline = Pipeline()
92101
pipeline.add_component(
93102
name="ner_extractor",

e2e/pipelines/test_pdf_content_extraction_pipeline.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
#
33
# SPDX-License-Identifier: Apache-2.0
44

5+
import os
6+
7+
import pytest
8+
59
from haystack import Pipeline
610
from haystack.components.converters.pypdf import PyPDFToDocument
711
from haystack.components.joiners import DocumentJoiner
@@ -13,6 +17,10 @@
1317
from haystack.components.routers.document_length_router import DocumentLengthRouter
1418

1519

20+
@pytest.mark.skipif(
21+
not os.environ.get("OPENAI_API_KEY", None),
22+
reason="Export an env var called OPENAI_API_KEY containing the OpenAI API key to run this test.",
23+
)
1624
def test_pdf_content_extraction_pipeline():
1725
"""
1826
Test a pipeline that processes PDFs with the following steps:

e2e/pipelines/test_preprocessing_pipeline.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
from haystack.document_stores.in_memory import InMemoryDocumentStore
1313

1414

15-
def test_preprocessing_pipeline(tmp_path):
15+
def test_preprocessing_pipeline(tmp_path, monkeypatch):
16+
monkeypatch.delenv("HF_API_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
17+
monkeypatch.delenv("HF_TOKEN", raising=False) # https://github.com/deepset-ai/haystack/issues/8811
18+
1619
# Create the pipeline and its components
1720
document_store = InMemoryDocumentStore()
1821
preprocessing_pipeline = Pipeline()

haystack/components/agents/agent.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# SPDX-License-Identifier: Apache-2.0
44

55
import inspect
6-
from typing import Any, Dict, List, Optional, Union
6+
from typing import Any, Optional, Union
77

88
from haystack import logging, tracing
99
from haystack.components.generators.chat.types import ChatGenerator
@@ -71,14 +71,14 @@ def __init__(
7171
self,
7272
*,
7373
chat_generator: ChatGenerator,
74-
tools: Optional[Union[List[Tool], Toolset]] = None,
74+
tools: Optional[Union[list[Tool], Toolset]] = None,
7575
system_prompt: Optional[str] = None,
76-
exit_conditions: Optional[List[str]] = None,
77-
state_schema: Optional[Dict[str, Any]] = None,
76+
exit_conditions: Optional[list[str]] = None,
77+
state_schema: Optional[dict[str, Any]] = None,
7878
max_agent_steps: int = 100,
7979
streaming_callback: Optional[StreamingCallbackT] = None,
8080
raise_on_tool_invocation_failure: bool = False,
81-
tool_invoker_kwargs: Optional[Dict[str, Any]] = None,
81+
tool_invoker_kwargs: Optional[dict[str, Any]] = None,
8282
) -> None:
8383
"""
8484
Initialize the agent component.
@@ -126,7 +126,7 @@ def __init__(
126126
# Initialize state schema
127127
resolved_state_schema = _deepcopy_with_exceptions(self._state_schema)
128128
if resolved_state_schema.get("messages") is None:
129-
resolved_state_schema["messages"] = {"type": List[ChatMessage], "handler": merge_lists}
129+
resolved_state_schema["messages"] = {"type": list[ChatMessage], "handler": merge_lists}
130130
self.state_schema = resolved_state_schema
131131

132132
self.chat_generator = chat_generator
@@ -172,7 +172,7 @@ def warm_up(self) -> None:
172172
self.chat_generator.warm_up()
173173
self._is_warmed_up = True
174174

175-
def to_dict(self) -> Dict[str, Any]:
175+
def to_dict(self) -> dict[str, Any]:
176176
"""
177177
Serialize the component to a dictionary.
178178
@@ -198,7 +198,7 @@ def to_dict(self) -> Dict[str, Any]:
198198
)
199199

200200
@classmethod
201-
def from_dict(cls, data: Dict[str, Any]) -> "Agent":
201+
def from_dict(cls, data: dict[str, Any]) -> "Agent":
202202
"""
203203
Deserialize the agent from a dictionary.
204204
@@ -219,9 +219,9 @@ def from_dict(cls, data: Dict[str, Any]) -> "Agent":
219219

220220
return default_from_dict(cls, data)
221221

222-
def _prepare_generator_inputs(self, streaming_callback: Optional[StreamingCallbackT] = None) -> Dict[str, Any]:
222+
def _prepare_generator_inputs(self, streaming_callback: Optional[StreamingCallbackT] = None) -> dict[str, Any]:
223223
"""Prepare inputs for the chat generator."""
224-
generator_inputs: Dict[str, Any] = {"tools": self.tools}
224+
generator_inputs: dict[str, Any] = {"tools": self.tools}
225225
if streaming_callback is not None:
226226
generator_inputs["streaming_callback"] = streaming_callback
227227
return generator_inputs
@@ -240,13 +240,13 @@ def _create_agent_span(self) -> Any:
240240

241241
def run( # noqa: PLR0915
242242
self,
243-
messages: List[ChatMessage],
243+
messages: list[ChatMessage],
244244
streaming_callback: Optional[StreamingCallbackT] = None,
245245
*,
246246
break_point: Optional[AgentBreakpoint] = None,
247247
snapshot: Optional[AgentSnapshot] = None,
248248
**kwargs: Any,
249-
) -> Dict[str, Any]:
249+
) -> dict[str, Any]:
250250
"""
251251
Process messages and execute tools until an exit condition is met.
252252
@@ -431,13 +431,13 @@ def run( # noqa: PLR0915
431431

432432
async def run_async( # noqa: PLR0915
433433
self,
434-
messages: List[ChatMessage],
434+
messages: list[ChatMessage],
435435
streaming_callback: Optional[StreamingCallbackT] = None,
436436
*,
437437
break_point: Optional[AgentBreakpoint] = None,
438438
snapshot: Optional[AgentSnapshot] = None,
439439
**kwargs: Any,
440-
) -> Dict[str, Any]:
440+
) -> dict[str, Any]:
441441
"""
442442
Asynchronously process messages and execute tools until the exit condition is met.
443443
@@ -626,7 +626,7 @@ async def run_async( # noqa: PLR0915
626626
result.update({"last_message": all_messages[-1]})
627627
return result
628628

629-
def _check_exit_conditions(self, llm_messages: List[ChatMessage], tool_messages: List[ChatMessage]) -> bool:
629+
def _check_exit_conditions(self, llm_messages: list[ChatMessage], tool_messages: list[ChatMessage]) -> bool:
630630
"""
631631
Check if any of the LLM messages' tool calls match an exit condition and if there are no errors.
632632

0 commit comments

Comments
 (0)