diff --git a/tools/check_api_approvals.sh b/tools/check_api_approvals.sh index c0a0b754d5191c7fba197c8947498eccbcec0d61..9391f8cdc014339cfa2cfb5bb4e97ea39d7602f3 100644 --- a/tools/check_api_approvals.sh +++ b/tools/check_api_approvals.sh @@ -63,7 +63,7 @@ fi api_src_spec_diff=`python ${PADDLE_ROOT}/tools/check_api_source_without_core_ops.py ${PADDLE_ROOT}/paddle/fluid/API_DEV.source.md5 ${PADDLE_ROOT}/paddle/fluid/API_PR.source.md5` if [ "$api_src_spec_diff" != "" ]; then echo_line="APIs without core.ops: \n${api_src_spec_diff}\n" - echo_line="${echo_line}You must have one RD (zhiqiu (Recommend) or phlrain) approval for the api change for the opreator-related api without 'core.ops'.\n" + echo_line="${echo_line}You must have one RD (zhiqiu (Recommend) or phlrain) approval for the api change for the opreator-related api without '_C_ops'.\n" echo_line="${echo_line}For more details, please click [https://github.com/PaddlePaddle/Paddle/wiki/paddle_api_development_manual.md]\n" check_approval 1 6888866 43953930 fi diff --git a/tools/count_api_without_core_ops.py b/tools/count_api_without_core_ops.py index e84a03d93e9bbfbc21552e97e98ccc706c1f4317..a2093e34fbacbf0d6145fecdae8d41867708204b 100644 --- a/tools/count_api_without_core_ops.py +++ b/tools/count_api_without_core_ops.py @@ -51,13 +51,23 @@ def split_with_and_without_core_ops(member, cur_name): if cur_name in omitted_list: return + if member.__doc__.find(':api_attr: Static Graph') != -1: + return + + if cur_name.find('ParamBase') != -1 or cur_name.find( + 'Parameter') != -1 or cur_name.find( + 'Variable') != -1 or cur_name.find( + 'control_flow') != -1 or cur_name.find( + 'contrib.mixed_precision') != -1: + return + if inspect.isclass(member): pass else: try: source = inspect.getsource(member) if source.find('append_op') != -1: - if source.find('core.ops') != -1: + if source.find('core.ops') != -1 or source.find('_C_ops') != -1: api_with_ops.append(cur_name) else: api_without_ops.append(cur_name) @@ -117,7 +127,13 @@ def is_primitive(instance): return False -def visit_all_module(mod, visited, func): +ErrorSet = set() +IdSet = set() +skiplist = [] +visited_modules = set() + + +def visit_all_module(mod, func): mod_name = mod.__name__ if mod_name != 'paddle' and not mod_name.startswith('paddle.'): return @@ -125,29 +141,32 @@ def visit_all_module(mod, visited, func): if mod_name.startswith('paddle.fluid.core'): return - if mod in visited: + if mod in visited_modules: return + visited_modules.add(mod) - visited.add(mod) - - for member_name in ( - name - for name in (mod.__all__ if hasattr(mod, "__all__") else dir(mod)) - if not name.startswith("_")): - instance = getattr(mod, member_name, None) - if instance is None: + member_names = dir(mod) + if hasattr(mod, "__all__"): + member_names += mod.__all__ + for member_name in member_names: + if member_name.startswith('_'): continue - - if is_primitive(instance): - continue - - if not hasattr(instance, "__name__"): + cur_name = mod_name + '.' + member_name + if cur_name in skiplist: continue - - if inspect.ismodule(instance): - visit_all_module(instance, visited, func) - else: - visit_member(mod.__name__, instance, func) + try: + instance = getattr(mod, member_name) + if inspect.ismodule(instance): + visit_all_module(instance, func) + else: + instance_id = id(instance) + if instance_id in IdSet: + continue + IdSet.add(instance_id) + visit_member(mod.__name__, instance, func) + except: + if not cur_name in ErrorSet and not cur_name in skiplist: + ErrorSet.add(cur_name) def get_apis_with_and_without_core_ops(modules): @@ -156,7 +175,7 @@ def get_apis_with_and_without_core_ops(modules): api_without_ops = [] for m in modules: visit_all_module( - importlib.import_module(m), set(), split_with_and_without_core_ops) + importlib.import_module(m), split_with_and_without_core_ops) return api_with_ops, api_without_ops @@ -164,7 +183,7 @@ def get_api_source_desc(modules): global func_dict func_dict = collections.OrderedDict() for m in modules: - visit_all_module(importlib.import_module(m), set(), get_md5_of_func) + visit_all_module(importlib.import_module(m), get_md5_of_func) return func_dict