Skip to content

Commit

Permalink
[utils] add beta warning and decorator (#26748)
Browse files Browse the repository at this point in the history
## Summary & Motivation

Fixes
[AD-736](https://linear.app/dagster-labs/issue/AD-736/add-beta-annotation)
in the API Lifecycle project.

Adding new Beta Python utils. Similar to #25363 

This is done in alignment with the new [API
lifecycle](https://www.notion.so/dagster/API-Lifecycle-Refresh-f72f6e199da3409c8c5da297a109b3c8).

The raised warning is a `Warning`.

Docs to be updated in subsequent PR.
  • Loading branch information
maximearmstrong authored Jan 3, 2025
1 parent 844b0d3 commit 5a63f7e
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 0 deletions.
115 changes: 115 additions & 0 deletions python_modules/dagster/dagster/_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
is_resource_def,
)
from dagster._utils.warnings import (
beta_warning,
deprecation_warning,
experimental_warning,
preview_warning,
Expand Down Expand Up @@ -177,6 +178,120 @@ def get_preview_info(obj: Annotatable) -> PreviewInfo:
return getattr(target, _PREVIEW_ATTR_NAME)


# ########################
# ##### BETA
# ########################


_BETA_ATTR_NAME: Final[str] = "_beta"


@dataclass
class BetaInfo:
additional_warn_text: Optional[str] = None
subject: Optional[str] = None


@overload
def beta(
__obj: T_Annotatable,
*,
additional_warn_text: Optional[str] = ...,
subject: Optional[str] = ...,
emit_runtime_warning: bool = ...,
) -> T_Annotatable: ...


@overload
def beta(
__obj: None = ...,
*,
additional_warn_text: Optional[str] = ...,
subject: Optional[str] = ...,
emit_runtime_warning: bool = ...,
) -> Callable[[T_Annotatable], T_Annotatable]: ...


def beta(
__obj: Optional[T_Annotatable] = None,
*,
additional_warn_text: Optional[str] = None,
subject: Optional[str] = None,
emit_runtime_warning: bool = True,
) -> Union[T_Annotatable, Callable[[T_Annotatable], T_Annotatable]]:
"""Mark an object as beta. This appends some metadata to the object that causes it to be
rendered with a "beta" tag and associated warning in the docs.
If `emit_runtime_warning` is True, a warning will also be emitted when the function is called,
having the same text as is displayed in the docs. For consistency between docs and runtime
warnings, this decorator is preferred to manual calls to `beta_warning`.
Args:
additional_warn_text (Optional[str]): Additional text to display after the beta warning.
subject (Optional[str]): The subject of the beta warning. Defaults to a string
representation of the decorated object. This is useful when marking usage of
a beta API inside an otherwise non-beta function, so
that it can be easily cleaned up later. It should only be used with
`emit_runtime_warning=False`, as we don't want to warn users when a
beta API is used internally.
emit_runtime_warning (bool): Whether to emit a warning when the function is called.
Usage:
.. code-block:: python
@beta
def my_beta_function(my_arg):
...
@beta
class MyBetaClass:
...
@beta(subject="some_beta_function", emit_runtime_warning=False)
def not_beta_function():
...
some_beta_function()
...
"""
if __obj is None:
return lambda obj: beta(
obj,
subject=subject,
emit_runtime_warning=emit_runtime_warning,
additional_warn_text=additional_warn_text,
)
else:
target = _get_annotation_target(__obj)
setattr(
target,
_BETA_ATTR_NAME,
BetaInfo(additional_warn_text, subject),
)

if emit_runtime_warning:
stack_level = _get_warning_stacklevel(__obj)
subject = subject or _get_subject(__obj)
warning_fn = lambda: beta_warning(
subject,
additional_warn_text=additional_warn_text,
stacklevel=stack_level,
)
return apply_pre_call_decorator(__obj, warning_fn)
else:
return __obj


def is_beta(obj: Annotatable) -> bool:
target = _get_annotation_target(obj)
return hasattr(target, _BETA_ATTR_NAME)


def get_beta_info(obj: Annotatable) -> BetaInfo:
target = _get_annotation_target(obj)
return getattr(target, _BETA_ATTR_NAME)


# ########################
# ##### SUPERSEDED
# ########################
Expand Down
26 changes: 26 additions & 0 deletions python_modules/dagster/dagster/_utils/warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,32 @@ def preview_warning(
)


# ########################
# ##### BETA
# ########################


class BetaWarning(Warning):
pass


def beta_warning(
subject: str,
additional_warn_text: Optional[str] = None,
stacklevel: int = 3,
):
if not _warnings_on.get():
return

warnings.warn(
f"{subject} is currently in beta, and may have breaking changes in minor version releases, "
f"with behavior changes in patch releases."
+ ((" " + additional_warn_text) if additional_warn_text else ""),
category=BetaWarning,
stacklevel=stacklevel,
)


# ########################
# ##### SUPERSEDED
# ########################
Expand Down

0 comments on commit 5a63f7e

Please sign in to comment.