mirror of
https://github.com/hwchase17/langchain.git
synced 2025-09-14 22:17:15 +00:00
core: Put Python version as a project requirement so it is considered by ruff (#26608)
Ruff doesn't know about the python version in `[tool.poetry.dependencies]`. It can get it from `project.requires-python`. Notes: * poetry seems to have issues getting the python constraints from `requires-python` and using `python` in per dependency constraints. So I had to duplicate the info. I will open an issue on poetry. * `inspect.isclass()` doesn't work correctly with `GenericAlias` (`list[...]`, `dict[..., ...]`) on Python <3.11 so I added some `not isinstance(type, GenericAlias)` checks: Python 3.11 ```pycon >>> import inspect >>> inspect.isclass(list) True >>> inspect.isclass(list[str]) False ``` Python 3.9 ```pycon >>> import inspect >>> inspect.isclass(list) True >>> inspect.isclass(list[str]) True ``` Co-authored-by: Eugene Yurtsev <eyurtsev@gmail.com>
This commit is contained in:
committed by
GitHub
parent
0f07cf61da
commit
a47b332841
@@ -1,4 +1,4 @@
|
||||
from typing import AsyncIterator, List
|
||||
from collections.abc import AsyncIterator
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -15,11 +15,11 @@ from langchain_core.utils.aiter import abatch_iterate
|
||||
],
|
||||
)
|
||||
async def test_abatch_iterate(
|
||||
input_size: int, input_iterable: List[str], expected_output: List[str]
|
||||
input_size: int, input_iterable: list[str], expected_output: list[str]
|
||||
) -> None:
|
||||
"""Test batching function."""
|
||||
|
||||
async def _to_async_iterable(iterable: List[str]) -> AsyncIterator[str]:
|
||||
async def _to_async_iterable(iterable: list[str]) -> AsyncIterator[str]:
|
||||
for item in iterable:
|
||||
yield item
|
||||
|
||||
|
@@ -1,20 +1,13 @@
|
||||
# mypy: disable-error-code="annotation-unchecked"
|
||||
import sys
|
||||
import typing
|
||||
from collections.abc import Iterable, Mapping, MutableMapping, Sequence
|
||||
from typing import Annotated as ExtensionsAnnotated
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
Dict,
|
||||
Iterable,
|
||||
List,
|
||||
Literal,
|
||||
Mapping,
|
||||
MutableMapping,
|
||||
MutableSet,
|
||||
Optional,
|
||||
Sequence,
|
||||
Set,
|
||||
Tuple,
|
||||
Type,
|
||||
Union,
|
||||
)
|
||||
from typing import TypedDict as TypingTypedDict
|
||||
@@ -22,9 +15,6 @@ from typing import TypedDict as TypingTypedDict
|
||||
import pytest
|
||||
from pydantic import BaseModel as BaseModelV2Maybe # pydantic: ignore
|
||||
from pydantic import Field as FieldV2Maybe # pydantic: ignore
|
||||
from typing_extensions import (
|
||||
Annotated as ExtensionsAnnotated,
|
||||
)
|
||||
from typing_extensions import (
|
||||
TypedDict as ExtensionsTypedDict,
|
||||
)
|
||||
@@ -47,7 +37,7 @@ from langchain_core.utils.function_calling import (
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def pydantic() -> Type[BaseModel]:
|
||||
def pydantic() -> type[BaseModel]:
|
||||
class dummy_function(BaseModel):
|
||||
"""dummy function"""
|
||||
|
||||
@@ -102,7 +92,7 @@ def dummy_tool() -> BaseTool:
|
||||
arg2: Literal["bar", "baz"] = Field(..., description="one of 'bar', 'baz'")
|
||||
|
||||
class DummyFunction(BaseTool):
|
||||
args_schema: Type[BaseModel] = Schema
|
||||
args_schema: type[BaseModel] = Schema
|
||||
name: str = "dummy_function"
|
||||
description: str = "dummy function"
|
||||
|
||||
@@ -127,7 +117,7 @@ def dummy_structured_tool() -> StructuredTool:
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def dummy_pydantic() -> Type[BaseModel]:
|
||||
def dummy_pydantic() -> type[BaseModel]:
|
||||
class dummy_function(BaseModel):
|
||||
"""dummy function"""
|
||||
|
||||
@@ -138,7 +128,7 @@ def dummy_pydantic() -> Type[BaseModel]:
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def dummy_pydantic_v2() -> Type[BaseModelV2Maybe]:
|
||||
def dummy_pydantic_v2() -> type[BaseModelV2Maybe]:
|
||||
class dummy_function(BaseModelV2Maybe):
|
||||
"""dummy function"""
|
||||
|
||||
@@ -151,7 +141,7 @@ def dummy_pydantic_v2() -> Type[BaseModelV2Maybe]:
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def dummy_typing_typed_dict() -> Type:
|
||||
def dummy_typing_typed_dict() -> type:
|
||||
class dummy_function(TypingTypedDict):
|
||||
"""dummy function"""
|
||||
|
||||
@@ -162,7 +152,7 @@ def dummy_typing_typed_dict() -> Type:
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def dummy_typing_typed_dict_docstring() -> Type:
|
||||
def dummy_typing_typed_dict_docstring() -> type:
|
||||
class dummy_function(TypingTypedDict):
|
||||
"""dummy function
|
||||
|
||||
@@ -178,7 +168,7 @@ def dummy_typing_typed_dict_docstring() -> Type:
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def dummy_extensions_typed_dict() -> Type:
|
||||
def dummy_extensions_typed_dict() -> type:
|
||||
class dummy_function(ExtensionsTypedDict):
|
||||
"""dummy function"""
|
||||
|
||||
@@ -189,7 +179,7 @@ def dummy_extensions_typed_dict() -> Type:
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def dummy_extensions_typed_dict_docstring() -> Type:
|
||||
def dummy_extensions_typed_dict_docstring() -> type:
|
||||
class dummy_function(ExtensionsTypedDict):
|
||||
"""dummy function
|
||||
|
||||
@@ -205,7 +195,7 @@ def dummy_extensions_typed_dict_docstring() -> Type:
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def json_schema() -> Dict:
|
||||
def json_schema() -> dict:
|
||||
return {
|
||||
"title": "dummy_function",
|
||||
"description": "dummy function",
|
||||
@@ -246,18 +236,18 @@ class DummyWithClassMethod:
|
||||
|
||||
|
||||
def test_convert_to_openai_function(
|
||||
pydantic: Type[BaseModel],
|
||||
pydantic: type[BaseModel],
|
||||
function: Callable,
|
||||
dummy_structured_tool: StructuredTool,
|
||||
dummy_tool: BaseTool,
|
||||
json_schema: Dict,
|
||||
json_schema: dict,
|
||||
Annotated_function: Callable,
|
||||
dummy_pydantic: Type[BaseModel],
|
||||
dummy_pydantic: type[BaseModel],
|
||||
runnable: Runnable,
|
||||
dummy_typing_typed_dict: Type,
|
||||
dummy_typing_typed_dict_docstring: Type,
|
||||
dummy_extensions_typed_dict: Type,
|
||||
dummy_extensions_typed_dict_docstring: Type,
|
||||
dummy_typing_typed_dict: type,
|
||||
dummy_typing_typed_dict_docstring: type,
|
||||
dummy_extensions_typed_dict: type,
|
||||
dummy_extensions_typed_dict_docstring: type,
|
||||
) -> None:
|
||||
expected = {
|
||||
"name": "dummy_function",
|
||||
@@ -436,7 +426,7 @@ def test_function_optional_param() -> None:
|
||||
def func5(
|
||||
a: Optional[str],
|
||||
b: str,
|
||||
c: Optional[List[Optional[str]]],
|
||||
c: Optional[list[Optional[str]]],
|
||||
) -> None:
|
||||
"""A test function"""
|
||||
pass
|
||||
@@ -544,7 +534,7 @@ def test__convert_typed_dict_to_openai_function(
|
||||
class SubTool(TypedDict):
|
||||
"""Subtool docstring"""
|
||||
|
||||
args: Annotated[Dict[str, Any], {}, "this does bar"] # noqa: F722 # type: ignore
|
||||
args: Annotated[dict[str, Any], {}, "this does bar"] # noqa: F722 # type: ignore
|
||||
|
||||
class Tool(TypedDict):
|
||||
"""Docstring
|
||||
@@ -555,18 +545,18 @@ def test__convert_typed_dict_to_openai_function(
|
||||
|
||||
arg1: str
|
||||
arg2: Union[int, str, bool]
|
||||
arg3: Optional[List[SubTool]]
|
||||
arg3: Optional[list[SubTool]]
|
||||
arg4: Annotated[Literal["bar", "baz"], ..., "this does foo"] # noqa: F722
|
||||
arg5: Annotated[Optional[float], None]
|
||||
arg6: Annotated[
|
||||
Optional[Sequence[Mapping[str, Tuple[Iterable[Any], SubTool]]]], []
|
||||
Optional[Sequence[Mapping[str, tuple[Iterable[Any], SubTool]]]], []
|
||||
]
|
||||
arg7: Annotated[List[SubTool], ...]
|
||||
arg8: Annotated[Tuple[SubTool], ...]
|
||||
arg7: Annotated[list[SubTool], ...]
|
||||
arg8: Annotated[tuple[SubTool], ...]
|
||||
arg9: Annotated[Sequence[SubTool], ...]
|
||||
arg10: Annotated[Iterable[SubTool], ...]
|
||||
arg11: Annotated[Set[SubTool], ...]
|
||||
arg12: Annotated[Dict[str, SubTool], ...]
|
||||
arg11: Annotated[set[SubTool], ...]
|
||||
arg12: Annotated[dict[str, SubTool], ...]
|
||||
arg13: Annotated[Mapping[str, SubTool], ...]
|
||||
arg14: Annotated[MutableMapping[str, SubTool], ...]
|
||||
arg15: Annotated[bool, False, "flag"] # noqa: F821 # type: ignore
|
||||
@@ -775,9 +765,9 @@ def test__convert_typed_dict_to_openai_function(
|
||||
|
||||
|
||||
@pytest.mark.parametrize("typed_dict", [ExtensionsTypedDict, TypingTypedDict])
|
||||
def test__convert_typed_dict_to_openai_function_fail(typed_dict: Type) -> None:
|
||||
def test__convert_typed_dict_to_openai_function_fail(typed_dict: type) -> None:
|
||||
class Tool(typed_dict):
|
||||
arg1: MutableSet # Pydantic 2 supports this, but pydantic v1 does not.
|
||||
arg1: typing.MutableSet # Pydantic 2 supports this, but pydantic v1 does not.
|
||||
|
||||
# Error should be raised since we're using v1 code path here
|
||||
with pytest.raises(TypeError):
|
||||
|
@@ -1,5 +1,3 @@
|
||||
from typing import List
|
||||
|
||||
import pytest
|
||||
|
||||
from langchain_core.utils.iter import batch_iterate
|
||||
@@ -15,7 +13,7 @@ from langchain_core.utils.iter import batch_iterate
|
||||
],
|
||||
)
|
||||
def test_batch_iterate(
|
||||
input_size: int, input_iterable: List[str], expected_output: List[str]
|
||||
input_size: int, input_iterable: list[str], expected_output: list[str]
|
||||
) -> None:
|
||||
"""Test batching function."""
|
||||
assert list(batch_iterate(input_size, input_iterable)) == expected_output
|
||||
|
@@ -1,6 +1,6 @@
|
||||
"""Test for some custom pydantic decorators."""
|
||||
|
||||
from typing import Any, Dict, List, Optional
|
||||
from typing import Any, Optional
|
||||
|
||||
import pytest
|
||||
from pydantic import ConfigDict
|
||||
@@ -24,7 +24,7 @@ def test_pre_init_decorator() -> None:
|
||||
y: int
|
||||
|
||||
@pre_init
|
||||
def validator(cls, v: Dict[str, Any]) -> Dict[str, Any]:
|
||||
def validator(cls, v: dict[str, Any]) -> dict[str, Any]:
|
||||
v["y"] = v["x"] + 1
|
||||
return v
|
||||
|
||||
@@ -45,7 +45,7 @@ def test_pre_init_decorator_with_more_defaults() -> None:
|
||||
d: int = Field(default_factory=lambda: 3)
|
||||
|
||||
@pre_init
|
||||
def validator(cls, v: Dict[str, Any]) -> Dict[str, Any]:
|
||||
def validator(cls, v: dict[str, Any]) -> dict[str, Any]:
|
||||
assert v["a"] == 1
|
||||
assert v["b"] is None
|
||||
assert v["c"] == 2
|
||||
@@ -69,7 +69,7 @@ def test_with_aliases() -> None:
|
||||
)
|
||||
|
||||
@pre_init
|
||||
def validator(cls, v: Dict[str, Any]) -> Dict[str, Any]:
|
||||
def validator(cls, v: dict[str, Any]) -> dict[str, Any]:
|
||||
v["z"] = v["x"]
|
||||
return v
|
||||
|
||||
@@ -142,7 +142,7 @@ def test_with_field_metadata() -> None:
|
||||
from pydantic import Field as FieldV2
|
||||
|
||||
class Foo(BaseModelV2):
|
||||
x: List[int] = FieldV2(
|
||||
x: list[int] = FieldV2(
|
||||
description="List of integers", min_length=10, max_length=15
|
||||
)
|
||||
|
||||
|
@@ -2,7 +2,7 @@ import os
|
||||
import re
|
||||
from contextlib import AbstractContextManager, nullcontext
|
||||
from copy import deepcopy
|
||||
from typing import Any, Callable, Dict, Optional, Tuple, Type, Union
|
||||
from typing import Any, Callable, Optional, Union
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
@@ -32,9 +32,9 @@ from langchain_core.utils.utils import secret_from_env
|
||||
)
|
||||
def test_check_package_version(
|
||||
package: str,
|
||||
check_kwargs: Dict[str, Optional[str]],
|
||||
check_kwargs: dict[str, Optional[str]],
|
||||
actual_version: str,
|
||||
expected: Optional[Tuple[Type[Exception], str]],
|
||||
expected: Optional[tuple[type[Exception], str]],
|
||||
) -> None:
|
||||
with patch("langchain_core.utils.utils.version", return_value=actual_version):
|
||||
if expected is None:
|
||||
|
Reference in New Issue
Block a user