diff --git a/lib/galaxy/actions/admin.py b/lib/galaxy/actions/admin.py index 6a54762b98e..1eb65a6b778 100644 --- a/lib/galaxy/actions/admin.py +++ b/lib/galaxy/actions/admin.py @@ -152,7 +152,7 @@ class AdminActions: if len(names) == 1: raise ActionInputError(f"Quota '{names[0]}' is a default, please unset it as a default before deleting it.") elif len(names) > 1: - raise ActionInputError("Quotas are defaults, please unset them as defaults before deleting them: " + ', '.join(names)) + raise ActionInputError(f"Quotas are defaults, please unset them as defaults before deleting them: {', '.join(names)}") message = "Deleted %d quotas: " % len(quotas) for q in quotas: q.deleted = True @@ -171,7 +171,7 @@ class AdminActions: if len(names) == 1: raise ActionInputError(f"Quota '{names[0]}' has not been deleted, so it cannot be undeleted.") elif len(names) > 1: - raise ActionInputError("Quotas have not been deleted so they cannot be undeleted: " + ', '.join(names)) + raise ActionInputError(f"Quotas have not been deleted so they cannot be undeleted: {', '.join(names)}") message = "Undeleted %d quotas: " % len(quotas) for q in quotas: q.deleted = False @@ -196,7 +196,7 @@ class AdminActions: if len(names) == 1: raise ActionInputError(f"Quota '{names[0]}' has not been deleted, so it cannot be purged.") elif len(names) > 1: - raise ActionInputError("Quotas have not been deleted so they cannot be undeleted: " + ', '.join(names)) + raise ActionInputError(f"Quotas have not been deleted so they cannot be undeleted: {', '.join(names)}") message = "Purged %d quotas: " % len(quotas) for q in quotas: # Delete UserQuotaAssociations diff --git a/lib/galaxy/authnz/custos_authnz.py b/lib/galaxy/authnz/custos_authnz.py index 4fa2fc5c4ea..33b035bbf50 100644 --- a/lib/galaxy/authnz/custos_authnz.py +++ b/lib/galaxy/authnz/custos_authnz.py @@ -114,7 +114,7 @@ class CustosAuthnz(IdentityProvider): log.exception(message) raise exceptions.AuthenticationFailed(message) else: - login_redirect_url = login_redirect_url + 'root/login?confirm=true&custos_token=' + json.dumps(token) + login_redirect_url = f"{login_redirect_url}root/login?confirm=true&custos_token={json.dumps(token)}" return login_redirect_url, None custos_authnz_token = CustosAuthnzToken(user=user, @@ -224,7 +224,7 @@ class CustosAuthnz(IdentityProvider): else: client_secret = self.config['client_secret'] token_endpoint = self.config['token_endpoint'] - clientIdAndSec = self.config['client_id'] + ":" + self.config['client_secret'] # for custos + clientIdAndSec = f"{self.config['client_id']}:{self.config['client_secret']}" # for custos return oauth2_session.fetch_token( token_endpoint, client_secret=client_secret, @@ -263,7 +263,7 @@ class CustosAuthnz(IdentityProvider): self.config['credential_url'] = '/'.join([self.config['url'].rstrip('/'), 'credentials']) self._get_custos_credentials() # Set custos endpoints - clientIdAndSec = self.config['client_id'] + ":" + self.config['client_secret'] + clientIdAndSec = f"{self.config['client_id']}:{self.config['client_secret']}" eps = requests.get(self.config['well_known_oidc_config_uri'], headers={"Authorization": f"Basic {util.unicodify(base64.b64encode(util.smart_str(clientIdAndSec)))}"}, verify=False, params={'client_id': self.config['client_id']}) @@ -276,7 +276,7 @@ class CustosAuthnz(IdentityProvider): self._load_well_known_oidc_config(well_known_oidc_config) def _get_custos_credentials(self): - clientIdAndSec = self.config['client_id'] + ":" + self.config['client_secret'] + clientIdAndSec = f"{self.config['client_id']}:{self.config['client_secret']}" creds = requests.get(self.config['credential_url'], headers={"Authorization": f"Basic {util.unicodify(base64.b64encode(util.smart_str(clientIdAndSec)))}"}, verify=False, params={'client_id': self.config['client_id']}) diff --git a/lib/galaxy/authnz/psa_authnz.py b/lib/galaxy/authnz/psa_authnz.py index f42dbe2b6cf..a8827168e1c 100644 --- a/lib/galaxy/authnz/psa_authnz.py +++ b/lib/galaxy/authnz/psa_authnz.py @@ -165,7 +165,7 @@ class PSAAuthnz(IdentityProvider): on_the_fly_config(trans.sa_session) self.config[setting_name('LOGIN_REDIRECT_URL')] = login_redirect_url strategy = Strategy(trans.request, trans.session, Storage, self.config) - strategy.session_set(BACKENDS_NAME[self.config['provider']] + '_state', state_token) + strategy.session_set(f"{BACKENDS_NAME[self.config['provider']]}_state", state_token) backend = self._load_backend(strategy, self.config['redirect_uri']) redirect_url = do_complete( backend, diff --git a/lib/galaxy/config/__init__.py b/lib/galaxy/config/__init__.py index 8d0dd87117f..25e714ff7d6 100644 --- a/lib/galaxy/config/__init__.py +++ b/lib/galaxy/config/__init__.py @@ -815,7 +815,7 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin): self.amqp_internal_connection = kwargs.get('amqp_internal_connection') # TODO Get extra amqp args as necessary for ssl elif 'database_connection' in kwargs: - self.amqp_internal_connection = "sqlalchemy+" + self.database_connection + self.amqp_internal_connection = f"sqlalchemy+{self.database_connection}" else: self.amqp_internal_connection = f"sqlalchemy+sqlite:///{self._in_data_dir('control.sqlite')}?isolation_level=IMMEDIATE" self.pretty_datetime_format = expand_pretty_datetime_format(self.pretty_datetime_format) diff --git a/lib/galaxy/containers/__init__.py b/lib/galaxy/containers/__init__.py index 97cf6e6cec1..5bf9a3c1a35 100644 --- a/lib/galaxy/containers/__init__.py +++ b/lib/galaxy/containers/__init__.py @@ -219,7 +219,7 @@ class ContainerInterface(metaclass=ABCMeta): } log.warning("option '%s' not in %s.option_map, guessing flag '%s' type '%s'", opt, self.__class__.__name__, optdef['flag'], optdef['type']) - opts.append(getattr(self, '_stringify_kwopt_' + optdef['type'])(optdef['flag'], val)) + opts.append(getattr(self, f"_stringify_kwopt_{optdef['type']}")(optdef['flag'], val)) return ' '.join(opts) def _stringify_kwopt_boolean(self, flag, val): @@ -272,7 +272,7 @@ class ContainerInterface(metaclass=ABCMeta): return stdout.strip() else: msg = f"Command '{command}' returned non-zero exit status {p.returncode}" - log.error(msg + ': ' + stderr.strip()) + log.error(f"{msg}: {stderr.strip()}") raise ContainerCLIError( msg, stdout=stdout.strip(), diff --git a/lib/galaxy/containers/docker.py b/lib/galaxy/containers/docker.py index aaf2c9cde4d..9a41889bcec 100644 --- a/lib/galaxy/containers/docker.py +++ b/lib/galaxy/containers/docker.py @@ -168,7 +168,7 @@ class DockerCLIInterface(DockerInterface): kwopt_list.append('{vol}:{bind}{mode}'.format( vol=hostvol, bind=guestopts['bind'], - mode=':' + mode if mode else '' + mode=f":{mode}" if mode else '' )) return self._stringify_kwopt_list(flag, kwopt_list) @@ -234,7 +234,7 @@ class DockerAPIClient: if isinstance(f, partial): f = f.func try: - return getattr(f, '__qualname__', f.im_class.__name__ + '.' + f.__name__) + return getattr(f, '__qualname__', f"{f.im_class.__name__}.{f.__name__}") except AttributeError: return f.__name__ @@ -489,7 +489,7 @@ class DockerAPIInterface(DockerInterface): # keyword arguments spec_kwopts = {} # retrieve the option map for the docker-py object we're creating - option_map = getattr(self, option_map_name + '_option_map') + option_map = getattr(self, f"{option_map_name}_option_map") # set defaults for key in filter(lambda k: option_map[k].get('default'), option_map.keys()): map_spec = option_map[key] diff --git a/lib/galaxy/containers/docker_model.py b/lib/galaxy/containers/docker_model.py index ebb62a016b9..7d368688f0f 100644 --- a/lib/galaxy/containers/docker_model.py +++ b/lib/galaxy/containers/docker_model.py @@ -24,8 +24,8 @@ from galaxy.util import ( CPUS_LABEL = '_galaxy_cpus' IMAGE_LABEL = '_galaxy_image' -CPUS_CONSTRAINT = 'node.labels.' + CPUS_LABEL -IMAGE_CONSTRAINT = 'node.labels.' + IMAGE_LABEL +CPUS_CONSTRAINT = f"node.labels.{CPUS_LABEL}" +IMAGE_CONSTRAINT = f"node.labels.{IMAGE_LABEL}" log = logging.getLogger(__name__) @@ -676,7 +676,7 @@ class DockerTask: service = service or interface.service(id=t.get('ServiceID')) node = node or interface.node(id=t.get('NodeID')) if service: - name = service.name + '.' + str(t['Slot']) + name = f"{service.name}.{str(t['Slot'])}" else: name = t['ID'] image = t['Spec']['ContainerSpec']['Image'].split('@', 1)[0], # remove pin diff --git a/lib/galaxy/containers/docker_swarm.py b/lib/galaxy/containers/docker_swarm.py index 8cc14768b0a..6ac26c547df 100644 --- a/lib/galaxy/containers/docker_swarm.py +++ b/lib/galaxy/containers/docker_swarm.py @@ -426,10 +426,10 @@ class DockerSwarmAPIInterface(DockerSwarmInterface, DockerAPIInterface): # service constraints kwopts['constraint'] = kwopts.get('constraint', []) if self._conf.service_create_image_constraint: - kwopts['constraint'].append(IMAGE_CONSTRAINT + '==' + image) + kwopts['constraint'].append(f"{IMAGE_CONSTRAINT}=={image}") if self._conf.service_create_cpus_constraint: cpus = kwopts.get('reserve_cpus', kwopts.get('limit_cpus', '1')) - kwopts['constraint'].append(CPUS_CONSTRAINT + '==' + cpus) + kwopts['constraint'].append(f"{CPUS_CONSTRAINT}=={cpus}") # ports if 'publish_port_random' in kwopts: kwopts['ports'] = [DockerSwarmAPIInterface.create_random_port_spec(kwopts.pop('publish_port_random'))] diff --git a/lib/galaxy/datatypes/assembly.py b/lib/galaxy/datatypes/assembly.py index d975251f5d4..b3be0ff1f9b 100644 --- a/lib/galaxy/datatypes/assembly.py +++ b/lib/galaxy/datatypes/assembly.py @@ -182,11 +182,11 @@ class Velvet(Html): dataset.metadata.short2_reads = short2_reads dataset.info = re.sub(r'.*velveth \S+', 'hash_length', re.sub(r'\n', ' ', log_msg)) if paired_end_reads: - gen_msg = gen_msg + ' Paired-End Reads' + gen_msg = f"{gen_msg} Paired-End Reads" if long_reads: - gen_msg = gen_msg + ' Long Reads' + gen_msg = f"{gen_msg} Long Reads" if len(gen_msg) > 0: - gen_msg = 'Uses: ' + gen_msg + gen_msg = f"Uses: {gen_msg}" except Exception: log.debug(f"Velveth could not read Log file in {efp}") log.debug(f"Velveth log info {gen_msg}") diff --git a/lib/galaxy/datatypes/binary.py b/lib/galaxy/datatypes/binary.py index 21329f8cdef..be2afb495ea 100644 --- a/lib/galaxy/datatypes/binary.py +++ b/lib/galaxy/datatypes/binary.py @@ -708,7 +708,7 @@ class CRAM(Binary): def set_meta(self, dataset, overwrite=True, **kwd): major_version, minor_version = self.get_cram_version(dataset.file_name) if major_version != -1: - dataset.metadata.cram_version = str(major_version) + "." + str(minor_version) + dataset.metadata.cram_version = f"{str(major_version)}.{str(minor_version)}" if not dataset.metadata.cram_index: index_file = dataset.metadata.spec['cram_index'].param.new_file(dataset=dataset) @@ -788,7 +788,7 @@ class Bcf(BaseBcf): try: cmd = ['python', '-c', f"import pysam.bcftools; pysam.bcftools.index('{dataset_symlink}')"] subprocess.check_call(cmd) - shutil.move(dataset_symlink + '.csi', index_file.file_name) + shutil.move(f"{dataset_symlink}.csi", index_file.file_name) except Exception as e: raise Exception(f'Error setting BCF metadata: {util.unicodify(e)}') finally: diff --git a/lib/galaxy/datatypes/converters/interval_to_fli.py b/lib/galaxy/datatypes/converters/interval_to_fli.py index 201a7d507d5..16dcf4f88d3 100644 --- a/lib/galaxy/datatypes/converters/interval_to_fli.py +++ b/lib/galaxy/datatypes/converters/interval_to_fli.py @@ -97,9 +97,9 @@ def main(): # Write padded entries. with open(out_fname, 'w') as out: - out.write(str(max_len + 1).ljust(max_len) + '\n') + out.write(f"{str(max_len + 1).ljust(max_len)}\n") for entry in entries: - out.write(entry.ljust(max_len) + '\n') + out.write(f"{entry.ljust(max_len)}\n") if __name__ == '__main__': diff --git a/lib/galaxy/datatypes/dataproviders/dataset.py b/lib/galaxy/datatypes/dataproviders/dataset.py index ccded5a6575..7d856ad847a 100644 --- a/lib/galaxy/datatypes/dataproviders/dataset.py +++ b/lib/galaxy/datatypes/dataproviders/dataset.py @@ -664,11 +664,11 @@ class SamtoolsDataProvider(line.RegexLineDataProvider): validated_flag_list.append('S') if validated_flag_list: - opt_list.append('-' + ''.join(validated_flag_list)) + opt_list.append(f"-{''.join(validated_flag_list)}") for flag, arg in options_dict.items(): if flag in self.FLAGS_W_ARGS: - opt_list.extend(['-' + flag, str(arg)]) + opt_list.extend([f"-{flag}", str(arg)]) return opt_list diff --git a/lib/galaxy/datatypes/dataproviders/external.py b/lib/galaxy/datatypes/dataproviders/external.py index 58790a5041d..7a3f9fb34f2 100644 --- a/lib/galaxy/datatypes/dataproviders/external.py +++ b/lib/galaxy/datatypes/dataproviders/external.py @@ -172,4 +172,4 @@ class TempfileDataProvider(base.DataProvider): parent_gen = super().__iter__() with open(self.tmp_file, 'w') as open_file: for datum in parent_gen: - open_file.write(datum + '\n') + open_file.write(f"{datum}\n") diff --git a/lib/galaxy/datatypes/genetics.py b/lib/galaxy/datatypes/genetics.py index 79742505f71..75c5281783b 100644 --- a/lib/galaxy/datatypes/genetics.py +++ b/lib/galaxy/datatypes/genetics.py @@ -102,7 +102,7 @@ class GenomeGraphs(Tabular): internal_url = "%s" % app.url_for(controller='dataset', dataset_id=dataset.id, action='display_at', - filename='ucsc_' + site_name) + filename=f"ucsc_{site_name}") display_url = "%s%s/display_as?id=%i&display_app=%s&authz_method=display_at" % (base_url, app.url_for(controller='root'), dataset.id, type) display_url = quote_plus(display_url) # was display_url = quote_plus( "%s/display_as?id=%i&display_app=%s" % (base_url, dataset.id, type) ) diff --git a/lib/galaxy/datatypes/isa.py b/lib/galaxy/datatypes/isa.py index 1511023ca84..4afb5b14e99 100644 --- a/lib/galaxy/datatypes/isa.py +++ b/lib/galaxy/datatypes/isa.py @@ -288,7 +288,7 @@ class _Isa(data.Data): html += '' html += '' diff --git a/lib/galaxy/datatypes/tabular.py b/lib/galaxy/datatypes/tabular.py index 95d1fbf28e7..5d82a9a858b 100644 --- a/lib/galaxy/datatypes/tabular.py +++ b/lib/galaxy/datatypes/tabular.py @@ -1132,8 +1132,8 @@ class ConnectivityTable(Tabular): edam_format = "format_3309" file_ext = "ct" - header_regexp = re.compile("^[0-9]+" + "(?:\t|[ ]+)" + ".*?" + "(?:ENERGY|energy|dG)" + "[ \t].*?=") - structure_regexp = re.compile("^[0-9]+" + "(?:\t|[ ]+)" + "[ACGTURYKMSWBDHVN]+" + "(?:\t|[ ]+)" + "[^\t]+" + "(?:\t|[ ]+)" + "[^\t]+" + "(?:\t|[ ]+)" + "[^\t]+" + "(?:\t|[ ]+)" + "[^\t]+") + header_regexp = re.compile(f"^[0-9]+(?: |[ ]+).*?(?:ENERGY|energy|dG)[ ].*?=") + structure_regexp = re.compile(f"^[0-9]+(?: |[ ]+)[ACGTURYKMSWBDHVN]+(?: |[ ]+)[^ ]+(?: |[ ]+)[^ ]+(?: |[ ]+)[^ ]+(?: |[ ]+)[^ ]+") def __init__(self, **kwd): super().__init__(**kwd) @@ -1230,7 +1230,7 @@ class ConnectivityTable(Tabular): ck_data_body = re.sub('\n[ \t]+', '\n', ck_data_body) ck_data_body = re.sub('[ ]+', '\t', ck_data_body) - return dumps({'ck_data': util.unicodify(ck_data_header + "\n" + ck_data_body), 'ck_index': ck_index + 1}) + return dumps({'ck_data': util.unicodify(f"{ck_data_header}\n{ck_data_body}"), 'ck_index': ck_index + 1}) @build_sniff_from_prefix diff --git a/lib/galaxy/datatypes/triples.py b/lib/galaxy/datatypes/triples.py index 7ee143a9a8f..c7ef1e4c2b9 100644 --- a/lib/galaxy/datatypes/triples.py +++ b/lib/galaxy/datatypes/triples.py @@ -130,7 +130,7 @@ class Rdf(xml.GenericXml, Triples): def sniff_prefix(self, file_prefix): # ' + path + return f"date +\"%s\" > {path}" def __read_seconds_since_epoch(self, job_directory, name): path = self._instrument_file_path(job_directory, f"epoch_{name}") diff --git a/lib/galaxy/jobs/__init__.py b/lib/galaxy/jobs/__init__.py index 78666c1e2b2..bdef16cf9b3 100644 --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -785,7 +785,7 @@ class JobConfiguration(ConfiguresHandlers): # Name to load was specified as '' if '.' not in load: # For legacy reasons, try from galaxy.jobs.runners first if there's no '.' in the name - module_name = 'galaxy.jobs.runners.' + load + module_name = f"galaxy.jobs.runners.{load}" try: module = __import__(module_name) except ImportError: @@ -1521,10 +1521,10 @@ class JobWrapper(HasResourceParameters): dataset.info = (dataset.info or '') if context['stdout'].strip(): # Ensure white space between entries - dataset.info = dataset.info.rstrip() + "\n" + context['stdout'].strip() + dataset.info = f"{dataset.info.rstrip()}\n{context['stdout'].strip()}" if context['stderr'].strip(): # Ensure white space between entries - dataset.info = dataset.info.rstrip() + "\n" + context['stderr'].strip() + dataset.info = f"{dataset.info.rstrip()}\n{context['stderr'].strip()}" dataset.tool_version = self.version_string dataset.set_size() if 'uuid' in context: @@ -2204,7 +2204,7 @@ class JobWrapper(HasResourceParameters): elif job.history is not None and job.history.user is not None: return job.history.user.email elif job.galaxy_session is not None: - return 'anonymous@' + job.galaxy_session.remote_addr.split()[-1] + return f"anonymous@{job.galaxy_session.remote_addr.split()[-1]}" else: return 'anonymous@unknown' diff --git a/lib/galaxy/jobs/actions/post.py b/lib/galaxy/jobs/actions/post.py index 7387500f609..afc7f6565a1 100644 --- a/lib/galaxy/jobs/actions/post.py +++ b/lib/galaxy/jobs/actions/post.py @@ -47,7 +47,7 @@ class EmailAction(DefaultJobAction): try: frm = app.config.email_from history_id_encoded = app.security.encode_id(job.history_id) - link = app.config.galaxy_infrastructure_url + "/histories/view?id=" + history_id_encoded + link = f"{app.config.galaxy_infrastructure_url}/histories/view?id={history_id_encoded}" if frm is None: if action.action_arguments and 'host' in action.action_arguments: host = action.action_arguments['host'] @@ -191,7 +191,7 @@ class RenameDatasetAction(DefaultJobAction): if len(fields) > 1: temp = "" for i in range(1, len(fields) - 1): - temp += "." + fields[i] + temp += f".{fields[i]}" replacement += temp elif operation == "upper": replacement = replacement.upper() @@ -313,7 +313,7 @@ class ColumnSetAction(DefaultJobAction): @classmethod def get_short_str(cls, pja): - return "Set the following metadata values:
" + "
".join('{} : {}'.format(escape(k), escape(v)) for k, v in pja.action_arguments.items()) + return f"Set the following metadata values:
{'
'.join('{} : {}'.format(escape(k), escape(v)) for k, v in pja.action_arguments.items())}" class SetMetadataAction(DefaultJobAction): diff --git a/lib/galaxy/jobs/dynamic_tool_destination.py b/lib/galaxy/jobs/dynamic_tool_destination.py index ad725a87e5b..046003b23af 100755 --- a/lib/galaxy/jobs/dynamic_tool_destination.py +++ b/lib/galaxy/jobs/dynamic_tool_destination.py @@ -352,9 +352,9 @@ class RuleValidator: if "nice_value" in rule: if rule["nice_value"] < -20 or rule["nice_value"] > 20: - error = "nice_value goes from -20 to 20; rule " + str(counter) - error += " in '" + str(tool) + "' has a nice_value of '" - error += str(rule["nice_value"]) + "'." + error = f"nice_value goes from -20 to 20; rule {str(counter)}" + error += f" in '{str(tool)}' has a nice_value of '" + error += f"{str(rule['nice_value'])}'." if not return_bool: error += " Setting nice_value to 0." rule["nice_value"] = 0 @@ -364,8 +364,8 @@ class RuleValidator: valid_rule = False else: - error = "No nice_value found for rule " + str(counter) + " in '" - error += str(tool) + "'." + error = f"No nice_value found for rule {str(counter)} in '" + error += f"{str(tool)}'." if not return_bool: error += " Setting nice_value to 0." rule["nice_value"] = 0 @@ -394,8 +394,8 @@ class RuleValidator: if "fail_message" in rule: if "destination" not in rule or rule['destination'] != "fail": - error = "Found a fail_message for rule " + str(counter) - error += " in '" + str(tool) + "', but destination is not 'fail'!" + error = f"Found a fail_message for rule {str(counter)}" + error += f" in '{str(tool)}', but destination is not 'fail'!" if not return_bool: error += " Setting destination to 'fail'." if verbose: @@ -409,12 +409,12 @@ class RuleValidator: suggestion = None if isinstance(rule["destination"], str): if rule["destination"] == "fail" and "fail_message" not in rule: - error = "Missing a fail_message for rule " + str(counter) - error += " in '" + str(tool) + "'." + error = f"Missing a fail_message for rule {str(counter)}" + error += f" in '{str(tool)}'." if not return_bool: error += " Adding generic fail_message." - message = "Invalid parameters for rule " + str(counter) - message += " in '" + str(tool) + "'." + message = f"Invalid parameters for rule {str(counter)}" + message += f" in '{str(tool)}'." rule["fail_message"] = message if verbose: log.debug(error) @@ -432,12 +432,12 @@ class RuleValidator: for priority in rule["destination"]["priority"]: if priority not in priority_list: error = "Invalid priority '" - error += str(priority) + "' for rule " - error += str(counter) + " in '" + str(tool) + "'." + error += f"{str(priority)}' for rule " + error += f"{str(counter)} in '{str(tool)}'." suggestion = get_typo_correction(priority, priority_list, max_edit_dist) if suggestion: - error += " Did you mean '" + str(suggestion) + "'?" + error += f" Did you mean '{str(suggestion)}'?" if not return_bool: error += " Ignoring..." if verbose: @@ -447,8 +447,8 @@ class RuleValidator: elif not isinstance(rule["destination"]["priority"][priority], str): error = "Cannot parse tool destination '" error += str(rule["destination"]["priority"][priority]) - error += "' for rule " + str(counter) - error += " in '" + str(tool) + "'." + error += f"' for rule {str(counter)}" + error += f" in '{str(tool)}'." if not return_bool: error += " Ignoring..." if verbose: @@ -463,24 +463,24 @@ class RuleValidator: if not is_valid: valid_rule = False else: - error = "No destination specified for rule " + str(counter) - error += " in '" + str(tool) + "'." + error = f"No destination specified for rule {str(counter)}" + error += f" in '{str(tool)}'." if not return_bool: error += " Ignoring..." if verbose: log.debug(error) valid_rule = False else: - error = "No destination specified for rule " + str(counter) - error += " in '" + str(tool) + "'." + error = f"No destination specified for rule {str(counter)}" + error += f" in '{str(tool)}'." if not return_bool: error += " Ignoring..." if verbose: log.debug(error) valid_rule = False else: - error = "No destination specified for rule " + str(counter) - error += " in '" + str(tool) + "'." + error = f"No destination specified for rule {str(counter)}" + error += f" in '{str(tool)}'." if not return_bool: error += " Ignoring..." if verbose: @@ -542,8 +542,8 @@ class RuleValidator: if upper_bound != -1 and lower_bound > upper_bound: - error = "lower_bound exceeds upper_bound for rule " + str(counter) - error += " in '" + str(tool) + "'." + error = f"lower_bound exceeds upper_bound for rule {str(counter)}" + error += f" in '{str(tool)}'." if not return_bool: error += " Reversing bounds." temp_upper_bound = rule["upper_bound"] @@ -555,8 +555,8 @@ class RuleValidator: valid_rule = False else: - error = "Missing bounds for rule " + str(counter) - error += " in '" + str(tool) + "'." + error = f"Missing bounds for rule {str(counter)}" + error += f" in '{str(tool)}'." if not return_bool: error += " Ignoring rule." rule = None @@ -594,8 +594,8 @@ class RuleValidator: """ if "arguments" not in rule or not isinstance(rule["arguments"], dict): - error = "No arguments found for rule " + str(counter) + " in '" - error += str(tool) + "' despite being of type arguments." + error = f"No arguments found for rule {str(counter)} in '" + error += f"{str(tool)}' despite being of type arguments." if not return_bool: error += " Ignoring rule." rule = None @@ -638,9 +638,9 @@ class RuleValidator: if isinstance(rule["users"], list): for user in reversed(rule["users"]): if not isinstance(user, str): - error = "Entry '" + str(user) + "' in users for rule " - error += str(counter) + " in tool '" + str(tool) - error += "' is in an " + "invalid format!" + error = f"Entry '{str(user)}' in users for rule " + error += f"{str(counter)} in tool '{str(tool)}" + error += f"' is in an invalid format!" if not return_bool: error += " Ignoring entry." if verbose: @@ -650,9 +650,9 @@ class RuleValidator: else: if re.match(emailregex, user) is None: - error = "Supplied email '" + str(user) - error += "' for rule " + str(counter) + " in tool '" - error += str(tool) + "' is in " + "an invalid format!" + error = f"Supplied email '{str(user)}" + error += f"' for rule {str(counter)} in tool '" + error += f"{str(tool)}' is in an invalid format!" if not return_bool: error += " Ignoring email." if verbose: @@ -672,8 +672,8 @@ class RuleValidator: # post-processing checking to make sure we didn't just remove all the users # if we did, we should ignore the rule if rule is not None and rule["users"] is not None and len(rule["users"]) == 0: - error = "No valid user emails were specified for rule " + str(counter) - error += " in tool '" + str(tool) + "'!" + error = f"No valid user emails were specified for rule {str(counter)}" + error += f" in tool '{str(tool)}'!" if not return_bool: error += " Ignoring rule." rule = None @@ -786,7 +786,7 @@ def validate_destination(app, destination: str, err_message: str, err_message_co if not valid_destination: error = err_message % err_message_contents if suggestion: - error += " Did you mean '" + suggestion + "'?" + error += f" Did you mean '{suggestion}'?" if not return_bool: error += " Ignoring..." if verbose: @@ -828,7 +828,7 @@ def validate_config(obj: dict, app=None, return_bool: bool = False): else: valid_config = False if obj: - log.debug("Verbose value '" + str(obj['verbose']) + "' is not True or False! Falling back to verbose...") + log.debug(f"Verbose value '{str(obj['verbose'])}' is not True or False! Falling back to verbose...") verbose = True if not return_bool and verbose: @@ -891,7 +891,7 @@ def validate_config(obj: dict, app=None, return_bool: bool = False): suggestion = get_typo_correction(obj['default_priority'], priority_list, max_edit_dist) if suggestion: - error += " Did you mean '" + str(suggestion) + "'?" + error += f" Did you mean '{str(suggestion)}'?" if verbose: log.debug(error) else: @@ -946,17 +946,17 @@ def validate_config(obj: dict, app=None, return_bool: bool = False): suggestion = get_typo_correction(curr['priority'], priority_list, max_edit_dist) if suggestion: - error += " Did you mean '" + str(suggestion) + "'?" + error += f" Did you mean '{str(suggestion)}'?" if verbose: log.debug(error) valid_config = False else: - error = "User '" + user + "' is missing a priority!" + error = f"User '{user}' is missing a priority!" if verbose: log.debug(error) valid_config = False else: - error = "User '" + user + "' is missing a priority!" + error = f"User '{user}' is missing a priority!" if verbose: log.debug(error) valid_config = False @@ -1027,13 +1027,13 @@ def validate_config(obj: dict, app=None, return_bool: bool = False): suggestion = get_typo_correction(priority, priority_list, max_edit_dist) if suggestion: - error += " Did you mean '" + str(suggestion) + "'?" + error += f" Did you mean '{str(suggestion)}'?" if verbose: log.debug(error) valid_config = False else: error = "No default priority destinations specified" - error += " for " + str(tool) + " in config!" + error += f" for {str(tool)} in config!" if verbose: log.debug(error) valid_config = False @@ -1081,8 +1081,8 @@ def validate_config(obj: dict, app=None, return_bool: bool = False): # if rule['rule_type'] in available_rule_types else: error = "Unrecognized rule_type '" - error += rule['rule_type'] + "' " - error += "found in '" + str(tool) + "'. " + error += f"{rule['rule_type']}' " + error += f"found in '{str(tool)}'. " if not return_bool: error += "Ignoring..." if verbose: @@ -1094,7 +1094,7 @@ def validate_config(obj: dict, app=None, return_bool: bool = False): counter += 1 error = "No rule_type found for rule " error += str(counter) - error += " in '" + str(tool) + "'." + error += f" in '{str(tool)}'." if verbose: log.debug(error) valid_config = False @@ -1102,7 +1102,7 @@ def validate_config(obj: dict, app=None, return_bool: bool = False): # if "rules" in curr and isinstance(curr['rules'], list): elif not tool_has_default: valid_config = False - error = "Tool '" + str(tool) + "' does not have" + error = f"Tool '{str(tool)}' does not have" error += " rules nor a default_destination!" if verbose: log.debug(error) @@ -1110,7 +1110,7 @@ def validate_config(obj: dict, app=None, return_bool: bool = False): # if obj['tools'][tool] is not None: else: valid_config = False - error = "Config section for tool '" + str(tool) + "' is blank!" + error = f"Config section for tool '{str(tool)}' is blank!" if verbose: log.debug(error) @@ -1128,7 +1128,7 @@ def validate_config(obj: dict, app=None, return_bool: bool = False): # quickly run through categories to detect unrecognized types for category in obj.keys(): if category not in valid_categories: - error = "Unrecognized category '" + category + error = f"Unrecognized category '{category}" error += "' found in config file!" if verbose: log.debug(error) @@ -1225,7 +1225,7 @@ def str_to_bytes(size): try: curr_size = float(curr_size) except ValueError: - error = "Unable to convert size " + str(size) + error = f"Unable to convert size {str(size)}" raise MalformedYMLException(error) # Get the unit and convert to bytes @@ -1234,7 +1234,7 @@ def str_to_bytes(size): for _ in range(pos, 1, -1): curr_size *= 1024 except ValueError: - error = "Unable to convert size " + str(size) + error = f"Unable to convert size {str(size)}" raise MalformedYMLException(error) except NameError: pass @@ -1343,7 +1343,7 @@ def map_tool_to_destination( if inp_data[da] is not None and os.path.isfile(inp_data[da].file_name): num_input_datasets += 1 if verbose: - message = "Loading file: " + str(da) + message = f"Loading file: {str(da)}" message += str(inp_data[da].file_name) log.debug(message) @@ -1367,15 +1367,15 @@ def map_tool_to_destination( except AttributeError: # Otherwise, say that input isn't a file if verbose: - log.debug("Not a file: " + str(inp_data[da])) + log.debug(f"Not a file: {str(inp_data[da])}") if verbose: if filesize_rule_present: - log.debug("Total size: " + bytes_to_str(file_size)) + log.debug(f"Total size: {bytes_to_str(file_size)}") if records_rule_present: - log.debug("Total amount of records: " + str(records)) + log.debug(f"Total amount of records: {str(records)}") if num_input_datasets_rule_present: - log.debug("Total number of files: " + str(num_input_datasets)) + log.debug(f"Total number of files: {str(num_input_datasets)}") matched_rule = None user_authorized = None @@ -1516,7 +1516,7 @@ def map_tool_to_destination( except KeyError: matched = False if verbose: - error = "Argument '" + str(arg) + error = f"Argument '{str(arg)}" error += "' not recognized!" log.debug(error) @@ -1528,15 +1528,15 @@ def map_tool_to_destination( # if user_authorized else: if verbose: - error = "User email '" + str(user_email) + "' not " + error = f"User email '{str(user_email)}' not " error += "specified in list of authorized users for " - error += "rule " + str(rule_counter) + " in tool '" - error += str(tool.old_id) + "'! Ignoring rule." + error += f"rule {str(rule_counter)} in tool '" + error += f"{str(tool.old_id)}'! Ignoring rule." log.debug(error) # if str(tool.old_id) in config else: - error = "Tool '" + str(tool.old_id) + "' not specified in config. " + error = f"Tool '{str(tool.old_id)}' not specified in config. " error += "Using default destination." if verbose: log.debug(error) @@ -1565,7 +1565,7 @@ def map_tool_to_destination( # if "default_destination" in config else: destination = "fail" - fail_message = "Job '" + str(tool.old_id) + "' failed; " + fail_message = f"Job '{str(tool.old_id)}' failed; " fail_message += "no global default destination specified in config!" # if fail_message is not None @@ -1582,11 +1582,11 @@ def map_tool_to_destination( if config is not None: if destination == "fail": - output = "An error occurred: " + fail_message + output = f"An error occurred: {fail_message}" log.debug(output) else: - output = "Running '" + str(tool.old_id) + "' with '" - output += destination + "'." + output = f"Running '{str(tool.old_id)}' with '" + output += f"{destination}'." log.debug(output) return destination @@ -1650,7 +1650,7 @@ def get_destination_list_from_job_config(job_config_location) -> set: destination_list.add(destination.get("id")) else: - error = "Destination ID '" + str(destination) + error = f"Destination ID '{str(destination)}" error += "' in job configuration file cannot be" error += " parsed. Things may not work as expected!" log.debug(error) @@ -1783,7 +1783,7 @@ if __name__ == '__main__': '-j', '--job-config', dest='job_config') parser.add_argument( - '-V', '--version', action='version', version="%(prog)s " + __version__) + '-V', '--version', action='version', version=f"%(prog)s {__version__}") args = parser.parse_args() diff --git a/lib/galaxy/jobs/handler.py b/lib/galaxy/jobs/handler.py index 5116e5662e8..af91fa1c2e2 100644 --- a/lib/galaxy/jobs/handler.py +++ b/lib/galaxy/jobs/handler.py @@ -1022,7 +1022,7 @@ class DefaultJobDispatcher: # URLs can have their URL params converted to the destination's param # dict by the plugin. self.app.job_config.convert_legacy_destinations(self.job_runners) - log.debug("Loaded job runners plugins: " + ':'.join(self.job_runners.keys())) + log.debug(f"Loaded job runners plugins: {':'.join(self.job_runners.keys())}") def __get_runner_name(self, job_wrapper): if job_wrapper.can_split(): diff --git a/lib/galaxy/jobs/runners/__init__.py b/lib/galaxy/jobs/runners/__init__.py index 9c2267090d3..cffed06346e 100644 --- a/lib/galaxy/jobs/runners/__init__.py +++ b/lib/galaxy/jobs/runners/__init__.py @@ -574,7 +574,7 @@ class JobState: job_name += f'_{self.job_wrapper.tool.old_id}' if not self.redact_email_in_job_name and self.job_wrapper.user: job_name += f'_{self.job_wrapper.user}' - self.job_name = ''.join(x if x in (string.ascii_letters + string.digits + '_') else '_' for x in job_name) + self.job_name = ''.join(x if x in (f"{string.ascii_letters + string.digits}_") else '_' for x in job_name) @staticmethod def default_job_file(files_dir, id_tag): diff --git a/lib/galaxy/jobs/runners/chronos.py b/lib/galaxy/jobs/runners/chronos.py index 5d3a42df1d4..d500ce3a5e8 100644 --- a/lib/galaxy/jobs/runners/chronos.py +++ b/lib/galaxy/jobs/runners/chronos.py @@ -147,10 +147,10 @@ class ChronosJobRunner(AsynchronousJobRunner): @handle_exception_call def queue_job(self, job_wrapper): - LOGGER.debug("Starting queue_job for job " + job_wrapper.get_id_tag()) + LOGGER.debug(f"Starting queue_job for job {job_wrapper.get_id_tag()}") if not self.prepare_job(job_wrapper, include_metadata=False, modify_command_for_container=False): - LOGGER.debug("Not ready " + job_wrapper.get_id_tag()) + LOGGER.debug(f"Not ready {job_wrapper.get_id_tag()}") return job_destination = job_wrapper.job_destination chronos_job_spec = self._get_job_spec(job_wrapper) @@ -279,7 +279,7 @@ class ChronosJobRunner(AsynchronousJobRunner): if not os.path.exists(job_wrapper.working_directory): LOGGER.error("No working directory found") - path = job_wrapper.working_directory + '/chronos_' + job_wrapper.get_id_tag() + '.sh' + path = f"{job_wrapper.working_directory}/chronos_{job_wrapper.get_id_tag()}.sh" mode = 0o755 with open(path, 'w', encoding='utf-8') as f: @@ -295,7 +295,7 @@ class ChronosJobRunner(AsynchronousJobRunner): template = { 'async': False, # 'command': job_wrapper.runner_command_line, - 'command': '$SHELL ' + command_script_path, + 'command': f"$SHELL {command_script_path}", 'owner': self.runner_params['owner'], 'disabled': False, 'schedule': 'R1//PT1S', diff --git a/lib/galaxy/jobs/runners/cli.py b/lib/galaxy/jobs/runners/cli.py index 629220ca664..0896619c8d4 100644 --- a/lib/galaxy/jobs/runners/cli.py +++ b/lib/galaxy/jobs/runners/cli.py @@ -43,8 +43,8 @@ class ShellJobRunner(AsynchronousJobRunner): params = {} shell_params, job_params = url.split('/')[2:4] # split 'foo=bar&baz=quux' into { 'foo' : 'bar', 'baz' : 'quux' } - shell_params = {'shell_' + k: v for k, v in [kv.split('=', 1) for kv in shell_params.split('&')]} - job_params = {'job_' + k: v for k, v in [kv.split('=', 1) for kv in job_params.split('&')]} + shell_params = {f"shell_{k}": v for k, v in [kv.split('=', 1) for kv in shell_params.split('&')]} + job_params = {f"job_{k}": v for k, v in [kv.split('=', 1) for kv in job_params.split('&')]} params.update(shell_params) params.update(job_params) log.debug(f"Converted URL '{url}' to destination runner=cli, params={params}") diff --git a/lib/galaxy/jobs/runners/drmaa.py b/lib/galaxy/jobs/runners/drmaa.py index 1e196031dec..dfab38465c6 100644 --- a/lib/galaxy/jobs/runners/drmaa.py +++ b/lib/galaxy/jobs/runners/drmaa.py @@ -45,8 +45,8 @@ class DRMAAJobRunner(AsynchronousJobRunner): runner_param_specs = { 'drmaa_library_path': dict(map=str, default=os.environ.get('DRMAA_LIBRARY_PATH', None))} for retry_exception in RETRY_EXCEPTIONS_LOWER: - runner_param_specs[retry_exception + '_state'] = dict(map=str, valid=lambda x: x in (model.Job.states.OK, model.Job.states.ERROR), default=model.Job.states.OK) - runner_param_specs[retry_exception + '_retries'] = dict(map=int, valid=lambda x: int(x) >= 0, default=0) + runner_param_specs[f"{retry_exception}_state"] = dict(map=str, valid=lambda x: x in (model.Job.states.OK, model.Job.states.ERROR), default=model.Job.states.OK) + runner_param_specs[f"{retry_exception}_retries"] = dict(map=int, valid=lambda x: int(x) >= 0, default=0) if 'runner_param_specs' not in kwargs: kwargs['runner_param_specs'] = dict() @@ -283,11 +283,11 @@ class DRMAAJobRunner(AsynchronousJobRunner): state = self.ds.job_status(external_job_id) # Reset exception retries for retry_exception in RETRY_EXCEPTIONS_LOWER: - setattr(ajs, retry_exception + '_retries', 0) + setattr(ajs, f"{retry_exception}_retries", 0) except (drmaa.InternalException, drmaa.InvalidJobException) as e: ecn = type(e).__name__ - retry_param = ecn.lower() + '_retries' - state_param = ecn.lower() + '_state' + retry_param = f"{ecn.lower()}_retries" + state_param = f"{ecn.lower()}_state" retries = getattr(ajs, retry_param, 0) log.warning("(%s/%s) unable to check job status because of %s exception for %d consecutive tries: %s", galaxy_id_tag, external_job_id, ecn, retries + 1, e) if self.runner_params[retry_param] > 0: @@ -436,7 +436,7 @@ class DRMAAJobRunner(AsynchronousJobRunner): job_name += f'_{job_wrapper.tool.old_id}' if not self.redact_email_in_job_name and external_runjob_script is None: job_name += f'_{job_wrapper.user}' - job_name = ''.join(x if x in (string.ascii_letters + string.digits + '_') else '_' for x in job_name) + job_name = ''.join(x if x in (f"{string.ascii_letters + string.digits}_") else '_' for x in job_name) if self.restrict_job_name_length: job_name = job_name[:self.restrict_job_name_length] return job_name diff --git a/lib/galaxy/jobs/runners/godocker.py b/lib/galaxy/jobs/runners/godocker.py index 9f9399497e6..6b689ca4984 100644 --- a/lib/galaxy/jobs/runners/godocker.py +++ b/lib/galaxy/jobs/runners/godocker.py @@ -157,7 +157,7 @@ class GodockerJobRunner(AsynchronousJobRunner): log.error("Job creation failure. No Response from GoDocker") job_wrapper.fail("Not submitted") else: - log.debug("Starting queue_job for job " + job_id) + log.debug(f"Starting queue_job for job {job_id}") # Create an object of AsynchronousJobState and add it to the monitor queue. ajs = AsynchronousJobState(files_dir=job_wrapper.working_directory, job_wrapper=job_wrapper, job_id=job_id, job_destination=job_destination) self.monitor_queue.put(ajs) @@ -180,7 +180,7 @@ class GodockerJobRunner(AsynchronousJobRunner): """ Get task from GoDocker """ job_persisted_state = job_state.job_wrapper.get_state() job_status_god = self.get_task(job_state.job_id) - log.debug("Job ID: " + str(job_state.job_id) + " Job Status: " + str(job_status_god['status']['primary'])) + log.debug(f"Job ID: {str(job_state.job_id)} Job Status: {str(job_status_god['status']['primary'])}") if job_status_god['status']['primary'] == "over" or job_persisted_state == model.Job.states.STOPPED: job_state.running = False @@ -234,7 +234,7 @@ class GodockerJobRunner(AsynchronousJobRunner): No Return data expected ''' job_id = job_wrapper.job_id - log.debug("STOP JOB EXECUTION OF JOB ID: " + str(job_id)) + log.debug(f"STOP JOB EXECUTION OF JOB ID: {str(job_id)}") # Get task status from GoDocker. job_status_god = self.get_task_status(job_id) if job_status_god['status']['primary'] != "over": @@ -276,8 +276,8 @@ class GodockerJobRunner(AsynchronousJobRunner): if vol['name'] == "go-docker": path = str(vol['path']) if path: - god_output_file = path + "/god.log" - god_error_file = path + "/god.err" + god_output_file = f"{path}/god.log" + god_error_file = f"{path}/god.err" try: # Read from GoDocker output_file and write it into galaxy output_file. f = open(god_output_file) @@ -299,9 +299,9 @@ class GodockerJobRunner(AsynchronousJobRunner): log_file.write(out_log) log_file.close() f.close() - log.debug("CREATE OUTPUT FILE: " + job_state.output_file) - log.debug("CREATE ERROR FILE: " + job_state.error_file) - log.debug("CREATE EXIT CODE FILE: " + job_state.exit_code_file) + log.debug(f"CREATE OUTPUT FILE: {job_state.output_file}") + log.debug(f"CREATE ERROR FILE: {job_state.error_file}") + log.debug(f"CREATE EXIT CODE FILE: {job_state.exit_code_file}") except OSError as e: log.error('Could not access task log file: %s', unicodify(e)) log.debug("IO Error occurred when accessing the files.") @@ -315,7 +315,7 @@ class GodockerJobRunner(AsynchronousJobRunner): Create Login model schema of GoDocker and call the http_post_request method. """ log.debug("LOGIN TASK TO BE EXECUTED \n") - log.debug("GODOCKER LOGIN: " + str(login)) + log.debug(f"GODOCKER LOGIN: {str(login)}") data = json.dumps({'user': login, 'apikey': apikey}) # Create object of Godocker class g_auth = Godocker(server, login, apikey, noCert) @@ -378,11 +378,11 @@ class GodockerJobRunner(AsynchronousJobRunner): if(job_destination.params["virtualenv"] == "true"): GALAXY_VENV_TEMPLATE = """GALAXY_VIRTUAL_ENV="%s"; if [ "$GALAXY_VIRTUAL_ENV" != "None" -a -z "$VIRTUAL_ENV" -a -f "$GALAXY_VIRTUAL_ENV/bin/activate" ]; then . "$GALAXY_VIRTUAL_ENV/bin/activate"; fi;""" venv = GALAXY_VENV_TEMPLATE % job_wrapper.galaxy_virtual_env - command = "#!/bin/bash\n" + "cd " + job_wrapper.working_directory + "\n" + venv + "\n" + job_wrapper.runner_command_line + command = f"#!/bin/bash\ncd {job_wrapper.working_directory}\n{venv}\n{job_wrapper.runner_command_line}" else: - command = "#!/bin/bash\n" + "cd " + job_wrapper.working_directory + "\n" + job_wrapper.runner_command_line + command = f"#!/bin/bash\ncd {job_wrapper.working_directory}\n{job_wrapper.runner_command_line}" except Exception: - command = "#!/bin/bash\n" + "cd " + job_wrapper.working_directory + "\n" + job_wrapper.runner_command_line + command = f"#!/bin/bash\ncd {job_wrapper.working_directory}\n{job_wrapper.runner_command_line}" # GoDocker Job model schema job = { @@ -424,7 +424,7 @@ class GodockerJobRunner(AsynchronousJobRunner): result = self.auth.http_post_request( "/api/1.0/task", json.dumps(job), - {'Authorization': 'Bearer ' + self.auth.token, 'Content-type': 'application/json', 'Accept': 'application/json'} + {'Authorization': f"Bearer {self.auth.token}", 'Content-type': 'application/json', 'Accept': 'application/json'} ) # Return job_id return str(result.json()['id']) @@ -435,7 +435,7 @@ class GodockerJobRunner(AsynchronousJobRunner): """ job = False if self.auth.token: - result = self.auth.http_get_request("/api/1.0/task/" + str(job_id), {'Authorization': 'Bearer ' + self.auth.token}) + result = self.auth.http_get_request(f"/api/1.0/task/{str(job_id)}", {'Authorization': f"Bearer {self.auth.token}"}) job = result.json() # Return the job return job @@ -446,7 +446,7 @@ class GodockerJobRunner(AsynchronousJobRunner): """ job = False if self.auth.token: - result = self.auth.http_get_request("/api/1.0/task/" + str(job_id) + "/suspend", {'Authorization': 'Bearer ' + self.auth.token}) + result = self.auth.http_get_request(f"/api/1.0/task/{str(job_id)}/suspend", {'Authorization': f"Bearer {self.auth.token}"}) job = result.json() # Return the job return job @@ -457,7 +457,7 @@ class GodockerJobRunner(AsynchronousJobRunner): """ job = False if self.auth.token: - result = self.auth.http_get_request("/api/1.0/task/" + str(job_id) + "/status", {'Authorization': 'Bearer ' + self.auth.token}) + result = self.auth.http_get_request(f"/api/1.0/task/{str(job_id)}/status", {'Authorization': f"Bearer {self.auth.token}"}) job = result.json() # Return task status return job @@ -468,7 +468,7 @@ class GodockerJobRunner(AsynchronousJobRunner): """ job = False if self.auth.token: - result = self.auth.http_delete_request("/api/1.0/task/" + str(job_id), {'Authorization': 'Bearer ' + self.auth.token}) + result = self.auth.http_delete_request(f"/api/1.0/task/{str(job_id)}", {'Authorization': f"Bearer {self.auth.token}"}) job = result.json() # Return the job return job diff --git a/lib/galaxy/jobs/runners/kubernetes.py b/lib/galaxy/jobs/runners/kubernetes.py index aaf33c98ed5..da158f48bf7 100644 --- a/lib/galaxy/jobs/runners/kubernetes.py +++ b/lib/galaxy/jobs/runners/kubernetes.py @@ -127,7 +127,7 @@ class KubernetesJobRunner(AsynchronousJobRunner): # prepare the job # We currently don't need to include_metadata or include_work_dir_outputs, as working directory is the same # where galaxy will expect results. - log.debug("Starting queue_job for job " + job_wrapper.get_id_tag()) + log.debug(f"Starting queue_job for job {job_wrapper.get_id_tag()}") ajs = AsynchronousJobState(files_dir=job_wrapper.working_directory, job_wrapper=job_wrapper, job_destination=job_wrapper.job_destination) @@ -240,7 +240,7 @@ class KubernetesJobRunner(AsynchronousJobRunner): """ label_val = self.LABEL_REGEX.sub("_", value) if not self.LABEL_START.search(label_val): - label_val = 'x' + label_val + label_val = f"x{label_val}" if not self.LABEL_END.search(label_val): label_val += 'x' return label_val @@ -521,14 +521,14 @@ class KubernetesJobRunner(AsynchronousJobRunner): repo = "" owner = "" if 'repo' in job_destination.params: - repo = job_destination.params['repo'] + "/" + repo = f"{job_destination.params['repo']}/" if 'owner' in job_destination.params: - owner = job_destination.params['owner'] + "/" + owner = f"{job_destination.params['owner']}/" k8s_cont_image = repo + owner + job_destination.params['image'] if 'tag' in job_destination.params: - k8s_cont_image += ":" + job_destination.params['tag'] + k8s_cont_image += f":{job_destination.params['tag']}" return k8s_cont_image @@ -788,7 +788,7 @@ class KubernetesJobRunner(AsynchronousJobRunner): def recover(self, job, job_wrapper): """Recovers jobs stuck in the queued/running state when Galaxy started""" job_id = job.get_job_runner_external_id() - log.debug("k8s trying to recover job: " + job_id) + log.debug(f"k8s trying to recover job: {job_id}") if job_id is None: self.put(job_wrapper) return diff --git a/lib/galaxy/jobs/runners/pbs.py b/lib/galaxy/jobs/runners/pbs.py index 8e235c44872..7088007a6f7 100644 --- a/lib/galaxy/jobs/runners/pbs.py +++ b/lib/galaxy/jobs/runners/pbs.py @@ -140,7 +140,7 @@ class PBSJobRunner(AsynchronousJobRunner): assert opts != [''] # stripping the - comes later (in parse_destination_params) for i, opt in enumerate(opts): - opts[i] = '-' + opt + opts[i] = f"-{opt}" except Exception: opts = [] for opt in opts: @@ -184,7 +184,7 @@ class PBSJobRunner(AsynchronousJobRunner): rval.append(dict(name=pbs.ATTR_l, value=val, resource=res)) else: try: - rval.append(dict(name=getattr(pbs, 'ATTR_' + arg), value=value)) + rval.append(dict(name=getattr(pbs, f"ATTR_{arg}"), value=value)) except AttributeError as e: raise Exception(f"Invalid parameter '{arg}': {e}") return rval @@ -242,8 +242,8 @@ class PBSJobRunner(AsynchronousJobRunner): # If an application server is set, we're staging if self.app.config.pbs_application_server: - pbs_ofile = self.app.config.pbs_application_server + ':' + ofile - pbs_efile = self.app.config.pbs_application_server + ':' + efile + pbs_ofile = f"{self.app.config.pbs_application_server}:{ofile}" + pbs_efile = f"{self.app.config.pbs_application_server}:{efile}" output_files = [str(o) for o in output_fnames] output_files.append(ecfile) stagein = self.get_stage_in_out(job_wrapper.get_input_fnames() + output_files, symlink=True) diff --git a/lib/galaxy/jobs/runners/slurm.py b/lib/galaxy/jobs/runners/slurm.py index f05dcd00658..794d9bde7ae 100644 --- a/lib/galaxy/jobs/runners/slurm.py +++ b/lib/galaxy/jobs/runners/slurm.py @@ -85,7 +85,7 @@ class SlurmJobRunner(DRMAAJobRunner): job_info_values.append(v) except ValueError: # Some value may contain spaces (e.g. `Comment=** time_limit (60m) min_nodes (1) **`) - job_info_values[-1] += ' ' + job_info + job_info_values[-1] += f" {job_info}" job_info_dict = dict(zip(job_info_keys, job_info_values)) return job_info_dict['JobState'] diff --git a/lib/galaxy/jobs/runners/util/cli/job/lsf.py b/lib/galaxy/jobs/runners/util/cli/job/lsf.py index bce64d4120e..a3ad27e123c 100644 --- a/lib/galaxy/jobs/runners/util/cli/job/lsf.py +++ b/lib/galaxy/jobs/runners/util/cli/job/lsf.py @@ -66,7 +66,7 @@ class LSF(BaseJobExec): return "bjobs -a -o \"id stat\" -noheader" # check this def get_single_status(self, job_id): - return "bjobs -o stat -noheader " + job_id + return f"bjobs -o stat -noheader {job_id}" def parse_status(self, status, job_ids): # Get status for each job, skipping header. @@ -91,7 +91,7 @@ class LSF(BaseJobExec): return self._get_job_state(status) def get_failure_reason(self, job_id): - return "bjobs -l " + job_id + return f"bjobs -l {job_id}" def parse_failure_reason(self, reason, job_id): # LSF will produce the following in the job output file: diff --git a/lib/galaxy/jobs/runners/util/cli/job/slurm.py b/lib/galaxy/jobs/runners/util/cli/job/slurm.py index ff8a6ba46d9..d87479b513d 100644 --- a/lib/galaxy/jobs/runners/util/cli/job/slurm.py +++ b/lib/galaxy/jobs/runners/util/cli/job/slurm.py @@ -52,7 +52,7 @@ class Slurm(BaseJobExec): return "squeue -a -o '%A %t'" def get_single_status(self, job_id): - return "squeue -a -o '%A %t' -j " + job_id + return f"squeue -a -o '%A %t' -j {job_id}" def parse_status(self, status, job_ids): # Get status for each job, skipping header. diff --git a/lib/galaxy/jobs/runners/util/condor/__init__.py b/lib/galaxy/jobs/runners/util/condor/__init__.py index 2fbead6c80f..93b2c5cdf5b 100644 --- a/lib/galaxy/jobs/runners/util/condor/__init__.py +++ b/lib/galaxy/jobs/runners/util/condor/__init__.py @@ -60,10 +60,10 @@ def build_submit_description(executable, output, error, user_log, query_params): submit_description = [] for key, value in all_query_params.items(): submit_description.append(f'{key} = {value}') - submit_description.append('executable = ' + executable) - submit_description.append('output = ' + output) - submit_description.append('error = ' + error) - submit_description.append('log = ' + user_log) + submit_description.append(f"executable = {executable}") + submit_description.append(f"output = {output}") + submit_description.append(f"error = {error}") + submit_description.append(f"log = {user_log}") submit_description.append('queue') return '\n'.join(submit_description) @@ -109,15 +109,15 @@ def summarize_condor_log(log_file, external_id): s1 = s4 = s7 = s5 = s9 = False with open(log_file) as log_handle: for line in log_handle: - if '001 (' + log_job_id + '.' in line: + if f"001 ({log_job_id}." in line: s1 = True - if '004 (' + log_job_id + '.' in line: + if f"004 ({log_job_id}." in line: s4 = True - if '007 (' + log_job_id + '.' in line: + if f"007 ({log_job_id}." in line: s7 = True - if '005 (' + log_job_id + '.' in line: + if f"005 ({log_job_id}." in line: s5 = True - if '009 (' + log_job_id + '.' in line: + if f"009 ({log_job_id}." in line: s9 = True file_size = log_handle.tell() return s1, s4, s7, s5, s9, file_size diff --git a/lib/galaxy/jobs/runners/util/pykube_util.py b/lib/galaxy/jobs/runners/util/pykube_util.py index 7b57c7f9e52..87abfe59cbe 100644 --- a/lib/galaxy/jobs/runners/util/pykube_util.py +++ b/lib/galaxy/jobs/runners/util/pykube_util.py @@ -83,7 +83,7 @@ def find_job_object_by_name(pykube_api, job_name, namespace=None): def find_pod_object_by_name(pykube_api, job_name, namespace=None): - return Pod.objects(pykube_api).filter(selector="job-name=" + job_name, namespace=namespace) + return Pod.objects(pykube_api).filter(selector=f"job-name={job_name}", namespace=namespace) def is_pod_unschedulable(pykube_api, pod, namespace=None): @@ -145,7 +145,7 @@ def job_object_dict(params, job_prefix, spec): "apiVersion": params.get('k8s_job_api_version', DEFAULT_JOB_API_VERSION), "kind": "Job", "metadata": { - "generateName": job_prefix + "-", + "generateName": f"{job_prefix}-", "namespace": params.get('k8s_namespace', DEFAULT_NAMESPACE), }, "spec": spec, diff --git a/lib/galaxy/jobs/splitters/multi.py b/lib/galaxy/jobs/splitters/multi.py index 3866ee90c2a..0fc3fe95a17 100644 --- a/lib/galaxy/jobs/splitters/multi.py +++ b/lib/galaxy/jobs/splitters/multi.py @@ -101,7 +101,7 @@ def do_split(job_wrapper): for file in names: os.symlink(file, os.path.join(dir, os.path.basename(file))) tasks = [] - prepare_files = os.path.join(util.galaxy_directory(), 'extract_dataset_parts.sh') + ' %s' + prepare_files = f"{os.path.join(util.galaxy_directory(), 'extract_dataset_parts.sh')} %s" for dir in task_dirs: task = model.Task(parent_job, dir, prepare_files % dir) tasks.append(task) @@ -167,7 +167,7 @@ def do_merge(job_wrapper, task_wrappers): msg = 'nothing to merge for %s (expected %i files)' \ % (output_file_name, len(task_dirs)) log.debug(msg) - stderr += msg + "\n" + stderr += f"{msg}\n" elif output in pickone_outputs: # just pick one of them if output not in pickone_done: @@ -189,7 +189,7 @@ def do_merge(job_wrapper, task_wrappers): out = tw.get_task().stdout.strip() err = tw.get_task().stderr.strip() if len(out) > 0: - stdout += "\n" + tw.working_directory + ':\n' + out + stdout += f"\n{tw.working_directory}:\n{out}" if len(err) > 0: - stderr += "\n" + tw.working_directory + ':\n' + err + stderr += f"\n{tw.working_directory}:\n{err}" return (stdout, stderr) diff --git a/lib/galaxy/managers/base.py b/lib/galaxy/managers/base.py index a5d4f3327b7..928dcc64b75 100644 --- a/lib/galaxy/managers/base.py +++ b/lib/galaxy/managers/base.py @@ -267,9 +267,9 @@ class ModelManager: try: return query.one() except sqlalchemy.orm.exc.NoResultFound: - raise exceptions.ObjectNotFound(self.model_class.__name__ + ' not found') + raise exceptions.ObjectNotFound(f"{self.model_class.__name__} not found") except sqlalchemy.orm.exc.MultipleResultsFound: - raise exceptions.InconsistentDatabase('found more than one ' + self.model_class.__name__) + raise exceptions.InconsistentDatabase(f"found more than one {self.model_class.__name__}") def _one_or_none(self, query): """ @@ -622,7 +622,7 @@ class ModelSerializer(HasAModelManager): return self.serializers[original_key] if original_key in self.serializable_keyset: return lambda i, k, **c: self.default_serializer(i, original_key, **c) - raise KeyError('serializer not found for remap: ' + original_key) + raise KeyError(f"serializer not found for remap: {original_key}") def default_serializer(self, item, key, **context): """ @@ -1053,7 +1053,7 @@ class ModelFilterParser(HasAModelManager): # correct op_string to usable function key fn_name = op_string if op_string in self.UNDERSCORED_OPS: - fn_name = '__' + op_string + '__' + fn_name = f"__{op_string}__" elif op_string == 'in': fn_name = 'in_' @@ -1084,7 +1084,7 @@ class ModelFilterParser(HasAModelManager): return True if bool_string in ('False', False): return False - raise ValueError('invalid boolean: ' + str(bool_string)) + raise ValueError(f"invalid boolean: {str(bool_string)}") def parse_id_list(self, id_list_string, sep=','): """ diff --git a/lib/galaxy/managers/citations.py b/lib/galaxy/managers/citations.py index a0a8dcd1818..174bdca10a3 100644 --- a/lib/galaxy/managers/citations.py +++ b/lib/galaxy/managers/citations.py @@ -46,7 +46,7 @@ class DoiCache: self._cache = CacheManager(**parse_cache_config_options(cache_opts)).get_cache('doi') def _raw_get_bibtex(self, doi): - doi_url = "https://doi.org/" + doi + doi_url = f"https://doi.org/{doi}" headers = {'Accept': 'application/x-bibtex'} req = requests.get(doi_url, headers=headers) req.encoding = req.apparent_encoding diff --git a/lib/galaxy/managers/containers.py b/lib/galaxy/managers/containers.py index e8ef05bdd57..3c105da8bd9 100644 --- a/lib/galaxy/managers/containers.py +++ b/lib/galaxy/managers/containers.py @@ -92,7 +92,7 @@ class LibraryFolderAsContainerManagerMixin(ContainerManagerMixin): return self.lda_manager elif isinstance(content, model.LibraryFolder): return self.folder_manager - raise TypeError('Unknown contents class: ' + str(content)) + raise TypeError(f"Unknown contents class: {str(content)}") class DatasetCollectionAsContainerManagerMixin(ContainerManagerMixin): @@ -111,4 +111,4 @@ class DatasetCollectionAsContainerManagerMixin(ContainerManagerMixin): return self.collection_manager elif isinstance(content, model.DatasetCollection): return self.collection_manager - raise TypeError('Unknown contents class: ' + str(content)) + raise TypeError(f"Unknown contents class: {str(content)}") diff --git a/lib/galaxy/managers/datasets.py b/lib/galaxy/managers/datasets.py index 8036962c52b..84f08e1f5af 100644 --- a/lib/galaxy/managers/datasets.py +++ b/lib/galaxy/managers/datasets.py @@ -489,7 +489,7 @@ class _UnflattenedMetadataDatasetAssociationSerializer(base.ModelSerializer, 'genome_build': lambda i, k, **c: i.dbkey, # derived (not mapped) attributes - 'data_type': lambda i, k, **c: i.datatype.__class__.__module__ + '.' + i.datatype.__class__.__name__, + 'data_type': lambda i, k, **c: f"{i.datatype.__class__.__module__}.{i.datatype.__class__.__name__}", 'converted': self.serialize_converted_datasets, # TODO: metadata/extra files @@ -636,7 +636,7 @@ class DatasetAssociationSerializer(_UnflattenedMetadataDatasetAssociationSeriali # prefix each key within and return prefixed = {} for key, val in metadata.items(): - prefixed_key = 'metadata_' + key + prefixed_key = f"metadata_{key}" prefixed[prefixed_key] = val return prefixed diff --git a/lib/galaxy/managers/executables.py b/lib/galaxy/managers/executables.py index d4250691c21..776f7299367 100644 --- a/lib/galaxy/managers/executables.py +++ b/lib/galaxy/managers/executables.py @@ -25,7 +25,7 @@ def artifact_class(trans, as_dict): else: for item in graph: found_id = item.get("id") - if found_id == object_id or found_id == "#" + object_id: + if found_id == object_id or found_id == f"#{object_id}": target_object = item if target_object and target_object.get("class"): diff --git a/lib/galaxy/managers/folders.py b/lib/galaxy/managers/folders.py index d3c0c305f23..96d071ccffe 100644 --- a/lib/galaxy/managers/folders.py +++ b/lib/galaxy/managers/folders.py @@ -135,9 +135,9 @@ class FolderManager: """ folder_dict = folder.to_dict(view='element') folder_dict = trans.security.encode_all_ids(folder_dict, True) - folder_dict['id'] = 'F' + folder_dict['id'] + folder_dict['id'] = f"F{folder_dict['id']}" if folder_dict['parent_id'] is not None: - folder_dict['parent_id'] = 'F' + folder_dict['parent_id'] + folder_dict['parent_id'] = f"F{folder_dict['parent_id']}" folder_dict['update_time'] = folder.update_time.strftime("%Y-%m-%d %I:%M %p") return folder_dict diff --git a/lib/galaxy/managers/lddas.py b/lib/galaxy/managers/lddas.py index 5f088b32078..c4dcdf6d3f4 100644 --- a/lib/galaxy/managers/lddas.py +++ b/lib/galaxy/managers/lddas.py @@ -45,7 +45,7 @@ class LDDAManager(DatasetAssociationManager): else: invalid_access_roles_ids.append(role_id) if len(invalid_access_roles_ids) > 0: - log.warning("The following roles could not be added to the dataset access permission: " + str(invalid_access_roles_ids)) + log.warning(f"The following roles could not be added to the dataset access permission: {str(invalid_access_roles_ids)}") access_permission = dict(access=valid_access_roles) trans.app.security_agent.set_dataset_permission(dataset, access_permission) @@ -61,7 +61,7 @@ class LDDAManager(DatasetAssociationManager): else: invalid_manage_roles_ids.append(role_id) if len(invalid_manage_roles_ids) > 0: - log.warning("The following roles could not be added to the dataset manage permission: " + str(invalid_manage_roles_ids)) + log.warning(f"The following roles could not be added to the dataset manage permission: {str(invalid_manage_roles_ids)}") manage_permission = {trans.app.security_agent.permitted_actions.DATASET_MANAGE_PERMISSIONS: valid_manage_roles} trans.app.security_agent.set_dataset_permission(dataset, manage_permission) @@ -76,6 +76,6 @@ class LDDAManager(DatasetAssociationManager): else: invalid_modify_roles_ids.append(role_id) if len(invalid_modify_roles_ids) > 0: - log.warning("The following roles could not be added to the dataset modify permission: " + str(invalid_modify_roles_ids)) + log.warning(f"The following roles could not be added to the dataset modify permission: {str(invalid_modify_roles_ids)}") modify_permission = {trans.app.security_agent.permitted_actions.LIBRARY_MODIFY: valid_modify_roles} trans.app.security_agent.set_library_item_permission(library_dataset, modify_permission) diff --git a/lib/galaxy/managers/libraries.py b/lib/galaxy/managers/libraries.py index 49bbd341d18..639cac2f518 100644 --- a/lib/galaxy/managers/libraries.py +++ b/lib/galaxy/managers/libraries.py @@ -56,7 +56,7 @@ class LibraryManager: except NoResultFound: raise exceptions.RequestParameterInvalidException('No library found with the id provided.') except Exception as e: - raise exceptions.InternalServerError('Error loading from the database.' + unicodify(e)) + raise exceptions.InternalServerError(f"Error loading from the database.{unicodify(e)}") library = self.secure(trans, library, check_accessible) return library @@ -558,7 +558,7 @@ class LibrariesManager: else: invalid_access_roles_names.append(role_id) if len(invalid_access_roles_names) > 0: - log.warning("The following roles could not be added to the library access permission: " + str(invalid_access_roles_names)) + log.warning(f"The following roles could not be added to the library access permission: {str(invalid_access_roles_names)}") # ADD TO LIBRARY ROLES valid_add_roles = [] @@ -571,7 +571,7 @@ class LibrariesManager: else: invalid_add_roles_names.append(role_id) if len(invalid_add_roles_names) > 0: - log.warning("The following roles could not be added to the add library item permission: " + str(invalid_add_roles_names)) + log.warning(f"The following roles could not be added to the add library item permission: {str(invalid_add_roles_names)}") # MANAGE LIBRARY ROLES valid_manage_roles = [] @@ -584,7 +584,7 @@ class LibrariesManager: else: invalid_manage_roles_names.append(role_id) if len(invalid_manage_roles_names) > 0: - log.warning("The following roles could not be added to the manage library permission: " + str(invalid_manage_roles_names)) + log.warning(f"The following roles could not be added to the manage library permission: {str(invalid_manage_roles_names)}") # MODIFY LIBRARY ROLES valid_modify_roles = [] @@ -597,7 +597,7 @@ class LibrariesManager: else: invalid_modify_roles_names.append(role_id) if len(invalid_modify_roles_names) > 0: - log.warning("The following roles could not be added to the modify library permission: " + str(invalid_modify_roles_names)) + log.warning(f"The following roles could not be added to the modify library permission: {str(invalid_modify_roles_names)}") permissions = {trans.app.security_agent.permitted_actions.LIBRARY_ACCESS: valid_access_roles} permissions.update({trans.app.security_agent.permitted_actions.LIBRARY_ADD: valid_add_roles}) @@ -623,7 +623,7 @@ class LibrariesManager: params = util.Params(payload) permissions = {} for k, v in trans.app.model.Library.permitted_actions.items(): - role_params = params.get(k + '_in', []) + role_params = params.get(f"{k}_in", []) in_roles = [trans.sa_session.query(trans.app.model.Role).get(trans.security.decode_id(x)) for x in util.listify(role_params)] permissions[trans.app.security_agent.get_action(v.action)] = in_roles trans.app.security_agent.set_all_library_permissions(trans, library, permissions) diff --git a/lib/galaxy/managers/library_datasets.py b/lib/galaxy/managers/library_datasets.py index 8c761458987..7bb2f55ecf2 100644 --- a/lib/galaxy/managers/library_datasets.py +++ b/lib/galaxy/managers/library_datasets.py @@ -43,7 +43,7 @@ class LibraryDatasetsManager(datasets.DatasetAssociationManager): try: ld = trans.sa_session.query(trans.app.model.LibraryDataset).filter(trans.app.model.LibraryDataset.table.c.id == decoded_library_dataset_id).one() except Exception as e: - raise InternalServerError('Error loading from the database.' + util.unicodify(e)) + raise InternalServerError(f"Error loading from the database.{util.unicodify(e)}") ld = self.secure(trans, ld, check_accessible) return ld @@ -232,7 +232,7 @@ class LibraryDatasetsManager(datasets.DatasetAssociationManager): if ldda.dataset.uuid: rval['uuid'] = str(ldda.dataset.uuid) rval['deleted'] = ld.deleted - rval['folder_id'] = 'F' + rval['folder_id'] + rval['folder_id'] = f"F{rval['folder_id']}" rval['full_path'] = full_path rval['file_size'] = util.nice_size(int(ldda.get_size())) rval['date_uploaded'] = ldda.create_time.strftime("%Y-%m-%d %I:%M %p") @@ -259,10 +259,10 @@ class LibraryDatasetsManager(datasets.DatasetAssociationManager): path_to_root = [] if folder.parent_id is None: # We are almost in root - path_to_root.append(('F' + trans.security.encode_id(folder.id), folder.name)) + path_to_root.append((f"F{trans.security.encode_id(folder.id)}", folder.name)) else: # We add the current folder and traverse up one folder. - path_to_root.append(('F' + trans.security.encode_id(folder.id), folder.name)) + path_to_root.append((f"F{trans.security.encode_id(folder.id)}", folder.name)) upper_folder = trans.sa_session.query(trans.app.model.LibraryFolder).get(folder.parent_id) path_to_root.extend(self._build_path(trans, upper_folder)) return path_to_root diff --git a/lib/galaxy/managers/markdown_parse.py b/lib/galaxy/managers/markdown_parse.py index 3c4effd7f9a..f4f658c878c 100644 --- a/lib/galaxy/managers/markdown_parse.py +++ b/lib/galaxy/managers/markdown_parse.py @@ -47,7 +47,7 @@ FUNCTION_ARG = r'\s*[\w\|]+\s*=\s*(?:%s)\s*' % ARG_VAL_REGEX # embed commas between arguments FUNCTION_MULTIPLE_ARGS = fr'(?P{FUNCTION_ARG})(?P(?:,{FUNCTION_ARG})*)' FUNCTION_MULTIPLE_ARGS_PATTERN = re.compile(FUNCTION_MULTIPLE_ARGS) -FUNCTION_CALL_LINE_TEMPLATE = r'\s*%s\s*\((?:' + FUNCTION_MULTIPLE_ARGS + r')?\)\s*' +FUNCTION_CALL_LINE_TEMPLATE = f"\\s*%s\\s*\\((?:{FUNCTION_MULTIPLE_ARGS})?\\)\\s*" GALAXY_MARKDOWN_FUNCTION_CALL_LINE = re.compile(FUNCTION_CALL_LINE_TEMPLATE % GALAXY_FLAVORED_MARKDOWN_CONTAINER_REGEX) WHITE_SPACE_ONLY_PATTERN = re.compile(r"^[\s]+$") diff --git a/lib/galaxy/managers/markdown_util.py b/lib/galaxy/managers/markdown_util.py index 53b0f5a1d0a..bf198d1a815 100644 --- a/lib/galaxy/managers/markdown_util.py +++ b/lib/galaxy/managers/markdown_util.py @@ -452,7 +452,7 @@ class ToBasicMarkdownDirectiveHandler(GalaxyInternalMarkdownDirectiveHandler): def walk_elements(collection, element_prefix=""): if ":" in collection.collection_type: for element in collection.elements: - walk_elements(element.child_collection, element_prefix + element.element_identifier + ":") + walk_elements(element.child_collection, f"{element_prefix + element.element_identifier}:") else: for element in collection.elements: markdown_wrapper[0] += f"**Element:** {element_prefix}{element.element_identifier}\n\n" @@ -495,7 +495,7 @@ class ToBasicMarkdownDirectiveHandler(GalaxyInternalMarkdownDirectiveHandler): markdown += "| " depth = parameter["depth"] if depth > 1: - markdown += ">" * (parameter["depth"] - 1) + " " + markdown += f"{'>' * (parameter['depth'] - 1)} " markdown += parameter["text"] markdown += " | " value = parameter["value"] @@ -767,7 +767,7 @@ def _remap_galaxy_markdown_calls(func, markdown): if matching_line: match = GALAXY_MARKDOWN_FUNCTION_CALL_LINE.match(line) - return func(match.group(1), matching_line + "\n") + return func(match.group(1), f"{matching_line}\n") else: return (container, True) diff --git a/lib/galaxy/managers/pages.py b/lib/galaxy/managers/pages.py index 292a7b351ad..7fb35b5f01e 100644 --- a/lib/galaxy/managers/pages.py +++ b/lib/galaxy/managers/pages.py @@ -485,9 +485,9 @@ class PageContentProcessor(HTMLParser): def _shorttag_replace(self, match): tag = match.group(1) if tag in self.elements_no_end_tag: - return '<' + tag + ' />' + return f"<{tag} />" else: - return '<' + tag + '>' + return f"<{tag}>" def feed(self, data): data = re.compile(r' 0: - llog_name += ':' + job_name + llog_name += f":{job_name}" llog = logging.getLogger(llog_name) # Print the command we're about to execute, ``set -x`` style. - llog.debug('+ ' + str(command)) + llog.debug(f"+ {str(command)}") # Launch the command as subprocess. A bufsize of 1 means line buffered. process_handle = subprocess.Popen(str(command), stdout=subprocess.PIPE, diff --git a/lib/galaxy/tool_util/cwl/parser.py b/lib/galaxy/tool_util/cwl/parser.py index 9339a83a2d7..1d3db7da6a5 100644 --- a/lib/galaxy/tool_util/cwl/parser.py +++ b/lib/galaxy/tool_util/cwl/parser.py @@ -148,7 +148,7 @@ def _to_cwl_tool_object(tool_path=None, tool_object=None, cwl_tool_object=None, path = tool_directory if path is None: path = os.getcwd() - uri = ref_resolver.file_uri(path) + "/" + uri = f"{ref_resolver.file_uri(path)}/" sourceline.add_lc_filename(tool_object, uri) raw_process_reference = schema_loader.raw_process_reference_for_object( tool_object, diff --git a/lib/galaxy/tool_util/cwl/schema.py b/lib/galaxy/tool_util/cwl/schema.py index 2059d016fe7..6de0dc4aac7 100644 --- a/lib/galaxy/tool_util/cwl/schema.py +++ b/lib/galaxy/tool_util/cwl/schema.py @@ -51,7 +51,7 @@ class SchemaLoader: """) processed_path = os.path.join(output_dir, os.path.basename(path)) path = os.path.abspath(path) - uri = "file://" + path + uri = f"file://{path}" loading_context = loading_context or self.loading_context() if REWRITE_EXPRESSIONS: from cwl_utils import cwl_v1_0_expression_refactor diff --git a/lib/galaxy/tool_util/deps/brew_exts.py b/lib/galaxy/tool_util/deps/brew_exts.py index 1f0c68afb6f..82a275c7cdc 100755 --- a/lib/galaxy/tool_util/deps/brew_exts.py +++ b/lib/galaxy/tool_util/deps/brew_exts.py @@ -513,7 +513,7 @@ def __action(sys): def recipe_cellar_path(cellar_path, recipe, version): recipe_base = recipe.split("/")[-1] recipe_base_path = os.path.join(cellar_path, recipe_base, version) - revision_paths = glob.glob(recipe_base_path + "_*") + revision_paths = glob.glob(f"{recipe_base_path}_*") if revision_paths: revisions = map(lambda x: int(x.rsplit("_", 1)[-1]), revision_paths) max_revision = max(revisions) @@ -547,8 +547,8 @@ def ensure_brew_on_path(args): def which(file): # http://stackoverflow.com/questions/5226958/which-equivalent-function-in-python for path in os.environ["PATH"].split(":"): - if os.path.exists(path + "/" + file): - return path + "/" + file + if os.path.exists(f"{path}/{file}"): + return f"{path}/{file}" return None diff --git a/lib/galaxy/tool_util/deps/container_resolvers/mulled.py b/lib/galaxy/tool_util/deps/container_resolvers/mulled.py index a6d698b4702..e2136dfb081 100644 --- a/lib/galaxy/tool_util/deps/container_resolvers/mulled.py +++ b/lib/galaxy/tool_util/deps/container_resolvers/mulled.py @@ -114,7 +114,7 @@ def identifier_to_cached_target(identifier, hash_func, namespace=None): prefix = "" if namespace is not None: prefix = f"quay.io/{namespace}/" - if image_name.startswith(prefix + "mulled-v1-"): + if image_name.startswith(f"{prefix}mulled-v1-"): if hash_func == "v2": return None @@ -123,7 +123,7 @@ def identifier_to_cached_target(identifier, hash_func, namespace=None): if version and version.isdigit(): build = version image = CachedV1MulledImageMultiTarget(hash, build, identifier) - elif image_name.startswith(prefix + "mulled-v2-"): + elif image_name.startswith(f"{prefix}mulled-v2-"): if hash_func == "v1": return None diff --git a/lib/galaxy/tool_util/deps/containers.py b/lib/galaxy/tool_util/deps/containers.py index 7c5d1032177..af49c501556 100644 --- a/lib/galaxy/tool_util/deps/containers.py +++ b/lib/galaxy/tool_util/deps/containers.py @@ -140,13 +140,13 @@ class ContainerFinder: repo_key = f"{container_type}_repo_{mode}" owner_key = f"{container_type}_owner_{mode}" if repo_key in destination_info: - repo = destination_info[repo_key] + "/" + repo = f"{destination_info[repo_key]}/" if owner_key in destination_info: - owner = destination_info[owner_key] + "/" + owner = f"{destination_info[owner_key]}/" cont_id = repo + owner + destination_info[f"{container_type}_image_{mode}"] tag_key = f"{container_type}_tag_{mode}" if tag_key in destination_info: - cont_id += ":" + destination_info[tag_key] + cont_id += f":{destination_info[tag_key]}" return cont_id def __default_container_id(self, container_type, destination_info): diff --git a/lib/galaxy/tool_util/deps/mulled/mulled_build.py b/lib/galaxy/tool_util/deps/mulled/mulled_build.py index 9ebedecb172..5fa69a497e1 100644 --- a/lib/galaxy/tool_util/deps/mulled/mulled_build.py +++ b/lib/galaxy/tool_util/deps/mulled/mulled_build.py @@ -269,7 +269,7 @@ def mull_targets( involucro_args.insert(6, '-set') involucro_args.insert(7, f"TEST_BINDS={','.join(test_bind)}") cmd = involucro_context.build_command(involucro_args) - print('Executing: ' + ' '.join(shlex.quote(_) for _ in cmd)) + print(f"Executing: {' '.join(shlex.quote(_) for _ in cmd)}") if dry_run: return 0 ensure_installed(involucro_context, True) diff --git a/lib/galaxy/tool_util/deps/mulled/mulled_build_files.py b/lib/galaxy/tool_util/deps/mulled/mulled_build_files.py index f21afeea3a9..8f436503f3a 100644 --- a/lib/galaxy/tool_util/deps/mulled/mulled_build_files.py +++ b/lib/galaxy/tool_util/deps/mulled/mulled_build_files.py @@ -57,7 +57,7 @@ def generate_targets(target_source): """Generate all targets from TSV files in specified file or directory.""" target_source = os.path.abspath(target_source) if os.path.isdir(target_source): - target_source_files = glob.glob(target_source + "/*.tsv") + target_source_files = glob.glob(f"{target_source}/*.tsv") else: target_source_files = [target_source] diff --git a/lib/galaxy/tool_util/deps/mulled/mulled_search.py b/lib/galaxy/tool_util/deps/mulled/mulled_search.py index b72d8f11ffe..249d09c9141 100755 --- a/lib/galaxy/tool_util/deps/mulled/mulled_search.py +++ b/lib/galaxy/tool_util/deps/mulled/mulled_search.py @@ -119,7 +119,7 @@ class CondaSearch(): """ if run_command is None: - raise Exception("Invalid search destination. " + deps_error_message("conda")) + raise Exception(f"Invalid search destination. {deps_error_message('conda')}") raw_out, err, exit_code = run_command( 'search', '-c', self.channel, diff --git a/lib/galaxy/tool_util/deps/mulled/mulled_update_singularity_containers.py b/lib/galaxy/tool_util/deps/mulled/mulled_update_singularity_containers.py index cc52d529e27..35ac039a60c 100644 --- a/lib/galaxy/tool_util/deps/mulled/mulled_update_singularity_containers.py +++ b/lib/galaxy/tool_util/deps/mulled/mulled_update_singularity_containers.py @@ -22,7 +22,7 @@ def docker_to_singularity(container, installation, filepath, no_sudo=False): """ Convert docker to singularity container. """ - cmd = [installation, 'build', '/'.join((filepath, container)), 'docker://quay.io/biocontainers/' + container] + cmd = [installation, 'build', '/'.join((filepath, container)), f"docker://quay.io/biocontainers/{container}"] try: if no_sudo: check_output(cmd, stderr=subprocess.STDOUT) @@ -68,7 +68,7 @@ def singularity_container_test(tests, installation, filepath): if test.get('imports', False): for imp in test['imports']: try: - check_output(exec_command.extend([test['import_lang'], 'import ' + imp]), stderr=subprocess.STDOUT) + check_output(exec_command.extend([test['import_lang'], f"import {imp}"]), stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: errors.append({'import': imp, 'output': unicodify(e.output)}) test_passed = False @@ -168,7 +168,7 @@ def container_testing(args=None): f.write(f"\n\t\t{container['container']}") for error in container['errors']: f.write('\n\t\t\tCOMMAND: {}\n\t\t\t\tERROR:{}'.format(error.get( - 'command', 'import' + error.get('import', 'nothing found')), error['output'])) + 'command', f"import{error.get('import', 'nothing found')}"), error['output'])) f.write('\n\tNO TEST AVAILABLE:') for container in test_results['notest']: f.write(f'\n\t\t{container}') diff --git a/lib/galaxy/tool_util/deps/resolvers/unlinked_tool_shed_packages.py b/lib/galaxy/tool_util/deps/resolvers/unlinked_tool_shed_packages.py index eafa3b685ad..9c3ac107003 100644 --- a/lib/galaxy/tool_util/deps/resolvers/unlinked_tool_shed_packages.py +++ b/lib/galaxy/tool_util/deps/resolvers/unlinked_tool_shed_packages.py @@ -37,7 +37,7 @@ from .galaxy_packages import BaseGalaxyPackageDependencyResolver log = logging.getLogger(__name__) MANUAL = "manual" -PREFERRED_OWNERS = MANUAL + ",iuc,devteam" +PREFERRED_OWNERS = f"{MANUAL},iuc,devteam" class UnlinkedToolShedPackageDependencyResolver(BaseGalaxyPackageDependencyResolver): @@ -84,7 +84,7 @@ class UnlinkedToolShedPackageDependencyResolver(BaseGalaxyPackageDependencyResol for owner in listdir(path): owner_path = join(path, owner) for package_name in listdir(owner_path): - if package_name.lower().startswith("package_" + name.lower()): + if package_name.lower().startswith(f"package_{name.lower()}"): package_path = join(owner_path, package_name) for revision in listdir(package_path): revision_path = join(package_path, revision) diff --git a/lib/galaxy/tool_util/loader_directory.py b/lib/galaxy/tool_util/loader_directory.py index 056ec577447..93cca0916a6 100644 --- a/lib/galaxy/tool_util/loader_directory.py +++ b/lib/galaxy/tool_util/loader_directory.py @@ -258,12 +258,12 @@ def _find_tool_files(path_or_uri_like, recursive, enable_beta_formats): else: if enable_beta_formats: if not recursive: - files = glob.glob(path + "/*") + files = glob.glob(f"{path}/*") else: files = _find_files(path, "*") else: if not recursive: - files = glob.glob(path + "/*.xml") + files = glob.glob(f"{path}/*.xml") else: files = _find_files(path, "*.xml") return [os.path.abspath(_) for _ in files] diff --git a/lib/galaxy/tool_util/locations/dockstore.py b/lib/galaxy/tool_util/locations/dockstore.py index 4076a71aab6..00a6aed23d2 100644 --- a/lib/galaxy/tool_util/locations/dockstore.py +++ b/lib/galaxy/tool_util/locations/dockstore.py @@ -19,7 +19,7 @@ class DockStoreResolver(ToolLocationResolver): tool_id, version = tool_id.split(":", 1) else: tool_id, version = tool_id, "latest" - tmp_path = self._temp_path(uri_like + ".cwl") + tmp_path = self._temp_path(f"{uri_like}.cwl") cwl_str = _Ga4ghToolClient().get_tool_cwl(tool_id, version=version, as_string=True) with open(tmp_path, "wb") as f: f.write(cwl_str) diff --git a/lib/galaxy/tool_util/output_checker.py b/lib/galaxy/tool_util/output_checker.py index 697c075f1a2..89e1b0bef29 100644 --- a/lib/galaxy/tool_util/output_checker.py +++ b/lib/galaxy/tool_util/output_checker.py @@ -162,11 +162,11 @@ def __regex_err_msg(match, stream, regex): that will contain the string matched on. """ # Get the description for the error level: - desc = StdioErrorLevel.desc(regex.error_level) + ": " + desc = f"{StdioErrorLevel.desc(regex.error_level)}: " mstart = match.start() mend = match.end() if mend - mstart > 256: - match_str = match.string[mstart:mstart + 256] + "..." + match_str = f"{match.string[mstart:mstart + 256]}..." else: match_str = match.string[mstart:mend] diff --git a/lib/galaxy/tool_util/verify/asserts/__init__.py b/lib/galaxy/tool_util/verify/asserts/__init__.py index 2dd433e324b..5eaff1f7d00 100644 --- a/lib/galaxy/tool_util/verify/asserts/__init__.py +++ b/lib/galaxy/tool_util/verify/asserts/__init__.py @@ -14,7 +14,7 @@ assertion_module_names = ['text', 'tabular', 'xml', 'hdf5', 'archive', 'size'] # to the list of assertion module names defined above. assertion_modules = [] for assertion_module_name in assertion_module_names: - full_assertion_module_name = 'galaxy.tool_util.verify.asserts.' + assertion_module_name + full_assertion_module_name = f"galaxy.tool_util.verify.asserts.{assertion_module_name}" try: # Dynamically import module __import__(full_assertion_module_name) @@ -33,7 +33,7 @@ def verify_assertions(data, assertion_description_list): def verify_assertion(data, assertion_description): tag = assertion_description["tag"] - assert_function_name = "assert_" + tag + assert_function_name = f"assert_{tag}" assert_function = None for assertion_module in assertion_modules: if hasattr(assertion_module, assert_function_name): diff --git a/lib/galaxy/tool_util/verify/interactor.py b/lib/galaxy/tool_util/verify/interactor.py index e4965b0bc67..f3c4f727834 100644 --- a/lib/galaxy/tool_util/verify/interactor.py +++ b/lib/galaxy/tool_util/verify/interactor.py @@ -369,7 +369,7 @@ class GalaxyInteractorApi: if force_path_paste: file_path = self.test_data_path(tool_id, file_name) tool_input.update({ - "files_%d|url_paste" % i: "file://" + file_path + "files_%d|url_paste" % i: f"file://{file_path}" }) else: file_content = self.test_data_download(tool_id, file_name, is_output=False) @@ -388,7 +388,7 @@ class GalaxyInteractorApi: if force_path_paste: file_name = self.test_data_path(tool_id, fname) tool_input.update({ - "files_0|url_paste": "file://" + file_name + "files_0|url_paste": f"file://{file_name}" }) else: file_content = self.test_data_download(tool_id, fname, is_output=False) @@ -1175,11 +1175,11 @@ def _verify_outputs(testdef, history, jobs, tool_id, data_list, data_collection_ for job_message in job_messages: message_type = job_message.get("type") if message_type == "regex" and job_message.get("stream") == "stderr": - stderr_prefix += (job_message.get("desc") or '') + "\n" + stderr_prefix += f"{job_message.get('desc') or ''}\n" elif message_type == "regex" and job_message.get("stream") == "stdout": - stdout_prefix += (job_message.get("desc") or '') + "\n" + stdout_prefix += f"{job_message.get('desc') or ''}\n" elif message_type == "exit_code": - stderr_prefix += (job_message.get("desc") or '') + "\n" + stderr_prefix += f"{job_message.get('desc') or ''}\n" else: raise Exception(f"Unknown job message type [{message_type}] in [{job_message}]") @@ -1226,7 +1226,7 @@ def _format_stream(output, stream, format): output = output or '' if format: msg = f"---------------------- >> begin tool {stream} << -----------------------\n" - msg += output + "\n" + msg += f"{output}\n" msg += f"----------------------- >> end tool {stream} << ------------------------\n" else: msg = output diff --git a/lib/galaxy/tool_util/verify/script.py b/lib/galaxy/tool_util/verify/script.py index 6d4102768f2..49551db2864 100644 --- a/lib/galaxy/tool_util/verify/script.py +++ b/lib/galaxy/tool_util/verify/script.py @@ -232,14 +232,14 @@ def _test_id_for_reference(test_reference): tool_version = test_reference.tool_version test_index = test_reference.test_index - if tool_version and tool_id.endswith("/" + tool_version): - tool_id = tool_id[:-len("/" + tool_version)] + if tool_version and tool_id.endswith(f"/{tool_version}"): + tool_id = tool_id[:-len(f"/{tool_version}")] label_base = tool_id if tool_version: - label_base += "/" + str(tool_version) + label_base += f"/{str(tool_version)}" - test_id = label_base + "-" + str(test_index) + test_id = f"{label_base}-{str(test_index)}" return test_id @@ -258,8 +258,8 @@ def _test_tool( test_index = test_reference.test_index # If given a tool_id with a version suffix, strip it off so we can treat tool_version # correctly at least in client_test_config. - if tool_version and tool_id.endswith("/" + tool_version): - tool_id = tool_id[:-len("/" + tool_version)] + if tool_version and tool_id.endswith(f"/{tool_version}"): + tool_id = tool_id[:-len(f"/{tool_version}")] test_id = _test_id_for_reference(test_reference) diff --git a/lib/galaxy/tools/__init__.py b/lib/galaxy/tools/__init__.py index 6d753030472..782084339a5 100644 --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -876,7 +876,7 @@ class Tool(Dictifiable): executable = self.version_string_cmd.split()[0] abs_executable = os.path.abspath(os.path.join(self.tool_dir, executable)) command_line = self.version_string_cmd.replace(executable, abs_executable, 1) - self.version_string_cmd = version_cmd_interpreter + " " + command_line + self.version_string_cmd = f"{version_cmd_interpreter} {command_line}" # Parallelism for tasks, read from tool config. self.parallelism = tool_source.parse_parallelism() @@ -1149,7 +1149,7 @@ class Tool(Dictifiable): raise Exception('URL parameters in a non-default tool action can not be used ' 'in conjunction with nginx upload. Please convert them to ' 'hidden POST parameters') - self.action = (self.app.config.nginx_upload_path + '?nginx_redir=', + self.action = (f"{self.app.config.nginx_upload_path}?nginx_redir=", unquote_plus(self.action)) self.target = input_elem.get("target", self.target) self.method = input_elem.get("method", self.method) @@ -2032,7 +2032,7 @@ class Tool(Dictifiable): for data_table_filename in data_table.filenames: # FIXME: from_shed_config seems to always be False. if not data_table.filenames[data_table_filename]['from_shed_config']: - tar_file = data_table.filenames[data_table_filename]['filename'] + '.sample' + tar_file = f"{data_table.filenames[data_table_filename]['filename']}.sample" sample_file = os.path.join(data_table.filenames[data_table_filename]['tool_data_path'], tar_file) # Use the .sample file, if one exists. If not, skip this data table. @@ -2550,10 +2550,10 @@ class DataSourceTool(OutputParameterJSONTool): wrapped_data = param_dict.get(out_name) # allow multiple files to be created cur_base_param_name = f'GALAXY|{out_name}|' - cur_name = param_dict.get(cur_base_param_name + 'name', name) - cur_dbkey = param_dict.get(cur_base_param_name + 'dkey', dbkey) - cur_info = param_dict.get(cur_base_param_name + 'info', info) - cur_data_type = param_dict.get(cur_base_param_name + 'data_type', data_type) + cur_name = param_dict.get(f"{cur_base_param_name}name", name) + cur_dbkey = param_dict.get(f"{cur_base_param_name}dkey", dbkey) + cur_info = param_dict.get(f"{cur_base_param_name}info", info) + cur_data_type = param_dict.get(f"{cur_base_param_name}data_type", data_type) if cur_name: data.name = cur_name if not data.info and cur_info: diff --git a/lib/galaxy/tools/actions/__init__.py b/lib/galaxy/tools/actions/__init__.py index 018565e36aa..1ce4dcafe56 100644 --- a/lib/galaxy/tools/actions/__init__.py +++ b/lib/galaxy/tools/actions/__init__.py @@ -801,7 +801,7 @@ class DefaultToolAction: def _get_default_data_name(self, dataset, tool, on_text=None, trans=None, incoming=None, history=None, params=None, job_params=None, **kwd): name = tool.name if on_text: - name += (" on " + on_text) + name += f" on {on_text}" return name diff --git a/lib/galaxy/tools/data/__init__.py b/lib/galaxy/tools/data/__init__.py index 612df1bd591..f5e42b70001 100644 --- a/lib/galaxy/tools/data/__init__.py +++ b/lib/galaxy/tools/data/__init__.py @@ -764,10 +764,10 @@ class TabularToolDataField(Dictifiable): return path def clean_base_dir(self, path): - return re.sub("^" + self.get_base_dir() + r"/*", "", path) + return re.sub(f"^{self.get_base_dir()}/*", "", path) def get_files(self): - return glob(self.get_base_path() + "*") + return glob(f"{self.get_base_path()}*") def get_filesize_map(self, rm_base_dir=False): out = {} diff --git a/lib/galaxy/tools/data_fetch.py b/lib/galaxy/tools/data_fetch.py index 9c800d4aa6e..c0fa8227fe9 100644 --- a/lib/galaxy/tools/data_fetch.py +++ b/lib/galaxy/tools/data_fetch.py @@ -142,7 +142,7 @@ def _fetch_target(upload_config, target): name = item.get("name") or 'Composite Dataset' dataset_bunch.name = name primary_file = sniff.stream_to_file(StringIO(datatype.generate_primary_file(dataset_bunch)), prefix='upload_auto_primary_file', dir=".") - extra_files_path = primary_file + "_extra" + extra_files_path = f"{primary_file}_extra" os.mkdir(extra_files_path) rval = { "name": name, @@ -172,7 +172,7 @@ def _fetch_target(upload_config, target): key, writable_file.is_binary, ".", - os.path.basename(extra_files_path) + "_", + f"{os.path.basename(extra_files_path)}_", composite_item, ) composite_item_idx += 1 @@ -262,7 +262,7 @@ def _fetch_target(upload_config, target): if extra_files: # TODO: optimize to just copy the whole directory to extra files instead. assert not upload_config.link_data_only, "linking composite dataset files not yet implemented" - extra_files_path = path + "_extra" + extra_files_path = f"{path}_extra" staged_extra_files = extra_files_path os.mkdir(extra_files_path) diff --git a/lib/galaxy/tools/error_reports/plugins/base_git.py b/lib/galaxy/tools/error_reports/plugins/base_git.py index 0a9b63994fb..361398f6ea4 100644 --- a/lib/galaxy/tools/error_reports/plugins/base_git.py +++ b/lib/galaxy/tools/error_reports/plugins/base_git.py @@ -56,7 +56,7 @@ class BaseGitPlugin(ErrorPlugin, metaclass=ABCMeta): return None try: if job.tool_id not in self.ts_repo_cache: - ts_repo_request_data = requests.get(ts_url + "/api/repositories?tool_ids=" + str(job.tool_id)).json() + ts_repo_request_data = requests.get(f"{ts_url}/api/repositories?tool_ids={str(job.tool_id)}").json() for repoinfo in ts_repo_request_data.values(): if isinstance(repoinfo, dict): diff --git a/lib/galaxy/tools/errors.py b/lib/galaxy/tools/errors.py index fadb9a9bebe..2c2d4c11269 100644 --- a/lib/galaxy/tools/errors.py +++ b/lib/galaxy/tools/errors.py @@ -244,7 +244,7 @@ class EmailErrorReporter(ErrorReporter): frm = self.app.config.email_from error_msg = validate_email_str(email) if not error_msg and self._can_access_dataset(user): - to += ', ' + email.strip() + to += f", {email.strip()}" subject = f"Galaxy tool error report from {email}" try: subject = "{} ({})".format( diff --git a/lib/galaxy/tools/expressions/evaluation.py b/lib/galaxy/tools/expressions/evaluation.py index c14332d9d3c..204e771ca60 100644 --- a/lib/galaxy/tools/expressions/evaluation.py +++ b/lib/galaxy/tools/expressions/evaluation.py @@ -27,7 +27,7 @@ def evaluate(config, input): close_fds=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - input_str = json.dumps(new_input) + "\n\n" + input_str = f"{json.dumps(new_input)}\n\n" input_bytes = input_str.encode("utf-8") (stdoutdata, stderrdata) = sp.communicate(input_bytes) if sp.returncode != 0: diff --git a/lib/galaxy/tools/parameters/__init__.py b/lib/galaxy/tools/parameters/__init__.py index f18c554d4a6..03fd992ad40 100644 --- a/lib/galaxy/tools/parameters/__init__.py +++ b/lib/galaxy/tools/parameters/__init__.py @@ -162,7 +162,7 @@ def visit_input_values(inputs, input_values, callback, name_prefix='', label_pre visit_input_values(input.inputs, d, callback, new_name_prefix, new_label_prefix, parent_prefix=new_name_prefix, **payload) elif isinstance(input, Conditional): values = input_values[input.name] = input_values.get(input.name, {}) - new_name_prefix = name_prefix + input.name + '|' + new_name_prefix = f"{name_prefix + input.name}|" case_error = None if get_current_case(input, values) >= 0 else 'The selected case is unavailable/invalid.' callback_helper(input.test_param, values, new_name_prefix, label_prefix, parent_prefix=name_prefix, context=context, error=case_error) values['__current_case__'] = get_current_case(input, values) @@ -170,7 +170,7 @@ def visit_input_values(inputs, input_values, callback, name_prefix='', label_pre visit_input_values(input.cases[values['__current_case__']].inputs, values, callback, new_name_prefix, label_prefix, parent_prefix=name_prefix, **payload) elif isinstance(input, Section): values = input_values[input.name] = input_values.get(input.name, {}) - new_name_prefix = name_prefix + input.name + '|' + new_name_prefix = f"{name_prefix + input.name}|" visit_input_values(input.inputs, values, callback, new_name_prefix, label_prefix, parent_prefix=name_prefix, **payload) else: callback_helper(input, input_values, name_prefix, label_prefix, parent_prefix=parent_prefix, context=context) @@ -260,12 +260,12 @@ def params_to_incoming(incoming, inputs, input_values, app, name_prefix=""): elif isinstance(input, Conditional): values = input_values[input.name] current = values['__current_case__'] - new_name_prefix = name_prefix + input.name + '|' + new_name_prefix = f"{name_prefix + input.name}|" incoming[new_name_prefix + input.test_param.name] = values[input.test_param.name] params_to_incoming(incoming, input.cases[current].inputs, values, app, new_name_prefix) elif isinstance(input, Section): values = input_values[input.name] - new_name_prefix = name_prefix + input.name + '|' + new_name_prefix = f"{name_prefix + input.name}|" params_to_incoming(incoming, input.inputs, values, app, new_name_prefix) else: value = input_values.get(input.name) @@ -419,7 +419,7 @@ def _populate_state_legacy(request_context, inputs, incoming, state, errors, pre if rep_index < input.max: new_state = {'__index__': rep_index} group_state.append(new_state) - _populate_state_legacy(request_context, input.inputs, incoming, new_state, errors, prefix=rep_prefix + '|', context=context, check=check, simple_errors=simple_errors) + _populate_state_legacy(request_context, input.inputs, incoming, new_state, errors, prefix=f"{rep_prefix}|", context=context, check=check, simple_errors=simple_errors) rep_index += 1 elif input.type == 'conditional': if input.value_ref and not input.value_ref_in_group: @@ -467,11 +467,11 @@ def _get_incoming_value(incoming, key, default): Fetch value from incoming dict directly or check special nginx upload created variants of this key. """ - if '__' + key + '__is_composite' in incoming: - composite_keys = incoming['__' + key + '__keys'].split() + if f"__{key}__is_composite" in incoming: + composite_keys = incoming[f"__{key}__keys"].split() value = dict() for composite_key in composite_keys: - value[composite_key] = incoming[key + '_' + composite_key] + value[composite_key] = incoming[f"{key}_{composite_key}"] return value else: return incoming.get(key, default) diff --git a/lib/galaxy/tools/parameters/basic.py b/lib/galaxy/tools/parameters/basic.py index 14c2994ae7a..ffe7b593a35 100644 --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -1177,7 +1177,7 @@ class SelectTagParameter(SelectToolParameter): """ options = [] for tag in self.get_tag_list(other_values): - options.append(('Tags: ' + tag, tag, False)) + options.append((f"Tags: {tag}", tag, False)) return options def get_initial_value(self, trans, other_values): @@ -1350,7 +1350,7 @@ class ColumnListParameter(SelectToolParameter): if isinstance(col, tuple) and len(col) == 2: options.append((col[1], col[0], False)) else: - options.append(('Column: ' + col, col, False)) + options.append((f"Column: {col}", col, False)) return options def get_initial_value(self, trans, other_values): diff --git a/lib/galaxy/tools/parameters/sanitize.py b/lib/galaxy/tools/parameters/sanitize.py index 080837155ba..79c498db340 100644 --- a/lib/galaxy/tools/parameters/sanitize.py +++ b/lib/galaxy/tools/parameters/sanitize.py @@ -43,7 +43,7 @@ class ToolParameterSanitizer: True """ - VALID_PRESET = {'default': (string.ascii_letters + string.digits + " -=_.()/+*^,:?!"), 'none': ''} + VALID_PRESET = {'default': (f"{string.ascii_letters + string.digits} -=_.()/+*^,:?!"), 'none': ''} MAPPING_PRESET = {'default': galaxy.util.mapped_chars, 'none': {}} DEFAULT_INVALID_CHAR = 'X' @@ -101,7 +101,7 @@ class ToolParameterSanitizer: if split_name.startswith('string.'): string_constant = split_name[7:] if string_constant in ('letters', 'lowercase', 'uppercase'): - split_name = 'string.ascii_' + string_constant + split_name = f"string.ascii_{string_constant}" try: value = eval(split_name) except NameError as e: diff --git a/lib/galaxy/tools/recommendations.py b/lib/galaxy/tools/recommendations.py index 5986f2ed69a..26ee9151f9a 100644 --- a/lib/galaxy/tools/recommendations.py +++ b/lib/galaxy/tools/recommendations.py @@ -79,7 +79,7 @@ class ToolRecommendations(): # iterate through all the attributes of the model to find weights of neural network layers for item in trained_model.keys(): if "weight_" in item: - weight = trained_model["weight_" + str(counter_layer_weights)][()] + weight = trained_model[f"weight_{str(counter_layer_weights)}"][()] model_weights.append(weight) counter_layer_weights += 1 self.loaded_model = tf.keras.models.model_from_json(model_config) diff --git a/lib/galaxy/tools/search/__init__.py b/lib/galaxy/tools/search/__init__.py index ac695b5d114..e5b8d28594d 100644 --- a/lib/galaxy/tools/search/__init__.py +++ b/lib/galaxy/tools/search/__init__.py @@ -190,7 +190,7 @@ class ToolBoxSearch: else: cleaned_query = ' '.join(token.text for token in self.rex(cleaned_query)) # Use asterisk Whoosh wildcard so e.g. 'bow' easily matches 'bowtie' - parsed_query = self.parser.parse('*' + cleaned_query + '*') + parsed_query = self.parser.parse(f"*{cleaned_query}*") hits = self.searcher.search(parsed_query, limit=float(tool_search_limit), sortedby='') return [hit['id'] for hit in hits] @@ -205,7 +205,7 @@ class ToolBoxSearch: ngrams = [token.text for token in token_analyzer(cleaned_query)] for query in ngrams: # Get the tool list with respective scores for each qgram - curr_hits = self.searcher.search(self.parser.parse('*' + query + '*'), limit=float(tool_search_limit)) + curr_hits = self.searcher.search(self.parser.parse(f"*{query}*"), limit=float(tool_search_limit)) for i, curr_hit in enumerate(curr_hits): is_present = False for prev_hit in hits_with_score: diff --git a/lib/galaxy/tools/toolbox/base.py b/lib/galaxy/tools/toolbox/base.py index a82222d6230..6634b83c5e9 100644 --- a/lib/galaxy/tools/toolbox/base.py +++ b/lib/galaxy/tools/toolbox/base.py @@ -558,7 +558,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): elem = etree.Element('label') elem.attrib['text'] = self.edam[term]['label'] elem.attrib['id'] = term - self._tool_panel['label_' + term] = ToolSectionLabel(elem) + self._tool_panel[f"label_{term}"] = ToolSectionLabel(elem) for (term, tool_id, key, val, val_name) in operations[term].values(): section = self._get_section(term, self.edam[term]['label']) @@ -572,7 +572,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): elem = etree.Element('label') elem.attrib['text'] = self.edam[term]['label'] elem.attrib['id'] = term - self._tool_panel['label_' + term] = ToolSectionLabel(elem) + self._tool_panel[f"label_{term}"] = ToolSectionLabel(elem) for (term, tool_id, key, val, val_name) in topics[term].values(): section = self._get_section(term, self.edam[term]['label']) @@ -587,7 +587,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): def _sort_edam_key(self, x): if x in ('operation_0004', 'topic_0003'): - return '!' + x + return f"!{x}" else: return self.edam[x]['label'] @@ -683,8 +683,8 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): if "/repos/" in tool_id: # test if tool came from a toolshed tool_id_without_tool_shed = tool_id.split("/repos/")[1] available_tool_sheds = [urlparse(_) for _ in self.app.tool_shed_registry.tool_sheds.values()] - available_tool_sheds = [url.geturl().replace(url.scheme + "://", '', 1) for url in available_tool_sheds] - tool_ids = [tool_shed + "repos/" + tool_id_without_tool_shed for tool_shed in available_tool_sheds] + available_tool_sheds = [url.geturl().replace(f"{url.scheme}://", '', 1) for url in available_tool_sheds] + tool_ids = [f"{tool_shed}repos/{tool_id_without_tool_shed}" for tool_shed in available_tool_sheds] if tool_id in tool_ids: # move original tool_id to the top of tool_ids tool_ids.remove(tool_id) tool_ids.insert(0, tool_id) @@ -953,7 +953,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): workflow_id = item.get('id') workflow = self._load_workflow(workflow_id) self._workflows_by_id[workflow_id] = workflow - key = 'workflow_' + workflow_id + key = f"workflow_{workflow_id}" if load_panel_dict: panel_dict[key] = workflow # Always load workflows into the integrated_panel_dict. @@ -963,7 +963,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): def _load_label_tag_set(self, item, panel_dict, integrated_panel_dict, load_panel_dict, index=None): label = ToolSectionLabel(item) - key = 'label_' + label.id + key = f"label_{label.id}" if load_panel_dict: panel_dict[key] = label integrated_panel_dict.update_or_append(index, key, label) @@ -1156,7 +1156,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): new_tool.installed_changeset_revision = old_tool.installed_changeset_revision new_tool.old_id = old_tool.old_id # Replace old_tool with new_tool in self._tool_panel - tool_key = 'tool_' + tool_id + tool_key = f"tool_{tool_id}" for key, val in self._tool_panel.items(): if key == tool_key: self._tool_panel[key] = new_tool @@ -1190,7 +1190,7 @@ class AbstractToolBox(Dictifiable, ManagesIntegratedToolPanelMixin): if tool_cache: tool_cache.expire_tool(tool_id) if remove_from_panel: - tool_key = 'tool_' + tool_id + tool_key = f"tool_{tool_id}" for key, val in self._tool_panel.items(): if key == tool_key: del self._tool_panel[key] diff --git a/lib/galaxy/tools/toolbox/integrated_panel.py b/lib/galaxy/tools/toolbox/integrated_panel.py index e3bcd078cac..4646896cbb8 100644 --- a/lib/galaxy/tools/toolbox/integrated_panel.py +++ b/lib/galaxy/tools/toolbox/integrated_panel.py @@ -110,10 +110,10 @@ $INTEGRATED_TOOL_PANEL with RenamedTemporaryFile(filename, mode='w') as f: f.write(tp_string) if tracking_directory: - with open(filename + ".stack", "w") as f: + with open(f"{filename}.stack", "w") as f: f.write(''.join(traceback.format_stack())) - shutil.copy(filename, filename + ".copy") - shutil.move(filename + ".copy", destination) + shutil.copy(filename, f"{filename}.copy") + shutil.move(f"{filename}.copy", destination) try: os.chmod(destination, RW_R__R__) except OSError: diff --git a/lib/galaxy/tools/toolbox/tags.py b/lib/galaxy/tools/toolbox/tags.py index ba0033a9454..88f25557543 100644 --- a/lib/galaxy/tools/toolbox/tags.py +++ b/lib/galaxy/tools/toolbox/tags.py @@ -49,7 +49,7 @@ class PersistentToolTagManager(AbstractToolTagManager): self.sa_session = app.model.context def reset_tags(self): - log.info("removing all tool tag associations (" + str(self.sa_session.query(self.app.model.ToolTagAssociation).count()) + ")") + log.info(f"removing all tool tag associations ({str(self.sa_session.query(self.app.model.ToolTagAssociation).count())})") self.sa_session.query(self.app.model.ToolTagAssociation).delete() self.sa_session.flush() diff --git a/lib/galaxy/util/compression_utils.py b/lib/galaxy/util/compression_utils.py index fefd5692a97..4a22807dd6a 100644 --- a/lib/galaxy/util/compression_utils.py +++ b/lib/galaxy/util/compression_utils.py @@ -170,7 +170,7 @@ class CompressedFile: elif self.file_type == "zip": for name in members.namelist(): if not safe_relpath(name): - raise Exception(name + " is blocked (illegal path).") + raise Exception(f"{name} is blocked (illegal path).") yield name def getmembers_tar(self): diff --git a/lib/galaxy/util/dictifiable.py b/lib/galaxy/util/dictifiable.py index 162d0bf3acd..acd6a5eaefb 100644 --- a/lib/galaxy/util/dictifiable.py +++ b/lib/galaxy/util/dictifiable.py @@ -50,7 +50,7 @@ class Dictifiable: # Fill item dict with visible keys. try: - visible_keys = self.__getattribute__('dict_' + view + '_visible_keys') + visible_keys = self.__getattribute__(f"dict_{view}_visible_keys") except AttributeError: raise Exception(f'Unknown Dictifiable view: {view}') for key in visible_keys: diff --git a/lib/galaxy/util/facts.py b/lib/galaxy/util/facts.py index 519b6936d4a..a00f597c11f 100644 --- a/lib/galaxy/util/facts.py +++ b/lib/galaxy/util/facts.py @@ -30,7 +30,7 @@ class Facts(MutableMapping): if config is not None: for name in dir(config): if not name.startswith('_') and isinstance(getattr(config, name), str): - self.__dict__['config_' + name] = lambda name=name: getattr(config, name) + self.__dict__[f"config_{name}"] = lambda name=name: getattr(config, name) def __getitem__(self, key): item = self.__dict__.__getitem__(key) diff --git a/lib/galaxy/util/heartbeat.py b/lib/galaxy/util/heartbeat.py index 7da6de5282d..baf8623486c 100644 --- a/lib/galaxy/util/heartbeat.py +++ b/lib/galaxy/util/heartbeat.py @@ -53,7 +53,7 @@ class Heartbeat(threading.Thread): pid=self.pid ) fname, ext = os.path.splitext(self.fname) - self.fname_nonsleeping = fname + '.nonsleeping' + ext + self.fname_nonsleeping = f"{fname}.nonsleeping{ext}" wait = self.period if self.period <= 0: wait = 60 diff --git a/lib/galaxy/util/inflection.py b/lib/galaxy/util/inflection.py index 84840aad6c0..3f5a5ca7b01 100644 --- a/lib/galaxy/util/inflection.py +++ b/lib/galaxy/util/inflection.py @@ -109,9 +109,9 @@ class Inflector: for form_a, form_b in self.IRREGULAR_WORDS.items(): if not pluralize: form_a, form_b = form_b, form_a - match = re.search('(' + form_a + ')$', word, re.IGNORECASE) + match = re.search(f"({form_a})$", word, re.IGNORECASE) if match: - return re.sub('(?i)' + form_a + '$', match.expand('\\1')[0] + form_b[1:], word) + return re.sub(f"(?i){form_a}$", match.expand('\\1')[0] + form_b[1:], word) def _apply_rules(self, rules, word): for pattern, replacement in rules: diff --git a/lib/galaxy/util/object_wrapper.py b/lib/galaxy/util/object_wrapper.py index 101a202fd36..16b71f599f3 100644 --- a/lib/galaxy/util/object_wrapper.py +++ b/lib/galaxy/util/object_wrapper.py @@ -60,7 +60,7 @@ __WRAP_MAPPINGS__ = (dict, UserDict, ) # Define the set of characters that are not sanitized, and define a set of mappings for those that are. # characters that are valid -VALID_CHARACTERS = set(string.ascii_letters + string.digits + " -=_.()/+*^,:?!@") +VALID_CHARACTERS = set(f"{string.ascii_letters + string.digits} -=_.()/+*^,:?!@") # characters that are allowed but need to be escaped CHARACTER_MAP = {'>': '__gt__', diff --git a/lib/galaxy/util/pastescript/loadwsgi.py b/lib/galaxy/util/pastescript/loadwsgi.py index 323fe2d2788..6e84867de35 100644 --- a/lib/galaxy/util/pastescript/loadwsgi.py +++ b/lib/galaxy/util/pastescript/loadwsgi.py @@ -75,7 +75,7 @@ def fix_type_error(exc_info, callable, varargs, kwargs): def _short_repr(v): v = repr(v) if len(v) > 12: - v = v[:8] + '...' + v[-4:] + v = f"{v[:8]}...{v[-4:]}" return v @@ -112,7 +112,7 @@ def lookup_object(spec): def import_string(s): - return pkg_resources.EntryPoint.parse("x=" + s).load(False) + return pkg_resources.EntryPoint.parse(f"x={s}").load(False) def _aslist(obj): @@ -353,7 +353,7 @@ def _loadconfig(object_type, uri, path, name, relative_to, if relative_to.endswith('/'): path = relative_to + path else: - path = relative_to + '/' + path + path = f"{relative_to}/{path}" if path.startswith('///'): path = path[2:] path = unquote(path) @@ -646,7 +646,7 @@ class ConfigLoader(_Loader): found.append(name_prefix) name = 'main' for section in sections: - if section.startswith(name_prefix + ':'): + if section.startswith(f"{name_prefix}:"): if section[len(name_prefix) + 1:].strip() == name: found.append(section) return found diff --git a/lib/galaxy/util/pastescript/serve.py b/lib/galaxy/util/pastescript/serve.py index 73c96963754..49b0ad8182e 100644 --- a/lib/galaxy/util/pastescript/serve.py +++ b/lib/galaxy/util/pastescript/serve.py @@ -228,7 +228,7 @@ class Command: def parse_args(self, args): if self.usage: - usage = ' ' + self.usage + usage = f" {self.usage}" else: usage = '' self.parser.usage = f"%prog [options]{usage}\n{self.summary}" @@ -567,7 +567,7 @@ class ServeCommand(Command): app_name = self.options.app_name vars = self.parse_vars(restvars) if not self._scheme_re.search(app_spec): - app_spec = 'config:' + app_spec + app_spec = f"config:{app_spec}" server_name = self.options.server_name if self.options.server: server_spec = 'egg:PasteScript' @@ -649,7 +649,7 @@ class ServeCommand(Command): if self.verbose > 1: raise if str(e): - msg = ' ' + str(e) + msg = f" {str(e)}" else: msg = '' print(f'Exiting{msg} (-v to see traceback)') diff --git a/lib/galaxy/util/submodules.py b/lib/galaxy/util/submodules.py index 068050a23d3..d0544e7489a 100644 --- a/lib/galaxy/util/submodules.py +++ b/lib/galaxy/util/submodules.py @@ -39,7 +39,7 @@ def __import_submodules_impl(module, recursive=False): module = importlib.import_module(module) submodules = [] for _, name, is_pkg in pkgutil.walk_packages(module.__path__): - full_name = module.__name__ + '.' + name + full_name = f"{module.__name__}.{name}" try: submodule = importlib.import_module(full_name) submodules.append(submodule) diff --git a/lib/galaxy/visualization/data_providers/phyloviz/baseparser.py b/lib/galaxy/visualization/data_providers/phyloviz/baseparser.py index a7c499bc231..45d9e1f6ae6 100644 --- a/lib/galaxy/visualization/data_providers/phyloviz/baseparser.py +++ b/lib/galaxy/visualization/data_providers/phyloviz/baseparser.py @@ -26,7 +26,7 @@ class Node: self.children += child def __str__(self): - return self.name + " id:" + str(self.id) + ", depth: " + str(self.depth) + return f"{self.name} id:{str(self.id)}, depth: {str(self.depth)}" def toJson(self): """Converts the data in the node to a dict representation of json""" diff --git a/lib/galaxy/visualization/data_providers/phyloviz/newickparser.py b/lib/galaxy/visualization/data_providers/phyloviz/newickparser.py index 4144b612344..e329d7cb8ec 100644 --- a/lib/galaxy/visualization/data_providers/phyloviz/newickparser.py +++ b/lib/galaxy/visualization/data_providers/phyloviz/newickparser.py @@ -43,7 +43,7 @@ class Newick_Parser(Base_Parser): """elements separated by comma could be empty""" if string.find("(") != -1: - raise Exception("Tree is not well form, location: " + string) + raise Exception(f"Tree is not well form, location: {string}") childrenString = string.split(",") childrenNodes = [] diff --git a/lib/galaxy/visualization/genomes.py b/lib/galaxy/visualization/genomes.py index 3869a5178ec..f9c3f62efac 100644 --- a/lib/galaxy/visualization/genomes.py +++ b/lib/galaxy/visualization/genomes.py @@ -50,7 +50,7 @@ class GenomeRegion: self.sequence = sequence def __str__(self): - return self.chrom + ":" + str(self.start) + "-" + str(self.end) + return f"{self.chrom}:{str(self.start)}-{str(self.end)}" @staticmethod def from_dict(obj_dict): diff --git a/lib/galaxy/visualization/plugins/config_parser.py b/lib/galaxy/visualization/plugins/config_parser.py index 1e62b9767fb..ca2c2f7972f 100644 --- a/lib/galaxy/visualization/plugins/config_parser.py +++ b/lib/galaxy/visualization/plugins/config_parser.py @@ -186,7 +186,7 @@ class VisualizationsConfigParser: entry_point_attrib = dict(entry_point.attrib) entry_point_type = entry_point_attrib.pop('entry_point_type', 'mako') if entry_point_type not in self.ALLOWED_ENTRY_POINT_TYPES: - raise ParsingException('Unknown entry_point type: ' + entry_point_type) + raise ParsingException(f"Unknown entry_point type: {entry_point_type}") return { 'type': entry_point_type, 'file': entry_point.text, diff --git a/lib/galaxy/visualization/plugins/interactive_environments.py b/lib/galaxy/visualization/plugins/interactive_environments.py index 37bf2d54d2e..713d679ac2f 100644 --- a/lib/galaxy/visualization/plugins/interactive_environments.py +++ b/lib/galaxy/visualization/plugins/interactive_environments.py @@ -51,7 +51,7 @@ class InteractiveEnvironmentRequest: self.attr.redact_username_in_logs = trans.app.config.redact_username_in_logs self.attr.galaxy_root_dir = os.path.abspath(self.attr.galaxy_config.root) self.attr.root = web.url_for("/") - self.attr.app_root = self.attr.root + "static/plugins/interactive_environments/" + self.attr.viz_id + "/static/" + self.attr.app_root = f"{self.attr.root}static/plugins/interactive_environments/{self.attr.viz_id}/static/" self.attr.import_volume = True plugin_path = os.path.abspath(plugin.path) @@ -101,7 +101,7 @@ class InteractiveEnvironmentRequest: # multiple leading '/' characters, which will cause the client to # request resources from http://dynamic_proxy_prefix if self.attr.proxy_prefix.startswith('/'): - self.attr.proxy_prefix = '/' + self.attr.proxy_prefix.lstrip('/') + self.attr.proxy_prefix = f"/{self.attr.proxy_prefix.lstrip('/')}" assert not self.attr.container_interface \ or not self.attr.container_interface.publish_port_list_required \ @@ -127,7 +127,7 @@ class InteractiveEnvironmentRequest: self.allowed_images = [x['image'] for x in yaml.safe_load(handle)] if len(self.allowed_images) == 0: - raise Exception("No allowed images specified for " + self.attr.viz_id) + raise Exception(f"No allowed images specified for {self.attr.viz_id}") self.default_image = self.allowed_images[0] @@ -146,7 +146,7 @@ class InteractiveEnvironmentRequest: 'docker_connect_port': None, } viz_config = configparser.ConfigParser(default_dict) - conf_path = os.path.join(self.attr.our_config_dir, self.attr.viz_id + ".ini") + conf_path = os.path.join(self.attr.our_config_dir, f"{self.attr.viz_id}.ini") if not os.path.exists(conf_path): conf_path = f"{conf_path}.sample" viz_config.read(conf_path) @@ -203,9 +203,9 @@ class InteractiveEnvironmentRequest: if self.attr.viz_config.has_option("docker", "galaxy_url"): conf_file['galaxy_url'] = self.attr.viz_config.get("docker", "galaxy_url") elif self.attr.galaxy_config.galaxy_infrastructure_url_set: - conf_file['galaxy_url'] = self.attr.galaxy_config.galaxy_infrastructure_url.rstrip('/') + '/' + conf_file['galaxy_url'] = f"{self.attr.galaxy_config.galaxy_infrastructure_url.rstrip('/')}/" else: - conf_file['galaxy_url'] = request.application_url.rstrip('/') + '/' + conf_file['galaxy_url'] = f"{request.application_url.rstrip('/')}/" # Galaxy paster port is deprecated conf_file['galaxy_paster_port'] = conf_file['galaxy_web_port'] diff --git a/lib/galaxy/visualization/plugins/plugin.py b/lib/galaxy/visualization/plugins/plugin.py index 1ca8c217a82..26466b286da 100644 --- a/lib/galaxy/visualization/plugins/plugin.py +++ b/lib/galaxy/visualization/plugins/plugin.py @@ -74,7 +74,7 @@ class VisualizationPlugin(ServesTemplatesPluginMixin): self.base_url = '/'.join((base_url, self.name)) if base_url else self.name self.static_path = self._get_static_path(self.path) if self.static_path and os.path.exists(os.path.join(self.static_path, 'logo.png')): - self.config['logo'] = self.static_path + '/logo.png' + self.config['logo'] = f"{self.static_path}/logo.png" template_cache_dir = context.get('template_cache_dir', None) additional_template_paths = context.get('additional_template_paths', []) self._set_up_template_plugin(template_cache_dir, additional_template_paths=additional_template_paths) diff --git a/lib/galaxy/visualization/plugins/registry.py b/lib/galaxy/visualization/plugins/registry.py index 3b5c23b915a..be1112778a5 100644 --- a/lib/galaxy/visualization/plugins/registry.py +++ b/lib/galaxy/visualization/plugins/registry.py @@ -180,7 +180,7 @@ class VisualizationsRegistry: """ plugin_name = os.path.split(plugin_path)[1] # TODO: this is the standard/older way to config - config_file = os.path.join(plugin_path, 'config', (plugin_name + '.xml')) + config_file = os.path.join(plugin_path, 'config', (f"{plugin_name}.xml")) if os.path.exists(config_file): config = self.config_parser.parse_file(config_file) if config is not None: @@ -218,7 +218,7 @@ class VisualizationsRegistry: Wrap to throw error if plugin not in registry. """ if key not in self.plugins: - raise ObjectNotFound('Unknown or invalid visualization: ' + key) + raise ObjectNotFound(f"Unknown or invalid visualization: {key}") return self.plugins[key] def get_plugins(self, embeddable=None): diff --git a/lib/galaxy/web/framework/base.py b/lib/galaxy/web/framework/base.py index 078a426932d..b64f5a76aef 100644 --- a/lib/galaxy/web/framework/base.py +++ b/lib/galaxy/web/framework/base.py @@ -34,11 +34,11 @@ def __resource_with_deleted(self, member_name, collection_name, **kwargs): as resource() with the addition of standardized routes for handling elements in Galaxy's "deleted but not really deleted" fashion. """ - collection_path = kwargs.get('path_prefix', '') + '/' + collection_name + '/deleted' - member_path = collection_path + '/{id}' - self.connect('deleted_' + collection_name, collection_path, controller=collection_name, action='index', deleted=True, conditions=dict(method=['GET'])) - self.connect('deleted_' + member_name, member_path, controller=collection_name, action='show', deleted=True, conditions=dict(method=['GET'])) - self.connect('undelete_deleted_' + member_name, member_path + '/undelete', controller=collection_name, action='undelete', + collection_path = f"{kwargs.get('path_prefix', '')}/{collection_name}/deleted" + member_path = f"{collection_path}/{{id}}" + self.connect(f"deleted_{collection_name}", collection_path, controller=collection_name, action='index', deleted=True, conditions=dict(method=['GET'])) + self.connect(f"deleted_{member_name}", member_path, controller=collection_name, action='show', deleted=True, conditions=dict(method=['GET'])) + self.connect(f"undelete_deleted_{member_name}", f"{member_path}/undelete", controller=collection_name, action='undelete', conditions=dict(method=['POST'])) self.resource(member_name, collection_name, **kwargs) @@ -146,7 +146,7 @@ class WebApplication: controller_name = map_match.pop('controller', None) controller = controllers.get(controller_name, None) if controller is None: - raise webob.exc.HTTPNotFound("No controller for " + path_info) + raise webob.exc.HTTPNotFound(f"No controller for {path_info}") # Resolve action method on controller # This is the easiest way to make the controller/action accessible for # url_for invocations. Specifically, grids. @@ -155,18 +155,18 @@ class WebApplication: if method is None and not use_default: # Skip default, we do this, for example, when we want to fail # through to another mapper. - raise webob.exc.HTTPNotFound("No action for " + path_info) + raise webob.exc.HTTPNotFound(f"No action for {path_info}") if method is None: # no matching method, we try for a default method = getattr(controller, 'default', None) if method is None: - raise webob.exc.HTTPNotFound("No action for " + path_info) + raise webob.exc.HTTPNotFound(f"No action for {path_info}") # Is the method exposed if not getattr(method, 'exposed', False): - raise webob.exc.HTTPNotFound("Action not exposed for " + path_info) + raise webob.exc.HTTPNotFound(f"Action not exposed for {path_info}") # Is the method callable if not callable(method): - raise webob.exc.HTTPNotFound("Action not callable for " + path_info) + raise webob.exc.HTTPNotFound(f"Action not callable for {path_info}") return (controller_name, controller, action, method) def handle_request(self, environ, start_response, body_renderer=None): @@ -183,7 +183,7 @@ class WebApplication: environ['is_api_request'] = False controllers = self.controllers if map_match is None: - raise webob.exc.HTTPNotFound("No route for " + path_info) + raise webob.exc.HTTPNotFound(f"No route for {path_info}") self.trace(path_info=path_info, map_match=map_match) # Setup routes rc = routes.request_config() @@ -395,7 +395,7 @@ class Request(webob.Request): @lazy_property def base(self): - return (self.scheme + "://" + self.host) + return (f"{self.scheme}://{self.host}") # @lazy_property # def params( self ): @@ -531,6 +531,6 @@ def walk_controller_modules(package_name): for fname in os.listdir(controller_dir): if not(fname.startswith("_")) and fname.endswith(".py"): name = fname[:-3] - module_name = package_name + "." + name + module_name = f"{package_name}.{name}" module = import_module(module_name) yield name, module diff --git a/lib/galaxy/web/framework/helpers/grids.py b/lib/galaxy/web/framework/helpers/grids.py index 349528c967c..0b101232428 100644 --- a/lib/galaxy/web/framework/helpers/grids.py +++ b/lib/galaxy/web/framework/helpers/grids.py @@ -123,7 +123,7 @@ class TextColumn(GridColumn): else: a_key = self.key model_class_key_field = getattr(self.model_class, a_key) - return func.lower(model_class_key_field).like("%" + a_filter.lower() + "%") + return func.lower(model_class_key_field).like(f"%{a_filter.lower()}%") def sort(self, trans, query, ascending, column_name=None): """Sort column using case-insensitive alphabetical sorting.""" @@ -245,7 +245,7 @@ class OwnerAnnotationColumn(TextColumn, UsesAnnotations): def get_single_filter(self, user, a_filter): """ Filter by annotation and annotation owner. """ return self.model_class.annotations.any( - and_(func.lower(self.model_annotation_association_class.annotation).like("%" + a_filter.lower() + "%"), + and_(func.lower(self.model_annotation_association_class.annotation).like(f"%{a_filter.lower()}%"), # TODO: not sure why, to filter by owner's annotations, we have to do this rather than # 'self.model_class.user==self.model_annotation_association_class.user' self.model_annotation_association_class.table.c.user_id == self.model_class.table.c.user_id)) @@ -282,10 +282,10 @@ class CommunityTagsColumn(TextColumn): for name, value in raw_tags: if name: # Filter by all tags. - clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_tname).like("%" + name.lower() + "%"))) + clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_tname).like(f"%{name.lower()}%"))) if value: # Filter by all values. - clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_value).like("%" + value.lower() + "%"))) + clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_value).like(f"%{value.lower()}%"))) return and_(*clause_list) @@ -311,10 +311,10 @@ class IndividualTagsColumn(CommunityTagsColumn): for name, value in raw_tags: if name: # Filter by individual's tag names. - clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_tname).like("%" + name.lower() + "%"), self.model_tag_association_class.user == user))) + clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_tname).like(f"%{name.lower()}%"), self.model_tag_association_class.user == user))) if value: # Filter by individual's tag values. - clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_value).like("%" + value.lower() + "%"), self.model_tag_association_class.user == user))) + clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_value).like(f"%{value.lower()}%"), self.model_tag_association_class.user == user))) return and_(*clause_list) @@ -564,7 +564,7 @@ class GridColumnFilter: def get_url_args(self): rval = {} for k, v in self.args.items(): - rval["f-" + k] = v + rval[f"f-{k}"] = v return rval @@ -639,12 +639,12 @@ class Grid: if use_default_filter: if self.default_filter: column_filter = self.default_filter.get(column.key) - elif "f-" + column.model_class.__name__ + f".{column.key}" in kwargs: + elif f"f-{column.model_class.__name__}.{column.key}" in kwargs: # Queries that include table joins cannot guarantee unique column names. This problem is # handled by setting the column_filter value to .. - column_filter = kwargs.get("f-" + column.model_class.__name__ + f".{column.key}") - elif "f-" + column.key in kwargs: - column_filter = kwargs.get("f-" + column.key) + column_filter = kwargs.get(f"f-{column.model_class.__name__}.{column.key}") + elif f"f-{column.key}" in kwargs: + column_filter = kwargs.get(f"f-{column.key}") elif column.key in base_filter: column_filter = base_filter.get(column.key) @@ -697,10 +697,10 @@ class Grid: # that we can encode to UTF-8 and thus handle user input to filters. if isinstance(column_filter, list): # Filter is a list; process each item. - extra_url_args["f-" + column.key] = dumps(column_filter) + extra_url_args[f"f-{column.key}"] = dumps(column_filter) else: # Process singleton filter. - extra_url_args["f-" + column.key] = column_filter + extra_url_args[f"f-{column.key}"] = column_filter # Process sort arguments. sort_key = None if 'sort' in kwargs: diff --git a/lib/galaxy/web/framework/middleware/error.py b/lib/galaxy/web/framework/middleware/error.py index e34b380079d..f50a0a2a158 100644 --- a/lib/galaxy/web/framework/middleware/error.py +++ b/lib/galaxy/web/framework/middleware/error.py @@ -422,14 +422,14 @@ def handle_exception(exc_info, error_stream, html=True, extra = "

The error has been logged to our team." if 'sentry_event_id' in environ: extra += " If you want to contact us about this error, please reference the following

" - extra += "GURU MEDITATION: #" + environ['sentry_event_id'] + "" + extra += f"GURU MEDITATION: #{environ['sentry_event_id']}" extra += "

" return_error = error_template('', msg, extra) else: return_error = None if not reported and error_stream: err_report = formatter.format_text(exc_data, show_hidden_frames=True) - err_report += '\n' + '-' * 60 + '\n' + err_report += f"\n{'-' * 60}\n" error_stream.write(err_report) if extra_data: error_stream.write(extra_data) diff --git a/lib/galaxy/web/framework/middleware/profile.py b/lib/galaxy/web/framework/middleware/profile.py index fc30f22cff0..f3cfd09bc47 100644 --- a/lib/galaxy/web/framework/middleware/profile.py +++ b/lib/galaxy/web/framework/middleware/profile.py @@ -113,7 +113,7 @@ def pstats_as_html(stats, *sel_list): # ncalls ncalls = str(nc) if nc != cc: - ncalls = ncalls + '/' + str(cc) + ncalls = f"{ncalls}/{str(cc)}" rval.append(f"{markupsafe.escape(ncalls)}") # tottime rval.append(f"{tt:0.8f}") @@ -147,7 +147,7 @@ def get_func_list(stats, sel_list): # Determine if an ordering was applied if stats.fcn_list: list = stats.fcn_list[:] - order_message = "Ordered by: " + stats.sort_type + order_message = f"Ordered by: {stats.sort_type}" else: list = list(stats.stats.keys()) order_message = "Random listing order was used" diff --git a/lib/galaxy/web/framework/middleware/remoteuser.py b/lib/galaxy/web/framework/middleware/remoteuser.py index c2527a9afa4..3b6d1a0c2e4 100644 --- a/lib/galaxy/web/framework/middleware/remoteuser.py +++ b/lib/galaxy/web/framework/middleware/remoteuser.py @@ -134,7 +134,7 @@ class RemoteUser: if environ.get(self.remote_user_header, None): if not environ[self.remote_user_header].count('@'): if self.maildomain is not None: - environ[self.remote_user_header] += '@' + self.maildomain + environ[self.remote_user_header] += f"@{self.maildomain}" else: title = "Access to Galaxy is denied" message = """ diff --git a/lib/galaxy/web/framework/middleware/statsd.py b/lib/galaxy/web/framework/middleware/statsd.py index e08cb382fac..40814988ca3 100644 --- a/lib/galaxy/web/framework/middleware/statsd.py +++ b/lib/galaxy/web/framework/middleware/statsd.py @@ -38,8 +38,8 @@ class StatsdMiddleware: self.galaxy_stasd_client.timing(page, dt) try: times = QUERY_COUNT_LOCAL.times - self.galaxy_stasd_client.timing("sql." + page, sum(times) * 1000.) - self.galaxy_stasd_client.incr("sqlqueries." + page, len(times)) + self.galaxy_stasd_client.timing(f"sql.{page}", sum(times) * 1000.) + self.galaxy_stasd_client.incr(f"sqlqueries.{page}", len(times)) except AttributeError: # Not logging query counts, skip pass diff --git a/lib/galaxy/web/framework/middleware/translogger.py b/lib/galaxy/web/framework/middleware/translogger.py index e11a0709d80..b567b2c9d1f 100644 --- a/lib/galaxy/web/framework/middleware/translogger.py +++ b/lib/galaxy/web/framework/middleware/translogger.py @@ -53,7 +53,7 @@ class TransLogger: req_uri = quote(environ.get('SCRIPT_NAME', '') + environ.get('PATH_INFO', '')) if environ.get('QUERY_STRING'): - req_uri += '?' + environ['QUERY_STRING'] + req_uri += f"?{environ['QUERY_STRING']}" method = environ['REQUEST_METHOD'] def replacement_start_response(status, headers, exc_info=None): diff --git a/lib/galaxy/web/legacy_framework/grids.py b/lib/galaxy/web/legacy_framework/grids.py index c7e479f474e..15e3522a13f 100644 --- a/lib/galaxy/web/legacy_framework/grids.py +++ b/lib/galaxy/web/legacy_framework/grids.py @@ -122,7 +122,7 @@ class TextColumn(GridColumn): else: a_key = self.key model_class_key_field = getattr(self.model_class, a_key) - return func.lower(model_class_key_field).like("%" + a_filter.lower() + "%") + return func.lower(model_class_key_field).like(f"%{a_filter.lower()}%") def sort(self, trans, query, ascending, column_name=None): """Sort column using case-insensitive alphabetical sorting.""" @@ -237,7 +237,7 @@ class OwnerAnnotationColumn(TextColumn, UsesAnnotations): def get_single_filter(self, user, a_filter): """ Filter by annotation and annotation owner. """ return self.model_class.annotations.any( - and_(func.lower(self.model_annotation_association_class.annotation).like("%" + a_filter.lower() + "%"), + and_(func.lower(self.model_annotation_association_class.annotation).like(f"%{a_filter.lower()}%"), # TODO: not sure why, to filter by owner's annotations, we have to do this rather than # 'self.model_class.user==self.model_annotation_association_class.user' self.model_annotation_association_class.table.c.user_id == self.model_class.table.c.user_id)) @@ -274,10 +274,10 @@ class CommunityTagsColumn(TextColumn): for name, value in raw_tags: if name: # Filter by all tags. - clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_tname).like("%" + name.lower() + "%"))) + clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_tname).like(f"%{name.lower()}%"))) if value: # Filter by all values. - clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_value).like("%" + value.lower() + "%"))) + clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_value).like(f"%{value.lower()}%"))) return and_(*clause_list) @@ -303,10 +303,10 @@ class IndividualTagsColumn(CommunityTagsColumn): for name, value in raw_tags: if name: # Filter by individual's tag names. - clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_tname).like("%" + name.lower() + "%"), self.model_tag_association_class.user == user))) + clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_tname).like(f"%{name.lower()}%"), self.model_tag_association_class.user == user))) if value: # Filter by individual's tag values. - clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_value).like("%" + value.lower() + "%"), self.model_tag_association_class.user == user))) + clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_value).like(f"%{value.lower()}%"), self.model_tag_association_class.user == user))) return and_(*clause_list) @@ -526,7 +526,7 @@ class GridColumnFilter: def get_url_args(self): rval = {} for k, v in self.args.items(): - rval["f-" + k] = v + rval[f"f-{k}"] = v return rval @@ -605,12 +605,12 @@ class Grid: if use_default_filter: if self.default_filter: column_filter = self.default_filter.get(column.key) - elif "f-" + column.model_class.__name__ + f".{column.key}" in kwargs: + elif f"f-{column.model_class.__name__}.{column.key}" in kwargs: # Queries that include table joins cannot guarantee unique column names. This problem is # handled by setting the column_filter value to .. - column_filter = kwargs.get("f-" + column.model_class.__name__ + f".{column.key}") - elif "f-" + column.key in kwargs: - column_filter = kwargs.get("f-" + column.key) + column_filter = kwargs.get(f"f-{column.model_class.__name__}.{column.key}") + elif f"f-{column.key}" in kwargs: + column_filter = kwargs.get(f"f-{column.key}") elif column.key in base_filter: column_filter = base_filter.get(column.key) @@ -664,12 +664,12 @@ class Grid: if isinstance(column_filter, list): # Filter is a list; process each item. column_filter = [str(_).encode('utf-8') if not isinstance(_, str) else _ for _ in column_filter] - extra_url_args["f-" + column.key] = dumps(column_filter) + extra_url_args[f"f-{column.key}"] = dumps(column_filter) else: # Process singleton filter. if not isinstance(column_filter, str): column_filter = str(column_filter) - extra_url_args["f-" + column.key] = column_filter.encode("utf-8") + extra_url_args[f"f-{column.key}"] = column_filter.encode("utf-8") # Process sort arguments. sort_key = None if 'sort' in kwargs: diff --git a/lib/galaxy/web/proxy/__init__.py b/lib/galaxy/web/proxy/__init__.py index 93d19d10993..9d15b550f1d 100644 --- a/lib/galaxy/web/proxy/__init__.py +++ b/lib/galaxy/web/proxy/__init__.py @@ -59,7 +59,7 @@ class ProxyManager: def setup_proxy(self, trans, host=DEFAULT_PROXY_TO_HOST, port=None, proxy_prefix="", route_name="", container_ids=None, container_interface=None): if self.manage_dynamic_proxy: log.info("Attempting to start dynamic proxy process") - log.debug("Cmd: " + ' '.join(self.lazy_process.command_and_args)) + log.debug(f"Cmd: {' '.join(self.lazy_process.command_and_args)}") self.lazy_process.start_process() if container_ids is None: diff --git a/lib/galaxy/web/statsd_client.py b/lib/galaxy/web/statsd_client.py index 7936213088e..b6c88ad73f0 100644 --- a/lib/galaxy/web/statsd_client.py +++ b/lib/galaxy/web/statsd_client.py @@ -42,7 +42,7 @@ class VanillaGalaxyStatsdClient: def _effective_infix(self, path, tags): tags = tags or {} if self.statsd_influxdb and tags: - return ',' + ",".join(f"{k}={v}" for (k, v) in tags.items()) + ",path=" + return f",{','.join(f'{k}={v}' for k, v in tags.items())}" + ',path=' if self.statsd_influxdb: return ',path=' else: diff --git a/lib/galaxy/web_stack/__init__.py b/lib/galaxy/web_stack/__init__.py index 3d420b8d592..3008347efc5 100644 --- a/lib/galaxy/web_stack/__init__.py +++ b/lib/galaxy/web_stack/__init__.py @@ -124,8 +124,8 @@ class ApplicationStack: for pool_name in self.configured_pools: if pool_name == base_pool: tag = job_config.DEFAULT_HANDLER_TAG - elif pool_name.startswith(base_pool + '.'): - tag = pool_name.replace(base_pool + '.', '', 1) + elif pool_name.startswith(f"{base_pool}."): + tag = pool_name.replace(f"{base_pool}.", '', 1) else: continue # Pools are hierarchical (so that you can have e.g. workflow schedulers use the job handlers pool if no @@ -181,7 +181,7 @@ class ApplicationStack: return {} def has_base_pool(self, pool_name): - return self.has_pool(pool_name) or any([pool.startswith(pool_name + '.') for pool in self.configured_pools]) + return self.has_pool(pool_name) or any([pool.startswith(f"{pool_name}.") for pool in self.configured_pools]) def has_pool(self, pool_name): return pool_name in self.configured_pools @@ -306,11 +306,11 @@ class UWSGIApplicationStack(MessageApplicationStack): val = unicodify(uwsgi.opt.get('shared-socket', [])[int(val.split('=')[1])]) proto = opt if opt != 'socket' else 'uwsgi' if proto == 'uwsgi' and ':' not in val: - return 'uwsgi://' + val + return f"uwsgi://{val}" else: - proto = proto + '://' + proto = f"{proto}://" host, port = val.rsplit(':', 1) - port = ':' + port.split(',', 1)[0] + port = f":{port.split(',', 1)[0]}" if host in UWSGIApplicationStack.bind_all_addrs: host = UWSGIApplicationStack.localhost_addrs[0] return proto + host + port @@ -421,7 +421,7 @@ class UWSGIApplicationStack(MessageApplicationStack): # Count the required number of uWSGI locks if job_config.use_messaging: for pool_name in self.configured_pools: - if (pool_name == base_pool or pool_name.startswith(base_pool + '.')): + if (pool_name == base_pool or pool_name.startswith(f"{base_pool}.")): self._lock_farms.add(pool_name) @property @@ -510,7 +510,7 @@ class UWSGIApplicationStack(MessageApplicationStack): root_pid = uwsgi.masterpid() or os.getpid() msg.append('Starting server in PID %d.' % root_pid) for s in UWSGIApplicationStack._serving_on(): - msg.append('serving on ' + s) + msg.append(f"serving on {s}") if len(msg) == 1: msg.append('serving on unknown URL') log.info('\n'.join(msg)) diff --git a/lib/galaxy/web_stack/transport.py b/lib/galaxy/web_stack/transport.py index 18eb1ebea95..95d8ecf93ac 100644 --- a/lib/galaxy/web_stack/transport.py +++ b/lib/galaxy/web_stack/transport.py @@ -39,7 +39,7 @@ class ApplicationStackTransport: # Don't unnecessarily start a thread that we don't need. if self.can_run and not self.running and not self.dispatcher_thread and self.dispatcher and self.dispatcher.handler_count: self.running = True - self.dispatcher_thread = threading.Thread(name=self.__class__.__name__ + ".dispatcher_thread", target=self._dispatch_messages) + self.dispatcher_thread = threading.Thread(name=f"{self.__class__.__name__}.dispatcher_thread", target=self._dispatch_messages) self.dispatcher_thread.start() log.info('%s dispatcher started', self.__class__.__name__) @@ -78,7 +78,7 @@ class UWSGIFarmMessageTransport(ApplicationStackTransport): need = len(self.stack._lock_farms) if num < need: raise RuntimeError('Need %i uWSGI locks but only %i exist(s): Set `locks = %i` in uWSGI configuration' % (need, num, need - 1)) - self._locks.extend(['RECV_MSG_FARM_' + x for x in sorted(self.stack._lock_farms)]) + self._locks.extend([f"RECV_MSG_FARM_{x}" for x in sorted(self.stack._lock_farms)]) # this would be nice, but in my 2.0.15 uWSGI, the uwsgi module has no set_option function, and I don't know if it'd work even if the function existed as documented # if len(self.lock_map) > 1: # uwsgi.set_option('locks', len(self.lock_map)) @@ -100,7 +100,7 @@ class UWSGIFarmMessageTransport(ApplicationStackTransport): uwsgi.unlock(self._locks.index(name_or_id)) def _farm_recv_msg_lock_num(self): - return self._locks.index('RECV_MSG_FARM_' + self.stack._farm_name) + return self._locks.index(f"RECV_MSG_FARM_{self.stack._farm_name}") def _dispatch_messages(self): # this could be moved to the base class if locking was abstracted and a get_message method was added diff --git a/lib/galaxy/webapps/base/controller.py b/lib/galaxy/webapps/base/controller.py index 2d343e6c8c4..d7bbbdc2950 100644 --- a/lib/galaxy/webapps/base/controller.py +++ b/lib/galaxy/webapps/base/controller.py @@ -800,7 +800,7 @@ class UsesVisualizationMixin(UsesLibraryMixinItems): # copy vis and alter title # TODO: need to handle custom db keys. - imported_visualization = visualization.copy(user=user, title="imported: " + visualization.title) + imported_visualization = visualization.copy(user=user, title=f"imported: {visualization.title}") trans.sa_session.add(imported_visualization) trans.sa_session.flush() return imported_visualization @@ -1238,7 +1238,7 @@ class UsesStoredWorkflowMixin(SharableItemSecurityMixin, UsesAnnotations): """ Imports a shared workflow """ # Copy workflow. imported_stored = model.StoredWorkflow() - imported_stored.name = "imported: " + stored.name + imported_stored.name = f"imported: {stored.name}" workflow = stored.latest_workflow.copy(user=trans.user) workflow.stored_workflow = imported_stored imported_stored.latest_workflow = workflow @@ -1471,7 +1471,7 @@ class UsesTagsMixin(SharableItemSecurityMixin): # boil the tag tuples down into a sorted list of DISTINCT name:val strings tags = all_tags_query.distinct().all() - tags = [((name + ':' + val) if val else name) for name, val in tags] + tags = [(f"{name}:{val}" if val else name) for name, val in tags] return sorted(tags) @@ -1552,7 +1552,7 @@ class UsesExtendedMetadataMixin(SharableItemSecurityMixin): """ if isinstance(meta, dict): for a in meta: - yield from self._scan_json_block(meta[a], prefix + "/" + a) + yield from self._scan_json_block(meta[a], f"{prefix}/{a}") elif isinstance(meta, list): for i, a in enumerate(meta): yield from self._scan_json_block(a, prefix + "[%d]" % (i)) diff --git a/lib/galaxy/webapps/base/webapp.py b/lib/galaxy/webapps/base/webapp.py index 4e265a3a040..867ed69b501 100644 --- a/lib/galaxy/webapps/base/webapp.py +++ b/lib/galaxy/webapps/base/webapp.py @@ -620,14 +620,14 @@ class GalaxyWebTransaction(base.DefaultWebTransaction, context.ProvidesHistoryCo user.set_random_password(length=12) user.external = True # Replace invalid characters in the username - for char in [x for x in username if x not in string.ascii_lowercase + string.digits + '-' + '.']: + for char in [x for x in username if x not in f"{string.ascii_lowercase + string.digits}-."]: username = username.replace(char, '-') # Find a unique username - user can change it later if self.sa_session.query(self.app.model.User).filter_by(username=username).first(): i = 1 - while self.sa_session.query(self.app.model.User).filter_by(username=(username + '-' + str(i))).first(): + while self.sa_session.query(self.app.model.User).filter_by(username=f"{username}-{str(i)}").first(): i += 1 - username += '-' + str(i) + username += f"-{str(i)}" user.username = username self.sa_session.add(user) self.sa_session.flush() diff --git a/lib/galaxy/webapps/galaxy/api/cloudauthz.py b/lib/galaxy/webapps/galaxy/api/cloudauthz.py index 1fa76c2e53f..8b4e7e9c7dc 100644 --- a/lib/galaxy/webapps/galaxy/api/cloudauthz.py +++ b/lib/galaxy/webapps/galaxy/api/cloudauthz.py @@ -91,7 +91,7 @@ class CloudAuthzController(BaseGalaxyAPIController): * status: HTTP response code * message: A message complementary to the response code. """ - msg_template = "Rejected user `" + str(trans.user.id) + "`'s request to create cloudauthz config because of {}." + msg_template = f"Rejected user `{str(trans.user.id)}`'s request to create cloudauthz config because of {{}}." if not isinstance(payload, dict): raise ActionInputError('Invalid payload data type. The payload is expected to be a dictionary, but ' 'received data of type `{}`.'.format(str(type(payload)))) @@ -172,7 +172,7 @@ class CloudAuthzController(BaseGalaxyAPIController): :return The cloudauthz record marked as deleted, serialized as a JSON object. """ - msg_template = "Rejected user `" + str(trans.user.id) + "`'s request to delete cloudauthz config because of {}." + msg_template = f"Rejected user `{str(trans.user.id)}`'s request to delete cloudauthz config because of {{}}." try: authz_id = self.decode_id(encoded_authz_id) except MalformedId as e: @@ -236,7 +236,7 @@ class CloudAuthzController(BaseGalaxyAPIController): """ - msg_template = "Rejected user `" + str(trans.user.id) + "`'s request to delete cloudauthz config because of {}." + msg_template = f"Rejected user `{str(trans.user.id)}`'s request to delete cloudauthz config because of {{}}." try: authz_id = self.decode_id(encoded_authz_id) except MalformedId as e: diff --git a/lib/galaxy/webapps/galaxy/api/history_contents.py b/lib/galaxy/webapps/galaxy/api/history_contents.py index 57bc80a5e1b..62dd596d87f 100644 --- a/lib/galaxy/webapps/galaxy/api/history_contents.py +++ b/lib/galaxy/webapps/galaxy/api/history_contents.py @@ -1023,7 +1023,7 @@ class HistoryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems, # ---- for composite files, we use id and name for a directory and, inside that, ... if self.hda_manager.is_composite(content): # ...save the 'main' composite file (gen. html) - paths_and_files.append((content.file_name, os.path.join(archive_path, content.name + '.html'))) + paths_and_files.append((content.file_name, os.path.join(archive_path, f"{content.name}.html"))) for extra_file in self.hda_manager.extra_files(content): extra_file_basename = os.path.basename(extra_file) archive_extra_file_path = os.path.join(archive_path, extra_file_basename) @@ -1033,8 +1033,8 @@ class HistoryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems, # ---- for single files, we add the true extension to id and name and store that single filename else: # some dataset names can contain their original file extensions, don't repeat - if not archive_path.endswith('.' + content.extension): - archive_path += '.' + content.extension + if not archive_path.endswith(f".{content.extension}"): + archive_path += f".{content.extension}" paths_and_files.append((content.file_name, archive_path)) # filter the contents that contain datasets using any filters possible from index above and map the datasets diff --git a/lib/galaxy/webapps/galaxy/api/library_contents.py b/lib/galaxy/webapps/galaxy/api/library_contents.py index d0d25f135ab..355dbb8df95 100644 --- a/lib/galaxy/webapps/galaxy/api/library_contents.py +++ b/lib/galaxy/webapps/galaxy/api/library_contents.py @@ -77,7 +77,7 @@ class LibraryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems, if not admin: can_access, folder_ids = trans.app.security_agent.check_folder_contents(trans.user, current_user_roles, subfolder) if (admin or can_access) and not subfolder.deleted: - subfolder.api_path = folder.api_path + '/' + subfolder.name + subfolder.api_path = f"{folder.api_path}/{subfolder.name}" subfolder.api_type = 'folder' rval.append(subfolder) rval.extend(traverse(subfolder)) @@ -88,7 +88,7 @@ class LibraryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems, ld.library_dataset_dataset_association.dataset ) if (admin or can_access) and not ld.deleted: - ld.api_path = folder.api_path + '/' + ld.name + ld.api_path = f"{folder.api_path}/{ld.name}" ld.api_type = 'file' rval.append(ld) return rval @@ -101,10 +101,10 @@ class LibraryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems, except NoResultFound: raise exceptions.RequestParameterInvalidException('No library found with the id provided.') except Exception as e: - raise exceptions.InternalServerError('Error loading from the database.' + util.unicodify(e)) + raise exceptions.InternalServerError(f"Error loading from the database.{util.unicodify(e)}") if not (trans.user_is_admin or trans.app.security_agent.can_access_library(current_user_roles, library)): raise exceptions.RequestParameterInvalidException('No library found with the id provided.') - encoded_id = 'F' + trans.security.encode_id(library.root_folder.id) + encoded_id = f"F{trans.security.encode_id(library.root_folder.id)}" # appending root folder rval.append(dict(id=encoded_id, type='folder', @@ -115,7 +115,7 @@ class LibraryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems, for content in traverse(library.root_folder): encoded_id = trans.security.encode_id(content.id) if content.api_type == 'folder': - encoded_id = 'F' + encoded_id + encoded_id = f"F{encoded_id}" rval.append(dict(id=encoded_id, type=content.api_type, name=content.api_path, @@ -146,16 +146,16 @@ class LibraryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems, if class_name == 'LibraryFolder': content = self.get_library_folder(trans, content_id, check_ownership=False, check_accessible=True) rval = content.to_dict(view='element', value_mapper={'id': trans.security.encode_id}) - rval['id'] = 'F' + str(rval['id']) + rval['id'] = f"F{str(rval['id'])}" if rval['parent_id'] is not None: # This can happen for root folders. - rval['parent_id'] = 'F' + str(trans.security.encode_id(rval['parent_id'])) + rval['parent_id'] = f"F{str(trans.security.encode_id(rval['parent_id']))}" rval['parent_library_id'] = trans.security.encode_id(rval['parent_library_id']) else: content = self.get_library_dataset(trans, content_id, check_ownership=False, check_accessible=True) rval = content.to_dict(view='element') rval['id'] = trans.security.encode_id(rval['id']) rval['ldda_id'] = trans.security.encode_id(rval['ldda_id']) - rval['folder_id'] = 'F' + str(trans.security.encode_id(rval['folder_id'])) + rval['folder_id'] = f"F{str(trans.security.encode_id(rval['folder_id']))}" rval['parent_library_id'] = trans.security.encode_id(rval['parent_library_id']) tag_manager = tags.GalaxyTagHandler(trans.sa_session) @@ -288,7 +288,7 @@ class LibraryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems, v = v.library_dataset encoded_id = trans.security.encode_id(v.id) if create_type == 'folder': - encoded_id = 'F' + encoded_id + encoded_id = f"F{encoded_id}" rval.append(dict(id=encoded_id, name=v.name, url=url_for('library_content', library_id=library_id, id=encoded_id))) @@ -368,7 +368,7 @@ class LibraryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems, """ if isinstance(meta, dict): for a in meta: - yield from self._scan_json_block(meta[a], prefix + "/" + a) + yield from self._scan_json_block(meta[a], f"{prefix}/{a}") elif isinstance(meta, list): for i, a in enumerate(meta): yield from self._scan_json_block(a, prefix + "[%d]" % (i)) diff --git a/lib/galaxy/webapps/galaxy/api/library_datasets.py b/lib/galaxy/webapps/galaxy/api/library_datasets.py index e99b1ab5581..108a28dbbec 100644 --- a/lib/galaxy/webapps/galaxy/api/library_datasets.py +++ b/lib/galaxy/webapps/galaxy/api/library_datasets.py @@ -94,7 +94,7 @@ class LibraryDatasetsController(BaseGalaxyAPIController, UsesVisualizationMixin, try: ldda = self.get_library_dataset_dataset_association(trans, id=encoded_ldda_id, check_ownership=False, check_accessible=False) except Exception as e: - raise exceptions.ObjectNotFound('Requested version of library dataset was not found.' + util.unicodify(e)) + raise exceptions.ObjectNotFound(f"Requested version of library dataset was not found.{util.unicodify(e)}") if ldda not in library_dataset.expired_datasets: raise exceptions.ObjectNotFound('Given library dataset does not have the requested version.') @@ -268,7 +268,7 @@ class LibraryDatasetsController(BaseGalaxyAPIController, UsesVisualizationMixin, else: invalid_access_roles_ids.append(role_id) if len(invalid_access_roles_ids) > 0: - log.warning("The following roles could not be added to the dataset access permission: " + str(invalid_access_roles_ids)) + log.warning(f"The following roles could not be added to the dataset access permission: {str(invalid_access_roles_ids)}") access_permission = dict(access=valid_access_roles) trans.app.security_agent.set_dataset_permission(dataset, access_permission) @@ -284,7 +284,7 @@ class LibraryDatasetsController(BaseGalaxyAPIController, UsesVisualizationMixin, else: invalid_manage_roles_ids.append(role_id) if len(invalid_manage_roles_ids) > 0: - log.warning("The following roles could not be added to the dataset manage permission: " + str(invalid_manage_roles_ids)) + log.warning(f"The following roles could not be added to the dataset manage permission: {str(invalid_manage_roles_ids)}") manage_permission = {trans.app.security_agent.permitted_actions.DATASET_MANAGE_PERMISSIONS: valid_manage_roles} trans.app.security_agent.set_dataset_permission(dataset, manage_permission) @@ -299,7 +299,7 @@ class LibraryDatasetsController(BaseGalaxyAPIController, UsesVisualizationMixin, else: invalid_modify_roles_ids.append(role_id) if len(invalid_modify_roles_ids) > 0: - log.warning("The following roles could not be added to the dataset modify permission: " + str(invalid_modify_roles_ids)) + log.warning(f"The following roles could not be added to the dataset modify permission: {str(invalid_modify_roles_ids)}") modify_permission = {trans.app.security_agent.permitted_actions.LIBRARY_MODIFY: valid_modify_roles} trans.app.security_agent.set_library_item_permission(library_dataset, modify_permission) return self._get_current_roles(trans, library_dataset) @@ -339,7 +339,7 @@ class LibraryDatasetsController(BaseGalaxyAPIController, UsesVisualizationMixin, rval['file_size'] = nice_size rval['update_time'] = library_dataset.update_time.strftime("%Y-%m-%d %I:%M %p") rval['deleted'] = library_dataset.deleted - rval['folder_id'] = 'F' + rval['folder_id'] + rval['folder_id'] = f"F{rval['folder_id']}" return rval @expose_api @@ -565,7 +565,7 @@ class LibraryDatasetsController(BaseGalaxyAPIController, UsesVisualizationMixin, except HTTPInternalServerError: raise exceptions.InternalServerError('Internal error.') except Exception as e: - raise exceptions.InternalServerError('Unknown error.' + util.unicodify(e)) + raise exceptions.InternalServerError(f"Unknown error.{util.unicodify(e)}") folders_to_download = kwd.get('folder_ids%5B%5D', None) if folders_to_download is None: @@ -647,7 +647,7 @@ class LibraryDatasetsController(BaseGalaxyAPIController, UsesVisualizationMixin, raise exceptions.ObjectNotFound("Requested dataset not found. ") except Exception as e: log.exception("Unable to add composite parent %s to temporary library download archive", ldda.dataset.file_name) - raise exceptions.InternalServerError("Unable to add composite parent to temporary library download archive. " + util.unicodify(e)) + raise exceptions.InternalServerError(f"Unable to add composite parent to temporary library download archive. {util.unicodify(e)}") flist = glob.glob(os.path.join(ldda.dataset.extra_files_path, '*.*')) # glob returns full paths for fpath in flist: @@ -664,7 +664,7 @@ class LibraryDatasetsController(BaseGalaxyAPIController, UsesVisualizationMixin, raise exceptions.ObjectNotFound("Requested dataset not found.") except Exception as e: log.exception("Unable to add %s to temporary library download archive %s", fname, outfname) - raise exceptions.InternalServerError("Unable to add dataset to temporary library download archive . " + util.unicodify(e)) + raise exceptions.InternalServerError(f"Unable to add dataset to temporary library download archive . {util.unicodify(e)}") else: try: archive.write(ldda.dataset.file_name, path) @@ -676,7 +676,7 @@ class LibraryDatasetsController(BaseGalaxyAPIController, UsesVisualizationMixin, raise exceptions.ObjectNotFound("Requested dataset not found.") except Exception as e: log.exception("Unable to add %s to temporary library download archive %s", ldda.dataset.file_name, outfname) - raise exceptions.InternalServerError("Unknown error. " + util.unicodify(e)) + raise exceptions.InternalServerError(f"Unknown error. {util.unicodify(e)}") trans.response.headers.update(archive.get_headers()) return archive.response() elif archive_format == 'uncompressed': diff --git a/lib/galaxy/webapps/galaxy/api/users.py b/lib/galaxy/webapps/galaxy/api/users.py index b240563ee2e..25233326d73 100644 --- a/lib/galaxy/webapps/galaxy/api/users.py +++ b/lib/galaxy/webapps/galaxy/api/users.py @@ -307,7 +307,7 @@ class UserAPIController(BaseGalaxyAPIController, UsesTagsMixin, BaseUIController input['help'] = f"{help} {required}" else: input['help'] = required - field = item + '|' + input['name'] + field = f"{item}|{input['name']}" for data_item in user.extra_preferences: if field in data_item: input['value'] = user.extra_preferences[data_item] @@ -421,7 +421,7 @@ class UserAPIController(BaseGalaxyAPIController, UsesTagsMixin, BaseUIController # Update user email and user's private role name which must match private_role = trans.app.security_agent.get_private_user_role(user) private_role.name = email - private_role.description = 'Private role for ' + email + private_role.description = f"Private role for {email}" user.email = email trans.sa_session.add(user) trans.sa_session.add(private_role) @@ -462,7 +462,7 @@ class UserAPIController(BaseGalaxyAPIController, UsesTagsMixin, BaseUIController extra_pref_keys = self._get_extra_user_preferences(trans) if extra_pref_keys is not None: for key in extra_pref_keys: - key_prefix = key + '|' + key_prefix = f"{key}|" for item in payload: if item.startswith(key_prefix): # Show error message if the required field is empty @@ -670,7 +670,7 @@ class UserAPIController(BaseGalaxyAPIController, UsesTagsMixin, BaseUIController new_filters = [] for prefixed_name in payload: if payload.get(prefixed_name) == 'true' and prefixed_name.startswith(filter_type): - prefix = filter_type + '|' + prefix = f"{filter_type}|" new_filters.append(prefixed_name[len(prefix):]) user.preferences[filter_type] = ','.join(new_filters) trans.sa_session.add(user) diff --git a/lib/galaxy/webapps/galaxy/api/workflows.py b/lib/galaxy/webapps/galaxy/api/workflows.py index 4614d07d88c..bb86e56b533 100644 --- a/lib/galaxy/webapps/galaxy/api/workflows.py +++ b/lib/galaxy/webapps/galaxy/api/workflows.py @@ -1431,7 +1431,7 @@ class WorkflowsAPIController(BaseGalaxyAPIController, UsesStoredWorkflowMixin, U install_options = workflow_create_options.install_options for k in tools: item = tools[k] - tool_shed_url = 'https://' + item['tool_shed'] + '/' + tool_shed_url = f"https://{item['tool_shed']}/" name = item['name'] owner = item['owner'] changeset_revision = item['changeset_revision'] diff --git a/lib/galaxy/webapps/galaxy/buildapp.py b/lib/galaxy/webapps/galaxy/buildapp.py index aab62951408..7fbe248c66d 100644 --- a/lib/galaxy/webapps/galaxy/buildapp.py +++ b/lib/galaxy/webapps/galaxy/buildapp.py @@ -683,21 +683,21 @@ def populate_api_routes(webapp, app): conditions = conditions or dict(method=['GET']) webapp.mapper.connect( f'workflow_invocation_{endpoint_name}', - '/api/workflows/{workflow_id}/invocations/{invocation_id}' + endpoint_suffix, + f"/api/workflows/{{workflow_id}}/invocations/{{invocation_id}}{endpoint_suffix}", controller='workflows', action=action, conditions=conditions, ) webapp.mapper.connect( f'workflow_usage_{endpoint_name}', - '/api/workflows/{workflow_id}/usage/{invocation_id}' + endpoint_suffix, + f"/api/workflows/{{workflow_id}}/usage/{{invocation_id}}{endpoint_suffix}", controller='workflows', action=action, conditions=conditions, ) webapp.mapper.connect( f'invocation_{endpoint_name}', - '/api/invocations/{invocation_id}' + endpoint_suffix, + f"/api/invocations/{{invocation_id}}{endpoint_suffix}", controller='workflows', action=action, conditions=conditions, diff --git a/lib/galaxy/webapps/galaxy/controllers/_create_history_template.py b/lib/galaxy/webapps/galaxy/controllers/_create_history_template.py index 9be9c2c77d5..e9d83587aec 100644 --- a/lib/galaxy/webapps/galaxy/controllers/_create_history_template.py +++ b/lib/galaxy/webapps/galaxy/controllers/_create_history_template.py @@ -32,7 +32,7 @@ def render_item_hda(trans, hda, children): elif hda.copied_from_library_dataset_dataset_association: template = render_hda_copied_from_library(trans, hda, children) else: - template = '
' + template = f"
" return template @@ -43,16 +43,16 @@ def render_hda_copied_from_history(trans, hda, children): template = '' id = trans.security.encode_id(hda.id) history_id = trans.security.encode_id(hda.copied_from_history_dataset_association.history_id) - url = url_for('/histories/view?id=' + history_id) + url = url_for(f"/histories/view?id={history_id}") template = '
' template += ' Copied from history dataset: ' - template += '' + hda.copied_from_history_dataset_association.name + '' + template += f"{hda.copied_from_history_dataset_association.name}" template += '
' template += 'History: ' template += '' - template += '' + hda.copied_from_history_dataset_association.history.name + '' + template += f"{hda.copied_from_history_dataset_association.history.name}" template += '
' - template += '
' + template += f"
" return template @@ -63,19 +63,19 @@ def render_hda_copied_from_library(trans, hda, children): template = '' id = trans.security.encode_id(hda.id) folder = hda.copied_from_library_dataset_dataset_association.library_dataset.folder - folder_id = 'F' + trans.security.encode_id(folder.id) - url = url_for('/library/list#folders/' + folder_id) + folder_id = f"F{trans.security.encode_id(folder.id)}" + url = url_for(f"/library/list#folders/{folder_id}") template = '
' template += '
' template += '
' template += 'Copied from library dataset:' - template += '' + hda.copied_from_library_dataset_dataset_association.name + '' + template += f"{hda.copied_from_library_dataset_dataset_association.name}" template += '
' template += '
' template += 'Library: ' template += '' - template += '' + folder.name + '
' - template += '
' + template += f"{folder.name}" + template += f"
" return template @@ -97,8 +97,8 @@ def render_item_job(trans, job, children): params_object = job.get_param_values(trans.app, ignore_errors=True) except Exception: pass - template += '
' + tool_name + '' - template += ' - ' + tool_desc + '
' + template += f"
{tool_name}" + template += f" - {tool_desc}
" if tool and params_object: template += '' template += inputs_recursive(trans, tool.inputs, params_object, depth=1) @@ -119,7 +119,7 @@ def render_item_wf(trans, wf, children): """ Render a workflow and its children (jobs) """ - template = '
' + wf.workflow.name + '' + template = f"
{wf.workflow.name}" template += '- Workflow
' for e, c in reversed(children): template += render_item(trans, e, c) @@ -131,7 +131,7 @@ def inputs_recursive_indent(text, depth): """ Add an indentation depending on the depth in a
""" - return '' + return f"" def inputs_recursive(trans, input_params, param_values, depth=1, upgrade_messages=None): @@ -162,7 +162,7 @@ def inputs_recursive(trans, input_params, param_values, depth=1, upgrade_message if is_valid: tool_parameter_template += '' tool_parameter_template += inputs_recursive_indent(text=input.test_param.label, depth=depth) - tool_parameter_template += '' + tool_parameter_template += f"" inputs_recursive(trans, input.cases[current_case].inputs, param_values[input.name], depth=depth + 1, upgrade_messages=upgrade_messages.get(input.name)) else: tool_parameter_template += '' @@ -171,7 +171,7 @@ def inputs_recursive(trans, input_params, param_values, depth=1, upgrade_message elif input.type == "upload_dataset": tool_parameter_template += '' tool_parameter_template += inputs_recursive_indent(text=input.group_title(param_values), depth=depth) - tool_parameter_template += '' + tool_parameter_template += f"" elif input.type == "data": tool_parameter_template += '' tool_parameter_template += inputs_recursive_indent(text=input.label, depth=depth) @@ -183,17 +183,17 @@ def inputs_recursive(trans, input_params, param_values, depth=1, upgrade_message hda = element encoded_id = trans.security.encode_id(hda.id) dataset_info_url = url_for(controller="dataset", action="show_params", dataset_id=encoded_id) - tool_parameter_template += '' + str(hda.hid) + ':' + hda.name + '' + tool_parameter_template += f"{str(hda.hid)}:{hda.name}" else: - tool_parameter_template += str(element.hid) + ':' + element.name + tool_parameter_template += f"{str(element.hid)}:{element.name}" tool_parameter_template += '' elif input.visible: label = input.label if (hasattr(input, "label") and input.label) else input.name tool_parameter_template += '' tool_parameter_template += inputs_recursive_indent(text=label, depth=depth) - tool_parameter_template += '' - tool_parameter_template += '' + tool_parameter_template += f"" + tool_parameter_template += f"" else: tool_parameter_template += '' if input.type == "conditional": diff --git a/lib/galaxy/webapps/galaxy/controllers/admin.py b/lib/galaxy/webapps/galaxy/controllers/admin.py index d6d8fa6b221..d1eb6168f87 100644 --- a/lib/galaxy/webapps/galaxy/controllers/admin.py +++ b/lib/galaxy/webapps/galaxy/controllers/admin.py @@ -676,7 +676,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP all_groups.append((group.name, trans.security.encode_id(group.id))) default_options = [('No', 'no')] for type_ in trans.app.model.DefaultQuotaAssociation.types: - default_options.append(('Yes, ' + type_, type_)) + default_options.append((f"Yes, {type_}", type_)) return {'title': 'Create Quota', 'inputs': [ { @@ -809,7 +809,7 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP default_value = quota.default[0].type if quota.default else 'no' default_options = [('No', 'no')] for typ in trans.app.model.DefaultQuotaAssociation.types.__members__.values(): - default_options.append(('Yes, ' + typ, typ)) + default_options.append((f"Yes, {typ}", typ)) return { 'title': 'Set quota default for \'%s\'' % util.sanitize_text(quota.name), 'inputs': [{ diff --git a/lib/galaxy/webapps/galaxy/controllers/async.py b/lib/galaxy/webapps/galaxy/controllers/async.py index dfc68373f1d..789abdd564b 100644 --- a/lib/galaxy/webapps/galaxy/controllers/async.py +++ b/lib/galaxy/webapps/galaxy/controllers/async.py @@ -70,7 +70,7 @@ class ASync(BaseUIController): data.state = data.blurb = data.states.RUNNING log.debug(f'executing tool {tool.id}') trans.log_event(f'Async executing tool {tool.id}', tool_id=tool.id) - galaxy_url = trans.request.base + f'/async/{tool_id}/{data.id}/{key}' + galaxy_url = f"{trans.request.base}/async/{tool_id}/{data.id}/{key}" galaxy_url = params.get("GALAXY_URL", galaxy_url) params = dict(URL=URL, GALAXY_URL=galaxy_url, name=data.name, info=data.info, dbkey=data.dbkey, data_type=data.ext) @@ -154,7 +154,7 @@ class ASync(BaseUIController): try: key = hmac_new(trans.app.config.tool_secret, "%d:%d" % (data.id, data.history_id)) - galaxy_url = trans.request.base + f'/async/{tool_id}/{data.id}/{key}' + galaxy_url = f"{trans.request.base}/async/{tool_id}/{data.id}/{key}" params.update({'GALAXY_URL': galaxy_url}) params.update({'data_id': data.id}) diff --git a/lib/galaxy/webapps/galaxy/controllers/authnz.py b/lib/galaxy/webapps/galaxy/controllers/authnz.py index c74b338a038..c7a8abe007f 100644 --- a/lib/galaxy/webapps/galaxy/controllers/authnz.py +++ b/lib/galaxy/webapps/galaxy/controllers/authnz.py @@ -125,7 +125,7 @@ class OIDC(JSAppLauncher): trans=trans, login_redirect_url=url_for('/')) except exceptions.AuthenticationFailed as e: - return trans.response.send_redirect(trans.request.base + url_for('/') + 'root/login?message=' + (str(e) or "Duplicate Email")) + return trans.response.send_redirect(f"{trans.request.base + url_for('/')}root/login?message={str(e) or 'Duplicate Email'}") if success is False: return trans.show_error_message(message) @@ -160,7 +160,7 @@ class OIDC(JSAppLauncher): @web.json @web.expose def logout(self, trans, provider, **kwargs): - post_logout_redirect_url = trans.request.base + url_for('/') + 'root/login?is_logout_redirect=true' + post_logout_redirect_url = f"{trans.request.base + url_for('/')}root/login?is_logout_redirect=true" success, message, redirect_uri = trans.app.authnz_manager.logout(provider, trans, post_logout_redirect_url=post_logout_redirect_url) diff --git a/lib/galaxy/webapps/galaxy/controllers/dataset.py b/lib/galaxy/webapps/galaxy/controllers/dataset.py index 4017de1ad5e..d14a47aa2ef 100644 --- a/lib/galaxy/webapps/galaxy/controllers/dataset.py +++ b/lib/galaxy/webapps/galaxy/controllers/dataset.py @@ -283,7 +283,7 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE in_roles[action.action] = [trans.security.encode_id(role.id) for role in roles] for index, action in trans.app.model.Dataset.permitted_actions.items(): if action == trans.app.security_agent.permitted_actions.DATASET_ACCESS: - help_text = action.description + '
NOTE: Users must have every role associated with this dataset in order to access it.' + help_text = f"{action.description}
NOTE: Users must have every role associated with this dataset in order to access it." else: help_text = action.description permission_inputs.append({ @@ -1003,10 +1003,10 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE source_contents.sort(key=lambda content: content.hid) for content in source_contents: if content is None: - error_msg = error_msg + "You tried to copy a dataset that does not exist. " + error_msg = f"{error_msg}You tried to copy a dataset that does not exist. " invalid_contents += 1 elif content.history != history: - error_msg = error_msg + "You tried to copy a dataset which is not in your current history. " + error_msg = f"{error_msg}You tried to copy a dataset which is not in your current history. " invalid_contents += 1 else: for hist in target_histories: @@ -1066,13 +1066,13 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE data = self.hda_manager.error_if_uploading(data) if data is None: - error_msg = error_msg + "You tried to copy a dataset that does not exist or that you do not have access to. " + error_msg = f"{error_msg}You tried to copy a dataset that does not exist or that you do not have access to. " invalid_datasets += 1 else: for hist in target_histories: dataset_copy = data.copy() if imported: - dataset_copy.name = "imported: " + dataset_copy.name + dataset_copy.name = f"imported: {dataset_copy.name}" hist.add_dataset(dataset_copy) trans.sa_session.flush() num_datasets_copied = len(dataset_ids) - invalid_datasets diff --git a/lib/galaxy/webapps/galaxy/controllers/history.py b/lib/galaxy/webapps/galaxy/controllers/history.py index ebfc530981b..d363d2790db 100644 --- a/lib/galaxy/webapps/galaxy/controllers/history.py +++ b/lib/galaxy/webapps/galaxy/controllers/history.py @@ -1179,7 +1179,7 @@ class HistoryController(BaseUIController, SharableMixin, UsesAnnotations, UsesIt trans.sa_session.add(h) trans.sa_session.flush() trans.log_event(f'History renamed: id: {str(h.id)}, renamed to: {new_name}') - messages.append('History \'' + cur_name + '\' renamed to \'' + new_name + '\'.') + messages.append(f"History '{cur_name}' renamed to '{new_name}'.") message = sanitize_text(' '.join(messages)) if messages else 'History names remain unchanged.' return {'message': message, 'status': 'success'} diff --git a/lib/galaxy/webapps/galaxy/controllers/page.py b/lib/galaxy/webapps/galaxy/controllers/page.py index d39ce3d2fa3..1754e4be236 100644 --- a/lib/galaxy/webapps/galaxy/controllers/page.py +++ b/lib/galaxy/webapps/galaxy/controllers/page.py @@ -338,8 +338,8 @@ class PageController(BaseUIController, SharableMixin, content_hide = True if "invocation_id" in kwd: invocation_id = kwd.get("invocation_id") - form_title = form_title + " from Invocation Report" - slug = "invocation-report-" + invocation_id + form_title = f"{form_title} from Invocation Report" + slug = f"invocation-report-{invocation_id}" invocation_report = self.workflow_manager.get_invocation_report(trans, invocation_id) title = invocation_report.get("title") content = invocation_report.get("markdown") diff --git a/lib/galaxy/webapps/galaxy/controllers/root.py b/lib/galaxy/webapps/galaxy/controllers/root.py index 81a89d156bc..22174cd8985 100644 --- a/lib/galaxy/webapps/galaxy/controllers/root.py +++ b/lib/galaxy/webapps/galaxy/controllers/root.py @@ -189,7 +189,7 @@ class RootController(controller.JSAppLauncher, UsesAnnotations): fStat = os.stat(data.file_name) trans.response.headers['Content-Length'] = str(fStat.st_size) if toext[0:1] != ".": - toext = "." + toext + toext = f".{toext}" fname = data.name fname = ''.join(c in FILENAME_VALID_CHARS and c or '_' for c in fname)[0:150] trans.response.headers["Content-Disposition"] = f'attachment; filename="GalaxyHistoryItem-{data.hid}-[{fname}]{toext}"' @@ -264,7 +264,7 @@ class RootController(controller.JSAppLauncher, UsesAnnotations): if import_history.user_id == user.id: return trans.show_error_message("You cannot import your own history.") new_history = import_history.copy(target_user=trans.user) - new_history.name = "imported: " + new_history.name + new_history.name = f"imported: {new_history.name}" new_history.user_id = user.id galaxy_session = trans.get_galaxy_session() try: @@ -284,7 +284,7 @@ class RootController(controller.JSAppLauncher, UsesAnnotations): to begin.""".format(new_history.name, web.url_for('/'))) elif not user_history.datasets or confirm: new_history = import_history.copy() - new_history.name = "imported: " + new_history.name + new_history.name = f"imported: {new_history.name}" new_history.user_id = None galaxy_session = trans.get_galaxy_session() try: @@ -351,7 +351,7 @@ class RootController(controller.JSAppLauncher, UsesAnnotations): data.set_peek() trans.sa_session.flush() trans.log_event("Added dataset %d to history %d" % (data.id, trans.history.id)) - return trans.show_ok_message("Dataset " + str(data.hid) + " added to history " + str(history_id) + ".") + return trans.show_ok_message(f"Dataset {str(data.hid)} added to history {str(history_id)}.") except Exception as e: msg = f"Failed to add dataset to history: {unicodify(e)}" log.error(msg) diff --git a/lib/galaxy/webapps/galaxy/controllers/tag.py b/lib/galaxy/webapps/galaxy/controllers/tag.py index f10e38cd6b0..5db26c4c4a0 100644 --- a/lib/galaxy/webapps/galaxy/controllers/tag.py +++ b/lib/galaxy/webapps/galaxy/controllers/tag.py @@ -109,7 +109,7 @@ class TagsController(BaseUIController, UsesTagsMixin): # Build select statement. cols_to_select = [item_tag_assoc_class.table.c.tag_id, func.count('*')] from_obj = item_tag_assoc_class.table.join(item_class.table).join(trans.app.model.Tag.table) - where_clause = and_(trans.app.model.Tag.table.c.name.like(q + "%"), + where_clause = and_(trans.app.model.Tag.table.c.name.like(f"{q}%"), item_tag_assoc_class.table.c.user_id == user.id) order_by = [func.count("*").desc()] group_by = item_tag_assoc_class.table.c.tag_id @@ -131,7 +131,7 @@ class TagsController(BaseUIController, UsesTagsMixin): # Add tag to autocomplete data. Use the most frequent name that user # has employed for the tag. tag_names = self._get_usernames_for_tag(trans, trans.user, tag, item_class, item_tag_assoc_class) - ac_data += tag_names[0] + "|" + tag_names[0] + "\n" + ac_data += f"{tag_names[0]}|{tag_names[0]}\n" return ac_data def _get_tag_autocomplete_values(self, trans, q, limit, timestamp, user=None, item=None, item_class=None): @@ -157,7 +157,7 @@ class TagsController(BaseUIController, UsesTagsMixin): from_obj = item_tag_assoc_class.table.join(item_class.table).join(trans.app.model.Tag.table) where_clause = and_(item_tag_assoc_class.table.c.user_id == user.id, trans.app.model.Tag.table.c.id == tag.id, - item_tag_assoc_class.table.c.value.like(tag_value + "%")) + item_tag_assoc_class.table.c.value.like(f"{tag_value}%")) order_by = [func.count("*").desc(), item_tag_assoc_class.table.c.value] group_by = item_tag_assoc_class.table.c.value # Do query and get result set. @@ -172,7 +172,7 @@ class TagsController(BaseUIController, UsesTagsMixin): ac_data = f"#Header|Your Values for '{tag_name}'\n" tag_uname = self._get_usernames_for_tag(trans, trans.user, tag, item_class, item_tag_assoc_class)[0] for row in result_set: - ac_data += tag_uname + ":" + row[0] + "|" + row[0] + "\n" + ac_data += f"{tag_uname}:{row[0]}|{row[0]}\n" return ac_data def _get_usernames_for_tag(self, trans, user, tag, item_class, item_tag_assoc_class): diff --git a/lib/galaxy/webapps/galaxy/controllers/visualization.py b/lib/galaxy/webapps/galaxy/controllers/visualization.py index 44aea3e5515..9b4d56dd6b8 100644 --- a/lib/galaxy/webapps/galaxy/controllers/visualization.py +++ b/lib/galaxy/webapps/galaxy/controllers/visualization.py @@ -402,7 +402,7 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization # Create imported visualization via copy. # TODO: need to handle custom db keys. - imported_visualization = visualization.copy(user=trans.user, title="imported: " + visualization.title) + imported_visualization = visualization.copy(user=trans.user, title=f"imported: {visualization.title}") # Persist session = trans.sa_session diff --git a/lib/galaxy/webapps/galaxy/controllers/workflow.py b/lib/galaxy/webapps/galaxy/controllers/workflow.py index 390c408a512..80870f8d1c0 100644 --- a/lib/galaxy/webapps/galaxy/controllers/workflow.py +++ b/lib/galaxy/webapps/galaxy/controllers/workflow.py @@ -205,7 +205,7 @@ class WorkflowController(BaseUIController, SharableMixin, UsesStoredWorkflowMixi Render workflow main page (management of existing workflows) """ # Take care of proxy prefix in url as well - redirect_url = url_for('/') + 'workflow' + redirect_url = f"{url_for('/')}workflow" return trans.response.send_redirect(redirect_url) @web.expose @@ -539,7 +539,7 @@ class WorkflowController(BaseUIController, SharableMixin, UsesStoredWorkflowMixi # Display the management page message = f'Created new workflow with name: {escape(new_stored.name)}' trans.set_message(message) - return_url = url_for('/') + f'workflow?status=done&message={escape(message)}' + return_url = f"{url_for('/')}workflow?status=done&message={escape(message)}" trans.response.send_redirect(return_url) @web.legacy_expose_api @@ -644,7 +644,7 @@ class WorkflowController(BaseUIController, SharableMixin, UsesStoredWorkflowMixi # Display the management page message = f"Workflow deleted: {escape(stored.name)}" trans.set_message(message) - return trans.response.send_redirect(url_for('/') + f'workflow?status=done&message={escape(message)}') + return trans.response.send_redirect(f"{url_for('/')}workflow?status=done&message={escape(message)}") @web.expose @web.require_login("edit workflows") diff --git a/lib/galaxy/webapps/reports/buildapp.py b/lib/galaxy/webapps/reports/buildapp.py index 0ec39bf28e8..224b4de2f45 100644 --- a/lib/galaxy/webapps/reports/buildapp.py +++ b/lib/galaxy/webapps/reports/buildapp.py @@ -33,7 +33,7 @@ def add_ui_controllers(webapp, app): for fname in os.listdir(controller_dir): if not fname.startswith("_") and fname.endswith(".py"): name = fname[:-3] - module_name = "galaxy.webapps.reports.controllers." + name + module_name = f"galaxy.webapps.reports.controllers.{name}" module = __import__(module_name) for comp in module_name.split(".")[1:]: module = getattr(module, comp) diff --git a/lib/galaxy/webapps/reports/controllers/tools.py b/lib/galaxy/webapps/reports/controllers/tools.py index 159d5bfe3ea..492dd9ce1a8 100644 --- a/lib/galaxy/webapps/reports/controllers/tools.py +++ b/lib/galaxy/webapps/reports/controllers/tools.py @@ -49,14 +49,14 @@ class Tools(BaseUIController): if len(splited) == 2: returned = "%s %dH" % (splited[0], int(splited[1].split(':')[0])) if colored: - return '' + returned + '' + return f"{returned}" return returned else: splited = tuple([float(_) for _ in str(date).split(':')]) if splited[0]: returned = '%d h. %d min.' % splited[:2] if colored: - return '' + returned + '' + return f"{returned}" return returned if splited[1]: return "%d min. %d sec." % splited[1:3] @@ -331,13 +331,13 @@ class Tools(BaseUIController): if words.count(word) > 1: to_replace.append(word) for word in to_replace: - sentence = ("
" + word) * 2 + sentence = f"
{word}" * 2 count = 2 - while sentence + "
" + word in new_key: - sentence += "
" + word + while f"{sentence}
{word}" in new_key: + sentence += f"
{word}" count += 1 if sentence in new_key: - new_key = new_key.replace(sentence, '
' + word + " [this line in %d times]" % (count)) + new_key = new_key.replace(sentence, f"
{word}{' [this line in %d times]' % count}") data[new_key] = counter[key] return trans.fill_template("/webapps/reports/tool_error_messages.mako", diff --git a/lib/galaxy/workflow/extract.py b/lib/galaxy/workflow/extract.py index a240731671f..1aacc814cf4 100644 --- a/lib/galaxy/workflow/extract.py +++ b/lib/galaxy/workflow/extract.py @@ -381,7 +381,7 @@ def __cleanup_param_values(inputs, values): # Cleanup the other deprecated crap associated with datasets # as well. Worse, for nested datasets all the metadata is # being pushed into the root. FIXME: MUST REMOVE SOON - key = prefix + key + "_" + key = f"{prefix + key}_" for k in root_values.keys(): if k not in root_input_keys and k.startswith(key): del root_values[k] diff --git a/lib/galaxy/workflow/modules.py b/lib/galaxy/workflow/modules.py index 81f8b8935ff..e57bed5f79c 100644 --- a/lib/galaxy/workflow/modules.py +++ b/lib/galaxy/workflow/modules.py @@ -1317,9 +1317,9 @@ class ToolModule(WorkflowModule): if old_tool_shed not in tool_id: # Only display the following warning if the tool comes from a different tool shed old_tool_shed_url = get_tool_shed_url_from_tool_shed_registry(trans.app, old_tool_shed) if not old_tool_shed_url: # a tool from a different tool_shed has been found, but the original tool shed has been deactivated - old_tool_shed_url = "http://" + old_tool_shed # let's just assume it's either http, or a http is forwarded to https. - old_url = old_tool_shed_url + f"/view/{module.tool.repository_owner}/{module.tool.repository_name}/" - new_url = module.tool.sharable_url + f'/{module.tool.changeset_revision}/' + old_tool_shed_url = f"http://{old_tool_shed}" # let's just assume it's either http, or a http is forwarded to https. + old_url = f"{old_tool_shed_url}/view/{module.tool.repository_owner}/{module.tool.repository_name}/" + new_url = f"{module.tool.sharable_url}/{module.tool.changeset_revision}/" new_tool_shed_url = new_url.split("/view")[0] message += f"The tool \'{module.tool.name}\', version {tool_version} by the owner {module.tool.repository_owner} installed from {old_tool_shed_url} is not available. " message += f"A derivation of this tool installed from {new_tool_shed_url} will be used instead. " diff --git a/lib/galaxy/workflow/trs_proxy.py b/lib/galaxy/workflow/trs_proxy.py index d1fa5fb85fb..6b4c396e9df 100644 --- a/lib/galaxy/workflow/trs_proxy.py +++ b/lib/galaxy/workflow/trs_proxy.py @@ -75,15 +75,15 @@ class TrsProxy: return self._get(trs_api_url) def get_versions(self, trs_server, tool_id, **kwd): - trs_api_url = self._get_tool_api_endpoint(trs_server, tool_id, **kwd) + "/versions" + trs_api_url = f"{self._get_tool_api_endpoint(trs_server, tool_id, **kwd)}/versions" return self._get(trs_api_url) def get_version(self, trs_server, tool_id, version_id, **kwd): - trs_api_url = self._get_tool_api_endpoint(trs_server, tool_id, **kwd) + "/versions/" + version_id + trs_api_url = f"{self._get_tool_api_endpoint(trs_server, tool_id, **kwd)}/versions/{version_id}" return self._get(trs_api_url) def get_version_descriptor(self, trs_server, tool_id, version_id, **kwd): - trs_api_url = self._get_tool_api_endpoint(trs_server, tool_id, **kwd) + "/versions/" + version_id + f"/{GA4GH_GALAXY_DESCRIPTOR}/descriptor" + trs_api_url = f"{self._get_tool_api_endpoint(trs_server, tool_id, **kwd)}/versions/{version_id}/{GA4GH_GALAXY_DESCRIPTOR}/descriptor" return self._get(trs_api_url)["content"] def _quote(self, tool_id, **kwd): @@ -110,10 +110,10 @@ class TrsProxy: def _get_api_endpoint(self, trs_server, **kwd): trs_url = self._server_dict[trs_server]["api_url"] - trs_api_endpoint = trs_url + "/" + "ga4gh/trs/v2/tools" + trs_api_endpoint = f"{trs_url}/ga4gh/trs/v2/tools" return trs_api_endpoint def _get_tool_api_endpoint(self, trs_server, tool_id, **kwd): tool_id = self._quote(tool_id, **kwd) - trs_api_url = self._get_api_endpoint(trs_server, **kwd) + "/" + tool_id + trs_api_url = f"{self._get_api_endpoint(trs_server, **kwd)}/{tool_id}" return trs_api_url diff --git a/lib/galaxy_test/api/test_api_batch.py b/lib/galaxy_test/api/test_api_batch.py index 5f192e4bbdf..cbdbd11139f 100644 --- a/lib/galaxy_test/api/test_api_batch.py +++ b/lib/galaxy_test/api/test_api_batch.py @@ -12,7 +12,7 @@ class ApiBatchTestCase(ApiTestCase): def _with_key(self, url, admin=False): sep = '&' if '?' in url else '?' - return url + sep + 'key=' + self._get_api_key(admin=admin) + return f"{url + sep}key={self._get_api_key(admin=admin)}" def _post_batch(self, batch): data = json.dumps({"batch": batch}) @@ -65,9 +65,9 @@ class ApiBatchTestCase(ApiTestCase): post_data = dict(name='test') create_response = self._post('histories', data=post_data).json() - history_url = '/api/histories/' + create_response['id'] - history_url_with_keys = history_url + '?v=dev&keys=size,non_ready_jobs' - contents_url_with_filters = history_url + '/contents?v=dev&q=deleted&qv=True' + history_url = f"/api/histories/{create_response['id']}" + history_url_with_keys = f"{history_url}?v=dev&keys=size,non_ready_jobs" + contents_url_with_filters = f"{history_url}/contents?v=dev&q=deleted&qv=True" batch = [ dict(url=self._with_key(history_url_with_keys)), dict(url=self._with_key(contents_url_with_filters)), diff --git a/lib/galaxy_test/api/test_dataset_collections.py b/lib/galaxy_test/api/test_dataset_collections.py index ec63e8a6e8f..1356dbf9bd7 100644 --- a/lib/galaxy_test/api/test_dataset_collections.py +++ b/lib/galaxy_test/api/test_dataset_collections.py @@ -347,12 +347,12 @@ class DatasetCollectionApiTestCase(ApiTestCase): hdca, root_contents_url = self._create_collection_contents_pair() # check limit - limited_contents = self._get(root_contents_url + '?limit=1').json() + limited_contents = self._get(f"{root_contents_url}?limit=1").json() assert len(limited_contents) == 1 assert limited_contents[0]['element_index'] == 0 # check offset - offset_contents = self._get(root_contents_url + '?offset=1').json() + offset_contents = self._get(f"{root_contents_url}?offset=1").json() assert len(offset_contents) == 1 assert offset_contents[0]['element_index'] == 1 diff --git a/lib/galaxy_test/api/test_tools.py b/lib/galaxy_test/api/test_tools.py index bc3ea2c1abe..d09df663f74 100644 --- a/lib/galaxy_test/api/test_tools.py +++ b/lib/galaxy_test/api/test_tools.py @@ -720,7 +720,7 @@ class ToolsTestCase(ApiTestCase, TestsTools): self.assertEqual(len(outputs), 1) output1 = outputs[0] output1_content = self.dataset_populator.get_history_dataset_content(history_id, dataset=output1) - self.assertEqual(output1_content.strip(), "Version " + version) + self.assertEqual(output1_content.strip(), f"Version {version}") @skip_without_tool("multiple_versions") @uses_test_history(require_new=False) diff --git a/lib/galaxy_test/base/populators.py b/lib/galaxy_test/base/populators.py index 601404508ad..29ad58e2392 100644 --- a/lib/galaxy_test/base/populators.py +++ b/lib/galaxy_test/base/populators.py @@ -1134,9 +1134,9 @@ class WorkflowPopulator(GalaxyInteractorHttpMixin, BaseWorkflowPopulator, Import ] for i in range(workflow_depth): - link = "cat_" + str(i) + "/out_file1" + link = f"cat_{str(i)}/out_file1" scale_workflow_steps.append( - {"tool_id": "cat", "state": {"input1": self._link(link)}, "label": "cat_" + str(i + 1)} + {"tool_id": "cat", "state": {"input1": self._link(link)}, "label": f"cat_{str(i + 1)}"} ) workflow_dict = { @@ -1156,8 +1156,8 @@ class WorkflowPopulator(GalaxyInteractorHttpMixin, BaseWorkflowPopulator, Import ] for i in range(workflow_depth): - link1 = "cat_" + str(i) + "#out_file1" - link2 = "cat_" + str(i) + "#out_file2" + link1 = f"cat_{str(i)}#out_file1" + link2 = f"cat_{str(i)}#out_file2" scale_workflow_steps.append( {"tool_id": "cat", "state": {"input1": self._link(link1), "input2": self._link(link2)}} ) @@ -1196,7 +1196,7 @@ class WorkflowPopulator(GalaxyInteractorHttpMixin, BaseWorkflowPopulator, Import @staticmethod def _link(link, output_name=None): if output_name is not None: - link = str(link) + "/" + output_name + link = f"{str(link)}/{output_name}" return {"$link": link} @@ -1762,7 +1762,7 @@ class GiHttpMixin: if route.startswith("/api/"): route = route[len("/api/"):] - return self._api_url() + "/" + route + return f"{self._api_url()}/{route}" class GiDatasetPopulator(BaseDatasetPopulator, GiHttpMixin): diff --git a/lib/galaxy_test/driver/driver_util.py b/lib/galaxy_test/driver/driver_util.py index 86156f838b9..c0c6cb71576 100644 --- a/lib/galaxy_test/driver/driver_util.py +++ b/lib/galaxy_test/driver/driver_util.py @@ -397,7 +397,7 @@ def database_conf(db_path, prefix="GALAXY", prefer_template_database=False): if do_template: database_template_parsed = urlparse(database_connection) template_name = database_template_parsed.path[1:] # drop / from /galaxy - actual_db = "gxtest" + ''.join(random.choice(string.ascii_uppercase) for _ in range(10)) + actual_db = f"gxtest{''.join(random.choice(string.ascii_uppercase) for _ in range(10))}" actual_database_parsed = database_template_parsed._replace(path=f"/{actual_db}") database_connection = actual_database_parsed.geturl() if not database_exists(database_connection): diff --git a/lib/galaxy_test/selenium/framework.py b/lib/galaxy_test/selenium/framework.py index 5a4d5dfda42..8c4348422ad 100644 --- a/lib/galaxy_test/selenium/framework.py +++ b/lib/galaxy_test/selenium/framework.py @@ -240,7 +240,7 @@ class TestWithSeleniumMixin(GalaxyTestSeleniumContext, UsesApiTestCaseMixin): try: self.setup_with_driver() except Exception: - dump_test_information(self, self.__class__.__name__ + "_setup") + dump_test_information(self, f"{self.__class__.__name__}_setup") raise def setup_with_driver(self): @@ -544,7 +544,7 @@ class SeleniumSessionGetPostMixin: def _get(self, route, data=None, headers=None, admin=False) -> Response: data = data or {} - full_url = self.selenium_context.build_url("api/" + route, for_selenium=False) + full_url = self.selenium_context.build_url(f"api/{route}", for_selenium=False) cookies = None if admin: full_url = f"{full_url}?key={self._mixin_admin_api_key}" @@ -554,7 +554,7 @@ class SeleniumSessionGetPostMixin: return response def _post(self, route, data=None, files=None, headers=None, admin=False, json: bool = False) -> Response: - full_url = self.selenium_context.build_url("api/" + route, for_selenium=False) + full_url = self.selenium_context.build_url(f"api/{route}", for_selenium=False) if data is None: data = {} @@ -573,7 +573,7 @@ class SeleniumSessionGetPostMixin: def _delete(self, route, data=None, headers=None, admin=False) -> Response: data = data or {} - full_url = self.selenium_context.build_url("api/" + route, for_selenium=False) + full_url = self.selenium_context.build_url(f"api/{route}", for_selenium=False) cookies = None if admin: full_url = f"{full_url}?key={self._mixin_admin_api_key}" @@ -584,7 +584,7 @@ class SeleniumSessionGetPostMixin: def _put(self, route, data=None, headers=None, admin=False) -> Response: data = data or {} - full_url = self.selenium_context.build_url("api/" + route, for_selenium=False) + full_url = self.selenium_context.build_url(f"api/{route}", for_selenium=False) cookies = None if admin: full_url = f"{full_url}?key={self._mixin_admin_api_key}" diff --git a/lib/galaxy_test/selenium/test_history_multi_view.py b/lib/galaxy_test/selenium/test_history_multi_view.py index c5cc1c9a3a7..b5886453c97 100644 --- a/lib/galaxy_test/selenium/test_history_multi_view.py +++ b/lib/galaxy_test/selenium/test_history_multi_view.py @@ -129,7 +129,7 @@ class HistoryMultiViewTestCase(SeleniumTestCase): histories = self.components.multi_history_view.histories.all() assert len(histories) == histories_number # search for history with history_id - assert should_exist == any(history.get_attribute("id") == "history-column-" + history_id for history in histories) + assert should_exist == any(history.get_attribute("id") == f"history-column-{history_id}" for history in histories) def copy_history(self, history_id): self.components.multi_history_view.history_dropdown_btn(history_id=history_id).wait_for_and_click() diff --git a/lib/galaxy_test/selenium/test_library_landing.py b/lib/galaxy_test/selenium/test_library_landing.py index 7d7ef25f783..2b0902db5b7 100644 --- a/lib/galaxy_test/selenium/test_library_landing.py +++ b/lib/galaxy_test/selenium/test_library_landing.py @@ -61,11 +61,11 @@ class LibraryLandingTestCase(SeleniumTestCase): self.wait_for_overlays_cleared() namebase = self._get_random_name(prefix="testsort") - self.libraries_index_create(namebase + " b") + self.libraries_index_create(f"{namebase} b") self.wait_for_overlays_cleared() - self.libraries_index_create(namebase + " a") + self.libraries_index_create(f"{namebase} a") self.wait_for_overlays_cleared() - self.libraries_index_create(namebase + " c") + self.libraries_index_create(f"{namebase} c") self.screenshot("libraries_index") diff --git a/lib/galaxy_test/selenium/test_workflow_editor.py b/lib/galaxy_test/selenium/test_workflow_editor.py index 6e476032a25..70ef7192b10 100644 --- a/lib/galaxy_test/selenium/test_workflow_editor.py +++ b/lib/galaxy_test/selenium/test_workflow_editor.py @@ -549,8 +549,8 @@ steps: def workflow_editor_connect(self, source, sink, screenshot_partial=None): source_id, sink_id = self.workflow_editor_source_sink_terminal_ids(source, sink) - source_element = self.driver.find_element_by_css_selector("#" + source_id) - sink_element = self.driver.find_element_by_css_selector("#" + sink_id) + source_element = self.driver.find_element_by_css_selector(f"#{source_id}") + sink_element = self.driver.find_element_by_css_selector(f"#{sink_id}") ac = self.action_chains() ac = ac.move_to_element(source_element).click_and_hold() diff --git a/lib/tool_shed/managers/groups.py b/lib/tool_shed/managers/groups.py index 45b3104e2f1..d3a5338bbc1 100644 --- a/lib/tool_shed/managers/groups.py +++ b/lib/tool_shed/managers/groups.py @@ -60,7 +60,7 @@ class GroupManager: raise ItemAccessibilityException('Only administrators can create groups.') else: if self.get(trans, name=name): - raise Conflict('Group with the given name already exists. Name: ' + str(name)) + raise Conflict(f"Group with the given name already exists. Name: {str(name)}") # TODO add description field to the model group = trans.app.model.Group(name=name) trans.sa_session.add(group) diff --git a/lib/tool_shed/test/base/twilltestcase.py b/lib/tool_shed/test/base/twilltestcase.py index b4ed4e816ba..ad4916aabcd 100644 --- a/lib/tool_shed/test/base/twilltestcase.py +++ b/lib/tool_shed/test/base/twilltestcase.py @@ -530,7 +530,7 @@ class ShedTwillTestCase(DrivenFunctionalTestCase): def deactivate_repository(self, installed_repository, strings_displayed=None, strings_not_displayed=None): encoded_id = self.security.encode_id(installed_repository.id) api_key = get_admin_api_key() - response = requests.delete(self.galaxy_url + "/api/tool_shed_repositories/" + encoded_id, data={'remove_from_disk': False, 'key': api_key}) + response = requests.delete(f"{self.galaxy_url}/api/tool_shed_repositories/{encoded_id}", data={'remove_from_disk': False, 'key': api_key}) assert response.status_code != 403, response.content def delete_files_from_repository(self, repository, filenames=None, strings_displayed=None, strings_not_displayed=None): @@ -1259,7 +1259,7 @@ class ShedTwillTestCase(DrivenFunctionalTestCase): def reset_installed_repository_metadata(self, repository): encoded_id = self.security.encode_id(repository.id) api_key = get_admin_api_key() - response = requests.post(self.galaxy_url + "/api/tool_shed_repositories/reset_metadata_on_selected_installed_repositories", data={'repository_ids': [encoded_id], 'key': api_key}) + response = requests.post(f"{self.galaxy_url}/api/tool_shed_repositories/reset_metadata_on_selected_installed_repositories", data={'repository_ids': [encoded_id], 'key': api_key}) assert response.status_code != 403, response.content def reset_metadata_on_selected_repositories(self, repository_ids): @@ -1269,7 +1269,7 @@ class ShedTwillTestCase(DrivenFunctionalTestCase): def reset_metadata_on_selected_installed_repositories(self, repository_ids): api_key = get_admin_api_key() - response = requests.post(self.galaxy_url + "/api/tool_shed_repositories/reset_metadata_on_selected_installed_repositories", data={'repository_ids': repository_ids, 'key': api_key}) + response = requests.post(f"{self.galaxy_url}/api/tool_shed_repositories/reset_metadata_on_selected_installed_repositories", data={'repository_ids': repository_ids, 'key': api_key}) assert response.status_code != 403, response.content def reset_repository_metadata(self, repository): @@ -1376,7 +1376,7 @@ class ShedTwillTestCase(DrivenFunctionalTestCase): def uninstall_repository(self, installed_repository, strings_displayed=None, strings_not_displayed=None): encoded_id = self.security.encode_id(installed_repository.id) api_key = get_admin_api_key() - response = requests.delete(self.galaxy_url + "/api/tool_shed_repositories/" + encoded_id, data={'remove_from_disk': True, 'key': api_key}) + response = requests.delete(f"{self.galaxy_url}/api/tool_shed_repositories/{encoded_id}", data={'remove_from_disk': True, 'key': api_key}) assert response.status_code != 403, response.content def update_installed_repository(self, installed_repository, strings_displayed=None, strings_not_displayed=None): @@ -1391,7 +1391,7 @@ class ShedTwillTestCase(DrivenFunctionalTestCase): def update_tool_shed_status(self): api_key = get_admin_api_key() - response = requests.get(self.galaxy_url + "/api/tool_shed_repositories/check_for_updates?key=" + api_key) + response = requests.get(f"{self.galaxy_url}/api/tool_shed_repositories/check_for_updates?key={api_key}") assert response.status_code != 403, response.content def upload_file(self, diff --git a/lib/tool_shed/test/functional/test_0420_citable_urls_for_repositories.py b/lib/tool_shed/test/functional/test_0420_citable_urls_for_repositories.py index 09e77b0fd8f..b9debaf3cd9 100644 --- a/lib/tool_shed/test/functional/test_0420_citable_urls_for_repositories.py +++ b/lib/tool_shed/test/functional/test_0420_citable_urls_for_repositories.py @@ -153,7 +153,7 @@ class TestRepositoryCitableURLs(ShedTwillTestCase): # Since twill does not load the contents of an iframe, we need to check that the iframe has been generated correctly, # then directly load the url that the iframe should be loading and check for the expected strings. # The iframe should point to /repository/view_repository?id= - strings_displayed = ['/repository', 'view_repository', 'id=' + encoded_repository_id] + strings_displayed = ['/repository', 'view_repository', f"id={encoded_repository_id}"] strings_displayed_in_iframe = ['user1', 'filtering_0420', 'Galaxy filtering tool for test 0420', first_changeset_hash] strings_displayed_in_iframe.append('Link to this repository revision:') strings_displayed_in_iframe.append(f'{self.url}/view/user1/filtering_0420/{first_changeset_hash}') @@ -177,7 +177,7 @@ class TestRepositoryCitableURLs(ShedTwillTestCase): # Since twill does not load the contents of an iframe, we need to check that the iframe has been generated correctly, # then directly load the url that the iframe should be loading and check for the expected strings. # The iframe should point to /repository/view_repository?id=&status=error - strings_displayed = ['/repository', 'view_repository', 'id=' + encoded_repository_id] + strings_displayed = ['/repository', 'view_repository', f"id={encoded_repository_id}"] strings_displayed.extend(['The+change+log', 'does+not+include+revision', invalid_changeset_hash, 'status=error']) self.load_citable_url(username='user1', repository_name='filtering_0420', diff --git a/lib/tool_shed/util/admin_util.py b/lib/tool_shed/util/admin_util.py index dea466e101e..79adee0339b 100644 --- a/lib/tool_shed/util/admin_util.py +++ b/lib/tool_shed/util/admin_util.py @@ -890,8 +890,8 @@ class Admin: def name_autocomplete_data(self, trans, q=None, limit=None, timestamp=None): """Return autocomplete data for user emails""" ac_data = "" - for user in trans.sa_session.query(trans.app.model.User).filter_by(deleted=False).filter(func.lower(trans.app.model.User.email).like(q.lower() + "%")): - ac_data = ac_data + user.email + "\n" + for user in trans.sa_session.query(trans.app.model.User).filter_by(deleted=False).filter(func.lower(trans.app.model.User.email).like(f"{q.lower()}%")): + ac_data = f"{ac_data + user.email}\n" return ac_data @web.expose diff --git a/lib/tool_shed/util/shed_index.py b/lib/tool_shed/util/shed_index.py index efe33007f3c..26afd1bc18c 100644 --- a/lib/tool_shed/util/shed_index.py +++ b/lib/tool_shed/util/shed_index.py @@ -120,7 +120,7 @@ def get_repos(sa_session, file_path, hgweb_config_dir, **kwargs): hg_repo = hg.repository(ui.ui(), repo_path.encode('utf-8')) lineage = [] for changeset in hg_repo.changelog: - lineage.append(unicodify(changeset) + ":" + unicodify(hg_repo[changeset])) + lineage.append(f"{unicodify(changeset)}:{unicodify(hg_repo[changeset])}") repo_lineage = str(lineage) # Parse all the tools within repo for a separate index. diff --git a/lib/tool_shed/util/shed_util_common.py b/lib/tool_shed/util/shed_util_common.py index 87c5f60cc69..01487d15831 100644 --- a/lib/tool_shed/util/shed_util_common.py +++ b/lib/tool_shed/util/shed_util_common.py @@ -193,7 +193,7 @@ def get_repository_file_contents(app, file_path, repository_id, is_admin=False): return 'Invalid file path' # Symlink targets are checked by is_path_browsable if os.path.islink(file_path): - safe_str = 'link to: ' + basic_util.to_html_string(os.readlink(file_path)) + safe_str = f"link to: {basic_util.to_html_string(os.readlink(file_path))}" return safe_str elif checkers.is_gzip(file_path): return '
gzip compressed file
' @@ -335,9 +335,9 @@ def handle_email_alerts(app, host, repository, content_alert_str='', new_repo_al if app.config.email_from is not None: email_from = app.config.email_from elif host.split(':')[0] in ['localhost', '127.0.0.1', '0.0.0.0']: - email_from = 'galaxy-no-reply@' + socket.getfqdn() + email_from = f"galaxy-no-reply@{socket.getfqdn()}" else: - email_from = 'galaxy-no-reply@' + host.split(':')[0] + email_from = f"galaxy-no-reply@{host.split(':')[0]}" ctx = repo[repo.changelog.tip()] username = unicodify(ctx.user()) try: @@ -454,7 +454,7 @@ def open_repository_files_folder(app, folder_path, repository_id, is_admin=False is_link = os.path.islink(full_path) path_is_browsable = is_path_browsable(app, full_path, repository_id) if is_link and not path_is_browsable: - log.warning('Valid folder contains a symlink outside of the repository location. Link found in: ' + str(full_path)) + log.warning(f"Valid folder contains a symlink outside of the repository location. Link found in: {str(full_path)}") if filename: if os.path.isdir(full_path) and path_is_browsable: # Append a '/' character so that our jquery dynatree will function properly. diff --git a/lib/tool_shed/webapp/buildapp.py b/lib/tool_shed/webapp/buildapp.py index 9abff46545c..bf176432d68 100644 --- a/lib/tool_shed/webapp/buildapp.py +++ b/lib/tool_shed/webapp/buildapp.py @@ -37,7 +37,7 @@ def add_ui_controllers(webapp, app): for fname in os.listdir(controller_dir): if not fname.startswith("_") and fname.endswith(".py"): name = fname[:-3] - module_name = "tool_shed.webapp.controllers." + name + module_name = f"tool_shed.webapp.controllers.{name}" module = __import__(module_name) for comp in module_name.split(".")[1:]: module = getattr(module, comp) diff --git a/lib/tool_shed/webapp/controllers/user.py b/lib/tool_shed/webapp/controllers/user.py index 8a0a64dd592..df2321ffc00 100644 --- a/lib/tool_shed/webapp/controllers/user.py +++ b/lib/tool_shed/webapp/controllers/user.py @@ -178,7 +178,7 @@ class User(BaseUser): # subscribe user to email list if trans.app.config.smtp_server is None: status = "error" - message = "Now logged in as " + user.email + ". However, subscribing to the mailing list has failed because mail is not configured for this Galaxy instance.
Please contact your local Galaxy administrator." + message = f"Now logged in as {user.email}. However, subscribing to the mailing list has failed because mail is not configured for this Galaxy instance.
Please contact your local Galaxy administrator." else: body = 'Join Mailing list.\n' to = trans.app.config.mailing_join_addr @@ -189,7 +189,7 @@ class User(BaseUser): except Exception: log.exception('Subscribing to the mailing list has failed.') status = "warning" - message = "Now logged in as " + user.email + ". However, subscribing to the mailing list has failed." + message = f"Now logged in as {user.email}. However, subscribing to the mailing list has failed." if status != "error": if not is_admin: # The handle_user_login() method has a call to the history_set_default_permissions() method @@ -243,7 +243,7 @@ class User(BaseUser): token=prt.token, qualified=True) body = PASSWORD_RESET_TEMPLATE % (host, prt.expiration_time.strftime(trans.app.config.pretty_datetime_format), reset_url) - frm = trans.app.config.email_from or 'galaxy-no-reply@' + host + frm = trans.app.config.email_from or f"galaxy-no-reply@{host}" subject = 'Galaxy Password Reset' try: util.send_mail(frm, email, subject, body, trans.app.config) @@ -362,7 +362,7 @@ class User(BaseUser): # The user's private role name must match the user's login ( email ) private_role = trans.app.security_agent.get_private_user_role(user) private_role.name = email - private_role.description = 'Private role for ' + email + private_role.description = f"Private role for {email}" # Change the email itself user.email = email trans.sa_session.add_all((user, private_role)) diff --git a/lib/tool_shed/webapp/framework/middleware/remoteuser.py b/lib/tool_shed/webapp/framework/middleware/remoteuser.py index dd4e35e7626..f0f9db25d36 100644 --- a/lib/tool_shed/webapp/framework/middleware/remoteuser.py +++ b/lib/tool_shed/webapp/framework/middleware/remoteuser.py @@ -91,7 +91,7 @@ class RemoteUser: if 'HTTP_REMOTE_USER' in environ and environ['HTTP_REMOTE_USER'] != '(null)': if not environ['HTTP_REMOTE_USER'].count('@'): if self.maildomain is not None: - environ['HTTP_REMOTE_USER'] += '@' + self.maildomain + environ['HTTP_REMOTE_USER'] += f"@{self.maildomain}" else: title = "Access to this Galaxy tool shed is denied" message = """ diff --git a/lib/tool_shed/webapp/search/repo_search.py b/lib/tool_shed/webapp/search/repo_search.py index d78160df649..fcfb01a3947 100644 --- a/lib/tool_shed/webapp/search/repo_search.py +++ b/lib/tool_shed/webapp/search/repo_search.py @@ -71,10 +71,10 @@ class RepoSearch: :returns results: dictionary containing hits themselves and the hits summary """ - log.debug('raw search query: #' + str(search_term)) + log.debug(f"raw search query: #{str(search_term)}") lower_search_term = search_term.lower() allow_query, search_term_without_filters = self._parse_reserved_filters(lower_search_term) - log.debug('term without filters: #' + str(search_term_without_filters)) + log.debug(f"term without filters: #{str(search_term_without_filters)}") whoosh_index_dir = trans.app.config.whoosh_index_dir index_exists = whoosh.index.exists_in(whoosh_index_dir) @@ -107,12 +107,12 @@ class RepoSearch: user_query = Every('name') sortedby = 'name' else: - user_query = parser.parse('*' + search_term_without_filters + '*') + user_query = parser.parse(f"*{search_term_without_filters}*") sortedby = '' try: hits = searcher.search_page(user_query, page, pagelen=page_size, filter=allow_query, terms=True, sortedby=sortedby) - log.debug('total hits: ' + str(len(hits))) - log.debug('scored hits: ' + str(hits.scored_length())) + log.debug(f"total hits: {str(len(hits))}") + log.debug(f"scored hits: {str(hits.scored_length())}") except ValueError: raise ObjectNotFound('The requested page does not exist.') results = {} @@ -121,7 +121,7 @@ class RepoSearch: results['page_size'] = str(page_size) results['hits'] = [] for hit in hits: - log.debug('matched terms: ' + str(hit.matched_terms())) + log.debug(f"matched terms: {str(hit.matched_terms())}") hit_dict = {} hit_dict['id'] = trans.security.encode_id(hit.get('id')) hit_dict['repo_owner_username'] = hit.get('repo_owner_username') diff --git a/lib/tool_shed/webapp/search/tool_search.py b/lib/tool_shed/webapp/search/tool_search.py index 4df4a19cba4..f325b022683 100644 --- a/lib/tool_shed/webapp/search/tool_search.py +++ b/lib/tool_shed/webapp/search/tool_search.py @@ -61,16 +61,16 @@ class ToolSearch: 'help', 'repo_owner_username'], schema=schema) - user_query = parser.parse('*' + search_term + '*') + user_query = parser.parse(f"*{search_term}*") try: hits = searcher.search_page(user_query, page, pagelen=page_size, terms=True) except ValueError: raise ObjectNotFound('The requested page does not exist.') - log.debug('searching tools for: #' + str(search_term)) - log.debug('total hits: ' + str(len(hits))) - log.debug('scored hits: ' + str(hits.scored_length())) + log.debug(f"searching tools for: #{str(search_term)}") + log.debug(f"total hits: {str(len(hits))}") + log.debug(f"scored hits: {str(hits.scored_length())}") results = {} results['total_results'] = str(len(hits)) results['page'] = str(page) diff --git a/lib/tool_shed/webapp/security/__init__.py b/lib/tool_shed/webapp/security/__init__.py index 96e3be5780c..f794ffad19b 100644 --- a/lib/tool_shed/webapp/security/__init__.py +++ b/lib/tool_shed/webapp/security/__init__.py @@ -124,7 +124,7 @@ class CommunityRBACAgent(RBACAgent): def create_private_user_role(self, user): # Create private role - role = self.model.Role(name=user.email, description='Private Role for ' + user.email, type=self.model.Role.types.PRIVATE) + role = self.model.Role(name=user.email, description=f"Private Role for {user.email}", type=self.model.Role.types.PRIVATE) self.sa_session.add(role) self.sa_session.flush() # Add user to role
' + text + '{text}
' + input.cases[current_case].value + '
{input.cases[current_case].value}
' + str(len(param_values[input.name])) + ' uploaded datasets
{str(len(param_values[input.name]))} uploaded datasets
' + input.value_to_display_text(param_values[input.name]) + '' + upgrade_messages.get(input.name, '') + '
{input.value_to_display_text(param_values[input.name])}{upgrade_messages.get(input.name, '')}