diff --git a/libs/core/langchain_core/_api/beta_decorator.py b/libs/core/langchain_core/_api/beta_decorator.py index 786f371ad21..5fc70a8eb83 100644 --- a/libs/core/langchain_core/_api/beta_decorator.py +++ b/libs/core/langchain_core/_api/beta_decorator.py @@ -156,50 +156,24 @@ def beta( _name = _name or obj.fget.__qualname__ old_doc = obj.__doc__ - class _BetaProperty(property): - """A beta property.""" + def _fget(instance: Any) -> Any: + if instance is not None: + emit_warning() + return obj.fget(instance) - 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 _fset(instance: Any, value: Any) -> None: + if instance is not None: + emit_warning() + obj.fset(instance, value) - 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 _fdel(instance: Any) -> None: + if instance is not None: + emit_warning() + obj.fdel(instance) - def __set__(self, instance: Any, value: Any) -> None: - if instance is not None: - emit_warning() - return self.fset(instance, value) - - def __delete__(self, instance: Any) -> None: - if instance is not None: - emit_warning() - return self.fdel(instance) - - def __set_name__(self, owner: Union[type, None], set_name: str) -> None: - nonlocal _name - if _name == "": - _name = set_name - - def finalize(wrapper: Callable[..., Any], new_doc: str) -> Any: # noqa: ARG001 + def finalize(_wrapper: Callable[..., Any], new_doc: str) -> Any: """Finalize the property.""" - return _BetaProperty( - fget=obj.fget, fset=obj.fset, fdel=obj.fdel, doc=new_doc - ) - + return property(fget=_fget, fset=_fset, fdel=_fdel, doc=new_doc) else: _name = _name or obj.__qualname__ if not _obj_type: diff --git a/libs/core/tests/unit_tests/_api/test_beta_decorator.py b/libs/core/tests/unit_tests/_api/test_beta_decorator.py index fb396505342..19d51295453 100644 --- a/libs/core/tests/unit_tests/_api/test_beta_decorator.py +++ b/libs/core/tests/unit_tests/_api/test_beta_decorator.py @@ -91,12 +91,20 @@ class ClassWithBetaMethods: """Original doc.""" return "This is a beta staticmethod." - @beta() # type: ignore[prop-decorator] @property def beta_property(self) -> str: """Original doc.""" 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: """Test beta function.""" @@ -222,14 +230,17 @@ def test_beta_property() -> None: obj = ClassWithBetaMethods() assert obj.beta_property == "This is a beta property." - assert len(warning_list) == 1 - warning = warning_list[0].message + obj.beta_property = "foo" - assert str(warning) == ( - "The attribute `ClassWithBetaMethods.beta_property` is in beta. " - "It is actively being worked on, so the API may change." - ) - doc = ClassWithBetaMethods.__dict__["beta_property"].__doc__ + 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. " + "It is actively being worked on, so the API may change." + ) + doc = ClassWithBetaMethods.beta_property.__doc__ assert isinstance(doc, str) assert doc.startswith(".. beta::")