diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml
index e1f87adb2..d41d276d0 100644
--- a/.github/workflows/ruff.yml
+++ b/.github/workflows/ruff.yml
@@ -15,4 +15,4 @@ jobs:
- uses: astral-sh/ruff-action@v3
with:
src: "./oioioi"
- version: 0.11.12
\ No newline at end of file
+ version: 0.13.2
\ No newline at end of file
diff --git a/conftest.py b/conftest.py
index 10f6cb198..e5ea66eb4 100644
--- a/conftest.py
+++ b/conftest.py
@@ -1,10 +1,7 @@
-from __future__ import print_function
-
import pytest
-
+from django.conf import settings
from oioioi.base.tests import pytest_plugin as base_plugin
from oioioi.contests.tests import pytest_plugin as contests_plugin
-from django.conf import settings
def pytest_addoption(parser):
diff --git a/ez_setup.py b/ez_setup.py
index d6f8ab522..455c5d505 100644
--- a/ez_setup.py
+++ b/ez_setup.py
@@ -14,8 +14,6 @@
This file can also be run as a script to install or upgrade setuptools.
"""
-from __future__ import print_function
-
import os
import sys
@@ -25,7 +23,7 @@
from md5 import md5
DEFAULT_VERSION = "0.6c11"
-DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
+DEFAULT_URL = f"http://pypi.python.org/packages/{sys.version[:3]}/s/setuptools/"
md5_data = {
"setuptools-0.6b1-py2.3.egg": "8822caf901250d848b996b7f25c6e6ca",
@@ -78,7 +76,7 @@ def _validate_md5(egg_name, data):
digest = md5(data).hexdigest()
if digest != md5_data[egg_name]:
print(
- ("md5 validation of %s failed! (Possible download problem?)" % egg_name),
+ (f"md5 validation of {egg_name} failed! (Possible download problem?)"),
file=sys.stderr,
)
sys.exit(2)
@@ -122,12 +120,11 @@ def do_download():
if was_imported:
print(
(
- "The required version of setuptools (>=%s) is not available, and\n"
+ f"The required version of setuptools (>={version}) is not available, and\n"
"can't be installed while this script is running. Please install\n"
" a more recent version first, using 'easy_install -U setuptools'."
- "\n\n(Currently using %r)"
- )
- % (version, e.args[0]),
+ f"\n\n(Currently using {e.args[0]!r})"
+ ),
file=sys.stderr,
)
sys.exit(2)
@@ -148,7 +145,7 @@ def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_d
"""
import urllib.request
- egg_name = "setuptools-%s-py%s.egg" % (version, sys.version[:3])
+ egg_name = f"setuptools-{version}-py{sys.version[:3]}.egg"
url = download_base + egg_name
saveto = os.path.join(to_dir, egg_name)
src = dst = None
@@ -251,7 +248,7 @@ def update_md5(filenames):
md5_data[base] = md5(f.read()).hexdigest()
f.close()
- data = [" %r: %r,\n" % it for it in md5_data.items()]
+ data = [" {!r}: {!r},\n".format(*it) for it in md5_data.items()]
data.sort()
repl = "".join(data)
diff --git a/oioioi/__init__.py b/oioioi/__init__.py
index a8063f0ac..5470ef493 100644
--- a/oioioi/__init__.py
+++ b/oioioi/__init__.py
@@ -1,2 +1,2 @@
# apply monkey patch
-from oioioi.contests import current_contest
+from oioioi.contests import current_contest # noqa: F401
diff --git a/oioioi/acm/controllers.py b/oioioi/acm/controllers.py
index 537f8a45d..aa5f25a3d 100644
--- a/oioioi/acm/controllers.py
+++ b/oioioi/acm/controllers.py
@@ -66,7 +66,7 @@ def fill_evaluation_environ(self, environ, submission):
environ["score_aggregator"] = "oioioi.acm.utils.acm_score_aggregator"
environ["report_kinds"] = ["FULL"]
- super(ACMContestController, self).fill_evaluation_environ(environ, submission)
+ super().fill_evaluation_environ(environ, submission)
def update_report_statuses(self, submission, queryset):
if submission.kind == "TESTRUN":
@@ -77,7 +77,7 @@ def update_report_statuses(self, submission, queryset):
def update_submission_score(self, submission):
if submission.kind == "TESTRUN":
- super(ACMContestController, self).update_submission_score(submission)
+ super().update_submission_score(submission)
return
try:
report = SubmissionReport.objects.get(submission=submission, status="ACTIVE", kind="FULL")
@@ -111,7 +111,7 @@ def __init__(self, user):
def _fill_user_result_for_problem(self, result, pi_submissions):
if pi_submissions:
- for penalties_count, submission in enumerate(pi_submissions, 1):
+ for penalties_count, submission in enumerate(pi_submissions, 1): # noqa: B007
if submission.status == "IGN":
# We have found IGNORED submission before accepted one.
# This means, that some other
@@ -213,7 +213,7 @@ def can_submit(self, request, problem_instance, check_round_times=True):
return True
if not is_participant(request):
return False
- return super(ACMOpenContestController, self).can_submit(request, problem_instance, check_round_times)
+ return super().can_submit(request, problem_instance, check_round_times)
class _FakeUserResultForProblem:
diff --git a/oioioi/acm/score.py b/oioioi/acm/score.py
index 5873b4d92..654f5dd76 100644
--- a/oioioi/acm/score.py
+++ b/oioioi/acm/score.py
@@ -7,7 +7,7 @@
def format_time(seconds):
minutes = seconds // 60
- return "%d:%02d" % (minutes // 60, minutes % 60)
+ return f"{minutes // 60}:{minutes % 60:02d}"
@total_ordering
@@ -143,14 +143,10 @@ def penalty_repr(self):
if self.penalties_count <= 3:
return "*" * self.penalties_count
else:
- return "*(%d)" % (self.penalties_count,)
+ return f"*({self.penalties_count})"
def total_time_repr(self):
- return "%d:%02d:%02d" % (
- self.total_time / 3600,
- (self.total_time % 3600) / 60,
- self.total_time % 60,
- )
+ return f"{int(self.total_time / 3600)}:{int((self.total_time % 3600) / 60):02d}:{int(self.total_time % 60):02d}"
def time_passed_repr(self):
return format_time(self.time_passed)
@@ -182,13 +178,7 @@ def _to_repr(self):
``penalties_count`` is number of unsuccessful submissions.
"""
ordering = 10**10 * (self.problems_solved + 1) - self.total_time
- return "%020d:%010d:%010d:%010d:%010d" % (
- ordering,
- self.problems_solved,
- self.time_passed,
- self.penalties_count,
- self.penalty_time,
- )
+ return f"{int(ordering):020d}:{self.problems_solved:010d}:{self.time_passed:010d}:{self.penalties_count:010d}:{self.penalty_time:010d}"
@property
def total_time(self):
diff --git a/oioioi/amppz/controllers.py b/oioioi/amppz/controllers.py
index 478990e6e..f4edd7932 100644
--- a/oioioi/amppz/controllers.py
+++ b/oioioi/amppz/controllers.py
@@ -41,7 +41,7 @@ def default_can_see_ranking(self, request):
return is_contest_admin(request) or is_contest_observer(request)
def default_contestlogo_url(self):
- return "%samppz/images/logo-cropped.png" % settings.STATIC_URL
+ return f"{settings.STATIC_URL}amppz/images/logo-cropped.png"
def default_contesticons_urls(self):
- return ["%samppz/images/menu-icon.png" % settings.STATIC_URL]
+ return [f"{settings.STATIC_URL}amppz/images/menu-icon.png"]
diff --git a/oioioi/balloons/admin.py b/oioioi/balloons/admin.py
index d985be620..273b63290 100644
--- a/oioioi/balloons/admin.py
+++ b/oioioi/balloons/admin.py
@@ -45,7 +45,7 @@ def color_display(self, instance):
color_display.short_description = _("Color")
def get_queryset(self, request):
- qs = super(ProblemBalloonsConfigAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
return qs.filter(problem_instance__contest=request.contest)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
@@ -54,7 +54,7 @@ def formfield_for_foreignkey(self, db_field, request, **kwargs):
if request.contest:
qs = qs.filter(contest=request.contest)
kwargs["queryset"] = qs
- return super(ProblemBalloonsConfigAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ return super().formfield_for_foreignkey(db_field, request, **kwargs)
contest_site.contest_register(ProblemBalloonsConfig, ProblemBalloonsConfigAdmin)
@@ -85,7 +85,7 @@ def get_readonly_fields(self, request, obj=None):
return self.readonly_fields
def get_queryset(self, request):
- qs = super(BalloonsDisplayAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
if request.contest is None:
return qs
return qs.filter(contest=request.contest)
@@ -101,7 +101,7 @@ def formfield_for_foreignkey(self, db_field, request, **kwargs):
if qs or not request.user.is_superuser:
kwargs["queryset"] = qs
- return super(BalloonsDisplayAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ return super().formfield_for_foreignkey(db_field, request, **kwargs)
admin.site.register(BalloonsDisplay, BalloonsDisplayAdmin)
@@ -159,7 +159,7 @@ class BalloonsDeliveryAccessDataAdminMixin:
"""
def __init__(self, *args, **kwargs):
- super(BalloonsDeliveryAccessDataAdminMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.inlines = tuple(self.inlines) + (BalloonsDeliveryAccessDataInline,)
diff --git a/oioioi/balloons/controllers.py b/oioioi/balloons/controllers.py
index 2be26bc2e..fd053be94 100644
--- a/oioioi/balloons/controllers.py
+++ b/oioioi/balloons/controllers.py
@@ -16,7 +16,7 @@ class BalloonsDeliveryACMControllerMixin:
"""
def submission_judged(self, submission, rejudged=False):
- super(BalloonsDeliveryACMControllerMixin, self).submission_judged(submission, rejudged)
+ super().submission_judged(submission, rejudged)
self._create_balloon_delivery(submission)
@transaction.atomic
diff --git a/oioioi/balloons/models.py b/oioioi/balloons/models.py
index c3e3783b1..1888a1aaf 100644
--- a/oioioi/balloons/models.py
+++ b/oioioi/balloons/models.py
@@ -56,11 +56,11 @@ class Meta:
ordering = ["id"]
def __str__(self):
- return "%(user)s for %(problem)s (%(delivered)s)" % {
- "user": self.user,
- "problem": self.problem_instance,
- "delivered": "delivered" if self.delivered else "not delivered",
- }
+ return "{user} for {problem} ({delivered})".format(
+ user=self.user,
+ problem=self.problem_instance,
+ delivered="delivered" if self.delivered else "not delivered",
+ )
class BalloonsDeliveryAccessData(models.Model):
diff --git a/oioioi/balloons/views.py b/oioioi/balloons/views.py
index 710fe30fc..daac60533 100644
--- a/oioioi/balloons/views.py
+++ b/oioioi/balloons/views.py
@@ -24,7 +24,7 @@
@make_request_condition
def has_balloons_cookie(request):
try:
- key = request.COOKIES["balloons_access_%s" % request.contest.id]
+ key = request.COOKIES[f"balloons_access_{request.contest.id}"]
access_data = BalloonsDeliveryAccessData.objects.get(contest__id=request.contest.id, access_key=key)
except (KeyError, BalloonsDeliveryAccessData.DoesNotExist):
return False
@@ -115,7 +115,7 @@ def balloons_access_cookie_view(request, access_key):
access_data.save()
response = redirect("balloons_delivery_panel", contest_id=request.contest.id)
response.set_cookie(
- key="balloons_access_%s" % request.contest.id,
+ key=f"balloons_access_{request.contest.id}",
value=access_key,
expires=validity_date,
)
diff --git a/oioioi/base/admin.py b/oioioi/base/admin.py
index 5b366bf3b..61ab25f34 100644
--- a/oioioi/base/admin.py
+++ b/oioioi/base/admin.py
@@ -74,10 +74,10 @@ def response_change(self, request, obj):
return HttpResponseRedirect(request.get_full_path())
if "came_from" in request.GET and "_continue" not in request.POST and "_saveasnew" not in request.POST and "_addanother" not in request.POST:
return safe_redirect(request, request.GET.get("came_from"))
- return super(ModelAdmin, self).response_change(request, obj)
+ return super().response_change(request, obj)
def change_view(self, request, object_id, form_url="", extra_context=None):
- response = super(ModelAdmin, self).change_view(request, object_id, form_url, extra_context)
+ response = super().change_view(request, object_id, form_url, extra_context)
if isinstance(response, TemplateResponse) and "came_from" in request.GET:
response.context_data["form_url"] += "?" + urllib.parse.urlencode({"came_from": request.GET.get("came_from")})
return response
@@ -90,7 +90,7 @@ def response_delete(self, request):
return HttpResponseRedirect(reverse("admin:index", current_app=self.admin_site.name))
return HttpResponseRedirect(
reverse(
- "admin:%s_%s_changelist" % (opts.app_label, opts.model_name),
+ f"admin:{opts.app_label}_{opts.model_name}_changelist",
current_app=self.admin_site.name,
)
)
@@ -134,8 +134,8 @@ def delete_view(self, request, object_id, extra_context=None):
request,
self.delete_confirmation_template
or [
- "admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower()),
- "admin/%s/delete_confirmation.html" % app_label,
+ f"admin/{app_label}/{opts.object_name.lower()}/delete_confirmation.html",
+ f"admin/{app_label}/delete_confirmation.html",
"admin/delete_confirmation.html",
],
context,
@@ -149,7 +149,7 @@ def get_custom_list_select_related(self):
return []
def get_queryset(self, request):
- qs = super(ModelAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
list_select_related = self.get_custom_list_select_related()
if list_select_related:
return qs.select_related(*list_select_related)
@@ -238,8 +238,8 @@ def delete_selected(modeladmin, request, queryset, **kwargs):
request,
custom_template
or [
- "admin/%s/%s/delete_selected_confirmation.html" % (app_label, opts.model_name),
- "admin/%s/delete_selected_confirmation.html" % app_label,
+ f"admin/{app_label}/{opts.model_name}/delete_selected_confirmation.html",
+ f"admin/{app_label}/delete_selected_confirmation.html",
"admin/delete_selected_confirmation.html",
],
context,
@@ -274,7 +274,7 @@ def format_callback(obj):
if not request.user.is_superuser and not model_admin.has_delete_permission(request, obj):
perms_needed.add(opts.verbose_name)
- return "%s: %s" % (capfirst(force_str(opts.verbose_name)), force_str(obj))
+ return f"{capfirst(force_str(opts.verbose_name))}: {force_str(obj)}"
# Get a nested list of dependent objects
to_delete = collector.nested(format_callback)
@@ -286,7 +286,7 @@ def format_callback(obj):
class AdminSite(DjangoAdminSite):
def __init__(self, *args, **kwargs):
- super(AdminSite, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
# Override default delete_selected action handler
# See delete_selected() docstring for further information
self._actions["delete_selected"] = delete_selected
@@ -303,7 +303,7 @@ def _reinit_model_admins(self):
def get_urls(self):
self._reinit_model_admins()
- return super(AdminSite, self).get_urls()
+ return super().get_urls()
def login(self, request, extra_context=None):
next_url = request.GET.get("next", None)
@@ -427,7 +427,7 @@ def has_delete_permission(self, request, obj=None):
class UserWithConsentsAdminMixin:
def __init__(self, *args, **kwargs):
- super(UserWithConsentsAdminMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.inlines = tuple(self.inlines) + (ConsentsInline,)
diff --git a/oioioi/base/fields.py b/oioioi/base/fields.py
index 4da370552..9c38a9549 100644
--- a/oioioi/base/fields.py
+++ b/oioioi/base/fields.py
@@ -45,7 +45,7 @@ def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH, limit_
_choices = self._generate_choices()
# pylint: disable=W0125
choices = list(_choices) if _choices else []
- named_groups = choices and isinstance(choices[0][1], (list, tuple))
+ named_groups = choices and isinstance(choices[0][1], list | tuple)
if not named_groups:
for choice, __ in choices:
if choice in ("", None):
@@ -93,7 +93,7 @@ def validate(self, value, model_instance):
superclass = self._get_superclass()
if not issubclass(obj, superclass):
- raise ValidationError(_("%(value)s is not a %(class_name)s") % dict(value=value, class_name=superclass.__name__))
+ raise ValidationError(_("%(value)s is not a %(class_name)s") % {"value": value, "class_name": superclass.__name__})
if getattr(obj, "abstract", False):
raise ValidationError(_("%s is an abstract class and cannot be used") % (value,))
@@ -107,11 +107,11 @@ def validate(self, value, model_instance):
if _choices and value not in self.empty_values:
for option_key, option_value in _choices:
- if isinstance(option_value, (list, tuple)):
+ if isinstance(option_value, list | tuple):
# This is an optgroup, so look inside the group for
# options.
# pylint: disable=W0612
- for optgroup_key, optgroup_value in option_value:
+ for optgroup_key, _optgroup_value in option_value:
if value == optgroup_key:
return
elif value == option_key:
@@ -139,17 +139,17 @@ def _generate_choices(self):
subclasses = superclass.subclasses
if subclasses:
for subclass in subclasses:
- dotted_name = "%s.%s" % (subclass.__module__, subclass.__name__)
+ dotted_name = f"{subclass.__module__}.{subclass.__name__}"
human_readable_name = getattr(subclass, "description", dotted_name)
yield dotted_name, human_readable_name
def to_python(self, value):
superclass = self._get_superclass()
superclass.load_subclasses()
- return super(DottedNameField, self).to_python(value)
+ return super().to_python(value)
def deconstruct(self):
- name, path, args, kwargs = super(DottedNameField, self).deconstruct()
+ name, path, args, kwargs = super().deconstruct()
kwargs["superclass"] = self.superclass_name
del kwargs["max_length"]
return name, path, args, kwargs
@@ -175,7 +175,7 @@ def __getitem__(self, key):
def register(self, value, description):
if len(value) > self.max_length:
- raise ValueError("Enum values must not be longer than %d chars" % (self.max_length,))
+ raise ValueError(f"Enum values must not be longer than {self.max_length} chars")
if not self.entries or value not in next(zip(*self.entries, strict=False)):
self.entries.append((value, description))
@@ -210,7 +210,7 @@ def __init__(self, registry=None, *args, **kwargs):
# This allows this field to be stored for migration purposes
# without the need to serialize an EnumRegistry object.
# Instead, we serialize 'max_length' and 'choices'.
- assert isinstance(registry, EnumRegistry), "Invalid registry passed to EnumField.__init__: %r" % (registry,)
+ assert isinstance(registry, EnumRegistry), f"Invalid registry passed to EnumField.__init__: {registry!r}"
kwargs["max_length"] = registry.max_length
kwargs["choices"] = self._generate_choices()
models.CharField.__init__(self, *args, **kwargs)
@@ -219,7 +219,7 @@ def _generate_choices(self):
return list(self.registry.entries)
def deconstruct(self):
- name, path, args, kwargs = super(EnumField, self).deconstruct()
+ name, path, args, kwargs = super().deconstruct()
kwargs.pop("choices", None)
return name, path, args, kwargs
@@ -243,10 +243,10 @@ def __init__(self, *args, **kwargs):
kwargs["validators"] = [RegexValidator(r"^\+?[0-9() -]{6,}$", _("Invalid phone number"))]
kwargs["help_text"] = _("Including the area code.")
- super(PhoneNumberField, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def deconstruct(self):
- name, path, args, kwargs = super(PhoneNumberField, self).deconstruct()
+ name, path, args, kwargs = super().deconstruct()
del kwargs["max_length"]
del kwargs["validators"]
del kwargs["help_text"]
@@ -260,10 +260,10 @@ def __init__(self, *args, **kwargs):
kwargs["max_length"] = 6
kwargs["validators"] = [RegexValidator(r"^\d{2}-\d{3}$", _("Enter a postal code in the format XX-XXX"))]
- super(PostalCodeField, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def deconstruct(self):
- name, path, args, kwargs = super(PostalCodeField, self).deconstruct()
+ name, path, args, kwargs = super().deconstruct()
del kwargs["max_length"]
del kwargs["validators"]
return name, path, args, kwargs
diff --git a/oioioi/base/forms.py b/oioioi/base/forms.py
index 2021a9e25..885e1f0ff 100644
--- a/oioioi/base/forms.py
+++ b/oioioi/base/forms.py
@@ -178,7 +178,7 @@ class Media:
def __init__(self, *args, **kwargs):
extra = kwargs.pop("extra", {})
- super(RegistrationFormWithNames, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
adjust_username_field(self)
tmp_fields = list(self.fields.items())
tmp_fields[1:1] = [
@@ -200,7 +200,7 @@ def __init__(self, *args, **kwargs):
self.allow_login_change = kwargs.pop("allow_login_change", False)
extra = kwargs.pop("extra", {})
- super(UserForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
adjust_username_field(self)
adjust_name_fields(self)
@@ -220,7 +220,7 @@ def clean_username(self):
return self.cleaned_data["username"]
def save(self, *args, **kwargs):
- instance = super(UserForm, self).save(*args, **kwargs)
+ instance = super().save(*args, **kwargs)
PreferencesSaved.send(self, user=instance)
return instance
@@ -232,7 +232,7 @@ class Media:
js = ("js/email-change.js",)
def __init__(self, *args, **kwargs):
- super(OioioiUserForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.user = kwargs.pop("instance", None)
def clean_confirm_password(self):
@@ -254,13 +254,13 @@ def clean_confirm_password(self):
class OioioiUserCreationForm(UserCreationForm):
def __init__(self, *args, **kwargs):
- super(OioioiUserCreationForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
adjust_username_field(self)
class OioioiUserChangeForm(UserChangeForm):
def __init__(self, *args, **kwargs):
- super(OioioiUserChangeForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
adjust_username_field(self)
adjust_name_fields(self)
self.fields["user_permissions"].queryset = Permission.objects.filter(codename="can_modify_tags")
@@ -344,7 +344,7 @@ def tag_as_str(self, tag):
return tag
def __init__(self, request, *args, **kwargs):
- super(PublicMessageForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["content"].widget.attrs["class"] = "monospace"
self.contest = request.contest
self.fields["content"].help_text = _("You can use the following tags and attributes: {}.").format(
@@ -360,7 +360,7 @@ def clean_content(self):
)
def save(self, commit=True, *args, **kwargs):
- instance = super(PublicMessageForm, self).save(commit=False, *args, **kwargs)
+ instance = super().save(commit=False, *args, **kwargs)
instance.contest = self.contest
if commit:
instance.save()
diff --git a/oioioi/base/management/commands/migrate.py b/oioioi/base/management/commands/migrate.py
index 112f42958..e4d4e7903 100644
--- a/oioioi/base/management/commands/migrate.py
+++ b/oioioi/base/management/commands/migrate.py
@@ -28,9 +28,9 @@ def handle(self, *args, **options):
"based on version 1.5 or 1.6 of the "
"Django framework. You'll have to make "
"an extra step before syncing your "
- "database. Consult %s for "
- "instructions." % GITHUB_LINK
+ f"database. Consult {GITHUB_LINK} for "
+ "instructions."
)
return
- super(Command, self).handle(*args, **options)
+ super().handle(*args, **options)
diff --git a/oioioi/base/management/commands/shell.py b/oioioi/base/management/commands/shell.py
index 0813bef88..40dc85aeb 100644
--- a/oioioi/base/management/commands/shell.py
+++ b/oioioi/base/management/commands/shell.py
@@ -98,7 +98,7 @@ def execute(self, sql, params=()):
else:
print(raw_sql)
print()
- print("Execution time: %.6fs [Database: %s]" % (execution_time, self.db.alias))
+ print(f"Execution time: {execution_time:.6f}s [Database: {self.db.alias}]")
print()
util.CursorDebugWrapper = PrintQueryWrapper
diff --git a/oioioi/base/menu.py b/oioioi/base/menu.py
index df8c6ad55..ae4fc7d39 100644
--- a/oioioi/base/menu.py
+++ b/oioioi/base/menu.py
@@ -92,7 +92,10 @@ def _get_all_registered_items(self, request):
def __init__(self, text=None, condition=None, show_icons=False):
self.text = text
if condition is None:
- condition = lambda request: True
+
+ def condition(request):
+ return True
+
self.condition = condition
self.show_icons = show_icons
self._registry = []
@@ -175,15 +178,15 @@ def template_context(self, request):
context_items = []
for item in sorted(items, key=attrgetter("order")):
if item.condition(request):
- attrs_str = " ".join(['%s="%s"' % (escape(k), escape(v)) for (k, v) in item.attrs.items()])
+ attrs_str = " ".join([f'{escape(k)}="{escape(v)}"' for (k, v) in item.attrs.items()])
attrs_str = mark_safe(attrs_str)
context_items.append(
- dict(
- url=item.url_generator(request),
- text=item.text,
- attrs=attrs_str,
- has_icon=self.show_icons,
- )
+ {
+ "url": item.url_generator(request),
+ "text": item.text,
+ "attrs": attrs_str,
+ "has_icon": self.show_icons,
+ }
)
return context_items
diff --git a/oioioi/base/models.py b/oioioi/base/models.py
index 7c12a2ba8..a129f2585 100644
--- a/oioioi/base/models.py
+++ b/oioioi/base/models.py
@@ -1,5 +1,12 @@
+import logging
+
import django.dispatch
from django.conf import settings
+from django.contrib.auth.models import User
+from django.db import models
+from django.db.models.signals import post_save
+from django.dispatch import receiver
+from django.utils.translation import gettext_lazy as _
# pylint: disable=unused-import
# Important. This import is to register signal handlers. Do not remove it.
@@ -13,13 +20,6 @@
setup_check()
captcha_check()
-import logging
-
-from django.contrib.auth.models import User
-from django.db import models
-from django.db.models.signals import post_save
-from django.dispatch import receiver
-from django.utils.translation import gettext_lazy as _
auditLogger = logging.getLogger(__name__ + ".audit")
diff --git a/oioioi/base/permissions.py b/oioioi/base/permissions.py
index e4bf7246b..436538bf9 100644
--- a/oioioi/base/permissions.py
+++ b/oioioi/base/permissions.py
@@ -35,7 +35,7 @@ class Condition:
"""
def __init__(self, condition, *args, **kwargs):
- super(Condition, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.condition = condition
def __call__(self, *args, **kwargs):
@@ -44,17 +44,25 @@ def __call__(self, *args, **kwargs):
def __or__(self, other):
if not isinstance(other, Condition):
return NotImplemented
- condition_or = lambda *args, **kwargs: self(*args, **kwargs) or other(*args, **kwargs)
+
+ def condition_or(*args, **kwargs):
+ return self(*args, **kwargs) or other(*args, **kwargs)
+
return Condition(condition_or)
def __and__(self, other):
if not isinstance(other, Condition):
return NotImplemented
- condition_and = lambda *args, **kwargs: self(*args, **kwargs) and other(*args, **kwargs)
+
+ def condition_and(*args, **kwargs):
+ return self(*args, **kwargs) and other(*args, **kwargs)
+
return Condition(condition_and)
def __invert__(self):
- condition_inverted = lambda *args, **kwargs: not self(*args, **kwargs)
+ def condition_inverted(*args, **kwargs):
+ return not self(*args, **kwargs)
+
return Condition(condition_inverted)
diff --git a/oioioi/base/templatetags/all_with_prefix.py b/oioioi/base/templatetags/all_with_prefix.py
index 99ff81be9..ed5251c75 100644
--- a/oioioi/base/templatetags/all_with_prefix.py
+++ b/oioioi/base/templatetags/all_with_prefix.py
@@ -24,6 +24,6 @@ def all_with_prefix(parser, token):
try:
_tag_name, prefix = token.split_contents()
except ValueError:
- msg = "%r tag requires a single argument" % token.split_contents()[0]
+ msg = f"{token.split_contents()[0]!r} tag requires a single argument"
raise TemplateSyntaxError(msg)
return AllWithPrefixNode(prefix)
diff --git a/oioioi/base/templatetags/common_media.py b/oioioi/base/templatetags/common_media.py
index 42714f058..93c6ba9ad 100644
--- a/oioioi/base/templatetags/common_media.py
+++ b/oioioi/base/templatetags/common_media.py
@@ -14,9 +14,9 @@ def generate_styles():
lines = []
for path in find_common_media():
if path.endswith(".css"):
- lines.append('' % (path,))
+ lines.append(f'')
elif path.endswith(".scss"):
- lines.append('' % (path,))
+ lines.append(f'')
return "\n".join(lines)
@@ -24,7 +24,7 @@ def generate_scripts():
lines = []
for path in find_common_media():
if path.endswith(".js"):
- lines.append('' % (path,))
+ lines.append(f'')
return "\n".join(lines)
diff --git a/oioioi/base/templatetags/menu.py b/oioioi/base/templatetags/menu.py
index 2be6b4794..19a716128 100644
--- a/oioioi/base/templatetags/menu.py
+++ b/oioioi/base/templatetags/menu.py
@@ -19,7 +19,7 @@ def render(self, context):
if isinstance(registry, str):
registry = import_string(registry)
if not isinstance(registry, MenuRegistry):
- raise TemplateSyntaxError("{%% generate_menu %%} got an argument which is not a MenuRegistry: %r" % (registry,))
+ raise TemplateSyntaxError(f"{{% generate_menu %}} got an argument which is not a MenuRegistry: {registry!r}")
context["menu"] = registry.template_context(request)
return ""
@@ -64,7 +64,7 @@ def generate_menu(parser, token):
"""
bits = token.split_contents()
if len(bits) > 2:
- raise TemplateSyntaxError("Unexpected arguments to {%% %s %%}" % (bits[0],))
+ raise TemplateSyntaxError(f"Unexpected arguments to {{% {bits[0]} %}}")
if len(bits) == 2:
target = parser.compile_filter(bits[1])
return GenerateMenuNode(target)
diff --git a/oioioi/base/templatetags/simple_filters.py b/oioioi/base/templatetags/simple_filters.py
index 121e9ae06..9e1329d79 100644
--- a/oioioi/base/templatetags/simple_filters.py
+++ b/oioioi/base/templatetags/simple_filters.py
@@ -219,7 +219,7 @@ def json_parse(value):
"""
This is a correct way of embedding json inside js in an HTML template.
"""
- return mark_safe("JSON.parse('%s')" % escapejs(json.dumps(value)))
+ return mark_safe(f"JSON.parse('{escapejs(json.dumps(value))}')")
@register.filter
diff --git a/oioioi/base/tests/__init__.py b/oioioi/base/tests/__init__.py
index 4d2ef81fa..f49b71646 100644
--- a/oioioi/base/tests/__init__.py
+++ b/oioioi/base/tests/__init__.py
@@ -5,11 +5,10 @@
from unittest import mock
import pytest
-from django.contrib.auth.models import AnonymousUser, User
+from django.contrib.auth.models import User
from django.core.cache import cache
from django.core.exceptions import ImproperlyConfigured
from django.db import DEFAULT_DB_ALIAS, connections
-from django.template.loaders.cached import Loader as CachedLoader
from django.test import TestCase as DjangoTestCase
from django.test.utils import CaptureQueriesContext
from django.urls import reverse
@@ -27,16 +26,16 @@ class _AssertNumQueriesLessThanContext(CaptureQueriesContext):
def __init__(self, test_case, num, connection):
self.test_case = test_case
self.num = num
- super(_AssertNumQueriesLessThanContext, self).__init__(connection)
+ super().__init__(connection)
def __exit__(self, exc_type, exc_value, traceback):
- super(_AssertNumQueriesLessThanContext, self).__exit__(exc_type, exc_value, traceback)
+ super().__exit__(exc_type, exc_value, traceback)
if exc_type is not None:
return
executed = len(self)
self.test_case.assertTrue(
executed < self.num,
- "%d queries executed, expected less than %d" % (executed, self.num),
+ f"{executed} queries executed, expected less than {self.num}",
)
@@ -86,7 +85,7 @@ def authenticate(self, request, username=None, password=None, **kwargs):
return User.objects.get(username=username)
except User.DoesNotExist:
raise AssertionError(
- "Tried to log in as %r without password, but such a user does not exist. Probably the test forgot to import a database fixture." % (username,)
+ f"Tried to log in as {username!r} without password, but such a user does not exist. Probably the test forgot to import a database fixture."
)
def get_user(self, user_id):
diff --git a/oioioi/base/tests/tests.py b/oioioi/base/tests/tests.py
index a419654e4..2ec2b660b 100644
--- a/oioioi/base/tests/tests.py
+++ b/oioioi/base/tests/tests.py
@@ -91,8 +91,8 @@ def test_check_perms(self):
admin = User.objects.get(username="test_admin")
user = User.objects.get(username="test_user")
template = Template('{% load check_perm %}{% check_perm "auth.add_user" for "whatever" as p %}{% if p %}yes{% endif %}')
- self.assertEqual(template.render(Context(dict(user=admin))), "yes")
- self.assertEqual(template.render(Context(dict(user=user))), "")
+ self.assertEqual(template.render(Context({"user": admin})), "yes")
+ self.assertEqual(template.render(Context({"user": user})), "")
class TestIndex(TestCase):
@@ -558,7 +558,7 @@ def test_utils_dont_need_settings(self):
class TestAllWithPrefix(TestCase):
def test_all_with_prefix(self):
t = Template("{% load all_with_prefix %}{% all_with_prefix a_ %}")
- context = Context(dict(a_foo="foo", a_bar="bar", b_baz="baz"))
+ context = Context({"a_foo": "foo", "a_bar": "bar", "b_baz": "baz"})
rendered = t.render(context)
self.assertIn("foo", rendered)
self.assertIn("bar", rendered)
@@ -610,7 +610,7 @@ def setUp(self):
def test_basic_usage(self):
field = EnumField(self.registry)
- self.assertEqual(sorted(list(field.choices)), [("ERR", "Error"), ("OK", "OK")])
+ self.assertEqual(sorted(field.choices), [("ERR", "Error"), ("OK", "OK")])
with self.assertRaises(ValidationError):
field.validate("FOO", None)
@@ -717,7 +717,7 @@ def _reload_urlconf(self):
clear_url_caches()
def _register_user(self, terms_accepted=True, pass_captcha=True):
- response = self.client.get(reverse("sign-up"))
+ self.client.get(reverse("sign-up"))
captcha_count = CaptchaStore.objects.count()
self.assertEqual(captcha_count, 1)
captcha = CaptchaStore.objects.all()[0]
@@ -1232,9 +1232,9 @@ def test_can_change_login_from_invalid(self):
# The html strings underneath may change with any django upgrade.
self.assertContains(
response,
- '' % value,
+ 'aria-describedby="id_username_helptext" id="id_username">',
html=True,
)
@@ -1265,9 +1265,9 @@ def test_login_cannot_change_from_valid(self):
response = self.client.get(self.url_edit_profile)
self.assertContains(
response,
- '' % value,
+ 'aria-describedby="id_username_helptext" id="id_username">',
html=True,
)
diff --git a/oioioi/base/utils/__init__.py b/oioioi/base/utils/__init__.py
index ece570e9f..fd6178774 100644
--- a/oioioi/base/utils/__init__.py
+++ b/oioioi/base/utils/__init__.py
@@ -14,8 +14,6 @@
import six
from django.forms.utils import flatatt
from django.http import Http404, HttpResponse, HttpResponseRedirect
-from django.shortcuts import render
-from django.template import Template
from django.template.loader import render_to_string
from django.template.response import TemplateResponse
from django.utils.encoding import force_str
@@ -30,7 +28,7 @@ class ClassInitMeta(type):
"""Meta class triggering __classinit__ on class intialization."""
def __init__(cls, class_name, bases, new_attrs):
- super(ClassInitMeta, cls).__init__(class_name, bases, new_attrs)
+ super().__init__(class_name, bases, new_attrs)
cls.__classinit__()
@@ -96,7 +94,7 @@ def __classinit__(cls):
# This is an artificial class created by mixins mechanism
return
- assert "subclasses" not in cls.__dict__, "%s defines attribute subclasses, but has RegisteredSubclassesMeta metaclass" % (cls,)
+ assert "subclasses" not in cls.__dict__, f"{cls} defines attribute subclasses, but has RegisteredSubclassesMeta metaclass"
cls.subclasses = []
cls.abstract = cls.__dict__.get("abstract", False)
@@ -105,7 +103,7 @@ def find_superclass(cls):
if not superclasses:
return None
if len(superclasses) > 1:
- raise AssertionError("%s derives from more than one RegisteredSubclassesBase" % (cls.__name__,))
+ raise AssertionError(f"{cls.__name__} derives from more than one RegisteredSubclassesBase")
superclass = superclasses[0]
if "__unmixed_class__" in superclass.__dict__:
superclass = superclass.__unmixed_class__
@@ -131,7 +129,7 @@ def load_subclasses(cls):
for app_module in list(settings.INSTALLED_APPS):
for name in modules_to_load:
try:
- module = "%s.%s" % (app_module, name)
+ module = f"{app_module}.{name}"
import_module(module)
except ImportError:
continue
@@ -141,7 +139,7 @@ def load_subclasses(cls):
class _RemoveMixinsFromInitMixin:
def __init__(self, *args, **kwargs):
kwargs.pop("mixins", None)
- super(_RemoveMixinsFromInitMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
class ObjectWithMixins(ClassInitBase):
@@ -255,7 +253,7 @@ def _make_mx_class(cls, mixins):
return type(
cls.__name__ + "WithMixins",
bases,
- dict(__module__=cls.__module__, __unmixed_class__=cls),
+ {"__module__": cls.__module__, "__unmixed_class__": cls},
)
else:
return cls
@@ -291,9 +289,8 @@ def _fixup_subclass(cls, subclass):
def mix_in(cls, mixin):
"""Appends the given mixin to the list of class mixins."""
assert cls.__unmixed_class__ is cls
- assert cls.allow_too_late_mixins or "_has_instances" not in cls.__dict__, "Adding mixin %r to %r too late. The latter already has instances." % (
- mixin,
- cls,
+ assert cls.allow_too_late_mixins or "_has_instances" not in cls.__dict__, (
+ f"Adding mixin {mixin!r} to {cls!r} too late. The latter already has instances."
)
cls.mixins.append(mixin)
cls._mx_class = None
@@ -386,7 +383,7 @@ def make_html_link(href, name, method="GET", extra_attrs=None):
if not extra_attrs:
extra_attrs = {}
attrs.update(extra_attrs)
- return mark_safe("%s" % (flatatt(attrs), conditional_escape(force_str(name))))
+ return mark_safe(f"{conditional_escape(force_str(name))}")
def make_html_links(links, extra_attrs=None):
@@ -508,7 +505,9 @@ def strip_num_or_hash(filename):
def naturalsort_key(key):
- convert = lambda text: int(text) if text.isdigit() else text
+ def convert(text):
+ return int(text) if text.isdigit() else text
+
return [convert(c) for c in re.split("([0-9]+)", key)]
@@ -524,7 +523,7 @@ def __init__(self, max_value, length=20):
def _show(self, preserve=False):
done_p = 100 * self.value / self.max_value
done_l = self.length * self.value / self.max_value
- s = "|" + "=" * done_l + " " * (self.length - done_l) + "| %d%%" % done_p
+ s = f"|{'=' * done_l}{' ' * (self.length - done_l)}| {done_p}%"
self.to_clear = 0 if preserve else len(s)
sys.stdout.write(s + ("\n" if preserve else ""))
sys.stdout.flush()
diff --git a/oioioi/base/utils/archive.py b/oioioi/base/utils/archive.py
index df96836df..43e4e4be0 100644
--- a/oioioi/base/utils/archive.py
+++ b/oioioi/base/utils/archive.py
@@ -104,7 +104,7 @@ def _archive_cls(file, ext=""):
base, ext = os.path.splitext(base)
cls = extension_map.get(ext)
if not cls:
- raise UnrecognizedArchiveFormat("Path not a recognized archive format: %s" % filename)
+ raise UnrecognizedArchiveFormat(f"Path not a recognized archive format: {filename}")
return cls
def extract(self, *args, **kwargs):
@@ -177,7 +177,7 @@ def check_files(self, to_path=None):
extract_path = os.path.join(target_path, filename)
extract_path = os.path.normpath(os.path.realpath(extract_path))
if not extract_path.startswith(target_path):
- raise UnsafeArchive("Archive member destination is outside the target directory. member: %s" % filename)
+ raise UnsafeArchive(f"Archive member destination is outside the target directory. member: {filename}")
class TarArchive(BaseArchive):
diff --git a/oioioi/base/utils/color.py b/oioioi/base/utils/color.py
index 05af145ff..fc9f15e00 100644
--- a/oioioi/base/utils/color.py
+++ b/oioioi/base/utils/color.py
@@ -15,13 +15,13 @@ class ColorField(models.CharField):
def __init__(self, *args, **kwargs):
kwargs["max_length"] = 7
- super(ColorField, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def formfield(self, **kwargs):
kwargs["widget"] = ColorWidget
- return super(ColorField, self).formfield(**kwargs)
+ return super().formfield(**kwargs)
def deconstruct(self):
- name, path, args, kwargs = super(ColorField, self).deconstruct()
+ name, path, args, kwargs = super().deconstruct()
del kwargs["max_length"]
return name, path, args, kwargs
diff --git a/oioioi/base/utils/deps.py b/oioioi/base/utils/deps.py
index d6b5477ca..84b9a828b 100644
--- a/oioioi/base/utils/deps.py
+++ b/oioioi/base/utils/deps.py
@@ -11,16 +11,12 @@ def check_django_app_dependencies(app_name, depends_on, strict=False):
app_name = app_name[:-7]
if not is_django_app_installed(app_name):
raise ImproperlyConfigured(
- "Django app %s is loaded (because something depends on it), but it's not in settings.INSTALLED_APPS. Please add it there." % (app_name,)
+ f"Django app {app_name} is loaded (because something depends on it), but it's not in settings.INSTALLED_APPS. Please add it there."
)
index = settings.INSTALLED_APPS.index(app_name)
- assert isinstance(depends_on, (list, tuple))
+ assert isinstance(depends_on, list | tuple)
for dep in depends_on:
if not is_django_app_installed(dep):
- raise ImproperlyConfigured("Django app %s requires %s, which is not present in settings.INSTALLED_APPS" % (app_name, dep))
+ raise ImproperlyConfigured(f"Django app {app_name} requires {dep}, which is not present in settings.INSTALLED_APPS")
if strict and index > settings.INSTALLED_APPS.index(dep):
- raise ImproperlyConfigured(
- "Django app %(overriding)s overrides "
- "%(overridden)s, so %(overriding)s should be placed "
- "before %(overridden)s in settings.INSTALLED_APPS" % {"overriding": app_name, "overridden": dep}
- )
+ raise ImproperlyConfigured(f"Django app {app_name} overrides {dep}, so {app_name} should be placed before {dep} in settings.INSTALLED_APPS")
diff --git a/oioioi/base/utils/execute.py b/oioioi/base/utils/execute.py
index fb177d6cb..a1cebee0f 100644
--- a/oioioi/base/utils/execute.py
+++ b/oioioi/base/utils/execute.py
@@ -68,7 +68,7 @@ def execute(
# Although there is some kind of support for "sequence" commands in the
# subprocess module, it works kinda wonky. If you want to investigate,
# comment the following two lines and see the tests blow up.
- if isinstance(command, (list, tuple)):
+ if isinstance(command, list | tuple):
command = " ".join(quote(x) for x in command)
def set_cwd():
@@ -102,6 +102,6 @@ def set_cwd():
if split_lines:
stdout = stdout.splitlines()
if rc and not ignore_errors and rc not in errors_to_ignore:
- raise ExecuteError("Failed to execute command: %s\n%s" % (command, stdout))
+ raise ExecuteError(f"Failed to execute command: {command}\n{stdout}")
return stdout
diff --git a/oioioi/base/utils/input_with_generate.py b/oioioi/base/utils/input_with_generate.py
index 7619672b9..94d509f7b 100644
--- a/oioioi/base/utils/input_with_generate.py
+++ b/oioioi/base/utils/input_with_generate.py
@@ -8,7 +8,7 @@ class TextInputWithGenerate(forms.TextInput):
def __init__(self, *args, **kwargs):
attrs = kwargs.setdefault("attrs", {})
attrs.setdefault("style", "width:200px;")
- super(TextInputWithGenerate, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def render(self, name, value, attrs=None, renderer=None):
if self.attrs is not None and "id" in self.attrs:
@@ -19,7 +19,7 @@ def render(self, name, value, attrs=None, renderer=None):
id = "id"
id += "_input-with-generate"
- html = super(TextInputWithGenerate, self).render(name, value, attrs, renderer)
+ html = super().render(name, value, attrs, renderer)
html = mark_safe(self.html_template.format(id=id, input_html=html))
return html
diff --git a/oioioi/base/utils/loaders.py b/oioioi/base/utils/loaders.py
index 0d4d6f0b7..acbe103b7 100644
--- a/oioioi/base/utils/loaders.py
+++ b/oioioi/base/utils/loaders.py
@@ -7,7 +7,7 @@ def load_modules(module_name):
"""This function loads module_name.py files in all installed apps."""
for app_module in list(settings.INSTALLED_APPS):
try:
- module = "%s.%s" % (app_module, module_name)
+ module = f"{app_module}.{module_name}"
import_module(module)
except ImportError:
continue
diff --git a/oioioi/base/utils/user_selection.py b/oioioi/base/utils/user_selection.py
index 878688a70..7682feec4 100644
--- a/oioioi/base/utils/user_selection.py
+++ b/oioioi/base/utils/user_selection.py
@@ -67,7 +67,7 @@ def _get_user_hints(substr, queryset, user_field_name=None):
_prefix(user_field_name, "last_name"),
)
)
- return ["%s (%s %s)" % u for u in users[:num_hints]]
+ return ["{} ({} {})".format(*u) for u in users[:num_hints]]
@jsonify
@@ -109,10 +109,10 @@ def __init__(self, attrs=None):
else:
attrs = dict(attrs)
attrs.setdefault("autocomplete", "off")
- super(UserSelectionWidget, self).__init__(attrs)
+ super().__init__(attrs)
def render(self, name, value, attrs=None, renderer=None):
- html = super(UserSelectionWidget, self).render(name, value, attrs, renderer)
+ html = super().render(name, value, attrs, renderer)
html += mark_safe(
self.html_template
% {
@@ -127,7 +127,7 @@ class UserSelectionField(forms.CharField):
widget = UserSelectionWidget
def __init__(self, hints_url=None, queryset=None, user_field_name=None, **kwargs):
- super(UserSelectionField, self).__init__(**kwargs)
+ super().__init__(**kwargs)
self.hints_url = hints_url
self.queryset = queryset
self.user_field_name = user_field_name
@@ -148,10 +148,10 @@ def prepare_value(self, value):
return User.objects.get(id=value).username
except User.DoesNotExist:
pass
- return super(UserSelectionField, self).prepare_value(value)
+ return super().prepare_value(value)
def to_python(self, value):
- value = super(UserSelectionField, self).to_python(value)
+ value = super().to_python(value)
if isinstance(value, User):
user = value
else:
diff --git a/oioioi/base/widgets.py b/oioioi/base/widgets.py
index 5d0c08503..a6bf822de 100644
--- a/oioioi/base/widgets.py
+++ b/oioioi/base/widgets.py
@@ -26,11 +26,11 @@ def get_context(self, name, value, attrs):
class AceEditorWidget(forms.widgets.Textarea):
def __init__(self, attrs, default_state=False):
- super(AceEditorWidget, self).__init__(attrs={"rows": 10, "class": "monospace"})
+ super().__init__(attrs={"rows": 10, "class": "monospace"})
self.default_state = default_state
def render(self, name, value, attrs=None, renderer=None):
- return super(AceEditorWidget, self).render(name, value, attrs=attrs, renderer=renderer) + render_to_string(
+ return super().render(name, value, attrs=attrs, renderer=renderer) + render_to_string(
"widgets/aceeditor.html",
{
"editor_id": "editor",
diff --git a/oioioi/celery/celery.py b/oioioi/celery/celery.py
index 7d61ad585..4a3da0139 100644
--- a/oioioi/celery/celery.py
+++ b/oioioi/celery/celery.py
@@ -1,8 +1,9 @@
import os
-from celery import Celery
from celery.signals import setup_logging
+from celery import Celery
+
# set the default Django settings module for the 'celery' program.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "oioioi.default_settings")
diff --git a/oioioi/clock/views.py b/oioioi/clock/views.py
index 93d10e2e2..3b7b143cf 100644
--- a/oioioi/clock/views.py
+++ b/oioioi/clock/views.py
@@ -36,13 +36,13 @@ def get_times_status(request, response):
timestamp = getattr(request, "timestamp", None)
contest = getattr(request, "contest", None)
response.update(
- dict(
- time=0,
- round_start_date=0,
- round_end_date=0,
- is_time_admin=False,
- is_admin_time_set=False,
- )
+ {
+ "time": 0,
+ "round_start_date": 0,
+ "round_end_date": 0,
+ "is_time_admin": False,
+ "is_admin_time_set": False,
+ }
)
if getattr(request, "real_user", None) and is_real_superuser(request):
diff --git a/oioioi/complaints/admin.py b/oioioi/complaints/admin.py
index d818b9fc2..4fad37dcf 100644
--- a/oioioi/complaints/admin.py
+++ b/oioioi/complaints/admin.py
@@ -26,7 +26,7 @@ class ComplaintsAdminMixin:
"""
def __init__(self, *args, **kwargs):
- super(ComplaintsAdminMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.inlines = tuple(self.inlines) + (ComplaintsConfigInline,)
diff --git a/oioioi/complaints/views.py b/oioioi/complaints/views.py
index e0870c414..bf361797b 100644
--- a/oioioi/complaints/views.py
+++ b/oioioi/complaints/views.py
@@ -50,7 +50,7 @@ def email_template_context(request, message):
participant = Participant.objects.get(user=user, contest=contest)
participant_status = participant.get_status_display()
try:
- participant_status += _(" (%(registration)s)") % dict(registration=participant.registration_model)
+ participant_status += _(" (%(registration)s)") % {"registration": participant.registration_model}
except ObjectDoesNotExist:
pass
except Participant.DoesNotExist:
@@ -61,7 +61,7 @@ def email_template_context(request, message):
"user": user,
"contest": contest,
"message": message.strip(),
- "user_info": "%s (%s)" % (user.get_full_name(), user),
+ "user_info": f"{user.get_full_name()} ({user})",
"participant": participant,
"participant_status": participant_status,
"complaints_email": get_complaints_email(request),
@@ -85,8 +85,8 @@ def notify_complainer(request, body, message_id, ref_id):
headers={
"Errors-To": context["complaints_email"],
"Reply-To": context["complaints_email"],
- "Message-ID": "<%s@oioioi>" % message_id,
- "References": "<%s@oioioi>" % ref_id,
+ "Message-ID": f"<{message_id}@oioioi>",
+ "References": f"<{ref_id}@oioioi>",
},
)
message.send()
@@ -105,8 +105,8 @@ def notify_jury(request, body, message_id, ref_id):
(context["complaints_email"],),
headers={
"Reply-To": request.user.email,
- "Message-ID": "<%s@oioioi>" % message_id,
- "References": "<%s@oioioi>" % ref_id,
+ "Message-ID": f"<{message_id}@oioioi>",
+ "References": f"<{ref_id}@oioioi>",
},
)
message.send()
diff --git a/oioioi/confirmations/controllers.py b/oioioi/confirmations/controllers.py
index a11c7daca..8e42ea2cc 100644
--- a/oioioi/confirmations/controllers.py
+++ b/oioioi/confirmations/controllers.py
@@ -11,7 +11,7 @@ def should_confirm_submission_receipt(self, request, submission):
return False
def create_submission(self, request, *args, **kwargs):
- submission = super(ConfirmationContestControllerMixin, self).create_submission(request, *args, **kwargs)
+ submission = super().create_submission(request, *args, **kwargs)
if self.should_confirm_submission_receipt(request, submission):
send_submission_receipt_confirmation(request, submission)
diff --git a/oioioi/contestexcl/admin.py b/oioioi/contestexcl/admin.py
index da14d8c3b..88431c5b9 100644
--- a/oioioi/contestexcl/admin.py
+++ b/oioioi/contestexcl/admin.py
@@ -16,7 +16,7 @@ class ExclusivenessConfigInline(admin.TabularInline):
category = _("Advanced")
def get_fields(self, request, obj=None):
- fields = super(ExclusivenessConfigInline, self).get_fields(request, obj)
+ fields = super().get_fields(request, obj)
# Superadmins don't need to see the disable field
if obj and request.user.is_superuser:
return [f for f in fields if f != "disable"]
@@ -49,7 +49,7 @@ class ContestAdminWithExclusivenessInlineMixin:
"""
def __init__(self, *args, **kwargs):
- super(ContestAdminWithExclusivenessInlineMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.inlines = tuple(self.inlines) + (ExclusivenessConfigInline,)
def _warn_on_contestexcl_overlap(self, request, ex_confs):
diff --git a/oioioi/contestexcl/forms.py b/oioioi/contestexcl/forms.py
index c0c3372d1..ad23b4072 100644
--- a/oioioi/contestexcl/forms.py
+++ b/oioioi/contestexcl/forms.py
@@ -18,12 +18,12 @@ class Meta:
model = ExclusivenessConfig
def clean(self):
- super(ExclusivenessConfigForm, self).clean()
+ super().clean()
if self.cleaned_data["disable"] and not self.instance.enabled:
raise ValidationError(_("This exclusiveness config is already disabled!"))
def save(self, commit=True):
- instance = super(ExclusivenessConfigForm, self).save(commit=False)
+ instance = super().save(commit=False)
if self.cleaned_data["disable"]:
instance.enabled = False
if commit:
diff --git a/oioioi/contestexcl/middleware.py b/oioioi/contestexcl/middleware.py
index 39fb788ad..83c892352 100644
--- a/oioioi/contestexcl/middleware.py
+++ b/oioioi/contestexcl/middleware.py
@@ -56,7 +56,9 @@ def _default_selector(user, contest):
if selector is None:
final_selector = _default_selector
else:
- final_selector = lambda user, contest: _default_selector(user, contest) and selector(user, contest)
+
+ def final_selector(user, contest):
+ return _default_selector(user, contest) and selector(user, contest)
if settings.ONLY_DEFAULT_CONTEST and (request.user is None or not request.user.is_superuser):
qs = [Contest.objects.get(id=settings.DEFAULT_CONTEST)]
diff --git a/oioioi/contestexcl/models.py b/oioioi/contestexcl/models.py
index da10ffbbd..5d2dfd7ae 100644
--- a/oioioi/contestexcl/models.py
+++ b/oioioi/contestexcl/models.py
@@ -56,7 +56,7 @@ class Meta:
verbose_name_plural = _("exclusiveness configs")
def __str__(self):
- return "%s (%s): %s - %s" % (
+ return "{} ({}): {} - {}".format(
self.contest,
"enabled" if self.enabled else "disabled",
self.start_date,
diff --git a/oioioi/contestexcl/tests.py b/oioioi/contestexcl/tests.py
index af61a0f31..44bb5bfd9 100644
--- a/oioioi/contestexcl/tests.py
+++ b/oioioi/contestexcl/tests.py
@@ -191,7 +191,7 @@ def _modify_contestexcl(
("contestcompiler_set", 0, 0, 0, 1000),
("checkerformatforcontest", 0, 0, 0, 1),
)
- data = dict()
+ data = {}
for name, total, initial, min_num, max_num in formsets:
data.update(
{
diff --git a/oioioi/contestlogo/admin.py b/oioioi/contestlogo/admin.py
index a6d416514..668759ca2 100644
--- a/oioioi/contestlogo/admin.py
+++ b/oioioi/contestlogo/admin.py
@@ -26,7 +26,7 @@ class ContestLogoAdminMixin:
"""Adds :class:`~oioioi.contestlogo.models.ContestLogo` to an admin panel."""
def __init__(self, *args, **kwargs):
- super(ContestLogoAdminMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.inlines = tuple(self.inlines) + (ContestLogoInline,)
@@ -59,7 +59,7 @@ class ContestIconAdminMixin:
"""Adds :class:`~oioioi.contestlogo.models.ContestIcon` to an admin panel."""
def __init__(self, *args, **kwargs):
- super(ContestIconAdminMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.inlines = tuple(self.inlines) + (ContestIconInline,)
diff --git a/oioioi/contestlogo/models.py b/oioioi/contestlogo/models.py
index 9410857ec..34feba5e4 100644
--- a/oioioi/contestlogo/models.py
+++ b/oioioi/contestlogo/models.py
@@ -10,10 +10,7 @@
def make_logo_filename(instance, filename):
- return "logo/%s/%s" % (
- instance.contest.id,
- get_valid_filename(os.path.basename(filename)),
- )
+ return f"logo/{instance.contest.id}/{get_valid_filename(os.path.basename(filename))}"
class ContestLogo(models.Model):
@@ -24,7 +21,7 @@ class ContestLogo(models.Model):
def save(self, *args, **kwargs):
self.updated_at = timezone.now()
- return super(ContestLogo, self).save(*args, **kwargs)
+ return super().save(*args, **kwargs)
@property
def filename(self):
@@ -36,10 +33,7 @@ class Meta:
def make_icon_filename(instance, filename):
- return "icons/%s/%s" % (
- instance.contest.id,
- get_valid_filename(os.path.basename(filename)),
- )
+ return f"icons/{instance.contest.id}/{get_valid_filename(os.path.basename(filename))}"
class ContestIcon(models.Model):
@@ -49,7 +43,7 @@ class ContestIcon(models.Model):
def save(self, *args, **kwargs):
self.updated_at = timezone.now()
- return super(ContestIcon, self).save(*args, **kwargs)
+ return super().save(*args, **kwargs)
@property
def filename(self):
diff --git a/oioioi/contestlogo/tests.py b/oioioi/contestlogo/tests.py
index 5a494e50d..089a8ab4d 100644
--- a/oioioi/contestlogo/tests.py
+++ b/oioioi/contestlogo/tests.py
@@ -97,7 +97,7 @@ def test_icon_last_modified(self):
icon = ContestIcon.objects.get()
icon.image = ContentFile(b"eloziom", name="foo")
icon.save()
- self.request_file("/c/c/icons/%d/" % icon.pk, icon.updated_at)
+ self.request_file(f"/c/c/icons/{icon.pk}/", icon.updated_at)
def test_logo_last_modified(self):
logo = ContestLogo.objects.get()
diff --git a/oioioi/contests/admin.py b/oioioi/contests/admin.py
index 8d35090bd..fb1f3925f 100644
--- a/oioioi/contests/admin.py
+++ b/oioioi/contests/admin.py
@@ -65,7 +65,7 @@
class ContestProxyAdminSite(admin.AdminSite):
def __init__(self, orig):
- super(ContestProxyAdminSite, self).__init__(orig.name)
+ super().__init__(orig.name)
self._orig = orig
def register(self, model_or_iterable, admin_class=None, **options):
@@ -74,28 +74,28 @@ def register(self, model_or_iterable, admin_class=None, **options):
def unregister(self, model_or_iterable):
self._orig.unregister(model_or_iterable)
try:
- super(ContestProxyAdminSite, self).unregister(model_or_iterable)
+ super().unregister(model_or_iterable)
except NotRegistered:
pass
def contest_register(self, model_or_iterable, admin_class=None, **options):
- super(ContestProxyAdminSite, self).register(model_or_iterable, admin_class, **options)
+ super().register(model_or_iterable, admin_class, **options)
def contest_unregister(self, model_or_iterable):
- super(ContestProxyAdminSite, self).unregister(model_or_iterable)
+ super().unregister(model_or_iterable)
def get_urls(self):
self._registry.update(self._orig._registry)
- return super(ContestProxyAdminSite, self).get_urls()
+ return super().get_urls()
def index(self, request, extra_context=None):
if request.contest:
- return super(ContestProxyAdminSite, self).index(request, extra_context)
+ return super().index(request, extra_context)
return self._orig.index(request, extra_context)
def app_index(self, request, app_label, extra_context=None):
if request.contest:
- return super(ContestProxyAdminSite, self).app_index(request, app_label, extra_context)
+ return super().app_index(request, app_label, extra_context)
return self._orig.app_index(request, app_label, extra_context)
@@ -180,7 +180,7 @@ def content_link(self, instance):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "round":
kwargs["queryset"] = Round.objects.filter(contest=request.contest)
- return super(AttachmentInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ return super().formfield_for_foreignkey(db_field, request, **kwargs)
class ContestLinkInline(admin.TabularInline):
@@ -218,7 +218,7 @@ def get_fields(self, request, obj=None):
def get_fieldsets(self, request, obj=None):
if obj and not request.GET.get("simple", False):
- return super(ContestAdmin, self).get_fieldsets(request, obj)
+ return super().get_fieldsets(request, obj)
fields = list(SimpleContestForm().base_fields.keys())
return [(None, {"fields": fields})]
@@ -242,10 +242,10 @@ def get_inlines(self, request, obj):
def get_form(self, request, obj=None, **kwargs):
if not self.has_change_permission(request, obj):
- return super(ContestAdmin, self).get_form(request, obj, **kwargs)
+ return super().get_form(request, obj, **kwargs)
if obj and not request.GET.get("simple", False):
- return super(ContestAdmin, self).get_form(request, obj, **kwargs)
+ return super().get_form(request, obj, **kwargs)
return modelform_factory(
self.model,
form=SimpleContestForm,
@@ -255,7 +255,7 @@ def get_form(self, request, obj=None, **kwargs):
def get_formsets(self, request, obj=None):
if obj and not request.GET.get("simple", False):
- return super(ContestAdmin, self).get_formsets(request, obj)
+ return super().get_formsets(request, obj)
return []
def response_change(self, request, obj):
@@ -263,10 +263,10 @@ def response_change(self, request, obj):
# view.
if "_popup" not in request.POST:
return HttpResponseRedirect(request.get_full_path())
- return super(ContestAdmin, self).response_change(request, obj)
+ return super().response_change(request, obj)
def response_add(self, request, obj, post_url_continue=None):
- default_redirection = super(ContestAdmin, self).response_add(request, obj, post_url_continue)
+ default_redirection = super().response_add(request, obj, post_url_continue)
if "_continue" in request.POST or "_addanother" in request.POST:
return default_redirection
else:
@@ -274,17 +274,17 @@ def response_add(self, request, obj, post_url_continue=None):
def response_delete(self, request):
set_cc_id(None)
- return super(ContestAdmin, self).response_delete(request)
+ return super().response_delete(request)
def _get_extra_context(self, extra_context):
extra_context = extra_context or {}
- extra_context["categories"] = sorted(set([getattr(inline, "category", None) for inline in self.inlines]))
+ extra_context["categories"] = sorted({getattr(inline, "category", None) for inline in self.inlines})
extra_context["no_category"] = NO_CATEGORY
return extra_context
def add_view(self, request, form_url="", extra_context=None):
extra_context = self._get_extra_context(extra_context)
- ret = super(ContestAdmin, self).add_view(request, form_url, extra_context)
+ ret = super().add_view(request, form_url, extra_context)
create_contest_attributes(request, True)
return ret
@@ -296,7 +296,7 @@ def change_view(self, request, object_id, form_url="", extra_context=None):
create_contest_attributes(request, False)
if not request.contest or request.contest.id != contest_id:
return redirect("oioioiadmin:contests_contest_change", object_id, contest_id=contest_id)
- return super(ContestAdmin, self).change_view(request, object_id, form_url, extra_context)
+ return super().change_view(request, object_id, form_url, extra_context)
def render_change_form(self, request, context, add=False, change=False, form_url="", obj=None):
if not add:
@@ -315,7 +315,7 @@ def delete_selected_contests(self, modeladmin, request, queryset):
def get_actions(self, request):
# Use delete_selected with a custom redirect.
- actions = super(ContestAdmin, self).get_actions(request)
+ actions = super().get_actions(request)
actions["delete_selected"] = (
self.delete_selected_contests,
"delete_selected",
@@ -357,7 +357,7 @@ def _attach_problem_ids_to_url(self, queryset, url_name):
# Attach problem ids as arguments to the URL
base_url = reverse(url_name)
query_string = urlencode({"ids": ",".join(str(i) for i in ids)}, doseq=True)
- return "%s?%s" % (base_url, query_string)
+ return f"{base_url}?{query_string}"
@action(description=_("Attach problems to another contest"))
def attach_problems_to_another_contest(self, request, queryset):
@@ -375,7 +375,7 @@ def __init__(self, *args, **kwargs):
# creating a thread local variable to store the request
self._request_local = threading.local()
self._request_local.request = None
- super(ProblemInstanceAdmin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def has_add_permission(self, request):
return False
@@ -393,13 +393,13 @@ def has_delete_permission(self, request, obj=None):
def has_view_permission(self, request, obj=None):
if is_contest_archived(request):
return is_contest_basicadmin(request)
- return super(ProblemInstanceAdmin, self).has_view_permission(request, obj)
+ return super().has_view_permission(request, obj)
def _problem_change_href(self, instance):
came_from = reverse("oioioiadmin:contests_probleminstance_changelist")
came_from_arg = urllib.parse.urlencode({"came_from": came_from})
problem_change_base_href = reverse("oioioiadmin:problems_problem_change", args=(instance.problem_id,))
- return "%s?%s" % (problem_change_base_href, came_from_arg)
+ return f"{problem_change_base_href}?{came_from_arg}"
def _rejudge_all_submissions_for_problem_href(self, instance):
return reverse("rejudge_all_submissions_for_problem", args=(instance.id,))
@@ -420,7 +420,7 @@ def _reattach_problem_href(self, instance):
base_url = reverse("reattach_problem_contest_list")
query_string = urlencode({"ids": instance.id})
# Attach problem id as an argument to the URL
- return "%s?%s" % (base_url, query_string)
+ return f"{base_url}?{query_string}"
def _add_or_update_href(self, instance):
return reverse("problemset_add_or_update") + "?" + urllib.parse.urlencode({"problem": instance.problem_id, "key": "upload"})
@@ -438,7 +438,7 @@ def _move_href(self, instance):
return reverse("oioioiadmin:contests_probleminstance_change", args=(instance.id,))
def get_list_display(self, request):
- items = super(ProblemInstanceAdmin, self).get_list_display(request)
+ items = super().get_list_display(request)
if not is_contest_admin(request):
disallowed_items = ["package"]
items = [item for item in items if item not in disallowed_items]
@@ -522,20 +522,20 @@ def package(self, instance):
def get_actions(self, request):
self._request_local.request = request
# Disable delete_selected.
- actions = super(ProblemInstanceAdmin, self).get_actions(request)
+ actions = super().get_actions(request)
if "delete_selected" in actions:
del actions["delete_selected"]
return actions
def get_custom_list_select_related(self):
- return super(ProblemInstanceAdmin, self).get_custom_list_select_related() + [
+ return super().get_custom_list_select_related() + [
"contest",
"round",
"problem",
]
def get_queryset(self, request):
- qs = super(ProblemInstanceAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
qs = (
qs.filter(contest=request.contest)
.annotate(localized_name=Subquery(ProblemName.objects.filter(problem=OuterRef("problem__pk"), language=get_language()).values("name")))
@@ -552,7 +552,7 @@ def get_queryset(self, request):
def changelist_view(self, request, extra_context=None):
extra_context = extra_context or {}
extra_context["show_add_button"] = not is_contest_archived(request)
- return super(ProblemInstanceAdmin, self).changelist_view(request, extra_context=extra_context)
+ return super().changelist_view(request, extra_context=extra_context)
contest_site.contest_register(ProblemInstance, ProblemInstanceAdmin)
@@ -696,7 +696,7 @@ def get_list_filter(self, request):
def get_urls(self):
urls = [path("rejudge/", self.rejudge_view)]
- return urls + super(SubmissionAdmin, self).get_urls()
+ return urls + super().get_urls()
def rejudge_view(self, request):
tests = request.POST.getlist("tests", [])
@@ -753,7 +753,7 @@ def has_rejudge_permission(self, request):
return is_contest_basicadmin(request)
def get_actions(self, request):
- actions = super(SubmissionAdmin, self).get_actions(request)
+ actions = super().get_actions(request)
if not request.user.is_superuser:
if not self.has_delete_permission(request):
del actions["delete_selected"]
@@ -779,10 +779,7 @@ def user_full_name(self, instance):
def problem_instance_display(self, instance):
if instance.kind != "NORMAL":
- return "%s (%s)" % (
- force_str(instance.problem_instance),
- force_str(instance.get_kind_display()),
- )
+ return f"{force_str(instance.problem_instance)} ({force_str(instance.get_kind_display())})"
else:
# return instance.problem_instance
# FIXME: This is a temporary hack,
@@ -852,7 +849,7 @@ def rejudge_action(self, request, queryset):
rejudge_action.short_description = _("Rejudge selected submissions")
def get_custom_list_select_related(self):
- return super(SubmissionAdmin, self).get_custom_list_select_related() + [
+ return super().get_custom_list_select_related() + [
"user",
"problem_instance",
"problem_instance__problem",
@@ -860,7 +857,7 @@ def get_custom_list_select_related(self):
]
def get_queryset(self, request):
- queryset = super(SubmissionAdmin, self).get_queryset(request)
+ queryset = super().get_queryset(request)
if request.contest:
queryset = queryset.filter(problem_instance__contest=request.contest)
queryset = queryset.order_by("-id")
@@ -873,7 +870,7 @@ def get_queryset(self, request):
def lookup_allowed(self, key, value, request):
if key == "user__username":
return True
- return super(SubmissionAdmin, self).lookup_allowed(key, value, request)
+ return super().lookup_allowed(key, value, request)
def change_view(self, request, object_id, form_url="", extra_context=None):
_contest_id = None
@@ -977,16 +974,16 @@ def user_full_name(self, instance):
user_full_name.admin_order_field = "user__last_name"
def get_queryset(self, request):
- qs = super(RoundTimeExtensionAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
return qs.filter(round__contest=request.contest)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "round":
kwargs["queryset"] = Round.objects.filter(contest=request.contest)
- return super(RoundTimeExtensionAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ return super().formfield_for_foreignkey(db_field, request, **kwargs)
def get_custom_list_select_related(self):
- return super(RoundTimeExtensionAdmin, self).get_custom_list_select_related() + [
+ return super().get_custom_list_select_related() + [
"user",
"round__contest",
]
@@ -1051,7 +1048,7 @@ def has_delete_permission(self, request, obj=None):
return self.has_change_permission(request, obj)
def get_queryset(self, request):
- qs = super(ContestPermissionAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
if request.contest:
qs = qs.filter(contest=request.contest)
return qs
@@ -1063,14 +1060,14 @@ def formfield_for_foreignkey(self, db_field, request, **kwargs):
qs = qs.filter(id=request.contest.id)
kwargs["initial"] = request.contest
kwargs["queryset"] = qs
- return super(ContestPermissionAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ return super().formfield_for_foreignkey(db_field, request, **kwargs)
def formfield_for_choice_field(self, db_field, request, **kwargs):
if db_field.name == "permission":
# Contest owners musn't manage other contest owners
if not request.user.is_superuser:
kwargs["choices"] = [i for i in contest_permissions if i[0] != "contests.contest_owner"]
- return super(ContestPermissionAdmin, self).formfield_for_choice_field(db_field, request, **kwargs)
+ return super().formfield_for_choice_field(db_field, request, **kwargs)
contest_site.register(ContestPermission, ContestPermissionAdmin)
diff --git a/oioioi/contests/attachment_registration.py b/oioioi/contests/attachment_registration.py
index 3f0457672..5b90bcf5e 100644
--- a/oioioi/contests/attachment_registration.py
+++ b/oioioi/contests/attachment_registration.py
@@ -24,7 +24,7 @@ def register(self, attachment_generator=None, order=sys.maxsize):
def to_list(self, **kwargs):
attachments = []
- for idx, gen in enumerate(self._registry):
+ for _idx, gen in enumerate(self._registry):
attachments.extend(gen(**kwargs))
return attachments
diff --git a/oioioi/contests/controllers.py b/oioioi/contests/controllers.py
index f6c3bf4e0..20774b23c 100644
--- a/oioioi/contests/controllers.py
+++ b/oioioi/contests/controllers.py
@@ -1039,7 +1039,7 @@ def can_see_round(self, request_or_context, round, no_admin=False):
if preparation_start < context.timestamp < preparation_end:
return False
- return super(PastRoundsHiddenContestControllerMixin, self).can_see_round(request_or_context, round, no_admin)
+ return super().can_see_round(request_or_context, round, no_admin)
class NotificationsMixinForContestController:
diff --git a/oioioi/contests/date_registration.py b/oioioi/contests/date_registration.py
index eae744e96..e1881dc08 100644
--- a/oioioi/contests/date_registration.py
+++ b/oioioi/contests/date_registration.py
@@ -57,13 +57,19 @@ def decorator(original_class):
return decorator
if name_generator is None:
- name_generator = lambda obj: str(model._meta.verbose_name) + " " + str(model._meta.get_field(date_field).verbose_name)
+
+ def name_generator(obj):
+ return str(model._meta.verbose_name) + " " + str(model._meta.get_field(date_field).verbose_name)
if round_chooser is None:
- round_chooser = lambda obj: None
+
+ def round_chooser(obj):
+ return None
if qs_filter is None:
- qs_filter = lambda qs, contest_id: qs.filter(contest=contest_id)
+
+ def qs_filter(qs, contest_id):
+ return qs.filter(contest=contest_id)
date_item = self.DateItem(date_field, name_generator, round_chooser, qs_filter, model)
self._registry.register(date_item, order)
@@ -76,15 +82,15 @@ def tolist(self, contest_id):
instances = item.qs_filter(model.objects.all(), contest_id)
for instance in instances:
context_items.append(
- dict(
- text=item.name_generator(instance),
- date=getattr(instance, item.date_field),
- date_field=item.date_field,
- model=model,
- id=instance.id,
- round=item.round_chooser(instance),
- order=self._registry.keys[idx],
- )
+ {
+ "text": item.name_generator(instance),
+ "date": getattr(instance, item.date_field),
+ "date_field": item.date_field,
+ "model": model,
+ "id": instance.id,
+ "round": item.round_chooser(instance),
+ "order": self._registry.keys[idx],
+ }
)
return context_items
diff --git a/oioioi/contests/fields.py b/oioioi/contests/fields.py
index fd884f497..cf0b246cd 100644
--- a/oioioi/contests/fields.py
+++ b/oioioi/contests/fields.py
@@ -12,7 +12,7 @@ class ScoreField(models.CharField):
def __init__(self, *args, **kwargs):
kwargs.setdefault("max_length", 255)
- super(ScoreField, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def get_prep_value(self, value):
if value is None:
diff --git a/oioioi/contests/forms.py b/oioioi/contests/forms.py
index dbff38dbd..193dd03fd 100644
--- a/oioioi/contests/forms.py
+++ b/oioioi/contests/forms.py
@@ -68,7 +68,7 @@ def _set_dates(self, round):
setattr(round, date, self.cleaned_data.get(date))
def __init__(self, *args, **kwargs):
- super(SimpleContestForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
instance = kwargs.get("instance", None)
if instance is not None:
rounds = instance.round_set.all()
@@ -85,14 +85,14 @@ def __init__(self, *args, **kwargs):
self._generate_default_dates()
def clean(self):
- cleaned_data = super(SimpleContestForm, self).clean()
+ cleaned_data = super().clean()
round = Round()
self._set_dates(round)
round.clean()
return cleaned_data
def save(self, commit=True):
- instance = super(SimpleContestForm, self).save(commit=False)
+ instance = super().save(commit=False)
rounds = instance.round_set.all()
if len(rounds) > 1:
raise ValueError("SimpleContestForm does not support contests with more than one round.")
@@ -113,7 +113,7 @@ def save(self, commit=True):
class ProblemInstanceForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
instance = kwargs.get("instance")
- super(ProblemInstanceForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
if instance and not instance.contest.is_archived:
self.fields["round"].queryset = instance.contest.round_set
self.fields["round"].required = True
@@ -174,7 +174,7 @@ def __init__(self, request, *args, **kwargs):
pi_choices = [(pi.id, str(pi)) for pi in pis]
# init form with previously sent data
- super(SubmissionForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
# prepare problem instance selector
pi_field = self.fields["problem_instance_id"]
@@ -274,7 +274,7 @@ def is_valid(self):
return forms.Form.is_valid(self)
def clean(self, check_submission_limit=True, check_round_times=True):
- cleaned_data = super(SubmissionForm, self).clean()
+ cleaned_data = super().clean()
if "kind" not in cleaned_data:
cleaned_data["kind"] = self.kind
@@ -305,7 +305,7 @@ class SubmissionFormForProblemInstance(SubmissionForm):
def __init__(self, request, problem_instance, *args, **kwargs):
self.problem_instance = problem_instance
kwargs["problem_instance"] = problem_instance
- super(SubmissionFormForProblemInstance, self).__init__(request, *args, **kwargs)
+ super().__init__(request, *args, **kwargs)
pis = self.fields["problem_instance_id"]
pis.widget.attrs["readonly"] = "True"
pis.widget.attrs["data-submit"] = "hidden"
@@ -318,13 +318,13 @@ class GetUserInfoForm(forms.Form):
user = UserSelectionField(label=_("Username"))
def __init__(self, request, *args, **kwargs):
- super(GetUserInfoForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["user"].hints_url = reverse("contest_user_hints", kwargs={"contest_id": request.contest.id})
class TestsSelectionForm(forms.Form):
def __init__(self, request, queryset, pis_count, uses_is_active, *args, **kwargs):
- super(TestsSelectionForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
problem_instance = queryset[0].problem_instance
tests = Test.objects.filter(problem_instance=problem_instance, is_active=True)
@@ -394,7 +394,7 @@ class RoundSelectionForm(forms.Form):
def __init__(self, *args, **kwargs):
contest = kwargs.pop("contest", None)
- super(RoundSelectionForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
if contest is None:
raise ValueError("Contest must be provided to RoundSelectionForm.")
self.fields["round"].queryset = Round.objects.filter(contest=contest)
diff --git a/oioioi/contests/handlers.py b/oioioi/contests/handlers.py
index ed4e1dd21..cfcf10428 100644
--- a/oioioi/contests/handlers.py
+++ b/oioioi/contests/handlers.py
@@ -210,7 +210,7 @@ def mail_admins_on_error(env, submission, exc_info, **kwargs):
try:
mail_admins(
- "System Error evaluating submission #%s" % env.get("submission_id", "???"),
+ "System Error evaluating submission #{}".format(env.get("submission_id", "???")),
"".join(traceback.format_exception(*exc_info)),
)
except (OSError, SMTPException) as e:
diff --git a/oioioi/contests/management/commands/hidden_results_diff.py b/oioioi/contests/management/commands/hidden_results_diff.py
index 0b7104ac8..b9fd0ec71 100644
--- a/oioioi/contests/management/commands/hidden_results_diff.py
+++ b/oioioi/contests/management/commands/hidden_results_diff.py
@@ -61,4 +61,4 @@ def handle(self, *args, **options):
new_score = new_report.score_report.score
if old_score != new_score:
- print("%s: %s -> %s" % (s, old_score, new_score))
+ print(f"{s}: {old_score} -> {new_score}")
diff --git a/oioioi/contests/models.py b/oioioi/contests/models.py
index d3b8d9ebf..579acba69 100644
--- a/oioioi/contests/models.py
+++ b/oioioi/contests/models.py
@@ -28,12 +28,9 @@
def make_contest_filename(instance, filename):
if not isinstance(instance, Contest):
- assert hasattr(instance, "contest"), "contest_file_generator used on object %r which does not have 'contest' attribute" % (instance,)
+ assert hasattr(instance, "contest"), f"contest_file_generator used on object {instance!r} which does not have 'contest' attribute"
instance = instance.contest
- return "contests/%s/%s" % (
- instance.id,
- get_valid_filename(os.path.basename(filename)),
- )
+ return f"contests/{instance.id}/{get_valid_filename(os.path.basename(filename))}"
class Contest(models.Model):
@@ -92,7 +89,7 @@ class Contest(models.Model):
def save(self, *args, **kwargs):
if not self.controller_name:
self.controller_name = "oioioi.teachers.controllers.TeacherContestController"
- super(Contest, self).save(*args, **kwargs)
+ super().save(*args, **kwargs)
@property
def controller(self):
@@ -505,13 +502,8 @@ def get_score_display(self):
return self.problem_instance.controller.render_submission_score(self)
def __str__(self):
- return "Submission(%d, %s, %s, %s, %s, %s)" % (
- self.id,
- self.problem_instance.problem.name,
- self.user.username if self.user else None,
- self.date,
- self.kind,
- self.status,
+ return (
+ f"Submission({self.id}, {self.problem_instance.problem.name}, {self.user.username if self.user else None}, {self.date}, {self.kind}, {self.status})"
)
@@ -657,7 +649,7 @@ class Meta:
verbose_name_plural = _("contest permissions")
def __str__(self):
- return "%s/%s: %s" % (self.contest, self.permission, self.user)
+ return f"{self.contest}/{self.permission}: {self.user}"
class ContestView(models.Model):
@@ -672,7 +664,7 @@ class Meta:
ordering = ("-timestamp",)
def __str__(self):
- return "%s,%s" % (self.user, self.contest)
+ return f"{self.user},{self.contest}"
class ContestLink(models.Model):
@@ -694,9 +686,11 @@ def contest_links_generator(request):
for link in links:
# pylint: disable=cell-var-from-loop
# http://docs.python-guide.org/en/latest/writing/gotchas/#late-binding-closures
- url_generator = lambda request, url=link.url: url
+ def url_generator(request, url=link.url):
+ return url
+
item = MenuItem(
- name="contest_link_%d" % link.id,
+ name=f"contest_link_{link.id}",
text=link.description,
url_generator=url_generator,
order=link.order,
diff --git a/oioioi/contests/scores.py b/oioioi/contests/scores.py
index 55835df90..92bdfd36b 100644
--- a/oioioi/contests/scores.py
+++ b/oioioi/contests/scores.py
@@ -35,7 +35,7 @@ class ScoreValue(ClassInitBase):
#: representation of the value. This must be overridden in all subclasses.
symbol = "__override_in_subclasses__"
- _subclasses = dict()
+ _subclasses = {}
@classmethod
def __classinit__(cls):
@@ -49,14 +49,14 @@ def __classinit__(cls):
return
if cls.symbol == this_class.symbol:
- raise AssertionError("Symbol attribute not defined in %r" % (cls,))
+ raise AssertionError(f"Symbol attribute not defined in {cls!r}")
if cls.symbol in this_class._subclasses:
- raise AssertionError("Duplicate symbol '%s' used in both %r and %r" % (cls.symbol, this_class._subclasses[cls.symbol], cls))
+ raise AssertionError(f"Duplicate symbol '{cls.symbol}' used in both {this_class._subclasses[cls.symbol]!r} and {cls!r}")
this_class._subclasses[cls.symbol] = cls
def serialize(self):
"""Converts the instance of any subclass to string."""
- return "%s:%s" % (self.symbol, self._to_repr())
+ return f"{self.symbol}:{self._to_repr()}"
def __repr__(self):
return self.serialize()
@@ -68,7 +68,7 @@ def deserialize(serialized):
return None
parts = serialized.split(":", 1)
if len(parts) < 2:
- raise ValidationError(_("Score must look like this: ':', for example 'int:100', not '%s'." % (serialized,)))
+ raise ValidationError(_("Score must look like this: ':', for example 'int:100', not '{}'.".format(serialized)))
symbol, value = parts
if symbol in ScoreValue._subclasses:
return ScoreValue._subclasses[symbol]._from_repr(value)
@@ -164,14 +164,14 @@ def __unicode__(self):
return str(self.value)
def __repr__(self):
- return "IntegerScore(%s)" % (self.value,)
+ return f"IntegerScore({self.value})"
@classmethod
def _from_repr(cls, value):
return cls(int(value))
def _to_repr(self):
- return "%019d" % self.value
+ return f"{self.value:019d}"
def to_int(self):
return self.value
diff --git a/oioioi/contests/serializers.py b/oioioi/contests/serializers.py
index 2a017c54d..eb42e5886 100644
--- a/oioioi/contests/serializers.py
+++ b/oioioi/contests/serializers.py
@@ -16,7 +16,7 @@ def __init__(self, pi, *args, **kwargs):
if pi is not None:
self.problem_instance_id = serializers.HiddenField(default=pi.pk)
self.problem_instance = pi
- super(SubmissionSerializer, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def validate(self, data):
for field in SubmissionSerializer.Meta.fields:
diff --git a/oioioi/contests/templatetags/get_user_name.py b/oioioi/contests/templatetags/get_user_name.py
index b01c6f1c0..26b8040d0 100644
--- a/oioioi/contests/templatetags/get_user_name.py
+++ b/oioioi/contests/templatetags/get_user_name.py
@@ -50,7 +50,7 @@ def _get_user_name(self, context, user):
def _get_name(parser, token, tag_name):
bits = token.split_contents()
if (len(bits) != 4 or bits[2] != "as") and (len(bits) != 2):
- raise TemplateSyntaxError("The tag should look like this: {%% %s [ as ] %%}" % tag_name)
+ raise TemplateSyntaxError(f"The tag should look like this: {{% {tag_name} [ as ] %}}")
asvar = None
if len(bits) == 4:
asvar = bits[3]
diff --git a/oioioi/contests/tests/__init__.py b/oioioi/contests/tests/__init__.py
index 3701eb0b2..990c4a75a 100644
--- a/oioioi/contests/tests/__init__.py
+++ b/oioioi/contests/tests/__init__.py
@@ -1,5 +1,3 @@
-from django.core.files.base import ContentFile
-from django.db.models import Q
from django.urls import reverse
from oioioi.base.utils.query_helpers import Q_always_false
@@ -81,7 +79,7 @@ def make_empty_contest_formset():
("contestcompiler_set", 0, 0, 0, 1000),
("checkerformatforcontest", 0, 0, 0, 1),
)
- data = dict()
+ data = {}
for name, total, initial, min_num, max_num in formsets:
data[f"{name}-TOTAL_FORMS"] = total
data[f"{name}-INITIAL_FORMS"] = initial
diff --git a/oioioi/contests/tests/tests.py b/oioioi/contests/tests/tests.py
index 0655475c1..c0f6836bb 100755
--- a/oioioi/contests/tests/tests.py
+++ b/oioioi/contests/tests/tests.py
@@ -197,8 +197,8 @@ def test_default_order(self):
def check_id_order_in_response(self, response, ids):
self.check_order_in_response(
response,
- ["/submission/%d/change" % x for x in ids],
- "Submission with id %d should be displayed before submission with id %d" % tuple(ids),
+ [f"/submission/{x}/change" for x in ids],
+ f"Submission with id {ids[0]} should be displayed before submission with id {ids[1]}",
)
@pytest.mark.skip(reason="TODO: Repair the ordering platform-wide.")
@@ -240,12 +240,12 @@ def check_order_in_response(self, response, order, error_msg):
self.assertIn(
test_first,
table_content,
- "Fixtures should contain submission with %s" % test_first,
+ f"Fixtures should contain submission with {test_first}",
)
self.assertIn(
test_second,
table_content,
- "Fixtures should contain submission with %s" % test_second,
+ f"Fixtures should contain submission with {test_second}",
)
test_first_index = table_content.index(test_first)
@@ -576,8 +576,8 @@ def test_recent_contests_list(self):
invisible_contest.save()
self.assertTrue(self.client.login(username="test_admin"))
- self.client.get("/c/%s/dashboard/" % contest.id)
- self.client.get("/c/%s/dashboard/" % invisible_contest.id)
+ self.client.get(f"/c/{contest.id}/dashboard/")
+ self.client.get(f"/c/{invisible_contest.id}/dashboard/")
response = self.client.get(reverse("select_contest"))
self.assertEqual(len(response.context["contests"]), 2)
self.assertContains(response, "Test contest")
@@ -585,15 +585,15 @@ def test_recent_contests_list(self):
self.client.logout()
self.assertTrue(self.client.login(username="test_admin"))
- response = self.client.get("/c/%s/dashboard/" % contest.id)
+ response = self.client.get(f"/c/{contest.id}/dashboard/")
self.assertContains(response, "dropdown open")
- response = self.client.get("/c/%s/dashboard/" % contest.id)
+ response = self.client.get(f"/c/{contest.id}/dashboard/")
self.assertNotContains(response, "dropdown open")
contests = [cv.contest for cv in ContestView.objects.all()]
self.assertEqual(contests, [contest, invisible_contest])
- self.client.get("/c/%s/dashboard/" % invisible_contest.id)
+ self.client.get(f"/c/{invisible_contest.id}/dashboard/")
response = self.client.get(reverse("select_contest"))
self.assertEqual(len(response.context["contests"]), 2)
contests = [cv.contest for cv in ContestView.objects.all()]
@@ -1176,7 +1176,7 @@ def failing_handler(env):
class BrokenContestController(ProgrammingContestController):
def fill_evaluation_environ(self, environ, submission):
- super(BrokenContestController, self).fill_evaluation_environ(environ, submission)
+ super().fill_evaluation_environ(environ, submission)
environ.setdefault("recipe", []).append(("failing_handler", "oioioi.contests.tests.tests.failing_handler"))
@@ -1642,17 +1642,17 @@ def check(visible, invisible):
# File list
response = self.client.get(list_url)
self.assertEqual(response.status_code, 200)
- for att, content, name in visible:
+ for att, _content, name in visible:
self.assertContains(response, name)
self.assertContains(response, att.description)
- for att, content, name in invisible:
+ for att, _content, name in invisible:
self.assertNotContains(response, name)
self.assertNotContains(response, att.description)
for f in response.context["files"]:
self.assertEqual(f["admin_only"], False)
# Actual accessibility
- for att, content, name in visible:
+ for att, content, _name in visible:
response = self.client.get(
reverse(
get_attachment_urlpattern_name(att),
@@ -1660,7 +1660,7 @@ def check(visible, invisible):
)
)
self.assertStreamingEqual(response, content)
- for att, content, name in invisible:
+ for att, _content, _name in invisible:
check_not_accessible(
self,
get_attachment_urlpattern_name(att),
@@ -1671,15 +1671,15 @@ def check(visible, invisible):
self.assertTrue(self.client.login(username="test_admin"))
response = self.client.get(list_url)
self.assertEqual(response.status_code, 200)
- for att, content, name in visible + invisible:
+ for att, _content, name in visible + invisible:
self.assertContains(response, name)
self.assertContains(response, att.description)
- invisible_names = set([f[2] for f in invisible])
+ invisible_names = {f[2] for f in invisible}
for f in response.context["files"]:
self.assertEqual(f["admin_only"], f["name"] in invisible_names)
# Actual accessibility as an admin
- for att, content, name in visible + invisible:
+ for att, content, _name in visible + invisible:
response = self.client.get(
reverse(
get_attachment_urlpattern_name(att),
@@ -3819,7 +3819,7 @@ def see_link_for_submission_on_problem_list(self, username, should_see):
contest = Contest.objects.get(pk="c")
problems_url = reverse("problems_list", kwargs={"contest_id": contest.id})
submission_url = reverse("submission", kwargs={"contest_id": contest.id, "submission_id": 1})
- expected_hyperlink = '' % submission_url
+ expected_hyperlink = f''
response = self.client.get(problems_url, follow=True)
@@ -3903,7 +3903,7 @@ class TestAPISubmitBase(APITestCase):
def __init__(self, *args, **kwargs):
self.fixtures += self.extra_fixtures
- super(TestAPISubmitBase, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def setUp(self):
self.client.force_authenticate(user=User.objects.get(username="test_user"))
@@ -3988,7 +3988,7 @@ def test_size_limit_accuracy(self):
self._assertSubmitted(response, 2)
def _assertUnsupportedExtension(self, contest, problem_instance, name, ext):
- response = self.contest_submit(contest, problem_instance, file_name="%s.%s" % (name, ext))
+ response = self.contest_submit(contest, problem_instance, file_name=f"{name}.{ext}")
self.assertContains(response, "Unknown or not supported file extension.", status_code=400)
def test_limiting_extensions(self):
diff --git a/oioioi/contests/urls.py b/oioioi/contests/urls.py
index 59c717179..709eeca46 100644
--- a/oioioi/contests/urls.py
+++ b/oioioi/contests/urls.py
@@ -206,8 +206,8 @@ def glob_namespaced_patterns(namespace):
views.filter_contests_view,
name="filter_contests",
),
- re_path(
- r"^get_contest_hints/$",
+ path(
+ "get_contest_hints/",
views.get_contest_hints_view,
name="get_contest_hints",
),
diff --git a/oioioi/contests/utils.py b/oioioi/contests/utils.py
index cf139982b..dd3954128 100755
--- a/oioioi/contests/utils.py
+++ b/oioioi/contests/utils.py
@@ -138,22 +138,19 @@ def generic_rounds_times(request=None, contest=None):
if not request or not hasattr(request, "user") or request.user.is_anonymous:
rtexts = {}
else:
- rtexts = dict((x["round_id"], x) for x in RoundTimeExtension.objects.filter(user=request.user, round__id__in=rids).values())
-
- result = dict(
- (
- r,
- RoundTimes(
- r.start_date,
- r.end_date,
- r.contest,
- r.results_date,
- r.public_results_date,
- rtexts[r.id]["extra_time"] if r.id in rtexts else 0,
- ),
+ rtexts = {x["round_id"]: x for x in RoundTimeExtension.objects.filter(user=request.user, round__id__in=rids).values()}
+
+ result = {
+ r: RoundTimes(
+ r.start_date,
+ r.end_date,
+ r.contest,
+ r.results_date,
+ r.public_results_date,
+ rtexts[r.id]["extra_time"] if r.id in rtexts else 0,
)
for r in rounds
- )
+ }
if request is not None:
getattr(request, cache_attribute)[contest.id] = result
return result
@@ -341,7 +338,7 @@ def get_results_visibility(request):
"""Returns the results ad ranking visibility for each round in the contest"""
rtimes = rounds_times(request, request.contest)
- dates = list()
+ dates = []
for r in rtimes.keys():
results_date = rtimes[r].results_date()
public_results_date = rtimes[r].public_results_date()
@@ -581,7 +578,7 @@ def best_round_to_display(request, allow_past_rounds=False):
past_rtimes = None
if timestamp and contest:
- rtimes = dict((round, contest.controller.get_round_times(request, round)) for round in Round.objects.filter(contest=contest))
+ rtimes = {round: contest.controller.get_round_times(request, round) for round in Round.objects.filter(contest=contest)}
next_rtimes = [(r, rt) for r, rt in rtimes.items() if rt.is_future(timestamp)]
next_rtimes.sort(key=lambda r_rt: r_rt[1].get_start())
current_rtimes = [(r, rt) for r, rt in rtimes if rt.is_active(timestamp) and rt.get_end()]
diff --git a/oioioi/contests/views.py b/oioioi/contests/views.py
index 8d6f3f863..eca82f7c2 100755
--- a/oioioi/contests/views.py
+++ b/oioioi/contests/views.py
@@ -182,8 +182,8 @@ def problems_list_view(request):
key=lambda p: (p[2].get_key_for_comparison(), p[0].round.name, p[0].short_name),
)
- show_submissions_limit = any([p[6] for p in problems_statements])
- show_submit_button = any([p[7] for p in problems_statements])
+ show_submissions_limit = any(p[6] for p in problems_statements)
+ show_submit_button = any(p[7] for p in problems_statements)
show_rounds = len(frozenset(pi.round_id for pi in problem_instances)) > 1
table_columns = 3 + int(show_problems_limits) + int(show_submissions_limit) + int(show_submit_button)
diff --git a/oioioi/dashboard/controllers.py b/oioioi/dashboard/controllers.py
index 4158b82ec..e7a38c144 100644
--- a/oioioi/dashboard/controllers.py
+++ b/oioioi/dashboard/controllers.py
@@ -13,7 +13,7 @@ def default_view(self, request):
if request.contest and can_enter_contest(request):
return reverse("contest_dashboard", kwargs={"contest_id": self.contest.id})
else:
- return super(DashboardDefaultViewMixin, self).default_view(request)
+ return super().default_view(request)
ContestController.mix_in(DashboardDefaultViewMixin)
diff --git a/oioioi/deployment/create_config.py b/oioioi/deployment/create_config.py
index f3606b8f0..638b76d5f 100644
--- a/oioioi/deployment/create_config.py
+++ b/oioioi/deployment/create_config.py
@@ -134,7 +134,7 @@ def main():
absolute_dir = os.path.abspath(args.dir)
if os.path.exists(absolute_dir):
- error("%s already exists; please specify another location" % (absolute_dir,))
+ error(f"{absolute_dir} already exists; please specify another location")
os.makedirs(absolute_dir)
diff --git a/oioioi/disqualification/admin.py b/oioioi/disqualification/admin.py
index 86d5ba4c0..9fa01c203 100644
--- a/oioioi/disqualification/admin.py
+++ b/oioioi/disqualification/admin.py
@@ -49,7 +49,7 @@ def formfield_for_foreignkey(self, db_field, request, **kwargs):
if request.contest:
qs = request.contest.controller.registration_controller().filter_participants(qs)
kwargs["queryset"] = qs
- return super(DisqualificationAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ return super().formfield_for_foreignkey(db_field, request, **kwargs)
def submission_link(self, instance):
if instance.submission is None:
@@ -60,11 +60,7 @@ def submission_link(self, instance):
}
return make_html_link(
reverse("submission", kwargs=reverse_kwargs),
- "%d (%s)"
- % (
- instance.submission_id,
- force_str(instance.submission.problem_instance),
- ),
+ f"{instance.submission_id} ({force_str(instance.submission.problem_instance)})",
)
submission_link.short_description = _("Submission")
@@ -82,14 +78,14 @@ def guilty_text(self, instance):
guilty_text.admin_order_field = "guilty"
def get_custom_list_select_related(self):
- return super(DisqualificationAdmin, self).get_custom_list_select_related() + [
+ return super().get_custom_list_select_related() + [
"submission",
"user",
"submission__problem_instance",
]
def get_queryset(self, request):
- return super(DisqualificationAdmin, self).get_queryset(request).filter(contest=request.contest).order_by("-id")
+ return super().get_queryset(request).filter(contest=request.contest).order_by("-id")
contest_site.contest_register(Disqualification, DisqualificationAdmin)
@@ -124,7 +120,7 @@ class DisqualificationsAdminMixin:
to an admin panel."""
def __init__(self, *args, **kwargs):
- super(DisqualificationsAdminMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.inlines = tuple(self.inlines) + (DisqualificationsConfigInline,)
diff --git a/oioioi/disqualification/controllers.py b/oioioi/disqualification/controllers.py
index fd291d24e..4de5fceba 100644
--- a/oioioi/disqualification/controllers.py
+++ b/oioioi/disqualification/controllers.py
@@ -66,7 +66,7 @@ def exclude_disqualified_users(self, queryset):
def change_submission_kind(self, submission, kind):
"""Changing the kind of submission should undisqualify given submission"""
old_kind = submission.kind
- super(DisqualificationContestControllerMixin, self).change_submission_kind(submission, kind)
+ super().change_submission_kind(submission, kind)
if submission.kind != old_kind:
Disqualification.objects.filter(submission=submission).update(guilty=False)
@@ -134,7 +134,7 @@ def _render_contestwide_disqualification_reason(self, request, user):
)
def render_my_submissions_header(self, request, submissions):
- header = super(DisqualificationContestControllerMixin, self).render_my_submissions_header(request, submissions)
+ header = super().render_my_submissions_header(request, submissions)
disq_header = self.render_disqualifications(request, request.user, submissions)
if disq_header:
header += disq_header
@@ -181,7 +181,7 @@ def render_disqualifications(self, request, user, submissions):
def get_contest_participant_info_list(self, request, user):
submissions = Submission.objects.filter(problem_instance__contest=request.contest, user=user).order_by("-date").select_related()
- info_list = super(DisqualificationContestControllerMixin, self).get_contest_participant_info_list(request, user)
+ info_list = super().get_contest_participant_info_list(request, user)
disqualification = self.render_disqualifications(request, user, submissions)
if disqualification:
@@ -196,7 +196,7 @@ class DisqualificationProgrammingContestControllerMixin:
"""ContestController mixin that renders submission disqualification info."""
def render_submission(self, request, submission):
- prev = super(DisqualificationProgrammingContestControllerMixin, self).render_submission(request, submission)
+ prev = super().render_submission(request, submission)
if self.is_submission_disqualified(submission) or (is_contest_admin(request) and self.has_disqualification_history(submission)):
return prev + self.render_submission_disqualifiaction(request, submission)
@@ -220,7 +220,7 @@ def _show_disqualified(self, key):
return self.is_admin_key(key)
def filter_users_for_ranking(self, key, queryset):
- qs = super(WithDisqualificationRankingControllerMixin, self).filter_users_for_ranking(key, queryset)
+ qs = super().filter_users_for_ranking(key, queryset)
if not self._show_disqualified(key):
qs = self.contest.controller.exclude_disqualified_users(qs)
@@ -229,26 +229,26 @@ def filter_users_for_ranking(self, key, queryset):
def _render_ranking_page(self, key, data, page):
if not self._show_disqualified(key):
- return super(WithDisqualificationRankingControllerMixin, self)._render_ranking_page(key, data, page)
+ return super()._render_ranking_page(key, data, page)
request = self._fake_request(page)
data["is_admin"] = self.is_admin_key(key)
return render_to_string("disqualification/default-ranking.html", context=data, request=request)
def _get_csv_header(self, key, data):
- header = super(WithDisqualificationRankingControllerMixin, self)._get_csv_header(key, data)
+ header = super()._get_csv_header(key, data)
if self._show_disqualified(key):
header.append(_("Disqualified"))
return header
def _get_csv_row(self, key, row):
- line = super(WithDisqualificationRankingControllerMixin, self)._get_csv_row(key, row)
+ line = super()._get_csv_row(key, row)
if self._show_disqualified(key):
line.append(_("Yes") if row.get("disqualified") else _("No"))
return line
def serialize_ranking(self, key):
- data = super(WithDisqualificationRankingControllerMixin, self).serialize_ranking(key)
+ data = super().serialize_ranking(key)
if not self._show_disqualified(key):
return data
return self._annotate_disqualified(key, data)
@@ -262,7 +262,7 @@ def _annotate_disqualified(self, key, data):
return data
def _ignore_in_ranking_places(self, data_row):
- prev = super(WithDisqualificationRankingControllerMixin, self)._ignore_in_ranking_places(data_row)
+ prev = super()._ignore_in_ranking_places(data_row)
return prev or data_row.get("disqualified", False)
diff --git a/oioioi/disqualification/models.py b/oioioi/disqualification/models.py
index ed538b830..54b43dc39 100644
--- a/oioioi/disqualification/models.py
+++ b/oioioi/disqualification/models.py
@@ -40,7 +40,7 @@ def save(self, *args, **kwargs):
assert self.contest.id == self.submission.problem_instance.contest_id
assert self.user.id == self.submission.user_id
- super(Disqualification, self).save(*args, **kwargs)
+ super().save(*args, **kwargs)
class DisqualificationsConfig(models.Model):
diff --git a/oioioi/disqualification/tests.py b/oioioi/disqualification/tests.py
index 56dcef8d3..ee4c43e3d 100644
--- a/oioioi/disqualification/tests.py
+++ b/oioioi/disqualification/tests.py
@@ -142,19 +142,28 @@ def _assert_submission(self, submission_id, disqualified):
def test_dashboard(self):
self.assertTrue(self.client.login(username="test_user"))
- response_cb = lambda: self.client.get(reverse("contest_dashboard", kwargs=self.contest_kwargs), follow=True)
+
+ def response_cb():
+ return self.client.get(reverse("contest_dashboard", kwargs=self.contest_kwargs), follow=True)
+
self._assert_disqualification_box(response_cb)
def test_my_submissions(self):
self.assertTrue(self.client.login(username="test_user"))
- response_cb = lambda: self.client.get(reverse("my_submissions", kwargs=self.contest_kwargs))
+
+ def response_cb():
+ return self.client.get(reverse("my_submissions", kwargs=self.contest_kwargs))
+
self._assert_disqualification_box(response_cb)
def test_user_info_page(self):
self.assertTrue(self.client.login(username="test_admin"))
user = User.objects.get(username="test_user")
contest = Contest.objects.get()
- response_callback = lambda: self.client.get(reverse("user_info", kwargs={"contest_id": contest.id, "user_id": user.id}))
+
+ def response_callback():
+ return self.client.get(reverse("user_info", kwargs={"contest_id": contest.id, "user_id": user.id}))
+
self._assert_disqualification_box(response_callback)
diff --git a/oioioi/evalmgr/admin.py b/oioioi/evalmgr/admin.py
index 7ac123720..4b01a6161 100644
--- a/oioioi/evalmgr/admin.py
+++ b/oioioi/evalmgr/admin.py
@@ -97,7 +97,7 @@ class SystemJobsQueueAdmin(admin.ModelAdmin):
actions = ["remove_from_queue", "delete_selected"]
def __init__(self, *args, **kwargs):
- super(SystemJobsQueueAdmin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.list_display_links = None
def _get_link(self, caption, app, *args, **kwargs):
@@ -173,14 +173,14 @@ def remove_from_queue(self, request, queryset):
remove_from_queue.short_description = _("Remove selected submissions from the queue")
def get_queryset(self, request):
- qs = super(SystemJobsQueueAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
return qs.exclude(state="CANCELLED")
def has_delete_permission(self, request, obj=None):
return is_contest_admin(request)
def get_custom_list_select_related(self):
- return super(SystemJobsQueueAdmin, self).get_custom_list_select_related() + [
+ return super().get_custom_list_select_related() + [
"submission__problem_instance",
"submission__problem_instance__contest",
"submission__problem_instance__problem",
@@ -205,7 +205,7 @@ class Meta:
class ContestJobsQueueAdmin(SystemJobsQueueAdmin):
def __init__(self, *args, **kwargs):
- super(ContestJobsQueueAdmin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.list_display = [x for x in self.list_display if x not in ("contest", "celery_task_id_link")]
self.list_display_links = None
self.list_filter = self.list_filter + [UserListFilter]
@@ -216,7 +216,7 @@ def has_change_permission(self, request, obj=None):
return is_contest_admin(request)
def get_queryset(self, request):
- qs = super(ContestJobsQueueAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
return qs.filter(submission__problem_instance__contest=request.contest)
diff --git a/oioioi/evalmgr/tasks.py b/oioioi/evalmgr/tasks.py
index a43c7b28c..7f32ac467 100644
--- a/oioioi/evalmgr/tasks.py
+++ b/oioioi/evalmgr/tasks.py
@@ -4,11 +4,11 @@
from uuid import uuid4
import six
+from celery.exceptions import Ignore
from django.db import transaction
from django.utils.module_loading import import_string
from celery import shared_task
-from celery.exceptions import Ignore
from oioioi.base.utils.db import require_transaction
from oioioi.base.utils.loaders import load_modules
from oioioi.evalmgr import logger
@@ -27,14 +27,14 @@ def _find_placeholder(recipe, name):
for i, entry in enumerate(recipe):
if entry[0] == name and entry[1] == placeholder:
return i
- raise IndexError("Placeholder '%s' not found in recipe" % (name,))
+ raise IndexError(f"Placeholder '{name}' not found in recipe")
def find_recipe_entry(recipe, name):
for i, entry in enumerate(recipe):
if entry[0] == name:
return i
- raise IndexError("Entry '%s' not found in recipe" % (name,))
+ raise IndexError(f"Entry '{name}' not found in recipe")
def recipe_placeholder(name):
@@ -143,7 +143,7 @@ def _run_phase(env, phase, extra_kwargs=None):
phaseName = phase[0]
handlerName = phase[1]
if len(phase) not in [2, 3]:
- raise TypeError("Receipt element has length neither 2 nor 3: %r" % phase)
+ raise TypeError(f"Receipt element has length neither 2 nor 3: {phase!r}")
if len(phase) == 2:
kwargs = {}
if len(phase) == 3:
@@ -153,7 +153,7 @@ def _run_phase(env, phase, extra_kwargs=None):
handler_func = import_string(handlerName)
env = handler_func(env, **kwargs)
if env is None:
- raise RuntimeError('Evaluation handler "%s" (%s) forgot to return the environment.' % (phaseName, handlerName))
+ raise RuntimeError(f'Evaluation handler "{phaseName}" ({handlerName}) forgot to return the environment.')
return env
@@ -218,7 +218,7 @@ def _run_error_handlers(env, exc_info):
error_handlers = env.get("error_handlers", [])
try:
for phase in error_handlers:
- env = _run_phase(env, phase, extra_kwargs=dict(exc_info=exc_info))
+ env = _run_phase(env, phase, extra_kwargs={"exc_info": exc_info})
# pylint: disable=broad-except
except Exception:
logger.error(
@@ -321,7 +321,7 @@ def prepare_transfer_handler(environ, **kwargs):
if "recipe" not in env:
raise RuntimeError('No recipe found in job environment. Did you forget to set environ["run_externally"]?')
if "error" in env:
- raise RuntimeError("Error from workers:\n%s\nTB:\n%s" % (env["error"]["message"], env["error"]["traceback"]))
+ raise RuntimeError("Error from workers:\n{}\nTB:\n{}".format(env["error"]["message"], env["error"]["traceback"]))
_mark_job_state(env, "PROGRESS")
while True:
recipe = env.get("recipe")
diff --git a/oioioi/evalmgr/tests/tests.py b/oioioi/evalmgr/tests/tests.py
index e6b7d19fb..d4daf8485 100644
--- a/oioioi/evalmgr/tests/tests.py
+++ b/oioioi/evalmgr/tests/tests.py
@@ -58,20 +58,20 @@ def rest_handler(env, **kwargs):
class TestLocalJobs(TestCase):
def test_evalmgr_job(self):
env = create_environ()
- env.update(dict(recipe=hunting, area="forest"))
+ env.update({"recipe": hunting, "area": "forest"})
env = delay_environ_wrapper(env).get()
self.assertEqual("Hedgehog hunted.", env["output"])
def test_cascade_job(self):
env = create_environ()
- env.update(dict(recipe=hunting, area="forest"))
+ env.update({"recipe": hunting, "area": "forest"})
env = delay_environ_wrapper(env).get()
self.assertEqual("Hedgehog hunted.", env["output"])
def test_multiple_jobs(self):
- city_result = delay_environ_wrapper(dict(job_id=42, recipe=hunting, area="city"))
- forest_result = delay_environ_wrapper(dict(job_id=43, recipe=hunting, area="forest"))
- jungle_result = delay_environ_wrapper(dict(job_id=44, recipe=hunting, area="jungle"))
+ city_result = delay_environ_wrapper({"job_id": 42, "recipe": hunting, "area": "city"})
+ forest_result = delay_environ_wrapper({"job_id": 43, "recipe": hunting, "area": "forest"})
+ jungle_result = delay_environ_wrapper({"job_id": 44, "recipe": hunting, "area": "jungle"})
self.assertEqual("Hedgehog hunted.", forest_result.get()["output"])
self.assertEqual("Epic fail.", city_result.get()["output"])
self.assertEqual("Epic fail.", jungle_result.get()["output"])
@@ -85,12 +85,12 @@ def upload_source(env, **kwargs):
def compile_source(env, **kwargs):
env.update(
- dict(
- source_file=env["remote_source_file"],
- out_file=env["binary_file"],
- compiler="system-gcc",
- job_type="compile",
- )
+ {
+ "source_file": env["remote_source_file"],
+ "out_file": env["binary_file"],
+ "compiler": "system-gcc",
+ "job_type": "compile",
+ }
)
return run_sioworkers_job(env)
@@ -104,7 +104,7 @@ def upload_inout(env, **kwargs):
def run(env, **kwargs):
- env.update(dict(exe_file=env["binary_file"], check_output=True, job_type="unsafe-exec"))
+ env.update({"exe_file": env["binary_file"], "check_output": True, "job_type": "unsafe-exec"})
return run_sioworkers_job(env)
@@ -142,17 +142,17 @@ class TestRemoteJobs(TestCase):
("upload test", "oioioi.evalmgr.tests.tests.upload_inout"),
("run", "oioioi.evalmgr.tests.tests.run"),
]
- evaluation_env = dict(
- job_id=42,
- recipe=evaluation_recipe,
- local_source_file=local_source_file,
- remote_source_file=remote_source_file,
- binary_file=binary_file,
- local_in_file=local_in_file,
- remote_in_file=remote_in_file,
- local_out_file=local_out_file,
- remote_out_file=remote_out_file,
- )
+ evaluation_env = {
+ "job_id": 42,
+ "recipe": evaluation_recipe,
+ "local_source_file": local_source_file,
+ "remote_source_file": remote_source_file,
+ "binary_file": binary_file,
+ "local_in_file": local_in_file,
+ "remote_in_file": remote_in_file,
+ "local_out_file": local_out_file,
+ "remote_out_file": remote_out_file,
+ }
def tearDown(self):
fc = get_client()
@@ -233,35 +233,35 @@ def test_error_behavior(self):
case = 1
tests = [ # evaluation error
(
- dict(recipe=hunting, area="elevator", error_handlers=self.error_handlers),
+ {"recipe": hunting, "area": "elevator", "error_handlers": self.error_handlers},
HuntingException,
"ARRESTED",
"ashamed",
),
# job with no recipe
(
- dict(
- very_important_task="kill another hedgehog remotely",
- error_handlers=self.arrest,
- ),
+ {
+ "very_important_task": "kill another hedgehog remotely",
+ "error_handlers": self.arrest,
+ },
RuntimeError,
"ARRESTED",
None,
),
# handler not returning environment
(
- dict(recipe=hunting, area="blackhole", error_handlers=self.arrest),
+ {"recipe": hunting, "area": "blackhole", "error_handlers": self.arrest},
RuntimeError,
"ARRESTED",
None,
),
# corrupted error handler
(
- dict(
- recipe=hunting,
- area="elevator",
- error_handlers=self.corrupted_error_handler,
- ),
+ {
+ "recipe": hunting,
+ "area": "elevator",
+ "error_handlers": self.corrupted_error_handler,
+ },
HuntingException,
None,
None,
diff --git a/oioioi/exportszu/forms.py b/oioioi/exportszu/forms.py
index 269b62952..cf0c2de07 100644
--- a/oioioi/exportszu/forms.py
+++ b/oioioi/exportszu/forms.py
@@ -12,5 +12,5 @@ class ExportSubmissionsForm(forms.Form):
only_final = forms.BooleanField(label=_("Only submissions used for final scoring"), required=False, initial=True)
def __init__(self, request, *args, **kwargs):
- super(ExportSubmissionsForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["round"].queryset = request.contest.round_set
diff --git a/oioioi/exportszu/utils.py b/oioioi/exportszu/utils.py
index 1ce155702..15ddcf802 100644
--- a/oioioi/exportszu/utils.py
+++ b/oioioi/exportszu/utils.py
@@ -61,7 +61,6 @@ def get_contest_id(self):
return self.contest.id
def collect_list(self):
- ccontroller = self.contest.controller
q_expressions = Q(user__isnull=False)
if self.round:
@@ -75,7 +74,7 @@ def collect_list(self):
if self.lang_exts:
q_expr_langs = Q()
for ext in self.lang_exts:
- q_expr_langs |= Q(source_file__contains=".%s@" % ext)
+ q_expr_langs |= Q(source_file__contains=f".{ext}@")
q_expressions &= q_expr_langs
if self.only_final:
@@ -170,12 +169,7 @@ def encode(obj):
index_csv.writerow([encode(col) for col in index_entry])
for s in submission_list:
- filename = "%s:%s:%s.%s" % (
- s.submission_id,
- s.username,
- s.problem_short_name,
- s.solution_language,
- )
+ filename = f"{s.submission_id}:{s.username}:{s.problem_short_name}.{s.solution_language}"
dest = os.path.join(files_dir, filename)
submission_collector.get_submission_source(dest, s.source_file)
diff --git a/oioioi/exportszu/views.py b/oioioi/exportszu/views.py
index cb668e40b..b1b3d202f 100644
--- a/oioioi/exportszu/views.py
+++ b/oioioi/exportszu/views.py
@@ -32,7 +32,7 @@ def export_submissions_view(request):
tmp_file.seek(0, os.SEEK_SET) # go to the beginning of the file
response = FileResponse(tmp_file)
response["Content-Type"] = "application/gzip"
- response["Content-Disposition"] = 'attachment; filename="%s.tgz"' % request.contest.id
+ response["Content-Disposition"] = f'attachment; filename="{request.contest.id}.tgz"'
return response
else:
form = ExportSubmissionsForm(request)
diff --git a/oioioi/filetracker/client.py b/oioioi/filetracker/client.py
index 38cfdc719..f67daf273 100644
--- a/oioioi/filetracker/client.py
+++ b/oioioi/filetracker/client.py
@@ -23,10 +23,10 @@ def get_client():
if isinstance(factory, str):
factory = import_string(factory)
if not callable(factory):
- raise ImproperlyConfigured("The FILETRACKER_CLIENT_FACTORY setting refers to non-callable: %r" % (factory,))
+ raise ImproperlyConfigured(f"The FILETRACKER_CLIENT_FACTORY setting refers to non-callable: {factory!r}")
client = factory()
if not isinstance(client, FiletrackerClient):
- raise ImproperlyConfigured("The factory pointed by FILETRACKER_CLIENT_FACTORY returned non-FiletrackerClient: %r" % (client,))
+ raise ImproperlyConfigured(f"The factory pointed by FILETRACKER_CLIENT_FACTORY returned non-FiletrackerClient: {client!r}")
# Needed for oioioi.sioworkers.backends.LocalBackend so that both Django
# and sioworkers use the same Filetracker client
diff --git a/oioioi/filetracker/fields.py b/oioioi/filetracker/fields.py
index dc1b55ec0..c911ba376 100644
--- a/oioioi/filetracker/fields.py
+++ b/oioioi/filetracker/fields.py
@@ -11,7 +11,7 @@ class FieldFile(files.FieldFile):
def __init__(self, instance, field, name):
if name is not None:
name = FiletrackerFilename(name)
- super(FieldFile, self).__init__(instance, field, name)
+ super().__init__(instance, field, name)
def read_using_cache(self):
"""Opens a file using a cache (if it's possible)"""
@@ -23,7 +23,7 @@ def read_using_cache(self):
class _FileDescriptor(files.FileDescriptor):
def __get__(self, instance=None, owner=None):
if instance is None:
- raise AttributeError("The '%s' attribute can only be accessed from %s instances." % (self.field.name, owner.__name__))
+ raise AttributeError(f"The '{self.field.name}' attribute can only be accessed from {owner.__name__} instances.")
file = instance.__dict__[self.field.name]
if isinstance(file, str) and file == "none":
instance.__dict__[self.field.name] = None
@@ -69,12 +69,12 @@ class FileField(files.FileField):
def __init__(self, *args, **kwargs):
# Default value max_length=100 is not sufficient.
kwargs.setdefault("max_length", 255)
- super(FileField, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def get_prep_value(self, value):
if hasattr(value, "name") and isinstance(value.name, FiletrackerFilename):
value = value.name.versioned_name
- return super(FileField, self).get_prep_value(value)
+ return super().get_prep_value(value)
def value_to_string(self, obj):
value = self.value_from_object(obj)
diff --git a/oioioi/filetracker/management/commands/collectgarbage.py b/oioioi/filetracker/management/commands/collectgarbage.py
index c84778006..f4ea67b5a 100644
--- a/oioioi/filetracker/management/commands/collectgarbage.py
+++ b/oioioi/filetracker/management/commands/collectgarbage.py
@@ -50,7 +50,7 @@ def handle(self, *args, **options):
all_files = get_client().list_local_files()
max_date_to_delete = datetime.datetime.now() - datetime.timedelta(days=options["days"])
- diff = set([f[0] for f in all_files]) - set(needed_files)
+ diff = {f[0] for f in all_files} - set(needed_files)
to_delete = [f[0] for f in all_files if f[0] in diff and datetime.datetime.fromtimestamp(f[1]) < max_date_to_delete]
files_count = len(to_delete)
diff --git a/oioioi/filetracker/tests.py b/oioioi/filetracker/tests.py
index 4f735df8c..68d2a109c 100644
--- a/oioioi/filetracker/tests.py
+++ b/oioioi/filetracker/tests.py
@@ -7,9 +7,9 @@
from django.db.models.fields.files import FieldFile, FileField
from django.urls import reverse
from django.utils import timezone
+from filetracker.client.dummy import DummyClient
from filetracker.client import Client as FiletrackerClient
-from filetracker.client.dummy import DummyClient
from oioioi.base.tests import TestCase
from oioioi.filetracker.models import FileTestModel
from oioioi.filetracker.storage import FiletrackerStorage
diff --git a/oioioi/filetracker/utils.py b/oioioi/filetracker/utils.py
index 904a8ffc2..e868a487b 100644
--- a/oioioi/filetracker/utils.py
+++ b/oioioi/filetracker/utils.py
@@ -38,14 +38,14 @@ def django_to_filetracker_path(django_file):
"""Returns the filetracker path of a :class:`django.core.files.File`."""
storage = getattr(django_file, "storage", None)
if not storage:
- raise ValueError("File of type %r is not stored in Filetracker" % (type(django_file),))
+ raise ValueError(f"File of type {type(django_file)!r} is not stored in Filetracker")
name = django_file.name
if hasattr(name, "versioned_name"):
name = name.versioned_name
try:
return storage._make_filetracker_path(name)
except AttributeError:
- raise ValueError("File is stored in %r, not Filetracker" % (storage,))
+ raise ValueError(f"File is stored in {storage!r}, not Filetracker")
def filetracker_to_django_file(filetracker_path, storage=None):
@@ -57,7 +57,7 @@ def filetracker_to_django_file(filetracker_path, storage=None):
prefix_len = len(storage.prefix.rstrip("/"))
if not filetracker_path.startswith(storage.prefix) or filetracker_path[prefix_len : prefix_len + 1] != "/":
- raise ValueError("Path %s is outside of storage prefix %s" % (filetracker_path, storage.prefix))
+ raise ValueError(f"Path {filetracker_path} is outside of storage prefix {storage.prefix}")
return FileInFiletracker(storage, FiletrackerFilename(filetracker_path[prefix_len + 1 :]))
diff --git a/oioioi/forum/admin.py b/oioioi/forum/admin.py
index f36038563..1b0c9605d 100644
--- a/oioioi/forum/admin.py
+++ b/oioioi/forum/admin.py
@@ -21,7 +21,7 @@ def string_concat(*strings):
def make_list_elem(elem, text=None):
if not text:
text = elem.name
- return "%s" % make_html_link(elem.get_admin_url(), text)
+ return f"{make_html_link(elem.get_admin_url(), text)}"
def get_permission(self, request):
@@ -50,7 +50,7 @@ def categories(self, obj):
ret = "".join(slist)
if not ret:
ret = string_concat("", _("Empty forum"), "")
- return mark_safe("" % ret)
+ return mark_safe(f"")
categories.short_description = _("Categories")
@@ -108,12 +108,12 @@ def response_change(self, request, obj):
# view.
if "_popup" not in request.POST:
return HttpResponseRedirect(request.get_full_path())
- return super(ForumAdmin, self).response_change(request, obj)
+ return super().response_change(request, obj)
def get_queryset(self, request):
# each qs filters forum/categories/threads/posts connected with
# this particular contest
- qs = super(ForumAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
qs = qs.filter(contest=request.contest)
return qs
@@ -130,7 +130,7 @@ def threads(self, obj):
ret = "".join(slist)
if not ret:
ret = string_concat("", _("Empty category"), "")
- return mark_safe("" % ret)
+ return mark_safe(f"")
threads.short_description = _("Threads")
@@ -161,20 +161,20 @@ def has_view_permission(self, request, obj=None):
def response_add(self, request, obj, post_url_continue=None):
if "_popup" not in request.POST:
return HttpResponseRedirect(reverse("oioioiadmin:forum_forum_change", args=(request.contest.forum.id,)))
- return super(CategoryAdmin, self).response_add(request, obj, post_url_continue)
+ return super().response_add(request, obj, post_url_continue)
def response_change(self, request, obj):
if "_popup" not in request.POST:
return HttpResponseRedirect(request.get_full_path())
- return super(CategoryAdmin, self).response_change(request, obj)
+ return super().response_change(request, obj)
def response_delete(self, request):
if "came_from" in request.GET or not self.has_change_permission(request):
- return super(CategoryAdmin, self).response_delete(request)
+ return super().response_delete(request)
return HttpResponseRedirect(reverse("oioioiadmin:forum_forum_change", args=(request.contest.forum.id,)))
def get_queryset(self, request):
- qs = super(CategoryAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
qs = qs.filter(forum=request.contest.forum)
return qs
@@ -185,18 +185,18 @@ class ThreadAdmin(admin.ModelAdmin):
def get_post_descr(self, post):
localtime = timezone.localtime(post.add_date)
- return "#%(id)s. %(author)s: %(date)s" % {
- "id": post.id,
- "author": post.author,
- "date": localtime.strftime("%Y-%m-%d %H:%M:%S"),
- }
+ return "#{id}. {author}: {date}".format(
+ id=post.id,
+ author=post.author,
+ date=localtime.strftime("%Y-%m-%d %H:%M:%S"),
+ )
def posts(self, obj):
slist = [make_list_elem(p, self.get_post_descr(p)) for p in obj.post_set.select_related("author").all()]
ret = "".join(slist)
if not ret:
ret = string_concat("", _("Empty thread"), "")
- return mark_safe("" % ret)
+ return mark_safe(f"")
posts.short_description = _("Posts")
@@ -221,25 +221,25 @@ def has_view_permission(self, request, obj=None):
def response_add(self, request, obj, post_url_continue=None):
if "_popup" not in request.POST:
return HttpResponseRedirect(reverse("oioioiadmin:forum_forum_change", args=(request.contest.forum.id,)))
- return super(ThreadAdmin, self).response_add(request, obj, post_url_continue)
+ return super().response_add(request, obj, post_url_continue)
def response_change(self, request, obj):
if "_popup" not in request.POST:
return HttpResponseRedirect(request.get_full_path())
- return super(ThreadAdmin, self).response_change(request, obj)
+ return super().response_change(request, obj)
def response_delete(self, request):
if "came_from" in request.GET or not self.has_change_permission(request):
- return super(ThreadAdmin, self).response_delete(request)
+ return super().response_delete(request)
return HttpResponseRedirect(reverse("oioioiadmin:forum_forum_change", args=(request.contest.forum.id,)))
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "category":
kwargs["queryset"] = Category.objects.filter(forum=request.contest.forum)
- return super(ThreadAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ return super().formfield_for_foreignkey(db_field, request, **kwargs)
def get_queryset(self, request):
- qs = super(ThreadAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
qs = qs.filter(category__forum=request.contest.forum)
return qs
@@ -291,17 +291,17 @@ def has_view_permission(self, request, obj=None):
def response_change(self, request, obj):
if "_popup" not in request.POST:
return HttpResponseRedirect(request.get_full_path())
- return super(PostAdmin, self).response_change(request, obj)
+ return super().response_change(request, obj)
def response_delete(self, request):
if "came_from" in request.GET or not self.has_change_permission(request):
- return super(PostAdmin, self).response_delete(request)
+ return super().response_delete(request)
return HttpResponseRedirect(reverse("oioioiadmin:forum_forum_change", args=(request.contest.forum.id,)))
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "thread":
kwargs["queryset"] = Thread.objects.filter(category__forum=request.contest.forum)
- return super(PostAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
+ return super().formfield_for_foreignkey(db_field, request, **kwargs)
def hide_action(self, request, queryset):
queryset.update(hidden=True)
@@ -363,7 +363,7 @@ def revoke_approval_action(self, request, queryset):
revoke_approval_action.short_description = _("Revoke approval of selected posts")
def get_queryset(self, request):
- qs = super(PostAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
qs = qs.filter(thread__category__forum=request.contest.forum)
return qs
@@ -383,7 +383,7 @@ def has_delete_permission(self, request, obj=None):
return get_permission(self, request)
def get_queryset(self, request):
- qs = super(BanAdmin, self).get_queryset(request)
+ qs = super().get_queryset(request)
qs = qs.filter(forum=request.contest.forum)
return qs
diff --git a/oioioi/forum/controllers.py b/oioioi/forum/controllers.py
index 6ae9e4191..6f1179fb0 100644
--- a/oioioi/forum/controllers.py
+++ b/oioioi/forum/controllers.py
@@ -12,7 +12,7 @@ class ContestControllerWithForum:
create_forum = True
def adjust_contest(self):
- super(ContestControllerWithForum, self).adjust_contest()
+ super().adjust_contest()
Forum.objects.get_or_create(contest=self.contest)
diff --git a/oioioi/forum/forms.py b/oioioi/forum/forms.py
index ff8476bf7..1e86d6c20 100644
--- a/oioioi/forum/forms.py
+++ b/oioioi/forum/forms.py
@@ -12,11 +12,11 @@ class Meta:
fields = ["content"]
def __init__(self, request, *args, **kwargs):
- super(PostForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["content"].widget.attrs["class"] = "monospace"
def is_valid(self):
- valid = super(PostForm, self).is_valid()
+ valid = super().is_valid()
if not valid:
return valid
if len(self.cleaned_data["content"]) > getattr(settings, "FORUM_POST_MAX_LENGTH", 20000):
@@ -33,7 +33,7 @@ class Meta:
content = forms.CharField(widget=forms.Textarea, required=True)
def __init__(self, request, *args, **kwargs):
- super(NewThreadForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["name"].label = _("Topic")
self.fields["name"].widget.attrs["class"] = "monospace"
self.fields["content"].widget.attrs["class"] = "monospace"
@@ -47,7 +47,7 @@ class Meta:
delete_reports = forms.BooleanField(widget=forms.CheckboxInput(), label=_("Remove user reports"), required=False)
def __init__(self, *args, **kwargs):
- super(BanForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["reason"].label = _("Reason")
self.fields["reason"].widget.attrs["class"] = "monospace"
@@ -58,7 +58,7 @@ class Meta:
fields = ["report_reason"]
def __init__(self, *args, **kwargs):
- super(ReportForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.fields["report_reason"].label = _("Reason")
self.fields["report_reason"].widget.attrs["class"] = "monospace non-resizable"
diff --git a/oioioi/forum/models.py b/oioioi/forum/models.py
index fb8d86caa..5271db2ae 100644
--- a/oioioi/forum/models.py
+++ b/oioioi/forum/models.py
@@ -31,7 +31,7 @@ class Meta:
verbose_name_plural = _("forums")
def __str__(self):
- return "%(name)s" % {"name": self.contest.name}
+ return f"{self.contest.name}"
def is_autolocked(self, now=None):
"""Returns true if forum is locked"""
@@ -65,7 +65,7 @@ class Meta:
ordering = ("order",)
def __str__(self):
- return "%s" % self.name
+ return f"{self.name}"
def count_threads(self):
return self.thread_set.count()
@@ -99,7 +99,7 @@ def save(self, **kwargs):
else:
self.order = 0
- super(Category, self).save(**kwargs)
+ super().save(**kwargs)
class Thread(models.Model):
@@ -121,7 +121,7 @@ class Meta:
verbose_name_plural = _("threads")
def __str__(self):
- return "%(name)s" % {"name": self.name}
+ return f"{self.name}"
def count_posts(self):
return self.post_set.count()
@@ -194,10 +194,7 @@ class Meta:
verbose_name_plural = _("posts")
def __str__(self):
- return "%(content)s in %(thread)s" % {
- "content": self.content,
- "thread": self.thread,
- }
+ return f"{self.content} in {self.thread}"
def get_admin_url(self):
return reverse("oioioiadmin:forum_post_change", args=(self.id,))
@@ -212,7 +209,7 @@ def get_in_thread_url(self):
"thread_id": thread.id,
},
)
- post_url = "%s#forum-post-%d" % (thread_url, self.id)
+ post_url = f"{thread_url!s}#forum-post-{self.id}"
return post_url
def can_be_removed(self):
diff --git a/oioioi/forum/tests.py b/oioioi/forum/tests.py
index 4d4c45d8b..589567b94 100644
--- a/oioioi/forum/tests.py
+++ b/oioioi/forum/tests.py
@@ -474,10 +474,7 @@ def test_report(self):
)
response = self.client.post(url, follow=True)
- reported_pattern = r"was reported\s*by\s*]*>\s*%s %s\s*<\/a>" % (
- name,
- surname,
- )
+ reported_pattern = rf"was reported\s*by\s*]*>\s*{name} {surname}\s*<\/a>"
self.assertTrue(re.search(reported_pattern, response.content.decode("utf-8")))
def test_approve_after_report(self):
diff --git a/oioioi/globalmessage/admin.py b/oioioi/globalmessage/admin.py
index 3c1408cd0..d66671f1b 100644
--- a/oioioi/globalmessage/admin.py
+++ b/oioioi/globalmessage/admin.py
@@ -25,7 +25,7 @@ def get_urls(self):
# Global Message singleton always has primary_key = 1
# @see GlobalMessage.get_singleton
pk = "1"
- urls = super(GlobalMessageAdmin, self).get_urls()
+ urls = super().get_urls()
custom_urls = [
path("", self.admin_site.admin_view(self.change_view), {"object_id": pk}),
diff --git a/oioioi/ipauthsync/admin.py b/oioioi/ipauthsync/admin.py
index ddacc454d..293d91808 100644
--- a/oioioi/ipauthsync/admin.py
+++ b/oioioi/ipauthsync/admin.py
@@ -27,5 +27,5 @@ class ContestAdminWithIpAuthSyncInlineMixin:
"""
def __init__(self, *args, **kwargs):
- super(ContestAdminWithIpAuthSyncInlineMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.inlines = tuple(self.inlines) + (IpAuthSyncConfigInline,)
diff --git a/oioioi/ipauthsync/controllers.py b/oioioi/ipauthsync/controllers.py
index 32cd21506..680005d94 100644
--- a/oioioi/ipauthsync/controllers.py
+++ b/oioioi/ipauthsync/controllers.py
@@ -9,7 +9,7 @@ class IpAuthSyncControllerMixin:
def mixins_for_admin(self):
from oioioi.ipauthsync.admin import ContestAdminWithIpAuthSyncInlineMixin
- mixins = super(IpAuthSyncControllerMixin, self).mixins_for_admin()
+ mixins = super().mixins_for_admin()
if is_onsite_contest(self.contest):
mixins = mixins + (ContestAdminWithIpAuthSyncInlineMixin,)
return mixins
diff --git a/oioioi/ipauthsync/management/commands/ipauthsyncd.py b/oioioi/ipauthsync/management/commands/ipauthsyncd.py
index 5b56cad86..97d064e77 100644
--- a/oioioi/ipauthsync/management/commands/ipauthsyncd.py
+++ b/oioioi/ipauthsync/management/commands/ipauthsyncd.py
@@ -40,7 +40,7 @@ def handle_config(self, config):
try:
r = requests.get(
f"http://{region.region_server}/ipauthsync/list",
- headers=dict(Host="oireg"),
+ headers={"Host": "oireg"},
)
r.raise_for_status()
@@ -53,16 +53,16 @@ def handle_config(self, config):
reg = OnsiteRegistration.objects.select_related("participant__user").get(number=zaw_id, region=region)
user = reg.participant.user
except OnsiteRegistration.DoesNotExist:
- warnings.append("* No user found for ZAW=%s (IP=%s)" % (zaw_id, ip))
+ warnings.append(f"* No user found for ZAW={zaw_id} (IP={ip})")
continue
try:
rc.ipauthsync_validate_ip(region, ip, user)
# pylint: disable=broad-except
except Exception as e:
- warnings.append("Invalid IP=%s (ZAW=%s): %s" % (ip, zaw_id, e))
+ warnings.append(f"Invalid IP={ip} (ZAW={zaw_id}): {e}")
- mapping.append("%s %s %s" % (zaw_id, ip, user.username))
+ mapping.append(f"{zaw_id} {ip} {user.username}")
yield user, ip
@@ -73,21 +73,21 @@ def handle_config(self, config):
msgs.warnings = warnings
msgs.save()
mail_admins(
- "ipauthsyncd: Warnings for region %s" % (region.short_name,),
+ f"ipauthsyncd: Warnings for region {region.short_name}",
warnings,
)
if mapping != msgs.mapping:
msgs.mapping = mapping
msgs.save()
mail_admins(
- "ipauthsyncd: Mapping for region %s" % (region.short_name,),
+ f"ipauthsyncd: Mapping for region {region.short_name}",
mapping,
)
if region.short_name in self.failing_regions:
self.failing_regions.remove(region.short_name)
mail_admins(
- "ipauthsyncd: Sync now OK for region %s" % (region.short_name,),
+ f"ipauthsyncd: Sync now OK for region {region.short_name}",
"(Intentionally left blank)",
)
# pylint: disable=broad-except
@@ -96,7 +96,7 @@ def handle_config(self, config):
continue
self.failing_regions.add(region.short_name)
mail_admins(
- "ipauthsyncd: Sync failing for region %s" % (region.short_name,),
+ f"ipauthsyncd: Sync failing for region {region.short_name}",
traceback.format_exc(),
)
diff --git a/oioioi/ipauthsync/models.py b/oioioi/ipauthsync/models.py
index f373c3727..912b23637 100644
--- a/oioioi/ipauthsync/models.py
+++ b/oioioi/ipauthsync/models.py
@@ -32,7 +32,7 @@ class Meta:
verbose_name_plural = _("IP authentication sync configs")
def __str__(self):
- return "%s (%s): %s - %s" % (
+ return "{} ({}): {} - {}".format(
self.contest,
"enabled" if self.enabled else "disabled",
self.start_date,
diff --git a/oioioi/ipdnsauth/management/commands/ipauth-dnsserver.py b/oioioi/ipdnsauth/management/commands/ipauth-dnsserver.py
index b0949f579..626a74bce 100644
--- a/oioioi/ipdnsauth/management/commands/ipauth-dnsserver.py
+++ b/oioioi/ipdnsauth/management/commands/ipauth-dnsserver.py
@@ -154,7 +154,7 @@ def add_arguments(self, parser):
parser.add_argument("--ttl", type=int, default=60, help="Specify TTL for returned records")
def __init__(self, *args, **kwargs):
- super(Command, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.options = None
def handle(self, *args, **options):
diff --git a/oioioi/ipdnsauth/management/commands/ipdnsauth.py b/oioioi/ipdnsauth/management/commands/ipdnsauth.py
index 8bcf719c7..db398c894 100644
--- a/oioioi/ipdnsauth/management/commands/ipdnsauth.py
+++ b/oioioi/ipdnsauth/management/commands/ipdnsauth.py
@@ -72,7 +72,7 @@ def load_data(self, module, modelMgr, data):
binding.save()
# pylint: disable=broad-except
except Exception as e:
- self.stderr.write("Error for %s: %s\n" % (row, e))
+ self.stderr.write(f"Error for {row}: {e}\n")
def load(self, module, modelMgr, filename):
self.load_data(module, modelMgr, self._read(filename))
@@ -87,7 +87,7 @@ def unload_data(self, module, modelMgr, data):
modelMgr.get(user__username=row[0], dns_name=row[1]).delete()
# pylint: disable=broad-except
except Exception as e:
- self.stderr.write("Error for %s: %s\n" % (row, e))
+ self.stderr.write(f"Error for {row}: {e}\n")
def unload(self, module, modelMgr, filename):
self.unload_data(module, modelMgr, self._read(filename))
diff --git a/oioioi/livedata/tests.py b/oioioi/livedata/tests.py
index d9ba3ce2d..9333125f9 100644
--- a/oioioi/livedata/tests.py
+++ b/oioioi/livedata/tests.py
@@ -41,7 +41,7 @@ def test_cache_unless_admin_or_observer(self):
contest = Contest.objects.get()
round = Round.objects.filter(contest_id=contest.id).get()
view_name = "livedata_teams_view"
- cache_key = "%s/%s/%s" % (view_name, contest.id, round.id)
+ cache_key = f"{view_name}/{contest.id}/{round.id}"
url = reverse(view_name, kwargs={"contest_id": contest.id, "round_id": round.id})
# For users that aren't admins or observers, the second request will
# come from the cache, this verifies if the cached result's content is
diff --git a/oioioi/livedata/utils.py b/oioioi/livedata/utils.py
index e74a739a8..ee88aaf8a 100644
--- a/oioioi/livedata/utils.py
+++ b/oioioi/livedata/utils.py
@@ -8,6 +8,6 @@ def can_see_livedata(request):
def get_display_name(user):
if user.last_name and user.first_name:
- return "%s. %s" % (user.first_name[0], user.last_name)
+ return f"{user.first_name[0]}. {user.last_name}"
else:
return user.username
diff --git a/oioioi/livedata/views.py b/oioioi/livedata/views.py
index b6104257b..cdcbc6700 100644
--- a/oioioi/livedata/views.py
+++ b/oioioi/livedata/views.py
@@ -26,7 +26,7 @@ def inner(request, round_id):
if not should_cache:
return view(request, round_id)
- cache_key = "%s/%s/%s" % (view.__name__, request.contest.id, round_id)
+ cache_key = f"{view.__name__}/{request.contest.id}/{round_id}"
result = cache.get(cache_key)
if result is None:
result = view(request, round_id)
diff --git a/oioioi/mailsubmit/admin.py b/oioioi/mailsubmit/admin.py
index eca32ff66..44edd00ed 100644
--- a/oioioi/mailsubmit/admin.py
+++ b/oioioi/mailsubmit/admin.py
@@ -38,7 +38,7 @@ class MailSubmissionConfigAdminMixin:
"""
def __init__(self, *args, **kwargs):
- super(MailSubmissionConfigAdminMixin, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.inlines = tuple(self.inlines) + (MailSubmissionConfigInline,)
@@ -62,7 +62,7 @@ class MailSubmissionAdmin(admin.ModelAdmin):
search_fields = ["user__username", "user__last_name"]
def get_custom_list_select_related(self):
- return super(MailSubmissionAdmin, self).get_custom_list_select_related() + [
+ return super().get_custom_list_select_related() + [
"user",
"accepted_by",
"problem_instance__problem",
@@ -118,13 +118,13 @@ def accept_action(self, request, queryset):
accept_action.short_description = _("Accept selected submissions")
def get_queryset(self, request):
- queryset = super(MailSubmissionAdmin, self).get_queryset(request)
+ queryset = super().get_queryset(request)
queryset = queryset.filter(problem_instance__contest=request.contest)
queryset = queryset.order_by("-id")
return queryset
def changelist_view(self, request, extra_context=None):
- return super(MailSubmissionAdmin, self).changelist_view(request, extra_context=extra_context)
+ return super().changelist_view(request, extra_context=extra_context)
contest_site.contest_register(MailSubmission, MailSubmissionAdmin)
diff --git a/oioioi/mailsubmit/forms.py b/oioioi/mailsubmit/forms.py
index 5f4eb36cb..3058308e3 100644
--- a/oioioi/mailsubmit/forms.py
+++ b/oioioi/mailsubmit/forms.py
@@ -14,10 +14,10 @@ class MailSubmissionForm(SubmissionForm):
def __init__(self, request, *args, **kwargs):
self.kind = "MAILSUBMIT"
- super(MailSubmissionForm, self).__init__(request, *args, add_kind_and_user_fields=False, **kwargs)
+ super().__init__(request, *args, add_kind_and_user_fields=False, **kwargs)
def clean(self):
- cleaned_data = super(MailSubmissionForm, self).clean(check_submission_limit=False, check_round_times=False)
+ cleaned_data = super().clean(check_submission_limit=False, check_round_times=False)
decision = is_mailsubmit_allowed(self.request)
if not decision:
@@ -39,11 +39,11 @@ class AcceptMailSubmissionForm(forms.Form):
)
def __init__(self, request, *args, **kwargs):
- super(AcceptMailSubmissionForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.request = request
def clean(self):
- cleaned_data = super(AcceptMailSubmissionForm, self).clean()
+ cleaned_data = super().clean()
if "mailsubmission_id" not in cleaned_data or "submission_hash" not in cleaned_data:
return cleaned_data
diff --git a/oioioi/mailsubmit/models.py b/oioioi/mailsubmit/models.py
index 0f3793569..5d003c611 100644
--- a/oioioi/mailsubmit/models.py
+++ b/oioioi/mailsubmit/models.py
@@ -16,11 +16,7 @@
def make_submission_filename(instance, filename):
if not instance.id:
instance.save()
- return "mailsubmissions/%s/%d%s" % (
- instance.problem_instance.contest.id,
- instance.id,
- os.path.splitext(filename)[1],
- )
+ return f"mailsubmissions/{instance.problem_instance.contest.id!s}/{instance.id}{os.path.splitext(filename)[1]!s}"
class MailSubmission(models.Model):
diff --git a/oioioi/mailsubmit/utils.py b/oioioi/mailsubmit/utils.py
index f51ee806d..c70ba897f 100644
--- a/oioioi/mailsubmit/utils.py
+++ b/oioioi/mailsubmit/utils.py
@@ -66,7 +66,7 @@ def mail_submission_hashes(mailsubmission):
pi = mailsubmission.problem_instance
- msg = "%d-%s-%d-%s" % (mailsubmission.id, pi.contest.id, pi.id, source_hash)
+ msg = f"{mailsubmission.id}-{pi.contest.id}-{pi.id}-{source_hash}"
msg = msg.encode("utf-8")
submission_hash = hmac.new(
diff --git a/oioioi/mailsubmit/views.py b/oioioi/mailsubmit/views.py
index 3ae29ca82..52d367d80 100644
--- a/oioioi/mailsubmit/views.py
+++ b/oioioi/mailsubmit/views.py
@@ -113,7 +113,7 @@ def _generate_pdfdoc(request, mailsubmission):
},
)
- filename = "%s-%s-%s.pdf" % (
+ filename = "{}-{}-{}.pdf".format(
_("confirmation"),
mailsubmission.problem_instance.short_name,
mailsubmission.id,
diff --git a/oioioi/mp/admin.py b/oioioi/mp/admin.py
index d2ca4e34e..47484bf1e 100644
--- a/oioioi/mp/admin.py
+++ b/oioioi/mp/admin.py
@@ -30,7 +30,7 @@ def has_delete_permission(self, request, obj=None):
return request.user.is_superuser
def get_actions(self, request):
- actions = super(MPRegistrationParticipantAdmin, self).get_actions(request)
+ actions = super().get_actions(request)
if "delete_selected" in actions:
del actions["delete_selected"]
return actions
diff --git a/oioioi/mp/controllers.py b/oioioi/mp/controllers.py
index 21a9447a3..0b7f2f3b8 100644
--- a/oioioi/mp/controllers.py
+++ b/oioioi/mp/controllers.py
@@ -89,7 +89,7 @@ def registration_view(self, request):
def mixins_for_admin(self):
from oioioi.participants.admin import TermsAcceptedPhraseAdminMixin
- return super(MPRegistrationController, self).mixins_for_admin() + (TermsAcceptedPhraseAdminMixin,)
+ return super().mixins_for_admin() + (TermsAcceptedPhraseAdminMixin,)
def can_change_terms_accepted_phrase(self, request):
return not MPRegistration.objects.filter(participant__contest=request.contest).exists()
@@ -185,7 +185,7 @@ def can_submit(self, request, problem_instance, check_round_times=True):
contest=problem_instance.contest,
end_date__gte=request.timestamp,
)
- return super(MPContestController, self).can_submit(request, problem_instance, check_round_times) or round_over_contest_running
+ return super().can_submit(request, problem_instance, check_round_times) or round_over_contest_running
class MPRankingController(DefaultRankingController):
diff --git a/oioioi/mp/forms.py b/oioioi/mp/forms.py
index d5085a45b..baf6767b4 100644
--- a/oioioi/mp/forms.py
+++ b/oioioi/mp/forms.py
@@ -38,7 +38,7 @@ class Meta:
exclude = ["participant"]
def __init__(self, *args, **kwargs):
- super(MP2025RegistrationForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
this_year = datetime.date.today().year
self.fields["birth_year"].validators.extend(
diff --git a/oioioi/mp/score.py b/oioioi/mp/score.py
index 508a66db1..a35695bc3 100644
--- a/oioioi/mp/score.py
+++ b/oioioi/mp/score.py
@@ -40,14 +40,14 @@ def __unicode__(self):
return str(self.value)
def __repr__(self):
- return "FloatScore(%s)" % (self.value,)
+ return f"FloatScore({self.value})"
@classmethod
def _from_repr(cls, value):
return cls(float(value))
def _to_repr(self):
- return "%017.2f" % self.value
+ return f"{self.value:017.2f}"
def to_int(self):
return int(self.value)
diff --git a/oioioi/mp/tests.py b/oioioi/mp/tests.py
index d721fd816..f6078c751 100644
--- a/oioioi/mp/tests.py
+++ b/oioioi/mp/tests.py
@@ -33,7 +33,7 @@ def _check_order(self, response, expected):
self.assertTrue(pattern_match)
pos = pattern_match.start()
- self.assertGreater(pos, prev_pos, msg=("Round %s has incorrect position" % (round_name,)))
+ self.assertGreater(pos, prev_pos, msg=(f"Round {round_name} has incorrect position"))
prev_pos = pos
def test_rounds_order(self):
diff --git a/oioioi/newsfeed/models.py b/oioioi/newsfeed/models.py
index 96372c4c6..e1026a6d7 100644
--- a/oioioi/newsfeed/models.py
+++ b/oioioi/newsfeed/models.py
@@ -47,4 +47,4 @@ def save(self, *args, **kwargs):
except NewsLanguageVersion.DoesNotExist:
pass
- return super(NewsLanguageVersion, self).save(*args, **kwargs)
+ return super().save(*args, **kwargs)
diff --git a/oioioi/notifications/processors.py b/oioioi/notifications/processors.py
index 70a06d8c1..b6bdba6ba 100644
--- a/oioioi/notifications/processors.py
+++ b/oioioi/notifications/processors.py
@@ -37,10 +37,10 @@ def generator():
notifications_session_id = get_notifications_session(request.session).uid
return render_to_string(
"notifications/notifications.html",
- dict(
- notif_server_url=settings.NOTIFICATIONS_SERVER_URL,
- notifications_session_id=notifications_session_id,
- ),
+ {
+ "notif_server_url": settings.NOTIFICATIONS_SERVER_URL,
+ "notifications_session_id": notifications_session_id,
+ },
)
return {"extra_navbar_right_notifications": lazy(generator, str)()}
diff --git a/oioioi/oauth/urls.py b/oioioi/oauth/urls.py
index f31bd29e9..a5fc83ffd 100644
--- a/oioioi/oauth/urls.py
+++ b/oioioi/oauth/urls.py
@@ -1,6 +1,6 @@
import oauth2_provider.views as oauth2_views
from django.conf import settings
-from django.urls import include, re_path
+from django.urls import include, path, re_path
from .middleware import (
AdminApplicationDelete,
@@ -34,5 +34,5 @@
]
urlpatterns = [
- re_path(r"^o/", include((oauth2_endpoint_views, "oauth2_provider"), namespace="oauth2_provider")),
+ path("o/", include((oauth2_endpoint_views, "oauth2_provider"), namespace="oauth2_provider")),
]
diff --git a/oioioi/oi/admin.py b/oioioi/oi/admin.py
index 0be003ab1..7705acca2 100644
--- a/oioioi/oi/admin.py
+++ b/oioioi/oi/admin.py
@@ -96,7 +96,7 @@ def get_all_related_objects(modelObj):
# http://stackoverflow.com/questions/3393378/django-merging-objects
related = get_all_related_objects(approved)
- valnames = dict()
+ valnames = {}
for r in related:
valnames.setdefault(r.related_model, []).append(r.field.name)
@@ -145,7 +145,7 @@ class OIRegistrationParticipantAdmin(ParticipantAdmin):
list_filter = ParticipantAdmin.list_filter + ["oi_oiregistration__school__province"]
def get_custom_list_select_related(self):
- return super(OIRegistrationParticipantAdmin, self).get_custom_list_select_related() + [
+ return super().get_custom_list_select_related() + [
"oi_oiregistration",
"oi_oiregistration__school",
]
@@ -179,7 +179,7 @@ def has_delete_permission(self, request, obj=None):
return request.user.is_superuser
def get_actions(self, request):
- actions = super(OIRegistrationParticipantAdmin, self).get_actions(request)
+ actions = super().get_actions(request)
if "delete_selected" in actions:
del actions["delete_selected"]
return actions
diff --git a/oioioi/oi/controllers.py b/oioioi/oi/controllers.py
index 90177f17f..e1d0d49e1 100644
--- a/oioioi/oi/controllers.py
+++ b/oioioi/oi/controllers.py
@@ -107,7 +107,7 @@ def registration_view(self, request):
return TemplateResponse(request, self.registration_template, context)
def get_contest_participant_info_list(self, request, user):
- prev = super(OIRegistrationController, self).get_contest_participant_info_list(request, user)
+ prev = super().get_contest_participant_info_list(request, user)
if can_see_personal_data(request):
sensitive_info = OIRegistration.objects.filter(participant__user=user, participant__contest=request.contest)
@@ -125,7 +125,7 @@ def get_contest_participant_info_list(self, request, user):
def mixins_for_admin(self):
from oioioi.participants.admin import TermsAcceptedPhraseAdminMixin
- return super(OIRegistrationController, self).mixins_for_admin() + (TermsAcceptedPhraseAdminMixin,)
+ return super().mixins_for_admin() + (TermsAcceptedPhraseAdminMixin,)
def can_change_terms_accepted_phrase(self, request):
return not OIRegistration.objects.filter(participant__contest=request.contest).exists()
@@ -145,7 +145,7 @@ class OIContestController(ProgrammingContestController):
)
def fill_evaluation_environ(self, environ, submission):
- super(OIContestController, self).fill_evaluation_environ(environ, submission)
+ super().fill_evaluation_environ(environ, submission)
environ["group_scorer"] = "oioioi.programs.utils.min_group_scorer"
environ["test_scorer"] = "oioioi.programs.utils.threshold_linear_test_scorer"
@@ -160,7 +160,7 @@ def can_submit(self, request, problem_instance, check_round_times=True):
return True
if not is_participant(request):
return False
- return super(OIContestController, self).can_submit(request, problem_instance, check_round_times)
+ return super().can_submit(request, problem_instance, check_round_times)
def can_see_stats(self, request):
return is_contest_admin(request) or is_contest_observer(request)
@@ -194,10 +194,10 @@ def default_can_see_ranking(self, request):
return is_contest_admin(request) or is_contest_observer(request)
def default_contestlogo_url(self):
- return "%(url)soi/logo.png" % {"url": settings.STATIC_URL}
+ return f"{settings.STATIC_URL}oi/logo.png"
def default_contesticons_urls(self):
- return ["%(url)simages/menu/menu-icon-%(i)d.png" % {"url": settings.STATIC_URL, "i": i} for i in range(1, 4)]
+ return [f"{settings.STATIC_URL}images/menu/menu-icon-{i}.png" for i in range(1, 4)]
class OIOnsiteContestController(OIContestController):
@@ -264,7 +264,7 @@ def can_see_test_comments(self, request, submissionreport):
return is_contest_admin(request) or self.results_visible(request, submission)
def reveal_score(self, request, submission):
- super(BOIOnsiteContestController, self).reveal_score(request, submission)
+ super().reveal_score(request, submission)
self.update_user_results(submission.user, submission.problem_instance)
def update_user_result_for_problem(self, result):
@@ -314,7 +314,7 @@ def default_contesticons_urls(self):
return []
def fill_evaluation_environ(self, environ, submission):
- super(BOIOnsiteContestController, self).fill_evaluation_environ(environ, submission)
+ super().fill_evaluation_environ(environ, submission)
environ["test_scorer"] = "oioioi.programs.utils.discrete_test_scorer"
diff --git a/oioioi/oi/forms.py b/oioioi/oi/forms.py
index 0d20020f4..3586a5288 100644
--- a/oioioi/oi/forms.py
+++ b/oioioi/oi/forms.py
@@ -24,14 +24,14 @@ def city_options(all_schools, province):
def school_options(all_schools, province, city):
schools = all_schools.filter(province=province, city=city).order_by("name").only("name", "address")
- schools = [(s.id, "%s (%s)" % (s.name, s.address)) for s in schools]
+ schools = [(s.id, f"{s.name} ({s.address})") for s in schools]
schools.insert(0, ("", _("-- Choose school --")))
return schools
class SchoolSelect(forms.Select):
def __init__(self, is_contest_with_coordinator=False, is_coordinator=False, *args, **kwargs):
- super(SchoolSelect, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.is_contest_with_coordinator = is_contest_with_coordinator
self.is_coordinator = is_coordinator
@@ -85,7 +85,7 @@ class Media:
js = ("oi/reg.js",)
def __init__(self, *args, **kwargs):
- super(OIRegistrationForm, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
this_year = datetime.date.today().year
years = list(reversed(range(this_year - 100, this_year + 1)))
diff --git a/oioioi/oi/management/commands/import_schools.py b/oioioi/oi/management/commands/import_schools.py
index dfba61bfe..41ab60ceb 100644
--- a/oioioi/oi/management/commands/import_schools.py
+++ b/oioioi/oi/management/commands/import_schools.py
@@ -350,7 +350,7 @@ def handle(self, *args, **kwargs):
DRY_RUN = dry_run
first_import = kwargs["first_import"]
backup_path = kwargs["backup_filename"]
- VERBOSITY = kwargs["verbosity"]
+ kwargs["verbosity"]
prepare_dir(BASE_DIR)
diff --git a/oioioi/oi/management/commands/oi_generate_dnsauth.py b/oioioi/oi/management/commands/oi_generate_dnsauth.py
index 3ecbb48ab..372c1fdbb 100644
--- a/oioioi/oi/management/commands/oi_generate_dnsauth.py
+++ b/oioioi/oi/management/commands/oi_generate_dnsauth.py
@@ -11,7 +11,7 @@
def username_to_dns_name(username):
hostname = username_to_hostname(username)
- return "oi-%s.dasie.mimuw.edu.pl" % (hostname,)
+ return f"oi-{hostname}.dasie.mimuw.edu.pl"
class Command(BaseCommand):
diff --git a/oioioi/oi/urls.py b/oioioi/oi/urls.py
index 162741e05..bd51aeaf0 100644
--- a/oioioi/oi/urls.py
+++ b/oioioi/oi/urls.py
@@ -1,4 +1,4 @@
-from django.urls import path, re_path
+from django.urls import path
from oioioi.oi import views
@@ -14,14 +14,14 @@
views.choose_school_view,
name="choose_school",
),
- re_path(
- r"^oi/consent/(?P[0-9]+)/$",
+ path(
+ "oi/consent//",
views.consent_view,
name="view_consent",
),
]
contest_patterns = [
- re_path(r"^register/oicities/$", views.cities_view),
- re_path(r"^register/oischools/$", views.schools_view),
+ path("register/oicities/", views.cities_view),
+ path("register/oischools/", views.schools_view),
]
diff --git a/oioioi/oireports/forms.py b/oioioi/oireports/forms.py
index 9d0f2b469..9339a9559 100644
--- a/oioioi/oireports/forms.py
+++ b/oioioi/oireports/forms.py
@@ -70,7 +70,7 @@ def _testgroups(request):
class OIReportCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
def render(self, *args, **kwargs):
- output = super(OIReportCheckboxSelectMultiple, self).render(*args, **kwargs)
+ output = super().render(*args, **kwargs)
return mark_safe(output.replace("", '').replace("