Skip to content

Commit e77e7e1

Browse files
committed
Add more type checking to Ramble
1 parent 82f759f commit e77e7e1

39 files changed

Lines changed: 310 additions & 174 deletions

lib/ramble/ramble/analysis/backwards.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"""Define the backwards-reading analysis strategy"""
1010

1111
import os
12+
from typing import Any, Dict, FrozenSet, Tuple
1213

1314
import ramble.success_criteria
1415
import ramble.util.lock as lk
@@ -121,9 +122,9 @@ def __call__(self, workspace):
121122

122123
exp_lock = app.experiment_lock
123124

124-
fom_values = {}
125-
context_metadata = {}
126-
null_key = (_NULL_CONTEXT, _NULL_CONTEXT, frozenset())
125+
fom_values: Dict[Tuple[str, str, FrozenSet[Any]], Dict[str, Any]] = {}
126+
context_metadata: Dict[Tuple[str, str, FrozenSet[Any]], Dict[str, Any]] = {}
127+
null_key: Tuple[str, str, FrozenSet[Any]] = (_NULL_CONTEXT, _NULL_CONTEXT, frozenset())
127128
context_metadata[null_key] = {
128129
"name": _NULL_CONTEXT,
129130
"def_name": _NULL_CONTEXT,

lib/ramble/ramble/analysis/forward.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import os
1212
import string
13+
from typing import Any, Dict, FrozenSet, Tuple
1314

1415
import ramble.success_criteria
1516
import ramble.util.lock as lk
@@ -61,9 +62,9 @@ def format_context(context_match, context_format):
6162

6263
exp_lock = app.experiment_lock
6364

64-
fom_values = {}
65-
context_metadata = {}
66-
null_key = (_NULL_CONTEXT, _NULL_CONTEXT, frozenset())
65+
fom_values: Dict[Tuple[str, str, FrozenSet[Any]], Dict[str, Any]] = {}
66+
context_metadata: Dict[Tuple[str, str, FrozenSet[Any]], Dict[str, Any]] = {}
67+
null_key: Tuple[str, str, FrozenSet[Any]] = (_NULL_CONTEXT, _NULL_CONTEXT, frozenset())
6768
context_metadata[null_key] = {
6869
"name": _NULL_CONTEXT,
6970
"def_name": _NULL_CONTEXT,
@@ -75,7 +76,7 @@ def format_context(context_match, context_format):
7576
for file, file_conf in files.items():
7677

7778
# Start with no active contexts in a file.
78-
active_contexts = {}
79+
active_contexts: Dict[str, Any] = {}
7980
logger.debug(f"Reading log file: {file}")
8081

8182
if not os.path.exists(file):

lib/ramble/ramble/cmd/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import os
1111
import re
12+
from typing import List, Optional
1213

1314
from llnl.util.lang import attr_setdefault
1415

@@ -50,7 +51,7 @@ def require_cmd_name(cname):
5051

5152

5253
#: global, cached list of all commands -- access through all_commands()
53-
_all_commands = None
54+
_all_commands: Optional[List[str]] = None
5455

5556

5657
def all_commands():

lib/ramble/ramble/cmd/common/arguments.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,17 @@
1313

1414
from ramble.util.logger import logger
1515

16-
from spack.util.pattern import Args
16+
17+
class Args:
18+
"""Class to hold positional flags and keyword arguments for parser.add_argument."""
19+
20+
flags: tuple
21+
kwargs: dict
22+
23+
def __init__(self, *flags, **kwargs):
24+
self.flags = tuple(flags)
25+
self.kwargs = kwargs
26+
1727

1828
__all__ = [
1929
"add_common_arguments",

lib/ramble/ramble/cmd/common/info.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import enum
1010
import fnmatch
1111
import textwrap
12+
from collections.abc import Iterable
1213

1314
from llnl.util.tty.colify import colified
1415

@@ -376,7 +377,7 @@ def print_single_attribute(obj, attr, verbose=False, pattern="*", format=support
376377
# Otherwise, we print the attribute's value directly.
377378
if isinstance(internal_attr, dict):
378379
to_print = list(internal_attr.keys())
379-
elif hasattr(internal_attr, "default_variants"):
380+
elif internal_attr is not None and hasattr(internal_attr, "default_variants"):
380381
to_print = []
381382
for variant in internal_attr.default_variants.values():
382383
to_print.append(variant)
@@ -387,7 +388,7 @@ def print_single_attribute(obj, attr, verbose=False, pattern="*", format=support
387388
to_print.append(variant)
388389
for variant in internal_attr.version_variants.values():
389390
to_print.append(variant)
390-
elif hasattr(internal_attr, "family_type"):
391+
elif internal_attr is not None and hasattr(internal_attr, "family_type"):
391392
to_print = [f"{internal_attr.family_type}={family}" for family in internal_attr]
392393
else:
393394
to_print = internal_attr
@@ -396,9 +397,7 @@ def print_single_attribute(obj, attr, verbose=False, pattern="*", format=support
396397
# if it's a list of dicts, convert the keys like above and print
397398
# otherwise filter it and print using the format specification
398399
# Otherwise, print it as a raw string.
399-
if isinstance(to_print, (list, set, tuple)) or (
400-
hasattr(to_print, "__iter__") and not isinstance(to_print, str)
401-
):
400+
if isinstance(to_print, Iterable) and not isinstance(to_print, str):
402401
to_print = list(to_print)
403402
if (
404403
internal_attr
@@ -415,9 +414,10 @@ def print_single_attribute(obj, attr, verbose=False, pattern="*", format=support
415414
if isinstance(internal_attr, dict):
416415
_print_verbose_dict_attr(internal_attr, pattern=pattern, indentation=indentation)
417416
elif (
418-
isinstance(internal_attr, (list, set, tuple))
419-
or (hasattr(internal_attr, "__iter__") and not isinstance(internal_attr, str))
420-
) and not hasattr(internal_attr, "as_str"):
417+
isinstance(internal_attr, Iterable)
418+
and not isinstance(internal_attr, str)
419+
and not hasattr(internal_attr, "as_str")
420+
):
421421
internal_list = list(internal_attr)
422422
# If it's a list of dicts, print each
423423
if internal_list and isinstance(internal_list[0], dict):
@@ -440,7 +440,7 @@ def print_single_attribute(obj, attr, verbose=False, pattern="*", format=support
440440
color.cprint(f"{colified(to_print, tty=True, indent=4)}")
441441
color.cprint("")
442442
else:
443-
if hasattr(internal_attr, "as_str"):
443+
if internal_attr is not None and hasattr(internal_attr, "as_str"):
444444
color.cprint(internal_attr.as_str(verbose=True))
445445
else:
446446
color.cprint(f"{indentation}{internal_attr}\n")

lib/ramble/ramble/cmd/config.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
section = "config"
2727
level = "long"
2828

29+
_add_parser = None
30+
2931

3032
def setup_parser(subparser):
3133
scopes_metavar = ramble.config.scopes_metavar
@@ -94,7 +96,8 @@ def setup_parser(subparser):
9496
)
9597

9698
# Make the add parser available later
97-
setup_parser.add_parser = add_parser
99+
global _add_parser
100+
_add_parser = add_parser
98101

99102
update = sp.add_parser("update", help="update configuration files to the latest format")
100103
ramble.cmd.common.arguments.add_common_arguments(update, ["yes_to_all"])
@@ -207,7 +210,8 @@ def config_add(args):
207210
This is a stateful operation that edits the config files."""
208211
if not (args.file or args.path):
209212
logger.error("No changes requested. Specify a file or value.")
210-
setup_parser.add_parser.print_help()
213+
if _add_parser:
214+
_add_parser.print_help()
211215
exit(1)
212216

213217
scope, _ = _get_scope_and_section(args)

lib/ramble/ramble/cmd/filter_groups.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# except according to those terms.
88

99
import copy
10+
from typing import Any, Dict, List
1011

1112
from llnl.util.tty.colify import colify
1213

@@ -203,7 +204,7 @@ def print_filter_groups(resolved_scope_name=None, original_scope_name=None, verb
203204
lines.extend(f" - {ew}" for ew in definition["exclude_where"])
204205
color.cprint("\n".join(lines))
205206
else:
206-
scope_groups = {}
207+
scope_groups: Dict[str, List[str]] = {}
207208
for item in groups_to_print:
208209
scope = item["scope"]
209210
name = item["name"]
@@ -212,7 +213,7 @@ def print_filter_groups(resolved_scope_name=None, original_scope_name=None, verb
212213
scope_groups[scope].append(name)
213214

214215
out_stream = logger.active_stream()
215-
colify_opts = {"indent": 4, "padding": 2}
216+
colify_opts: Dict[str, Any] = {"indent": 4, "padding": 2}
216217
if out_stream:
217218
colify_opts["output"] = out_stream
218219

lib/ramble/ramble/cmd/license.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def _object_file_regex_list(is_ramble_root=True):
4242

4343

4444
#: regular expressions for licensed files.
45-
licensed_files = [
45+
_raw_licensed_files = [
4646
# ramble scripts
4747
r"bin/ramble$",
4848
r"bin/ramble-python$",
@@ -66,6 +66,7 @@ def _object_file_regex_list(is_ramble_root=True):
6666
# examples
6767
r"examples/.*\.yaml$",
6868
]
69+
licensed_files = [re.compile(regex) for regex in _raw_licensed_files]
6970

7071

7172
#: licensed files that can have LGPL language in them
@@ -327,8 +328,6 @@ def license(parser, args):
327328
if not git:
328329
logger.die("ramble license requires git in your environment")
329330

330-
licensed_files[:] = [re.compile(regex) for regex in licensed_files]
331-
332331
commands = {
333332
"list-files": list_files,
334333
"verify": verify,

lib/ramble/ramble/cmd/python.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ def python(parser, args, unknown_args):
8181

8282
# Run user choice of interpreter
8383
if args.python_interpreter == "ipython":
84-
return ramble.cmd.python.ipython_interpreter(args)
85-
return ramble.cmd.python.python_interpreter(args)
84+
return ipython_interpreter(args)
85+
return python_interpreter(args)
8686

8787

8888
def ipython_interpreter(args):

lib/ramble/ramble/cmd/style.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def is_object(f):
8989
#
9090
# For each file, if the filename pattern matches, we'll add per-line
9191
# exemptions if any patterns in the sub-dict match.
92-
pattern_exemptions = {
92+
_raw_pattern_exemptions = {
9393
# exemptions applied only to application.py files.
9494
rf"application.py|{base_class_file}$": {
9595
# Allow 'from ramble.appkit import *' in applications,
@@ -144,7 +144,7 @@ def is_object(f):
144144
re.compile(file_pattern): {
145145
code: [re.compile(p) for p in patterns] for code, patterns in error_dict.items()
146146
}
147-
for file_pattern, error_dict in pattern_exemptions.items()
147+
for file_pattern, error_dict in _raw_pattern_exemptions.items()
148148
}
149149

150150
# Tools run in the given order

0 commit comments

Comments
 (0)