diff --git a/lib/galaxy/actions/admin.py b/lib/galaxy/actions/admin.py index e7eb173092a..1eb65a6b778 100644 --- a/lib/galaxy/actions/admin.py +++ b/lib/galaxy/actions/admin.py @@ -45,7 +45,7 @@ class AdminActions: # If this is a default quota, create the DefaultQuotaAssociation if params.default != 'no': self.app.quota_agent.set_default_quota(params.default, quota) - message = "Default quota '%s' has been created." % quota.name + message = f"Default quota '{quota.name}' has been created." else: # Create the UserQuotaAssociations in_users = [self.sa_session.query(self.app.model.User).get(decode_id(x) if decode_id else x) for x in util.listify(params.in_users)] @@ -113,7 +113,7 @@ class AdminActions: quota.operation = params.operation self.sa_session.add(quota) self.sa_session.flush() - message = "Quota '{}' is now '{}'.".format(quota.name, quota.operation + quota.display_amount) + message = f"Quota '{quota.name}' is now '{quota.operation + quota.display_amount}'." return message def _set_quota_default(self, quota, params): @@ -125,19 +125,19 @@ class AdminActions: message = f"Quota '{quota.name}' is now the default for {params.default} users." else: if quota.default: - message = "Quota '{}' is no longer the default for {} users.".format(quota.name, quota.default[0].type) + message = f"Quota '{quota.name}' is no longer the default for {quota.default[0].type} users." for dqa in quota.default: self.sa_session.delete(dqa) self.sa_session.flush() else: - message = "Quota '%s' is not a default." % quota.name + message = f"Quota '{quota.name}' is not a default." return message def _unset_quota_default(self, quota, params=None): if not quota.default: - raise ActionInputError("Quota '%s' is not a default." % quota.name) + raise ActionInputError(f"Quota '{quota.name}' is not a default.") else: - message = "Quota '{}' is no longer the default for {} users.".format(quota.name, quota.default[0].type) + message = f"Quota '{quota.name}' is no longer the default for {quota.default[0].type} users." for dqa in quota.default: self.sa_session.delete(dqa) self.sa_session.flush() @@ -150,9 +150,9 @@ class AdminActions: if q.default: names.append(q.name) if len(names) == 1: - raise ActionInputError("Quota '%s' is a default, please unset it as a default before deleting it." % (names[0])) + 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 @@ -169,9 +169,9 @@ class AdminActions: if not q.deleted: names.append(q.name) if len(names) == 1: - raise ActionInputError("Quota '%s' has not been deleted, so it cannot be undeleted." % (names[0])) + 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 @@ -194,9 +194,9 @@ class AdminActions: if not q.deleted: names.append(q.name) if len(names) == 1: - raise ActionInputError("Quota '%s' has not been deleted, so it cannot be purged." % (names[0])) + 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/actions/library.py b/lib/galaxy/actions/library.py index bd3d6f009d9..ef371cb7cc9 100644 --- a/lib/galaxy/actions/library.py +++ b/lib/galaxy/actions/library.py @@ -169,11 +169,11 @@ class LibraryActions: if os.path.isfile(path): files.append(path) except Exception as e: - message = "Unable to get file list for configured {}, error: {}".format(import_dir_desc, util.unicodify(e)) + message = f"Unable to get file list for configured {import_dir_desc}, error: {util.unicodify(e)}" response_code = 500 return None, response_code, message if not files: - message = "The directory '%s' contains no valid files" % full_dir + message = f"The directory '{full_dir}' contains no valid files" response_code = 400 return None, response_code, message return files, None, None @@ -296,15 +296,15 @@ class LibraryActions: if isinstance(item, trans.model.HistoryDatasetAssociation): # Make sure the user has the DATASET_ACCESS permission on the history_dataset_association. if not item: - message = "Invalid history dataset (%s) specified." % escape(str(item)) + message = f"Invalid history dataset ({escape(str(item))}) specified." can_access = False elif not trans.app.security_agent.can_access_dataset(current_user_roles, item.dataset) and item.history.user == trans.user: - message = "You do not have permission to access the history dataset with id (%s)." % str(item.id) + message = f"You do not have permission to access the history dataset with id ({str(item.id)})." can_access = False else: # Make sure the user has the LIBRARY_ACCESS permission on the library item. if not item: - message = "Invalid library item (%s) specified." % escape(str(item)) + message = f"Invalid library item ({escape(str(item))}) specified." can_access = False elif not (is_admin or trans.app.security_agent.can_access_library_item(current_user_roles, item, trans.user)): if isinstance(item, trans.model.Library): @@ -313,7 +313,7 @@ class LibraryActions: item_type = 'folder' else: item_type = '(unknown item type)' - message = "You do not have permission to access the {} with id ({}).".format(escape(item_type), str(item.id)) + message = f"You do not have permission to access the {escape(item_type)} with id ({str(item.id)})." can_access = False if not can_access: return 400, message @@ -321,5 +321,5 @@ class LibraryActions: def _check_add(self, trans, is_admin, item, current_user_roles): # Deny access if the user is not an admin and does not have the LIBRARY_ADD permission. if not (is_admin or trans.app.security_agent.can_add_library_item(current_user_roles, item)): - message = "You are not authorized to add an item to (%s)." % escape(item.name) + message = f"You are not authorized to add an item to ({escape(item.name)})." return 403, message diff --git a/lib/galaxy/app.py b/lib/galaxy/app.py index fa6b7e6b62a..ca604776c54 100644 --- a/lib/galaxy/app.py +++ b/lib/galaxy/app.py @@ -350,7 +350,7 @@ class UniverseApplication(StructuredApp, GalaxyManagerApplication): self.url_for = url_for self.server_starttime = int(time.time()) # used for cachebusting - log.info("Galaxy app startup finished %s" % startup_timer) + log.info(f"Galaxy app startup finished {startup_timer}") def _shutdown_queue_worker(self): self.queue_worker.shutdown() diff --git a/lib/galaxy/auth/__init__.py b/lib/galaxy/auth/__init__.py index f7976ea32a1..064ae8af2af 100644 --- a/lib/galaxy/auth/__init__.py +++ b/lib/galaxy/auth/__init__.py @@ -56,7 +56,7 @@ class AuthManager: } for provider, options in self.active_authenticators(email, username, password): if provider is None: - log.debug("Unable to find module: %s" % options) + log.debug(f"Unable to find module: {options}") else: options['no_password_check'] = no_password_check auth_results = provider.authenticate(email, username, password, options) @@ -76,7 +76,7 @@ class AuthManager: """Checks the username/email and password using auth providers.""" for provider, options in self.active_authenticators(user.email, user.username, password): if provider is None: - log.debug("Unable to find module: %s" % options) + log.debug(f"Unable to find module: {options}") else: auth_result = provider.authenticate_user(user, password, options) if auth_result is True: @@ -91,7 +91,7 @@ class AuthManager: """ for provider, options in self.active_authenticators(user.email, user.username, current_password): if provider is None: - log.debug("Unable to find module: %s" % options) + log.debug(f"Unable to find module: {options}") else: auth_result = provider.authenticate_user(user, current_password, options) if auth_result is True: diff --git a/lib/galaxy/auth/providers/alwaysreject.py b/lib/galaxy/auth/providers/alwaysreject.py index 9e5ec450389..e39990ae977 100644 --- a/lib/galaxy/auth/providers/alwaysreject.py +++ b/lib/galaxy/auth/providers/alwaysreject.py @@ -26,7 +26,7 @@ class AlwaysReject(AuthProvider): """ See abstract method documentation. """ - log.debug("User: %s, ALWAYSREJECT: None" % (user.id if options['redact_username_in_logs'] else user.email)) + log.debug(f"User: {user.id if options['redact_username_in_logs'] else user.email}, ALWAYSREJECT: None") return None diff --git a/lib/galaxy/auth/providers/ldap_ad.py b/lib/galaxy/auth/providers/ldap_ad.py index 91088748f86..dac936f7386 100644 --- a/lib/galaxy/auth/providers/ldap_ad.py +++ b/lib/galaxy/auth/providers/ldap_ad.py @@ -25,7 +25,7 @@ log = logging.getLogger(__name__) def _get_subs(d, k, params): if k not in d or not d[k]: - raise ConfigurationError("Missing '%s' parameter in LDAP options" % k) + raise ConfigurationError(f"Missing '{k}' parameter in LDAP options") return str(d[k]).format(**params) diff --git a/lib/galaxy/auth/providers/localdb.py b/lib/galaxy/auth/providers/localdb.py index 61095352780..d17d865a7dc 100644 --- a/lib/galaxy/auth/providers/localdb.py +++ b/lib/galaxy/auth/providers/localdb.py @@ -25,7 +25,7 @@ class LocalDB(AuthProvider): See abstract method documentation. """ user_ok = user.check_password(password) - log.debug("User: {}, LOCALDB: {}".format(user.id if options['redact_username_in_logs'] else user.email, user_ok)) + log.debug(f"User: {user.id if options['redact_username_in_logs'] else user.email}, LOCALDB: {user_ok}") return user_ok diff --git a/lib/galaxy/auth/providers/pam_auth.py b/lib/galaxy/auth/providers/pam_auth.py index 4037d6d91f0..69a56186935 100644 --- a/lib/galaxy/auth/providers/pam_auth.py +++ b/lib/galaxy/auth/providers/pam_auth.py @@ -64,7 +64,7 @@ class PAM(AuthProvider): auto_register_email = None force_fail = False if not options['redact_username_in_logs']: - log.debug("use username: {} use email {} email {} username {}".format(options.get('login-use-username'), options.get('login-use-email', False), email, username)) + log.debug(f"use username: {options.get('login-use-username')} use email {options.get('login-use-email', False)} email {email} username {username}") # check email based login first because if email exists in Galaxy DB # we will be given the "public name" as username if string_as_bool(options.get('login-use-email', False)) and email is not None: @@ -95,7 +95,7 @@ class PAM(AuthProvider): elif options.get('maildomain', None) is not None: # we can register a user with this username and mail domain # if auto registration is enabled - auto_register_email = '{}@{}'.format(username, options['maildomain']) + auto_register_email = f"{username}@{options['maildomain']}" auto_register_username = username else: log.debug('PAM authenticate: username login selected but no username provided') @@ -142,10 +142,10 @@ class PAM(AuthProvider): authenticated = p_auth.authenticate(pam_username, password, service=pam_service) if authenticated: - log.debug('PAM authentication successful for {}'.format('redacted' if options['redact_username_in_logs'] else pam_username)) + log.debug(f"PAM authentication successful for {'redacted' if options['redact_username_in_logs'] else pam_username}") return True, auto_register_email, auto_register_username else: - log.debug('PAM authentication failed for {}'.format('redacted' if options['redact_username_in_logs'] else pam_username)) + log.debug(f"PAM authentication failed for {'redacted' if options['redact_username_in_logs'] else pam_username}") return False, '', '' def authenticate_user(self, user, password, options): diff --git a/lib/galaxy/auth/util.py b/lib/galaxy/auth/util.py index 09ad3e8d53d..7f9f0f2dd1b 100644 --- a/lib/galaxy/auth/util.py +++ b/lib/galaxy/auth/util.py @@ -47,7 +47,7 @@ def get_authenticators(auth_config_file, auth_config_file_set): type_elem_text = auth_elem.find('type').text plugin_class = __plugins_dict.get(type_elem_text) if not plugin_class: - raise Exception("Authenticator type '{}' not recognized, should be one of {}".format(type_elem_text, ', '.join(__plugins_dict))) + raise Exception(f"Authenticator type '{type_elem_text}' not recognized, should be one of {', '.join(__plugins_dict)}") plugin = plugin_class() # check filterelem diff --git a/lib/galaxy/authnz/custos_authnz.py b/lib/galaxy/authnz/custos_authnz.py index 92c3074becd..33b035bbf50 100644 --- a/lib/galaxy/authnz/custos_authnz.py +++ b/lib/galaxy/authnz/custos_authnz.py @@ -110,11 +110,11 @@ class CustosAuthnz(IdentityProvider): and len(trans.app.auth_manager.authenticators) == 0): user = existing_user else: - message = "There already exists a user with email %s. To associate this external login, you must first be logged in as that existing account." % email + message = f"There already exists a user with email {email}. To associate this external login, you must first be logged in as that existing account." 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, @@ -180,7 +180,7 @@ class CustosAuthnz(IdentityProvider): # Find CustosAuthnzToken record for this provider (should only be one) provider_tokens = [token for token in user.custos_auth if token.provider == self.config["provider"]] if len(provider_tokens) == 0: - raise Exception("User is not associated with provider {}".format(self.config["provider"])) + raise Exception(f"User is not associated with provider {self.config['provider']}") if len(provider_tokens) > 1: for idx, token in enumerate(provider_tokens): id_token_decoded = self._decode_token_no_signature(token.id_token) @@ -190,13 +190,13 @@ class CustosAuthnz(IdentityProvider): trans.sa_session.flush() return True, "", disconnect_redirect_url except Exception as e: - return False, "Failed to disconnect provider {}: {}".format(provider, util.unicodify(e)), None + return False, f"Failed to disconnect provider {provider}: {util.unicodify(e)}", None def logout(self, trans, post_logout_redirect_url=None): try: redirect_url = self.config['end_session_endpoint'] if post_logout_redirect_url is not None: - redirect_url += "?redirect_uri={}".format(quote(post_logout_redirect_url)) + redirect_url += f"?redirect_uri={quote(post_logout_redirect_url)}" return redirect_url except Exception as e: log.error("Failed to generate logout redirect_url", exc_info=e) @@ -224,12 +224,12 @@ 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, authorization_response=trans.request.url, - headers={"Authorization": "Basic %s" % util.unicodify(base64.b64encode(util.smart_str(clientIdAndSec)))}, # for custos + headers={"Authorization": f"Basic {util.unicodify(base64.b64encode(util.smart_str(clientIdAndSec)))}"}, # for custos verify=self._get_verify_param()) def _get_userinfo(self, oauth2_session): @@ -263,9 +263,9 @@ 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": "Basic %s" % util.unicodify(base64.b64encode(util.smart_str(clientIdAndSec)))}, + headers={"Authorization": f"Basic {util.unicodify(base64.b64encode(util.smart_str(clientIdAndSec)))}"}, verify=False, params={'client_id': self.config['client_id']}) well_known_oidc_config = eps.json() self._load_well_known_oidc_config(well_known_oidc_config) @@ -276,9 +276,9 @@ 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": "Basic %s" % util.unicodify(base64.b64encode(util.smart_str(clientIdAndSec)))}, + headers={"Authorization": f"Basic {util.unicodify(base64.b64encode(util.smart_str(clientIdAndSec)))}"}, verify=False, params={'client_id': self.config['client_id']}) credentials = creds.json() self.config['iam_client_secret'] = credentials['iam_client_secret'] diff --git a/lib/galaxy/authnz/psa_authnz.py b/lib/galaxy/authnz/psa_authnz.py index 00223a60404..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, @@ -355,7 +355,7 @@ def verify(strategy=None, response=None, details=None, **kwargs): result = requests.post( f"https://iam.googleapis.com/v1/projects/-/serviceAccounts/{endpoint}:getIamPolicy", headers={ - 'Authorization': 'Bearer {}'.format(response.get("access_token")), + 'Authorization': f"Bearer {response.get('access_token')}", 'Accept': 'application/json'}) res = json.loads(result.content) if result.status_code == requests.codes.ok: diff --git a/lib/galaxy/celery/tasks.py b/lib/galaxy/celery/tasks.py index 878c080f64b..a70a27d641b 100644 --- a/lib/galaxy/celery/tasks.py +++ b/lib/galaxy/celery/tasks.py @@ -33,7 +33,7 @@ def recalculate_user_disk_usage(session: scoped_session, user_id=None): user.calculate_and_set_disk_usage() log.info(f"New user disk usage is {user.disk_usage}") else: - log.error("Recalculate user disk usage task failed, user %s not found" % user_id) + log.error(f"Recalculate user disk usage task failed, user {user_id} not found") else: log.error("Recalculate user disk usage task received without user_id.") diff --git a/lib/galaxy/config/__init__.py b/lib/galaxy/config/__init__.py index 1134db7e5d6..25e714ff7d6 100644 --- a/lib/galaxy/config/__init__.py +++ b/lib/galaxy/config/__init__.py @@ -176,7 +176,7 @@ class BaseAppConfiguration: # NOTE: This will check all supplied keyword arguments, including those not in the schema. # To check only schema options, change the line below to `if property not in self._raw_config:` if key not in self._raw_config: - log.warning("Configuration option does not exist: '%s'" % key) + log.warning(f"Configuration option does not exist: '{key}'") return key in self._kwargs def resolve_path(self, path): @@ -257,7 +257,7 @@ class BaseAppConfiguration: for key in self.add_sample_file_to_defaults: if not self.is_set(key): defaults = listify(getattr(self, key), do_strip=True) - sample = '%s.sample' % defaults[-1] # if there are multiple defaults, use last as template + sample = f'{defaults[-1]}.sample' # if there are multiple defaults, use last as template sample = self._in_sample_dir(sample) # resolve w.r.t sample_dir defaults.append(sample) setattr(self, key, defaults) @@ -356,7 +356,7 @@ class BaseAppConfiguration: if not hasattr(self, key): setattr(self, key, value) elif key not in base_configs: - raise ConfigurationError("Attempting to override existing attribute '%s'" % key) + raise ConfigurationError(f"Attempting to override existing attribute '{key}'") def _resolve_paths(self): @@ -486,7 +486,7 @@ class CommonConfigurationMixin: try: os.makedirs(path) except Exception as e: - raise ConfigurationError("Unable to create missing directory: {}\n{}".format(path, unicodify(e))) + raise ConfigurationError(f"Unable to create missing directory: {path}\n{unicodify(e)}") class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin): @@ -581,7 +581,7 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin): self.check_migrate_databases = kwargs.get('check_migrate_databases', True) if not self.database_connection: # Provide default if not supplied by user db_path = self._in_data_dir('universe.sqlite') - self.database_connection = 'sqlite:///%s?isolation_level=IMMEDIATE' % db_path + self.database_connection = f'sqlite:///{db_path}?isolation_level=IMMEDIATE' self.database_engine_options = get_database_engine_options(kwargs) self.database_create_tables = string_as_bool(kwargs.get('database_create_tables', 'True')) self.database_encoding = kwargs.get('database_encoding') # Create new databases with this encoding @@ -815,16 +815,16 @@ 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 = "sqlalchemy+sqlite:///%s?isolation_level=IMMEDIATE" % self._in_data_dir("control.sqlite") + 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) try: with open(self.user_preferences_extra_conf_path) as stream: self.user_preferences_extra = yaml.safe_load(stream) except Exception: if self.is_set('user_preferences_extra_conf_path'): - log.warning('Config file (%s) could not be found or is malformed.' % self.user_preferences_extra_conf_path) + log.warning(f'Config file ({self.user_preferences_extra_conf_path}) could not be found or is malformed.') self.user_preferences_extra = {'preferences': {}} # Experimental: This will not be enabled by default and will hide @@ -840,7 +840,7 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin): ie_dirs = self.interactive_environment_plugins_directory self.gie_dirs = [d.strip() for d in (ie_dirs.split(",") if ie_dirs else [])] if ie_dirs: - self.visualization_plugins_directory += ",%s" % ie_dirs + self.visualization_plugins_directory += f",{ie_dirs}" self.proxy_session_map = self.dynamic_proxy_session_map self.manage_dynamic_proxy = self.dynamic_proxy_manage # Set to false if being launched externally @@ -991,14 +991,14 @@ class GalaxyAppConfiguration(BaseAppConfiguration, CommonConfigurationMixin): tool_configs = self.tool_configs for path in tool_configs: if not os.path.exists(path) and path not in (self.shed_tool_config_file, self.migrated_tools_config): - raise ConfigurationError("Tool config file not found: %s" % path) + raise ConfigurationError(f"Tool config file not found: {path}") for datatypes_config in listify(self.datatypes_config): if not os.path.isfile(datatypes_config): - raise ConfigurationError("Datatypes config file not found: %s" % datatypes_config) + raise ConfigurationError(f"Datatypes config file not found: {datatypes_config}") # Check for deprecated options. for key in self.config_dict.keys(): if key in self.deprecated_options: - log.warning("Config option '%s' is deprecated and will be removed in a future release. Please consult the latest version of the sample configuration file." % key) + log.warning(f"Config option '{key}' is deprecated and will be removed in a future release. Please consult the latest version of the sample configuration file.") @staticmethod def _parse_allowed_origin_hostnames(allowed_origin_hostnames): @@ -1033,7 +1033,7 @@ def reload_config_options(current_config): if current_config._raw_config[option] != modified_config[option]: current_config._raw_config[option] = modified_config[option] setattr(current_config, option, modified_config[option]) - log.info('Reloaded %s' % option) + log.info(f'Reloaded {option}') def get_database_engine_options(kwargs, model_prefix=''): @@ -1052,7 +1052,7 @@ def get_database_engine_options(kwargs, model_prefix=''): 'pool_threadlocal': string_as_bool, 'server_side_cursors': string_as_bool } - prefix = "%sdatabase_engine_option_" % model_prefix + prefix = f"{model_prefix}database_engine_option_" prefix_len = len(prefix) rval = {} for key, value in kwargs.items(): @@ -1306,7 +1306,7 @@ class ConfiguresGalaxyMixin: else: from galaxy.model.tool_shed_install import mapping as install_mapping install_db_url = self.config.install_database_connection - log.info("Install database using its own connection %s" % install_db_url) + log.info(f"Install database using its own connection {install_db_url}") self.install_model = install_mapping.init(install_db_url, install_database_options) diff --git a/lib/galaxy/config/config_manage.py b/lib/galaxy/config/config_manage.py index da8c5bbf0ce..309cebc5200 100644 --- a/lib/galaxy/config/config_manage.py +++ b/lib/galaxy/config/config_manage.py @@ -201,29 +201,29 @@ class _OptionAction: class _DeprecatedAction(_OptionAction): def lint(self, args, app_desc, key, value): - print("Option [%s] has been deprecated, this will likely be dropped in future releases of Galaxy." % key) + print(f"Option [{key}] has been deprecated, this will likely be dropped in future releases of Galaxy.") class _DeprecatedAndDroppedAction(_OptionAction): def converted(self, args, app_desc, key, value): - print("Option [%s] has been deprecated and dropped. It is not included in converted configuration." % key) + print(f"Option [{key}] has been deprecated and dropped. It is not included in converted configuration.") return DROP_OPTION_VALUE def lint(self, args, app_desc, key, value): - print("Option [%s] has been deprecated. Option should be dropped without replacement." % key) + print(f"Option [{key}] has been deprecated. Option should be dropped without replacement.") class _PasteAppFactoryAction(_OptionAction): def converted(self, args, app_desc, key, value): if value not in app_desc.expected_app_factories: - raise Exception("Ending convert process - unknown paste factory encountered [%s]" % value) + raise Exception(f"Ending convert process - unknown paste factory encountered [{value}]") return DROP_OPTION_VALUE def lint(self, args, app_desc, key, value): if value not in app_desc.expected_app_factories: - print("Problem - unknown paste app factory encountered [%s]" % value) + print(f"Problem - unknown paste app factory encountered [{value}]") class _ProductionUnsafe(_OptionAction): @@ -409,7 +409,7 @@ def _to_rst(args, app_desc, heading_level="~"): def _write_option_rst(args, rst, key, heading_level, option_value): - title = "``%s``" % key + title = f"``{key}``" heading = heading_level * len(title) rst.write(f"{heading}\n{title}\n{heading}\n\n") option, value = _parse_option_value(option_value) @@ -426,9 +426,9 @@ def _write_option_rst(args, rst, key, heading_level, option_value): default = "false" elif default == "": default = '""' - rst.write(":Default: ``%s``\n" % default) + rst.write(f":Default: ``{default}``\n") if type: - rst.write(":Type: %s\n" % type) + rst.write(f":Type: {type}\n") rst.write("\n\n") @@ -513,7 +513,7 @@ def _find_app_options_from_config_parser(p): def _lint(args, app_desc): path = _find_config(args, app_desc) if not os.path.exists(path): - raise Exception("Expected configuration file [%s] not found." % path) + raise Exception(f"Expected configuration file [{path}] not found.") app_items = _find_app_options(app_desc, path) for key, value in app_items.items(): option_action = OPTION_ACTIONS.get(key) @@ -564,7 +564,7 @@ class GzipFilter: def _run_conversion(args, app_desc): ini_config = _find_config(args, app_desc) if ini_config and not _is_ini(ini_config): - _warn("Cannot convert YAML file %s, this option is only for ini config files." % ini_config) + _warn(f"Cannot convert YAML file {ini_config}, this option is only for ini config files.") sys.exit(1) elif not ini_config: _warn("Failed to find a config to convert - exiting without changes.") @@ -613,7 +613,7 @@ def _run_conversion(args, app_desc): if value in filters: applied_filters.append(filters[value]) else: - _warn("Unknown filter found [%s], exiting..." % value) + _warn(f"Unknown filter found [{value}], exiting...") sys.exit(1) uwsgi_dict = _server_paste_to_uwsgi(app_desc, server_config, applied_filters) @@ -656,7 +656,7 @@ def _is_ini(path): def _replace_file(args, f, app_desc, from_path, to_path): _write_to_file(args, f, to_path) - backup_path = "%s.backup" % from_path + backup_path = f"{from_path}.backup" print(f"Moving [{from_path}] to [{backup_path}]") if args.dry_run: print("... skipping because --dry-run is enabled.") @@ -704,7 +704,7 @@ def _write_to_file(args, f, path): print(f"Overwriting {path} with the following contents:\n{contents_indented}") print("... skipping because --dry-run is enabled.") else: - print("Overwriting %s" % path) + print(f"Overwriting {path}") safe_makedirs(os.path.dirname(path)) with open(path, "w") as to_f: to_f.write(contents) @@ -736,7 +736,7 @@ def _write_section(args, f, section_header, section_dict, uwsgi_hack=False): def _write_header(f, section_header): - f.write("%s:\n\n" % section_header) + f.write(f"{section_header}:\n\n") def _write_option(args, f, key, option_value, as_comment=False, uwsgi_hack=False): @@ -756,7 +756,7 @@ def _write_option(args, f, key, option_value, as_comment=False, uwsgi_hack=False key_val_str = yaml.dump({key: value}, width=float("inf")).lstrip("{").rstrip("\n}") lines = f"{comment}{as_comment_str}{key_val_str}" lines_idented = "\n".join(f" {line}" for line in lines.split("\n")) - f.write("%s\n\n" % lines_idented) + f.write(f"{lines_idented}\n\n") def _parse_option_value(option_value): @@ -807,7 +807,7 @@ def _server_paste_to_uwsgi(app_desc, server_config, applied_filters): def _warn(message): - print("WARNING: %s" % message) + print(f"WARNING: {message}") def _get_option_desc(option): diff --git a/lib/galaxy/config/script.py b/lib/galaxy/config/script.py index b8ce2e46ba5..ec44e7d7a2d 100644 --- a/lib/galaxy/config/script.py +++ b/lib/galaxy/config/script.py @@ -90,7 +90,7 @@ def main(argv=None): if not os.path.exists(directory): os.makedirs(directory) - print("Bootstrapping Galaxy configuration into directory %s" % relative_config_dir) + print(f"Bootstrapping Galaxy configuration into directory {relative_config_dir}") _handle_galaxy_yml(args, config_dir, data_dir) _handle_install(args, dependencies) _print_config_summary(args, mode, relative_config_dir) @@ -104,7 +104,7 @@ def _print_config_summary(args, mode, relative_config_dir): def _print_galaxy_yml_info(args, mode): print(" - galaxy.yml created, update to configure Galaxy.") - print(" * Target web server %s" % mode) + print(f" * Target web server {mode}") if args.host == DEFAULT_HOST: print(" * Binding to host localhost, remote clients will not be able to connect.") elif _determine_host(args) == "0.0.0.0": @@ -117,7 +117,7 @@ def _print_galaxy_run(mode): if mode.startswith("uwsgi"): print(" uwsgi --yaml galaxy.yml") else: - raise Exception("Unknown mode: %s" % mode) + raise Exception(f"Unknown mode: {mode}") def _determine_mode(args): @@ -178,7 +178,7 @@ def _handle_install(args, dependencies): def _check_file(path, force): if os.path.exists(path) and not force: - print("File %s exists, exiting. Run with --force to replace configuration." % path, file=sys.stderr) + print(f"File {path} exists, exiting. Run with --force to replace configuration.", file=sys.stderr) sys.exit(1) diff --git a/lib/galaxy/containers/__init__.py b/lib/galaxy/containers/__init__.py index ac416914177..ffb9c9e25c8 100644 --- a/lib/galaxy/containers/__init__.py +++ b/lib/galaxy/containers/__init__.py @@ -45,7 +45,7 @@ class ContainerVolume(metaclass=ABCMeta): self.host_path = host_path self.mode = mode if mode and not self.mode_is_valid: - raise ValueError("Invalid container volume mode: %s" % mode) + raise ValueError(f"Invalid container volume mode: {mode}") @abstractmethod def from_str(cls, as_str): @@ -205,7 +205,7 @@ class ContainerInterface(metaclass=ABCMeta): return opttype def _guess_kwopt_flag(self, opt): - return '--%s' % opt.replace('_', '-') + return f"--{opt.replace('_', '-')}" def _stringify_kwopts(self, kwopts): opts = [] @@ -219,25 +219,25 @@ 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): """ """ - return '{flag}={value}'.format(flag=flag, value=str(val).lower()) + return f'{flag}={str(val).lower()}' def _stringify_kwopt_string(self, flag, val): """ """ - return '{flag} {value}'.format(flag=flag, value=shlex.quote(str(val))) + return f'{flag} {shlex.quote(str(val))}' def _stringify_kwopt_list(self, flag, val): """ """ if isinstance(val, str): return self._stringify_kwopt_string(flag, val) - return ' '.join('{flag} {value}'.format(flag=flag, value=shlex.quote(str(v))) for v in val) + return ' '.join(f'{flag} {shlex.quote(str(v))}' for v in val) def _stringify_kwopt_list_of_kvpairs(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(), @@ -346,7 +346,7 @@ def build_container_interfaces(containers_config_file, containers_conf=None): interfaces = {} for k, conf in containers_conf.items(): container_type = conf.get('type', DEFAULT_CONTAINER_TYPE) - assert container_type in interface_classes, "unknown container interface type: %s" % container_type + assert container_type in interface_classes, f"unknown container interface type: {container_type}" interfaces[k] = interface_classes[container_type](conf, k, containers_config_file) return interfaces diff --git a/lib/galaxy/containers/docker.py b/lib/galaxy/containers/docker.py index 7b1d23d8594..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) @@ -198,7 +198,7 @@ class DockerCLIInterface(DockerInterface): try: return self._run_docker(subcommand='inspect', args=container_id)[0] except (IndexError, ContainerCLIError) as exc: - msg = "Invalid container id: %s" % container_id + msg = f"Invalid container id: {container_id}" if exc.stdout == '[]' and exc.stderr == f'Error: no such object: {container_id}': log.warning(msg) return [] @@ -210,7 +210,7 @@ class DockerCLIInterface(DockerInterface): try: return self._run_docker(subcommand='image inspect', args=image)[0] except (IndexError, ContainerCLIError) as exc: - msg = "%s not pulled, cannot get digest" % image + msg = f"{image} not pulled, cannot get digest" if exc.stdout == '[]' and exc.stderr == f'Error: no such image: {image}': log.warning(msg, image) return [] @@ -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] @@ -585,10 +585,10 @@ class DockerAPIInterface(DockerInterface): try: return self._client.inspect_container(container_id) except docker.errors.NotFound: - raise ContainerNotFound("Invalid container id: %s" % container_id, container_id=container_id) + raise ContainerNotFound(f"Invalid container id: {container_id}", container_id=container_id) def image_inspect(self, image): try: return self._client.inspect_image(image) except docker.errors.NotFound: - raise ContainerImageNotFound("%s not pulled, cannot get digest" % image, image=image) + raise ContainerImageNotFound(f"{image} not pulled, cannot get digest", image=image) diff --git a/lib/galaxy/containers/docker_model.py b/lib/galaxy/containers/docker_model.py index 65c9cabeca1..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__) @@ -85,7 +85,7 @@ class DockerVolume(ContainerVolume): Docker volume syntax. """ if not as_str: - raise ValueError("Failed to parse Docker volume from %s" % as_str) + raise ValueError(f"Failed to parse Docker volume from {as_str}") parts = as_str.split(":", 2) kwds = dict(host_path=parts[0]) if len(parts) == 1: @@ -109,7 +109,7 @@ class DockerVolume(ContainerVolume): volume_for_cmd_line = shlex.quote(volume_str) else: # e.g. $_GALAXY_JOB_TMP_DIR:$_GALAXY_JOB_TMP_DIR:rw so don't single quote. - volume_for_cmd_line = '"%s"' % volume_str + volume_for_cmd_line = f'"{volume_str}"' return volume_for_cmd_line def to_native(self): @@ -406,7 +406,7 @@ class DockerServiceConstraint: if len(t[0]) < len(constraint[0]): constraint = t if constraint[0] == constraint_str: - raise Exception('Unable to parse constraint string: %s' % constraint_str) + raise Exception(f'Unable to parse constraint string: {constraint_str}') return [x.strip() for x in constraint] @classmethod @@ -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/annotation.py b/lib/galaxy/datatypes/annotation.py index 64ed7220c91..98f14d1959e 100644 --- a/lib/galaxy/datatypes/annotation.py +++ b/lib/galaxy/datatypes/annotation.py @@ -26,7 +26,7 @@ class SnapHmm(Text): try: return dataset.peek except Exception: - return "SNAP HMM model (%s)" % (nice_size(dataset.get_size())) + return f"SNAP HMM model ({nice_size(dataset.get_size())})" def sniff_prefix(self, file_prefix): """ @@ -55,7 +55,7 @@ class Augustus(CompressedArchive): try: return dataset.peek except Exception: - return "Augustus model (%s)" % (nice_size(dataset.get_size())) + return f"Augustus model ({nice_size(dataset.get_size())})" def sniff(self, filename): """ diff --git a/lib/galaxy/datatypes/anvio.py b/lib/galaxy/datatypes/anvio.py index 6825be459e0..f88e9e0c788 100644 --- a/lib/galaxy/datatypes/anvio.py +++ b/lib/galaxy/datatypes/anvio.py @@ -28,7 +28,7 @@ class AnvioComposite(Html): cannot rename the datasets here - they come with the default unfortunately """ defined_files = self.get_composite_files(dataset=dataset).items() - rval = ["
%s