[docs] Decorator to create a deprecation warning (#155127)

This PR adds the `@deprecate` decorator for internal functions which we are prepping for deprecation.  Add it on top of an internal function to emit a deprecation warning + allow bc with the non internal version of the function.

Tested with `python test/test_utils.py TestDeprecate.test_deprecated `

Furthermore, testing with a modified version of the tes in the pr gives something like this which is what we want

```
/home/sahanp/repos/pytorch/test/test_utils.py:1239: UserWarning: deprecated_api is DEPRECATED, please consider using an alternative API(s).
  deprecated_api(1, 2)
  ```
Pull Request resolved: https://github.com/pytorch/pytorch/pull/155127
Approved by: https://github.com/albanD

Co-authored-by: albanD <desmaison.alban@gmail.com>
This commit is contained in:
PaliC
2025-06-25 18:09:00 +00:00
committed by PyTorch MergeBot
parent 4bc3e4b497
commit 09ffba3cf7
2 changed files with 71 additions and 0 deletions

View File

@ -4,6 +4,7 @@ import logging
import os
import sys
import tempfile
import typing_extensions
from typing import Any, Callable, Optional, TypeVar
from typing_extensions import ParamSpec
@ -282,3 +283,54 @@ def record_chromium_event_internal(
def profiler_allow_cudagraph_cupti_lazy_reinit_cuda12():
return True
def deprecated():
"""
When we deprecate a function that might still be in use, we make it internal
by adding a leading underscore. This decorator is used with a private function,
and creates a public alias without the leading underscore, but has a deprecation
warning. This tells users "THIS FUNCTION IS DEPRECATED, please use something else"
without breaking them, however, if they still really really want to use the
deprecated function without the warning, they can do so by using the internal
function name.
"""
def decorator(func: Callable[_P, _T]) -> Callable[_P, _T]:
# Validate naming convention single leading underscore, not dunder
if not (func.__name__.startswith("_")):
raise ValueError(
"@deprecate must decorate a function whose name "
"starts with a single leading underscore (e.g. '_foo') as the api should be considered internal for deprecation."
)
public_name = func.__name__[1:] # drop exactly one leading underscore
module = sys.modules[func.__module__]
# Don't clobber an existing symbol accidentally.
if hasattr(module, public_name):
raise RuntimeError(
f"Cannot create alias '{public_name}' -> symbol already exists in {module.__name__}. \
Please rename it or consult a pytorch developer on what to do"
)
warning_msg = f"{func.__name__[1:]} is DEPRECATED, please consider using an alternative API(s). "
# public deprecated alias
alias = typing_extensions.deprecated(
warning_msg, category=UserWarning, stacklevel=1
)(func)
alias.__name__ = public_name
# Adjust qualname if nested inside a class or another function
if "." in func.__qualname__:
alias.__qualname__ = func.__qualname__.rsplit(".", 1)[0] + "." + public_name
else:
alias.__qualname__ = public_name
setattr(module, public_name, alias)
return func
return decorator