diff --git a/coldfront/core/allocation/admin.py b/coldfront/core/allocation/admin.py
index 972396858b..f48c8de302 100644
--- a/coldfront/core/allocation/admin.py
+++ b/coldfront/core/allocation/admin.py
@@ -246,11 +246,7 @@ def allocation_status(self, obj):
return obj.allocation.status
def pi(self, obj):
- return "{} {} ({})".format(
- obj.allocation.project.pi.first_name,
- obj.allocation.project.pi.last_name,
- obj.allocation.project.pi.username,
- )
+ return f"{obj.allocation.project.pi.first_name} {obj.allocation.project.pi.last_name} ({obj.allocation.project.pi.username})"
def project(self, obj):
return textwrap.shorten(obj.allocation.project.title, width=50)
@@ -330,7 +326,7 @@ def allocation_status(self, obj):
return obj.allocation.status
def user_info(self, obj):
- return "{} {} ({})".format(obj.user.first_name, obj.user.last_name, obj.user.username)
+ return f"{obj.user.first_name} {obj.user.last_name} ({obj.user.username})"
def resource(self, obj):
return obj.allocation.resources.first()
diff --git a/coldfront/core/allocation/forms.py b/coldfront/core/allocation/forms.py
index 8068ba43a1..88957aa5fe 100644
--- a/coldfront/core/allocation/forms.py
+++ b/coldfront/core/allocation/forms.py
@@ -45,7 +45,10 @@ def __init__(self, request_user, project_pk, *args, **kwargs):
user_query_set = user_query_set.exclude(user=project_obj.pi)
if user_query_set:
self.fields["users"].choices = (
- (user.user.username, "%s %s (%s)" % (user.user.first_name, user.user.last_name, user.user.username))
+ (
+ user.user.username,
+ f"{user.user.first_name} {user.user.last_name} ({user.user.username})",
+ )
for user in user_query_set
)
self.fields["users"].help_text = "
Select users in your project to add to this allocation."
@@ -229,7 +232,7 @@ def clean(self):
class AllocationChangeForm(forms.Form):
EXTENSION_CHOICES = [(0, "No Extension")]
for choice in ALLOCATION_CHANGE_REQUEST_EXTENSION_DAYS:
- EXTENSION_CHOICES.append((choice, "{} days".format(choice)))
+ EXTENSION_CHOICES.append((choice, f"{choice} days"))
end_date_extension = forms.TypedChoiceField(
label="Request End Date Extension",
@@ -265,7 +268,7 @@ class Meta:
fields = "__all__"
def __init__(self, *args, **kwargs):
- super(AllocationAttributeCreateForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["allocation_attribute_type"].queryset = self.fields["allocation_attribute_type"].queryset.order_by(
Lower("name")
)
diff --git a/coldfront/core/allocation/models.py b/coldfront/core/allocation/models.py
index 3e6ef9bf9d..20605f5356 100644
--- a/coldfront/core/allocation/models.py
+++ b/coldfront/core/allocation/models.py
@@ -175,12 +175,7 @@ def get_information(self):
"Allocation attribute '%s' == 0 but has a usage", attribute.allocation_attribute_type.name
)
- string = "{}: {}/{} ({} %)
".format(
- attribute.allocation_attribute_type.name,
- attribute.allocationattributeusage.value,
- attribute.value,
- percent,
- )
+ string = f"{attribute.allocation_attribute_type.name}: {attribute.allocationattributeusage.value}/{attribute.value} ({percent} %)
"
html_string += string
return mark_safe(html_string)
@@ -340,7 +335,7 @@ def has_perm(self, user, perm):
return perm in perms
def __str__(self):
- return "%s (%s)" % (self.get_parent_resource.name, self.project.pi)
+ return f"{self.get_parent_resource.name} ({self.project.pi})"
def get_eula(self):
if self.get_resources_as_list:
@@ -428,7 +423,7 @@ class AllocationAttributeType(TimeStampedModel):
history = HistoricalRecords()
def __str__(self):
- return "%s" % (self.name)
+ return self.name
class Meta:
ordering = [
@@ -469,40 +464,34 @@ def clean(self):
.exclude(id=self.pk)
.exists()
):
- raise ValidationError(
- "'{}' attribute already exists for this allocation.".format(self.allocation_attribute_type)
- )
+ raise ValidationError(f"'{self.allocation_attribute_type}' attribute already exists for this allocation.")
expected_value_type = self.allocation_attribute_type.attribute_type.name.strip()
if expected_value_type == "Int" and not isinstance(literal_eval(self.value), int):
raise ValidationError(
- 'Invalid Value "%s" for "%s". Value must be an integer.'
- % (self.value, self.allocation_attribute_type.name)
+ f'Invalid Value "{self.value}" for "{self.allocation_attribute_type.name}". Value must be an integer.'
)
elif expected_value_type == "Float" and not (
isinstance(literal_eval(self.value), float) or isinstance(literal_eval(self.value), int)
):
raise ValidationError(
- 'Invalid Value "%s" for "%s". Value must be a float.'
- % (self.value, self.allocation_attribute_type.name)
+ f'Invalid Value "{self.value}" for "{self.allocation_attribute_type.name}". Value must be a float.'
)
elif expected_value_type == "Yes/No" and self.value not in ["Yes", "No"]:
raise ValidationError(
- 'Invalid Value "%s" for "%s". Allowed inputs are "Yes" or "No".'
- % (self.value, self.allocation_attribute_type.name)
+ f'Invalid Value "{self.value}" for "{self.allocation_attribute_type.name}". Allowed inputs are "Yes" or "No".'
)
elif expected_value_type == "Date":
try:
datetime.datetime.strptime(self.value.strip(), "%Y-%m-%d")
except ValueError:
raise ValidationError(
- 'Invalid Value "%s" for "%s". Date must be in format YYYY-MM-DD'
- % (self.value, self.allocation_attribute_type.name)
+ f'Invalid Value "{self.value}" for "{self.allocation_attribute_type.name}". Date must be in format YYYY-MM-DD'
)
def __str__(self):
- return "%s" % (self.allocation_attribute_type.name)
+ return self.allocation_attribute_type.name
def typed_value(self):
"""
@@ -572,7 +561,7 @@ class AllocationAttributeUsage(TimeStampedModel):
history = HistoricalRecords()
def __str__(self):
- return "{}: {}".format(self.allocation_attribute.allocation_attribute_type.name, self.value)
+ return f"{self.allocation_attribute.allocation_attribute_type.name}: {self.value}"
class AllocationUserStatusChoice(TimeStampedModel):
@@ -631,7 +620,7 @@ def is_active(self):
return self.status.name == "Active" and self.allocation.status.name in active_allocation_statuses
def __str__(self):
- return "%s" % (self.user)
+ return str(self.user)
class Meta:
verbose_name_plural = "Allocation User Status"
@@ -711,7 +700,7 @@ def get_parent_resource(self):
return self.allocation.resources.filter(is_allocatable=True).first()
def __str__(self):
- return "%s (%s)" % (self.get_parent_resource.name, self.allocation.project.pi)
+ return f"{self.get_parent_resource.name} ({self.allocation.project.pi})"
class AllocationAttributeChangeRequest(TimeStampedModel):
@@ -729,4 +718,4 @@ class AllocationAttributeChangeRequest(TimeStampedModel):
history = HistoricalRecords()
def __str__(self):
- return "%s" % (self.allocation_attribute.allocation_attribute_type.name)
+ return str(self.allocation_attribute.allocation_attribute_type.name)
diff --git a/coldfront/core/allocation/tasks.py b/coldfront/core/allocation/tasks.py
index 883420aee0..e34531587c 100644
--- a/coldfront/core/allocation/tasks.py
+++ b/coldfront/core/allocation/tasks.py
@@ -50,7 +50,7 @@ def update_statuses():
sub_obj.status = expired_status_choice
sub_obj.save()
- logger.info("Allocations set to expired: {}".format(allocations_to_expire.count()))
+ logger.info(f"Allocations set to expired: {allocations_to_expire.count()}")
def send_eula_reminders():
diff --git a/coldfront/core/allocation/tests/test_models.py b/coldfront/core/allocation/tests/test_models.py
index 0363a74302..0cfb64c09b 100644
--- a/coldfront/core/allocation/tests/test_models.py
+++ b/coldfront/core/allocation/tests/test_models.py
@@ -37,7 +37,7 @@ def setUpTestData(cls):
def test_allocation_str(self):
"""test that allocation str method returns correct string"""
- allocation_str = "%s (%s)" % (self.allocation.get_parent_resource.name, self.allocation.project.pi)
+ allocation_str = f"{self.allocation.get_parent_resource.name} ({self.allocation.project.pi})"
self.assertEqual(str(self.allocation), allocation_str)
diff --git a/coldfront/core/allocation/tests/test_views.py b/coldfront/core/allocation/tests/test_views.py
index e01b870c79..62de1e0768 100644
--- a/coldfront/core/allocation/tests/test_views.py
+++ b/coldfront/core/allocation/tests/test_views.py
@@ -75,7 +75,7 @@ class AllocationListViewTest(AllocationViewBaseTest):
@classmethod
def setUpTestData(cls):
"""Set up users and project for testing"""
- super(AllocationListViewTest, cls).setUpTestData()
+ super().setUpTestData()
cls.additional_allocations = [AllocationFactory() for i in list(range(100))]
for allocation in cls.additional_allocations:
allocation.resources.add(ResourceFactory(name="holylfs09/tier1"))
diff --git a/coldfront/core/allocation/utils.py b/coldfront/core/allocation/utils.py
index d091d0aad4..7aec3979d0 100644
--- a/coldfront/core/allocation/utils.py
+++ b/coldfront/core/allocation/utils.py
@@ -16,7 +16,7 @@ def set_allocation_user_status_to_error(allocation_user_pk):
def generate_guauge_data_from_usage(name, value, usage):
- label = "%s: %.2f of %.2f" % (name, usage, value)
+ label = f"{name}: {usage:.2f} of {value:.2f}"
try:
percent = (usage / value) * 100
diff --git a/coldfront/core/allocation/views.py b/coldfront/core/allocation/views.py
index 02c129d267..4c60d22ec7 100644
--- a/coldfront/core/allocation/views.py
+++ b/coldfront/core/allocation/views.py
@@ -317,12 +317,7 @@ def post(self, request, *args, **kwargs):
if action == "auto-approve":
messages.success(
request,
- "Allocation to {} has been ACTIVATED for {} {} ({})".format(
- allocation_obj.get_parent_resource,
- allocation_obj.project.pi.first_name,
- allocation_obj.project.pi.last_name,
- allocation_obj.project.pi.username,
- ),
+ f"Allocation to {allocation_obj.get_parent_resource} has been ACTIVATED for {allocation_obj.project.pi.first_name} {allocation_obj.project.pi.last_name} ({allocation_obj.project.pi.username})",
)
return HttpResponseRedirect(reverse("allocation-request-list"))
@@ -567,7 +562,8 @@ def get_context_data(self, **kwargs):
order_by = self.request.GET.get("order_by")
if order_by:
direction = self.request.GET.get("direction")
- filter_parameters_with_order_by = filter_parameters + "order_by=%s&direction=%s&" % (order_by, direction)
+ filter_parameters_string = "" if not filter_parameters else filter_parameters
+ filter_parameters_with_order_by = filter_parameters_string + f"order_by={order_by}&direction={direction}&"
else:
filter_parameters_with_order_by = filter_parameters
@@ -1814,12 +1810,7 @@ def post(self, request, *args, **kwargs):
messages.success(
request,
- "Allocation change request to {} has been DENIED for {} {} ({})".format(
- allocation_change_obj.allocation.resources.first(),
- allocation_change_obj.allocation.project.pi.first_name,
- allocation_change_obj.allocation.project.pi.last_name,
- allocation_change_obj.allocation.project.pi.username,
- ),
+ f"Allocation change request to {allocation_change_obj.allocation.resources.first()} has been DENIED for {allocation_change_obj.allocation.project.pi.first_name} {allocation_change_obj.allocation.project.pi.last_name} ({allocation_change_obj.allocation.project.pi.username})",
)
send_allocation_customer_email(
@@ -1894,12 +1885,7 @@ def post(self, request, *args, **kwargs):
messages.success(
request,
- "Allocation change request to {} has been APPROVED for {} {} ({})".format(
- allocation_change_obj.allocation.get_parent_resource,
- allocation_change_obj.allocation.project.pi.first_name,
- allocation_change_obj.allocation.project.pi.last_name,
- allocation_change_obj.allocation.project.pi.username,
- ),
+ f"Allocation change request to {allocation_change_obj.allocation.get_parent_resource} has been APPROVED for {allocation_change_obj.allocation.project.pi.first_name} {allocation_change_obj.allocation.project.pi.last_name} ({allocation_change_obj.allocation.project.pi.username})",
)
allocation_change_approved.send(
diff --git a/coldfront/core/attribute_expansion.py b/coldfront/core/attribute_expansion.py
index 68260536f2..7a35e32f79 100644
--- a/coldfront/core/attribute_expansion.py
+++ b/coldfront/core/attribute_expansion.py
@@ -44,7 +44,7 @@ def get_attriblist_str(attribute_name, resources=[], allocations=[]):
attriblist attributes are found, we return None.
"""
- attriblist_name = "{aname}{suffix}".format(aname=attribute_name, suffix=ATTRIBUTE_EXPANSION_ATTRIBLIST_SUFFIX)
+ attriblist_name = f"{attribute_name}{ATTRIBUTE_EXPANSION_ATTRIBLIST_SUFFIX}"
attriblist = None
# Check resources first
@@ -115,9 +115,7 @@ def get_attribute_parameter_value(argument, attribute_parameter_dict, error_text
else:
# Bad string literal
logger.warning(
- "Bad string literal '{}' found while processing {}; missing final single quote".format(
- argument, error_text
- )
+ f"Bad string literal '{argument}' found while processing {error_text}; missing final single quote"
)
return None
@@ -167,11 +165,7 @@ def get_attribute_parameter_value(argument, attribute_parameter_dict, error_text
value = float(argument)
return value
except ValueError:
- logger.warning(
- "Unable to evaluate argument '{arg}' while processing {etxt}, returning None".format(
- arg=argument, etxt=error_text
- )
- )
+ logger.warning(f"Unable to evaluate argument '{argument}' while processing {error_text}, returning None")
return None
# Should not reach here
@@ -214,12 +208,12 @@ def process_attribute_parameter_operation(opcode, oldvalue, argument, error_text
"""
# Argument should never be None
if argument is None:
- logger.warning("Operator {}= acting on None argument in {}, returning None".format(opcode, error_text))
+ logger.warning(f"Operator {opcode}= acting on None argument in {error_text}, returning None")
return None
# Assignment and default operations allow oldvalue to be None
if oldvalue is None:
if opcode != ":" and opcode != "|":
- logger.warning("Operator {}= acting on oldvalue=None in {}, returning None".format(opcode, error_text))
+ logger.warning(f"Operator {opcode}= acting on oldvalue=None in {error_text}, returning None")
return None
try:
@@ -242,9 +236,7 @@ def process_attribute_parameter_operation(opcode, oldvalue, argument, error_text
return newval
else:
logger.warning(
- "Operator {}= acting on parameter of type {} in {}, returning None".format(
- opcode, type(oldvalue), error_text
- )
+ f"Operator {opcode}= acting on parameter of type {type(oldvalue)} in {error_text}, returning None"
)
return None
if opcode == "-":
@@ -260,17 +252,13 @@ def process_attribute_parameter_operation(opcode, oldvalue, argument, error_text
if argument == "floor":
newval = math.floor(oldvalue)
else:
- logger.error(
- "Unrecognized function named {} in {}= for {}, returning None".format(argument, opcode, error_text)
- )
+ logger.error(f"Unrecognized function named {argument} in {opcode}= for {error_text}, returning None")
return None
# If reached here, we do not recognize opcode
- logger.error("Unrecognized operation {}= in {}, returning None".format(opcode, error_text))
+ logger.error(f"Unrecognized operation {opcode}= in {error_text}, returning None")
except Exception:
logger.warning(
- "Error performing operator {op}= on oldvalue='{old}' and argument={arg} in {errtext}".format(
- op=opcode, old=oldvalue, arg=argument, errtext=error_text
- )
+ f"Error performing operator {opcode}= on oldvalue='{oldvalue}' and argument={argument} in {error_text}"
)
return None
@@ -320,9 +308,9 @@ def process_attribute_parameter_string(
# No '=' found, so invalid format of parmstr
# Log error and return unmodified attribute_parameter_dict
logger.error(
- "Invalid parameter string '{pstr}', no '=', while "
+ f"Invalid parameter string '{parameter_string}', no '=', while "
"creating attribute parameter dictionary for expanding "
- "attribute {aname}".format(aname=attribute_name, pstr=parameter_string)
+ f"attribute {attribute_name}"
)
return attribute_parameter_dict
pname = tmp[0]
@@ -338,8 +326,8 @@ def process_attribute_parameter_string(
value = argument
else:
# Extra text to display in diagnostics if error occurs
- error_text = "processing attribute_parameter_string={pstr} for expansion of attribute {aname}".format(
- pstr=parameter_string, aname=attribute_name
+ error_text = (
+ f"processing attribute_parameter_string={parameter_string} for expansion of attribute {attribute_name}"
)
value = get_attribute_parameter_value(
argument=argument,
@@ -463,7 +451,7 @@ def expand_attribute(raw_value, attribute_name, attriblist_string, resources=[],
# referencing a parameter not defined in apdict to divide by
# zero errors in processing apdict. We just log it and then
# return raw_value
- logger.error("Error expanding {aname}: {error}".format(aname=attribute_name, error=xcept))
+ logger.error(f"Error expanding {attribute_name}: {xcept}")
return raw_value
@@ -485,7 +473,7 @@ def convert_type(value, type_name, error_text="unknown"):
future "Attribute Expanded ..." types.
"""
if type_name is None:
- logger.error("No AttributeType found for {}".format(error_text))
+ logger.error(f"No AttributeType found for {error_text}")
return value
if type_name.endswith("Text"):
diff --git a/coldfront/core/field_of_science/management/commands/import_field_of_science_data.py b/coldfront/core/field_of_science/management/commands/import_field_of_science_data.py
index f71e1f0038..0d5625b86c 100644
--- a/coldfront/core/field_of_science/management/commands/import_field_of_science_data.py
+++ b/coldfront/core/field_of_science/management/commands/import_field_of_science_data.py
@@ -18,7 +18,7 @@ def handle(self, *args, **options):
self.stdout.write("Adding field of science ...")
file_path = os.path.join(app_commands_dir, "data", "field_of_science_data.csv")
FieldOfScience.objects.all().delete()
- with open(file_path, "r") as fp:
+ with open(file_path) as fp:
for line in fp:
pk, parent_id, is_selectable, description, fos_nsf_id, fos_nsf_abbrev, directorate_fos_id = (
line.strip().split("\t")
diff --git a/coldfront/core/grant/admin.py b/coldfront/core/grant/admin.py
index b77b71f36c..8c5bd4561b 100644
--- a/coldfront/core/grant/admin.py
+++ b/coldfront/core/grant/admin.py
@@ -58,7 +58,7 @@ class GrantAdmin(SimpleHistoryAdmin):
]
def Project_PI(self, obj):
- return "{} {} ({})".format(obj.project.pi.first_name, obj.project.pi.last_name, obj.project.pi.username)
+ return f"{obj.project.pi.first_name} {obj.project.pi.last_name} ({obj.project.pi.username})"
def Funding_Agency(self, obj):
if obj.funding_agency.name == "Other":
diff --git a/coldfront/core/grant/forms.py b/coldfront/core/grant/forms.py
index f40024b357..a78ab7c03b 100644
--- a/coldfront/core/grant/forms.py
+++ b/coldfront/core/grant/forms.py
@@ -18,19 +18,17 @@ class Meta:
"project",
]
labels = {
- "percent_credit": "Percent credit to {}".format(CENTER_NAME),
- "direct_funding": "Direct funding to {}".format(CENTER_NAME),
+ "percent_credit": f"Percent credit to {CENTER_NAME}",
+ "direct_funding": f"Direct funding to {CENTER_NAME}",
}
help_texts = {
"percent_credit": "Percent credit as entered in the sponsored projects form for grant submission as financial credit to the department/unit in the credit distribution section. Enter only digits, decimals, percent symbols, or spaces.",
- "direct_funding": "Funds budgeted specifically for {} services, hardware, software, and/or personnel. Enter only digits, decimals, commas, dollar signs, or spaces.".format(
- CENTER_NAME
- ),
+ "direct_funding": f"Funds budgeted specifically for {CENTER_NAME} services, hardware, software, and/or personnel. Enter only digits, decimals, commas, dollar signs, or spaces.",
"total_amount_awarded": "Enter only digits, decimals, commas, dollar signs, or spaces.",
}
def __init__(self, *args, **kwargs):
- super(GrantForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["funding_agency"].queryset = self.fields["funding_agency"].queryset.order_by("name")
diff --git a/coldfront/core/grant/models.py b/coldfront/core/grant/models.py
index d1fa1b28f4..9c7c4e5a04 100644
--- a/coldfront/core/grant/models.py
+++ b/coldfront/core/grant/models.py
@@ -152,7 +152,7 @@ def grant_pi(self):
"""
if self.role == "PI":
- return "{} {}".format(self.project.pi.first_name, self.project.pi.last_name)
+ return f"{self.project.pi.first_name} {self.project.pi.last_name}"
else:
return self.grant_pi_full_name
diff --git a/coldfront/core/grant/views.py b/coldfront/core/grant/views.py
index ed6f075d53..4e385529d1 100644
--- a/coldfront/core/grant/views.py
+++ b/coldfront/core/grant/views.py
@@ -188,7 +188,7 @@ def post(self, request, *args, **kwargs):
grant_obj.delete()
grants_deleted_count += 1
- messages.success(request, "Deleted {} grants from project.".format(grants_deleted_count))
+ messages.success(request, f"Deleted {grants_deleted_count} grants from project.")
else:
for error in formset.errors:
messages.error(request, error)
diff --git a/coldfront/core/portal/utils.py b/coldfront/core/portal/utils.py
index 5ddacaff98..8a63369efe 100644
--- a/coldfront/core/portal/utils.py
+++ b/coldfront/core/portal/utils.py
@@ -30,10 +30,10 @@ def generate_total_grants_by_agency_chart_data(total_grants_by_agency):
def generate_resources_chart_data(allocations_count_by_resource_type):
if allocations_count_by_resource_type:
- cluster_label = "Cluster: %d" % (allocations_count_by_resource_type.get("Cluster", 0))
- cloud_label = "Cloud: %d" % (allocations_count_by_resource_type.get("Cloud", 0))
- server_label = "Server: %d" % (allocations_count_by_resource_type.get("Server", 0))
- storage_label = "Storage: %d" % (allocations_count_by_resource_type.get("Storage", 0))
+ cluster_label = f"Cluster: {allocations_count_by_resource_type.get('Cluster', 0)}"
+ cloud_label = f"Cloud: {allocations_count_by_resource_type.get('Cloud', 0)}"
+ server_label = f"Server: {allocations_count_by_resource_type.get('Server', 0)}"
+ storage_label = f"Storage: {allocations_count_by_resource_type.get('Storage', 0)}"
resource_plot_data = {
"columns": [
@@ -65,10 +65,10 @@ def generate_allocations_chart_data():
start_time = datetime.date(now.year - 1, 1, 1)
expired_count = Allocation.objects.filter(status__name="Expired", end_date__gte=start_time).count()
- active_label = "Active: %d" % (active_count)
- new_label = "New: %d" % (new_count)
- renewal_requested_label = "Renewal Requested: %d" % (renewal_requested_count)
- expired_label = "Expired: %d" % (expired_count)
+ active_label = f"Active: {active_count}"
+ new_label = f"New: {new_count}"
+ renewal_requested_label = f"Renewal Requested: {renewal_requested_count}"
+ expired_label = f"Expired: {expired_count}"
allocation_chart_data = {
"columns": [
diff --git a/coldfront/core/project/admin.py b/coldfront/core/project/admin.py
index 400df4824c..00ba5b8e3f 100644
--- a/coldfront/core/project/admin.py
+++ b/coldfront/core/project/admin.py
@@ -77,10 +77,10 @@ def project_title(self, obj):
return textwrap.shorten(obj.project.title, width=50)
def PI(self, obj):
- return "{} {} ({})".format(obj.project.pi.first_name, obj.project.pi.last_name, obj.project.pi.username)
+ return f"{obj.project.pi.first_name} {obj.project.pi.last_name} ({obj.project.pi.username})"
def User(self, obj):
- return "{} {} ({})".format(obj.user.first_name, obj.user.last_name, obj.user.username)
+ return f"{obj.user.first_name} {obj.user.last_name} ({obj.user.username})"
def get_fields(self, request, obj):
if obj is None:
@@ -229,7 +229,7 @@ def project_status(self, obj):
return obj.project.status
def pi(self, obj):
- return "{} {} ({})".format(obj.project.pi.first_name, obj.project.pi.last_name, obj.project.pi.username)
+ return f"{obj.project.pi.first_name} {obj.project.pi.last_name} ({obj.project.pi.username})"
def project(self, obj):
return textwrap.shorten(obj.project.title, width=50)
@@ -341,7 +341,7 @@ class ProjectAdmin(SimpleHistoryAdmin):
]
def PI(self, obj):
- return "{} {} ({})".format(obj.pi.first_name, obj.pi.last_name, obj.pi.username)
+ return f"{obj.pi.first_name} {obj.pi.last_name} ({obj.pi.username})"
def get_fields(self, request, obj):
if obj is None:
@@ -398,4 +398,4 @@ class ProjectReviewAdmin(SimpleHistoryAdmin):
list_filter = ("status",)
def PI(self, obj):
- return "{} {} ({})".format(obj.project.pi.first_name, obj.project.pi.last_name, obj.project.pi.username)
+ return f"{obj.project.pi.first_name} {obj.project.pi.last_name} ({obj.project.pi.username})"
diff --git a/coldfront/core/project/forms.py b/coldfront/core/project/forms.py
index a861b6918d..5ae473670d 100644
--- a/coldfront/core/project/forms.py
+++ b/coldfront/core/project/forms.py
@@ -56,8 +56,7 @@ def __init__(self, request_user, project_pk, *args, **kwargs):
allocation_choices = [
(
allocation.id,
- "%s (%s) %s"
- % (
+ "{} ({}) {}".format(
allocation.get_parent_resource.name,
allocation.get_parent_resource.resource_type.name,
allocation.description if allocation.description else "",
@@ -108,7 +107,7 @@ class ProjectReviewForm(forms.Form):
def __init__(self, project_pk, *args, **kwargs):
super().__init__(*args, **kwargs)
project_obj = get_object_or_404(Project, pk=project_pk)
- now = datetime.datetime.now(datetime.timezone.utc)
+ now = datetime.datetime.now(datetime.UTC)
if project_obj.grant_set.exists():
latest_grant = project_obj.grant_set.order_by("-modified")[0]
@@ -135,11 +134,9 @@ class ProjectReviewEmailForm(forms.Form):
def __init__(self, pk, *args, **kwargs):
super().__init__(*args, **kwargs)
project_review_obj = get_object_or_404(ProjectReview, pk=int(pk))
- self.fields["email_body"].initial = "Dear {} {} \n{}".format(
- project_review_obj.project.pi.first_name,
- project_review_obj.project.pi.last_name,
- EMAIL_DIRECTOR_PENDING_PROJECT_REVIEW_EMAIL,
- )
+ self.fields[
+ "email_body"
+ ].initial = f"Dear {project_review_obj.project.pi.first_name} {project_review_obj.project.pi.last_name} \n{EMAIL_DIRECTOR_PENDING_PROJECT_REVIEW_EMAIL}"
self.fields["cc"].initial = ", ".join([EMAIL_DIRECTOR_EMAIL_ADDRESS] + EMAIL_ADMIN_LIST)
@@ -152,7 +149,7 @@ class Meta:
}
def __init__(self, *args, **kwargs):
- super(ProjectAttributeAddForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
user = (kwargs.get("initial")).get("user")
self.fields["proj_attr_type"].queryset = self.fields["proj_attr_type"].queryset.order_by(Lower("name"))
if not user.is_superuser:
diff --git a/coldfront/core/project/models.py b/coldfront/core/project/models.py
index db2341a531..0b0cd9634d 100644
--- a/coldfront/core/project/models.py
+++ b/coldfront/core/project/models.py
@@ -168,7 +168,7 @@ def needs_review(self):
if self.status.name == "Archived":
return False
- now = datetime.datetime.now(datetime.timezone.utc)
+ now = datetime.datetime.now(datetime.UTC)
if self.force_review is True:
return True
@@ -384,7 +384,7 @@ class ProjectUser(TimeStampedModel):
history = HistoricalRecords()
def __str__(self):
- return "%s %s (%s)" % (self.user.first_name, self.user.last_name, self.user.username)
+ return f"{self.user.first_name} {self.user.last_name} ({self.user.username})"
class Meta:
unique_together = ("user", "project")
@@ -432,7 +432,7 @@ class ProjectAttributeType(TimeStampedModel):
history = HistoricalRecords()
def __str__(self):
- return "%s (%s)" % (self.name, self.attribute_type.name)
+ return f"{self.name} ({self.attribute_type.name})"
def __repr__(self) -> str:
return str(self)
@@ -470,7 +470,7 @@ def clean(self):
self.proj_attr_type.is_unique
and self.project.projectattribute_set.filter(proj_attr_type=self.proj_attr_type).exists()
):
- raise ValidationError("'{}' attribute already exists for this project.".format(self.proj_attr_type))
+ raise ValidationError(f"'{self.proj_attr_type}' attribute already exists for this project.")
expected_value_type = self.proj_attr_type.attribute_type.name.strip()
@@ -486,7 +486,7 @@ def clean(self):
validator.validate_date()
def __str__(self):
- return "%s" % (self.proj_attr_type.name)
+ return str(self.proj_attr_type.name)
class ProjectAttributeUsage(TimeStampedModel):
@@ -502,4 +502,4 @@ class ProjectAttributeUsage(TimeStampedModel):
history = HistoricalRecords()
def __str__(self):
- return "{}: {}".format(self.project_attribute.proj_attr_type.name, self.value)
+ return f"{self.project_attribute.proj_attr_type.name}: {self.value}"
diff --git a/coldfront/core/project/tests/test_views.py b/coldfront/core/project/tests/test_views.py
index 116fdd2619..b3a8268760 100644
--- a/coldfront/core/project/tests/test_views.py
+++ b/coldfront/core/project/tests/test_views.py
@@ -61,7 +61,7 @@ class ProjectDetailViewTest(ProjectViewTestBase):
@classmethod
def setUpTestData(cls):
"""Set up users and project for testing"""
- super(ProjectDetailViewTest, cls).setUpTestData()
+ super().setUpTestData()
cls.url = f"/project/{cls.project.pk}/"
def test_projectdetail_access(self):
@@ -121,7 +121,7 @@ class ProjectCreateTest(ProjectViewTestBase):
@classmethod
def setUpTestData(cls):
"""Set up users and project for testing"""
- super(ProjectCreateTest, cls).setUpTestData()
+ super().setUpTestData()
cls.url = "/project/create/"
def test_project_access(self):
@@ -140,7 +140,7 @@ class ProjectAttributeCreateTest(ProjectViewTestBase):
@classmethod
def setUpTestData(cls):
"""Set up users and project for testing"""
- super(ProjectAttributeCreateTest, cls).setUpTestData()
+ super().setUpTestData()
int_attributetype = PAttributeTypeFactory(name="Int")
cls.int_projectattributetype = ProjectAttributeTypeFactory(attribute_type=int_attributetype)
cls.url = f"/project/{cls.project.pk}/project-attribute-create/"
@@ -198,7 +198,7 @@ class ProjectAttributeUpdateTest(ProjectViewTestBase):
@classmethod
def setUpTestData(cls):
"""Set up users and project for testing"""
- super(ProjectAttributeUpdateTest, cls).setUpTestData()
+ super().setUpTestData()
cls.projectattribute = ProjectAttributeFactory(
value=36238, proj_attr_type=cls.projectattributetype, project=cls.project
)
@@ -219,7 +219,7 @@ class ProjectAttributeDeleteTest(ProjectViewTestBase):
@classmethod
def setUpTestData(cls):
"""set up users and project for testing"""
- super(ProjectAttributeDeleteTest, cls).setUpTestData()
+ super().setUpTestData()
cls.projectattribute = ProjectAttributeFactory(
value=36238, proj_attr_type=cls.projectattributetype, project=cls.project
)
@@ -242,7 +242,7 @@ class ProjectListViewTest(ProjectViewTestBase):
@classmethod
def setUpTestData(cls):
"""Set up users and project for testing"""
- super(ProjectListViewTest, cls).setUpTestData()
+ super().setUpTestData()
# add 100 projects to test pagination, permissions, search functionality
additional_projects = [ProjectFactory() for i in list(range(100))]
cls.additional_projects = [p for p in additional_projects if p.pi.last_name != cls.project.pi.last_name]
diff --git a/coldfront/core/project/views.py b/coldfront/core/project/views.py
index df2adc82f3..9728a6f9b9 100644
--- a/coldfront/core/project/views.py
+++ b/coldfront/core/project/views.py
@@ -340,9 +340,9 @@ def get_context_data(self, **kwargs):
if value:
if isinstance(value, list):
for ele in value:
- filter_parameters += "{}={}&".format(key, ele)
+ filter_parameters += f"{key}={ele}&"
else:
- filter_parameters += "{}={}&".format(key, value)
+ filter_parameters += f"{key}={value}&"
context["project_search_form"] = project_search_form
else:
filter_parameters = None
@@ -351,7 +351,8 @@ def get_context_data(self, **kwargs):
order_by = self.request.GET.get("order_by")
if order_by:
direction = self.request.GET.get("direction")
- filter_parameters_with_order_by = filter_parameters + "order_by=%s&direction=%s&" % (order_by, direction)
+ filter_parameters_string = "" if not filter_parameters else filter_parameters
+ filter_parameters_with_order_by = filter_parameters_string + f"order_by={order_by}&direction={direction}&"
else:
filter_parameters_with_order_by = filter_parameters
@@ -483,9 +484,9 @@ def get_context_data(self, **kwargs):
if value:
if isinstance(value, list):
for ele in value:
- filter_parameters += "{}={}&".format(key, ele)
+ filter_parameters += f"{key}={ele}&"
else:
- filter_parameters += "{}={}&".format(key, value)
+ filter_parameters += f"{key}={value}&"
context["project_search_form"] = project_search_form
else:
filter_parameters = None
@@ -494,7 +495,8 @@ def get_context_data(self, **kwargs):
order_by = self.request.GET.get("order_by")
if order_by:
direction = self.request.GET.get("direction")
- filter_parameters_with_order_by = filter_parameters + "order_by=%s&direction=%s&" % (order_by, direction)
+ filter_parameters_string = "" if not filter_parameters else filter_parameters
+ filter_parameters_with_order_by = filter_parameters_string + f"order_by={order_by}&direction={direction}&"
else:
filter_parameters_with_order_by = filter_parameters
@@ -888,7 +890,7 @@ def post(self, request, *args, **kwargs):
sender=self.__class__, allocation_user_pk=allocation_user_obj.pk
)
- messages.success(request, "Added {} users to project.".format(added_users_count))
+ messages.success(request, f"Added {added_users_count} users to project.")
else:
if not formset.is_valid():
for error in formset.errors:
@@ -1010,9 +1012,9 @@ def post(self, request, *args, **kwargs):
)
if remove_users_count == 1:
- messages.success(request, "Removed {} user from project.".format(remove_users_count))
+ messages.success(request, f"Removed {remove_users_count} user from project.")
else:
- messages.success(request, "Removed {} users from project.".format(remove_users_count))
+ messages.success(request, f"Removed {remove_users_count} users from project.")
else:
for error in formset.errors:
messages.error(request, error)
@@ -1192,7 +1194,7 @@ def get(self, request, *args, **kwargs):
context["project_review_form"] = project_review_form
context["project_users"] = ", ".join(
[
- "{} {}".format(ele.user.first_name, ele.user.last_name)
+ f"{ele.user.first_name} {ele.user.last_name}"
for ele in project_obj.projectuser_set.filter(status__name="Active").order_by("user__last_name")
]
)
@@ -1282,7 +1284,7 @@ def get(self, request, project_review_pk):
project_review_obj.project.project_needs_review = False
project_review_obj.save()
- messages.success(request, "Project review for {} has been completed".format(project_review_obj.project.title))
+ messages.success(request, f"Project review for {project_review_obj.project.title} has been completed")
return HttpResponseRedirect(reverse("project-review-list"))
@@ -1335,11 +1337,7 @@ def form_valid(self, form):
messages.success(
self.request,
- "Email sent to {} {} ({})".format(
- project_review_obj.project.pi.first_name,
- project_review_obj.project.pi.last_name,
- project_review_obj.project.pi.username,
- ),
+ f"Email sent to {project_review_obj.project.pi.first_name} {project_review_obj.project.pi.last_name} ({project_review_obj.project.pi.username})",
)
return super().form_valid(form)
@@ -1501,7 +1499,7 @@ def post(self, request, *args, **kwargs):
proj_attr.delete()
- messages.success(request, "Deleted {} attributes from project.".format(attributes_deleted_count))
+ messages.success(request, f"Deleted {attributes_deleted_count} attributes from project.")
else:
for error in formset.errors:
messages.error(request, error)
diff --git a/coldfront/core/publication/tests/tests.py b/coldfront/core/publication/tests/tests.py
index 249840082a..aeb65263ca 100644
--- a/coldfront/core/publication/tests/tests.py
+++ b/coldfront/core/publication/tests/tests.py
@@ -52,7 +52,7 @@ def __init__(self):
def setUp(self):
self.data = self.Data()
- self.unique_id_generator = ("unique_id_{}".format(id) for id in itertools.count())
+ self.unique_id_generator = (f"unique_id_{id}" for id in itertools.count())
def test_fields_generic(self):
self.assertEqual(0, len(Publication.objects.all()))
@@ -168,7 +168,7 @@ def mock_parse(thing_to_parse):
bibtexparser_cls.return_value.parse.side_effect = mock_parse
as_text = Mock(spec_set=bibtexparser.bibdatabase.as_text)
- as_text.side_effect = lambda bib_entry: "as_text({})".format(bib_entry)
+ as_text.side_effect = lambda bib_entry: f"as_text({bib_entry})"
self.crossref = crossref
self.bibtexparser_cls = bibtexparser_cls
@@ -178,7 +178,7 @@ def mock_parse(thing_to_parse):
def patch(self):
def dotpath(qualname):
module_under_test = coldfront.core.publication.views
- return "{}.{}".format(module_under_test.__name__, qualname)
+ return f"{module_under_test.__name__}.{qualname}"
with contextlib.ExitStack() as stack:
patches = [
diff --git a/coldfront/core/publication/views.py b/coldfront/core/publication/views.py
index 6cb8f36cfc..711e39f9d1 100644
--- a/coldfront/core/publication/views.py
+++ b/coldfront/core/publication/views.py
@@ -114,9 +114,7 @@ def _search_id(self, unique_id):
elif source.name == "adsabs":
try:
- url = "http://adsabs.harvard.edu/cgi-bin/nph-bib_query?bibcode={}&data_type=BIBTEX".format(
- unique_id
- )
+ url = f"http://adsabs.harvard.edu/cgi-bin/nph-bib_query?bibcode={unique_id}&data_type=BIBTEX"
r = requests.get(url, timeout=5)
bp = BibTexParser(interpolate_strings=False)
bib_database = bp.parse(r.text)
@@ -167,7 +165,7 @@ def _search_id(self, unique_id):
else:
# fallback: clearly indicate that data was absent
source_name = matching_source_obj.name
- journal = "[no journal info from {}]".format(source_name.upper())
+ journal = f"[no journal info from {source_name.upper()}]"
pub_dict = {}
pub_dict["author"] = author
@@ -408,7 +406,7 @@ def post(self, request, *args, **kwargs):
publication_obj.delete()
publications_deleted_count += 1
- messages.success(request, "Deleted {} publications from project.".format(publications_deleted_count))
+ messages.success(request, f"Deleted {publications_deleted_count} publications from project.")
else:
for error in formset.errors:
messages.error(request, error)
diff --git a/coldfront/core/resource/forms.py b/coldfront/core/resource/forms.py
index 6a711f35b0..686efebd9b 100644
--- a/coldfront/core/resource/forms.py
+++ b/coldfront/core/resource/forms.py
@@ -46,7 +46,7 @@ class Meta:
fields = "__all__"
def __init__(self, *args, **kwargs):
- super(ResourceAttributeCreateForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["resource_attribute_type"].queryset = self.fields["resource_attribute_type"].queryset.order_by(
Lower("name")
)
diff --git a/coldfront/core/resource/models.py b/coldfront/core/resource/models.py
index d2a5531022..1cb1a3b964 100644
--- a/coldfront/core/resource/models.py
+++ b/coldfront/core/resource/models.py
@@ -230,7 +230,7 @@ def get_ondemand_status(self):
return None
def __str__(self):
- return "%s (%s)" % (self.name, self.resource_type.name)
+ return f"{self.name} ({self.resource_type.name})"
def natural_key(self):
return [self.name]
@@ -255,19 +255,19 @@ def clean(self):
expected_value_type = self.resource_attribute_type.attribute_type.name.strip()
if expected_value_type == "Int" and not self.value.isdigit():
- raise ValidationError('Invalid Value "%s". Value must be an integer.' % (self.value))
+ raise ValidationError(f'Invalid Value "{self.value}". Value must be an integer.')
elif expected_value_type == "Active/Inactive" and self.value not in ["Active", "Inactive"]:
- raise ValidationError('Invalid Value "%s". Allowed inputs are "Active" or "Inactive".' % (self.value))
+ raise ValidationError(f'Invalid Value "{self.value}". Allowed inputs are "Active" or "Inactive".')
elif expected_value_type == "Public/Private" and self.value not in ["Public", "Private"]:
- raise ValidationError('Invalid Value "%s". Allowed inputs are "Public" or "Private".' % (self.value))
+ raise ValidationError(f'Invalid Value "{self.value}". Allowed inputs are "Public" or "Private".')
elif expected_value_type == "Date":
try:
datetime.strptime(self.value.strip(), "%m/%d/%Y")
except ValueError:
- raise ValidationError('Invalid Value "%s". Date must be in format MM/DD/YYYY' % (self.value))
+ raise ValidationError(f'Invalid Value "{self.value}". Date must be in format MM/DD/YYYY')
def __str__(self):
- return "%s: %s (%s)" % (self.resource_attribute_type, self.value, self.resource)
+ return f"{self.resource_attribute_type}: {self.value} ({self.resource})"
def typed_value(self):
"""
diff --git a/coldfront/core/resource/views.py b/coldfront/core/resource/views.py
index 7f9e4aca3a..1aafe614a5 100644
--- a/coldfront/core/resource/views.py
+++ b/coldfront/core/resource/views.py
@@ -185,7 +185,7 @@ def post(self, request, *args, **kwargs):
resource_attribute = ResourceAttribute.objects.get(pk=form_data["pk"])
resource_attribute.delete()
- messages.success(request, "Deleted {} attributes from resource.".format(attributes_deleted_count))
+ messages.success(request, f"Deleted {attributes_deleted_count} attributes from resource.")
else:
for error in formset.errors:
messages.error(request, error)
@@ -288,9 +288,9 @@ def get_context_data(self, **kwargs):
if value:
if isinstance(value, list):
for ele in value:
- filter_parameters += "{}={}&".format(key, ele)
+ filter_parameters += f"{key}={ele}&"
else:
- filter_parameters += "{}={}&".format(key, value)
+ filter_parameters += f"{key}={value}&"
context["resource_search_form"] = resource_search_form
else:
filter_parameters = None
@@ -299,7 +299,8 @@ def get_context_data(self, **kwargs):
order_by = self.request.GET.get("order_by")
if order_by:
direction = self.request.GET.get("direction")
- filter_parameters_with_order_by = filter_parameters + "order_by=%s&direction=%s&" % (order_by, direction)
+ filter_parameters_string = "" if not filter_parameters else filter_parameters
+ filter_parameters_with_order_by = filter_parameters_string + f"order_by={order_by}&direction={direction}&"
else:
filter_parameters_with_order_by = filter_parameters
diff --git a/coldfront/core/test_helpers/decorators.py b/coldfront/core/test_helpers/decorators.py
index 41ec96259f..9a7d5c79bd 100644
--- a/coldfront/core/test_helpers/decorators.py
+++ b/coldfront/core/test_helpers/decorators.py
@@ -11,7 +11,7 @@ def _skipUnlessEnvDefined(varname, reason=None):
skip = varname not in os.environ
if skip and reason is None:
- reason = "Automatically skipped. {} is not defined".format(varname)
+ reason = f"Automatically skipped. {varname} is not defined"
return functools.partial(unittest.skipIf, skip, reason)
diff --git a/coldfront/core/test_helpers/factories.py b/coldfront/core/test_helpers/factories.py
index b852110095..42750beeec 100644
--- a/coldfront/core/test_helpers/factories.py
+++ b/coldfront/core/test_helpers/factories.py
@@ -86,7 +86,7 @@ class Meta:
last_name = factory.Faker("last_name")
# username = factory.Faker('username')
username = factory.LazyAttribute(lambda o: f"{o.first_name}{o.last_name}")
- email = factory.LazyAttribute(lambda o: "%s@example.com" % o.username)
+ email = factory.LazyAttribute(lambda o: f"{o.username}@example.com")
class UserProfileFactory(DjangoModelFactory):
diff --git a/coldfront/core/utils/common.py b/coldfront/core/utils/common.py
index 9fd84a2de3..4ea3b0ae34 100644
--- a/coldfront/core/utils/common.py
+++ b/coldfront/core/utils/common.py
@@ -24,7 +24,7 @@ def import_from_settings(attr, *args):
return getattr(settings, attr, args[0])
return getattr(settings, attr)
except AttributeError:
- raise ImproperlyConfigured("Setting {0} not found".format(attr))
+ raise ImproperlyConfigured(f"Setting {attr} not found")
def get_domain_url(request):
diff --git a/coldfront/core/utils/mail.py b/coldfront/core/utils/mail.py
index 6e4d442ed1..1645aabe33 100644
--- a/coldfront/core/utils/mail.py
+++ b/coldfront/core/utils/mail.py
@@ -148,8 +148,8 @@ def send_allocation_eula_customer_email(
ctx = email_template_context()
ctx["resource"] = allocation_obj.get_parent_resource
ctx["url"] = url
- ctx["allocation_user"] = "{} {} ({})".format(
- allocation_user.user.first_name, allocation_user.user.last_name, allocation_user.user.username
+ ctx["allocation_user"] = (
+ f"{allocation_user.user.first_name} {allocation_user.user.last_name} ({allocation_user.user.username})"
)
if include_eula:
ctx["eula"] = allocation_obj.get_eula()
diff --git a/coldfront/core/utils/mixins/views.py b/coldfront/core/utils/mixins/views.py
index 105749241c..ca06e4a741 100644
--- a/coldfront/core/utils/mixins/views.py
+++ b/coldfront/core/utils/mixins/views.py
@@ -32,7 +32,7 @@ def to_snake(string):
app_label = self.model._meta.app_label
model_name = self.model.__name__
- return ["{}/{}{}.html".format(app_label, to_snake(model_name), self.template_name_suffix)]
+ return [f"{app_label}/{to_snake(model_name)}{self.template_name_suffix}.html"]
class ProjectInContextMixin:
diff --git a/coldfront/plugins/freeipa/management/commands/freeipa_check.py b/coldfront/plugins/freeipa/management/commands/freeipa_check.py
index 165b033127..6ef3afbc61 100644
--- a/coldfront/plugins/freeipa/management/commands/freeipa_check.py
+++ b/coldfront/plugins/freeipa/management/commands/freeipa_check.py
@@ -44,7 +44,7 @@ def add_arguments(self, parser):
def writerow(self, row):
try:
- self.stdout.write("{0: <12}{1: <20}{2: <30}{3}".format(*row))
+ self.stdout.write(f"{row[0]:<20}{row[1]:<15}{row[2]}")
except BrokenPipeError:
devnull = os.open(os.devnull, os.O_WRONLY)
os.dup2(devnull, sys.stdout.fileno())
diff --git a/coldfront/plugins/freeipa/management/commands/freeipa_expire_users.py b/coldfront/plugins/freeipa/management/commands/freeipa_expire_users.py
index 3bd0bcdd09..6029e87a81 100644
--- a/coldfront/plugins/freeipa/management/commands/freeipa_expire_users.py
+++ b/coldfront/plugins/freeipa/management/commands/freeipa_expire_users.py
@@ -29,7 +29,7 @@ def add_arguments(self, parser):
def writerow(self, row):
try:
- self.stdout.write("{0: <20}{1: <15}{2}".format(*row))
+ self.stdout.write(f"{row[0]:<20}{row[1]:<15}{row[2]}")
except BrokenPipeError:
devnull = os.open(os.devnull, os.O_WRONLY)
os.dup2(devnull, sys.stdout.fileno())
diff --git a/coldfront/plugins/freeipa/search.py b/coldfront/plugins/freeipa/search.py
index 12da2f9cab..d34a3da3e9 100644
--- a/coldfront/plugins/freeipa/search.py
+++ b/coldfront/plugins/freeipa/search.py
@@ -25,7 +25,7 @@ def __init__(self, user_search_string, search_by):
self.FREEIPA_USER_SEARCH_BASE = import_from_settings("FREEIPA_USER_SEARCH_BASE", "cn=users,cn=accounts")
self.FREEIPA_KTNAME = import_from_settings("FREEIPA_KTNAME", "")
- self.server = Server("ldap://{}".format(self.FREEIPA_SERVER), use_ssl=True, connect_timeout=1)
+ self.server = Server(f"ldap://{self.FREEIPA_SERVER}", use_ssl=True, connect_timeout=1)
if len(self.FREEIPA_KTNAME) > 0:
logger.info("Kerberos bind enabled: %s", self.FREEIPA_KTNAME)
# kerberos SASL/GSSAPI bind
@@ -36,7 +36,7 @@ def __init__(self, user_search_string, search_by):
self.conn = Connection(self.server, auto_bind=True)
if not self.conn.bind():
- raise ImproperlyConfigured("Failed to bind to LDAP server: {}".format(self.conn.result))
+ raise ImproperlyConfigured(f"Failed to bind to LDAP server: {self.conn.result}")
else:
logger.info("LDAP bind successful: %s", self.conn.extend.standard.who_am_i())
diff --git a/coldfront/plugins/freeipa/utils.py b/coldfront/plugins/freeipa/utils.py
index 0893bf9662..c76eabfc97 100644
--- a/coldfront/plugins/freeipa/utils.py
+++ b/coldfront/plugins/freeipa/utils.py
@@ -36,7 +36,7 @@ class NotMemberError(ApiError):
api.Backend.rpcclient.connect()
except Exception as e:
logger.error("Failed to initialze FreeIPA lib: %s", e)
- raise ImproperlyConfigured("Failed to initialze FreeIPA: {0}".format(e))
+ raise ImproperlyConfigured(f"Failed to initialze FreeIPA: {e}")
def check_ipa_group_error(res):
diff --git a/coldfront/plugins/iquota/utils.py b/coldfront/plugins/iquota/utils.py
index 9b63bcc3a9..8fb458664b 100644
--- a/coldfront/plugins/iquota/utils.py
+++ b/coldfront/plugins/iquota/utils.py
@@ -49,14 +49,14 @@ def get_user_quota(self):
token = self.gssclient_token()
headers = {"Authorization": "Negotiate " + token}
- url = "https://{}:{}/quota?user={}".format(self.IQUOTA_API_HOST, self.IQUOTA_API_PORT, self.username)
+ url = f"https://{self.IQUOTA_API_HOST}:{self.IQUOTA_API_PORT}/quota?user={self.username}"
r = requests.get(url, headers=headers, verify=self.IQUOTA_CA_CERT)
try:
usage = r.json()[0]
except KeyError:
- raise MissingQuotaError("Missing user quota for username: %s" % (self.username))
+ raise MissingQuotaError(f"Missing user quota for username: {self.username}")
else:
user_used = usage["used"]
user_limit = usage["soft_limit"]
@@ -77,7 +77,7 @@ def _get_group_quota(self, group):
headers = {"Authorization": "Negotiate " + token}
- url = "https://{}:{}/quota?group={}".format(self.IQUOTA_API_HOST, self.IQUOTA_API_PORT, group)
+ url = f"https://{self.IQUOTA_API_HOST}:{self.IQUOTA_API_PORT}/quota?group={group}"
r = requests.get(url, headers=headers, verify=self.IQUOTA_CA_CERT)
diff --git a/coldfront/plugins/mokey_oidc/auth.py b/coldfront/plugins/mokey_oidc/auth.py
index b8d5d77e7c..1316469494 100644
--- a/coldfront/plugins/mokey_oidc/auth.py
+++ b/coldfront/plugins/mokey_oidc/auth.py
@@ -93,7 +93,7 @@ def filter_users_by_claims(self, claims):
return self.UserModel.objects.none()
def verify_claims(self, claims):
- verified = super(OIDCMokeyAuthenticationBackend, self).verify_claims(claims)
+ verified = super().verify_claims(claims)
if len(ALLOWED_GROUPS) == 0 and len(DENY_GROUPS) == 0:
return verified and True
diff --git a/coldfront/plugins/slurm/associations.py b/coldfront/plugins/slurm/associations.py
index 28b74fde92..d1c519b5db 100644
--- a/coldfront/plugins/slurm/associations.py
+++ b/coldfront/plugins/slurm/associations.py
@@ -77,7 +77,7 @@ def new_from_stream(stream):
parts = line.split(":")
name = re.sub(r"^Cluster - ", "", parts[0]).strip("\n'")
if len(name) == 0:
- raise (SlurmParserError("Cluster name not found for line: {}".format(line)))
+ raise (SlurmParserError(f"Cluster name not found for line: {line}"))
cluster = SlurmCluster(name)
cluster.specs += parts[1:]
elif re.match("^Account - '[^']+'", line):
@@ -88,11 +88,11 @@ def new_from_stream(stream):
if parent == "root":
cluster.accounts["root"] = SlurmAccount("root")
if not parent:
- raise (SlurmParserError("Parent name not found for line: {}".format(line)))
+ raise (SlurmParserError(f"Parent name not found for line: {line}"))
elif re.match("^User - '[^']+'", line):
user = SlurmUser.new_from_sacctmgr(line)
if not parent:
- raise (SlurmParserError("Found user record without Parent for line: {}".format(line)))
+ raise (SlurmParserError(f"Found user record without Parent for line: {line}"))
account = cluster.accounts[parent]
account.add_user(user)
cluster.accounts[parent] = account
@@ -109,7 +109,7 @@ def new_from_resource(resource):
specs = resource.get_attribute_list(SLURM_SPECS_ATTRIBUTE_NAME)
user_specs = resource.get_attribute_list(SLURM_USER_SPECS_ATTRIBUTE_NAME)
if not name:
- raise (SlurmError("Resource {} missing slurm_cluster".format(resource)))
+ raise (SlurmError(f"Resource {resource} missing slurm_cluster"))
cluster = SlurmCluster(name, specs)
@@ -143,13 +143,10 @@ def add_allocation(self, allocation, specs=None, user_specs=None):
self.accounts[name] = account
def write(self, out):
- self._write(out, "# ColdFront Allocation Slurm associations dump {}\n".format(datetime.datetime.now().date()))
+ self._write(out, f"# ColdFront Allocation Slurm associations dump {datetime.datetime.now().date()}\n")
self._write(
out,
- "Cluster - '{}':{}\n".format(
- self.name,
- self.format_specs(),
- ),
+ f"Cluster - '{self.name}':{self.format_specs()}\n",
)
if "root" in self.accounts:
self.accounts["root"].write(out)
@@ -176,12 +173,12 @@ def new_from_sacctmgr(line):
"""Create a new SlurmAccount by parsing a line from sacctmgr dump. For
example: Account - 'physics':Description='physics group':Organization='cas':Fairshare=100"""
if not re.match("^Account - '[^']+'", line):
- raise (SlurmParserError('Invalid format. Must start with "Account" for line: {}'.format(line)))
+ raise (SlurmParserError(f'Invalid format. Must start with "Account" for line: {line}'))
parts = line.split(":")
name = re.sub(r"^Account - ", "", parts[0]).strip("\n'")
if len(name) == 0:
- raise (SlurmParserError("Cluster name not found for line: {}".format(line)))
+ raise (SlurmParserError(f"Cluster name not found for line: {line}"))
return SlurmAccount(name, specs=parts[1:])
@@ -195,7 +192,7 @@ def add_allocation(self, allocation, user_specs=None):
name = "root"
if name != self.name:
- raise (SlurmError("Allocation {} slurm_account_name does not match {}".format(allocation, self.name)))
+ raise (SlurmError(f"Allocation {allocation} slurm_account_name does not match {self.name}"))
self.specs += allocation.get_attribute_list(SLURM_SPECS_ATTRIBUTE_NAME)
@@ -218,14 +215,11 @@ def write(self, out):
if self.name != "root":
self._write(
out,
- "Account - '{}':{}\n".format(
- self.name,
- self.format_specs(),
- ),
+ f"Account - '{self.name}':{self.format_specs()}\n",
)
def write_users(self, out):
- self._write(out, "Parent - '{}'\n".format(self.name))
+ self._write(out, f"Parent - '{self.name}'\n")
for uid, user in self.users.items():
user.write(out)
@@ -236,20 +230,17 @@ def new_from_sacctmgr(line):
"""Create a new SlurmUser by parsing a line from sacctmgr dump. For
example: User - 'jane':DefaultAccount='physics':Fairshare=Parent:QOS='general-compute'"""
if not re.match("^User - '[^']+'", line):
- raise (SlurmParserError('Invalid format. Must start with "User" for line: {}'.format(line)))
+ raise (SlurmParserError(f'Invalid format. Must start with "User" for line: {line}'))
parts = line.split(":")
name = re.sub(r"^User - ", "", parts[0]).strip("\n'")
if len(name) == 0:
- raise (SlurmParserError("User name not found for line: {}".format(line)))
+ raise (SlurmParserError(f"User name not found for line: {line}"))
return SlurmUser(name, specs=parts[1:])
def write(self, out):
self._write(
out,
- "User - '{}':{}\n".format(
- self.name,
- self.format_specs(),
- ),
+ f"User - '{self.name}':{self.format_specs()}\n",
)
diff --git a/coldfront/plugins/slurm/management/commands/slurm_dump.py b/coldfront/plugins/slurm/management/commands/slurm_dump.py
index 5e590f8628..a9d5ee58a5 100644
--- a/coldfront/plugins/slurm/management/commands/slurm_dump.py
+++ b/coldfront/plugins/slurm/management/commands/slurm_dump.py
@@ -53,5 +53,5 @@ def handle(self, *args, **options):
cluster.write(self.stdout)
continue
- with open(os.path.join(out_dir, "{}.cfg".format(cluster.name)), "w") as fh:
+ with open(os.path.join(out_dir, f"{cluster.name}.cfg"), "w") as fh:
cluster.write(fh)
diff --git a/coldfront/plugins/slurm/tests/test_associations.py b/coldfront/plugins/slurm/tests/test_associations.py
index 7d97ea55ef..5a20689b47 100644
--- a/coldfront/plugins/slurm/tests/test_associations.py
+++ b/coldfront/plugins/slurm/tests/test_associations.py
@@ -21,7 +21,7 @@ def setUpClass(cls):
call_command("add_default_project_choices")
call_command("add_default_allocation_choices")
call_command("add_default_publication_sources")
- super(AssociationTest, cls).setUpClass()
+ super().setUpClass()
def test_allocations_to_slurm(self):
resource = Resource.objects.get(name="University HPC")
diff --git a/coldfront/plugins/slurm/utils.py b/coldfront/plugins/slurm/utils.py
index 7f8bf9db48..a72eae6f18 100644
--- a/coldfront/plugins/slurm/utils.py
+++ b/coldfront/plugins/slurm/utils.py
@@ -44,7 +44,7 @@ def _run_slurm_cmd(cmd, noop=True):
return
try:
- result = subprocess.run(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
+ result = subprocess.run(shlex.split(cmd), check=True, capture_output=True)
except subprocess.CalledProcessError as e:
if "Nothing deleted" in str(e.stdout):
# We tried to delete something that didn't exist. Don't throw error
@@ -56,7 +56,7 @@ def _run_slurm_cmd(cmd, noop=True):
return e.stdout
logger.error("Slurm command failed: %s", cmd)
- err_msg = "return_value={} stdout={} stderr={}".format(e.returncode, e.stdout, e.stderr)
+ err_msg = f"return_value={e.returncode} stdout={e.stdout} stderr={e.stderr}"
raise SlurmError(err_msg)
logger.debug("Slurm cmd: %s", cmd)
diff --git a/coldfront/plugins/system_monitor/utils.py b/coldfront/plugins/system_monitor/utils.py
index 98ec886c19..0361adf5e7 100644
--- a/coldfront/plugins/system_monitor/utils.py
+++ b/coldfront/plugins/system_monitor/utils.py
@@ -103,12 +103,13 @@ def parse_html_using_beautiful_soup(self):
utilized_percent = round(processors_utilized[0] / processors_utilized[1] * 1000) / 10
free_percent = round(free / processors_utilized[1] * 1000) / 10
- utilized_label = "Processors Utilized: %s (%s%%)" % (processors_utilized[0], utilized_percent)
- free_label = "Processors Free: %s (%s%%)" % (free, free_percent)
+ utilized_label = f"Processors Utilized: {processors_utilized[0]} ({utilized_percent}%)"
+ free_label = f"Processors Free: {free} ({free_percent}%)"
+
utilized_value = processors_utilized[0]
free_value = free
- running_label = "Running: %s" % (jobs[0])
- queued_label = "Queued: %s" % (jobs[1])
+ running_label = f"Running: {jobs[0]}"
+ queued_label = f"Queued: {jobs[1]}"
running_value = job_numbers[0]
queued_value = job_numbers[1]
except Exception:
diff --git a/coldfront/plugins/xdmod/utils.py b/coldfront/plugins/xdmod/utils.py
index 7922ad325e..c8e3f14885 100644
--- a/coldfront/plugins/xdmod/utils.py
+++ b/coldfront/plugins/xdmod/utils.py
@@ -53,9 +53,9 @@ def xdmod_fetch_total_cpu_hours(start, end, account, resources=None, statistics=
if resources is None:
resources = []
- url = "{}{}".format(XDMOD_API_URL, _ENDPOINT_CORE_HOURS)
+ url = f"{XDMOD_API_URL}{_ENDPOINT_CORE_HOURS}"
payload = _DEFAULT_PARAMS
- payload["pi_filter"] = '"{}"'.format(account)
+ payload["pi_filter"] = f'"{account}"'
payload["resource_filter"] = '"{}"'.format(",".join(resources))
payload["start_date"] = start
payload["end_date"] = end
@@ -72,7 +72,7 @@ def xdmod_fetch_total_cpu_hours(start, end, account, resources=None, statistics=
error = r.json()
# XXX fix me. Here we assume any json response is bad as we're
# expecting xml but XDMoD should just return json always.
- raise XdmodNotFoundError("Got json response but expected XML: {}".format(error))
+ raise XdmodNotFoundError(f"Got json response but expected XML: {error}")
except json.decoder.JSONDecodeError:
pass
except requests.exceptions.JSONDecodeError:
@@ -81,11 +81,11 @@ def xdmod_fetch_total_cpu_hours(start, end, account, resources=None, statistics=
try:
root = ET.fromstring(r.text)
except ET.ParserError as e:
- raise XdmodError("Invalid XML data returned from XDMoD API: {}".format(e))
+ raise XdmodError(f"Invalid XML data returned from XDMoD API: {e}")
rows = root.find("rows")
if len(rows) != 1:
- raise XdmodNotFoundError("Rows not found for {} - {}".format(account, resources))
+ raise XdmodNotFoundError(f"Rows not found for {account} - {resources}")
cells = rows.find("row").findall("cell")
if len(cells) != 2:
@@ -103,9 +103,9 @@ def xdmod_fetch_total_storage(start, end, account, resources=None, statistics="p
payload_end = end
if payload_end is None:
payload_end = "2099-01-01"
- url = "{}{}".format(XDMOD_API_URL, _ENDPOINT_CORE_HOURS)
+ url = f"{XDMOD_API_URL}{_ENDPOINT_CORE_HOURS}"
payload = _DEFAULT_PARAMS
- payload["pi_filter"] = '"{}"'.format(account)
+ payload["pi_filter"] = f'"{account}"'
payload["resource_filter"] = "{}".format(",".join(resources))
payload["start_date"] = start
payload["end_date"] = payload_end
@@ -121,11 +121,11 @@ def xdmod_fetch_total_storage(start, end, account, resources=None, statistics="p
try:
root = ET.fromstring(r.text)
except ET.ParserError as e:
- raise XdmodError("Invalid XML data returned from XDMoD API: {}".format(e))
+ raise XdmodError(f"Invalid XML data returned from XDMoD API: {e}")
rows = root.find("rows")
if len(rows) != 1:
- raise XdmodNotFoundError("Rows not found for {} - {}".format(account, resources))
+ raise XdmodNotFoundError(f"Rows not found for {account} - {resources}")
cells = rows.find("row").findall("cell")
if len(cells) != 2:
@@ -140,7 +140,7 @@ def xdmod_fetch_cloud_core_time(start, end, project, resources=None):
if resources is None:
resources = []
- url = "{}{}".format(XDMOD_API_URL, _ENDPOINT_CORE_HOURS)
+ url = f"{XDMOD_API_URL}{_ENDPOINT_CORE_HOURS}"
payload = _DEFAULT_PARAMS
payload["project_filter"] = project
payload["resource_filter"] = '"{}"'.format(",".join(resources))
@@ -159,18 +159,18 @@ def xdmod_fetch_cloud_core_time(start, end, project, resources=None):
error = r.json()
# XXX fix me. Here we assume any json response is bad as we're
# expecting xml but XDMoD should just return json always.
- raise XdmodNotFoundError("Got json response but expected XML: {}".format(error))
+ raise XdmodNotFoundError(f"Got json response but expected XML: {error}")
except json.decoder.JSONDecodeError:
pass
try:
root = ET.fromstring(r.text)
except ET.ParserError as e:
- raise XdmodError("Invalid XML data returned from XDMoD API: {}".format(e))
+ raise XdmodError(f"Invalid XML data returned from XDMoD API: {e}")
rows = root.find("rows")
if len(rows) != 1:
- raise XdmodNotFoundError("Rows not found for {} - {}".format(project, resources))
+ raise XdmodNotFoundError(f"Rows not found for {project} - {resources}")
cells = rows.find("row").findall("cell")
if len(cells) != 2:
diff --git a/pyproject.toml b/pyproject.toml
index 33bf9873f8..a20069512c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -107,7 +107,7 @@ indent-width = 4
target-version = "py312"
[tool.ruff.lint]
-select = ["E4", "E7", "E9", "F", "I"]
+select = ["E4", "E7", "E9", "F", "I", "UP"]
[tool.ruff.format]
indent-style = "space"