Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[utils] add beta warning and decorator #26748

Merged
merged 4 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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