+ return (
+ format_html(
+ u'''
''',
- format_html_join(
- u'\n',
- u'''
+ format_html_join(
+ u'\n',
+ u''' |

{}
| ''',
- ((p.get_absolute_url(), p.caption) for p in pictures),
- ),
- ) if pictures else u''
+ ((p.get_absolute_url(), p.caption) for p in pictures),
+ ),
+ )
+ if pictures
+ else u''
+ )
def render_question(self, request, question):
pictures = question.quizquestionpicture_set.all()
@@ -173,7 +177,6 @@ def create_submission(self, request, problem_instance, form_data, **kwargs):
return submission
def _submit_answers(self, selected_answers, question, submission):
-
if question.is_text_input:
sub = QuizSubmissionTextAnswer.objects.create(
quiz_submission=submission,
diff --git a/oioioi/quizzes/problem_sources.py b/oioioi/quizzes/problem_sources.py
index 027eca268..b469397c0 100644
--- a/oioioi/quizzes/problem_sources.py
+++ b/oioioi/quizzes/problem_sources.py
@@ -3,6 +3,7 @@
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
+
from oioioi.base.utils import generate_key
from oioioi.base.utils.redirect import safe_redirect
from oioioi.contests.models import ProblemInstance
diff --git a/oioioi/quizzes/tests.py b/oioioi/quizzes/tests.py
index b5d6038dd..82ef0645f 100644
--- a/oioioi/quizzes/tests.py
+++ b/oioioi/quizzes/tests.py
@@ -443,7 +443,7 @@ def test_quiz_tab_visibility(self):
url = reverse('problem_site', kwargs={'site_key': quiz.problemsite.url_key})
response = self.client.get(url, follow=True)
- for (allowed_tab, disabled_tab) in zip(
+ for allowed_tab, disabled_tab in zip(
self.allowed_quiz_tabs, self.disabled_quiz_tabs
):
self.assertContains(response, allowed_tab)
diff --git a/oioioi/rankings/models.py b/oioioi/rankings/models.py
index 663a6526b..fa9281a8b 100644
--- a/oioioi/rankings/models.py
+++ b/oioioi/rankings/models.py
@@ -176,9 +176,7 @@ def save_recalc_results(recalc, date_before, date_after, serialized, pages_list)
r = Ranking.objects.filter(recalc_in_progress=recalc).select_for_update().get()
except Ranking.DoesNotExist:
return
- r.serialized_data = pickle.dumps(
- serialized
- )
+ r.serialized_data = pickle.dumps(serialized)
save_pages(r, pages_list)
r.last_recalculation_date = date_before
r.last_recalculation_duration = date_after - date_before
diff --git a/oioioi/rankings/tests.py b/oioioi/rankings/tests.py
index fb4923c4b..c1e3500e4 100644
--- a/oioioi/rankings/tests.py
+++ b/oioioi/rankings/tests.py
@@ -307,7 +307,7 @@ def test_invalidate_view(self):
self.assertTrue(ranking.is_up_to_date())
recalc = choose_for_recalculation()
self.assertIsNone(recalc)
- response = self.client.post(url, key='key')
+ self.client.post(url, key='key')
ranking.refresh_from_db()
self.assertFalse(ranking.is_up_to_date())
recalc = choose_for_recalculation()
diff --git a/oioioi/scoresreveal/admin.py b/oioioi/scoresreveal/admin.py
index 9deaa78d1..c2c2b7465 100644
--- a/oioioi/scoresreveal/admin.py
+++ b/oioioi/scoresreveal/admin.py
@@ -2,10 +2,8 @@
from django.utils.translation import gettext_lazy as _
from oioioi.base import admin
-from oioioi.base.admin import NO_CATEGORY
from oioioi.base.forms import AlwaysChangedModelForm
from oioioi.contests.admin import ProblemInstanceAdmin, SubmissionAdmin
-from oioioi.contests.utils import is_contest_admin
from oioioi.scoresreveal.models import ScoreRevealConfig
from oioioi.scoresreveal.utils import is_revealed
diff --git a/oioioi/scoresreveal/controllers.py b/oioioi/scoresreveal/controllers.py
index f7c9d333e..7dccd6bb2 100644
--- a/oioioi/scoresreveal/controllers.py
+++ b/oioioi/scoresreveal/controllers.py
@@ -170,9 +170,7 @@ def render_submission_footer(self, request, submission):
'scoresreveal/submission-footer.html',
request=request,
context={
- 'submission': submission_template_context(
- request, submission
- ),
+ 'submission': submission_template_context(request, submission),
'scores_reveals': scores_reveals,
'scores_reveals_limit': scores_reveals_limit,
'scores_reveals_disable_time': scores_reveals_disable_time,
diff --git a/oioioi/scoresreveal/tests.py b/oioioi/scoresreveal/tests.py
index aef2881f2..06f2997f9 100644
--- a/oioioi/scoresreveal/tests.py
+++ b/oioioi/scoresreveal/tests.py
@@ -13,8 +13,8 @@
RoundTimeExtension,
Submission,
)
-from oioioi.scoresreveal.models import ScoreRevealConfig
from oioioi.quizzes.models import QuizSubmission
+from oioioi.scoresreveal.models import ScoreRevealConfig
class TestScoresManualReveal(TestCase):
diff --git a/oioioi/selenium_settings.py b/oioioi/selenium_settings.py
index c4c583efb..874b3b6c7 100644
--- a/oioioi/selenium_settings.py
+++ b/oioioi/selenium_settings.py
@@ -1,4 +1,4 @@
-# pylint: disable=wildcard-import
+# ruff: noqa
from settings import *
# Enable optional modules.
diff --git a/oioioi/similarsubmits/tests.py b/oioioi/similarsubmits/tests.py
index 8db741e32..899450d32 100644
--- a/oioioi/similarsubmits/tests.py
+++ b/oioioi/similarsubmits/tests.py
@@ -7,6 +7,10 @@
from oioioi.similarsubmits.models import SubmissionsSimilarityGroup
+def none_returner():
+ return None
+
+
class TestSimilarSubmitViews(TestCase):
fixtures = [
'test_users',
@@ -48,7 +52,7 @@ def test_bulk_add_similar_submits_view(self):
def test_invalid_bulk_form(self):
invalid_bulks = ['1:user:test.cpp', '1:usertestcpp 1:user:test.cpp']
- mock_request = lambda: None
+ mock_request = none_returner
mock_request.contest = None
for bulk in invalid_bulks:
form_data = {'similar_groups': bulk}
diff --git a/oioioi/similarsubmits/urls.py b/oioioi/similarsubmits/urls.py
index 1f55cb59f..cef2404cf 100644
--- a/oioioi/similarsubmits/urls.py
+++ b/oioioi/similarsubmits/urls.py
@@ -13,5 +13,7 @@
views.mark_not_guilty_view,
name='mark_not_guilty',
),
- re_path(r'^bulk_add/$', views.bulk_add_similarities_view, name='bulk_add_similarities'),
+ re_path(
+ r'^bulk_add/$', views.bulk_add_similarities_view, name='bulk_add_similarities'
+ ),
]
diff --git a/oioioi/simpleui/forms.py b/oioioi/simpleui/forms.py
index 6a1fd3ac2..b28d23a03 100644
--- a/oioioi/simpleui/forms.py
+++ b/oioioi/simpleui/forms.py
@@ -1,6 +1,7 @@
from django import forms
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
+
from oioioi.base.utils import make_html_link
from oioioi.contests.models import ProblemInstance, Round
from oioioi.programs.models import Test
diff --git a/oioioi/simpleui/urls.py b/oioioi/simpleui/urls.py
index 8a884208f..edb9ade28 100644
--- a/oioioi/simpleui/urls.py
+++ b/oioioi/simpleui/urls.py
@@ -1,10 +1,13 @@
from django.urls import re_path
+
from oioioi.simpleui import views
app_name = 'simpleui'
noncontest_patterns = [
- re_path(r'^user-dashboard/$', views.user_dashboard_view, name='simpleui_user_dashboard')
+ re_path(
+ r'^user-dashboard/$', views.user_dashboard_view, name='simpleui_user_dashboard'
+ )
]
contest_patterns = [
diff --git a/oioioi/sinolpack/package.py b/oioioi/sinolpack/package.py
index 8805d8675..aa2322428 100644
--- a/oioioi/sinolpack/package.py
+++ b/oioioi/sinolpack/package.py
@@ -11,13 +11,13 @@
import chardet
import six
-
from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.core.files import File
from django.core.validators import slug_re
from django.utils.translation import gettext as _
+
from oioioi.base.utils import generate_key, naturalsort_key
from oioioi.base.utils.archive import Archive
from oioioi.base.utils.execute import ExecuteError, execute
@@ -251,7 +251,7 @@ def _override_compiler(self, prefix, lang, compilation_job):
'cpp': 'C++',
'pas': 'Pascal',
'java': 'Java',
- 'py': 'Python'
+ 'py': 'Python',
}
if lang in name_map and lang in settings.OVERRIDE_COMPILER_LANGS:
@@ -271,7 +271,7 @@ def _run_compilation_job(self, ext, ft_source_name, out_name):
prefix = 'system'
compilation_job['compiler'] = prefix + '-' + lang
self._override_compiler(prefix, lang, compilation_job)
-
+
if not self.use_make and self.prog_archive:
compilation_job['additional_archive'] = self.prog_archive
add_extra_files(
@@ -320,7 +320,7 @@ def _make_ins(self, re_string):
renv = run_sioworkers_job(env)
if renv['return_code'] != 0:
- raise ProblemPackageError(_("Ingen failed: %r") % renv)
+ raise ProblemPackageError(_("Ingen failed: %r") % renv)
get_client().delete_file(env['compiled_file'])
return renv['collected_files']
@@ -574,7 +574,7 @@ def _process_statements(self):
# pylint: disable=maybe-no-member
self.problem.statements.all().delete()
- lang_prefs = [''] + ['-' + l[0] for l in settings.STATEMENT_LANGUAGES]
+ lang_prefs = [''] + ['-' + lang[0] for lang in settings.STATEMENT_LANGUAGES]
if self.use_make:
self._compile_latex_docs(docdir)
@@ -618,7 +618,6 @@ def _force_index_encoding(self, htmlzipfile):
with zipfile.ZipFile(htmlzipfile, 'r') as archive, archive.open(
'index.html'
) as index:
-
data = index.read()
# First, we check if index.html is utf-8 encoded.
# If it is - nothing to do.
diff --git a/oioioi/sinolpack/tests.py b/oioioi/sinolpack/tests.py
index c45ab1373..eb35f408b 100644
--- a/oioioi/sinolpack/tests.py
+++ b/oioioi/sinolpack/tests.py
@@ -1,11 +1,11 @@
# coding: utf-8
import os.path
+import urllib.parse
import zipfile
+from io import BytesIO
import pytest
-import urllib.parse
-from io import BytesIO
from django.conf import settings
from django.core.files import File
from django.core.management import call_command
@@ -15,6 +15,7 @@
from django.urls import reverse
from django.utils.html import escape
from django.utils.module_loading import import_string
+
from oioioi.base.tests import TestCase, needs_linux
from oioioi.contests.current_contest import ContestMode
from oioioi.contests.models import (
@@ -67,6 +68,7 @@ def no_makefiles(fn):
# both_configurations will be run twice. Once in safe and once in unsafe unpack
# mode.
+
# Unfortunately, you won't be able run such a decorated method as a single
# test, that is:
# ./test.sh oioioi.sinolpack.tests:TestSinolPackage.test_huge_unpack_update
diff --git a/oioioi/sioworkers/backends.py b/oioioi/sioworkers/backends.py
index 1dba4f49a..e040faab4 100644
--- a/oioioi/sioworkers/backends.py
+++ b/oioioi/sioworkers/backends.py
@@ -5,11 +5,11 @@
# this assumption, even a single call to LocalClient.build would break that
# code.
from threading import Lock
+from xmlrpc.client import Server
import sio.workers.runner
from django.conf import settings
from django.db import transaction
-from xmlrpc.client import Server
from oioioi.evalmgr.tasks import delay_environ
diff --git a/oioioi/sioworkers/management/commands/download_sandboxes.py b/oioioi/sioworkers/management/commands/download_sandboxes.py
index d061d1f8b..f3d68ec18 100644
--- a/oioioi/sioworkers/management/commands/download_sandboxes.py
+++ b/oioioi/sioworkers/management/commands/download_sandboxes.py
@@ -2,10 +2,10 @@
import os
import os.path
-
import urllib.error
import urllib.parse
import urllib.request
+
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
@@ -95,9 +95,7 @@ def handle(self, *args, **options):
print("--- Downloading Manifest ...", file=self.stdout)
try:
manifest_url = options['manifest_url']
- manifest = (
- urllib.request.urlopen(manifest_url).read().decode('utf-8')
- )
+ manifest = urllib.request.urlopen(manifest_url).read().decode('utf-8')
manifest = manifest.strip().splitlines()
except Exception as e:
raise CommandError("Error downloading manifest: %s" % (e,))
@@ -105,9 +103,7 @@ def handle(self, *args, **options):
print("--- Looking for license ...", file=self.stdout)
try:
license_url = urllib.parse.urljoin(manifest_url, 'LICENSE')
- license = (
- urllib.request.urlopen(license_url).read().decode('utf-8')
- )
+ license = urllib.request.urlopen(license_url).read().decode('utf-8')
if not options['license_agreement']:
self.display_license(license)
except urllib.error.HTTPError as e:
@@ -153,7 +149,8 @@ def handle(self, *args, **options):
quiet_flag = ['-nv'] if options['quiet'] else []
execute(
- [options['wget'], '-N', '--no-check-certificate', '-i', '-'] + quiet_flag,
+ [options['wget'], '-N', '--no-check-certificate', '-i', '-']
+ + quiet_flag,
stdin='\n'.join(urls).encode('utf-8'),
capture_output=False,
cwd=download_dir,
diff --git a/oioioi/sioworkers/management/commands/worker.py b/oioioi/sioworkers/management/commands/worker.py
index c4630d44d..43c4c690d 100644
--- a/oioioi/sioworkers/management/commands/worker.py
+++ b/oioioi/sioworkers/management/commands/worker.py
@@ -1,8 +1,8 @@
import json
+from xmlrpc.client import Server
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
-from xmlrpc.client import Server
class Command(BaseCommand):
@@ -19,9 +19,9 @@ def add_arguments(self, parser):
parser.add_argument('args', type=str, nargs='*', help='Command\' arguments')
def cmd_list(self, **kwargs):
- l = self.server.get_workers()
- if l:
- self.stdout.write('\n'.join(map(str, l)))
+ workers = self.server.get_workers()
+ if workers:
+ self.stdout.write('\n'.join(map(str, workers)))
else:
self.stdout.write('No workers connected.\n')
diff --git a/oioioi/statistics/plotfunctions.py b/oioioi/statistics/plotfunctions.py
index cabe00a19..d2966c8a8 100644
--- a/oioioi/statistics/plotfunctions.py
+++ b/oioioi/statistics/plotfunctions.py
@@ -212,7 +212,7 @@ def test_scores(request, problem):
# Why .order_by()? Just in case. More in the following link:
# https://docs.djangoproject.com/en/dev/topics/db/
# aggregation/#interaction-with-default-ordering-or-order-by
- # Testreports for deleted tests remain in the database,
+ # Testreports for deleted tests remain in the database,
# we can't show them here.
agg = (
TestReport.objects.filter(
diff --git a/oioioi/statistics/plottypes.py b/oioioi/statistics/plottypes.py
index 65bff871a..fc1bea941 100644
--- a/oioioi/statistics/plottypes.py
+++ b/oioioi/statistics/plottypes.py
@@ -88,7 +88,7 @@ def highcharts_options(self, data):
options['%sAxis' % a][b] = data[key]
# Setting axes titles
if 'titles' in data:
- for (key, title) in data['titles'].items():
+ for key, title in data['titles'].items():
options.setdefault(key, {}).update({'title': {'text': title}})
return options
diff --git a/oioioi/statistics/views.py b/oioioi/statistics/views.py
index 584738aa8..9598b943e 100644
--- a/oioioi/statistics/views.py
+++ b/oioioi/statistics/views.py
@@ -23,7 +23,7 @@ def links(request):
links_list = []
plot_groups = controller.statistics_available_plot_groups(request)
- for (category, object_name, description) in plot_groups:
+ for category, object_name, description in plot_groups:
category_name, link = statistics_categories[category]
links_list.append(
{
@@ -62,7 +62,7 @@ def statistics_view(
controller = request.contest.controller
category_key = ''
- for (key, desc) in statistics_categories:
+ for key, desc in statistics_categories:
if desc[1] == category:
category_key = key
category = category_key
@@ -79,7 +79,7 @@ def statistics_view(
else:
raise Http404
- if not (category, object_name) in set(
+ if (category, object_name) not in set(
(c, o) for (c, o, d) in controller.statistics_available_plot_groups(request)
):
raise PermissionDenied(_("You have no access to those charts"))
diff --git a/oioioi/submitservice/static/submitservice/submit.py b/oioioi/submitservice/static/submitservice/submit.py
index 63374275e..863dc0914 100755
--- a/oioioi/submitservice/static/submitservice/submit.py
+++ b/oioioi/submitservice/static/submitservice/submit.py
@@ -11,13 +11,12 @@
import random
import string
import sys
+import urllib.parse
+import urllib.request
import webbrowser
from argparse import ArgumentParser
from os.path import expanduser, splitext
-import urllib.parse
-import urllib.request
-
class MultiPartForm(object):
"""Accumulate the data to be used when posting a form."""
@@ -204,9 +203,7 @@ def submit(filename, task_name, token, contest_url, open_webbrowser):
form.add_field('task', task_name)
form.add_file('file', solution_file.name, filehandle=solution_file)
body = str(form)
- request = urllib.request.Request(
- '%ssubmitservice/submit/' % contest_url
- )
+ request = urllib.request.Request('%ssubmitservice/submit/' % contest_url)
request.add_header('Content-Type', form.get_content_type())
request.add_header('Content-Length', str(len(body)))
request.add_data(body)
diff --git a/oioioi/suspendjudge/handlers.py b/oioioi/suspendjudge/handlers.py
index ae8cbbed2..4ba26b772 100644
--- a/oioioi/suspendjudge/handlers.py
+++ b/oioioi/suspendjudge/handlers.py
@@ -1,6 +1,6 @@
-from celery.exceptions import Ignore
from django.db import transaction
+from celery.exceptions import Ignore
from oioioi.contests.handlers import _get_submission_or_skip
from oioioi.evalmgr.utils import mark_job_state
from oioioi.programs.models import ModelProgramSubmission
diff --git a/oioioi/suspendjudge/models.py b/oioioi/suspendjudge/models.py
index d6686c85f..6d8aab569 100644
--- a/oioioi/suspendjudge/models.py
+++ b/oioioi/suspendjudge/models.py
@@ -1,7 +1,6 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
-from oioioi.base.utils.deps import check_django_app_dependencies
from oioioi.contests.models import ProblemInstance
from oioioi.evalmgr.models import job_states
diff --git a/oioioi/suspendjudge/tests.py b/oioioi/suspendjudge/tests.py
index 579313596..558e9acba 100644
--- a/oioioi/suspendjudge/tests.py
+++ b/oioioi/suspendjudge/tests.py
@@ -1,6 +1,6 @@
-from celery.exceptions import Ignore
from django.urls import reverse
+from celery.exceptions import Ignore
from oioioi.base.tests import TestCase
from oioioi.contests.models import Contest, ProblemInstance, Submission
from oioioi.evalmgr.tasks import create_environ
diff --git a/oioioi/szkopul/settings.py b/oioioi/szkopul/settings.py
index e51943f65..c2196514b 100644
--- a/oioioi/szkopul/settings.py
+++ b/oioioi/szkopul/settings.py
@@ -1,9 +1,18 @@
# -*- coding: utf-8 -*-
from datetime import datetime
+
import pytz
from django.utils.safestring import mark_safe
-from oioioi.default_settings import *
+
from oioioi.contests.current_contest import ContestMode
+from oioioi.default_settings import (
+ AUTHENTICATION_BACKENDS,
+ CACHED_TEMPLATE_LOADERS,
+ INSTALLED_APPS,
+ PROBLEM_SOURCES,
+ TEMPLATES,
+ UNCACHED_TEMPLATE_LOADERS,
+)
# This should match INSTALLATION_CONFIG_VERSION in
# "oioioi/default_settings.py".
@@ -57,9 +66,7 @@
# Email addresses to send communication from users (for example requests for
# teacher accounts).
-MANAGERS = (
- ('Szkopul Admin', 'sio2@sio2project.mimuw.edu.pl'),
-)
+MANAGERS = (('Szkopul Admin', 'sio2@sio2project.mimuw.edu.pl'),)
# Registration checkbox descriptions
@@ -70,11 +77,19 @@
" zgodę na przetwarzanie moich ww. danych osobowych"
" oraz oświadczam,"
" że zapoznałam/zapoznałem się z "
- "
klauzulą informacyjną")
+ "
klauzulą informacyjną"
+)
# See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts
-ALLOWED_HOSTS = ['szkopul.edu.pl', 'szk.oioioi.edu.pl',
- 'snag.dasie.mimuw.edu.pl', 'snag', 'szkopul', 'szkopul2', 'localhost']
+ALLOWED_HOSTS = [
+ 'szkopul.edu.pl',
+ 'szk.oioioi.edu.pl',
+ 'snag.dasie.mimuw.edu.pl',
+ 'snag',
+ 'szkopul',
+ 'szkopul2',
+ 'localhost',
+]
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
@@ -175,21 +190,13 @@
RUN_SIOWORKERSD = False
SUBMITTABLE_LANGUAGES = {
- 'C': {
- 'display_name': 'C'
- },
- 'C++': {
- 'display_name': 'C++'
- },
- 'Pascal': {
- 'display_name': 'Pascal'
- },
+ 'C': {'display_name': 'C'},
+ 'C++': {'display_name': 'C++'},
+ 'Pascal': {'display_name': 'Pascal'},
# 'Java': {
# 'display_name': 'Java'
# },
- 'Python': {
- 'display_name': 'Python'
- },
+ 'Python': {'display_name': 'Python'},
}
SUBMITTABLE_EXTENSIONS = {
@@ -204,25 +211,21 @@
# By default that means ones defined here:
# https://github.com/sio2project/sioworkers/blob/master/setup.py#L71
AVAILABLE_COMPILERS = {
- 'C': {
- 'gcc4_8_2_c99': {'display_name': 'gcc:4.8.2 std=gnu99'}
- },
+ 'C': {'gcc4_8_2_c99': {'display_name': 'gcc:4.8.2 std=gnu99'}},
'C++': {
'g++4_8_2_cpp11': {'display_name': 'g++:4.8.2 std=c++11'},
'g++8_3_cpp17': {'display_name': 'g++:8.3 std=c++17'},
'g++8_3_cpp17_amd64': {'display_name': 'g++:8.3 std=c++17 x64'},
- 'g++10_2_cpp17_amd64': {'display_name': 'g++:10.2 std=c++17 x64'}
- },
- 'Pascal': {
- 'fpc2_6_2': {'display_name': 'fpc:2.6.2'}
+ 'g++10_2_cpp17_amd64': {'display_name': 'g++:10.2 std=c++17 x64'},
},
+ 'Pascal': {'fpc2_6_2': {'display_name': 'fpc:2.6.2'}},
# 'Java': {
# 'java1_8': {'display_name': 'java:1.8'}
# },
'Python': {
'python_3_4_numpy': {'display_name': 'python:3.4 + numpy'},
'python_3_7_numpy': {'display_name': 'python:3.7 + numpy'},
- 'python_3_9_numpy': {'display_name': 'python:3.9 + numpy'}
+ 'python_3_9_numpy': {'display_name': 'python:3.9 + numpy'},
},
}
@@ -362,7 +365,7 @@
'oioioi.problemsharing',
'oioioi.usergroups',
'oioioi.usercontests',
- 'oioioi.plagiarism'
+ 'oioioi.plagiarism',
) + INSTALLED_APPS
PROBLEM_TAGS_VISIBLE = True
@@ -385,13 +388,21 @@
]
# VERY STUPID WORKAROUND FOR SZKOPUL-FK
-if 'oioioi.problems.processors.dangling_problems_processor' in TEMPLATES[0]['OPTIONS']['context_processors']:
+if (
+ 'oioioi.problems.processors.dangling_problems_processor'
+ in TEMPLATES[0]['OPTIONS']['context_processors']
+):
TEMPLATES[0]['OPTIONS']['context_processors'].remove(
- 'oioioi.problems.processors.dangling_problems_processor')
+ 'oioioi.problems.processors.dangling_problems_processor'
+ )
# AND FOR SZKOPUL-FJ
-if 'oioioi.problems.processors.problems_need_rejudge_processor' in TEMPLATES[0]['OPTIONS']['context_processors']:
+if (
+ 'oioioi.problems.processors.problems_need_rejudge_processor'
+ in TEMPLATES[0]['OPTIONS']['context_processors']
+):
TEMPLATES[0]['OPTIONS']['context_processors'].remove(
- 'oioioi.problems.processors.problems_need_rejudge_processor')
+ 'oioioi.problems.processors.problems_need_rejudge_processor'
+ )
AUTHENTICATION_BACKENDS += (
'oioioi.teachers.auth.TeacherAuthBackend',
@@ -459,9 +470,7 @@
'handlers': ['console'],
},
'filters': {
- 'require_debug_false': {
- '()': 'django.utils.log.RequireDebugFalse'
- },
+ 'require_debug_false': {'()': 'django.utils.log.RequireDebugFalse'},
},
'formatters': {
'date_and_level': {
@@ -483,17 +492,17 @@
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
- 'class': 'django.utils.log.AdminEmailHandler'
+ 'class': 'django.utils.log.AdminEmailHandler',
},
'audit': {
'level': 'INFO',
'class': 'logging.FileHandler',
'formatter': 'date_and_level',
- 'filename': '/sio2/deployment/logs/audit.log'
+ 'filename': '/sio2/deployment/logs/audit.log',
},
'emit_notification': {
'level': 'DEBUG',
- 'class': 'oioioi.base.notification.NotificationHandler'
+ 'class': 'oioioi.base.notification.NotificationHandler',
},
},
'loggers': {
@@ -510,7 +519,7 @@
'django.security': {
'handlers': ['console'],
'level': 'ERROR',
- 'propagate': False
+ 'propagate': False,
},
'oioioi': {
'handlers': ['console', 'emit_notification'],
@@ -532,7 +541,7 @@
'level': 'INFO',
'propagate': False,
},
- }
+ },
}
# If set to True, usercontests will become read-only: it will be impossible to
diff --git a/oioioi/szkopul/tests.py b/oioioi/szkopul/tests.py
index 3186492f1..47af01633 100644
--- a/oioioi/szkopul/tests.py
+++ b/oioioi/szkopul/tests.py
@@ -14,7 +14,6 @@
class TestMainPageView(TestCase):
-
fixtures = [
'test_users',
'test_contest',
diff --git a/oioioi/szkopul/views.py b/oioioi/szkopul/views.py
index fe1c3cf17..091abcd48 100644
--- a/oioioi/szkopul/views.py
+++ b/oioioi/szkopul/views.py
@@ -1,8 +1,8 @@
-import django
from django.conf import settings
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
+
from oioioi.base.main_page import register_main_page_view
from oioioi.contests.controllers import submission_template_context
from oioioi.contests.models import Submission
diff --git a/oioioi/teachers/admin.py b/oioioi/teachers/admin.py
index 3a405ab6e..e061cdc12 100644
--- a/oioioi/teachers/admin.py
+++ b/oioioi/teachers/admin.py
@@ -11,15 +11,30 @@
from oioioi.base.menu import personal_menu_registry
from oioioi.base.permissions import is_superuser
from oioioi.contests.admin import ContestAdmin
-from oioioi.teachers.forms import TeacherContestForm, AddTeacherForm
+from oioioi.teachers.forms import AddTeacherForm, TeacherContestForm
from oioioi.teachers.models import ContestTeacher, RegistrationConfig, Teacher
class TeacherAdmin(admin.ModelAdmin):
- list_display = ['teacher_login', 'teacher_email', 'teacher_first_name', 'teacher_last_name', 'school', 'is_active', 'join_date']
- list_editable = ['is_active']
-
- search_fields = ['school', 'user__username', 'user__first_name', 'user__last_name', 'user__email', 'join_date']
+ list_display = [
+ 'teacher_login',
+ 'teacher_email',
+ 'teacher_first_name',
+ 'teacher_last_name',
+ 'school',
+ 'is_active',
+ 'join_date',
+ ]
+ list_editable = ['is_active']
+
+ search_fields = [
+ 'school',
+ 'user__username',
+ 'user__first_name',
+ 'user__last_name',
+ 'user__email',
+ 'join_date',
+ ]
form = AddTeacherForm
diff --git a/oioioi/teachers/forms.py b/oioioi/teachers/forms.py
index 5382eefb0..e1433ad48 100644
--- a/oioioi/teachers/forms.py
+++ b/oioioi/teachers/forms.py
@@ -3,10 +3,9 @@
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
+from oioioi.base.utils.user_selection import UserSelectionField
from oioioi.contests.forms import SimpleContestForm
from oioioi.teachers.models import Teacher
-from oioioi.base.utils.user_selection import UserSelectionField
-
class TeacherContestForm(SimpleContestForm):
diff --git a/oioioi/teachers/models.py b/oioioi/teachers/models.py
index 232c4d4e9..262cf63b0 100644
--- a/oioioi/teachers/models.py
+++ b/oioioi/teachers/models.py
@@ -2,7 +2,6 @@
from django.contrib.auth.models import User
from django.core.exceptions import ImproperlyConfigured
from django.db import models
-
from django.utils.translation import gettext_lazy as _
from oioioi.base.utils import generate_key
@@ -17,7 +16,6 @@
)
-
class Teacher(models.Model):
user = models.OneToOneField(
User, primary_key=True, verbose_name=_("user"), on_delete=models.CASCADE
@@ -33,7 +31,6 @@ def __str__(self):
return str(self.user)
-
class ContestTeacher(models.Model):
contest = models.ForeignKey(Contest, on_delete=models.CASCADE)
teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE)
diff --git a/oioioi/teachers/views.py b/oioioi/teachers/views.py
index cc45a9c62..758182de9 100644
--- a/oioioi/teachers/views.py
+++ b/oioioi/teachers/views.py
@@ -4,7 +4,6 @@
from django.core.exceptions import PermissionDenied, SuspiciousOperation
from django.core.mail import EmailMessage
from django.http import Http404
-from django.http import JsonResponse
from django.shortcuts import get_object_or_404, redirect
from django.template.loader import render_to_string
from django.template.response import TemplateResponse
@@ -52,11 +51,13 @@ def is_teacher(request):
def is_not_teacher(request):
return not_anonymous(request) and not request.user.has_perm('teachers.teacher')
+
@enforce_condition(is_superuser)
def get_non_teacher_names(request):
queryset = User.objects.filter(teacher__isnull=True)
return get_user_hints_view(request, 'substr', queryset)
+
def send_request_email(request, teacher, message):
context = {
'teacher': teacher,
diff --git a/oioioi/test_settings.py b/oioioi/test_settings.py
index 03b7b5008..4c0a74f51 100644
--- a/oioioi/test_settings.py
+++ b/oioioi/test_settings.py
@@ -1,4 +1,4 @@
-# pylint: disable=wildcard-import
+# ruff: noqa
from oioioi.default_settings import *
TIME_ZONE = 'UTC'
diff --git a/oioioi/testrun/controllers.py b/oioioi/testrun/controllers.py
index be4ba4346..bc75971bc 100644
--- a/oioioi/testrun/controllers.py
+++ b/oioioi/testrun/controllers.py
@@ -14,7 +14,7 @@
from oioioi.base.utils import is_ajax
from oioioi.base.utils.archive import Archive
from oioioi.contests.controllers import submission_template_context
-from oioioi.contests.models import ScoreReport, Submission, SubmissionReport
+from oioioi.contests.models import ScoreReport, SubmissionReport
from oioioi.evalmgr.tasks import extend_after_placeholder
from oioioi.problems.utils import can_admin_problem
from oioioi.programs.controllers import (
@@ -127,10 +127,7 @@ def adjust_submission_form(self, request, form, problem_instance):
# Otherwise one could bypass checks and limits for example by
# uploading a zipfile without the '.zip' extension.
def validate_file_size(file):
- if (
- is_zipfile(file)
- and file.size > self.get_testrun_zipped_input_limit()
- ):
+ if is_zipfile(file) and file.size > self.get_testrun_zipped_input_limit():
raise ValidationError(_("Zipped input file size limit exceeded."))
elif file.size > self.get_testrun_input_limit():
raise ValidationError(_("Input file size limit exceeded."))
diff --git a/oioioi/testrun/models.py b/oioioi/testrun/models.py
index cf9d30623..033cde5ae 100644
--- a/oioioi/testrun/models.py
+++ b/oioioi/testrun/models.py
@@ -10,7 +10,7 @@
submission_statuses,
)
from oioioi.filetracker.fields import FileField
-from oioioi.problems.models import Problem, ProblemInstance
+from oioioi.problems.models import ProblemInstance
from oioioi.programs.models import ProgramSubmission
submission_statuses.register('TESTRUN_OK', _("No error"))
diff --git a/oioioi/testspackages/views.py b/oioioi/testspackages/views.py
index 4708c1c48..37ce4c6b1 100644
--- a/oioioi/testspackages/views.py
+++ b/oioioi/testspackages/views.py
@@ -1,9 +1,9 @@
import os
from django.core.exceptions import PermissionDenied
+from django.http import Http404
from django.shortcuts import get_object_or_404
from django.urls import reverse
-from django.http import Http404
from oioioi.base.permissions import enforce_condition, not_anonymous
from oioioi.base.utils import request_cached
@@ -11,13 +11,13 @@
attachment_registry,
attachment_registry_problemset,
)
+from oioioi.contests.models import ProblemInstance
from oioioi.contests.utils import (
can_enter_contest,
contest_exists,
is_contest_admin,
visible_problem_instances,
)
-from oioioi.contests.models import ProblemInstance
from oioioi.filetracker.utils import stream_file
from oioioi.problems.utils import can_admin_problem
from oioioi.testspackages.models import TestsPackage
diff --git a/oioioi/timeline/views.py b/oioioi/timeline/views.py
index 61cab5799..9e769648d 100644
--- a/oioioi/timeline/views.py
+++ b/oioioi/timeline/views.py
@@ -90,7 +90,6 @@ def timeline_view(request):
if obj_str in tosave:
setattr(tosave[obj_str], item['date_field'], parsed_date)
else:
-
setattr(obj, item['date_field'], parsed_date)
tosave[obj_str] = obj
diff --git a/oioioi/urls.py b/oioioi/urls.py
index a8f5920a8..577e71a1e 100644
--- a/oioioi/urls.py
+++ b/oioioi/urls.py
@@ -2,8 +2,8 @@
from django.conf import settings
from django.contrib import admin as django_admin
-from django.views import i18n
from django.urls import include, re_path
+from django.views import i18n
from oioioi.base import registration_backend
from oioioi.filetracker.views import raw_file_view
diff --git a/oioioi/usercontests/admin.py b/oioioi/usercontests/admin.py
index e3ffee267..cfbe61a89 100755
--- a/oioioi/usercontests/admin.py
+++ b/oioioi/usercontests/admin.py
@@ -9,8 +9,6 @@
from oioioi.base.menu import personal_menu_registry
from oioioi.base.permissions import make_request_condition
from oioioi.contests.admin import ContestAdmin, RoundInline
-from oioioi.contests.permissions import can_create_contest
-from oioioi.contests.utils import has_any_contest
from oioioi.usercontests.forms import UserContestForm
from oioioi.usercontests.models import UserContest
@@ -50,13 +48,12 @@ def use_usercontest_admin_form(request):
class UserRoundInlineFormset(RoundInline.formset):
def clean(self):
-
super(UserRoundInlineFormset, self).clean()
if not hasattr(settings, 'USER_CONTEST_TIMEOUT'):
return
for form in self.forms:
- if not 'end_date' in form.cleaned_data.keys():
+ if 'end_date' not in form.cleaned_data.keys():
continue
if form.cleaned_data['end_date'] is None:
raise forms.ValidationError(
diff --git a/oioioi/usercontests/tests.py b/oioioi/usercontests/tests.py
index 4fb3f8b8a..d5015809a 100644
--- a/oioioi/usercontests/tests.py
+++ b/oioioi/usercontests/tests.py
@@ -100,7 +100,7 @@ class TestUserContestCreationForm(TestCase):
fixtures = ['test_users']
def _get_future_date(self):
- date = '2037-04-19' # far in the future and in 32bit timestamp range.
+ date = '2037-04-19' # far in the future and in 32bit timestamp range.
assert datetime.strptime(date, '%Y-%M-%d') > datetime.now()
return date
diff --git a/oioioi/usergroups/admin.py b/oioioi/usergroups/admin.py
index 1c6bc371f..a11ce96e6 100644
--- a/oioioi/usergroups/admin.py
+++ b/oioioi/usergroups/admin.py
@@ -8,8 +8,8 @@
from oioioi.base import admin
from oioioi.base.menu import personal_menu_registry
from oioioi.base.permissions import is_superuser
+from oioioi.contests.admin import NO_CATEGORY, ContestAdmin
from oioioi.usergroups.models import UserGroup, UserGroupRanking
-from oioioi.contests.admin import ContestAdmin, NO_CATEGORY
def get_user_name_and_login_bounded(self, user):
@@ -65,9 +65,7 @@ class UserGroupRankingInline(admin.StackedInline):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'user_group':
- kwargs['queryset'] = UserGroup.objects.filter(
- contests=request.contest
- )
+ kwargs['queryset'] = UserGroup.objects.filter(contests=request.contest)
return super(UserGroupRankingInline, self).formfield_for_foreignkey(
db_field, request, **kwargs
)
diff --git a/oioioi/usergroups/controllers.py b/oioioi/usergroups/controllers.py
index df876fd29..31c352bfd 100644
--- a/oioioi/usergroups/controllers.py
+++ b/oioioi/usergroups/controllers.py
@@ -1,11 +1,10 @@
from django.db.models import Q
from django.utils import timezone
-from oioioi.rankings.controllers import CONTEST_RANKING_KEY
+from oioioi.contests.utils import is_contest_basicadmin, is_contest_observer
+from oioioi.rankings.controllers import CONTEST_RANKING_KEY, DefaultRankingController
from oioioi.teachers.controllers import TeacherRegistrationController
from oioioi.usergroups.models import UserGroup, UserGroupRanking
-from oioioi.contests.utils import is_contest_basicadmin, is_contest_observer
-from oioioi.rankings.controllers import DefaultRankingController
USER_GROUP_RANKING_PREFIX = 'g'
diff --git a/oioioi/usergroups/management/commands/remove_user_group_rankings.py b/oioioi/usergroups/management/commands/remove_user_group_rankings.py
index 58bd7a008..e0210d25f 100644
--- a/oioioi/usergroups/management/commands/remove_user_group_rankings.py
+++ b/oioioi/usergroups/management/commands/remove_user_group_rankings.py
@@ -2,9 +2,9 @@
from django.db import transaction
from django.utils.translation import gettext as _
-from oioioi.usergroups.models import UserGroupRanking
from oioioi.rankings.models import Ranking
from oioioi.usergroups.controllers import USER_GROUP_RANKING_PREFIX
+from oioioi.usergroups.models import UserGroupRanking
class Command(BaseCommand):
diff --git a/oioioi/usergroups/models.py b/oioioi/usergroups/models.py
index 7dc02d3c4..d3346dbdc 100644
--- a/oioioi/usergroups/models.py
+++ b/oioioi/usergroups/models.py
@@ -4,7 +4,6 @@
from django.db import models
from django.db.models import ProtectedError
from django.db.models.signals import post_delete, pre_save
-
from django.utils.translation import gettext_lazy as _
from oioioi.base.utils import generate_key
@@ -14,7 +13,6 @@
check_django_app_dependencies(__name__, ['oioioi.teachers'])
-
class UserGroup(models.Model):
"""Group of user which can be moved around contests by teachers"""
diff --git a/oioioi/usergroups/tests.py b/oioioi/usergroups/tests.py
index 8300e9f1d..42144abe4 100644
--- a/oioioi/usergroups/tests.py
+++ b/oioioi/usergroups/tests.py
@@ -1,19 +1,18 @@
from django.contrib.auth.models import User
+from django.core.management import call_command
from django.test import RequestFactory
+from django.test.utils import override_settings
from django.urls import reverse
from django.urls.exceptions import NoReverseMatch
-from django.test.utils import override_settings
-from django.core.management import call_command
-
from oioioi.base.tests import TestCase
from oioioi.contests.models import Contest
from oioioi.contests.tests.utils import make_user_contest_admin
from oioioi.participants.models import Participant
+from oioioi.rankings.models import Ranking
from oioioi.teachers.tests import change_contest_type
from oioioi.usergroups import utils
from oioioi.usergroups.models import ActionConfig, UserGroup
-from oioioi.rankings.models import Ranking
class TestAdmin(TestCase):
diff --git a/oioioi/workers/management/commands/start_receive_from_workers.py b/oioioi/workers/management/commands/start_receive_from_workers.py
index 74f29462f..ecbecf7f7 100644
--- a/oioioi/workers/management/commands/start_receive_from_workers.py
+++ b/oioioi/workers/management/commands/start_receive_from_workers.py
@@ -1,9 +1,9 @@
import cgi
+import http.server
import json
import logging
-
-import http.server
import socketserver
+
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import transaction
diff --git a/oioioi/workers/views.py b/oioioi/workers/views.py
index b1012866a..9b0b328cf 100644
--- a/oioioi/workers/views.py
+++ b/oioioi/workers/views.py
@@ -1,7 +1,6 @@
-import json
+import xmlrpc.client
from operator import itemgetter # pylint: disable=E0611
-import xmlrpc.client
from django.conf import settings
from django.http import JsonResponse
from django.shortcuts import render
@@ -22,8 +21,8 @@ def get_all_names():
return [i['name'] for i in get_info_about_workers()]
-def del_worker(l):
- for i in l:
+def del_worker(workers):
+ for i in workers:
server.forget_worker(i)
diff --git a/oioioi/zeus/backends.py b/oioioi/zeus/backends.py
index 5d7b2fc92..53d0e68e6 100644
--- a/oioioi/zeus/backends.py
+++ b/oioioi/zeus/backends.py
@@ -1,15 +1,15 @@
from __future__ import print_function
import base64
+import http.client
import json
import logging
import pprint
import time
-
-import http.client
import urllib.error
import urllib.parse
import urllib.request
+
from django.conf import settings
from django.utils.module_loading import import_string
diff --git a/oioioi/zeus/controllers.py b/oioioi/zeus/controllers.py
index 2e552eb8e..dc0d83c6c 100644
--- a/oioioi/zeus/controllers.py
+++ b/oioioi/zeus/controllers.py
@@ -1,4 +1,3 @@
-from django.conf import settings
from django.utils.translation import gettext_lazy as _
from oioioi.evalmgr.tasks import recipe_placeholder
diff --git a/oioioi/zeus/handlers.py b/oioioi/zeus/handlers.py
index c105feb52..f46797cca 100644
--- a/oioioi/zeus/handlers.py
+++ b/oioioi/zeus/handlers.py
@@ -239,9 +239,7 @@ def update_problem_tests_set(env, kind, **kwargs):
problem = data.problem
env_tests = {
- key: value
- for key, value in env['tests'].items()
- if value['kind'] == kind
+ key: value for key, value in env['tests'].items() if value['kind'] == kind
}
test_names = list(env_tests.keys())
diff --git a/oioioi/zeus/tests.py b/oioioi/zeus/tests.py
index 256f73862..f3bdbfbb8 100644
--- a/oioioi/zeus/tests.py
+++ b/oioioi/zeus/tests.py
@@ -1,7 +1,7 @@
import json
+import urllib.parse
import pytest
-import urllib.parse
from django.urls import reverse
from oioioi.base.tests import TestCase, TestsUtilsMixin
@@ -111,7 +111,7 @@ def _get_base_test_info(self, metadata=''):
'metadata': metadata,
'runtime': 100,
'time_limit_ms': 1000,
- 'memory_limit_byte': 2 ** 24,
+ 'memory_limit_byte': 2**24,
}
def _assert_dict_contains_subset(self, subset, dictionary):
@@ -182,7 +182,7 @@ def test_importing(self):
'group': '1',
'max_score': 2,
'exec_time_limit': 1000,
- 'exec_memory_limit': 2 ** 14,
+ 'exec_memory_limit': 2**14,
'zeus_metadata': '1a,1,2',
},
tests['1a'],
diff --git a/oioioi_cypress/cypress/fixtures/sum.py b/oioioi_cypress/cypress/fixtures/sum.py
index 392a942c8..b8dc7af99 100644
--- a/oioioi_cypress/cypress/fixtures/sum.py
+++ b/oioioi_cypress/cypress/fixtures/sum.py
@@ -1 +1 @@
-print(sum(list(map(int, input().split()))))
\ No newline at end of file
+print(sum(list(map(int, input().split()))))
diff --git a/oioioi_selenium/__init__.py b/oioioi_selenium/__init__.py
index 13c49d745..dd66cc073 100644
--- a/oioioi_selenium/__init__.py
+++ b/oioioi_selenium/__init__.py
@@ -96,9 +96,7 @@ def __new__(mcs, class_name, class_parents, class_attrs):
return type.__new__(mcs, class_name, class_parents, new_attrs)
-class OIOIOISeleniumTestCaseBase(
- unittest.TestCase, metaclass=WrapTestsWithScreenshots
-):
+class OIOIOISeleniumTestCaseBase(unittest.TestCase, metaclass=WrapTestsWithScreenshots):
def setUp(self):
self.driver = WebDriver()
diff --git a/pyproject.toml b/pyproject.toml
index a2c34cd01..a97dbe40e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -26,3 +26,17 @@ exclude = '''
)/
'''
force-exclude = '((.*)?default_settings.py|(.*)migrations(.*))'
+
+# Linter
+ruff = "^0.265.0"
+[tool.ruff]
+line-length = 120
+select = [
+ "E", # pycodestyle
+ "F", # pyflakes
+ "I" # isort
+]
+src = ["oioioi"]
+exclude = [
+ "migrations"
+]
\ No newline at end of file
diff --git a/requirements_static.txt b/requirements_static.txt
index a2bd3344d..825abcb7a 100644
--- a/requirements_static.txt
+++ b/requirements_static.txt
@@ -1,4 +1,6 @@
black==22.3
isort==5.6.4
+ruff==0.0.269
elastic-apm
python-memcached
+pre-commit==3.3.2
diff --git a/rst/gendoc.py b/rst/gendoc.py
index e9a603113..9b8b40196 100644
--- a/rst/gendoc.py
+++ b/rst/gendoc.py
@@ -16,7 +16,8 @@
sections_suff = '../rst/source/sections/'
sections_dist = len(sections_suff.split(os.sep))
-entries = ["""
+entries = [
+ """
..
Autogenerated by the /rst/gendoc.py script
@@ -31,7 +32,8 @@
* - Module
- Implements
-"""]
+"""
+]
missing = []
oioioi_dirname = os.path.dirname(oioioi.__file__)
@@ -39,7 +41,7 @@
for root, dirs, files in os.walk(oioioi_dirname):
dirs.sort()
rel_root = os.path.relpath(root, sections_dirname)
- module_name = '.'.join(rel_root.split(os.sep)[sections_dist - 1:])
+ module_name = '.'.join(rel_root.split(os.sep)[sections_dist - 1 :])
if "." in module_name or module_name.startswith("_") or not module_name:
continue
@@ -49,10 +51,7 @@
include_readme = "*README.rst missing*"
missing.append(module_name)
- entries.append(
- f" * - {module_name}\n"
- f" - {include_readme}\n"
- )
+ entries.append(f" * - {module_name}\n" f" - {include_readme}\n")
content = ''.join(entries)
@@ -60,7 +59,6 @@
print(sys.stderr, "Some README.rst for modules are missing:", missing)
-
if len(sys.argv) > 1 and (sys.argv[1] == '--verbose' or sys.argv[1] == '-v'):
print(content)
diff --git a/rst/source/conf.py b/rst/source/conf.py
index cc75880b2..07efcb3e3 100644
--- a/rst/source/conf.py
+++ b/rst/source/conf.py
@@ -18,6 +18,7 @@
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
import django
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'oioioi.test_settings')
django.setup()