mirror of
https://github.com/hwchase17/langchain.git
synced 2025-09-21 18:39:57 +00:00
refactor(core): improve beta decorator (#32505)
This is better than using a subclass as returning a `property` works with `ClassWithBetaMethods.beta_property.__doc__` Co-authored-by: Mason Daugherty <mason@langchain.dev>
This commit is contained in:
committed by
GitHub
parent
c3b28c769a
commit
714f74a847
@@ -156,50 +156,24 @@ def beta(
|
|||||||
_name = _name or obj.fget.__qualname__
|
_name = _name or obj.fget.__qualname__
|
||||||
old_doc = obj.__doc__
|
old_doc = obj.__doc__
|
||||||
|
|
||||||
class _BetaProperty(property):
|
def _fget(instance: Any) -> Any:
|
||||||
"""A beta property."""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
fget: Union[Callable[[Any], Any], None] = None,
|
|
||||||
fset: Union[Callable[[Any, Any], None], None] = None,
|
|
||||||
fdel: Union[Callable[[Any], None], None] = None,
|
|
||||||
doc: Union[str, None] = None,
|
|
||||||
) -> None:
|
|
||||||
super().__init__(fget, fset, fdel, doc)
|
|
||||||
self.__orig_fget = fget
|
|
||||||
self.__orig_fset = fset
|
|
||||||
self.__orig_fdel = fdel
|
|
||||||
self.__doc__ = doc
|
|
||||||
|
|
||||||
def __get__(
|
|
||||||
self, instance: Any, owner: Union[type, None] = None
|
|
||||||
) -> Any:
|
|
||||||
if instance is not None or owner is not None:
|
|
||||||
emit_warning()
|
|
||||||
return self.fget(instance)
|
|
||||||
|
|
||||||
def __set__(self, instance: Any, value: Any) -> None:
|
|
||||||
if instance is not None:
|
if instance is not None:
|
||||||
emit_warning()
|
emit_warning()
|
||||||
return self.fset(instance, value)
|
return obj.fget(instance)
|
||||||
|
|
||||||
def __delete__(self, instance: Any) -> None:
|
def _fset(instance: Any, value: Any) -> None:
|
||||||
if instance is not None:
|
if instance is not None:
|
||||||
emit_warning()
|
emit_warning()
|
||||||
return self.fdel(instance)
|
obj.fset(instance, value)
|
||||||
|
|
||||||
def __set_name__(self, owner: Union[type, None], set_name: str) -> None:
|
def _fdel(instance: Any) -> None:
|
||||||
nonlocal _name
|
if instance is not None:
|
||||||
if _name == "<lambda>":
|
emit_warning()
|
||||||
_name = set_name
|
obj.fdel(instance)
|
||||||
|
|
||||||
def finalize(wrapper: Callable[..., Any], new_doc: str) -> Any: # noqa: ARG001
|
def finalize(_wrapper: Callable[..., Any], new_doc: str) -> Any:
|
||||||
"""Finalize the property."""
|
"""Finalize the property."""
|
||||||
return _BetaProperty(
|
return property(fget=_fget, fset=_fset, fdel=_fdel, doc=new_doc)
|
||||||
fget=obj.fget, fset=obj.fset, fdel=obj.fdel, doc=new_doc
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
_name = _name or obj.__qualname__
|
_name = _name or obj.__qualname__
|
||||||
if not _obj_type:
|
if not _obj_type:
|
||||||
|
@@ -91,12 +91,20 @@ class ClassWithBetaMethods:
|
|||||||
"""Original doc."""
|
"""Original doc."""
|
||||||
return "This is a beta staticmethod."
|
return "This is a beta staticmethod."
|
||||||
|
|
||||||
@beta() # type: ignore[prop-decorator]
|
|
||||||
@property
|
@property
|
||||||
def beta_property(self) -> str:
|
def beta_property(self) -> str:
|
||||||
"""Original doc."""
|
"""Original doc."""
|
||||||
return "This is a beta property."
|
return "This is a beta property."
|
||||||
|
|
||||||
|
@beta_property.setter
|
||||||
|
def beta_property(self, _value: str) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@beta() # type: ignore[misc]
|
||||||
|
@beta_property.deleter
|
||||||
|
def beta_property(self) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def test_beta_function() -> None:
|
def test_beta_function() -> None:
|
||||||
"""Test beta function."""
|
"""Test beta function."""
|
||||||
@@ -222,14 +230,17 @@ def test_beta_property() -> None:
|
|||||||
obj = ClassWithBetaMethods()
|
obj = ClassWithBetaMethods()
|
||||||
assert obj.beta_property == "This is a beta property."
|
assert obj.beta_property == "This is a beta property."
|
||||||
|
|
||||||
assert len(warning_list) == 1
|
obj.beta_property = "foo"
|
||||||
warning = warning_list[0].message
|
|
||||||
|
|
||||||
assert str(warning) == (
|
del obj.beta_property
|
||||||
|
|
||||||
|
assert len(warning_list) == 3
|
||||||
|
for warning in warning_list:
|
||||||
|
assert str(warning.message) == (
|
||||||
"The attribute `ClassWithBetaMethods.beta_property` is in beta. "
|
"The attribute `ClassWithBetaMethods.beta_property` is in beta. "
|
||||||
"It is actively being worked on, so the API may change."
|
"It is actively being worked on, so the API may change."
|
||||||
)
|
)
|
||||||
doc = ClassWithBetaMethods.__dict__["beta_property"].__doc__
|
doc = ClassWithBetaMethods.beta_property.__doc__
|
||||||
assert isinstance(doc, str)
|
assert isinstance(doc, str)
|
||||||
assert doc.startswith(".. beta::")
|
assert doc.startswith(".. beta::")
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user