ソースを参照

Change logic for MYPY checker

Tomas Sebestik 4 年 前
コミット
396acc5b31
1 ファイル変更35 行追加23 行削除
  1. 35 23
      tools/ci/check_type_comments.py

+ 35 - 23
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)
+            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)
+
         else:
-            if not types_valid(file_name):
+            if not types_valid_global_rules(file_name, ignorelisted=False):
                 type_issues.append(file_name)
 
-    if updated_list != ignore_list:
+    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