aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/python/util/deprecation.py
diff options
context:
space:
mode:
Diffstat (limited to 'tensorflow/python/util/deprecation.py')
-rw-r--r--tensorflow/python/util/deprecation.py72
1 files changed, 64 insertions, 8 deletions
diff --git a/tensorflow/python/util/deprecation.py b/tensorflow/python/util/deprecation.py
index 376be39978..9e2202eaf8 100644
--- a/tensorflow/python/util/deprecation.py
+++ b/tensorflow/python/util/deprecation.py
@@ -37,6 +37,11 @@ _PRINT_DEPRECATION_WARNINGS = True
_PRINTED_WARNING = {}
+class DeprecatedNamesAlreadySet(Exception):
+ """Raised when setting deprecated names multiple times for the same symbol."""
+ pass
+
+
def _add_deprecated_function_notice_to_docstring(doc, date, instructions):
"""Adds a deprecation notice to a docstring for deprecated functions."""
main_text = ['THIS FUNCTION IS DEPRECATED. It will be removed %s.' %
@@ -87,6 +92,27 @@ def _call_location(outer=False):
return '%s:%d' % (entry[1], entry[2])
+def _wrap_decorator(wrapped_function):
+ """Indicate that one function wraps another.
+
+ This decorator wraps a function using `tf_decorator.make_decorator`
+ so that doc generation scripts can pick up original function
+ signature.
+ It would be better to use @functools.wrap decorator, but it would
+ not update function signature to match wrapped function in Python 2.
+
+ Args:
+ wrapped_function: The function that decorated function wraps.
+
+ Returns:
+ Function that accepts wrapper function as an argument and returns
+ `TFDecorator` instance.
+ """
+ def wrapper(wrapper_func):
+ return tf_decorator.make_decorator(wrapped_function, wrapper_func)
+ return wrapper
+
+
def deprecated_alias(deprecated_name, name, func_or_class, warn_once=True):
"""Deprecate a symbol in favor of a new name with identical semantics.
@@ -144,7 +170,7 @@ def deprecated_alias(deprecated_name, name, func_or_class, warn_once=True):
if tf_inspect.isclass(func_or_class):
# Make a new class with __init__ wrapped in a warning.
- class NewClass(func_or_class): # pylint: disable=missing-docstring
+ class _NewClass(func_or_class): # pylint: disable=missing-docstring
__doc__ = decorator_utils.add_notice_to_docstring(
func_or_class.__doc__, 'Please use %s instead.' % name,
'DEPRECATED CLASS',
@@ -153,27 +179,28 @@ def deprecated_alias(deprecated_name, name, func_or_class, warn_once=True):
__name__ = func_or_class.__name__
__module__ = _call_location(outer=True)
+ @_wrap_decorator(func_or_class.__init__)
def __init__(self, *args, **kwargs):
- if hasattr(NewClass.__init__, '__func__'):
+ if hasattr(_NewClass.__init__, '__func__'):
# Python 2
- NewClass.__init__.__func__.__doc__ = func_or_class.__init__.__doc__
+ _NewClass.__init__.__func__.__doc__ = func_or_class.__init__.__doc__
else:
# Python 3
- NewClass.__init__.__doc__ = func_or_class.__init__.__doc__
+ _NewClass.__init__.__doc__ = func_or_class.__init__.__doc__
if _PRINT_DEPRECATION_WARNINGS:
# We're making the alias as we speak. The original may have other
# aliases, so we cannot use it to check for whether it's already been
# warned about.
- if NewClass.__init__ not in _PRINTED_WARNING:
+ if _NewClass.__init__ not in _PRINTED_WARNING:
if warn_once:
- _PRINTED_WARNING[NewClass.__init__] = True
+ _PRINTED_WARNING[_NewClass.__init__] = True
logging.warning(
'From %s: The name %s is deprecated. Please use %s instead.\n',
_call_location(), deprecated_name, name)
- super(NewClass, self).__init__(*args, **kwargs)
+ super(_NewClass, self).__init__(*args, **kwargs)
- return NewClass
+ return _NewClass
else:
decorator_utils.validate_callable(func_or_class, 'deprecated')
@@ -197,6 +224,35 @@ def deprecated_alias(deprecated_name, name, func_or_class, warn_once=True):
func_or_class.__doc__, None, 'Please use %s instead.' % name))
+def deprecated_endpoints(*args):
+ """Decorator for marking endpoints deprecated.
+
+ This decorator does not print deprecation messages.
+ TODO(annarev): eventually start printing deprecation warnings when
+ @deprecation_endpoints decorator is added.
+
+ Args:
+ *args: Deprecated endpoint names.
+
+ Returns:
+ A function that takes symbol as an argument and adds
+ _tf_deprecated_api_names to that symbol.
+ _tf_deprecated_api_names would be set to a list of deprecated
+ endpoint names for the symbol.
+ """
+ def deprecated_wrapper(func):
+ # pylint: disable=protected-access
+ if '_tf_deprecated_api_names' in func.__dict__:
+ raise DeprecatedNamesAlreadySet(
+ 'Cannot set deprecated names for %s to %s. '
+ 'Deprecated names are already set to %s.' % (
+ func.__name__, str(args), str(func._tf_deprecated_api_names)))
+ func._tf_deprecated_api_names = args
+ # pylint: disable=protected-access
+ return func
+ return deprecated_wrapper
+
+
def deprecated(date, instructions, warn_once=True):
"""Decorator for marking functions or methods deprecated.