Skip to content

Commit e3683a6

Browse files
committed
Cleanup use of dicts, e.g. use of .keys()
Using `x in dict.keys()` is discouraged and should be `x in dict` directly which is potentially more performant and easier to read/shorter. Accesses to keys and their values should use `dict.items` to avoid the lookup overhead.
1 parent 1cd4438 commit e3683a6

22 files changed

Lines changed: 69 additions & 68 deletions

File tree

easybuild/base/frozendict.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def __init__(self, *args, **kwargs):
7676

7777
# handle unknown keys: either ignore them or raise an exception
7878
tmpdict = dict(*args, **kwargs)
79-
unknown_keys = [key for key in tmpdict.keys() if key not in self.KNOWN_KEYS]
79+
unknown_keys = [key for key in tmpdict if key not in self.KNOWN_KEYS]
8080
if unknown_keys:
8181
if ignore_unknown_keys:
8282
for key in unknown_keys:

easybuild/base/generaloption.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ def _make_debug_options(self):
10231023

10241024
def _set_default_loglevel(self):
10251025
"""Set the default loglevel if no logging options are set"""
1026-
loglevel_set = sum([getattr(self.options, name, False) for name in self._logopts.keys()])
1026+
loglevel_set = sum([getattr(self.options, name, False) for name in self._logopts])
10271027
if not loglevel_set and self.DEFAULT_LOGLEVEL is not None:
10281028
setLogLevel(self.DEFAULT_LOGLEVEL)
10291029

easybuild/base/optcomplete.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ def __call__(self, **kwargs):
169169
if self.CALL_ARGS_OPTIONAL is not None:
170170
all_args.extend(self.CALL_ARGS_OPTIONAL)
171171

172-
for arg in kwargs.keys():
172+
for arg in kwargs:
173173
if arg not in all_args:
174174
# remove it
175175
kwargs.pop(arg)

easybuild/framework/easyconfig/easyconfig.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* Victor Holanda (CSCS, ETH Zurich)
4242
"""
4343

44+
import contextlib
4445
import copy
4546
import difflib
4647
import functools
@@ -199,8 +200,7 @@ def triage_easyconfig_params(variables, ec):
199200

200201
for key in variables:
201202
# validations are skipped, just set in the config
202-
if any(key in d for d in (ec, DEPRECATED_EASYCONFIG_PARAMETERS.keys(),
203-
ALTERNATIVE_EASYCONFIG_PARAMETERS.keys())):
203+
if any(key in d for d in (ec, DEPRECATED_EASYCONFIG_PARAMETERS, ALTERNATIVE_EASYCONFIG_PARAMETERS)):
204204
ec_params[key] = variables[key]
205205
_log.debug("setting config option %s: value %s (type: %s)", key, ec_params[key], type(ec_params[key]))
206206
elif key in REPLACED_PARAMETERS:
@@ -728,7 +728,7 @@ def update(self, key, value, allow_duplicate=True):
728728
# Overwrite easyconfig parameter value with updated value, preserving type
729729
self[key] = param_value
730730

731-
def set_keys(self, params):
731+
def set_keys(self, params: dict):
732732
"""
733733
Set keys in this EasyConfig instance based on supplied easyconfig parameter values.
734734
@@ -739,15 +739,15 @@ def set_keys(self, params):
739739
# disable templating when setting easyconfig parameters
740740
# required to avoid problems with values that need more parsing to be done (e.g. dependencies)
741741
with self.disable_templating():
742-
for key in sorted(params.keys()):
742+
for key, value in sorted(params.items()):
743743
# validations are skipped, just set in the config
744-
if any(key in x.keys() for x in (self._config, ALTERNATIVE_EASYCONFIG_PARAMETERS,
745-
DEPRECATED_EASYCONFIG_PARAMETERS)):
746-
self[key] = params[key]
744+
if any(key in x for x in (self._config, ALTERNATIVE_EASYCONFIG_PARAMETERS,
745+
DEPRECATED_EASYCONFIG_PARAMETERS)):
746+
self[key] = value
747747
self.log.info("setting easyconfig parameter %s: value %s (type: %s)",
748748
key, self[key], type(self[key]))
749749
else:
750-
raise EasyBuildError("Unknown easyconfig parameter: %s (value '%s')", key, params[key])
750+
raise EasyBuildError("Unknown easyconfig parameter: %s (value '%s')", key, value)
751751

752752
def parse(self):
753753
"""
@@ -2202,15 +2202,18 @@ def resolve_template(value, tmpl_dict, expect_resolved=True):
22022202
try:
22032203
orig_value = value
22042204
# map old templates to new values for alternative and deprecated templates
2205-
alt_map = {old_tmpl: tmpl_dict[new_tmpl] for (old_tmpl, new_tmpl) in
2206-
ALTERNATIVE_EASYCONFIG_TEMPLATES.items() if new_tmpl in tmpl_dict.keys()}
2207-
alt_map2 = {new_tmpl: tmpl_dict[old_tmpl] for (old_tmpl, new_tmpl) in
2208-
ALTERNATIVE_EASYCONFIG_TEMPLATES.items() if old_tmpl in tmpl_dict.keys()}
2209-
depr_map = {old_tmpl: tmpl_dict[new_tmpl] for (old_tmpl, (new_tmpl, ver)) in
2210-
DEPRECATED_EASYCONFIG_TEMPLATES.items() if new_tmpl in tmpl_dict.keys()}
2205+
new_tmpl_dict = tmpl_dict.copy()
2206+
with contextlib.suppress(KeyError):
2207+
new_tmpl_dict.update({old_tmpl: tmpl_dict[new_tmpl]
2208+
for (old_tmpl, new_tmpl) in ALTERNATIVE_EASYCONFIG_TEMPLATES.items()})
2209+
new_tmpl_dict.update({new_tmpl: tmpl_dict[old_tmpl]
2210+
for (old_tmpl, new_tmpl) in ALTERNATIVE_EASYCONFIG_TEMPLATES.items()})
2211+
depr_map = {old_tmpl: tmpl_dict[new_tmpl]
2212+
for (old_tmpl, new_tmpl) in DEPRECATED_EASYCONFIG_TEMPLATES.items()}
2213+
new_tmpl_dict.update(depr_map)
22112214

22122215
# try templating with alternative and deprecated templates included
2213-
value = value % {**tmpl_dict, **alt_map, **alt_map2, **depr_map}
2216+
value = value % new_tmpl_dict
22142217

22152218
for old_tmpl, val in depr_map.items():
22162219
# check which deprecated templates were replaced, and issue deprecation warnings

easybuild/framework/easyconfig/types.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def check_key_types(val, allowed_types):
103103
"""Check whether type of keys for specific dict value are as expected."""
104104
if isinstance(val, dict):
105105
res = True
106-
for key in val.keys():
106+
for key in val:
107107
res &= any(is_value_of_type(key, t) for t in allowed_types)
108108
else:
109109
_log.debug("Specified value %s (type: %s) is not a dict, so key types check failed", val, type(val))
@@ -115,7 +115,7 @@ def check_key_types(val, allowed_types):
115115
def check_known_keys(val, allowed_keys):
116116
"""Check whether all keys for specified dict value are known keys."""
117117
if isinstance(val, dict):
118-
res = all(key in allowed_keys for key in val.keys())
118+
res = all(key in allowed_keys for key in val)
119119
else:
120120
_log.debug("Specified value %s (type: %s) is not a dict, so known keys check failed", val, type(val))
121121
res = False

easybuild/tools/containers/docker.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ def resolve_template_data(self):
150150

151151
def validate(self):
152152
"""Perform validation of specified container configuration."""
153-
if self.container_config not in DOCKER_OS_INSTALL_DEPS_TMPLS.keys():
153+
if self.container_config not in DOCKER_OS_INSTALL_DEPS_TMPLS:
154154
raise EasyBuildError("Unsupported container config '%s'" % self.container_config)
155155
super().validate()
156156

easybuild/tools/docs.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,7 @@ def list_software_md(software, detailed=True):
850850
]
851851

852852
# links to per-letter tables
853-
key_letters = nub(sorted(k[0].lower() for k in software.keys()))
853+
key_letters = nub(sorted(k[0].lower() for k in software))
854854
letter_links = ' - '.join(['[' + x + '](#' + x + ')' for x in ascii_lowercase if x in key_letters])
855855
lines.extend([letter_links, ''])
856856

@@ -922,7 +922,7 @@ def list_software_md(software, detailed=True):
922922
return '\n'.join(lines)
923923

924924

925-
def list_software_rst(software, detailed=False):
925+
def list_software_rst(software: dict, detailed=False):
926926
"""
927927
Return overview of supported software in RST format
928928
@@ -942,7 +942,7 @@ def list_software_rst(software, detailed=False):
942942

943943
# links to per-letter tables
944944
letter_refs = ''
945-
key_letters = nub(sorted(k[0].lower() for k in software.keys()))
945+
key_letters = nub(sorted(k[0].lower() for k in software))
946946
for letter in ascii_lowercase:
947947
if letter in key_letters:
948948
if letter_refs:
@@ -1072,7 +1072,7 @@ def list_software_txt(software, detailed=False):
10721072
return '\n'.join(lines)
10731073

10741074

1075-
def list_software_json(software, detailed=False):
1075+
def list_software_json(software: dict, detailed=False):
10761076
"""
10771077
Return overview of supported software in json
10781078
@@ -1320,11 +1320,11 @@ def avail_toolchain_opts_json(name, tc_dict):
13201320
raise NotImplementedError("JSON output not implemented yet for --avail-toolchain-opts")
13211321

13221322

1323-
def avail_toolchain_opts_txt(name, tc_dict):
1323+
def avail_toolchain_opts_txt(name, tc_dict: dict):
13241324
""" Returns overview of toolchain options in txt format """
13251325
doc = ["Available options for %s toolchain:" % name]
1326-
for opt_name in sorted(tc_dict.keys()):
1327-
doc.append("%s%s: %s (default: %s)" % (INDENT_4SPACES, opt_name, tc_dict[opt_name][1], tc_dict[opt_name][0]))
1326+
for opt_name, value in sorted(tc_dict.items()):
1327+
doc.append("%s%s: %s (default: %s)" % (INDENT_4SPACES, opt_name, value[1], value[0]))
13281328

13291329
return '\n'.join(doc)
13301330

easybuild/tools/filetools.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -781,7 +781,7 @@ def parse_http_header_fields_urlpat(arg, urlpat=None, header=None, urlpat_header
781781
argline = header.strip() + ':' + argline
782782

783783
if urlpat is not None:
784-
if urlpat in urlpat_headers.keys():
784+
if urlpat in urlpat_headers:
785785
urlpat_headers[urlpat].append(argline) # add headers to the list
786786
else:
787787
urlpat_headers[urlpat] = [argline] # new list headers for this urlpat
@@ -1618,9 +1618,9 @@ def create_patch_info(patch_spec):
16181618
patch_info = {'name': patch_spec}
16191619
elif isinstance(patch_spec, dict):
16201620
patch_info = {}
1621-
for key in patch_spec.keys():
1621+
for key, value in patch_spec.items():
16221622
if key in valid_keys:
1623-
patch_info[key] = patch_spec[key]
1623+
patch_info[key] = value
16241624
else:
16251625
raise EasyBuildError(
16261626
"Wrong patch spec '%s', use of unknown key %s in dict (valid keys are %s)",

easybuild/tools/github.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@
9494
GITHUB_API_URL = 'https://api.github.com'
9595
GITHUB_BRANCH_MAIN = 'main'
9696
GITHUB_BRANCH_MASTER = 'master'
97-
GITHUB_DIR_TYPE = u'dir'
97+
GITHUB_DIR_TYPE = 'dir'
9898
GITHUB_EB_MAIN = 'easybuilders'
9999
GITHUB_EASYBLOCKS_REPO = 'easybuild-easyblocks'
100100
GITHUB_EASYCONFIGS_REPO = 'easybuild-easyconfigs'
101101
GITHUB_FRAMEWORK_REPO = 'easybuild-framework'
102102
GITHUB_DEVELOP_BRANCH = 'develop'
103-
GITHUB_FILE_TYPE = u'file'
103+
GITHUB_FILE_TYPE = 'file'
104104
GITHUB_PR_STATE_OPEN = 'open'
105105
GITHUB_PR_STATES = [GITHUB_PR_STATE_OPEN, 'closed', 'all']
106106
GITHUB_PR_ORDER_CREATED = 'created'
@@ -2226,7 +2226,7 @@ def det_account_branch_for_pr(pr_id, github_user=None, pr_target_repo=None):
22262226
return account, branch
22272227

22282228

2229-
def det_pr_target_repo(paths):
2229+
def det_pr_target_repo(paths: dict):
22302230
"""Determine target repository for pull request from given cagetorized list of files
22312231
22322232
:param paths: paths to categorized lists of files (easyconfigs, files to delete, patches, .py files)
@@ -2239,7 +2239,7 @@ def det_pr_target_repo(paths):
22392239

22402240
_log.info("Trying to derive target repository based on specified files...")
22412241

2242-
easyconfigs, files_to_delete, patch_files, py_files = [paths[key] for key in sorted(paths.keys())]
2242+
easyconfigs, files_to_delete, patch_files, py_files = sorted(paths.items())
22432243

22442244
# Python files provided, and no easyconfig files or patches
22452245
if py_files and not (easyconfigs or patch_files):

easybuild/tools/module_naming_scheme/hierarchical_mns.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ def det_modpath_extensions(self, ec):
199199
extend_comps = []
200200
# exclude GCC for which <name>/<version> is used as $MODULEPATH extension
201201
excluded_comps = ['GCC']
202-
for comps in COMP_NAME_VERSION_TEMPLATES.keys():
202+
for comps in COMP_NAME_VERSION_TEMPLATES:
203203
extend_comps.extend([comp for comp in comps.split(',') if comp not in excluded_comps])
204204

205205
comp_name_ver = None

0 commit comments

Comments
 (0)