From c8d0d1419b0a38a286463db589bfb530b019d220 Mon Sep 17 00:00:00 2001 From: Shibo Tao <62922815+T8T9@users.noreply.github.com> Date: Thu, 6 Aug 2020 11:44:23 +0800 Subject: [PATCH] add paddle.utils.deprecated. (#25912) * add paddle.utils.deprecated. * add docstring. test=develop * add alias paddle.utils.deprecated. test=develop * rm deprecated in python/paddle/fluid/annotations.py. test=develop * 1. check version before warning. 2. bug fix. test=develop * bug fix. test=develop * use paddle.fluid.require_version. test=develop * fix doc * fix doc. test=develop * fix doc. test=develop * bug fix. test=develop * use packaging.version. test=develop. * enhance doc. test=develop * add compare_version function. test=develop * add version.py. test=develop * remove packaging. test=develop * move compare_version to deprecated.py. test=develop * remove print. test=develop * fix. test=develop * fix. test=develop * fix. test=develop * fix. test=develop * inline. test=develop * fix. test=develop --- python/paddle/fluid/annotations.py | 39 --------- .../dygraph_to_static/program_translator.py | 1 - python/paddle/fluid/layers/device.py | 4 +- python/paddle/fluid/layers/nn.py | 2 + python/paddle/utils/__init__.py | 3 +- python/paddle/utils/deprecated.py | 82 +++++++++++++++++++ 6 files changed, 88 insertions(+), 43 deletions(-) delete mode 100644 python/paddle/fluid/annotations.py create mode 100644 python/paddle/utils/deprecated.py diff --git a/python/paddle/fluid/annotations.py b/python/paddle/fluid/annotations.py deleted file mode 100644 index 15e7976354f..00000000000 --- a/python/paddle/fluid/annotations.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (c) 2018 PaddlePaddle 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. - -from __future__ import print_function -import functools -import sys - -__all__ = ['deprecated'] - - -def deprecated(since, instead, extra_message=""): - def decorator(func): - err_msg = "API {0} is deprecated since {1}. Please use {2} instead.".format( - func.__name__, since, instead) - if len(extra_message) != 0: - err_msg += "\n" - err_msg += extra_message - - @functools.wraps(func) - def wrapper(*args, **kwargs): - print(err_msg, file=sys.stderr) - return func(*args, **kwargs) - - wrapper.__doc__ += "\n " - wrapper.__doc__ += err_msg - return wrapper - - return decorator diff --git a/python/paddle/fluid/dygraph/dygraph_to_static/program_translator.py b/python/paddle/fluid/dygraph/dygraph_to_static/program_translator.py index 6272f7369ec..79e812ff619 100644 --- a/python/paddle/fluid/dygraph/dygraph_to_static/program_translator.py +++ b/python/paddle/fluid/dygraph/dygraph_to_static/program_translator.py @@ -36,7 +36,6 @@ from paddle.fluid.wrapped_decorator import signature_safe_contextmanager from paddle.fluid.dygraph.base import param_guard from paddle.fluid.data_feeder import check_type from paddle.fluid.dygraph.dygraph_to_static.partial_program import partial_program_from -from paddle.fluid.annotations import deprecated __all__ = ['ProgramTranslator', 'convert_to_static'] diff --git a/python/paddle/fluid/layers/device.py b/python/paddle/fluid/layers/device.py index 78226a52017..42ccdbb8d26 100644 --- a/python/paddle/fluid/layers/device.py +++ b/python/paddle/fluid/layers/device.py @@ -20,12 +20,12 @@ from __future__ import print_function from .layer_function_generator import autodoc from ..framework import unique_name from ..layer_helper import LayerHelper -from ..annotations import deprecated +from paddle.utils import deprecated __all__ = [] -@deprecated(since='0.15.0', instead="ParallelExecutor") +@deprecated(since='0.15.0', update_to="paddle.fluid.ParallelExecutor") @autodoc() def get_places(device_count=None, device_type=None): helper = LayerHelper('get_places', **locals()) diff --git a/python/paddle/fluid/layers/nn.py b/python/paddle/fluid/layers/nn.py index 46fb61745ae..a46391452bb 100644 --- a/python/paddle/fluid/layers/nn.py +++ b/python/paddle/fluid/layers/nn.py @@ -37,6 +37,7 @@ from functools import reduce from .. import core from ..data_feeder import convert_dtype, check_variable_and_dtype, check_type, check_dtype import paddle +from paddle.utils import deprecated __all__ = [ 'fc', @@ -11614,6 +11615,7 @@ Examples: return _elementwise_op(LayerHelper('elementwise_sub', **locals())) +@deprecated(since="2.0.0", update_to="paddle.multiply") def elementwise_mul(x, y, axis=-1, act=None, name=None): """ :alias_main: paddle.elementwise_mul diff --git a/python/paddle/utils/__init__.py b/python/paddle/utils/__init__.py index 33537929044..85d0e133fa4 100644 --- a/python/paddle/utils/__init__.py +++ b/python/paddle/utils/__init__.py @@ -16,8 +16,9 @@ from .plot import Ploter from .profiler import ProfilerOptions from .profiler import Profiler from .profiler import get_profiler +from .deprecated import deprecated -__all__ = ['dump_config', 'Ploter'] +__all__ = ['dump_config', 'Ploter', 'deprecated'] #TODO: define new api under this directory # __all__ = ['unique_name', diff --git a/python/paddle/utils/deprecated.py b/python/paddle/utils/deprecated.py new file mode 100644 index 00000000000..27621c2d872 --- /dev/null +++ b/python/paddle/utils/deprecated.py @@ -0,0 +1,82 @@ +# Copyright (c) 2018 PaddlePaddle 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. +""" +decorator to deprecate a function or class +""" + +import warnings +import functools +import paddle + + +def deprecated(update_to="", since="", reason=""): + """Decorate a function to signify its deprecation. + + This function wraps a method that will soon be removed and does two things: + - The docstring of the API will be modified to include a notice + about deprecation." + - Raises a :class:`~exceptions.DeprecatedWarning` when old API is called. + Args: + since(str): The version at which the decorated method is considered deprecated. + update_to(str): The new API users should use. + reason(str): The reason why the API is deprecated. + Returns: + decorator: decorated function or class. + """ + + def decorator(func): + """construct warning message, and return a decorated function or class.""" + assert isinstance(update_to, str), 'type of "update_to" must be str.' + assert isinstance(since, str), 'type of "since" must be str.' + assert isinstance(reason, str), 'type of "reason" must be str.' + + _since = since.strip() + _update_to = update_to.strip() + _reason = reason.strip() + + msg = 'API "{}.{}" is deprecated'.format(func.__module__, func.__name__) + if len(_since) > 0: + msg += " since {}".format(_since) + msg += ", and may be removed in future versions." + if len(_update_to) > 0: + assert _update_to.startswith( + "paddle." + ), 'Argument update_to must start with "paddle.", your value is "{}"'.format( + update_to) + msg += ' Use "{}" instead.'.format(_update_to) + if len(_reason) > 0: + msg += "\n reason: {}".format(_reason) + + @functools.wraps(func) + def wrapper(*args, **kwargs): + """deprecated warning should be fired in 3 circumstances: + 1. current version is develop version, i.e. "0.0.0", because we assume develop version is always the latest version. + 2. since version is empty, in this case, API is deprecated in all versions. + 3. current version is newer than since version. + """ + v_current = [int(i) for i in paddle.__version__.split(".")] + v_current += [0] * (4 - len(v_current)) + v_since = [int(i) for i in _since.split(".")] + v_since += [0] * (4 - len(v_since)) + if paddle.__version__ == "0.0.0" or _since == "" or v_current >= v_since: + warnings.simplefilter('always', + DeprecationWarning) # turn off filter + warnings.warn(msg, category=DeprecationWarning, stacklevel=2) + warnings.simplefilter('default', + DeprecationWarning) # reset filter + return func(*args, **kwargs) + + return wrapper + + return decorator -- GitLab