From 189ae6463154cd89eb25d59f4ed5dd90be7d8bf7 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Fri, 26 Jul 2024 16:14:56 +0200 Subject: [PATCH 1/2] Use python 3.11 for knowledge-graph linting --- libs/knowledge-graph/pyproject.toml | 79 ++++++++++++++++++- .../cassandra_graph_store.py | 21 ++--- .../ragstack_knowledge_graph/extraction.py | 9 ++- .../knowledge_graph.py | 25 +++--- .../knowledge_schema.py | 15 ++-- .../ragstack_knowledge_graph/render.py | 8 +- .../ragstack_knowledge_graph/runnables.py | 8 +- .../schema_inference.py | 3 +- .../ragstack_knowledge_graph/templates.py | 7 +- .../ragstack_knowledge_graph/traverse.py | 37 ++++----- .../ragstack_knowledge_graph/utils.py | 5 +- libs/knowledge-graph/tests/conftest.py | 7 +- libs/knowledge-graph/tests/test_extraction.py | 1 + .../tests/test_knowledge_graph.py | 1 + libs/knowledge-graph/tests/test_runnables.py | 1 + .../tests/test_schema_inference.py | 5 +- pyproject.toml | 3 - 17 files changed, 156 insertions(+), 79 deletions(-) diff --git a/libs/knowledge-graph/pyproject.toml b/libs/knowledge-graph/pyproject.toml index 6a23d7392..df13db0f8 100644 --- a/libs/knowledge-graph/pyproject.toml +++ b/libs/knowledge-graph/pyproject.toml @@ -61,4 +61,81 @@ warn_unused_ignores = true [tool.pytest.ini_options] testpaths = ["tests"] -asyncio_mode = "auto" \ No newline at end of file +asyncio_mode = "auto" + +[tool.ruff] +target-version = "py311" + +[tool.ruff.lint] +pydocstyle.convention = "google" +ignore = [ + "COM812", # Messes with the formatter + "D100", # Do we want to activate (docstring in module) ? + "D104", # Do we want to activate (docstring in package) ? + "D105", # Do we want to activate (docstring in magic method) ? + "D107", # Do we want to activate (docstring in __init__) ? + "ERA", # Do we want to activate (no commented code) ? + "ISC001", # Messes with the formatter + "PERF203", # Incorrect detection + "PLR09", # TODO: do we enforce these ones (complexity) ? + "TRY003", # A bit too strict ? + "TD002", # We know the TODOs authors with git. Activate anyway ? + "TD003", # Do we want to activate (TODOs with issue reference) ? +] + +select = [ + "A", + "ARG", + "ASYNC", + "B", + "BLE", + "C4", + "COM", + "D", + "DTZ", + "E", + "EXE", + "F", + "FLY", + "FURB", + "G", + "I", + "ICN", + "INP", + "INT", + "ISC", + "LOG", + "N", + "NPY", + "PD", + "PERF", + "PGH", + "PIE", + "PL", + "PT", + "PYI", + "Q", + "RET", + "RSE", + "RUF", + "S", + "SIM", + "SLF", + "SLOT", + "T10", + "T20", + "TCH", + "TD", + "TID", + "TRY", + "UP", + "W", + "YTT", +] + +[tool.ruff.lint.per-file-ignores] +"tests/*" = [ + "D", + "S101", + "T20", +] \ No newline at end of file diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/cassandra_graph_store.py b/libs/knowledge-graph/ragstack_knowledge_graph/cassandra_graph_store.py index 0141c97e3..9e920f00b 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/cassandra_graph_store.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/cassandra_graph_store.py @@ -1,4 +1,5 @@ -from typing import Any, Dict, Iterable, List, Optional, Sequence, Union +from collections.abc import Iterable, Sequence +from typing import Any from cassandra.cluster import Session from langchain_community.graphs.graph_document import GraphDocument @@ -12,7 +13,7 @@ from .traverse import Node, Relation -def _elements(documents: Iterable[GraphDocument]) -> Iterable[Union[Node, Relation]]: +def _elements(documents: Iterable[GraphDocument]) -> Iterable[Node | Relation]: def _node(node: LangChainNode) -> Node: return Node(name=str(node.id), type=node.type) @@ -32,9 +33,9 @@ def __init__( self, node_table: str = "entities", edge_table: str = "relationships", - text_embeddings: Optional[Embeddings] = None, - session: Optional[Session] = None, - keyspace: Optional[str] = None, + text_embeddings: Embeddings | None = None, + session: Session | None = None, + keyspace: str | None = None, ) -> None: """Create a Cassandra Graph Store. @@ -51,7 +52,7 @@ def __init__( @override def add_graph_documents( - self, graph_documents: List[GraphDocument], include_source: bool = False + self, graph_documents: list[GraphDocument], include_source: bool = False ) -> None: # TODO: Include source. self.graph.insert(_elements(graph_documents)) @@ -59,8 +60,8 @@ def add_graph_documents( # TODO: should this include the types of each node? @override def query( - self, query: str, params: Optional[Dict[str, Any]] = None - ) -> List[Dict[str, Any]]: + self, query: str, params: dict[str, Any] | None = None + ) -> list[dict[str, Any]]: raise ValueError("Querying Cassandra should use `as_runnable`.") @override @@ -71,7 +72,7 @@ def get_schema(self) -> str: @property @override - def get_structured_schema(self) -> Dict[str, Any]: + def get_structured_schema(self) -> dict[str, Any]: raise NotImplementedError @override @@ -80,7 +81,7 @@ def refresh_schema(self) -> None: def as_runnable( self, steps: int = 3, edge_filters: Sequence[str] = () - ) -> Runnable[Union[Node, Sequence[Node]], Iterable[Relation]]: + ) -> Runnable[Node | Sequence[Node], Iterable[Relation]]: """Convert to a runnable. Returns a runnable that retrieves the sub-graph near the input entity or diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/extraction.py b/libs/knowledge-graph/ragstack_knowledge_graph/extraction.py index 771c2b13a..f65c5f1b3 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/extraction.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/extraction.py @@ -1,4 +1,5 @@ -from typing import TYPE_CHECKING, Any, Dict, List, Sequence, Union, cast +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, cast from langchain_community.graphs.graph_document import GraphDocument from langchain_core.documents import Document @@ -47,7 +48,7 @@ def __init__( self._validator = KnowledgeSchemaValidator(schema) self.strict = strict - messages: List[MessageLikeRepresentation] = [ + messages: list[MessageLikeRepresentation] = [ SystemMessagePromptTemplate( prompt=load_template( "extraction.md", knowledge_schema_yaml=schema.to_yaml_str() @@ -73,7 +74,7 @@ def __init__( self._chain = prompt | structured_llm def _process_response( - self, document: Document, response: Union[Dict[str, Any], BaseModel] + self, document: Document, response: dict[str, Any] | BaseModel ) -> GraphDocument: raw_graph = cast(_Graph, response) nodes = ( @@ -96,7 +97,7 @@ def _process_response( return graph_document - def extract(self, documents: List[Document]) -> List[GraphDocument]: + def extract(self, documents: list[Document]) -> list[GraphDocument]: """Extract knowledge graphs from a list of documents.""" # TODO: Define an async version of extraction? responses = self._chain.batch_as_completed( diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_graph.py b/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_graph.py index fed23be7b..b726591d9 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_graph.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_graph.py @@ -1,7 +1,8 @@ import json import re +from collections.abc import Iterable, Sequence from itertools import repeat -from typing import Any, Dict, Iterable, Optional, Sequence, Tuple, Union, cast +from typing import Any, cast from cassandra.cluster import ResponseFuture, Session from cassandra.query import BatchStatement @@ -12,12 +13,12 @@ from .utils import batched -def _serialize_md_dict(md_dict: Dict[str, Any]) -> str: +def _serialize_md_dict(md_dict: dict[str, Any]) -> str: return json.dumps(md_dict, separators=(",", ":"), sort_keys=True) -def _deserialize_md_dict(md_string: str) -> Dict[str, Any]: - return cast(Dict[str, Any], json.loads(md_string)) +def _deserialize_md_dict(md_string: str) -> dict[str, Any]: + return cast(dict[str, Any], json.loads(md_string)) def _parse_node(row: Any) -> Node: @@ -52,9 +53,9 @@ def __init__( self, node_table: str = "entities", edge_table: str = "relationships", - text_embeddings: Optional[Embeddings] = None, - session: Optional[Session] = None, - keyspace: Optional[str] = None, + text_embeddings: Embeddings | None = None, + session: Session | None = None, + keyspace: str | None = None, apply_schema: bool = True, ) -> None: session = check_resolve_session(session) @@ -197,7 +198,7 @@ def query_nearest_nodes(self, nodes: Iterable[str], k: int = 1) -> Iterable[Node # TODO: Introduce `ainsert` for async insertions. def insert( self, - elements: Iterable[Union[Node, Relation]], + elements: Iterable[Node | Relation], ) -> None: """Insert the given elements into the graph.""" for batch in batched(elements, n=4): @@ -245,10 +246,10 @@ def insert( def subgraph( self, - start: Union[Node, Sequence[Node]], + start: Node | Sequence[Node], edge_filters: Sequence[str] = (), steps: int = 3, - ) -> Tuple[Iterable[Node], Iterable[Relation]]: + ) -> tuple[Iterable[Node], Iterable[Relation]]: """Retrieve the sub-graph from the given starting nodes.""" edges = self.traverse(start, edge_filters, steps) @@ -274,7 +275,7 @@ def subgraph( def traverse( self, - start: Union[Node, Sequence[Node]], + start: Node | Sequence[Node], edge_filters: Sequence[str] = (), steps: int = 3, ) -> Iterable[Relation]: @@ -306,7 +307,7 @@ def traverse( async def atraverse( self, - start: Union[Node, Sequence[Node]], + start: Node | Sequence[Node], edge_filters: Sequence[str] = (), steps: int = 3, ) -> Iterable[Relation]: diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_schema.py b/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_schema.py index 4d43c9528..6229d1ecb 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_schema.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_schema.py @@ -1,5 +1,6 @@ +from collections.abc import Sequence from pathlib import Path -from typing import Dict, List, Self, Sequence, Union +from typing import Self from langchain_community.graphs.graph_document import GraphDocument from langchain_core.pydantic_v1 import BaseModel @@ -33,10 +34,10 @@ class RelationshipSchema(BaseModel): edge_type: str """The name of the edge type for the relationhsip.""" - source_types: List[str] + source_types: list[str] """The node types for the source of the relationship.""" - target_types: List[str] + target_types: list[str] """The node types for the target of the relationship.""" description: str @@ -59,14 +60,14 @@ class Example(BaseModel): class KnowledgeSchema(BaseModel): """Schema for a knowledge graph.""" - nodes: List[NodeSchema] + nodes: list[NodeSchema] """Allowed node types for the knowledge schema.""" - relationships: List[RelationshipSchema] + relationships: list[RelationshipSchema] """Allowed relationships for the knowledge schema.""" @classmethod - def from_file(cls, path: Union[str, Path]) -> Self: + def from_file(cls, path: str | Path) -> Self: """Load a KnowledgeSchema from a JSON or YAML file. Args: @@ -91,7 +92,7 @@ def __init__(self, schema: KnowledgeSchema) -> None: self._nodes = {node.type: node for node in schema.nodes} - self._relationships: Dict[str, List[RelationshipSchema]] = {} + self._relationships: dict[str, list[RelationshipSchema]] = {} for r in schema.relationships: self._relationships.setdefault(r.edge_type, []).append(r) diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/render.py b/libs/knowledge-graph/ragstack_knowledge_graph/render.py index 5cdc3765f..1886afe5b 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/render.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/render.py @@ -1,4 +1,4 @@ -from typing import Dict, Iterable, Tuple, Union +from collections.abc import Iterable import graphviz from langchain_community.graphs.graph_document import GraphDocument, Node @@ -11,7 +11,7 @@ def _node_label(node: Node) -> str: def print_graph_documents( - graph_documents: Union[GraphDocument, Iterable[GraphDocument]], + graph_documents: GraphDocument | Iterable[GraphDocument], ) -> None: """Prints the relationships in the graph documents.""" if isinstance(graph_documents, GraphDocument): @@ -25,7 +25,7 @@ def print_graph_documents( def render_graph_documents( - graph_documents: Union[GraphDocument, Iterable[GraphDocument]], + graph_documents: GraphDocument | Iterable[GraphDocument], ) -> graphviz.Digraph: """Renders the relationships in the graph documents.""" if isinstance(graph_documents, GraphDocument): @@ -33,7 +33,7 @@ def render_graph_documents( dot = graphviz.Digraph() - nodes: Dict[Tuple[Union[str, int], str], str] = {} + nodes: dict[tuple[str | int, str], str] = {} def _node_id(node: Node) -> str: node_key = (node.id, node.type) diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/runnables.py b/libs/knowledge-graph/ragstack_knowledge_graph/runnables.py index 9ed597df5..92425fee3 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/runnables.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/runnables.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional +from typing import Any from langchain_core.language_models import BaseChatModel from langchain_core.output_parsers import JsonOutputParser @@ -25,8 +25,8 @@ def extract_entities( llm: BaseChatModel, keyword_extraction_prompt: str = QUERY_ENTITY_EXTRACT_PROMPT, - node_types: Optional[List[str]] = None, -) -> Runnable[Dict[str, Any], List[Node]]: + node_types: list[str] | None = None, +) -> Runnable[dict[str, Any], list[Node]]: """Return a keyword-extraction runnable. This will expect a dictionary containing the `"question"` to extract keywords from. @@ -59,7 +59,7 @@ class SimpleNode(BaseModel): class SimpleNodeList(BaseModel): """Represents a list of simple nodes.""" - nodes: List[SimpleNode] + nodes: list[SimpleNode] output_parser = JsonOutputParser(pydantic_object=SimpleNodeList) return ( diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/schema_inference.py b/libs/knowledge-graph/ragstack_knowledge_graph/schema_inference.py index 6c13c84c8..3b188e70e 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/schema_inference.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/schema_inference.py @@ -1,4 +1,5 @@ -from typing import Sequence, cast +from collections.abc import Sequence +from typing import cast from langchain_core.documents import Document from langchain_core.language_models.chat_models import BaseChatModel diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/templates.py b/libs/knowledge-graph/ragstack_knowledge_graph/templates.py index 7bd66f2cd..ca97233f1 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/templates.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/templates.py @@ -1,14 +1,13 @@ +from collections.abc import Callable from os import path -from typing import Callable, Union, cast +from typing import cast from langchain_core.prompts import PromptTemplate TEMPLATE_PATH = path.join(path.dirname(__file__), "prompt_templates") -def load_template( - filename: str, **kwargs: Union[str, Callable[[], str]] -) -> PromptTemplate: +def load_template(filename: str, **kwargs: str | Callable[[], str]) -> PromptTemplate: """Load a template from a file.""" template = PromptTemplate.from_file(path.join(TEMPLATE_PATH, filename)) if kwargs: diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/traverse.py b/libs/knowledge-graph/ragstack_knowledge_graph/traverse.py index 8f1bee77e..2ceaf6da1 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/traverse.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/traverse.py @@ -1,18 +1,11 @@ import asyncio import threading from asyncio import Future, Task +from collections.abc import Iterable, Sequence from typing import ( Any, - Dict, - Iterable, - List, NamedTuple, - Optional, Self, - Sequence, - Set, - Tuple, - Union, ) from cassandra.cluster import PreparedStatement, ResponseFuture, Session @@ -22,7 +15,7 @@ class _Node(NamedTuple): name: str type: str - properties: Dict[str, Any] + properties: dict[str, Any] class Node(_Node): @@ -34,7 +27,7 @@ def __new__( cls, name: str, type: str, # noqa: A002 - properties: Optional[Dict[str, Any]] = None, + properties: dict[str, Any] | None = None, ) -> "Node": """Create a new node.""" if properties is None: @@ -101,7 +94,7 @@ def _prepare_edge_query( def traverse( - start: Union[Node, Sequence[Node]], + start: Node | Sequence[Node], edge_table: str, edge_source_name: str = "source_name", edge_source_type: str = "source_type", @@ -110,8 +103,8 @@ def traverse( edge_type: str = "edge_type", edge_filters: Sequence[str] = (), steps: int = 3, - session: Optional[Session] = None, - keyspace: Optional[str] = None, + session: Session | None = None, + keyspace: str | None = None, ) -> Iterable[Relation]: """Traverse the graph from the given starting nodes. @@ -141,9 +134,9 @@ def traverse( session = check_resolve_session(session) keyspace = check_resolve_keyspace(keyspace) - pending: Set[int] = set() - distances: Dict[Node, int] = {} - results: Set[Relation] = set() + pending: set[int] = set() + distances: dict[Node, int] = {} + results: set[Relation] = set() query = _prepare_edge_query( edge_table=edge_table, edge_source_name=edge_source_name, @@ -157,7 +150,7 @@ def traverse( ) condition = threading.Condition() - error: Optional[BaseException] = None + error: BaseException | None = None def handle_result( rows: Iterable[Any], source_distance: int, request: ResponseFuture @@ -240,7 +233,7 @@ def _handle_page(self, rows: Iterable[Any]) -> None: def _handle_error(self, error: BaseException) -> None: self.loop.call_soon_threadsafe(self.current_page_future.set_exception, error) - async def next(self) -> Tuple[int, List[Relation], Optional[Self]]: + async def next(self) -> tuple[int, list[Relation], Self | None]: """Fetch the next page of results.""" page = [_parse_relation(r) for r in await self.current_page_future] @@ -252,7 +245,7 @@ async def next(self) -> Tuple[int, List[Relation], Optional[Self]]: async def atraverse( - start: Union[Node, Sequence[Node]], + start: Node | Sequence[Node], edge_table: str, edge_source_name: str = "source_name", edge_source_type: str = "source_type", @@ -261,8 +254,8 @@ async def atraverse( edge_type: str = "edge_type", edge_filters: Sequence[str] = (), steps: int = 3, - session: Optional[Session] = None, - keyspace: Optional[str] = None, + session: Session | None = None, + keyspace: str | None = None, ) -> Iterable[Relation]: """Async traversal of the graph from the given starting nodes. @@ -312,7 +305,7 @@ async def atraverse( def fetch_relation( tg: asyncio.TaskGroup, depth: int, source: Node - ) -> Task[Tuple[int, List[Relation], Optional[AsyncPagedQuery]]]: + ) -> Task[tuple[int, list[Relation], AsyncPagedQuery | None]]: paged_query = AsyncPagedQuery( depth, session.execute_async(query, (source.name, source.type)) ) diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/utils.py b/libs/knowledge-graph/ragstack_knowledge_graph/utils.py index 2c5fddd9f..b57ec952d 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/utils.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/utils.py @@ -5,7 +5,10 @@ from itertools import batched # type: ignore[attr-defined] except ImportError: from itertools import islice - from typing import Iterable, Iterator, TypeVar + from typing import TYPE_CHECKING, TypeVar + + if TYPE_CHECKING: + from collections.abc import Iterable, Iterator # Fallback implementation for older Python versions diff --git a/libs/knowledge-graph/tests/conftest.py b/libs/knowledge-graph/tests/conftest.py index 47e88405a..2bb756a0c 100644 --- a/libs/knowledge-graph/tests/conftest.py +++ b/libs/knowledge-graph/tests/conftest.py @@ -1,5 +1,5 @@ import secrets -from typing import Iterator, List +from collections.abc import Iterator import pytest from cassandra.cluster import Cluster, Session @@ -7,10 +7,11 @@ from langchain.graphs.graph_document import GraphDocument, Node, Relationship from langchain_core.documents import Document from langchain_core.language_models import BaseChatModel -from ragstack_knowledge_graph.cassandra_graph_store import CassandraGraphStore from testcontainers.core.container import DockerContainer from testcontainers.core.waiting_utils import wait_for_logs +from ragstack_knowledge_graph.cassandra_graph_store import CassandraGraphStore + load_dotenv() @@ -65,7 +66,7 @@ def llm() -> BaseChatModel: class DataFixture: def __init__( - self, session: Session, keyspace: str, documents: List[GraphDocument] + self, session: Session, keyspace: str, documents: list[GraphDocument] ) -> None: self.session = session self.keyspace = "default_keyspace" diff --git a/libs/knowledge-graph/tests/test_extraction.py b/libs/knowledge-graph/tests/test_extraction.py index 473e729c5..26188fbb5 100644 --- a/libs/knowledge-graph/tests/test_extraction.py +++ b/libs/knowledge-graph/tests/test_extraction.py @@ -4,6 +4,7 @@ from langchain_community.graphs.graph_document import Node, Relationship from langchain_core.documents import Document from langchain_core.language_models import BaseChatModel + from ragstack_knowledge_graph.extraction import KnowledgeSchemaExtractor from ragstack_knowledge_graph.knowledge_schema import KnowledgeSchema diff --git a/libs/knowledge-graph/tests/test_knowledge_graph.py b/libs/knowledge-graph/tests/test_knowledge_graph.py index 2e64d5c1d..68e9db672 100644 --- a/libs/knowledge-graph/tests/test_knowledge_graph.py +++ b/libs/knowledge-graph/tests/test_knowledge_graph.py @@ -2,6 +2,7 @@ import pytest from cassandra.cluster import Session + from ragstack_knowledge_graph.knowledge_graph import CassandraKnowledgeGraph from ragstack_knowledge_graph.traverse import Node, Relation diff --git a/libs/knowledge-graph/tests/test_runnables.py b/libs/knowledge-graph/tests/test_runnables.py index d8f20c4ae..9f12a8f31 100644 --- a/libs/knowledge-graph/tests/test_runnables.py +++ b/libs/knowledge-graph/tests/test_runnables.py @@ -1,4 +1,5 @@ from langchain_core.language_models import BaseChatModel + from ragstack_knowledge_graph.runnables import extract_entities from ragstack_knowledge_graph.traverse import Node diff --git a/libs/knowledge-graph/tests/test_schema_inference.py b/libs/knowledge-graph/tests/test_schema_inference.py index c7793cf69..e7d73ca96 100644 --- a/libs/knowledge-graph/tests/test_schema_inference.py +++ b/libs/knowledge-graph/tests/test_schema_inference.py @@ -1,8 +1,7 @@ -from typing import List - import pytest from langchain_core.documents import Document from langchain_core.language_models import BaseChatModel + from ragstack_knowledge_graph.schema_inference import KnowledgeSchemaInferer MARIE_CURIE_SOURCE = """ @@ -46,7 +45,7 @@ def test_schema_inference(llm: BaseChatModel) -> None: # We don't do more testing here since this is meant to attempt to infer things. -def any_of_in_list(values: List[str], *expected: str) -> None: +def any_of_in_list(values: list[str], *expected: str) -> None: for value in values: if value in expected: return diff --git a/pyproject.toml b/pyproject.toml index 74a9e913f..717c360df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -141,9 +141,6 @@ select = [ "docker/examples/*" = [ "INP001", ] -"libs/langchain/ragstack_langchain/graph_store/*" = [ - "D", -] [build-system] requires = ["poetry-core"] From 4bbbe3269f62b8e12b718708ad13fe1a745d7df1 Mon Sep 17 00:00:00 2001 From: Christophe Bornet Date: Fri, 26 Jul 2024 18:33:11 +0200 Subject: [PATCH 2/2] Use pydantic 2.6+ --- libs/knowledge-graph/pyproject.toml | 2 +- libs/knowledge-graph/ragstack_knowledge_graph/extraction.py | 3 ++- .../ragstack_knowledge_graph/knowledge_schema.py | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libs/knowledge-graph/pyproject.toml b/libs/knowledge-graph/pyproject.toml index df13db0f8..16a6ee663 100644 --- a/libs/knowledge-graph/pyproject.toml +++ b/libs/knowledge-graph/pyproject.toml @@ -36,7 +36,7 @@ pytest-dotenv = "^0.5.2" pytest-rerunfailures = "^14.0" mypy = "^1.10.1" types-pyyaml = "^6.0.1" -pydantic = "<2" # for compatibility between LangChain and pydantic-yaml type checking +pydantic = "^2.6.0" [build-system] requires = ["poetry-core"] diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/extraction.py b/libs/knowledge-graph/ragstack_knowledge_graph/extraction.py index f65c5f1b3..9e4332cf1 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/extraction.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/extraction.py @@ -32,7 +32,8 @@ def _format_example(idx: int, example: Example) -> str: from pydantic_yaml import to_yaml_str - return f"Example {idx}:\n```yaml\n{to_yaml_str(example)}\n```" + yaml_example = to_yaml_str(example) # type: ignore[arg-type] + return f"Example {idx}:\n```yaml\n{yaml_example}\n```" class KnowledgeSchemaExtractor: diff --git a/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_schema.py b/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_schema.py index 6229d1ecb..17f4a55fc 100644 --- a/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_schema.py +++ b/libs/knowledge-graph/ragstack_knowledge_graph/knowledge_schema.py @@ -75,13 +75,13 @@ def from_file(cls, path: str | Path) -> Self: """ from pydantic_yaml import parse_yaml_file_as - return parse_yaml_file_as(cls, path) + return parse_yaml_file_as(cls, path) # type: ignore[type-var] def to_yaml_str(self) -> str: """Convert the schema to a YAML string.""" from pydantic_yaml import to_yaml_str - return to_yaml_str(self) + return to_yaml_str(self) # type: ignore[arg-type] class KnowledgeSchemaValidator: