From 7e1a56c9a17c016d3791f981fe190c6f25fbc325 Mon Sep 17 00:00:00 2001 From: ooooo <3164076421@qq.com> Date: Thu, 28 Dec 2023 18:43:12 +0800 Subject: [PATCH 01/15] open_warning --- python/paddle/utils/deprecated.py | 2 +- test/legacy_test/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/paddle/utils/deprecated.py b/python/paddle/utils/deprecated.py index 873c6b3a6a9fce..93d2fd1c13f804 100755 --- a/python/paddle/utils/deprecated.py +++ b/python/paddle/utils/deprecated.py @@ -48,7 +48,7 @@ def deprecated(update_to="", since="", reason="", level=0): def decorator(func): # TODO(zhiqiu): temporally disable the warnings - return func + # return 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.' diff --git a/test/legacy_test/CMakeLists.txt b/test/legacy_test/CMakeLists.txt index 824d50d8a6aaf7..4f848f6d2fae67 100644 --- a/test/legacy_test/CMakeLists.txt +++ b/test/legacy_test/CMakeLists.txt @@ -118,7 +118,7 @@ if(((NOT WITH_ROCM) AND (NOT WITH_GPU)) OR WIN32) list(REMOVE_ITEM TEST_OPS test_fleet_executor_cond_interceptor) endif() -list(REMOVE_ITEM TEST_OPS test_deprecated_decorator) +# list(REMOVE_ITEM TEST_OPS test_deprecated_decorator) if(WIN32) list(REMOVE_ITEM TEST_OPS test_multiprocess_reader_exception) From bc3ec46f1992cf1764698a3841f29109dd772c2c Mon Sep 17 00:00:00 2001 From: ooooo <3164076421@qq.com> Date: Thu, 28 Dec 2023 21:41:27 +0800 Subject: [PATCH 02/15] update unittest --- test/legacy_test/test_deprecated_decorator.py | 30 +++---------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index 81ae80a1f9bf78..cac3fe2e78a553 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -19,19 +19,18 @@ import numpy as np import paddle -from paddle import _legacy_C_ops from paddle.utils import deprecated LOWEST_WARNING_POSTION = 3 ERROR_WARNING_POSTION = sys.maxsize # custom paddle version -paddle.version.major = '1' -paddle.version.minor = '8' +paddle.version.major = '2' +paddle.version.minor = '6' paddle.version.patch = '0' paddle.version.rc = '0' -paddle.__version__ = '1.8.0' -paddle.version.full_version = '1.8.0' +paddle.__version__ = '2.6.0' +paddle.version.full_version = '2.6.0' print("current paddle version: ", paddle.__version__) paddle.disable_static() @@ -87,27 +86,6 @@ def test_new_multiply(self): # 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 base.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 = _legacy_C_ops.elementwise_mul(x, y) - - # expected - expected = LOWEST_WARNING_POSTION - - # captured - captured = get_warning_index(paddle.multiply) - - # testting - self.assertGreater(expected, captured) - def test_tensor_gradient(self): paddle.__version__ = '2.1.0' From ce68f384d1e9f95ea665f0c7176cff87e7c2e774 Mon Sep 17 00:00:00 2001 From: ooooo <3164076421@qq.com> Date: Thu, 28 Dec 2023 21:46:27 +0800 Subject: [PATCH 03/15] update --- test/legacy_test/test_deprecated_decorator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index cac3fe2e78a553..bc05a93c5bfec0 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -25,12 +25,12 @@ ERROR_WARNING_POSTION = sys.maxsize # custom paddle version -paddle.version.major = '2' -paddle.version.minor = '6' +paddle.version.major = '0' +paddle.version.minor = '0' paddle.version.patch = '0' paddle.version.rc = '0' -paddle.__version__ = '2.6.0' -paddle.version.full_version = '2.6.0' +paddle.__version__ = '0.0.0' +paddle.version.full_version = '0.0.0' print("current paddle version: ", paddle.__version__) paddle.disable_static() From e203db5bf58ec086145c58269a106812c89edbc8 Mon Sep 17 00:00:00 2001 From: ooooo <3164076421@qq.com> Date: Thu, 28 Dec 2023 22:16:32 +0800 Subject: [PATCH 04/15] fix typos --- test/legacy_test/CMakeLists.txt | 2 -- test/legacy_test/test_deprecated_decorator.py | 1 - 2 files changed, 3 deletions(-) diff --git a/test/legacy_test/CMakeLists.txt b/test/legacy_test/CMakeLists.txt index 4f848f6d2fae67..ed0f40f982d23c 100644 --- a/test/legacy_test/CMakeLists.txt +++ b/test/legacy_test/CMakeLists.txt @@ -118,8 +118,6 @@ if(((NOT WITH_ROCM) AND (NOT WITH_GPU)) OR WIN32) list(REMOVE_ITEM TEST_OPS test_fleet_executor_cond_interceptor) endif() -# list(REMOVE_ITEM TEST_OPS test_deprecated_decorator) - if(WIN32) list(REMOVE_ITEM TEST_OPS test_multiprocess_reader_exception) list(REMOVE_ITEM TEST_OPS test_trainer_desc) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index bc05a93c5bfec0..511ce1e953e716 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -63,7 +63,6 @@ class TestDeprecatedDocorator(unittest.TestCase): """ tests for paddle's Deprecated Docorator. 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_new_multiply(self): From e8f23bd71b3b935d0158fd825f429edb6b67de34 Mon Sep 17 00:00:00 2001 From: SigureMo Date: Thu, 28 Dec 2023 17:51:18 +0000 Subject: [PATCH 05/15] fix warning in test runner --- test/legacy_test/test_deprecated_decorator.py | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index 511ce1e953e716..e21cd94c5f4eb6 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -33,7 +33,12 @@ paddle.version.full_version = '0.0.0' print("current paddle version: ", paddle.__version__) -paddle.disable_static() + +# NOTE(SigureMo): After Python 3.7, Python hide the DeprecationWarning if the +# module is not __main__. So we need to enables warnings manually. +# See more details from https://peps.python.org/pep-0565/#recommended-filter-settings-for-test-runners +if not sys.warnoptions: + warnings.simplefilter("default") def get_warning_index(api): @@ -65,25 +70,25 @@ class TestDeprecatedDocorator(unittest.TestCase): test_new_multiply: test for new api, which should not insert warning information. """ - def test_new_multiply(self): - """ - Test for new multiply api, expected result should be False. - """ + # 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) + # 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 + # # expected + # expected = LOWEST_WARNING_POSTION - # captured - captured = get_warning_index(paddle.multiply) + # # captured + # captured = get_warning_index(paddle.multiply) - # testting - self.assertLess(expected, captured) + # # testting + # self.assertLess(expected, captured) def test_tensor_gradient(self): paddle.__version__ = '2.1.0' From c4ee9dae8545368b8055b7f60a879294e78bde19 Mon Sep 17 00:00:00 2001 From: SigureMo Date: Thu, 28 Dec 2023 17:52:12 +0000 Subject: [PATCH 06/15] uncomment --- test/legacy_test/test_deprecated_decorator.py | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index e21cd94c5f4eb6..4b7880cbfbc29b 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -70,25 +70,25 @@ class TestDeprecatedDocorator(unittest.TestCase): test_new_multiply: test for new api, which should not insert warning information. """ - # def test_new_multiply(self): - # """ - # Test for new multiply api, expected result should be False. - # """ + 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) + 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 + # expected + expected = LOWEST_WARNING_POSTION - # # captured - # captured = get_warning_index(paddle.multiply) + # captured + captured = get_warning_index(paddle.multiply) - # # testting - # self.assertLess(expected, captured) + # testting + self.assertLess(expected, captured) def test_tensor_gradient(self): paddle.__version__ = '2.1.0' From b2eae644fbf74f6bb05f9c8d55ce4cfb72130247 Mon Sep 17 00:00:00 2001 From: SigureMo Date: Thu, 28 Dec 2023 17:52:54 +0000 Subject: [PATCH 07/15] cleanup todo --- python/paddle/utils/deprecated.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/paddle/utils/deprecated.py b/python/paddle/utils/deprecated.py index 93d2fd1c13f804..2727b2366861bb 100755 --- a/python/paddle/utils/deprecated.py +++ b/python/paddle/utils/deprecated.py @@ -47,8 +47,6 @@ def deprecated(update_to="", since="", reason="", level=0): """ def decorator(func): - # TODO(zhiqiu): temporally disable the warnings - # return 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.' From eb43676b929e8bcd09356beb6cd4199332e666e3 Mon Sep 17 00:00:00 2001 From: SigureMo Date: Thu, 28 Dec 2023 18:27:18 +0000 Subject: [PATCH 08/15] using VisibleDeprecationWarning --- python/paddle/utils/deprecated.py | 14 +++++++++++++- test/legacy_test/test_deprecated_decorator.py | 7 ------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/python/paddle/utils/deprecated.py b/python/paddle/utils/deprecated.py index 2727b2366861bb..dfdf35c27e569a 100755 --- a/python/paddle/utils/deprecated.py +++ b/python/paddle/utils/deprecated.py @@ -24,6 +24,18 @@ __all__ = [] +class VisibleDeprecationWarning(UserWarning): + """Visible deprecation warning. + + After Python 3.7, Python hide the DeprecationWarning if the module is not + __main__. So we use this warning to make the deprecation warning visible. + + See more details from https://peps.python.org/pep-0565/ + """ + + ... + + def deprecated(update_to="", since="", reason="", level=0): """Decorate a function to signify its deprecation. @@ -108,7 +120,7 @@ def wrapper(*args, **kwargs): or v_current >= v_since ): warnings.warn( - warningmsg, category=DeprecationWarning, stacklevel=2 + warningmsg, category=VisibleDeprecationWarning, stacklevel=2 ) return func(*args, **kwargs) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index 4b7880cbfbc29b..61dd40f2cd75f7 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -34,13 +34,6 @@ print("current paddle version: ", paddle.__version__) -# NOTE(SigureMo): After Python 3.7, Python hide the DeprecationWarning if the -# module is not __main__. So we need to enables warnings manually. -# See more details from https://peps.python.org/pep-0565/#recommended-filter-settings-for-test-runners -if not sys.warnoptions: - warnings.simplefilter("default") - - def get_warning_index(api): """ Given an paddle API, return the index of the Warinng information in its doc string if exists; From 8dcc37afbe0332b2efabf1c59202228059de3e91 Mon Sep 17 00:00:00 2001 From: SigureMo Date: Thu, 28 Dec 2023 18:31:18 +0000 Subject: [PATCH 09/15] update comment --- python/paddle/utils/deprecated.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/paddle/utils/deprecated.py b/python/paddle/utils/deprecated.py index dfdf35c27e569a..3623cf9a94c548 100755 --- a/python/paddle/utils/deprecated.py +++ b/python/paddle/utils/deprecated.py @@ -27,8 +27,8 @@ class VisibleDeprecationWarning(UserWarning): """Visible deprecation warning. - After Python 3.7, Python hide the DeprecationWarning if the module is not - __main__. So we use this warning to make the deprecation warning visible. + Since Python 3.7, Python only show the DeprecationWarning if the module + is __main__. So we use this warning to make the deprecation warning visible. See more details from https://peps.python.org/pep-0565/ """ From 100f0ebf206d07604b476782b0edea2f33df9858 Mon Sep 17 00:00:00 2001 From: SigureMo Date: Thu, 28 Dec 2023 18:36:18 +0000 Subject: [PATCH 10/15] fix typo --- test/legacy_test/test_deprecated_decorator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index 61dd40f2cd75f7..35f5319fb3c8a2 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -57,9 +57,9 @@ def get_warning_index(api): return ERROR_WARNING_POSTION -class TestDeprecatedDocorator(unittest.TestCase): +class TestDeprecatedDecorator(unittest.TestCase): """ - tests for paddle's Deprecated Docorator. + tests for paddle's deprecated decorator. test_new_multiply: test for new api, which should not insert warning information. """ From d2b9edcdc1523edd72e18b28c42a0324cfe10815 Mon Sep 17 00:00:00 2001 From: ooooo <3164076421@qq.com> Date: Fri, 29 Dec 2023 12:19:59 +0800 Subject: [PATCH 11/15] fix indentation --- python/paddle/utils/deprecated.py | 6 ++++-- test/legacy_test/test_deprecated_decorator.py | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/python/paddle/utils/deprecated.py b/python/paddle/utils/deprecated.py index 3623cf9a94c548..10403ea7ff7428 100755 --- a/python/paddle/utils/deprecated.py +++ b/python/paddle/utils/deprecated.py @@ -85,9 +85,11 @@ def decorator(func): ) msg += f' Please use "{_update_to}" instead.' if len(_reason) > 0: - msg += f"\nreason: {_reason}" + msg += f"\n Reason: {_reason}" if func.__doc__: - func.__doc__ = ('\n\nWarning: ' + msg + '\n') + func.__doc__ + func.__doc__ = ( + '\n\n Warning:\n ' + msg + '\n' + ) + func.__doc__ if level == 0: return func diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index 35f5319fb3c8a2..fe6db8c96cebab 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -47,11 +47,13 @@ def get_warning_index(api): """ doc_lst = api.__doc__.splitlines() - for idx, val in enumerate(doc_lst): + doc_iter = iter(doc_lst) + for idx, val in enumerate(doc_iter): + next_val = next(doc_iter, None) if ( - val.startswith("Warning: ") - and val.endswith(" instead.") - and "and will be removed in future versions." in val + val.startswith(" Warning:") + and next_val.endswith(" instead.") + and "and will be removed in future versions." in next_val ): return idx return ERROR_WARNING_POSTION From e6ea94208884e9d4a0376329d1aa16808a078682 Mon Sep 17 00:00:00 2001 From: ooooo <3164076421@qq.com> Date: Fri, 29 Dec 2023 12:22:02 +0800 Subject: [PATCH 12/15] fix --- test/legacy_test/test_deprecated_decorator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index fe6db8c96cebab..ec170cfa2dc587 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -51,7 +51,7 @@ def get_warning_index(api): for idx, val in enumerate(doc_iter): next_val = next(doc_iter, None) if ( - val.startswith(" Warning:") + val == (" Warning:\n") and next_val.endswith(" instead.") and "and will be removed in future versions." in next_val ): From b29825392bf9297320c8271747d98ffcb20f73ab Mon Sep 17 00:00:00 2001 From: ooooo <3164076421@qq.com> Date: Fri, 29 Dec 2023 12:37:20 +0800 Subject: [PATCH 13/15] fix --- test/legacy_test/test_deprecated_decorator.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index ec170cfa2dc587..9685482d229e94 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -47,11 +47,10 @@ def get_warning_index(api): """ doc_lst = api.__doc__.splitlines() - doc_iter = iter(doc_lst) - for idx, val in enumerate(doc_iter): - next_val = next(doc_iter, None) + for idx, val in enumerate(doc_lst): + next_val = doc_lst[idx + 1] if idx + 1 < len(doc_lst) else "" if ( - val == (" Warning:\n") + val == (" Warning:") and next_val.endswith(" instead.") and "and will be removed in future versions." in next_val ): From be2277cbd871114c02cb052561ff70e11a862af1 Mon Sep 17 00:00:00 2001 From: ooooo <3164076421@qq.com> Date: Fri, 29 Dec 2023 16:44:01 +0800 Subject: [PATCH 14/15] fix indent level and test --- python/paddle/utils/deprecated.py | 7 ++++--- test/legacy_test/test_deprecated_decorator.py | 13 ++++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/python/paddle/utils/deprecated.py b/python/paddle/utils/deprecated.py index 10403ea7ff7428..39b1f737480987 100755 --- a/python/paddle/utils/deprecated.py +++ b/python/paddle/utils/deprecated.py @@ -16,6 +16,7 @@ """ import functools +import inspect import sys import warnings @@ -85,11 +86,11 @@ def decorator(func): ) msg += f' Please use "{_update_to}" instead.' if len(_reason) > 0: - msg += f"\n Reason: {_reason}" + msg += f"\n Reason: {_reason}" if func.__doc__: func.__doc__ = ( - '\n\n Warning:\n ' + msg + '\n' - ) + func.__doc__ + '\n\nWarning:\n ' + msg + '\n\n' + ) + inspect.cleandoc(func.__doc__) if level == 0: return func diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index 9685482d229e94..194a5af3b67bd9 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -50,7 +50,7 @@ def get_warning_index(api): for idx, val in enumerate(doc_lst): next_val = doc_lst[idx + 1] if idx + 1 < len(doc_lst) else "" if ( - val == (" Warning:") + val == ("Warning:") and next_val.endswith(" instead.") and "and will be removed in future versions." in next_val ): @@ -84,6 +84,17 @@ def test_new_multiply(self): # testting self.assertLess(expected, captured) + def test_indent_level(self): + # test for different indent_level + dataset = paddle.base.DatasetFactory().create_dataset("InMemoryDataset") + with warnings.catch_warnings(record=True): + dataset.set_merge_by_lineid() + print(paddle.base.InMemoryDataset.set_merge_by_lineid.__doc__) + assert ( + '\nSet merge by' + in paddle.base.InMemoryDataset.set_merge_by_lineid.__doc__ + ) + def test_tensor_gradient(self): paddle.__version__ = '2.1.0' From 08de4a8ef49655f6c476cf591fcac7e4cc80f41c Mon Sep 17 00:00:00 2001 From: ooooo <3164076421@qq.com> Date: Fri, 29 Dec 2023 21:01:39 +0800 Subject: [PATCH 15/15] update --- test/legacy_test/test_deprecated_decorator.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/legacy_test/test_deprecated_decorator.py b/test/legacy_test/test_deprecated_decorator.py index 194a5af3b67bd9..0c7ce0f0625900 100755 --- a/test/legacy_test/test_deprecated_decorator.py +++ b/test/legacy_test/test_deprecated_decorator.py @@ -46,13 +46,16 @@ def get_warning_index(api): 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): - next_val = doc_lst[idx + 1] if idx + 1 < len(doc_lst) else "" + doc_list = api.__doc__.splitlines() + if len(doc_list) < 2: + return ERROR_WARNING_POSTION + for idx, (current_line, next_line) in enumerate( + zip(doc_list[:-1], doc_list[1:]) + ): if ( - val == ("Warning:") - and next_val.endswith(" instead.") - and "and will be removed in future versions." in next_val + current_line == "Warning:" + and next_line.endswith(" instead.") + and "and will be removed in future versions." in next_line ): return idx return ERROR_WARNING_POSTION @@ -89,7 +92,6 @@ def test_indent_level(self): dataset = paddle.base.DatasetFactory().create_dataset("InMemoryDataset") with warnings.catch_warnings(record=True): dataset.set_merge_by_lineid() - print(paddle.base.InMemoryDataset.set_merge_by_lineid.__doc__) assert ( '\nSet merge by' in paddle.base.InMemoryDataset.set_merge_by_lineid.__doc__