diff --git a/Makefile.in b/Makefile.in index 149e19987..cec040d0b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -551,6 +551,9 @@ format-make: format-yaml: yamlfix +MYPY = mypy +MYPY_FLAGS = --strict --no-error-summary + PYLINT = pylint PYLINT_FLAGS = --recursive=n --score=n --disable=R0801 PYLINT_TEST_FLAGS = $(PYLINT_FLAGS) --disable=C0103,C0114,C0116,C0209,C0411,C0413,C0301,R0801,R0912,R0915,R0916,R1702,W0511,W0621 @@ -562,6 +565,16 @@ RUFF_FLAGS = check --ignore=E402,E501,E701 lint-py: $(MAKE) -k lint-py-pylint lint-py-pylint-tests lint-py-ruff +lint-py-mypy: + for filename in `fgrep -l '# mypy' $(PY_PROGRAMS)`; do \ + echo "$(MYPY) $(MYPY_FLAGS) $$filename" ; \ + $(MYPY) $(MYPY_FLAGS) $$filename ; \ + done + @echo "Not mypy checked: " `fgrep -L '# mypy' $(PY_PROGRAMS)` + +lint-py-mypy-none: + @echo "mypy not checking: " `fgrep -L '# mypy' $(PY_PROGRAMS)` + lint-py-pylint: $(PYLINT) $(PYLINT_FLAGS) $(PY_PROGRAMS) diff --git a/bin/verilator_ccache_report b/bin/verilator_ccache_report index 2c39d4f30..3ddd38491 100755 --- a/bin/verilator_ccache_report +++ b/bin/verilator_ccache_report @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0103,C0114,C0115,C0116,C0123,C0209,C0301,R0902,R0913,R0914,R0912,R0915,W0621 ###################################################################### @@ -36,7 +37,7 @@ results = {} elapsed = {} -def toDateTime(s): +def toDateTime(s: str) -> datetime: return datetime.strptime(s, "%Y-%m-%dT%H:%M:%S.%f") @@ -53,6 +54,7 @@ for logfile in args.logdir.iterdir(): match = re.match(r'\[(\S+)\s.*Result: (.*)$', line) if match: assert obj is not None + assert start is not None elapsed[obj] = toDateTime(match.group(1)) - start results[obj] = match.group(2) diff --git a/bin/verilator_difftree b/bin/verilator_difftree index f63b1024c..7ab32425c 100755 --- a/bin/verilator_difftree +++ b/bin/verilator_difftree @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0103,C0114,C0116,C0209,W0603 ###################################################################### @@ -12,7 +13,7 @@ import sys exit_code = 0 -def diff(a, b): +def diff(a: str, b: str) -> None: if not os.path.exists(a): sys.stderr.write("%Error: No old diff filename found: " + a + "\n") sys.exit(2) @@ -29,9 +30,9 @@ def diff(a, b): sys.exit(2) -def diff_dir(a, b): +def diff_dir(a: str, b: str) -> None: # Diff all files under two directories - files = collections.defaultdict(lambda: {}) + files: dict[str, dict[str, str]] = collections.defaultdict(lambda: {}) for fn in glob.glob(a + "/*.tree"): base = re.sub(r'.*/', '', fn) @@ -54,7 +55,7 @@ def diff_dir(a, b): sys.stderr.write("%Warning: No .tree files found that have similar base names\n") -def diff_file(a, b): +def diff_file(a: str, b: str) -> None: global exit_code # Compare the two tree files @@ -82,20 +83,7 @@ def diff_file(a, b): exit_code = 2 -def version_from(filename): - # Return dump format - with open(filename, "r", encoding="utf8") as fh: - lineno = 0 - for line in fh: - if lineno > 10: - break - match = re.search(r'format (0x[0-9.]+)', line) - if match: - return hex(match.group(1)) - return 1.0 - - -def filterf(fn1, fn2): +def filterf(fn1: str, fn2: str) -> None: # Remove hex numbers before diffing with open(fn1, "r", encoding="utf8") as fh1: with open(fn2, "w", encoding="utf8") as fh2: diff --git a/bin/verilator_gantt b/bin/verilator_gantt index 29d335065..63e094818 100755 --- a/bin/verilator_gantt +++ b/bin/verilator_gantt @@ -33,7 +33,7 @@ ThreadScheduleWaitIntervals = [] # list of (start, tick, ecpu) pairs ###################################################################### -def read_data(filename): +def read_data(filename: str) -> None: with open(filename, "r", encoding="utf8") as fh: re_thread = re.compile(r'^VLPROFTHREAD (\d+)$') re_record = re.compile(r'^VLPROFEXEC (\S+) (\d+)(.*)$') @@ -171,7 +171,7 @@ def re_match_result(regexp, line, result_to): ###################################################################### -def report(): +def report() -> None: print("Verilator Gantt report") print("\nArgument settings:") @@ -220,12 +220,12 @@ def report(): print() -def report_numa(): +def report_numa() -> None: print("\nNUMA assignment:") print(" NUMA status = %s" % Global['info']['numa']) -def report_mtasks(): +def report_mtasks() -> None: if not Mtasks: return @@ -342,7 +342,7 @@ def report_mtasks(): print(" e ^ stddev = %0.3f" % math.exp(stddev)) -def report_cpus(): +def report_cpus() -> None: print("\nCPU info:") Global['cpu_sockets'] = collections.defaultdict(lambda: 0) @@ -377,14 +377,14 @@ def report_cpus(): Global['cpu_socket_cores_warning'] = True -def report_sections(): +def report_sections() -> None: for thread, section in Sections.items(): if section: print(f"\nSection profile for thread {thread}:") report_section(section) -def report_section(section): +def report_section(section) -> None: totalTime = collections.defaultdict(lambda: 0) selfTime = collections.defaultdict(lambda: 0) @@ -436,7 +436,7 @@ def report_section(section): ###################################################################### -def write_vcd(filename): +def write_vcd(filename: str) -> None: print("Writing %s" % filename) with open(filename, "w", encoding="utf8") as fh: # dict of dicts of hierarchy elements/signal name -> (code, width) diff --git a/bin/verilator_includer b/bin/verilator_includer index c41755823..f8149cac9 100755 --- a/bin/verilator_includer +++ b/bin/verilator_includer @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0114,C0209 # # Copyright 2003-2025 by Wilson Snyder. This program is free software; you diff --git a/bin/verilator_profcfunc b/bin/verilator_profcfunc index 60c5a428a..f05934900 100755 --- a/bin/verilator_profcfunc +++ b/bin/verilator_profcfunc @@ -10,7 +10,7 @@ import re ###################################################################### -def profcfunc(filename): +def profcfunc(filename: str) -> None: funcs = {} with open(filename, "r", encoding="utf8") as fh: @@ -26,7 +26,7 @@ def profcfunc(filename): calls = float(match.group(3)) func = match.group(4) if func not in funcs: - funcs[func] = {'pct': 0, 'sec': 0, 'calls': 0} + funcs[func] = {'pct': 0.0, 'sec': 0.0, 'calls': 0} funcs[func]['pct'] += pct funcs[func]['sec'] += sec funcs[func]['calls'] += calls @@ -150,7 +150,7 @@ def profcfunc(filename): print((" time seconds seconds calls %-" + str(design_width) + "s type filename and line number") % "design") - cume = 0 + cume = 0.0 for func in sorted(vfuncs.keys(), key=lambda f: vfuncs[f]['sec'], reverse=True): cume += vfuncs[func]['sec'] print(("%6.2f %9.2f %8.2f %10d %-" + str(design_width) + "s %s") % diff --git a/docs/bin/vl_sphinx_extract b/docs/bin/vl_sphinx_extract index 99caea230..f312ac32d 100755 --- a/docs/bin/vl_sphinx_extract +++ b/docs/bin/vl_sphinx_extract @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0112,C0114,C0115,C0116,C0209,C0301,R0903 # -*- Python -*- See copyright, etc below ###################################################################### @@ -11,9 +12,8 @@ import re class VlSphinxExtract: debug = 0 - SkipBasenames = {} - def process(self, filename): + def process(self, filename: str) -> None: with open(filename, "r", encoding="utf8") as fhr: fhw = None for line in fhr: diff --git a/docs/bin/vl_sphinx_fix b/docs/bin/vl_sphinx_fix index 185a0a55d..99ccf1ca3 100755 --- a/docs/bin/vl_sphinx_fix +++ b/docs/bin/vl_sphinx_fix @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0112,C0114,C0115,C0116,C0209,C0301,R0903 # -*- Python -*- See copyright, etc below ###################################################################### @@ -12,19 +13,17 @@ import re class VlSphinxFix: debug = 0 - SkipBasenames = {} - def process(self, path): + def process(self, path: str) -> None: if os.path.isdir(path): for basefile in os.listdir(path): file = os.path.join(path, basefile) - if ((basefile != ".") and (basefile != "..") and basefile not in self.SkipBasenames - and not os.path.islink(file)): + if ((basefile != ".") and (basefile != "..") and not os.path.islink(file)): self.process(file) elif re.search(r'\.(html|tex)$', path): self._edit(path) - def _edit(self, filename): + def _edit(self, filename: str) -> None: is_html = re.search(r'\.(html)$', filename) with open(filename, "r", encoding="utf8") as fhr: origfile = fhr.read() diff --git a/docs/guide/install.rst b/docs/guide/install.rst index fcafa18c9..6aebca34c 100644 --- a/docs/guide/install.rst +++ b/docs/guide/install.rst @@ -160,7 +160,7 @@ Those developing Verilator itself also need these (see internals.rst): sudo apt-get install python3-clang python3-distro pipx yapf3 bear jq python3 -m venv --system-site-packages ~/.verilator_pyenv source ~/.verilator_pyenv/bin/activate - pip3 install sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe gersemi mbake ruff + pip3 install sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe gersemi mbake mypy ruff pip3 install git+https://github.com/antmicro/astsee.git pipx install sarif-tools cpan install Pod::Perldoc diff --git a/nodist/dot_importer b/nodist/dot_importer index c8d335af5..48fda9897 100755 --- a/nodist/dot_importer +++ b/nodist/dot_importer @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0103,C0114,C0115,C0116,C0209,C0301 ###################################################################### @@ -14,7 +15,7 @@ Edges = [] ####################################################################### -def dotread(filename): +def dotread(filename: str) -> None: with open(filename, "r", encoding="utf8") as fh: header = True vnum = 0 @@ -55,7 +56,7 @@ def dotread(filename): ####################################################################### -def cwrite(filename): +def cwrite(filename: str) -> None: with open(filename, "w", encoding="utf8") as fh: fh.write("void V3GraphTestImport::dotImport() {\n") fh.write(" auto* gp = &m_graph;\n") diff --git a/nodist/fuzzer/actual_fail b/nodist/fuzzer/actual_fail index 9bca018f3..bf511c73d 100755 --- a/nodist/fuzzer/actual_fail +++ b/nodist/fuzzer/actual_fail @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0103,C0114,C0115,C0116,C0321,R0911 ###################################################################### # DESCRIPTION: Fuzzer result checker @@ -18,25 +19,25 @@ from subprocess import getstatusoutput from argparse import ArgumentParser -def interesting(s): +def interesting(s: str) -> bool: if 'assert' in s: - return 1 + return True if 'Assert' in s: - return 1 + return True if 'Aborted' in s: - return 1 + return True if 'terminate' in s: if 'unterminated' in s: - return 0 - return 1 + return False + return True if 'Segmentation' in s: - return 1 + return True if 'internal error' in s: - return 1 - return 0 + return True + return False -def main(): +def main() -> None: p = ArgumentParser() p.add_argument('--dir', default='out1/queue') args = p.parse_args() diff --git a/nodist/install_test b/nodist/install_test index 32b750d4f..2704c2532 100755 --- a/nodist/install_test +++ b/nodist/install_test @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0103,C0114,C0115,C0116,C0209,R0801,R0915 ###################################################################### @@ -12,7 +13,7 @@ import sys ###################################################################### -def test(): +def test() -> None: if not os.path.exists("nodist/install_test"): sys.exit("%Error: Run from the top of the verilator kit") @@ -80,30 +81,30 @@ def test(): print("*-* All Finished *-*") -def write_verilog(odir): +def write_verilog(odir: str) -> None: shutil.copy2("examples/make_hello_c/top.v", odir + "/top.v") shutil.copy2("examples/make_hello_c/sim_main.cpp", odir + "/sim_main.cpp") -def cleanenv(): +def cleanenv() -> None: for var in os.environ: if var in ('VERILATOR_ROOT', 'VERILATOR_INCLUDE', 'VERILATOR_NO_OPT_BUILD'): print("unset %s # Was '%s'" % (var, os.environ[var])) del os.environ[var] -def get_cpu_count(): +def get_cpu_count() -> int: try: return len(os.sched_getaffinity(0)) except AttributeError: return multiprocessing.cpu_count() -def calc_jobs(): +def calc_jobs() -> int: return get_cpu_count() + 1 -def run(command): +def run(command: str) -> None: # run a system command, check errors print("\t%s" % command) os.system(command) diff --git a/nodist/lint_py_test_filter b/nodist/lint_py_test_filter index 3cd1c78bf..f6f82f7b5 100755 --- a/nodist/lint_py_test_filter +++ b/nodist/lint_py_test_filter @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable= ###################################################################### @@ -17,7 +18,7 @@ SUPPRESSES = [ ###################################################################### -def process(): +def process() -> None: anymsg = False for line in sys.stdin: line = line.rstrip(); diff --git a/nodist/log_changes b/nodist/log_changes index 5a28f6ecf..2a042d205 100755 --- a/nodist/log_changes +++ b/nodist/log_changes @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0114,C0116,C0209,R0911,R0912,R0915 ###################################################################### @@ -10,7 +11,7 @@ import re ####################################################################### -def message_section(msg): +def message_section(msg: str) -> int: """Return sorting-section number for given commit message""" if re.match(r'^Support', msg): return 10 @@ -27,7 +28,7 @@ def message_section(msg): return 0 -def process(): +def process() -> None: cmd = "git log" msgs = {} diff --git a/nodist/verilator_saif_diff b/nodist/verilator_saif_diff index a29332775..e0be1fbbd 100755 --- a/nodist/verilator_saif_diff +++ b/nodist/verilator_saif_diff @@ -19,12 +19,12 @@ SIGNAL_TYPE = "SIGNAL" EOF_ERROR = "Unexpected EOF" -def saif_assert(expression, message): +def saif_assert(expression : bool, message : str) -> None: if not expression: raise Exception(message) -def saif_error(message): +def saif_error(message : str) -> None: raise Exception(message) @@ -34,7 +34,7 @@ class SAIFSignalBit: low_time: int transitions: int - def __init__(self, name): + def __init__(self, name : str): self.name = name self.high_time = 0 self.low_time = 0 @@ -43,7 +43,7 @@ class SAIFSignalBit: class SAIFInstance: - def __init__(self, scope_name): + def __init__(self, scope_name : str): self.scope_name = scope_name self.parent_instance = None self.nets = {} @@ -52,7 +52,7 @@ class SAIFInstance: class SAIFToken: - def __init__(self, token): + def __init__(self, token : str): self.token = token self.type = '' self.value = '' @@ -69,11 +69,11 @@ class SAIFParser: self.direction = '' self.saif_version = '' self.top_instances = {} - self.duration = 0 + self.duration = '' self.divider = '' self.timescale = '' - def parse(self, saif_filename): + def parse(self, saif_filename : str) -> None: file_contents = '' with open(saif_filename, 'r', encoding="utf8") as saif_file: content = saif_file.readlines() @@ -180,7 +180,7 @@ class SAIFParser: saif_assert(len(self.token_stack) == 1, "Incorrect nesting of scopes") -def compare_saif_instances(first: SAIFInstance, second: SAIFInstance): +def compare_saif_instances(first: SAIFInstance, second: SAIFInstance) -> None: if len(first.nets) != len(second.nets): saif_error(f"Number of nets doesn't match in {first.scope_name}: " f"{len(first.nets)} != {len(second.nets)}") @@ -202,7 +202,7 @@ def compare_saif_instances(first: SAIFInstance, second: SAIFInstance): compare_saif_instances(instance, second.child_instances[instance_name]) -def compare_saif_contents(first_file: str, second_file: str): +def compare_saif_contents(first_file: str, second_file: str) -> int: """Test if second SAIF file has the same values as the first""" first_saif = SAIFParser() first_saif.parse(first_file) diff --git a/src/bisonpre b/src/bisonpre index e14b8170b..e2817eee9 100755 --- a/src/bisonpre +++ b/src/bisonpre @@ -11,10 +11,10 @@ import sys ###################################################################### -Bison_Version = None +Bison_Version = 0.0 -def process(): +def process() -> None: unlink_outputs() supports_report = Bison_Version >= 2.3 @@ -56,43 +56,43 @@ def process(): unlink_tmp() -def tmp_prefix(): +def tmp_prefix() -> str: return output_prefix() + "_pretmp" -def output_prefix(): +def output_prefix() -> str: if Args.output: o = re.sub(r'\.[^.]*$', '', Args.output) return o - return Args.file_prefix + ".tab" + return str(Args.file_prefix) + ".tab" -def unlink_ok(filename): +def unlink_ok(filename: str) -> None: try: os.unlink(filename) except OSError: pass -def unlink_tmp(): +def unlink_tmp() -> None: unlink_ok(tmp_prefix() + ".c") unlink_ok(tmp_prefix() + ".h") unlink_ok(tmp_prefix() + ".output") -def unlink_outputs(): +def unlink_outputs() -> None: unlink_tmp() unlink_ok(output_prefix() + ".c") unlink_ok(output_prefix() + ".h") # We don't remove .output file, as it's useful for debugging errors -def bison_version_check(): +def bison_version_check() -> float: with subprocess.Popen([Args.yacc, "--version"], stdout=subprocess.PIPE) as sp: out = str(sp.stdout.read()) - match = re.search(r'([0-9]+\.[0-9]+)', out) - if match: - v = float(match.group(1)) + m = re.search(r'([0-9]+\.[0-9]+)', out) + if m: + v = float(m.group(1)) if v < 1.875: sys.exit("bisonpre: %Error: '" + Args.yacc + "' is version " + v + "; version 1.875 or newer is required\n") @@ -101,14 +101,14 @@ def bison_version_check(): sys.exit("bisonpre: %Error: '" + Args.yacc + "' is not installed, or not working\n") -def clean_output(filename, outname, is_output, is_c): +def clean_output(filename: str, outname: str, is_output: bool, is_c: bool) -> None: print(" edit " + filename + " " + outname) with open(filename, "r", encoding="utf-8") as fh: lines = fh.readlines() if is_output: - state_line = {} + state_line: dict[str, int] = {} lineno = 0 for line in lines: lineno += 1 @@ -122,14 +122,14 @@ def clean_output(filename, outname, is_output, is_c): if match: line = line.rstrip() if match.group(1) in state_line: - line += " // line " + state_line[match.group(1)] + line += " // line " + str(state_line[match.group(1)]) line += "\n" out.append(line) lines = out out = [] if is_c: - token_values = {} + token_values: dict[str, str] = {} for line in lines: if re.search(r'enum\s+yytokentype', line) and not re.search(r';', line): match = re.search(r'\b(\S+) = (\d+)', line) @@ -165,7 +165,7 @@ def clean_output(filename, outname, is_output, is_c): fh.write(line) -def warning_check(filename): +def warning_check(filename: str) -> None: with open(filename, "r", encoding="utf-8") as fh: linenum = 0 for line in fh: @@ -177,12 +177,9 @@ def warning_check(filename): ###################################################################### -def clean_input(filename, outname): +def clean_input(filename: str, outname: str) -> None: print(" edit " + filename + " " + outname) - global Filename # pylint: disable=global-variable-undefined - Filename = filename - with open(filename, "r", encoding="utf-8") as fh: lines = fh.readlines() @@ -191,7 +188,7 @@ def clean_input(filename, outname): global Rules # pylint: disable=global-variable-undefined Rules = {} - types = {} + types: dict[str, dict[str, int]] = {} tokens = {} last_rule = None section = 1 @@ -344,7 +341,7 @@ def clean_input(filename, outname): for line in linesin: lineno += 1 if _enaline(line) and re.search(r'BISONPRE_COPY', line): - line = _bisonpre_copy(line, lineno, 0) + line = _bisonpre_copy(line, filename, lineno, 0) lines.append(line) # Replace ~[x]~ - must be after BISONPRE_COPY expansion @@ -391,7 +388,7 @@ def clean_input(filename, outname): fh.write(line) -def _bisonpre_copy(text, lineno, depth): +def _bisonpre_copy(text: str, filename: str, lineno: int, depth: int) -> str: while re.search(r'BISONPRE_COPY', text): match = re.match( # 1 2 3 4 5 @@ -399,14 +396,14 @@ def _bisonpre_copy(text, lineno, depth): text, flags=re.DOTALL) if not match: - sys.exit("%Error: " + Filename + ":" + str(lineno) + ": Bad form of BISONPRE_NOT: " + + sys.exit("%Error: " + filename + ":" + str(lineno) + ": Bad form of BISONPRE_NOT: " + text) text = match.group(1) + '{HERE}' + match.group(5) once = match.group(2) rule = match.group(3) code = match.group(4) if rule not in Rules: - sys.exit("%Error: " + Filename + ":" + str(lineno) + + sys.exit("%Error: " + filename + ":" + str(lineno) + ": Can't find definition for rule: " + rule) if depth > 0 and once: # _ONCE means don't inherit @@ -422,7 +419,7 @@ def _bisonpre_copy(text, lineno, depth): continue match = re.match(r'^\s*s/(.*?)/(.*?)/g\s*$', op) if not match: - sys.exit("%Error: " + Filename + ":" + str(lineno) + + sys.exit("%Error: " + filename + ":" + str(lineno) + ": Didn't understand replacement: " + op) left = match.group(1) right = match.group(2) @@ -435,7 +432,7 @@ def _bisonpre_copy(text, lineno, depth): return text -def _enaline(line): +def _enaline(line: str) -> bool: return not re.search(r'//UN', line) diff --git a/src/config_rev b/src/config_rev index 3d187ba59..2b32b57d6 100755 --- a/src/config_rev +++ b/src/config_rev @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0103,C0114 ###################################################################### # diff --git a/src/flexfix b/src/flexfix index b834453c3..57a207976 100755 --- a/src/flexfix +++ b/src/flexfix @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0114,C0301 ###################################################################### # diff --git a/src/vlcovgen b/src/vlcovgen index 28c70e423..250e51b8e 100755 --- a/src/vlcovgen +++ b/src/vlcovgen @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0103,C0114,C0116,C0209,eval-used ###################################################################### @@ -12,7 +13,7 @@ Items = [] ###################################################################### -def read_keys(filename): +def read_keys(filename: str) -> None: with open(filename, "r", encoding="utf8") as fh: for line in fh: line = re.sub(r'\/\/.*$', '', line) @@ -31,7 +32,7 @@ def read_keys(filename): ###################################################################### -def lint(): +def lint() -> None: shorts = {} for item in Items: if item['short'] in shorts: @@ -39,7 +40,7 @@ def lint(): shorts[item['short']] = True -def write_keys(filename): +def write_keys(filename: str) -> None: orig = [] out = [] diff --git a/test_regress/driver.py b/test_regress/driver.py index 72ff53d86..32b83ed26 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -25,6 +25,7 @@ import time from functools import lru_cache # Eventually use python 3.9's cache from pprint import pformat, pprint +from typing import Optional import distro @@ -50,7 +51,7 @@ All_Scenarios = { # Globals test = None -Arg_Tests = [] +Arg_Tests: list[str] = [] Quitting = False Vltmt_Threads = 3 forker = None @@ -155,7 +156,7 @@ class Capabilities: if match: Capabilities._cached_cmake_version = match.group(1) + "." + match.group(2) else: - Capabilities._cached_cmake_version = 0 + Capabilities._cached_cmake_version = "none" return Capabilities._cached_cmake_version @staticproperty @@ -227,7 +228,7 @@ class Capabilities: if match: Capabilities._cached_make_version = match.group(1) else: - Capabilities._cached_make_version = -1 + Capabilities._cached_make_version = "none" return Capabilities._cached_make_version # Fetch @@ -243,7 +244,7 @@ class Capabilities: # Internals @staticmethod - def _verilator_get_supported(feature) -> str: + def _verilator_get_supported(feature) -> bool: # Returns if given feature is supported cmd = "perl " + os.environ['VERILATOR_ROOT'] + "/bin/verilator -get-supported " + feature out = VtOs.run_capture(cmd, check=False).strip() @@ -561,7 +562,7 @@ class Runner: @staticmethod def _py_filename_adjust(py_filename: str, - tdir_def: str) -> list: # Return (py_filename, t_dir) + tdir_def: str) -> tuple[str, str]: # Return (py_filename, t_dir) for tdir in Args.test_dirs: # pylint: disable=redefined-outer-name # t_dir used both absolutely and under obj_dir try_py_filename = tdir + "/" + os.path.basename(py_filename) @@ -596,7 +597,7 @@ class Runner: out += " Time %d:%02d" % (int(delta / 60), delta % 60) return out - def _manual_args(self) -> str: + def _manual_args(self) -> list[str]: # Return command line with scenarios stripped out = [] for oarg in Args.orig_argv_sw: @@ -1752,7 +1753,7 @@ class VlTest: fails=False, # True: normal 1 exit code, 'any': any exit code logfile=None, # Filename to write putput to tee=True, - verilator_run=False) -> str: # Move gcov data to parallel area + verilator_run=False) -> bool: # Move gcov data to parallel area try: command = ' '.join(cmd) @@ -2343,7 +2344,7 @@ class VlTest: return again def _files_identical_reader(self, f1, f2, fn1: str, fn2: str, is_logfile: bool, - strip_hex: bool, moretry: bool) -> None: + strip_hex: bool, moretry: bool) -> bool: # If moretry, then return true to try again l1s = f1.readlines() l2s = f2.readlines() if f2 else [] @@ -2496,7 +2497,7 @@ class VlTest: self.copy_if_golden(fn1, fn2) self.error("SAIF files don't match!") - def _vcd_read(self, filename: str) -> str: + def _vcd_read(self, filename: str) -> dict: data = {} with open(filename, 'r', encoding='latin-1') as fh: hier_stack = ["TOP"] @@ -2608,7 +2609,7 @@ class VlTest: if re.search(regexp, contents, re.MULTILINE): self.error("File_grep_not: " + filename + ": Regexp found: '" + regexp + "'") - def file_grep(self, filename: str, regexp, expvalue=None) -> list: + def file_grep(self, filename: str, regexp, expvalue=None) -> Optional[list]: contents = self.file_contents(filename) if contents == "_Already_Errored_": return None @@ -2762,7 +2763,7 @@ def calc_threads(default_threads) -> int: return ok_threads if (ok_threads < default_threads) else default_threads -def _calc_hashset() -> list: +def _calc_hashset() -> None: match = re.match(r'^(\d+)/(\d+)$', Args.hashset) if not match: sys.exit("%Error: Need number/number format for --hashset: " + Args.hashset) diff --git a/test_regress/t/t_pipe_exit_bad_pf.pf b/test_regress/t/t_pipe_exit_bad_pf.pf index 3ddf3b8bd..312b25bc0 100755 --- a/test_regress/t/t_pipe_exit_bad_pf.pf +++ b/test_regress/t/t_pipe_exit_bad_pf.pf @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0114 # # DESCRIPTION: Verilator: Verilog Test example --pipe-filter script diff --git a/test_regress/t/t_pipe_filter_pf.pf b/test_regress/t/t_pipe_filter_pf.pf index d638a1245..6c25e3042 100755 --- a/test_regress/t/t_pipe_filter_pf.pf +++ b/test_regress/t/t_pipe_filter_pf.pf @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +# mypy: disallow-untyped-defs # pylint: disable=C0103,C0114 # # DESCRIPTION: Verilator: Verilog Test example --pipe-filter script