From 396acc5b31e000e7b97086dfc5d0e6b2e3280db2 Mon Sep 17 00:00:00 2001 From: Tomas Sebestik Date: Mon, 10 May 2021 16:30:03 +0200 Subject: [PATCH] Change logic for MYPY checker --- tools/ci/check_type_comments.py | 60 ++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/tools/ci/check_type_comments.py b/tools/ci/check_type_comments.py index 4b41405269..1ce8c31647 100755 --- a/tools/ci/check_type_comments.py +++ b/tools/ci/check_type_comments.py @@ -15,7 +15,6 @@ # limitations under the License. import argparse -import re import subprocess from sys import exit @@ -26,50 +25,63 @@ except ImportError: pass IGNORE_LIST_MYPY = 'tools/ci/mypy_ignore_list.txt' -COMMENT_RE = re.compile(r'#\s+type:\s+\(', re.MULTILINE) # REGEX: "# type: (" -def type_comments_in_file(file_name): # type: (str) -> bool - """ Check if type annotations (type comments) are present in the file """ - with open(file_name, 'r') as f: - return bool(COMMENT_RE.search(f.read())) +def types_valid_global_rules(file_name, ignorelisted): # type: (str, bool) -> bool + """ + Run Mypy check with global rules on the given file, return TRUE if Mypy check passes + """ + output = subprocess.DEVNULL if ignorelisted else None + mypy_exit_code = subprocess.call('mypy {}'.format(file_name), shell=True, stdout=output) + + return not bool(mypy_exit_code) -def types_valid(file_name): # type: (str) -> bool - """ Run Mypy check on the given file, return TRUE if Mypy check passes """ - mypy_exit_code = subprocess.call(('mypy %s' % file_name), shell=True) +def types_valid_ignored_rules(file_name): # type: (str) -> bool + """ + Run Mypy check with rules for ignore list on the given file, return TRUE if Mypy check passes + """ + mypy_exit_code = subprocess.call('mypy {} --allow-untyped-defs'.format(file_name), shell=True) return not bool(mypy_exit_code) def check_files(files): # type: (List[str]) -> List[str] """ Check files for type annotatins: - - new python file -> run Mypy check - - existed file updated by type annotations -> run Mypy check, remove from ignore list - - existed file updated, but no type annotations added -> skip Mypy check on file + - new python file -> run Mypy check with global rules + - existed file on ignore list -> run Mypy check with Global rules: + global check OK -> remove from ignore list (updates on the file system) + global check FAILS -> run Mypy check with Ignored rules + Global rules: Enforce type annotations for all functions in file + Ignored rules: Do not enforce untyped functions, check only already typed """ type_issues = [] with open(IGNORE_LIST_MYPY, 'r') as f: ignore_list = [item.strip() for item in f.readlines()] - updated_list = ignore_list.copy() + updated_ignore_list = ignore_list.copy() for file_name in files: if file_name in ignore_list: - if type_comments_in_file(file_name): - if types_valid(file_name): - updated_list.remove(file_name) - print('\33[93m\n File %s removed automatically from ignore list - run commit again! \n\33[0m' % file_name) - else: - type_issues.append(file_name) - else: - if not types_valid(file_name): + if types_valid_global_rules(file_name, ignorelisted=True): + updated_ignore_list.remove(file_name) + print('\33[93m\n File {} removed from ignore list - run commit again! \n\33[0m'.format(file_name)) + continue + + if types_valid_ignored_rules(file_name): + continue + else: type_issues.append(file_name) - if updated_list != ignore_list: + else: + if not types_valid_global_rules(file_name, ignorelisted=False): + type_issues.append(file_name) + + if updated_ignore_list != ignore_list: with open(IGNORE_LIST_MYPY, 'w') as f: - for item in updated_list: - f.write('%s\n' % item) + for item in updated_ignore_list: + f.write('{}\n'.format(item)) + return type_issues