diff --git a/CTFd/__init__.py b/CTFd/__init__.py index 144126f2..b5f2ba35 100644 --- a/CTFd/__init__.py +++ b/CTFd/__init__.py @@ -185,15 +185,15 @@ def create_app(config="CTFd.config.Config"): app.jinja_loader = jinja2.ChoiceLoader(loaders) from CTFd.models import ( # noqa: F401 - db, - Teams, - Solves, Challenges, Fails, - Flags, - Tags, Files, + Flags, + Solves, + Tags, + Teams, Tracking, + db, ) url = create_database() @@ -214,8 +214,8 @@ def create_app(config="CTFd.config.Config"): # db.create_all call because tests use the in-memory SQLite # database (each connection, including db creation, is a new db). # https://docs.sqlalchemy.org/en/13/dialects/sqlite.html#foreign-key-support - from sqlalchemy.engine import Engine from sqlalchemy import event + from sqlalchemy.engine import Engine @event.listens_for(Engine, "connect") def set_sqlite_pragma(dbapi_connection, connection_record): @@ -275,16 +275,16 @@ def create_app(config="CTFd.config.Config"): init_template_globals(app) # Importing here allows tests to use sensible names (e.g. api instead of api_bp) - from CTFd.views import views - from CTFd.teams import teams - from CTFd.users import users - from CTFd.challenges import challenges - from CTFd.scoreboard import scoreboard - from CTFd.auth import auth from CTFd.admin import admin from CTFd.api import api - from CTFd.events import events + from CTFd.auth import auth + from CTFd.challenges import challenges from CTFd.errors import render_error + from CTFd.events import events + from CTFd.scoreboard import scoreboard + from CTFd.teams import teams + from CTFd.users import users + from CTFd.views import views app.register_blueprint(views) app.register_blueprint(teams) diff --git a/CTFd/admin/__init__.py b/CTFd/admin/__init__.py index dedb2ea1..1c883cad 100644 --- a/CTFd/admin/__init__.py +++ b/CTFd/admin/__init__.py @@ -1,7 +1,7 @@ -import csv +import csv # noqa: I001 import datetime -import os from io import StringIO +import os from flask import Blueprint, abort from flask import current_app as app @@ -18,14 +18,14 @@ from flask import ( admin = Blueprint("admin", __name__) # isort:imports-firstparty -from CTFd.admin import challenges # noqa: F401 -from CTFd.admin import notifications # noqa: F401 -from CTFd.admin import pages # noqa: F401 -from CTFd.admin import scoreboard # noqa: F401 -from CTFd.admin import statistics # noqa: F401 -from CTFd.admin import submissions # noqa: F401 -from CTFd.admin import teams # noqa: F401 -from CTFd.admin import users # noqa: F401 +from CTFd.admin import challenges # noqa: F401,I001 +from CTFd.admin import notifications # noqa: F401,I001 +from CTFd.admin import pages # noqa: F401,I001 +from CTFd.admin import scoreboard # noqa: F401,I001 +from CTFd.admin import statistics # noqa: F401,I001 +from CTFd.admin import submissions # noqa: F401,I001 +from CTFd.admin import teams # noqa: F401,I001 +from CTFd.admin import users # noqa: F401,I001 from CTFd.cache import ( cache, clear_challenges, diff --git a/CTFd/api/v1/challenges.py b/CTFd/api/v1/challenges.py index 7cf734c8..d035221b 100644 --- a/CTFd/api/v1/challenges.py +++ b/CTFd/api/v1/challenges.py @@ -1,4 +1,4 @@ -from typing import List +from typing import List # noqa: I001 from flask import abort, render_template, request, url_for from flask_restx import Namespace, Resource diff --git a/CTFd/api/v1/statistics/__init__.py b/CTFd/api/v1/statistics/__init__.py index bbe79ddd..cec5a6ce 100644 --- a/CTFd/api/v1/statistics/__init__.py +++ b/CTFd/api/v1/statistics/__init__.py @@ -5,7 +5,7 @@ statistics_namespace = Namespace( ) # isort:imports-firstparty -from CTFd.api.v1.statistics import challenges # noqa: F401 +from CTFd.api.v1.statistics import challenges # noqa: F401,I001 from CTFd.api.v1.statistics import scores # noqa: F401 from CTFd.api.v1.statistics import submissions # noqa: F401 from CTFd.api.v1.statistics import teams # noqa: F401 diff --git a/CTFd/auth.py b/CTFd/auth.py index 3bbb5fa9..f261f253 100644 --- a/CTFd/auth.py +++ b/CTFd/auth.py @@ -1,4 +1,4 @@ -import base64 +import base64 # noqa: I001 import requests from flask import Blueprint, abort diff --git a/CTFd/cache/__init__.py b/CTFd/cache/__init__.py index 94d7bcf0..bcbcc35c 100644 --- a/CTFd/cache/__init__.py +++ b/CTFd/cache/__init__.py @@ -60,7 +60,7 @@ def clear_config(): def clear_standings(): - from CTFd.models import Users, Teams + from CTFd.models import Users, Teams # noqa: I001 from CTFd.constants.static import CacheKeys from CTFd.utils.scores import get_standings, get_team_standings, get_user_standings from CTFd.api.v1.scoreboard import ScoreboardDetail, ScoreboardList @@ -99,7 +99,7 @@ def clear_standings(): def clear_challenges(): - from CTFd.utils.challenges import get_all_challenges + from CTFd.utils.challenges import get_all_challenges # noqa: I001 from CTFd.utils.challenges import get_solves_for_challenge_id from CTFd.utils.challenges import get_solve_ids_for_user_id from CTFd.utils.challenges import get_solve_counts_for_challenges @@ -124,7 +124,7 @@ def clear_user_recent_ips(user_id): def clear_user_session(user_id): - from CTFd.utils.user import ( + from CTFd.utils.user import ( # noqa: I001 get_user_attrs, get_user_place, get_user_score, @@ -138,7 +138,7 @@ def clear_user_session(user_id): def clear_all_user_sessions(): - from CTFd.utils.user import ( + from CTFd.utils.user import ( # noqa: I001 get_user_attrs, get_user_place, get_user_score, diff --git a/CTFd/models/__init__.py b/CTFd/models/__init__.py index 387b873b..0bd62d9d 100644 --- a/CTFd/models/__init__.py +++ b/CTFd/models/__init__.py @@ -501,7 +501,7 @@ class Users(db.Model): to no imports within the CTFd application as importing from the application itself will result in a circular import. """ - from CTFd.utils.scores import get_user_standings + from CTFd.utils.scores import get_user_standings # noqa: I001 from CTFd.utils.humanize.numbers import ordinalize standings = get_user_standings(admin=admin) @@ -618,7 +618,7 @@ class Teams(db.Model): ] def get_invite_code(self): - from flask import current_app + from flask import current_app # noqa: I001 from CTFd.utils.security.signing import serialize, hmac secret_key = current_app.config["SECRET_KEY"] @@ -637,7 +637,7 @@ class Teams(db.Model): @classmethod def load_invite_code(cls, code): - from flask import current_app + from flask import current_app # noqa: I001 from CTFd.utils.security.signing import ( unserialize, hmac, @@ -736,7 +736,7 @@ class Teams(db.Model): to no imports within the CTFd application as importing from the application itself will result in a circular import. """ - from CTFd.utils.scores import get_team_standings + from CTFd.utils.scores import get_team_standings # noqa: I001 from CTFd.utils.humanize.numbers import ordinalize standings = get_team_standings(admin=admin) diff --git a/CTFd/plugins/migrations.py b/CTFd/plugins/migrations.py index cf4ddea7..36bcae47 100644 --- a/CTFd/plugins/migrations.py +++ b/CTFd/plugins/migrations.py @@ -1,4 +1,4 @@ -import inspect +import inspect # noqa: I001 import os from alembic.config import Config diff --git a/CTFd/utils/initialization/__init__.py b/CTFd/utils/initialization/__init__.py index 7379b36e..9eacb0f8 100644 --- a/CTFd/utils/initialization/__init__.py +++ b/CTFd/utils/initialization/__init__.py @@ -52,7 +52,7 @@ def init_template_filters(app): def init_template_globals(app): - from CTFd.constants import JINJA_ENUMS + from CTFd.constants import JINJA_ENUMS # noqa: I001 from CTFd.constants.assets import Assets from CTFd.constants.config import Configs from CTFd.constants.plugins import Plugins diff --git a/CTFd/utils/user/__init__.py b/CTFd/utils/user/__init__.py index 077e953d..dcf16725 100644 --- a/CTFd/utils/user/__init__.py +++ b/CTFd/utils/user/__init__.py @@ -1,4 +1,4 @@ -import datetime +import datetime # noqa: I001 import re from flask import abort diff --git a/CTFd/views.py b/CTFd/views.py index 8876bab8..72b1c5b9 100644 --- a/CTFd/views.py +++ b/CTFd/views.py @@ -1,4 +1,4 @@ -import os +import os # noqa: I001 from flask import Blueprint, abort from flask import current_app as app diff --git a/Makefile b/Makefile index f7da0961..e9734a98 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ lint: - flake8 --ignore=E402,E501,E712,W503,E203 --exclude=CTFd/uploads CTFd/ migrations/ tests/ + ruff check --select E,F,W,B,C4,I --ignore E402,E501,E712,B904,B905 --exclude=CTFd/uploads CTFd/ migrations/ tests/ yarn lint black --check --diff --exclude=CTFd/uploads --exclude=node_modules . prettier --check 'CTFd/themes/**/assets/**/*' diff --git a/development.txt b/development.txt index 100f2b01..d1bbf9f0 100644 --- a/development.txt +++ b/development.txt @@ -3,7 +3,7 @@ pip-tools==5.4.0 pytest==5.4.2 pytest-randomly==3.4.0 coverage==5.1 -flake8==3.8.2 +ruff==0.0.260 psycopg2-binary==2.8.6 codecov==2.1.7 moto==1.3.16 @@ -14,10 +14,7 @@ pytest-cov==2.9.0 sphinx_rtd_theme==0.4.3 flask-debugtoolbar==0.11.0 isort==4.3.21 -flake8-isort==3.0.0 Faker==4.1.0 pipdeptree==2.2.0 black==19.10b0 pytest-sugar==0.9.4 -flake8-comprehensions==3.3.1 -flake8-bugbear==20.11.1 diff --git a/migrations/env.py b/migrations/env.py index 5f824edb..f30d8fc9 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -1,4 +1,4 @@ -from __future__ import with_statement +from __future__ import with_statement # noqa: I001 import logging from logging.config import fileConfig diff --git a/migrations/versions/0366ba6575ca_add_table_for_comments.py b/migrations/versions/0366ba6575ca_add_table_for_comments.py index e7a696b1..e26e5090 100644 --- a/migrations/versions/0366ba6575ca_add_table_for_comments.py +++ b/migrations/versions/0366ba6575ca_add_table_for_comments.py @@ -5,7 +5,7 @@ Revises: 1093835a1051 Create Date: 2020-08-14 00:46:54.161120 """ -from alembic import op +from alembic import op # noqa: I001 import sqlalchemy as sa diff --git a/migrations/versions/07dfbe5e1edc_add_format_to_pages.py b/migrations/versions/07dfbe5e1edc_add_format_to_pages.py index bedd74c4..a90ea89a 100644 --- a/migrations/versions/07dfbe5e1edc_add_format_to_pages.py +++ b/migrations/versions/07dfbe5e1edc_add_format_to_pages.py @@ -5,7 +5,7 @@ Revises: 75e8ab9a0014 Create Date: 2021-06-15 19:57:37.410152 """ -from alembic import op +from alembic import op # noqa: I001 import sqlalchemy as sa diff --git a/migrations/versions/46a278193a94_enable_millisecond_precision_in_mysql_.py b/migrations/versions/46a278193a94_enable_millisecond_precision_in_mysql_.py index c0fd0c02..71829074 100644 --- a/migrations/versions/46a278193a94_enable_millisecond_precision_in_mysql_.py +++ b/migrations/versions/46a278193a94_enable_millisecond_precision_in_mysql_.py @@ -5,7 +5,7 @@ Revises: 4d3c1b59d011 Create Date: 2022-11-01 23:27:44.620893 """ -from alembic import op +from alembic import op # noqa: I001 from sqlalchemy.dialects import mysql diff --git a/migrations/versions/4d3c1b59d011_add_next_id_to_challenges_table.py b/migrations/versions/4d3c1b59d011_add_next_id_to_challenges_table.py index fff0b276..7b39a3bf 100644 --- a/migrations/versions/4d3c1b59d011_add_next_id_to_challenges_table.py +++ b/migrations/versions/4d3c1b59d011_add_next_id_to_challenges_table.py @@ -5,7 +5,7 @@ Revises: 6012fe8de495 Create Date: 2022-04-07 03:53:27.554190 """ -from alembic import op +from alembic import op # noqa: I001 import sqlalchemy as sa diff --git a/migrations/versions/6012fe8de495_add_connection_info_column_to_challenges.py b/migrations/versions/6012fe8de495_add_connection_info_column_to_challenges.py index 4ed0fbc4..2c5e85a4 100644 --- a/migrations/versions/6012fe8de495_add_connection_info_column_to_challenges.py +++ b/migrations/versions/6012fe8de495_add_connection_info_column_to_challenges.py @@ -5,7 +5,7 @@ Revises: ef87d69ec29a Create Date: 2021-07-30 03:50:54.219124 """ -from alembic import op +from alembic import op # noqa: I001 import sqlalchemy as sa diff --git a/migrations/versions/75e8ab9a0014_add_fields_and_fieldentries_tables.py b/migrations/versions/75e8ab9a0014_add_fields_and_fieldentries_tables.py index 4bef4cb6..f09170b3 100644 --- a/migrations/versions/75e8ab9a0014_add_fields_and_fieldentries_tables.py +++ b/migrations/versions/75e8ab9a0014_add_fields_and_fieldentries_tables.py @@ -5,7 +5,7 @@ Revises: 0366ba6575ca Create Date: 2020-08-19 00:36:17.579497 """ -from alembic import op +from alembic import op # noqa: I001 import sqlalchemy as sa diff --git a/migrations/versions/a03403986a32_add_theme_code_injections_to_configs.py b/migrations/versions/a03403986a32_add_theme_code_injections_to_configs.py index fc4349fa..7279641f 100644 --- a/migrations/versions/a03403986a32_add_theme_code_injections_to_configs.py +++ b/migrations/versions/a03403986a32_add_theme_code_injections_to_configs.py @@ -5,7 +5,7 @@ Revises: 080d29b15cd3 Create Date: 2020-02-13 01:10:16.430424 """ -from alembic import op +from alembic import op # noqa: I001 from sqlalchemy.sql import column, table from CTFd.models import db diff --git a/migrations/versions/ef87d69ec29a_add_topics_and_challenge_topics_tables.py b/migrations/versions/ef87d69ec29a_add_topics_and_challenge_topics_tables.py index 1e87ca8d..a1ea7e6c 100644 --- a/migrations/versions/ef87d69ec29a_add_topics_and_challenge_topics_tables.py +++ b/migrations/versions/ef87d69ec29a_add_topics_and_challenge_topics_tables.py @@ -5,7 +5,7 @@ Revises: 07dfbe5e1edc Create Date: 2021-07-29 23:22:39.345426 """ -from alembic import op +from alembic import op # noqa: I001 import sqlalchemy as sa diff --git a/tests/cache/test_challenges.py b/tests/cache/test_challenges.py index 73093d5c..b139f742 100644 --- a/tests/cache/test_challenges.py +++ b/tests/cache/test_challenges.py @@ -60,7 +60,7 @@ def test_deleting_challenge_clears_cache_solves(): data = req.get_json()["data"] challenge = data[0] assert challenge["solves"] == 1 - from CTFd.utils.challenges import ( + from CTFd.utils.challenges import ( # noqa: I001 get_solves_for_challenge_id, get_solve_counts_for_challenges, ) @@ -100,7 +100,7 @@ def test_deleting_solve_clears_cache(): data = req.get_json()["data"] challenge = data[0] assert challenge["solves"] == 1 - from CTFd.utils.challenges import ( + from CTFd.utils.challenges import ( # noqa: I001 get_solves_for_challenge_id, get_solve_counts_for_challenges, ) diff --git a/tests/constants/test_constants.py b/tests/constants/test_constants.py index 2d74537e..144d2902 100644 --- a/tests/constants/test_constants.py +++ b/tests/constants/test_constants.py @@ -24,7 +24,7 @@ def test_RawEnum(): def test_JSEnum(): - from CTFd.constants import JS_ENUMS + from CTFd.constants import JS_ENUMS # noqa: I001 import json @JSEnum