[Git][ghc/ghc][wip/junit-fixes] It passes mypy

Ben Gamari gitlab at gitlab.haskell.org
Sun Jun 23 14:25:45 UTC 2019



Ben Gamari pushed to branch wip/junit-fixes at Glasgow Haskell Compiler / GHC


Commits:
302f3179 by Ben Gamari at 2019-06-23T14:25:06Z
It passes mypy

- - - - -


5 changed files:

- testsuite/driver/my_typing.py
- testsuite/driver/perf_notes.py
- testsuite/driver/runtests.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py


Changes:

=====================================
testsuite/driver/my_typing.py
=====================================
@@ -37,3 +37,7 @@ WayName = NewType("WayName", str)
 TestName = NewType("TestName", str)
 OutputNormalizer = Callable[[str], str]
 IssueNumber = NewType("IssueNumber", int)
+
+# Used by perf_notes
+GitHash = NewType("GitHash", str)
+GitRef = NewType("GitRef", str)


=====================================
testsuite/driver/perf_notes.py
=====================================
@@ -23,6 +23,7 @@ from math import ceil, trunc
 
 from testutil import passed, failBecause, testing_metrics
 
+from my_typing import *
 
 # Check if "git rev-parse" can be run successfully.
 # True implies the current directory is a git repo.
@@ -73,7 +74,8 @@ def parse_perf_stat(stat_str):
 
 # Get all recorded (in a git note) metrics for a given commit.
 # Returns an empty array if the note is not found.
-def get_perf_stats(commit='HEAD', namespace='perf'):
+def get_perf_stats(commit: GitRef=GitRef('HEAD'),
+                   namespace: str='perf'):
     try:
         log = subprocess.check_output(['git', 'notes', '--ref=' + namespace, 'show', commit], stderr=subprocess.STDOUT).decode('utf-8')
     except subprocess.CalledProcessError:
@@ -85,20 +87,19 @@ def get_perf_stats(commit='HEAD', namespace='perf'):
     return log
 
 # Check if a str is in a 40 character git commit hash.
-# str -> bool
 _commit_hash_re = re.compile('[0-9a-f]' * 40)
-def is_commit_hash(hash):
+def is_commit_hash(hash: str) -> bool:
     return _commit_hash_re.fullmatch(hash) != None
 
 # Convert a <ref> to a commit hash code.
-# str -> str
-def commit_hash(commit):
+def commit_hash(commit: Union[GitHash, GitRef]) -> GitHash:
     if is_commit_hash(commit):
-        return commit
-    return subprocess.check_output(['git', 'rev-parse', commit], \
+        return GitHash(commit)
+    hash = subprocess.check_output(['git', 'rev-parse', commit], \
             stderr=subprocess.STDOUT) \
             .decode() \
             .strip()
+    return GitHash(hash)
 
 # Get allowed changes to performance. This is extracted from the commit message of
 # the given commit in this form:
@@ -113,27 +114,27 @@ def commit_hash(commit):
 #                   ...
 #               }
 #   }
-_get_allowed_perf_changes_cache = {}
-def get_allowed_perf_changes(commit='HEAD'):
+_get_allowed_perf_changes_cache = {} # type: ignore
+def get_allowed_perf_changes(commit: GitRef=GitRef('HEAD')):
     global _get_allowed_perf_changes_cache
-    commit =  commit_hash(commit)
-    if not commit in _get_allowed_perf_changes_cache:
-        _get_allowed_perf_changes_cache[commit] \
-            = parse_allowed_perf_changes(get_commit_message(commit))
-    return _get_allowed_perf_changes_cache[commit]
+    chash = commit_hash(commit)
+    if not chash in _get_allowed_perf_changes_cache:
+        _get_allowed_perf_changes_cache[chash] \
+            = parse_allowed_perf_changes(get_commit_message(chash))
+    return _get_allowed_perf_changes_cache[chash]
 
 # Get the commit message of any commit <ref>.
 # This is cached (keyed on the full commit hash).
-_get_commit_message = {}
-def get_commit_message(commit='HEAD'):
+_get_commit_message = {} # type: Dict[GitHash, str]
+def get_commit_message(commit: Union[GitHash, GitRef]=GitRef('HEAD')):
     global _get_commit_message
-    commit =  commit_hash(commit)
+    commit = commit_hash(commit)
     if not commit in _get_commit_message:
         _get_commit_message[commit] = subprocess.check_output(\
             ['git', '--no-pager', 'log', '-n1', '--format=%B', commit]).decode()
     return _get_commit_message[commit]
 
-def parse_allowed_perf_changes(commitMsg):
+def parse_allowed_perf_changes(commitMsg: str):
     # Helper regex. Non-capturing unless postfixed with Cap.
     s = r"(?:\s*\n?\s+)"                                    # Space, possible new line with an indent.
     qstr = r"(?:'(?:[^'\\]|\\.)*')"                         # Quoted string.
@@ -150,7 +151,7 @@ def parse_allowed_perf_changes(commitMsg):
         )
 
     matches = re.findall(exp, commitMsg, re.M)
-    changes = {}
+    changes = {} # type: ignore
     for (direction, metrics_str, opts_str, tests_str) in matches:
         tests = tests_str.split()
         for test in tests:
@@ -300,18 +301,18 @@ def best_fit_ci_test_env():
 
     return BestFitCiTestEnv[1]
 
-_baseline_depth_commit_log = {}
+_baseline_depth_commit_log = {} # type: ignore
 
 # Get the commit hashes for the last BaselineSearchDepth commits from and
 # including the input commit. The output commits are all commit hashes.
 # str -> [str]
-def baseline_commit_log(commit):
+def baseline_commit_log(commit: GitRef):
     global _baseline_depth_commit_log
-    commit = commit_hash(commit)
+    chash = commit_hash(commit)
     if not commit in _baseline_depth_commit_log:
-        _baseline_depth_commit_log[commit] = commit_log(commit, BaselineSearchDepth)
+        _baseline_depth_commit_log[chash] = commit_log(chash, BaselineSearchDepth)
 
-    return _baseline_depth_commit_log[commit]
+    return _baseline_depth_commit_log[chash]
 
 # Get the commit hashes for the last n commits from and
 # including the input commit. The output commits are all commit hashes.
@@ -333,7 +334,7 @@ def commit_log(commitOrRange, n=None):
 # Cache of baseline values. This is a dict of dicts indexed on:
 # (useCiNamespace, commit) -> (test_env, test, metric, way) -> baseline
 # (bool          , str   ) -> (str     , str , str   , str) -> float
-_commit_metric_cache = {}
+_commit_metric_cache = {} # type: ignore
 
 # Get the baseline of a test at a given commit. This is the expected value
 # *before* the commit is applied (i.e. on the parent commit).
@@ -350,7 +351,7 @@ _commit_metric_cache = {}
 # returns: the Baseline named tuple or None if no metric was found within
 #          BaselineSearchDepth commits and since the last expected change
 #          (ignoring any expected change in the given commit).
-def baseline_metric(commit, name, test_env, metric, way):
+def baseline_metric(commit: GitRef, name: str, test_env: str, metric: str, way: str):
     # For performance reasons (in order to avoid calling commit_hash), we assert
     # commit is already a commit hash.
     assert is_commit_hash(commit)
@@ -556,9 +557,9 @@ if __name__ == '__main__':
 
     env = 'local'
     name = re.compile('.*')
-    # metrics is a tuple (str commit, PerfStat stat)
-    CommitAndStat = namedtuple('CommitAndStat', ['commit', 'stat'])
-    metrics = []
+    CommitAndStat = NamedTuple('CommitAndStat',
+                               [('commit', GitHash), ('stat', PerfStat)])
+    metrics = [] # type: List[CommitAndStat]
     singleton_commit = len(args.commits) == 1
 
     #


=====================================
testsuite/driver/runtests.py
=====================================
@@ -24,7 +24,7 @@ import traceback
 import subprocess
 
 from testutil import getStdout, Watcher, str_warn, str_info
-from testglobals import getConfig, ghc_env, getTestRun, TestOptions, brokens
+from testglobals import getConfig, ghc_env, getTestRun, TestConfig, TestOptions, brokens
 from perf_notes import MetricChange, inside_git_repo, is_worktree_dirty
 from junit import junit
 import cpu_features
@@ -39,7 +39,11 @@ global config
 config = getConfig() # get it from testglobals
 
 def signal_handler(signal, frame):
-        stopNow()
+    stopNow()
+
+def get_compiler_info() -> TestConfig:
+    """ Overriddden by configuration file. """
+    raise NotImplementedError
 
 # -----------------------------------------------------------------------------
 # cmd-line options
@@ -154,7 +158,7 @@ if windows:
     import ctypes
     # Windows and mingw* Python provide windll, msys2 python provides cdll.
     if hasattr(ctypes, 'WinDLL'):
-        mydll = ctypes.WinDLL
+        mydll = ctypes.WinDLL    # type: ignore
     else:
         mydll = ctypes.CDLL
 


=====================================
testsuite/driver/testglobals.py
=====================================
@@ -140,6 +140,9 @@ class TestConfig:
         # Are we testing an in-tree compiler?
         self.in_tree_compiler = True
 
+        # Is the compiler dynamically linked?
+        self.ghc_dynamic = False
+
         # the timeout program
         self.timeout_prog = ''
         self.timeout = 300
@@ -171,6 +174,9 @@ class TestConfig:
         # Should we cleanup after test runs?
         self.cleanup = True
 
+        # I have no idea what this does
+        self.package_conf_cache_file = None # type: Optional[Path]
+
 
 global config
 config = TestConfig()
@@ -262,6 +268,9 @@ class TestOptions:
        # override the expected result for certain ways
        self.expect_fail_for = []
 
+       # the stdin file that this test will use (empty for <name>.stdin)
+       self.srcdir = None
+
        # the stdin file that this test will use (empty for <name>.stdin)
        self.stdin = ''
 
@@ -367,10 +376,14 @@ class TestOptions:
        self.compile_timeout_multiplier = 1.0
        self.run_timeout_multiplier = 1.0
 
-       # Sould we run tests in a local subdirectory (<testname>-run) or
+       # Should we run tests in a local subdirectory (<testname>-run) or
        # in temporary directory in /tmp? See Note [Running tests in /tmp].
        self.local = True
 
+       # The directory where the runtime statistics output from Haddock are
+       # found.
+       self.stats_file_dir = None
+
 # The default set of options
 global default_testopts
 default_testopts = TestOptions()


=====================================
testsuite/driver/testlib.py
=====================================
@@ -38,6 +38,10 @@ if config.use_threads:
 global wantToStop
 wantToStop = False
 
+# I have no idea what the type of this is
+global thisdir_settings
+thisdir_settings = None # type: ignore
+
 def stopNow() -> None:
     global wantToStop
     wantToStop = True
@@ -55,12 +59,12 @@ if config.use_threads:
 else:
     class TestOpts_Local:
         pass
-    testopts_local = TestOpts_Local()
+    testopts_local = TestOpts_Local() # type: ignore
 
-def getTestOpts():
+def getTestOpts() -> TestOptions:
     return testopts_local.x
 
-def setLocalTestOpts(opts):
+def setLocalTestOpts(opts: TestOptions) -> None:
     global testopts_local
     testopts_local.x = opts
 
@@ -716,9 +720,9 @@ def newTestDir(tempdir, dir):
 # Should be equal to entry in toplevel .gitignore.
 testdir_suffix = '.run'
 
-def _newTestDir(name: TestName, opts, tempdir, dir):
+def _newTestDir(name: TestName, opts: TestOptions, tempdir, dir):
     testdir = os.path.join('', *(p for p in PurePath(dir).parts if p != '..'))
-    opts.srcdir = Path(os.path.join(os.getcwd(), dir))
+    opts.srcdir = Path.cwd() / dir
     opts.testdir = Path(os.path.join(tempdir, testdir, name + testdir_suffix))
     opts.compiler_always_flags = config.compiler_always_flags
 
@@ -787,11 +791,11 @@ if config.use_threads:
                 pool_sema.release()
 
 def get_package_cache_timestamp() -> float:
-    if config.package_conf_cache_file == '':
+    if config.package_conf_cache_file is None:
         return 0.0
     else:
         try:
-            return os.stat(config.package_conf_cache_file).st_mtime
+            return config.package_conf_cache_file.stat().st_mtime
         except:
             return 0.0
 
@@ -867,7 +871,7 @@ def test_common_work(watcher: testutil.Watcher,
             elif '*' in filename:
                 # Don't use wildcards in extra_files too much, as
                 # globbing is slow.
-                files.update(f.relative_to(opts.srcdir)
+                files.update(str(Path(f).relative_to(opts.srcdir))
                              for f in glob.iglob(str(in_srcdir(filename))))
 
             elif filename:
@@ -1257,7 +1261,7 @@ def metric_dict(name, way, metric, value):
 # Returns a pass/fail object. Passes if the stats are withing the expected value ranges.
 # This prints the results for the user.
 def check_stats(name, way, stats_file, range_fields) -> Any:
-    head_commit = Perf.commit_hash('HEAD') if Perf.inside_git_repo() else None
+    head_commit = Perf.commit_hash(GitRef('HEAD')) if Perf.inside_git_repo() else None
     result = passed()
     if range_fields:
         try:
@@ -2153,7 +2157,10 @@ def in_srcdir(name: Union[Path, str], suffix: str='') -> Path:
     return getTestOpts().srcdir / add_suffix(name, suffix)
 
 def in_statsdir(name: Union[Path, str], suffix: str='') -> Path:
-    return getTestOpts().stats_file_dir / add_suffix(name, suffix)
+    dir = getTestOpts().stats_file_dir
+    if dir is None:
+        raise TypeError('stats_file_dir is not set')
+    return dir / add_suffix(name, suffix)
 
 # Finding the sample output.  The filename is of the form
 #



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/commit/302f31798b0b74841fa3d470731538878ed5bc73

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/commit/302f31798b0b74841fa3d470731538878ed5bc73
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20190623/dda0025a/attachment-0001.html>


More information about the ghc-commits mailing list