From 1b65fb67c94b9caf99fe14d0b8341f70dc5e8d33 Mon Sep 17 00:00:00 2001 From: Martin Wicke Date: Fri, 24 Jun 2016 15:50:13 -0800 Subject: [PATCH] Add deprecation decorators. Deprecate dnn_ops.dnn. Change: 125830566 --- tensorflow/contrib/framework/BUILD | 1 + tensorflow/contrib/framework/__init__.py | 2 + .../framework/python/framework/__init__.py | 1 + .../framework/python/framework/deprecation.py | 112 ++++++++++++++++++ .../contrib/learn/python/learn/ops/dnn_ops.py | 2 + 5 files changed, 118 insertions(+) create mode 100644 tensorflow/contrib/framework/python/framework/deprecation.py diff --git a/tensorflow/contrib/framework/BUILD b/tensorflow/contrib/framework/BUILD index c9cd4817def..b13de8e53f5 100644 --- a/tensorflow/contrib/framework/BUILD +++ b/tensorflow/contrib/framework/BUILD @@ -14,6 +14,7 @@ py_library( srcs = [ "__init__.py", "python/framework/__init__.py", + "python/framework/deprecation.py", "python/framework/tensor_util.py", "python/ops/__init__.py", "python/ops/arg_scope.py", diff --git a/tensorflow/contrib/framework/__init__.py b/tensorflow/contrib/framework/__init__.py index 9e6ef55c5b2..c8cca813bbd 100644 --- a/tensorflow/contrib/framework/__init__.py +++ b/tensorflow/contrib/framework/__init__.py @@ -28,6 +28,8 @@ @@with_shape @@with_same_shape +## Deprecation +@@deprecated ## Arg_Scope @@arg_scope diff --git a/tensorflow/contrib/framework/python/framework/__init__.py b/tensorflow/contrib/framework/python/framework/__init__.py index 496f9532c1d..d7724ba8e58 100644 --- a/tensorflow/contrib/framework/python/framework/__init__.py +++ b/tensorflow/contrib/framework/python/framework/__init__.py @@ -19,4 +19,5 @@ from __future__ import division from __future__ import print_function # pylint: disable=wildcard-import +from tensorflow.contrib.framework.python.framework.deprecation import deprecated from tensorflow.contrib.framework.python.framework.tensor_util import * diff --git a/tensorflow/contrib/framework/python/framework/deprecation.py b/tensorflow/contrib/framework/python/framework/deprecation.py new file mode 100644 index 00000000000..fb75139dadf --- /dev/null +++ b/tensorflow/contrib/framework/python/framework/deprecation.py @@ -0,0 +1,112 @@ +# pylint: disable=g-bad-file-header +# Copyright 2016 The TensorFlow Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== + +"""Tensor utility functions.""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +import re + +from tensorflow.python.platform import tf_logging as logging + + +def _get_qualified_name(function): + # Python 3 + if hasattr('__qualname__', function): + return function.__qualname__ + + # Python 2 + if hasattr('im_class', function): + return function.im_class.__name__ + '.' + function.__name__ + return function.__name__ + + +def _add_deprecation_to_docstring(doc, date, instructions): + """Adds a deprecation notice to a docstring.""" + lines = doc.splitlines() + + lines[0] += ' (deprecated)' + + notice = [ + '', + 'THIS FUNCTION IS DEPRECATED. It will be removed after %s.' % date, + 'Instructions for updating:', + '%s' % instructions, + ] + + if len(lines) > 1: + # Make sure that we keep our distance from the main body + if lines[1].strip(): + notice += [''] + + lines = [lines[0]] + notice + lines[1:] + else: + lines += notice + + return '\n'.join(lines) + + +def deprecated(date, instructions): + """Decorator for marking functions or methods deprecated. + + This decorator adds a deprecation warning to a function's docstring. It has + the following format: + + (from ) is deprecated and will be removed after . + Instructions for updating: + + + whenever the decorated function is called. will include the class + name if it is a method. + + It also edits the docstring of the function: ' (deprecated)' is appended + to the first line of the docstring and a deprecation notice is prepended + to the rest of the docstring. + + Args: + date: String. The date the function is scheduled to be removed. Must be + ISO 8601 (YYYY-MM-DD). + instructions: String. Instructions on how to update code using the + deprecated function. + + Returns: + Decorated function or method. + + Raises: + ValueError: If date is not in ISO 8601 format, or instructions are empty. + """ + if not date: + raise ValueError('Tell us what date this will be deprecated!') + if not re.match(r'20\d\d-[01]\d-[0123]\d', date): + raise ValueError('Date must be YYYY-MM-DD.') + if not instructions: + raise ValueError('Don\'t deprecate things without conversion instructions!') + + def deprecated_wrapper(func): + """Deprecation wrapper.""" + def new_func(*args, **kwargs): + logging.warn('%s (from %s) is deprecated and will be removed after %s.\n' + 'Instructions for updating:\n%s', + _get_qualified_name(func), func.__module__, + date, instructions) + return func(*args, **kwargs) + new_func.__name__ = func.__name__ + new_func.__doc__ = _add_deprecation_to_docstring(func.__doc__, date, + instructions) + new_func.__dict__.update(func.__dict__) + return new_func + return deprecated_wrapper diff --git a/tensorflow/contrib/learn/python/learn/ops/dnn_ops.py b/tensorflow/contrib/learn/python/learn/ops/dnn_ops.py index 8e20f6b998c..c1fba21619e 100644 --- a/tensorflow/contrib/learn/python/learn/ops/dnn_ops.py +++ b/tensorflow/contrib/learn/python/learn/ops/dnn_ops.py @@ -20,6 +20,7 @@ from __future__ import division from __future__ import print_function from tensorflow.contrib import layers +from tensorflow.contrib.framework.python.framework.deprecation import deprecated from tensorflow.contrib.learn.python.learn.ops import dropout_ops from tensorflow.python.framework import ops from tensorflow.python.ops import array_ops as array_ops_ @@ -28,6 +29,7 @@ from tensorflow.python.ops import nn from tensorflow.python.ops import variable_scope as vs +@deprecated('2016-08-01', 'Please use tf.contrib.layers.stack instead.') def dnn(tensor_in, hidden_units, activation=nn.relu, dropout=None): """Creates fully connected deep neural network subgraph. -- GitLab