CI: add initial type annotation checking

pull/6148/head
Michael Hirsch, Ph.D 5 years ago committed by Jussi Pakkanen
parent d080917561
commit 6e708208dd
  1. 7
      azure-pipelines.yml
  2. 2
      mesonbuild/minit.py
  3. 14
      mesonbuild/msetup.py
  4. 6
      mesonbuild/mtest.py
  5. 14
      tools/ac_converter.py
  6. 2
      tools/boost_names.py
  7. 21
      tools/dircondenser.py

@ -11,7 +11,7 @@ variables:
CI: 1 CI: 1
jobs: jobs:
- job: Pylint - job: PylintMyPy
pool: pool:
vmImage: ubuntu-latest vmImage: ubuntu-latest
@ -20,10 +20,11 @@ jobs:
inputs: inputs:
versionSpec: '3.7' versionSpec: '3.7'
addToPath: true addToPath: true
- script: python -m pip install pylint - script: python -m pip install pylint mypy
displayName: Install Pylint displayName: 'Install Pylint, MyPy'
- script: pylint mesonbuild - script: pylint mesonbuild
displayName: Lint Checks displayName: Lint Checks
- script: mypy --follow-imports=skip mesonbuild/mtest.py mesonbuild/minit.py mesonbuild/msetup.py mesonbuild/wrap tools/
- job: vs2015 - job: vs2015

@ -83,7 +83,7 @@ def create_sample(options):
raise RuntimeError('Unreachable code') raise RuntimeError('Unreachable code')
print(info_message) print(info_message)
def autodetect_options(options, sample=False): def autodetect_options(options, sample: bool = False):
if not options.name: if not options.name:
options.name = Path().resolve().stem options.name = Path().resolve().stem
if not re.match('[a-zA-Z_][a-zA-Z0-9]*', options.name) and sample: if not re.match('[a-zA-Z_][a-zA-Z0-9]*', options.name) and sample:

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import typing
import time import time
import sys, stat import sys, stat
import datetime import datetime
@ -96,11 +97,11 @@ class MesonApp:
self.options = options self.options = options
def has_build_file(self, dirname): def has_build_file(self, dirname: str) -> bool:
fname = os.path.join(dirname, environment.build_filename) fname = os.path.join(dirname, environment.build_filename)
return os.path.exists(fname) return os.path.exists(fname)
def validate_core_dirs(self, dir1, dir2): def validate_core_dirs(self, dir1: str, dir2: str) -> typing.Tuple[str, str]:
if dir1 is None: if dir1 is None:
if dir2 is None: if dir2 is None:
if not os.path.exists('meson.build') and os.path.exists('../meson.build'): if not os.path.exists('meson.build') and os.path.exists('../meson.build'):
@ -130,7 +131,7 @@ class MesonApp:
return ndir2, ndir1 return ndir2, ndir1
raise MesonException('Neither directory contains a build file %s.' % environment.build_filename) raise MesonException('Neither directory contains a build file %s.' % environment.build_filename)
def validate_dirs(self, dir1, dir2, reconfigure, wipe): def validate_dirs(self, dir1: str, dir2: str, reconfigure: bool, wipe: bool) -> typing.Tuple[str, str]:
(src_dir, build_dir) = self.validate_core_dirs(dir1, dir2) (src_dir, build_dir) = self.validate_core_dirs(dir1, dir2)
priv_dir = os.path.join(build_dir, 'meson-private/coredata.dat') priv_dir = os.path.join(build_dir, 'meson-private/coredata.dat')
if os.path.exists(priv_dir): if os.path.exists(priv_dir):
@ -142,12 +143,11 @@ class MesonApp:
'\nIf build failures persist, run "meson setup --wipe" to rebuild from scratch\n' '\nIf build failures persist, run "meson setup --wipe" to rebuild from scratch\n'
'using the same options as passed when configuring the build.' 'using the same options as passed when configuring the build.'
'\nTo change option values, run "meson configure" instead.') '\nTo change option values, run "meson configure" instead.')
sys.exit(0) raise SystemExit
else: else:
has_cmd_line_file = os.path.exists(coredata.get_cmd_line_file(build_dir)) has_cmd_line_file = os.path.exists(coredata.get_cmd_line_file(build_dir))
if (wipe and not has_cmd_line_file) or (not wipe and reconfigure): if (wipe and not has_cmd_line_file) or (not wipe and reconfigure):
print('Directory does not contain a valid build tree:\n{}'.format(build_dir)) raise SystemExit('Directory does not contain a valid build tree:\n{}'.format(build_dir))
sys.exit(1)
return src_dir, build_dir return src_dir, build_dir
def generate(self): def generate(self):
@ -239,7 +239,7 @@ class MesonApp:
os.unlink(cdf) os.unlink(cdf)
raise raise
def run(options): def run(options) -> int:
coredata.parse_cmd_line_options(options) coredata.parse_cmd_line_options(options)
app = MesonApp(options) app = MesonApp(options)
app.generate() app.generate()

@ -533,7 +533,7 @@ class SingleTestRunner:
# We don't want setsid() in gdb because gdb needs the # We don't want setsid() in gdb because gdb needs the
# terminal in order to handle ^C and not show tcsetpgrp() # terminal in order to handle ^C and not show tcsetpgrp()
# errors avoid not being able to use the terminal. # errors avoid not being able to use the terminal.
os.setsid() os.setsid() # type: ignore
p = subprocess.Popen(cmd, p = subprocess.Popen(cmd,
stdout=stdout, stdout=stdout,
@ -570,11 +570,11 @@ class SingleTestRunner:
# killing a process and all its children so we need # killing a process and all its children so we need
# to roll our own. # to roll our own.
if is_windows(): if is_windows():
subprocess.call(['taskkill', '/F', '/T', '/PID', str(p.pid)]) subprocess.run(['taskkill', '/F', '/T', '/PID', str(p.pid)])
else: else:
try: try:
# Kill the process group that setsid() created. # Kill the process group that setsid() created.
os.killpg(p.pid, signal.SIGKILL) os.killpg(p.pid, signal.SIGKILL) # type: ignore
except ProcessLookupError: except ProcessLookupError:
# Sometimes (e.g. with Wine) this happens. # Sometimes (e.g. with Wine) this happens.
# There's nothing we can do (maybe the process # There's nothing we can do (maybe the process

@ -389,9 +389,9 @@ with open(sys.argv[1]) as f:
token = arr[1] token = arr[1]
if token in function_data: if token in function_data:
fdata = function_data[token] fdata = function_data[token]
functions.append((token, fdata[0], fdata[1])) functions.append([token, fdata[0], fdata[1]])
elif token.startswith('HAVE_') and not token.endswith('_H'): elif token.startswith('HAVE_') and not token.endswith('_H'):
functions.append((token, )) functions.append([token])
except Exception: except Exception:
pass pass
@ -427,12 +427,12 @@ endforeach
# Convert function checks. # Convert function checks.
print('check_functions = [') print('check_functions = [')
for token in functions: for tok in functions:
if len(token) == 3: if len(tok) == 3:
token, fdata0, fdata1 = token tokstr, fdata0, fdata1 = tok
print(" ['%s', '%s', '#include<%s>']," % (token, fdata0, fdata1)) print(" ['%s', '%s', '#include<%s>']," % (tokstr, fdata0, fdata1))
else: else:
print('# check token', token) print('# check token', tok)
print(']\n') print(']\n')
print('''foreach f : check_functions print('''foreach f : check_functions

@ -31,7 +31,7 @@ import json
import re import re
Module = collections.namedtuple('Module', ['dirname', 'name', 'libnames']) Module = collections.namedtuple('Module', ['dirname', 'name', 'libnames'])
Module.__repr__ = lambda self: str((self.dirname, self.name, self.libnames)) Module.__repr__ = lambda self: str((self.dirname, self.name, self.libnames)) # type: ignore
LIBS = 'libs' LIBS = 'libs'

@ -32,25 +32,28 @@ to this:
This directory must be run from source root as it touches run_unittests.py. This directory must be run from source root as it touches run_unittests.py.
''' '''
import os, sys, subprocess import typing
import os
import sys
import subprocess
from glob import glob from glob import glob
def get_entries(): def get_entries() -> typing.List[typing.Tuple[int, str]]:
entries = [] entries = []
for e in glob('*'): for e in glob('*'):
if not os.path.isdir(e): if not os.path.isdir(e):
sys.exit('Current directory must not contain any files.') raise SystemExit('Current directory must not contain any files.')
(number, rest) = e.split(' ', 1) (number, rest) = e.split(' ', 1)
try: try:
number = int(number) numstr = int(number)
except ValueError: except ValueError:
sys.exit('Dir name %d does not start with a number.' % e) raise SystemExit('Dir name {} does not start with a number.'.format(e))
entries.append((number, rest)) entries.append((numstr, rest))
entries.sort() entries.sort()
return entries return entries
def replace_source(sourcefile, replacements): def replace_source(sourcefile: str, replacements: typing.List[typing.Tuple[str, str]]):
with open(sourcefile, 'r') as f: with open(sourcefile, 'r') as f:
contents = f.read() contents = f.read()
for old_name, new_name in replacements: for old_name, new_name in replacements:
@ -58,7 +61,7 @@ def replace_source(sourcefile, replacements):
with open(sourcefile, 'w') as f: with open(sourcefile, 'w') as f:
f.write(contents) f.write(contents)
def condense(dirname): def condense(dirname: str):
curdir = os.getcwd() curdir = os.getcwd()
os.chdir(dirname) os.chdir(dirname)
entries = get_entries() entries = get_entries()
@ -77,6 +80,6 @@ def condense(dirname):
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) != 1: if len(sys.argv) != 1:
sys.exit('This script takes no arguments.') raise SystemExit('This script takes no arguments.')
for d in glob('test cases/*'): for d in glob('test cases/*'):
condense(d) condense(d)

Loading…
Cancel
Save