未验证 提交 2f50aa22 编写于 作者: J joejiong 提交者: GitHub

add deprecated information to the top of an API docstring (#26818)

As the title
上级 d8984a6b
...@@ -12031,6 +12031,8 @@ for func in [ ...@@ -12031,6 +12031,8 @@ for func in [
elementwise_floordiv, elementwise_floordiv,
]: ]:
op_proto = OpProtoHolder.instance().get_op_proto(func.__name__) op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
# insert the c++ doc string on top of python doc string
func.__doc__ = _generate_doc_string_( func.__doc__ = _generate_doc_string_(
op_proto, op_proto,
additional_args_lines=[ additional_args_lines=[
...@@ -12048,6 +12050,16 @@ for func in [ ...@@ -12048,6 +12050,16 @@ for func in [
"mkldnn_data_type", "Scale_x", "Scale_y", "Scale_out" "mkldnn_data_type", "Scale_x", "Scale_y", "Scale_out"
}) + """\n""" + str(func.__doc__) }) + """\n""" + str(func.__doc__)
doc_list = func.__doc__.splitlines()
for idx, val in enumerate(doc_list):
if val.startswith("Warning: ") and val.endswith(
" instead."
) and "and will be removed in future versions." in val:
doc_list.insert(0, doc_list.pop(idx))
func.__doc__ = "\n" + "\n".join(i for i in doc_list)
break
for func in []: for func in []:
op_proto = OpProtoHolder.instance().get_op_proto(func.__name__) op_proto = OpProtoHolder.instance().get_op_proto(func.__name__)
func.__doc__ = _generate_doc_string_( func.__doc__ = _generate_doc_string_(
......
# Copyright (c) 2020 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 paddle
import numpy as np
import paddle
import paddle.fluid as fluid
from paddle.static import Program, program_guard
import unittest
import paddle.fluid.core as core
import sys
LOWEST_WARNING_POSTION = 3
ERROR_WARNING_POSTION = sys.maxsize
# custom paddle version
paddle.version.major = '1'
paddle.version.minor = '8'
paddle.version.patch = '0'
paddle.version.rc = '0'
paddle.__version__ = '1.8.0'
paddle.version.full_version = '1.8.0'
print("current paddle version: ", paddle.__version__)
paddle.disable_static()
def get_warning_index(api):
"""
Given an paddle API, return the index of the Warinng information in its doc string if exists;
If Warinng information doesn't exist, return the default ERROR_WARNING_POSTION, sys.maxsize.
Args:
API (python object)
Returns:
index (int): the index of the Warinng information in its doc string if exists.
"""
doc_lst = api.__doc__.splitlines()
for idx, val in enumerate(doc_lst):
if val.startswith("Warning: ") and val.endswith(
" instead."
) and "and will be removed in future versions." in val:
return idx
return ERROR_WARNING_POSTION
class TestDeprecatedDocorator(unittest.TestCase):
"""
tests for paddle's Deprecated Docorator.
test_fluid_data: test for old fluid.data API.
test_fluid_elementwise_mul: test for old fluid.layers.elementwise_xxx APIs.
test_new_multiply: test for new api, which should not insert warning information.
test_ops_elementwise_mul: test for C++ elementwise_mul op, which should not insert warning information.
"""
def test_fluid_data(self):
"""
test old fluid elementwise_mul api, it should fire Warinng function,
which insert the Warinng info on top of API's doc string.
"""
# Initialization
x = fluid.data(name='x', shape=[3, 2, 1], dtype='float32')
# expected
expected = LOWEST_WARNING_POSTION
# captured
captured = get_warning_index(fluid.data)
# testting
self.assertGreater(expected, captured)
def test_fluid_elementwise_mul(self):
"""
test old fluid elementwise_mul api, it should trigger Warinng function,
which insert the Warinng info on top of API's doc string.
"""
# Initialization
a = np.random.uniform(0.1, 1, [51, 76]).astype(np.float32)
b = np.random.uniform(0.1, 1, [51, 76]).astype(np.float32)
x = paddle.to_tensor(a)
y = paddle.to_tensor(b)
res = fluid.layers.elementwise_mul(x, y)
# expected
expected = LOWEST_WARNING_POSTION
# captured
captured = get_warning_index(fluid.layers.elementwise_mul)
# testting
self.assertGreater(expected, captured)
def test_new_multiply(self):
"""
Test for new multiply api, expected result should be False.
"""
a = np.random.uniform(0.1, 1, [51, 76]).astype(np.float32)
b = np.random.uniform(0.1, 1, [51, 76]).astype(np.float32)
x = paddle.to_tensor(a)
y = paddle.to_tensor(b)
res = paddle.multiply(x, y)
# expected
expected = LOWEST_WARNING_POSTION
# captured
captured = get_warning_index(paddle.multiply)
# testting
self.assertLess(expected, captured)
def test_ops_elementwise_mul(self):
"""
Test for new C++ elementwise_op, expected result should be True,
because not matter what fluid.layers.elementwise_mul is deprecated.
"""
a = np.random.uniform(0.1, 1, [51, 76]).astype(np.float32)
b = np.random.uniform(0.1, 1, [51, 76]).astype(np.float32)
x = paddle.to_tensor(a)
y = paddle.to_tensor(b)
res = core.ops.elementwise_mul(x, y)
# expected
expected = LOWEST_WARNING_POSTION
# captured
captured = get_warning_index(fluid.layers.elementwise_mul)
# testting
self.assertGreater(expected, captured)
if __name__ == '__main__':
unittest.main()
...@@ -45,7 +45,7 @@ def deprecated(update_to="", since="", reason=""): ...@@ -45,7 +45,7 @@ def deprecated(update_to="", since="", reason=""):
def decorator(func): def decorator(func):
# TODO(zhiqiu): We temporally disable the warnings for 2.0-bata, and it should be re-enabled in the future. # TODO(zhiqiu): We temporally disable the warnings for 2.0-bata, and it should be re-enabled in the future.
return func # return func
"""construct warning message, and return a decorated function or class.""" """construct warning message, and return a decorated function or class."""
assert isinstance(update_to, str), 'type of "update_to" must be str.' assert isinstance(update_to, str), 'type of "update_to" must be str.'
assert isinstance(since, str), 'type of "since" must be str.' assert isinstance(since, str), 'type of "since" must be str.'
...@@ -56,9 +56,10 @@ def deprecated(update_to="", since="", reason=""): ...@@ -56,9 +56,10 @@ def deprecated(update_to="", since="", reason=""):
_reason = reason.strip() _reason = reason.strip()
msg = 'API "{}.{}" is deprecated'.format(func.__module__, func.__name__) msg = 'API "{}.{}" is deprecated'.format(func.__module__, func.__name__)
if len(_since) > 0: if len(_since) > 0:
msg += " since {}".format(_since) msg += " since {}".format(_since)
msg += ", and may be removed in future versions." msg += ", and will be removed in future versions."
if len(_update_to) > 0: if len(_update_to) > 0:
assert _update_to.startswith( assert _update_to.startswith(
"paddle." "paddle."
...@@ -67,6 +68,11 @@ def deprecated(update_to="", since="", reason=""): ...@@ -67,6 +68,11 @@ def deprecated(update_to="", since="", reason=""):
msg += ' Please use "{}" instead.'.format(_update_to) msg += ' Please use "{}" instead.'.format(_update_to)
if len(_reason) > 0: if len(_reason) > 0:
msg += "\n reason: {}".format(_reason) msg += "\n reason: {}".format(_reason)
if func.__doc__:
func.__doc__ = ('\n\nWarning: ' + msg + '\n') + func.__doc__
# TODO(Joejiong) Early returning the wrapper function, currently we disable the warning wrapper,
# because the 2.0beta APIs are still under development, we will restore the warning functionality when 2.0 rc APIs become stable.
return func
@functools.wraps(func) @functools.wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
...@@ -75,6 +81,7 @@ def deprecated(update_to="", since="", reason=""): ...@@ -75,6 +81,7 @@ def deprecated(update_to="", since="", reason=""):
2. since version is empty, in this case, API is deprecated in all versions. 2. since version is empty, in this case, API is deprecated in all versions.
3. current version is newer than since version. 3. current version is newer than since version.
""" """
msg = "\033[93mWarning %s \033[0m" % (msg)
v_current = [int(i) for i in paddle.__version__.split(".")] v_current = [int(i) for i in paddle.__version__.split(".")]
v_current += [0] * (4 - len(v_current)) v_current += [0] * (4 - len(v_current))
v_since = [int(i) for i in _since.split(".")] v_since = [int(i) for i in _since.split(".")]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册