core[patch]: Add _api.rename_parameter to support renaming of parameters in functions (#25101)

Add ability to rename paramerters in function signatures

```python

    @rename_parameter(since="2.0.0", removal="3.0.0", old="old_name", new="new_name")
    def foo(new_name: str) -> str:
        """original doc"""
        return new_name
```

---------

Co-authored-by: Bagatur <baskaryan@gmail.com>
Co-authored-by: Bagatur <22008038+baskaryan@users.noreply.github.com>
This commit is contained in:
Eugene Yurtsev
2024-08-22 20:16:31 -04:00
committed by GitHub
parent 0258cb96fa
commit c316361115
2 changed files with 145 additions and 2 deletions

View File

@@ -4,7 +4,11 @@ from typing import Any, Dict
import pytest
from langchain_core._api.deprecation import deprecated, warn_deprecated
from langchain_core._api.deprecation import (
deprecated,
rename_parameter,
warn_deprecated,
)
from langchain_core.pydantic_v1 import BaseModel
@@ -412,3 +416,84 @@ def test_raise_error_for_bad_decorator() -> None:
def deprecated_function() -> str:
"""original doc"""
return "This is a deprecated function."
def test_rename_parameter() -> None:
"""Test rename parameter."""
@rename_parameter(since="2.0.0", removal="3.0.0", old="old_name", new="new_name")
def foo(new_name: str) -> str:
"""original doc"""
return new_name
with warnings.catch_warnings(record=True) as warning_list:
warnings.simplefilter("always")
assert foo(old_name="hello") == "hello" # type: ignore[call-arg]
assert len(warning_list) == 1
assert foo(new_name="hello") == "hello"
assert foo("hello") == "hello"
assert foo.__doc__ == "original doc"
with pytest.raises(TypeError):
foo(meow="hello") # type: ignore[call-arg]
with pytest.raises(TypeError):
assert foo("hello", old_name="hello") # type: ignore[call-arg]
with pytest.raises(TypeError):
assert foo(old_name="goodbye", new_name="hello") # type: ignore[call-arg]
async def test_rename_parameter_for_async_func() -> None:
"""Test rename parameter."""
@rename_parameter(since="2.0.0", removal="3.0.0", old="old_name", new="new_name")
async def foo(new_name: str) -> str:
"""original doc"""
return new_name
with warnings.catch_warnings(record=True) as warning_list:
warnings.simplefilter("always")
assert await foo(old_name="hello") == "hello" # type: ignore[call-arg]
assert len(warning_list) == 1
assert await foo(new_name="hello") == "hello"
assert await foo("hello") == "hello"
assert foo.__doc__ == "original doc"
with pytest.raises(TypeError):
await foo(meow="hello") # type: ignore[call-arg]
with pytest.raises(TypeError):
assert await foo("hello", old_name="hello") # type: ignore[call-arg]
with pytest.raises(TypeError):
assert await foo(old_name="a", new_name="hello") # type: ignore[call-arg]
def test_rename_parameter_method() -> None:
"""Test that it works for a method."""
class Foo:
@rename_parameter(
since="2.0.0", removal="3.0.0", old="old_name", new="new_name"
)
def a(self, new_name: str) -> str:
return new_name
foo = Foo()
with warnings.catch_warnings(record=True) as warning_list:
warnings.simplefilter("always")
assert foo.a(old_name="hello") == "hello" # type: ignore[call-arg]
assert len(warning_list) == 1
assert str(warning_list[0].message) == (
"The parameter `old_name` of `a` was deprecated in 2.0.0 and will be "
"removed "
"in 3.0.0 Use `new_name` instead."
)
assert foo.a(new_name="hello") == "hello"
assert foo.a("hello") == "hello"
with pytest.raises(TypeError):
foo.a(meow="hello") # type: ignore[call-arg]
with pytest.raises(TypeError):
assert foo.a("hello", old_name="hello") # type: ignore[call-arg]