From 3d3652ca884d7db945e20bab5143d8b4c071c44b Mon Sep 17 00:00:00 2001 From: Matt Wang Date: Tue, 9 Apr 2024 17:44:17 +0800 Subject: [PATCH 1/8] lint: replace flake8 with ruff --- poetry.lock | 77 ++++++++++++++++++-------------------------------- pyproject.toml | 21 +++++++++++++- src/.flake8 | 4 --- 3 files changed, 47 insertions(+), 55 deletions(-) delete mode 100644 src/.flake8 diff --git a/poetry.lock b/poetry.lock index f303271d4..eff1023ba 100644 --- a/poetry.lock +++ b/poetry.lock @@ -571,22 +571,6 @@ files = [ [package.extras] tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] -[[package]] -name = "flake8" -version = "7.0.0" -description = "the modular source code checker: pep8 pyflakes and co" -optional = false -python-versions = ">=3.8.1" -files = [ - {file = "flake8-7.0.0-py2.py3-none-any.whl", hash = "sha256:a6dfbb75e03252917f2473ea9653f7cd799c3064e54d4c8140044c5c065f53c3"}, - {file = "flake8-7.0.0.tar.gz", hash = "sha256:33f96621059e65eec474169085dc92bf26e7b2d47366b70be2f67ab80dc25132"}, -] - -[package.dependencies] -mccabe = ">=0.7.0,<0.8.0" -pycodestyle = ">=2.11.0,<2.12.0" -pyflakes = ">=3.2.0,<3.3.0" - [[package]] name = "google-api-core" version = "2.8.0" @@ -1065,17 +1049,6 @@ files = [ [package.dependencies] traitlets = "*" -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - [[package]] name = "odfpy" version = "1.4.1" @@ -1350,28 +1323,6 @@ files = [ [package.dependencies] pyasn1 = ">=0.4.6,<0.7.0" -[[package]] -name = "pycodestyle" -version = "2.11.1" -description = "Python style guide checker" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"}, - {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"}, -] - -[[package]] -name = "pyflakes" -version = "3.2.0" -description = "passive checker of Python programs" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"}, - {file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"}, -] - [[package]] name = "pygments" version = "2.17.2" @@ -1652,6 +1603,32 @@ files = [ [package.dependencies] pyasn1 = ">=0.1.3" +[[package]] +name = "ruff" +version = "0.3.5" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.3.5-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:aef5bd3b89e657007e1be6b16553c8813b221ff6d92c7526b7e0227450981eac"}, + {file = "ruff-0.3.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:89b1e92b3bd9fca249153a97d23f29bed3992cff414b222fcd361d763fc53f12"}, + {file = "ruff-0.3.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e55771559c89272c3ebab23326dc23e7f813e492052391fe7950c1a5a139d89"}, + {file = "ruff-0.3.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dabc62195bf54b8a7876add6e789caae0268f34582333cda340497c886111c39"}, + {file = "ruff-0.3.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a05f3793ba25f194f395578579c546ca5d83e0195f992edc32e5907d142bfa3"}, + {file = "ruff-0.3.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:dfd3504e881082959b4160ab02f7a205f0fadc0a9619cc481982b6837b2fd4c0"}, + {file = "ruff-0.3.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87258e0d4b04046cf1d6cc1c56fadbf7a880cc3de1f7294938e923234cf9e498"}, + {file = "ruff-0.3.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:712e71283fc7d9f95047ed5f793bc019b0b0a29849b14664a60fd66c23b96da1"}, + {file = "ruff-0.3.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a532a90b4a18d3f722c124c513ffb5e5eaff0cc4f6d3aa4bda38e691b8600c9f"}, + {file = "ruff-0.3.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:122de171a147c76ada00f76df533b54676f6e321e61bd8656ae54be326c10296"}, + {file = "ruff-0.3.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d80a6b18a6c3b6ed25b71b05eba183f37d9bc8b16ace9e3d700997f00b74660b"}, + {file = "ruff-0.3.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a7b6e63194c68bca8e71f81de30cfa6f58ff70393cf45aab4c20f158227d5936"}, + {file = "ruff-0.3.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a759d33a20c72f2dfa54dae6e85e1225b8e302e8ac655773aff22e542a300985"}, + {file = "ruff-0.3.5-py3-none-win32.whl", hash = "sha256:9d8605aa990045517c911726d21293ef4baa64f87265896e491a05461cae078d"}, + {file = "ruff-0.3.5-py3-none-win_amd64.whl", hash = "sha256:dc56bb16a63c1303bd47563c60482a1512721053d93231cf7e9e1c6954395a0e"}, + {file = "ruff-0.3.5-py3-none-win_arm64.whl", hash = "sha256:faeeae9905446b975dcf6d4499dc93439b131f1443ee264055c5716dd947af55"}, + {file = "ruff-0.3.5.tar.gz", hash = "sha256:a067daaeb1dc2baf9b82a32dae67d154d95212080c80435eb052d95da647763d"}, +] + [[package]] name = "six" version = "1.16.0" @@ -1885,4 +1862,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "~3.10.0" -content-hash = "ff0d596caa9a752648f6f87a28c3f274a59410dfeff3b8c517d95a6124cf13e8" +content-hash = "9cc3edd81f19cae7b6b3111fad25d06943108f5483fd9b81734d9f4bced8251a" diff --git a/pyproject.toml b/pyproject.toml index 77b9c0a9e..cd86a5136 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,15 +38,34 @@ Pillow = "10.3.0" [tool.poetry.group.dev.dependencies] cssselect = "1.2.0" django-debug-toolbar = "4.3.0" -flake8 = "7.0.0" pytest = "8.1.1" pytest-cov = "5.0.0" pytest-django = "4.8.0" pytest-mock = "3.14.0" pytest-xdist = "3.5.0" +ruff = "0.3.5" Werkzeug = "3.0.2" +[tool.ruff] +exclude = [ + ".git", + "__pycache__", + "migrations" +] +line-length = 120 + +[tool.ruff.lint] +ignore = [ + "E251", +] +select = [ + "E", # pycodestyle error + "W", # pycodestyle warning + "F", # Pyflakes +] + + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" diff --git a/src/.flake8 b/src/.flake8 deleted file mode 100644 index 7702f7fa9..000000000 --- a/src/.flake8 +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -ignore = E251,W504 -max-line-length = 120 -exclude = __pycache__,migrations From f3d3dac78f499b225c7148a92972f727d17e1920 Mon Sep 17 00:00:00 2001 From: Matt Wang Date: Tue, 9 Apr 2024 17:44:47 +0800 Subject: [PATCH 2/8] ci: run ruff instead of flake8 --- .github/workflows/ci.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 66794c785..cfe4a7bde 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -51,9 +51,9 @@ jobs: with: cmd: install - - name: Run Flake8 on src + - name: Run ruff on src run: | - poetry run flake8 --config src/.flake8 src + poetry run ruff check src - name: Run DB migration for test run: | From 5972ba179793bd350fc320088be39baf2b1f2966 Mon Sep 17 00:00:00 2001 From: Matt Wang Date: Tue, 9 Apr 2024 17:48:56 +0800 Subject: [PATCH 3/8] lint: introduce isort (with ruff) --- pyproject.toml | 15 +++++++++++ src/attendee/api/urls.py | 1 - src/attendee/api/views.py | 6 ++--- src/attendee/tests.py | 1 + src/ccip/views.py | 10 ++++--- src/conftest.py | 5 ++-- src/core/admin.py | 5 ++-- src/core/middlewares.py | 3 +-- src/core/models.py | 6 ++--- src/core/templatetags/i18n_plus.py | 3 +-- src/core/templatetags/pycontw_tools.py | 1 - src/core/tests/test_middlewares.py | 1 - src/core/tests/test_validators.py | 1 - src/core/tests/test_views.py | 3 +-- src/core/utils.py | 4 +-- src/core/validators.py | 1 - src/core/views.py | 4 +-- src/events/admin.py | 25 ++++++++++++------ src/events/api/serializers.py | 2 +- src/events/api/views.py | 18 ++++++++----- .../management/commands/import_events.py | 2 -- src/events/models.py | 22 ++++++++-------- src/events/renderers.py | 13 ++++++---- src/events/resources.py | 3 +-- src/events/templatetags/events.py | 8 +++--- src/events/tests/api/test_list_speeches.py | 1 - src/events/tests/conftest.py | 2 -- src/events/tests/renderers/conftest.py | 8 +++--- src/events/tests/renderers/test_collect.py | 2 +- .../tests/renderers/test_render_block.py | 2 +- src/events/tests/renderers/test_render_row.py | 1 - src/events/tests/test_admin.py | 14 +++++++--- src/events/tests/test_management.py | 1 - src/events/tests/test_views.py | 1 - src/events/translation.py | 2 +- src/events/views.py | 15 +++++++---- src/proposals/admin.py | 1 - src/proposals/api/urls.py | 1 + src/proposals/api/views.py | 2 +- src/proposals/forms/proposals.py | 6 ++--- src/proposals/forms/speakers.py | 1 - .../management/commands/export_proposals.py | 2 +- .../commands/export_proposals_create_time.py | 5 ++-- .../management/commands/loadproposals.py | 1 - .../management/commands/recent_proposals.py | 5 ++-- src/proposals/models.py | 15 +++++++---- src/proposals/templatetags/proposals.py | 1 - .../tests/forms/test_additional_speaker.py | 3 ++- src/proposals/tests/forms/test_proposal.py | 9 ++++--- src/proposals/tests/test_management.py | 4 +-- src/proposals/tests/test_templatetags.py | 1 - src/proposals/tests/views/test_cancel.py | 3 +-- src/proposals/tests/views/test_create.py | 2 +- src/proposals/tests/views/test_edit.py | 1 - src/proposals/urls.py | 1 - src/proposals/utils.py | 1 - src/proposals/views/cancel.py | 1 - src/proposals/views/create.py | 3 +-- src/proposals/views/mixins.py | 3 +-- src/proposals/views/speakers.py | 7 ++--- src/proposals/views/update.py | 7 +++-- src/pycontw2016/settings/base.py | 1 - src/pycontw2016/settings/local.py | 13 +++++----- src/pycontw2016/settings/production/base.py | 3 +-- .../settings/production/pycontw2016.py | 2 +- .../settings/production/pycontw2017.py | 2 +- .../settings/production/pycontw2018.py | 2 +- .../settings/production/pycontw2019.py | 2 +- .../settings/production/pycontw2020.py | 2 +- .../settings/production/pycontw2021.py | 3 ++- .../settings/production/pycontw2022.py | 4 ++- .../settings/production/pycontw2023.py | 4 ++- .../settings/production/pycontw2024.py | 4 ++- src/pycontw2016/settings/testing/base.py | 2 +- .../settings/testing/pycontw2016.py | 3 +-- .../settings/testing/pycontw2017.py | 3 +-- .../settings/testing/pycontw2018.py | 3 +-- .../settings/testing/pycontw2019.py | 3 +-- .../settings/testing/pycontw2020.py | 3 +-- .../settings/testing/pycontw2021.py | 4 +-- .../settings/testing/pycontw2022.py | 4 +-- .../settings/testing/pycontw2023.py | 4 +-- .../settings/testing/pycontw2024.py | 4 +-- src/pycontw2016/urls.py | 1 - src/pycontw2016/wsgi.py | 1 - src/reviews/admin.py | 4 +-- src/reviews/context.py | 4 +-- src/reviews/management/commands/snaptalks.py | 4 +-- src/reviews/models.py | 5 ++-- src/reviews/templatetags/review_tools.py | 1 - src/reviews/urls.py | 1 - src/reviews/views.py | 4 +-- src/sponsors/admin.py | 3 +-- src/sponsors/api/urls.py | 3 ++- src/sponsors/api/views.py | 4 +-- src/sponsors/models.py | 7 +++-- src/sponsors/templatetags/sponsors.py | 1 - src/sponsors/translation.py | 4 +-- src/template_tests/test_pycontw2016.py | 2 -- src/users/admin.py | 2 +- src/users/forms.py | 16 +++++++----- src/users/models.py | 14 +++++----- src/users/tests/test_forms.py | 5 ++-- src/users/tests/test_views_profile.py | 2 -- src/users/tests/test_views_signup.py | 4 +-- src/users/urls.py | 1 - src/users/views.py | 26 ++++++++++--------- 107 files changed, 256 insertions(+), 236 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cd86a5136..f84418726 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,6 +63,21 @@ select = [ "E", # pycodestyle error "W", # pycodestyle warning "F", # Pyflakes + "I001", # isort +] + +[tool.ruff.lint.isort] +known-first-party = [ + "attendee", + "ccip", + "core", + "events", + "postgres", + "proposals", + "pycontw2016", + "reviews", + "sponsors", + "users" ] diff --git a/src/attendee/api/urls.py b/src/attendee/api/urls.py index 70f6e1194..03c9ca59c 100644 --- a/src/attendee/api/urls.py +++ b/src/attendee/api/urls.py @@ -2,7 +2,6 @@ from attendee.api.views import AttendeeAPIView - urlpatterns = [ path('verify/', AttendeeAPIView.as_view()), ] diff --git a/src/attendee/api/views.py b/src/attendee/api/views.py index 1bc7a7c1b..242e0a3bd 100644 --- a/src/attendee/api/views.py +++ b/src/attendee/api/views.py @@ -1,11 +1,11 @@ from django.conf import settings from registry.helper import reg -from rest_framework import views, status -from rest_framework.response import Response +from rest_framework import status, views from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response -from core.authentication import TokenAuthentication from attendee.models import Attendee +from core.authentication import TokenAuthentication class AttendeeAPIView(views.APIView): diff --git a/src/attendee/tests.py b/src/attendee/tests.py index 252861424..9d5392238 100644 --- a/src/attendee/tests.py +++ b/src/attendee/tests.py @@ -1,6 +1,7 @@ import pytest from django.conf import settings from registry.helper import reg + from attendee.models import Attendee from core.models import Token diff --git a/src/ccip/views.py b/src/ccip/views.py index 5c3c9e655..1c9a05fe2 100644 --- a/src/ccip/views.py +++ b/src/ccip/views.py @@ -1,18 +1,20 @@ import operator -from datetime import timezone, timedelta +from datetime import timedelta, timezone from django.http import JsonResponse from django.templatetags.static import static from django.utils import translation from django.utils.encoding import force_str from django.utils.translation import pgettext_lazy -from django.views.generic import View, TemplateView +from django.views.generic import TemplateView, View from core.utils import TemplateExistanceStatusResponse from core.views import IndexView from events.models import ( - CustomEvent, KeynoteEvent, - ProposedTalkEvent, ProposedTutorialEvent, + CustomEvent, + KeynoteEvent, + ProposedTalkEvent, + ProposedTutorialEvent, SponsoredEvent, ) from proposals.models import PrimarySpeaker diff --git a/src/conftest.py b/src/conftest.py index 455c38008..4945322ca 100644 --- a/src/conftest.py +++ b/src/conftest.py @@ -1,12 +1,11 @@ import collections -import six import pytest - +import six +from django.conf import settings from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser from django.test.html import parse_html -from django.conf import settings from rest_framework.test import APIClient from proposals.models import TalkProposal diff --git a/src/core/admin.py b/src/core/admin.py index e4fb1f89d..a9065c46d 100644 --- a/src/core/admin.py +++ b/src/core/admin.py @@ -1,9 +1,8 @@ -from django.contrib import admin from django.conf import settings +from django.contrib import admin from django.utils.translation import gettext_lazy as _ - -from registry.models import Entry from registry.admin import EntryAdmin +from registry.models import Entry class CurrentConferenceFilter(admin.filters.SimpleListFilter): diff --git a/src/core/middlewares.py b/src/core/middlewares.py index a07e58131..663d72540 100644 --- a/src/core/middlewares.py +++ b/src/core/middlewares.py @@ -1,9 +1,8 @@ import re from django.conf import settings -from django.urls import get_script_prefix from django.http import HttpResponseRedirect - +from django.urls import get_script_prefix # Matches things like # /en diff --git a/src/core/models.py b/src/core/models.py index c9cd1d628..bbc833ab8 100644 --- a/src/core/models.py +++ b/src/core/models.py @@ -7,14 +7,14 @@ from django.utils.translation import gettext_lazy as _ from .choices import ( + ATTEND_IN_PERSON, CATEGORY_CHOICES, LANGUAGE_CHOICES, + LIVE_STREAM_POLICY_CHOICES, + LIVING_IN_TAIWAN_CHOICES, PYTHON_LVL_CHOICES, RECORDING_POLICY_CHOICES, - LIVING_IN_TAIWAN_CHOICES, - LIVE_STREAM_POLICY_CHOICES, REFERRING_POLICY_CHOICES, - ATTEND_IN_PERSON, ) from .validators import EAWMaxLengthValidator diff --git a/src/core/templatetags/i18n_plus.py b/src/core/templatetags/i18n_plus.py index ea37ba48b..09e46e9de 100644 --- a/src/core/templatetags/i18n_plus.py +++ b/src/core/templatetags/i18n_plus.py @@ -1,6 +1,5 @@ -from django.urls import get_script_prefix from django.template import Library - +from django.urls import get_script_prefix register = Library() diff --git a/src/core/templatetags/pycontw_tools.py b/src/core/templatetags/pycontw_tools.py index 6eff23f1a..f63c42bff 100644 --- a/src/core/templatetags/pycontw_tools.py +++ b/src/core/templatetags/pycontw_tools.py @@ -2,7 +2,6 @@ from django.template import Library - register = Library() diff --git a/src/core/tests/test_middlewares.py b/src/core/tests/test_middlewares.py index 89edc752f..c32e3f66f 100644 --- a/src/core/tests/test_middlewares.py +++ b/src/core/tests/test_middlewares.py @@ -1,5 +1,4 @@ import pytest - from django.test import override_settings diff --git a/src/core/tests/test_validators.py b/src/core/tests/test_validators.py index efa4d874b..260d452d3 100644 --- a/src/core/tests/test_validators.py +++ b/src/core/tests/test_validators.py @@ -1,5 +1,4 @@ import pytest - from django.core.exceptions import ValidationError from core.validators import EAWMaxLengthValidator diff --git a/src/core/tests/test_views.py b/src/core/tests/test_views.py index 4b6f9f28a..4d808cb08 100644 --- a/src/core/tests/test_views.py +++ b/src/core/tests/test_views.py @@ -2,12 +2,11 @@ import os import pytest - from django.conf import settings from django.utils.translation import activate +from pytest_django.asserts import assertRedirects from events.models import Schedule -from pytest_django.asserts import assertRedirects @pytest.mark.django_db diff --git a/src/core/utils.py b/src/core/utils.py index d00eb1e6a..664a2b4a8 100644 --- a/src/core/utils.py +++ b/src/core/utils.py @@ -4,13 +4,11 @@ from django.http import Http404 from django.template.loader import TemplateDoesNotExist from django.template.response import TemplateResponse +from django.test import override_settings from django.utils.functional import lazy from django.utils.html import conditional_escape, format_html, mark_safe -from django.test import override_settings - from registry.helper import reg - format_html_lazy = lazy(format_html, str) diff --git a/src/core/validators.py b/src/core/validators.py index 0c91b041f..a01d1e734 100644 --- a/src/core/validators.py +++ b/src/core/validators.py @@ -2,7 +2,6 @@ from django.core.validators import MaxLengthValidator - # We duplicate the mapping used in the JavaScript library for consistency. # N(eutral) class is counted as 1, and A(mbiguous) as 2. # http://d.hatena.ne.jp/takenspc/20111126#1322252878 diff --git a/src/core/views.py b/src/core/views.py index d40a90423..03894ed5d 100644 --- a/src/core/views.py +++ b/src/core/views.py @@ -1,10 +1,10 @@ import functools from django.http import Http404 -from django.views.defaults import page_not_found, server_error -from django.views.generic import TemplateView from django.shortcuts import redirect from django.urls import reverse +from django.views.defaults import page_not_found, server_error +from django.views.generic import TemplateView from .data import EXTRA_DATA from .utils import ( diff --git a/src/events/admin.py b/src/events/admin.py index bec13f3b4..3acb18aee 100644 --- a/src/events/admin.py +++ b/src/events/admin.py @@ -1,24 +1,33 @@ from django.conf import settings from django.contrib import admin -from django.urls import reverse from django.db.models import Q +from django.urls import reverse from django.utils.html import format_html from django.utils.timezone import make_naive from django.utils.translation import ( - ugettext, gettext_lazy as _, pgettext_lazy as p, + gettext_lazy as _, +) +from django.utils.translation import ( + pgettext_lazy as p, +) +from django.utils.translation import ( + ugettext, ) - -from modeltranslation.admin import TranslationAdmin - from import_export.admin import ImportExportMixin +from modeltranslation.admin import TranslationAdmin from .forms import CustomEventForm from .models import ( - CustomEvent, KeynoteEvent, ProposedTalkEvent, ProposedTutorialEvent, + CustomEvent, JobListingsEvent, - SponsoredEvent, Time, Schedule, + KeynoteEvent, + ProposedTalkEvent, + ProposedTutorialEvent, + Schedule, + SponsoredEvent, + Time, ) -from .resources import TimeResource, CustomEventResource +from .resources import CustomEventResource, TimeResource class TimeRangeFilter(admin.SimpleListFilter): diff --git a/src/events/api/serializers.py b/src/events/api/serializers.py index 790acae28..8fb4fbbf1 100644 --- a/src/events/api/serializers.py +++ b/src/events/api/serializers.py @@ -1,7 +1,7 @@ from rest_framework import serializers from rest_framework.utils.serializer_helpers import ReturnDict -from events.models import ProposedTalkEvent, ProposedTutorialEvent, SponsoredEvent, KeynoteEvent +from events.models import KeynoteEvent, ProposedTalkEvent, ProposedTutorialEvent, SponsoredEvent from proposals.models import TalkProposal, TutorialProposal diff --git a/src/events/api/views.py b/src/events/api/views.py index 3494265c0..0333fb6a2 100644 --- a/src/events/api/views.py +++ b/src/events/api/views.py @@ -1,20 +1,24 @@ import collections from typing import List, Union -from rest_framework.generics import RetrieveAPIView, ListAPIView -from rest_framework.views import APIView -from rest_framework.response import Response -from rest_framework.permissions import IsAuthenticated - from django.conf import settings from django.db.models import Count from django.http import Http404 from django.utils.timezone import make_naive +from rest_framework.generics import ListAPIView, RetrieveAPIView +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework.views import APIView from core.authentication import TokenAuthentication from events.models import ( - CustomEvent, Location, ProposedTalkEvent, - ProposedTutorialEvent, SponsoredEvent, Time, KeynoteEvent + CustomEvent, + KeynoteEvent, + Location, + ProposedTalkEvent, + ProposedTutorialEvent, + SponsoredEvent, + Time, ) from . import serializers diff --git a/src/events/management/commands/import_events.py b/src/events/management/commands/import_events.py index 6591da125..97d79e131 100644 --- a/src/events/management/commands/import_events.py +++ b/src/events/management/commands/import_events.py @@ -2,7 +2,6 @@ import json import pytz - from django.apps import apps from django.conf import settings from django.core.management.base import BaseCommand @@ -11,7 +10,6 @@ from events.models import Location, Time from events.renderers import EVENT_CLASSES - cst = pytz.timezone('Asia/Taipei') DAYS = list(settings.EVENTS_DAY_NAMES.keys()) diff --git a/src/events/models.py b/src/events/models.py index e0b8ad783..110f1ae66 100644 --- a/src/events/models.py +++ b/src/events/models.py @@ -4,27 +4,27 @@ import urllib.parse import pytz - -from storages.backends.gcloud import GoogleCloudStorage - from django.conf import settings -from django.core.files.storage import default_storage from django.contrib.staticfiles import finders -from django.urls import reverse, reverse_lazy +from django.core.files.storage import default_storage from django.db import models -from django.utils.timezone import make_naive -from django.utils.translation import get_language, gettext, gettext_lazy as _ +from django.urls import reverse, reverse_lazy from django.utils.text import slugify +from django.utils.timezone import make_naive +from django.utils.translation import get_language, gettext +from django.utils.translation import gettext_lazy as _ +from storages.backends.gcloud import GoogleCloudStorage from core.models import ( - BigForeignKey, EventInfo, - ConferenceRelated, DefaultConferenceManagerMixin, + BigForeignKey, + ConferenceRelated, + DefaultConferenceManagerMixin, + EventInfo, ) from core.utils import format_html_lazy -from proposals.models import TalkProposal, TutorialProposal, PrimarySpeaker +from proposals.models import PrimarySpeaker, TalkProposal, TutorialProposal from sponsors.models import Sponsor - MIDNIGHT_TIME = datetime.time(tzinfo=pytz.timezone('Asia/Taipei')) EVENT_DATETIME_START_END = ( diff --git a/src/events/renderers.py b/src/events/renderers.py index 2f69b8dc2..01db08b40 100644 --- a/src/events/renderers.py +++ b/src/events/renderers.py @@ -1,19 +1,22 @@ import itertools import sortedcontainers - from django.conf import settings from django.utils.html import format_html, format_html_join from django.utils.safestring import mark_safe from django.utils.timezone import make_naive -from django.utils.translation import gettext, gettext_lazy as _ +from django.utils.translation import gettext +from django.utils.translation import gettext_lazy as _ from core.utils import html_join -from proposals.utils import format_names - from events.models import ( - Location, CustomEvent, KeynoteEvent, ProposedTalkEvent, SponsoredEvent, + CustomEvent, + KeynoteEvent, + Location, + ProposedTalkEvent, + SponsoredEvent, ) +from proposals.utils import format_names def render_customevent(e): diff --git a/src/events/resources.py b/src/events/resources.py index 276c6f6f3..000191634 100644 --- a/src/events/resources.py +++ b/src/events/resources.py @@ -1,8 +1,7 @@ from django.utils import timezone - from import_export import fields, resources, widgets -from .models import Time, CustomEvent +from .models import CustomEvent, Time class TimeResource(resources.ModelResource): diff --git a/src/events/templatetags/events.py b/src/events/templatetags/events.py index e95222b7c..5e3d8c1ab 100644 --- a/src/events/templatetags/events.py +++ b/src/events/templatetags/events.py @@ -1,3 +1,6 @@ +from datetime import datetime, timedelta +from math import floor + from django.conf import settings from django.template import Library from django.template.loader import get_template @@ -5,11 +8,8 @@ from django.utils.translation import gettext_lazy as _ from events.models import KeynoteEvent, Location -from sponsors.models import Sponsor, OpenRole from proposals.utils import format_names - -from datetime import datetime, timedelta -from math import floor +from sponsors.models import OpenRole, Sponsor LOCATION_DISPLAY_DICT = { Location.R0: _('R1'), diff --git a/src/events/tests/api/test_list_speeches.py b/src/events/tests/api/test_list_speeches.py index ae5069403..577009356 100644 --- a/src/events/tests/api/test_list_speeches.py +++ b/src/events/tests/api/test_list_speeches.py @@ -1,5 +1,4 @@ import pytest - from django.urls import reverse from core.models import Token diff --git a/src/events/tests/conftest.py b/src/events/tests/conftest.py index a82f24f7d..d0a98e48e 100644 --- a/src/events/tests/conftest.py +++ b/src/events/tests/conftest.py @@ -1,12 +1,10 @@ import pytest import pytz - from django.utils.dateparse import parse_datetime from django.utils.timezone import is_naive from events.models import Location, SponsoredEvent, Time - cst = pytz.timezone('Asia/Taipei') diff --git a/src/events/tests/renderers/conftest.py b/src/events/tests/renderers/conftest.py index 999532572..c097f6fe6 100644 --- a/src/events/tests/renderers/conftest.py +++ b/src/events/tests/renderers/conftest.py @@ -4,12 +4,14 @@ import pytz from events.models import ( - Location, Time, - CustomEvent, KeynoteEvent, ProposedTalkEvent, + CustomEvent, + KeynoteEvent, + Location, + ProposedTalkEvent, + Time, ) from proposals.models import AdditionalSpeaker - cst = pytz.timezone('Asia/Taipei') diff --git a/src/events/tests/renderers/test_collect.py b/src/events/tests/renderers/test_collect.py index 41988d545..cda922946 100644 --- a/src/events/tests/renderers/test_collect.py +++ b/src/events/tests/renderers/test_collect.py @@ -1,7 +1,7 @@ import itertools -import sortedcontainers import pytest +import sortedcontainers from events import renderers from events.renderers import make_group diff --git a/src/events/tests/renderers/test_render_block.py b/src/events/tests/renderers/test_render_block.py index 2945e8169..dde9a322b 100644 --- a/src/events/tests/renderers/test_render_block.py +++ b/src/events/tests/renderers/test_render_block.py @@ -1,7 +1,7 @@ import pytest from events import renderers -from events.models import Location, CustomEvent +from events.models import CustomEvent, Location @pytest.fixture diff --git a/src/events/tests/renderers/test_render_row.py b/src/events/tests/renderers/test_render_row.py index 5f3d4fdfd..d3fcc5ea1 100644 --- a/src/events/tests/renderers/test_render_row.py +++ b/src/events/tests/renderers/test_render_row.py @@ -1,5 +1,4 @@ import pytest - from django.utils.timezone import make_naive from events import renderers diff --git a/src/events/tests/test_admin.py b/src/events/tests/test_admin.py index 3e42df517..00b0050a3 100644 --- a/src/events/tests/test_admin.py +++ b/src/events/tests/test_admin.py @@ -1,16 +1,22 @@ import pytest - from django.contrib.admin import site from django.contrib.admin.views.main import ChangeList from django.contrib.auth.models import AnonymousUser from django.utils.encoding import force_str from events.admin import ( - CustomEventAdmin, KeynoteEventAdmin, ProposedTalkEventAdmin, - SponsoredEventAdmin, TimeAdmin, + CustomEventAdmin, + KeynoteEventAdmin, + ProposedTalkEventAdmin, + SponsoredEventAdmin, + TimeAdmin, ) from events.models import ( - CustomEvent, KeynoteEvent, ProposedTalkEvent, SponsoredEvent, Time, + CustomEvent, + KeynoteEvent, + ProposedTalkEvent, + SponsoredEvent, + Time, ) diff --git a/src/events/tests/test_management.py b/src/events/tests/test_management.py index 037b25c6e..fb98a2b08 100644 --- a/src/events/tests/test_management.py +++ b/src/events/tests/test_management.py @@ -3,7 +3,6 @@ import unittest.mock import pytest - from django.core.management import call_command from events.models import KeynoteEvent diff --git a/src/events/tests/test_views.py b/src/events/tests/test_views.py index 8852cbcc2..42d4e3643 100644 --- a/src/events/tests/test_views.py +++ b/src/events/tests/test_views.py @@ -1,5 +1,4 @@ import pytest - from django.conf import settings diff --git a/src/events/translation.py b/src/events/translation.py index 7de073c4c..0c1005dcd 100644 --- a/src/events/translation.py +++ b/src/events/translation.py @@ -1,4 +1,4 @@ -from modeltranslation.translator import translator, TranslationOptions +from modeltranslation.translator import TranslationOptions, translator from .models import KeynoteEvent diff --git a/src/events/views.py b/src/events/views.py index 20d090650..bf4b2ff21 100644 --- a/src/events/views.py +++ b/src/events/views.py @@ -4,9 +4,9 @@ from django.conf import settings from django.contrib.auth.mixins import PermissionRequiredMixin -from django.urls import reverse from django.db.models import Count, Prefetch from django.http import HttpResponseNotFound, HttpResponseRedirect +from django.urls import reverse from django.utils import translation from django.utils.translation import gettext_lazy as _ from django.views.generic import CreateView, DetailView, ListView, TemplateView @@ -17,13 +17,18 @@ from .forms import ScheduleCreationForm from .models import ( - EVENT_ROOMS, Schedule, Time, Location, - CustomEvent, KeynoteEvent, SponsoredEvent, - ProposedTalkEvent, ProposedTutorialEvent, + EVENT_ROOMS, + CustomEvent, + KeynoteEvent, + Location, + ProposedTalkEvent, + ProposedTutorialEvent, + Schedule, + SponsoredEvent, + Time, ) from .renderers import render_all - logger = logging.getLogger(__name__) diff --git a/src/proposals/admin.py b/src/proposals/admin.py index 866bbb4b1..9ca770b05 100644 --- a/src/proposals/admin.py +++ b/src/proposals/admin.py @@ -1,6 +1,5 @@ from django.contrib import admin from django.contrib.contenttypes.admin import GenericTabularInline - from import_export.admin import ExportMixin from .models import AdditionalSpeaker, TalkProposal, TutorialProposal diff --git a/src/proposals/api/urls.py b/src/proposals/api/urls.py index 3a985c8fc..57dc28025 100644 --- a/src/proposals/api/urls.py +++ b/src/proposals/api/urls.py @@ -1,4 +1,5 @@ from django.urls import path + from proposals.api.views import ProposalSummaryAPIView urlpatterns = [ diff --git a/src/proposals/api/views.py b/src/proposals/api/views.py index d76bfc3ef..9bfdac5f7 100644 --- a/src/proposals/api/views.py +++ b/src/proposals/api/views.py @@ -1,6 +1,6 @@ from rest_framework import views -from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response from core.authentication import TokenAuthentication from proposals.models import TalkProposal, TutorialProposal diff --git a/src/proposals/forms/proposals.py b/src/proposals/forms/proposals.py index 88cdfaf5d..56ff1207a 100644 --- a/src/proposals/forms/proposals.py +++ b/src/proposals/forms/proposals.py @@ -1,16 +1,16 @@ +from crispy_forms.helper import FormHelper from django import forms from django.conf import settings from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ -from crispy_forms.helper import FormHelper - from core.utils import form_has_instance from proposals.models import TalkProposal, TutorialProposal from .mixins import ( RequestUserSpeakerValidationMixin, - TalkProposalMixin, TutorialProposalMixin, + TalkProposalMixin, + TutorialProposalMixin, ) diff --git a/src/proposals/forms/speakers.py b/src/proposals/forms/speakers.py index 0ba4ea0f0..157efc23e 100644 --- a/src/proposals/forms/speakers.py +++ b/src/proposals/forms/speakers.py @@ -7,7 +7,6 @@ from .mixins import RequestUserSpeakerValidationMixin - User = get_user_model() diff --git a/src/proposals/management/commands/export_proposals.py b/src/proposals/management/commands/export_proposals.py index d4cbf3406..28480c7e9 100644 --- a/src/proposals/management/commands/export_proposals.py +++ b/src/proposals/management/commands/export_proposals.py @@ -2,8 +2,8 @@ from django.core.management.base import BaseCommand from django.core.serializers.json import DjangoJSONEncoder -from proposals.models import TalkProposal, TutorialProposal +from proposals.models import TalkProposal, TutorialProposal PROPOSAL_TYPE_MAPPING = { 'talk': TalkProposal, 'tutorial': TutorialProposal diff --git a/src/proposals/management/commands/export_proposals_create_time.py b/src/proposals/management/commands/export_proposals_create_time.py index f3cd71da5..5320513e8 100644 --- a/src/proposals/management/commands/export_proposals_create_time.py +++ b/src/proposals/management/commands/export_proposals_create_time.py @@ -1,9 +1,10 @@ import json -import pytz +import pytz +from django.core.management.base import BaseCommand from django.utils import timezone + from proposals.models import TalkProposal, TutorialProposal -from django.core.management.base import BaseCommand PROPOSAL_TYPE_MAPPING = { 'talk': TalkProposal, 'tutorial': TutorialProposal diff --git a/src/proposals/management/commands/loadproposals.py b/src/proposals/management/commands/loadproposals.py index 4ec05d4e6..d2b16dd1c 100644 --- a/src/proposals/management/commands/loadproposals.py +++ b/src/proposals/management/commands/loadproposals.py @@ -4,7 +4,6 @@ from django.contrib.auth import get_user_model from django.core.management.base import BaseCommand - User = get_user_model() diff --git a/src/proposals/management/commands/recent_proposals.py b/src/proposals/management/commands/recent_proposals.py index 6c8dd60da..84709e9f7 100644 --- a/src/proposals/management/commands/recent_proposals.py +++ b/src/proposals/management/commands/recent_proposals.py @@ -1,15 +1,16 @@ from datetime import datetime, timedelta from io import StringIO -from tabulate import tabulate import pytz +from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.mail import send_mail from django.core.management.base import BaseCommand, CommandError -from django.conf import settings from django.db.models import Q +from tabulate import tabulate from proposals.models import TalkProposal, TutorialProposal + from .slack import Slack utc_tz = pytz.UTC diff --git a/src/proposals/models.py b/src/proposals/models.py index 5ca64c715..dfe5cc77e 100644 --- a/src/proposals/models.py +++ b/src/proposals/models.py @@ -2,16 +2,21 @@ from django.conf import settings from django.contrib.contenttypes.fields import ( - GenericForeignKey, GenericRelation, + GenericForeignKey, + GenericRelation, ) -from django.urls import reverse from django.db import models from django.db.models import Q -from django.utils.translation import gettext, gettext_lazy as _ +from django.urls import reverse +from django.utils.translation import gettext +from django.utils.translation import gettext_lazy as _ from core.models import ( - ConferenceRelated, DefaultConferenceManager, - BigForeignKey, EAWTextField, EventInfo, + BigForeignKey, + ConferenceRelated, + DefaultConferenceManager, + EAWTextField, + EventInfo, ) diff --git a/src/proposals/templatetags/proposals.py b/src/proposals/templatetags/proposals.py index fd4472b44..b8a245e88 100644 --- a/src/proposals/templatetags/proposals.py +++ b/src/proposals/templatetags/proposals.py @@ -2,7 +2,6 @@ from proposals.utils import SEP_DEFAULT, SEP_LAST, format_names - register = Library() diff --git a/src/proposals/tests/forms/test_additional_speaker.py b/src/proposals/tests/forms/test_additional_speaker.py index c46c9cc6f..40a42f036 100644 --- a/src/proposals/tests/forms/test_additional_speaker.py +++ b/src/proposals/tests/forms/test_additional_speaker.py @@ -1,7 +1,8 @@ import pytest from proposals.forms import ( - AdditionalSpeakerCancelForm, AdditionalSpeakerCreateForm, + AdditionalSpeakerCancelForm, + AdditionalSpeakerCreateForm, AdditionalSpeakerSetStatusForm, ) from proposals.models import AdditionalSpeaker diff --git a/src/proposals/tests/forms/test_proposal.py b/src/proposals/tests/forms/test_proposal.py index 61f2bb8b0..3d6c7ce87 100644 --- a/src/proposals/tests/forms/test_proposal.py +++ b/src/proposals/tests/forms/test_proposal.py @@ -1,9 +1,12 @@ import pytest from proposals.forms import ( - TalkProposalCancelForm, TutorialProposalCancelForm, - TalkProposalCreateForm, TutorialProposalCreateForm, - TalkProposalUpdateForm, TutorialProposalUpdateForm, + TalkProposalCancelForm, + TalkProposalCreateForm, + TalkProposalUpdateForm, + TutorialProposalCancelForm, + TutorialProposalCreateForm, + TutorialProposalUpdateForm, ) from proposals.models import TalkProposal, TutorialProposal diff --git a/src/proposals/tests/test_management.py b/src/proposals/tests/test_management.py index 0dabf43ad..a7dd614af 100644 --- a/src/proposals/tests/test_management.py +++ b/src/proposals/tests/test_management.py @@ -6,18 +6,16 @@ import pytest import pytz - -from django.utils.timezone import now from django.conf import settings from django.core import mail from django.core.exceptions import ImproperlyConfigured from django.core.management import call_command from django.core.management.base import CommandError from django.test import override_settings +from django.utils.timezone import now from proposals.models import TalkProposal - taiwan_tz = pytz.timezone('Asia/Taipei') FakeHTTPResponse = collections.namedtuple('FakeHTTPResponse', 'status data') diff --git a/src/proposals/tests/test_templatetags.py b/src/proposals/tests/test_templatetags.py index c669f55a1..97ba79818 100644 --- a/src/proposals/tests/test_templatetags.py +++ b/src/proposals/tests/test_templatetags.py @@ -1,5 +1,4 @@ import pytest - from django.contrib.auth import get_user_model from django.template import Context, Template diff --git a/src/proposals/tests/views/test_cancel.py b/src/proposals/tests/views/test_cancel.py index 73b94e9d8..e1331c99c 100644 --- a/src/proposals/tests/views/test_cancel.py +++ b/src/proposals/tests/views/test_cancel.py @@ -1,9 +1,8 @@ import pytest - from django.contrib import messages -from proposals.models import TalkProposal, TutorialProposal from core.utils import set_registry +from proposals.models import TalkProposal, TutorialProposal def test_talk_proposal_cancel_login(client): diff --git a/src/proposals/tests/views/test_create.py b/src/proposals/tests/views/test_create.py index b79347c62..0c1781e61 100644 --- a/src/proposals/tests/views/test_create.py +++ b/src/proposals/tests/views/test_create.py @@ -1,7 +1,7 @@ from django.contrib import messages -from proposals.models import TalkProposal, TutorialProposal from core.utils import set_registry +from proposals.models import TalkProposal, TutorialProposal @set_registry(**{'proposals.creatable': False}) diff --git a/src/proposals/tests/views/test_edit.py b/src/proposals/tests/views/test_edit.py index d8228b123..3a66beeee 100644 --- a/src/proposals/tests/views/test_edit.py +++ b/src/proposals/tests/views/test_edit.py @@ -1,5 +1,4 @@ import pytest - from django.contrib import messages from core.utils import set_registry diff --git a/src/proposals/urls.py b/src/proposals/urls.py index bd7af73c3..640aec3dd 100644 --- a/src/proposals/urls.py +++ b/src/proposals/urls.py @@ -2,7 +2,6 @@ from . import views - urlpatterns = [ url(r'^talk/submit/$', diff --git a/src/proposals/utils.py b/src/proposals/utils.py index c2667194f..bb2e2d818 100644 --- a/src/proposals/utils.py +++ b/src/proposals/utils.py @@ -1,6 +1,5 @@ from django.utils.translation import pgettext_lazy - SEP_DEFAULT = pgettext_lazy('speaker name default separator', ', ') SEP_LAST = pgettext_lazy('speaker name last separator', ' and ') diff --git a/src/proposals/views/cancel.py b/src/proposals/views/cancel.py index 3674fea2d..f33e9792e 100644 --- a/src/proposals/views/cancel.py +++ b/src/proposals/views/cancel.py @@ -2,7 +2,6 @@ from django.contrib import messages from django.utils.html import format_html from django.utils.translation import ugettext - from registry.helper import reg from proposals.forms import TalkProposalCancelForm, TutorialProposalCancelForm diff --git a/src/proposals/views/create.py b/src/proposals/views/create.py index 93e34b875..4533c646d 100644 --- a/src/proposals/views/create.py +++ b/src/proposals/views/create.py @@ -4,13 +4,12 @@ from django.utils.html import format_html from django.utils.translation import gettext from django.views.generic import CreateView - from registry.helper import reg from core.mixins import FormValidMessageMixin from proposals.forms import TalkProposalCreateForm, TutorialProposalCreateForm -from .mixins import UserProfileRequiredMixin, CocAgreementMixin, ReviewsStateMixin +from .mixins import CocAgreementMixin, ReviewsStateMixin, UserProfileRequiredMixin class ProposalCreateView( diff --git a/src/proposals/views/mixins.py b/src/proposals/views/mixins.py index 4b983da30..6e2348345 100644 --- a/src/proposals/views/mixins.py +++ b/src/proposals/views/mixins.py @@ -2,10 +2,9 @@ from django.contrib.auth.mixins import UserPassesTestMixin from django.core.exceptions import PermissionDenied from django.http import Http404 -from django.utils.translation import gettext_lazy as _ from django.shortcuts import redirect from django.urls import reverse - +from django.utils.translation import gettext_lazy as _ from registry.helper import reg from reviews.context import reviews_state diff --git a/src/proposals/views/speakers.py b/src/proposals/views/speakers.py index fe0d11e26..2f6ff952f 100644 --- a/src/proposals/views/speakers.py +++ b/src/proposals/views/speakers.py @@ -1,16 +1,17 @@ from django.contrib.auth.mixins import LoginRequiredMixin -from django.urls import reverse from django.http import Http404 +from django.urls import reverse from django.views.generic import CreateView, UpdateView from core.mixins import FormValidMessageMixin from proposals.forms import ( - AdditionalSpeakerCancelForm, AdditionalSpeakerCreateForm, + AdditionalSpeakerCancelForm, + AdditionalSpeakerCreateForm, AdditionalSpeakerSetStatusForm, ) from proposals.models import AdditionalSpeaker, TalkProposal, TutorialProposal -from .mixins import ProposalEditMixin, UserProfileRequiredMixin, ReviewsStateMixin +from .mixins import ProposalEditMixin, ReviewsStateMixin, UserProfileRequiredMixin class ProposalManageSpeakersView( diff --git a/src/proposals/views/update.py b/src/proposals/views/update.py index aaaf53c0f..764798fa7 100644 --- a/src/proposals/views/update.py +++ b/src/proposals/views/update.py @@ -10,8 +10,11 @@ from reviews.models import Review from .mixins import ( - ProposalEditMixin, ProposalExamplesMixin, UserProfileRequiredMixin, - CocAgreementMixin, ReviewsStateMixin, + CocAgreementMixin, + ProposalEditMixin, + ProposalExamplesMixin, + ReviewsStateMixin, + UserProfileRequiredMixin, ) diff --git a/src/pycontw2016/settings/base.py b/src/pycontw2016/settings/base.py index 699fb2a03..bcd6f63e6 100644 --- a/src/pycontw2016/settings/base.py +++ b/src/pycontw2016/settings/base.py @@ -13,7 +13,6 @@ import os import environ - from django.conf import locale from django.contrib.messages import constants as messages from django.urls import reverse_lazy diff --git a/src/pycontw2016/settings/local.py b/src/pycontw2016/settings/local.py index 658f35ba4..01a4b2942 100644 --- a/src/pycontw2016/settings/local.py +++ b/src/pycontw2016/settings/local.py @@ -1,13 +1,14 @@ -from .base import ( - BASE_DIR, INSTALLED_APPS, MIDDLEWARE, - env, -) -from .base import * # NOQA - import logging.config import os import sys +from .base import * # NOQA +from .base import ( + BASE_DIR, + INSTALLED_APPS, + MIDDLEWARE, + env, +) # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True diff --git a/src/pycontw2016/settings/production/base.py b/src/pycontw2016/settings/production/base.py index 990c2d3d7..1af1a08b5 100644 --- a/src/pycontw2016/settings/production/base.py +++ b/src/pycontw2016/settings/production/base.py @@ -9,9 +9,8 @@ # Google Cloud storage from google.oauth2 import service_account +from ..base import * # noqa from ..base import BASE_DIR, TEMPLATES, env -from ..base import * # noqa - # For security and performance reasons, DEBUG is turned off DEBUG = False diff --git a/src/pycontw2016/settings/production/pycontw2016.py b/src/pycontw2016/settings/production/pycontw2016.py index 7904a9f3f..ef6a7758b 100644 --- a/src/pycontw2016/settings/production/pycontw2016.py +++ b/src/pycontw2016/settings/production/pycontw2016.py @@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _ -from .base import * # noqa +from .base import * # noqa # Override static and media URL for prefix in WSGI server. # https://code.djangoproject.com/ticket/25598 diff --git a/src/pycontw2016/settings/production/pycontw2017.py b/src/pycontw2016/settings/production/pycontw2017.py index 27fe0fde5..3a4235483 100644 --- a/src/pycontw2016/settings/production/pycontw2017.py +++ b/src/pycontw2016/settings/production/pycontw2017.py @@ -1,7 +1,7 @@ import os +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa # Override static and media URL for prefix in WSGI server. # https://code.djangoproject.com/ticket/25598 diff --git a/src/pycontw2016/settings/production/pycontw2018.py b/src/pycontw2016/settings/production/pycontw2018.py index 27fe0fde5..3a4235483 100644 --- a/src/pycontw2016/settings/production/pycontw2018.py +++ b/src/pycontw2016/settings/production/pycontw2018.py @@ -1,7 +1,7 @@ import os +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa # Override static and media URL for prefix in WSGI server. # https://code.djangoproject.com/ticket/25598 diff --git a/src/pycontw2016/settings/production/pycontw2019.py b/src/pycontw2016/settings/production/pycontw2019.py index d220543d4..69b9788fe 100644 --- a/src/pycontw2016/settings/production/pycontw2019.py +++ b/src/pycontw2016/settings/production/pycontw2019.py @@ -1,7 +1,7 @@ import os +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa # Override static and media URL for prefix in WSGI server. # https://code.djangoproject.com/ticket/25598 diff --git a/src/pycontw2016/settings/production/pycontw2020.py b/src/pycontw2016/settings/production/pycontw2020.py index b6136941f..e22c77287 100644 --- a/src/pycontw2016/settings/production/pycontw2020.py +++ b/src/pycontw2016/settings/production/pycontw2020.py @@ -1,7 +1,7 @@ import os +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa # Override static and media URL for prefix in WSGI server. # https://code.djangoproject.com/ticket/25598 diff --git a/src/pycontw2016/settings/production/pycontw2021.py b/src/pycontw2016/settings/production/pycontw2021.py index 1074aa60d..bc6f0f6fa 100644 --- a/src/pycontw2016/settings/production/pycontw2021.py +++ b/src/pycontw2016/settings/production/pycontw2021.py @@ -1,8 +1,9 @@ import os from django.utils.translation import gettext_lazy as _ + +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa # Override static and media URL for prefix in WSGI server. # https://code.djangoproject.com/ticket/25598 diff --git a/src/pycontw2016/settings/production/pycontw2022.py b/src/pycontw2016/settings/production/pycontw2022.py index 3b4d703e6..03b04a473 100644 --- a/src/pycontw2016/settings/production/pycontw2022.py +++ b/src/pycontw2016/settings/production/pycontw2022.py @@ -1,7 +1,9 @@ import os + from django.utils.translation import gettext_lazy as _ + +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa # Override static and media URL for prefix in WSGI server. # https://code.djangoproject.com/ticket/25598 diff --git a/src/pycontw2016/settings/production/pycontw2023.py b/src/pycontw2016/settings/production/pycontw2023.py index 6fd46be25..ef39b6291 100644 --- a/src/pycontw2016/settings/production/pycontw2023.py +++ b/src/pycontw2016/settings/production/pycontw2023.py @@ -1,7 +1,9 @@ import os + from django.utils.translation import gettext_lazy as _ + +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa # Override static and media URL for prefix in WSGI server. # https://code.djangoproject.com/ticket/25598 diff --git a/src/pycontw2016/settings/production/pycontw2024.py b/src/pycontw2016/settings/production/pycontw2024.py index 30a56fe18..4bb7d97d4 100644 --- a/src/pycontw2016/settings/production/pycontw2024.py +++ b/src/pycontw2016/settings/production/pycontw2024.py @@ -1,7 +1,9 @@ import os + from django.utils.translation import gettext_lazy as _ + +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa # Override static and media URL for prefix in WSGI server. # https://code.djangoproject.com/ticket/25598 diff --git a/src/pycontw2016/settings/testing/base.py b/src/pycontw2016/settings/testing/base.py index b28b20598..64af5cfaa 100644 --- a/src/pycontw2016/settings/testing/base.py +++ b/src/pycontw2016/settings/testing/base.py @@ -1,7 +1,7 @@ import os +from ..local import * # noqa from ..local import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from ..local import * # noqa DEBUG = False diff --git a/src/pycontw2016/settings/testing/pycontw2016.py b/src/pycontw2016/settings/testing/pycontw2016.py index 461a5075c..b6f7e7cab 100644 --- a/src/pycontw2016/settings/testing/pycontw2016.py +++ b/src/pycontw2016/settings/testing/pycontw2016.py @@ -1,8 +1,7 @@ import os +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa - CONFERENCE_DEFAULT_SLUG = 'pycontw-2016' TEMPLATES[0]['DIRS'][1] = os.path.join(BASE_DIR, 'templates', 'pycontw-2016') diff --git a/src/pycontw2016/settings/testing/pycontw2017.py b/src/pycontw2016/settings/testing/pycontw2017.py index 9007edaab..dd5392fce 100644 --- a/src/pycontw2016/settings/testing/pycontw2017.py +++ b/src/pycontw2016/settings/testing/pycontw2017.py @@ -1,8 +1,7 @@ import os +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa - CONFERENCE_DEFAULT_SLUG = 'pycontw-2017' TEMPLATES[0]['DIRS'][1] = os.path.join(BASE_DIR, 'templates', 'pycontw-2017') diff --git a/src/pycontw2016/settings/testing/pycontw2018.py b/src/pycontw2016/settings/testing/pycontw2018.py index ab453b522..34aec60a5 100644 --- a/src/pycontw2016/settings/testing/pycontw2018.py +++ b/src/pycontw2016/settings/testing/pycontw2018.py @@ -1,8 +1,7 @@ import os +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa - CONFERENCE_DEFAULT_SLUG = 'pycontw-2018' TEMPLATES[0]['DIRS'][1] = os.path.join(BASE_DIR, 'templates', 'pycontw-2018') diff --git a/src/pycontw2016/settings/testing/pycontw2019.py b/src/pycontw2016/settings/testing/pycontw2019.py index 216304122..50fa145d1 100644 --- a/src/pycontw2016/settings/testing/pycontw2019.py +++ b/src/pycontw2016/settings/testing/pycontw2019.py @@ -1,8 +1,7 @@ import os +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa - CONFERENCE_DEFAULT_SLUG = 'pycontw-2019' TEMPLATES[0]['DIRS'][1] = os.path.join(BASE_DIR, 'templates', 'pycontw-2019') diff --git a/src/pycontw2016/settings/testing/pycontw2020.py b/src/pycontw2016/settings/testing/pycontw2020.py index 7ba855ee0..e7a9e4a22 100644 --- a/src/pycontw2016/settings/testing/pycontw2020.py +++ b/src/pycontw2016/settings/testing/pycontw2020.py @@ -1,8 +1,7 @@ import os +from .base import * # noqa from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa - CONFERENCE_DEFAULT_SLUG = 'pycontw-2020' TEMPLATES[0]['DIRS'][1] = os.path.join(BASE_DIR, 'templates', 'pycontw-2020') diff --git a/src/pycontw2016/settings/testing/pycontw2021.py b/src/pycontw2016/settings/testing/pycontw2021.py index d2aa1eecd..fe692d152 100644 --- a/src/pycontw2016/settings/testing/pycontw2021.py +++ b/src/pycontw2016/settings/testing/pycontw2021.py @@ -1,9 +1,9 @@ import os from django.utils.translation import gettext_lazy as _ -from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa +from .base import * # noqa +from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES CONFERENCE_DEFAULT_SLUG = 'pycontw-2021' diff --git a/src/pycontw2016/settings/testing/pycontw2022.py b/src/pycontw2016/settings/testing/pycontw2022.py index a57f5b012..e0b366364 100644 --- a/src/pycontw2016/settings/testing/pycontw2022.py +++ b/src/pycontw2016/settings/testing/pycontw2022.py @@ -1,9 +1,9 @@ import os from django.utils.translation import gettext_lazy as _ -from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa +from .base import * # noqa +from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES CONFERENCE_DEFAULT_SLUG = 'pycontw-2022' diff --git a/src/pycontw2016/settings/testing/pycontw2023.py b/src/pycontw2016/settings/testing/pycontw2023.py index 0e294c6ec..154f4f8f7 100644 --- a/src/pycontw2016/settings/testing/pycontw2023.py +++ b/src/pycontw2016/settings/testing/pycontw2023.py @@ -1,9 +1,9 @@ import os from django.utils.translation import gettext_lazy as _ -from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa +from .base import * # noqa +from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES CONFERENCE_DEFAULT_SLUG = 'pycontw-2023' diff --git a/src/pycontw2016/settings/testing/pycontw2024.py b/src/pycontw2016/settings/testing/pycontw2024.py index 9f999213f..3c5a8724b 100644 --- a/src/pycontw2016/settings/testing/pycontw2024.py +++ b/src/pycontw2016/settings/testing/pycontw2024.py @@ -1,9 +1,9 @@ import os from django.utils.translation import gettext_lazy as _ -from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES -from .base import * # noqa +from .base import * # noqa +from .base import BASE_DIR, STATICFILES_DIRS, TEMPLATES CONFERENCE_DEFAULT_SLUG = 'pycontw-2024' diff --git a/src/pycontw2016/urls.py b/src/pycontw2016/urls.py index 7fa27c62d..0d0f7cbd4 100644 --- a/src/pycontw2016/urls.py +++ b/src/pycontw2016/urls.py @@ -8,7 +8,6 @@ from core.views import error_page, flat_page, index from users.views import user_dashboard - urlpatterns = i18n_patterns( # Add top-level URL patterns here. diff --git a/src/pycontw2016/wsgi.py b/src/pycontw2016/wsgi.py index 2974a2113..b7ac3d595 100644 --- a/src/pycontw2016/wsgi.py +++ b/src/pycontw2016/wsgi.py @@ -11,7 +11,6 @@ from django.conf import settings from django.core.wsgi import get_wsgi_application - os.environ.setdefault( 'DJANGO_SETTINGS_MODULE', 'pycontw2016.settings.production.pycontw2016', diff --git a/src/reviews/admin.py b/src/reviews/admin.py index 50704a069..54d63bd55 100644 --- a/src/reviews/admin.py +++ b/src/reviews/admin.py @@ -4,8 +4,8 @@ from django.contrib import admin from django.utils.html import linebreaks -from django.utils.translation import ugettext, gettext_lazy as _ - +from django.utils.translation import gettext_lazy as _ +from django.utils.translation import ugettext from import_export.admin import ImportExportMixin from .models import Review, TalkProposalSnapshot diff --git a/src/reviews/context.py b/src/reviews/context.py index 13de57995..396cac411 100644 --- a/src/reviews/context.py +++ b/src/reviews/context.py @@ -1,12 +1,10 @@ -from datetime import datetime from collections import namedtuple +from datetime import datetime from django.conf import settings from django.utils import timezone - from registry.helper import reg - # This code is located here, but not in context_processor # because this is not intended to be processed at every page # preparing these requires database query, and only a subset of diff --git a/src/reviews/management/commands/snaptalks.py b/src/reviews/management/commands/snaptalks.py index 6e4d32e6f..312d9dae9 100644 --- a/src/reviews/management/commands/snaptalks.py +++ b/src/reviews/management/commands/snaptalks.py @@ -3,16 +3,14 @@ from django.conf import settings from django.core import serializers -from django.core.serializers.json import DjangoJSONEncoder from django.core.management.base import BaseCommand, CommandError +from django.core.serializers.json import DjangoJSONEncoder from django.db import transaction - from registry.helper import reg from proposals.models import TalkProposal from reviews.models import TalkProposalSnapshot - PythonSerializer = serializers.get_serializer('python') diff --git a/src/reviews/models.py b/src/reviews/models.py index 915d9061d..010b7b348 100644 --- a/src/reviews/models.py +++ b/src/reviews/models.py @@ -4,14 +4,13 @@ from django.conf import settings from django.db import models from django.db.models import Q -from django.utils.translation import ugettext, gettext_lazy as _ - +from django.utils.translation import gettext_lazy as _ +from django.utils.translation import ugettext from registry.helper import reg from core.models import BigForeignKey, DefaultConferenceManager from proposals.models import TalkProposal - REVIEW_REQUIRED_PERMISSIONS = ['reviews.add_review'] diff --git a/src/reviews/templatetags/review_tools.py b/src/reviews/templatetags/review_tools.py index 7b108f203..56b81ae72 100644 --- a/src/reviews/templatetags/review_tools.py +++ b/src/reviews/templatetags/review_tools.py @@ -7,7 +7,6 @@ from core import difftools from core.utils import html_join - register = Library() diff --git a/src/reviews/urls.py b/src/reviews/urls.py index 9250f9e51..f81b1df27 100644 --- a/src/reviews/urls.py +++ b/src/reviews/urls.py @@ -2,7 +2,6 @@ from .views import ReviewEditView, TalkProposalListView - urlpatterns = [ url(r'^$', TalkProposalListView.as_view(), name='review_proposal_list'), url(r'^talk/(?P\d+)/$', diff --git a/src/reviews/views.py b/src/reviews/views.py index 47675612d..cc3ab316f 100644 --- a/src/reviews/views.py +++ b/src/reviews/views.py @@ -3,17 +3,17 @@ import random from django.contrib.auth.mixins import PermissionRequiredMixin -from django.urls import reverse from django.db.models import Count from django.http import Http404 +from django.urls import reverse from django.views.generic import ListView, UpdateView from core.utils import SequenceQuerySet from proposals.models import TalkProposal +from .context import reviews_state from .forms import ReviewForm from .models import REVIEW_REQUIRED_PERMISSIONS, Review, TalkProposalSnapshot -from .context import reviews_state class ReviewableMixin: diff --git a/src/sponsors/admin.py b/src/sponsors/admin.py index b05ace09f..90468743a 100644 --- a/src/sponsors/admin.py +++ b/src/sponsors/admin.py @@ -1,8 +1,7 @@ from django.contrib import admin - from modeltranslation.admin import TranslationAdmin -from .models import Sponsor, OpenRole +from .models import OpenRole, Sponsor @admin.register(Sponsor) diff --git a/src/sponsors/api/urls.py b/src/sponsors/api/urls.py index a63ae6ccd..e85a56829 100644 --- a/src/sponsors/api/urls.py +++ b/src/sponsors/api/urls.py @@ -1,5 +1,6 @@ from django.urls import path -from sponsors.api.views import SponsorAPIView, JobAPIView + +from sponsors.api.views import JobAPIView, SponsorAPIView urlpatterns = [ path("", SponsorAPIView.as_view()), diff --git a/src/sponsors/api/views.py b/src/sponsors/api/views.py index 8436aea32..022ddd959 100644 --- a/src/sponsors/api/views.py +++ b/src/sponsors/api/views.py @@ -1,11 +1,11 @@ from collections import OrderedDict from rest_framework import views -from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response from core.authentication import TokenAuthentication -from sponsors.models import Sponsor, OpenRole +from sponsors.models import OpenRole, Sponsor class SponsorAPIView(views.APIView): diff --git a/src/sponsors/models.py b/src/sponsors/models.py index 9a5a4bede..6d9525563 100644 --- a/src/sponsors/models.py +++ b/src/sponsors/models.py @@ -1,13 +1,12 @@ -from storages.backends.gcloud import GoogleCloudStorage - from django.conf import settings from django.core.files.storage import default_storage from django.db import models +from django.utils.text import slugify from django.utils.translation import gettext_lazy as _ from django.utils.translation import override -from django.utils.text import slugify +from storages.backends.gcloud import GoogleCloudStorage -from core.models import ConferenceRelated, BigForeignKey +from core.models import BigForeignKey, ConferenceRelated def select_storage(): diff --git a/src/sponsors/templatetags/sponsors.py b/src/sponsors/templatetags/sponsors.py index b433b1dd8..d8dbafb6d 100644 --- a/src/sponsors/templatetags/sponsors.py +++ b/src/sponsors/templatetags/sponsors.py @@ -7,7 +7,6 @@ from sponsors.models import Sponsor - register = Library() diff --git a/src/sponsors/translation.py b/src/sponsors/translation.py index 7db2532c5..03a9cc1a5 100644 --- a/src/sponsors/translation.py +++ b/src/sponsors/translation.py @@ -1,6 +1,6 @@ -from modeltranslation.translator import translator, TranslationOptions +from modeltranslation.translator import TranslationOptions, translator -from .models import Sponsor, OpenRole +from .models import OpenRole, Sponsor class SponsorTranslationOptions(TranslationOptions): diff --git a/src/template_tests/test_pycontw2016.py b/src/template_tests/test_pycontw2016.py index b02583540..c85a50c40 100644 --- a/src/template_tests/test_pycontw2016.py +++ b/src/template_tests/test_pycontw2016.py @@ -1,13 +1,11 @@ import re import pytest - from django.conf import settings from django.contrib.auth import get_user_model from django.core import mail, signing from django.test import override_settings - pytestmark = pytest.mark.skipif( settings.CONFERENCE_DEFAULT_SLUG != 'pycontw-2016', reason='Not current conference', diff --git a/src/users/admin.py b/src/users/admin.py index e663a2b0c..93aa33241 100644 --- a/src/users/admin.py +++ b/src/users/admin.py @@ -2,8 +2,8 @@ from django.contrib.auth.admin import UserAdmin from django.utils.translation import gettext_lazy as _ -from .models import User, CocRecord from .forms import AdminUserChangeForm, UserCreationForm +from .models import CocRecord, User @admin.register(User) diff --git a/src/users/forms.py b/src/users/forms.py index c67a34d3c..e9113c36a 100644 --- a/src/users/forms.py +++ b/src/users/forms.py @@ -1,21 +1,25 @@ +from crispy_forms.bootstrap import FormActions +from crispy_forms.helper import FormHelper +from crispy_forms.layout import HTML, Div, Field, Fieldset, Layout, Submit from django import forms from django.contrib.auth import authenticate, get_user_model from django.contrib.auth.forms import ( AuthenticationForm as BaseAuthenticationForm, +) +from django.contrib.auth.forms import ( PasswordResetForm as BasePasswordResetForm, - SetPasswordForm as BaseSetPasswordForm, +) +from django.contrib.auth.forms import ( ReadOnlyPasswordHashField, ) +from django.contrib.auth.forms import ( + SetPasswordForm as BaseSetPasswordForm, +) from django.core.files.images import get_image_dimensions from django.urls import reverse from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ -from crispy_forms.helper import FormHelper -from crispy_forms.layout import Field, Fieldset, Layout, Submit, HTML, Div -from crispy_forms.bootstrap import FormActions - - User = get_user_model() diff --git a/src/users/models.py b/src/users/models.py index 487216b1f..2c0c398e7 100644 --- a/src/users/models.py +++ b/src/users/models.py @@ -1,26 +1,28 @@ -import datetime import base64 +import datetime import hashlib import os from django.conf import settings from django.contrib.auth.models import ( - AbstractBaseUser, BaseUserManager, PermissionsMixin, + AbstractBaseUser, + BaseUserManager, + PermissionsMixin, ) from django.core import signing from django.core.mail import send_mail -from django.urls import reverse from django.core.validators import RegexValidator from django.db import models from django.template.loader import render_to_string from django.templatetags.static import static +from django.urls import reverse from django.utils import timezone -from django.utils.translation import gettext, gettext_lazy as _ - +from django.utils.translation import gettext +from django.utils.translation import gettext_lazy as _ from sorl.thumbnail import get_thumbnail +from core.models import BigForeignKey, EAWTextField from core.utils import format_html_lazy -from core.models import EAWTextField, BigForeignKey class UserQueryset(models.QuerySet): diff --git a/src/users/tests/test_forms.py b/src/users/tests/test_forms.py index 9c04edefc..efe561bec 100644 --- a/src/users/tests/test_forms.py +++ b/src/users/tests/test_forms.py @@ -1,9 +1,10 @@ import pytest - from crispy_forms.helper import FormHelper from users.forms import ( - PasswordResetForm, PublicUserCreationForm, SetPasswordForm, + PasswordResetForm, + PublicUserCreationForm, + SetPasswordForm, ) diff --git a/src/users/tests/test_views_profile.py b/src/users/tests/test_views_profile.py index 26c8c3a6c..afb2ec5aa 100644 --- a/src/users/tests/test_views_profile.py +++ b/src/users/tests/test_views_profile.py @@ -1,9 +1,7 @@ import pytest - from django.contrib import messages from django.contrib.auth import get_user_model - User = get_user_model() diff --git a/src/users/tests/test_views_signup.py b/src/users/tests/test_views_signup.py index 5466f2e8b..213932f5b 100644 --- a/src/users/tests/test_views_signup.py +++ b/src/users/tests/test_views_signup.py @@ -1,11 +1,9 @@ import pytest - from django.contrib import messages from django.contrib.auth import get_user_model from django.core import mail -from django.urls import reverse from django.test import override_settings - +from django.urls import reverse User = get_user_model() diff --git a/src/users/urls.py b/src/users/urls.py index 04203ec52..f71dd74ec 100644 --- a/src/users/urls.py +++ b/src/users/urls.py @@ -3,7 +3,6 @@ from . import views - urlpatterns = [ url(r'^login/$', views.login, name='login'), diff --git a/src/users/views.py b/src/users/views.py index e8f83b8c9..fe6825bfa 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -1,28 +1,30 @@ +import lxml.html from django.conf import settings -from django.contrib import messages -from django.contrib import auth +from django.contrib import auth, messages from django.contrib.auth import views as auth_views from django.contrib.auth.decorators import login_required -from django.urls import reverse from django.http import Http404 from django.shortcuts import redirect, render -from django.utils.translation import gettext, get_language +from django.template.loader import render_to_string +from django.urls import reverse +from django.utils.translation import get_language, gettext from django.views.decorators.cache import never_cache from django.views.decorators.debug import sensitive_post_parameters from django.views.decorators.http import require_POST -from django.template.loader import render_to_string +from lxml import etree + +from reviews.context import proposals_state, reviews_state from .decorators import login_forbidden from .forms import ( - AuthenticationForm, PublicUserCreationForm, UserProfileUpdateForm, - PasswordResetForm, SetPasswordForm, CocAgreementForm, + AuthenticationForm, + CocAgreementForm, + PasswordResetForm, + PublicUserCreationForm, + SetPasswordForm, + UserProfileUpdateForm, ) from .models import CocRecord -from reviews.context import proposals_state, reviews_state - -from lxml import etree -import lxml.html - User = auth.get_user_model() From 25257fdb69a900ff669283e9d231b6387e64ab0f Mon Sep 17 00:00:00 2001 From: Matt Wang Date: Tue, 9 Apr 2024 17:53:17 +0800 Subject: [PATCH 4/8] lint: introduce pep-naming (with ruff) --- pyproject.toml | 1 + src/ccip/views.py | 6 +++--- src/core/utils.py | 2 +- src/events/api/views.py | 4 ++-- src/events/management/commands/import_events.py | 4 ++-- src/events/renderers.py | 4 ++-- src/proposals/management/commands/export_proposals.py | 8 ++++---- .../management/commands/export_proposals_create_time.py | 4 ++-- 8 files changed, 17 insertions(+), 16 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f84418726..09f715183 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -64,6 +64,7 @@ select = [ "W", # pycodestyle warning "F", # Pyflakes "I001", # isort + "N", # pep8-naming ] [tool.ruff.lint.isort] diff --git a/src/ccip/views.py b/src/ccip/views.py index 1c9a05fe2..18163fc43 100644 --- a/src/ccip/views.py +++ b/src/ccip/views.py @@ -169,15 +169,15 @@ def _transform_session(request, event, type_key, info_getter): for speaker in event_info.speakers ] - LOCAL_TIMEZONE = timezone(offset=timedelta(hours=8)) + local_timezone = timezone(offset=timedelta(hours=8)) # Explicitly show the local timezone used by OPass(CCIP) # to avoid iOS device showing UTC+0 time without changing it to local time # https://github.com/CCIP-App/CCIP-iOS/issues/54 session = { 'id': f'{type_key}-{event_info.pk}', 'type': type_key, - 'start': event.begin_time.value.astimezone(LOCAL_TIMEZONE).isoformat() if event.begin_time else None, - 'end': event.end_time.value.astimezone(LOCAL_TIMEZONE).isoformat() if event.end_time else None, + 'start': event.begin_time.value.astimezone(local_timezone).isoformat() if event.begin_time else None, + 'end': event.end_time.value.astimezone(local_timezone).isoformat() if event.end_time else None, 'slide': event_info.slide_link, 'speakers': [speaker['id'] for speaker in speakers], 'tags': [tag['id'] for tag in tags], diff --git a/src/core/utils.py b/src/core/utils.py index 664a2b4a8..04e255b7f 100644 --- a/src/core/utils.py +++ b/src/core/utils.py @@ -122,7 +122,7 @@ def __missing__(self, key): return self[key] -class set_registry(override_settings): +class set_registry(override_settings): # noqa: N801 def enable(self): for key, value in self.options.items(): reg[f'{settings.CONFERENCE_DEFAULT_SLUG}.{key}'] = value diff --git a/src/events/api/views.py b/src/events/api/views.py index 0333fb6a2..eabb50b84 100644 --- a/src/events/api/views.py +++ b/src/events/api/views.py @@ -150,14 +150,14 @@ def event_id(self) -> int: @property def event_type(self) -> str: - TYPE_MAP = { + type_map = { CustomEvent: 'custom', KeynoteEvent: 'keynote', ProposedTalkEvent: 'talk', SponsoredEvent: 'sponsored', ProposedTutorialEvent: 'tutorial', } - return TYPE_MAP[type(self.obj)] + return type_map[type(self.obj)] @property def title(self) -> Union[str, dict]: diff --git a/src/events/management/commands/import_events.py b/src/events/management/commands/import_events.py index 97d79e131..527d6288a 100644 --- a/src/events/management/commands/import_events.py +++ b/src/events/management/commands/import_events.py @@ -47,8 +47,8 @@ def add_arguments(self, parser): def handle(self, *args, filename, truncate=False, **options): if truncate: - for Cls in EVENT_CLASSES: - Cls.objects.all().delete() + for kls in EVENT_CLASSES: + kls.objects.all().delete() with open(filename) as f: data = json.load(f) for model_name, datasets in data.items(): diff --git a/src/events/renderers.py b/src/events/renderers.py index 01db08b40..20022d803 100644 --- a/src/events/renderers.py +++ b/src/events/renderers.py @@ -347,9 +347,9 @@ def collect_event_groups(events): EVENT_CLASSES = (CustomEvent, KeynoteEvent, ProposedTalkEvent, SponsoredEvent) -def _filter_events(Cls, day): +def _filter_events(kls, day): return ( - Cls.objects + kls.objects .filter(begin_time__value__date=day, end_time__value__date=day) .select_related('begin_time', 'end_time') ) diff --git a/src/proposals/management/commands/export_proposals.py b/src/proposals/management/commands/export_proposals.py index 28480c7e9..4f7e8ce53 100644 --- a/src/proposals/management/commands/export_proposals.py +++ b/src/proposals/management/commands/export_proposals.py @@ -15,14 +15,14 @@ class Command(BaseCommand): def handle(self, *args, **options): joint_proposals = {} - for ptype, Proposal in PROPOSAL_TYPE_MAPPING.items(): - joint_proposals[ptype] = self.export_proposals(Proposal) + for ptype, proposal_class in PROPOSAL_TYPE_MAPPING.items(): + joint_proposals[ptype] = self.export_proposals(proposal_class) json_str = json.dumps(joint_proposals, cls=DjangoJSONEncoder) self.stdout.write(json_str) - def export_proposals(self, Proposal): - proposals = Proposal.objects.filter( + def export_proposals(self, proposal_class): + proposals = proposal_class.objects.filter( cancelled=False ).select_related( 'submitter__email', diff --git a/src/proposals/management/commands/export_proposals_create_time.py b/src/proposals/management/commands/export_proposals_create_time.py index 5320513e8..5680ffc7a 100644 --- a/src/proposals/management/commands/export_proposals_create_time.py +++ b/src/proposals/management/commands/export_proposals_create_time.py @@ -19,8 +19,8 @@ def handle(self, *args, **options): def export_proposals_create_time(self): joint_proposals = [] - for ptype, Proposal in PROPOSAL_TYPE_MAPPING.items(): - for p in Proposal.objects.filter(cancelled=False): + for ptype, proposal_class in PROPOSAL_TYPE_MAPPING.items(): + for p in proposal_class.objects.filter(cancelled=False): timezone.activate(pytz.timezone('Asia/Taipei')) # ^you can edit 'Asia/Taipei to other area.' time = timezone.localtime(p.created_at).strftime('%Y-%m-%d %H:%M:%S') From 9f99a27489a9ca1e86a3f294493477e1218c057a Mon Sep 17 00:00:00 2001 From: Matt Wang Date: Tue, 9 Apr 2024 18:11:16 +0800 Subject: [PATCH 5/8] lint: introduce bugbear (with ruff) --- pyproject.toml | 1 + src/ccip/views.py | 4 ++-- src/core/utils.py | 6 +++--- src/core/views.py | 4 ++-- src/events/api/serializers.py | 4 ++-- src/events/renderers.py | 4 ++-- src/events/templatetags/events.py | 4 ++-- src/events/tests/test_management.py | 2 +- src/events/views.py | 2 +- src/proposals/forms/speakers.py | 8 ++++---- src/proposals/views/speakers.py | 4 ++-- src/reviews/views.py | 4 ++-- src/users/models.py | 4 ++-- src/users/views.py | 4 ++-- 14 files changed, 28 insertions(+), 27 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 09f715183..e1cfa741c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,6 +65,7 @@ select = [ "F", # Pyflakes "I001", # isort "N", # pep8-naming + "B", # bugbear ] [tool.ruff.lint.isort] diff --git a/src/ccip/views.py b/src/ccip/views.py index 18163fc43..6fea89f7f 100644 --- a/src/ccip/views.py +++ b/src/ccip/views.py @@ -45,8 +45,8 @@ def _iter_translations(value): def _transform_translatable(key, value): data = {'id': key} - for code, value in _iter_translations(value): - data[code] = {'name': value} + for code, val in _iter_translations(value): + data[code] = {'name': val} return data diff --git a/src/core/utils.py b/src/core/utils.py index 04e255b7f..c98936121 100644 --- a/src/core/utils.py +++ b/src/core/utils.py @@ -29,10 +29,10 @@ class TemplateExistanceStatusResponse(TemplateResponse): def resolve_template(self, template): try: return super().resolve_template(template) - except (UnicodeEncodeError, TemplateDoesNotExist): + except (UnicodeEncodeError, TemplateDoesNotExist) as err: if settings.DEBUG: raise - raise Http404 + raise Http404 from err def collect_language_codes(user_code): @@ -128,5 +128,5 @@ def enable(self): reg[f'{settings.CONFERENCE_DEFAULT_SLUG}.{key}'] = value def disable(self): - for key, value in self.options.items(): + for key in self.options.keys(): del reg[f'{settings.CONFERENCE_DEFAULT_SLUG}.{key}'] diff --git a/src/core/views.py b/src/core/views.py index 03894ed5d..19fbb43ab 100644 --- a/src/core/views.py +++ b/src/core/views.py @@ -81,6 +81,6 @@ def error_page(request, code): '404': functools.partial(page_not_found, exception=Http404()), '500': server_error, }[code] - except KeyError: - raise Http404 + except KeyError as err: + raise Http404 from err return view_func(request) diff --git a/src/events/api/serializers.py b/src/events/api/serializers.py index 8fb4fbbf1..7ee99b7bc 100644 --- a/src/events/api/serializers.py +++ b/src/events/api/serializers.py @@ -35,7 +35,7 @@ def format_speakers_data(request, speakers, show_details=True): return formatted -def flatten_proposal_field(representation, allow_fields=[]): +def flatten_proposal_field(representation, allow_fields=None): """ The helper function that used in `to_representation()` for flattening the `proposal` object from serialized @@ -43,7 +43,7 @@ def flatten_proposal_field(representation, allow_fields=[]): """ proposal_repr = representation.pop('proposal') for key in proposal_repr: - if key in allow_fields or not allow_fields: + if not allow_fields or key in allow_fields: representation[key] = proposal_repr[key] return representation diff --git a/src/events/renderers.py b/src/events/renderers.py index 20022d803..d5ad70e58 100644 --- a/src/events/renderers.py +++ b/src/events/renderers.py @@ -82,10 +82,10 @@ def render_event(e): func_name = 'render_{cls}'.format(cls=type(e).__name__.lower()) try: func = globals()[func_name] - except KeyError: + except KeyError as err: raise ValueError( 'No suitable renderer for {!r} of {!r}'.format(e, type(e)), - ) + ) from err return func(e) diff --git a/src/events/templatetags/events.py b/src/events/templatetags/events.py index 5e3d8c1ab..f8d2919a5 100644 --- a/src/events/templatetags/events.py +++ b/src/events/templatetags/events.py @@ -53,7 +53,7 @@ def gen_timeline(start, end): time_next = time_start row_start_next = 1 row_end_next = 6 - for i in range(ticks_count): + for __ in range(ticks_count): time_next += timedelta(seconds=MARKER_UNIT) row_start_next += scale_unit_multiplier row_end_next += scale_unit_multiplier @@ -86,7 +86,7 @@ def event_cell_class(event): @register.filter def event_tr_class(slot_info): - for room, event in slot_info: + for __, event in slot_info: if event._meta.label_lower == 'events.customevent': return 'custom' return '' diff --git a/src/events/tests/test_management.py b/src/events/tests/test_management.py index fb98a2b08..59802dba8 100644 --- a/src/events/tests/test_management.py +++ b/src/events/tests/test_management.py @@ -24,7 +24,7 @@ def keynote_event_json(): class MockFile(unittest.mock.MagicMock): def __init__(self, *args, **kwargs): - super().__init__(spec=io.FileIO, *args, **kwargs) + super().__init__(*args, spec=io.FileIO, **kwargs) class MockOpen(unittest.mock.Mock): diff --git a/src/events/views.py b/src/events/views.py index bf4b2ff21..255ef6aa8 100644 --- a/src/events/views.py +++ b/src/events/views.py @@ -186,7 +186,7 @@ def get_day_grouped_events(self): end_time_iter = iter(times) next(end_time_iter, None) - for begin, end in zip(times, end_time_iter): + for begin, __ in zip(times, end_time_iter): try: day_info = day_info_dict[begin.value.date()] except KeyError: diff --git a/src/proposals/forms/speakers.py b/src/proposals/forms/speakers.py index 157efc23e..1ac6e8835 100644 --- a/src/proposals/forms/speakers.py +++ b/src/proposals/forms/speakers.py @@ -44,8 +44,8 @@ class Meta: model = AdditionalSpeaker fields = [] - def __init__(self, proposal=None, request=None, *args, **kwargs): - super().__init__(request=request, *args, **kwargs) + def __init__(self, *args, proposal=None, request=None, **kwargs): + super().__init__(*args, request=request, **kwargs) if form_has_instance(self): raise ValueError( 'Additional speaker creation form cannot be used ' @@ -69,8 +69,8 @@ def clean_email(self): email = self.cleaned_data['email'] try: user = User.objects.get_valid_speakers().get(email=email) - except User.DoesNotExist: - raise forms.ValidationError(self.get_error_message('invalid_user')) + except User.DoesNotExist as err: + raise forms.ValidationError(self.get_error_message('invalid_user')) from err # The rest of the validation is ordered this way to minimize queries # on valid data. diff --git a/src/proposals/views/speakers.py b/src/proposals/views/speakers.py index 2f6ff952f..8c4b4aa08 100644 --- a/src/proposals/views/speakers.py +++ b/src/proposals/views/speakers.py @@ -33,8 +33,8 @@ def get_proposal(self): cancelled=False, ) ) - except self.proposal_model.DoesNotExist: - raise Http404 + except self.proposal_model.DoesNotExist as err: + raise Http404 from err return proposal def get(self, request, *args, **kwargs): diff --git a/src/reviews/views.py b/src/reviews/views.py index cc3ab316f..6e0ea7534 100644 --- a/src/reviews/views.py +++ b/src/reviews/views.py @@ -214,8 +214,8 @@ def get_proposal(self): .filter_reviewable(self.request.user) .get(pk=self.kwargs['proposal_pk']) ) - except self.proposal_model.DoesNotExist: - raise Http404 + except self.proposal_model.DoesNotExist as err: + raise Http404 from err return proposal def get_snapshot(self, proposal): diff --git a/src/users/models.py b/src/users/models.py index 2c0c398e7..b9865c4c4 100644 --- a/src/users/models.py +++ b/src/users/models.py @@ -97,8 +97,8 @@ def get_with_verification_key(self, verification_key): verification_key, salt=settings.SECRET_KEY, ) - except signing.BadSignature: - raise self.model.DoesNotExist + except signing.BadSignature as err: + raise self.model.DoesNotExist from err return self.get(**{self.model.USERNAME_FIELD: username}) diff --git a/src/users/views.py b/src/users/views.py index fe6825bfa..24415ac66 100644 --- a/src/users/views.py +++ b/src/users/views.py @@ -54,8 +54,8 @@ def user_signup(request): def user_verify(request, verification_key): try: user = User.objects.get_with_verification_key(verification_key) - except User.DoesNotExist: - raise Http404 + except User.DoesNotExist as err: + raise Http404 from err user.verified = True user.save() messages.success(request, gettext('Email verification successful.')) From f84b6d3a47add83d9abb8c7c674ba4461baa439d Mon Sep 17 00:00:00 2001 From: Matt Wang Date: Tue, 9 Apr 2024 18:44:17 +0800 Subject: [PATCH 6/8] lint: introduce pyupgrade (with ruff) --- pyproject.toml | 1 + src/ccip/views.py | 3 +-- src/core/context_processors.py | 2 +- src/core/difftools.py | 4 +-- src/core/models.py | 2 +- src/core/tests/test_views.py | 4 +-- src/core/utils.py | 2 +- src/events/admin.py | 8 +++--- src/events/models.py | 7 ++--- src/events/renderers.py | 4 +-- .../tests/renderers/test_render_block.py | 6 ++--- src/events/tests/test_views.py | 4 +-- src/events/views.py | 2 +- .../commands/export_proposals_create_time.py | 2 +- .../management/commands/recent_proposals.py | 27 +++++++------------ src/proposals/models.py | 10 +++---- src/proposals/tests/test_management.py | 2 +- src/proposals/tests/views/test_create.py | 4 +-- src/proposals/tests/views/test_speakers.py | 2 +- src/proposals/utils.py | 2 +- src/proposals/views/mixins.py | 3 ++- src/pycontw2016/logger.py | 4 +-- src/sponsors/models.py | 5 +--- src/sponsors/templatetags/sponsors.py | 2 +- src/users/models.py | 10 +++---- src/users/tests/test_views_signup.py | 2 +- 26 files changed, 51 insertions(+), 73 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e1cfa741c..8ea6e44fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -66,6 +66,7 @@ select = [ "I001", # isort "N", # pep8-naming "B", # bugbear + "UP", # pyupgrade ] [tool.ruff.lint.isort] diff --git a/src/ccip/views.py b/src/ccip/views.py index 6fea89f7f..c11d4fd50 100644 --- a/src/ccip/views.py +++ b/src/ccip/views.py @@ -77,8 +77,7 @@ def __bool__(self): @property def speakers(self): - for s in self._speakers: - yield s + yield from self._speakers def _get_empty_event_info(event): diff --git a/src/core/context_processors.py b/src/core/context_processors.py index 5cff9e7d0..8c69cf1ff 100644 --- a/src/core/context_processors.py +++ b/src/core/context_processors.py @@ -9,7 +9,7 @@ def _build_google_form_url(uid): - return 'https://docs.google.com/forms/d/e/{uid}/viewform'.format(uid=uid) + return f'https://docs.google.com/forms/d/e/{uid}/viewform' def script_prefix(request): diff --git a/src/core/difftools.py b/src/core/difftools.py index a1e70a396..f3b2ca8d9 100644 --- a/src/core/difftools.py +++ b/src/core/difftools.py @@ -91,12 +91,12 @@ def dump_equal(a, b, loa, lob, hia, hib): def dump_delete(a, b, loa, lob, hia, hib): for line in a[loa:hia]: - yield mark_safe('{}'.format(conditional_escape(line))) + yield mark_safe(f'{conditional_escape(line)}') def dump_insert(a, b, loa, lob, hia, hib): for line in b[lob:hib]: - yield mark_safe('{}'.format(conditional_escape(line))) + yield mark_safe(f'{conditional_escape(line)}') BLOCK_HANDLERS = { diff --git a/src/core/models.py b/src/core/models.py index bbc833ab8..3e1f6267b 100644 --- a/src/core/models.py +++ b/src/core/models.py @@ -224,7 +224,7 @@ class Meta: def save(self, *args, **kwargs): if not self.key: self.key = self.generate_key() - return super(Token, self).save(*args, **kwargs) + return super().save(*args, **kwargs) @classmethod def generate_key(cls): diff --git a/src/core/tests/test_views.py b/src/core/tests/test_views.py index 4d808cb08..16f148970 100644 --- a/src/core/tests/test_views.py +++ b/src/core/tests/test_views.py @@ -89,7 +89,7 @@ def activate_default_language(): @pytest.fixture def content_page_full_path(language, content_page_path): - return '/{}{}'.format(language, content_page_path) + return f'/{language}{content_page_path}' def test_content_pages(client, parser, content_page_full_path): @@ -162,7 +162,7 @@ def get_link_safty_pair(tag): def get_error_message(): errors = [ - ' {0!r}'.format(*p) + f' {p[0]!r}' for p in link_noopener_pairs if p[1] is not True ] diff --git a/src/core/utils.py b/src/core/utils.py index c98936121..d9aef386d 100644 --- a/src/core/utils.py +++ b/src/core/utils.py @@ -81,7 +81,7 @@ def __init__(self, seq): self._seq = seq def __repr__(self): - return ''.format(seq=self._seq) + return f'' def __len__(self): return len(self._seq) diff --git a/src/events/admin.py b/src/events/admin.py index 3acb18aee..f5ba89006 100644 --- a/src/events/admin.py +++ b/src/events/admin.py @@ -35,13 +35,13 @@ class TimeRangeFilter(admin.SimpleListFilter): title = _('time value') parameter_name = 'time-range' day_queries = { - 'day{}'.format(i): Q(value__date=date) + f'day{i}': Q(value__date=date) for i, date in enumerate(settings.EVENTS_DAY_NAMES, 1) } def lookups(self, request, model_admin): return [ - ('day{}'.format(i), name) + (f'day{i}', name) for i, name in enumerate(settings.EVENTS_DAY_NAMES.values(), 1) ] @@ -84,13 +84,13 @@ def get_minute(self, instance): class EventTimeRangeFilter(admin.SimpleListFilter): filter_kwargs_dict = { - 'day{}'.format(i): day + f'day{i}': day for i, day in enumerate(settings.EVENTS_DAY_NAMES, 1) } def lookups(self, request, model_admin): return [ - ('day{}'.format(i), name) + (f'day{i}', name) for i, name in enumerate(settings.EVENTS_DAY_NAMES.values(), 1) ] diff --git a/src/events/models.py b/src/events/models.py index 110f1ae66..d5b0229d4 100644 --- a/src/events/models.py +++ b/src/events/models.py @@ -44,10 +44,7 @@ def select_storage(): def photo_upload_to(instance, filename): - return 'speaker/{speakername}/{filename}'.format( - speakername=slugify(instance.speaker_name, allow_unicode=True), - filename=filename, - ) + return f'speaker/{slugify(instance.speaker_name, allow_unicode=True)}/{filename}' class TimeManager(models.Manager): @@ -302,7 +299,7 @@ def __str__(self): def get_absolute_url(self): url = reverse('page', kwargs={'path': 'conference/keynotes'}) split = urllib.parse.urlsplit(url) - frag = 'keynote-speaker-{slug}'.format(slug=self.slug) + frag = f'keynote-speaker-{self.slug}' return urllib.parse.urlunsplit(split._replace(fragment=frag)) def get_static_data(self): diff --git a/src/events/renderers.py b/src/events/renderers.py index d5ad70e58..f72cce981 100644 --- a/src/events/renderers.py +++ b/src/events/renderers.py @@ -79,12 +79,12 @@ def render_sponsoredevent(e): def render_event(e): - func_name = 'render_{cls}'.format(cls=type(e).__name__.lower()) + func_name = f'render_{type(e).__name__.lower()}' try: func = globals()[func_name] except KeyError as err: raise ValueError( - 'No suitable renderer for {!r} of {!r}'.format(e, type(e)), + f'No suitable renderer for {e!r} of {type(e)!r}', ) from err return func(e) diff --git a/src/events/tests/renderers/test_render_block.py b/src/events/tests/renderers/test_render_block.py index dde9a322b..cfbacccdd 100644 --- a/src/events/tests/renderers/test_render_block.py +++ b/src/events/tests/renderers/test_render_block.py @@ -9,7 +9,7 @@ def simple_component_renderer(mocker): mocker.patch.multiple( 'events.renderers', render_event=str, - render_block_location=lambda v: '{} '.format(v), + render_block_location=lambda v: f'{v} ', ) @@ -108,9 +108,7 @@ def test_render_attached_period(utils, events, event_key, begin, end): rendered = renderers.render_attached_period(e.begin_time, e.end_time) assert utils.is_safe(rendered) assert rendered == ( - '
{} – {}
'.format( - begin, end, - ) + f'
{begin} – {end}
' ) diff --git a/src/events/tests/test_views.py b/src/events/tests/test_views.py index 42d4e3643..4eed11f08 100644 --- a/src/events/tests/test_views.py +++ b/src/events/tests/test_views.py @@ -17,7 +17,7 @@ def test_talk_list(client, accepted_talk_proposal, sponsored_block_event): ) @pytest.mark.parametrize('pk,status', [(42, 200), (9, 404)]) def test_talk_detail(client, accepted_talk_proposal, pk, status): - r = client.get('/en-us/events/talk/{pk}/'.format(pk=pk)) + r = client.get(f'/en-us/events/talk/{pk}/') assert r.status_code == status @@ -30,5 +30,5 @@ def test_talk_detail(client, accepted_talk_proposal, pk, status): ('carmona-eugene', 404), ]) def test_sponsored_event_detail(client, sponsored_block_event, slug, status): - r = client.get('/en-us/events/talk/sponsored/{slug}/'.format(slug=slug)) + r = client.get(f'/en-us/events/talk/sponsored/{slug}/') assert r.status_code == status diff --git a/src/events/views.py b/src/events/views.py index 255ef6aa8..dc4f5ed7a 100644 --- a/src/events/views.py +++ b/src/events/views.py @@ -190,7 +190,7 @@ def get_day_grouped_events(self): try: day_info = day_info_dict[begin.value.date()] except KeyError: - logger.warn('Invalid time sot dropped: {}'.format(begin)) + logger.warn(f'Invalid time sot dropped: {begin}') continue for event in begin_time_event_dict[begin]: location = event.location diff --git a/src/proposals/management/commands/export_proposals_create_time.py b/src/proposals/management/commands/export_proposals_create_time.py index 5680ffc7a..b9c3c521d 100644 --- a/src/proposals/management/commands/export_proposals_create_time.py +++ b/src/proposals/management/commands/export_proposals_create_time.py @@ -25,7 +25,7 @@ def export_proposals_create_time(self): # ^you can edit 'Asia/Taipei to other area.' time = timezone.localtime(p.created_at).strftime('%Y-%m-%d %H:%M:%S') joint_proposals.append({ - 'proposal_type(id)': ptype + '({})'.format(p.id), + 'proposal_type(id)': ptype + f'({p.id})', 'title': p.title, 'speaker_name': p.submitter.speaker_name, 'email': p.submitter.email, diff --git a/src/proposals/management/commands/recent_proposals.py b/src/proposals/management/commands/recent_proposals.py index 84709e9f7..c18b134b1 100644 --- a/src/proposals/management/commands/recent_proposals.py +++ b/src/proposals/management/commands/recent_proposals.py @@ -99,15 +99,11 @@ def handle(self, *args, **options): else: self.summary(recent_talks, recent_tutorials) self.msg.write( - '\n\nGot total {:d} new proposals.\n'.format( - recent_talks.count() + recent_tutorials.count() - )) + f'\n\nGot total {recent_talks.count() + recent_tutorials.count():d} new proposals.\n') + talk_count = TalkProposal.objects.filter(cancelled=False).count() + tutorial_count = TutorialProposal.objects.filter(cancelled=False).count() self.msg.write( - 'So far {:d} talk and {:d} tutorial proposals have been submitted.' - .format( - TalkProposal.objects.filter(cancelled=False).count(), - TutorialProposal.objects.filter(cancelled=False).count() - ) + f'So far {talk_count:d} talk and {tutorial_count:d} tutorial proposals have been submitted.' ) self.report(start_dt, end_dt, options['mailto'], options['slack']) self.msg.close() # close the StringIO @@ -126,8 +122,7 @@ def report(self, start_dt, end_dt, mailto=None, slack=False): """Report to either the stdout or mailing to some address""" self.stdout.write(self.msg.getvalue()) title = ( - 'Proposal submission summary from {:%m/%d} to {:%m/%d}' - .format(start_dt, end_dt) + f'Proposal submission summary from {start_dt:%m/%d} to {end_dt:%m/%d}' ) if mailto: subject = '[PyConTW2016][Program] %s' % title @@ -145,7 +140,7 @@ def report(self, start_dt, end_dt, mailto=None, slack=False): # Create the Slack client and send message slack = Slack(url=settings.SLACK_WEBHOOK_URL) status, msg = slack.notify( - text='*%s*\n```\n%s\n```' % (title, self.msg.getvalue()) + text=f'*{title}*\n```\n{self.msg.getvalue()}\n```' ) if status != 200: self.stderr.write(self.style.ERROR( @@ -175,15 +170,13 @@ def create_datetime_range_lookup(self, recent_days, day_shift_hour): ) from e if today_dt > today_utc_dt: raise CommandError( - "Today's datetime {:%Y-%m-%d %H:%M} ({!s}) is yet present" - .format(today_dt, taiwan_tz) + f"Today's datetime {today_dt:%Y-%m-%d %H:%M} ({taiwan_tz!s}) is yet present" ) earliest_dt = today_dt - timedelta(days=recent_days) self.msg.write( - 'Proposals submitted during the recent {:d} days\n' - 'From {:%Y-%m-%d %H:%M} to {:%Y-%m-%d %H:%M}\n' - '(Timezone: {!s})\n\n' - .format(recent_days, earliest_dt, today_dt, taiwan_tz) + f'Proposals submitted during the recent {recent_days:d} days\n' + f'From {earliest_dt:%Y-%m-%d %H:%M} to {today_dt:%Y-%m-%d %H:%M}\n' + f'(Timezone: {taiwan_tz!s})\n\n' ) recent_lookup = Q( created_at__gte=earliest_dt, diff --git a/src/proposals/models.py b/src/proposals/models.py index dfe5cc77e..c100df23f 100644 --- a/src/proposals/models.py +++ b/src/proposals/models.py @@ -35,7 +35,7 @@ def __init__(self, *, proposal=None, user=None): self._user = user or proposal.submitter def __repr__(self): - return ''.format(name=self.user.speaker_name) + return f'' def __eq__(self, other): return ( @@ -105,10 +105,7 @@ class Meta: verbose_name_plural = _('additional speakers') def __str__(self): - return '{name} ({status})'.format( - name=self.user.speaker_name, - status=self.get_status_display(), - ) + return f'{self.user.speaker_name} ({self.get_status_display()})' class ProposalQuerySet(models.QuerySet): @@ -231,8 +228,7 @@ def speakers(self): .select_related('user') ) - for speaker in additionals: - yield speaker + yield from additionals @property def speaker_count(self): diff --git a/src/proposals/tests/test_management.py b/src/proposals/tests/test_management.py index a7dd614af..e6a209b43 100644 --- a/src/proposals/tests/test_management.py +++ b/src/proposals/tests/test_management.py @@ -255,7 +255,7 @@ def test_default_hour_option(capsys): call_command('recent_proposals') out, err = capsys.readouterr() assert re.search( - r'to {:%Y-%m-%d %H}:00$'.format(now_dt), + rf'to {now_dt:%Y-%m-%d %H}:00$', out, re.MULTILINE ) diff --git a/src/proposals/tests/views/test_create.py b/src/proposals/tests/views/test_create.py index 0c1781e61..46d74f1e6 100644 --- a/src/proposals/tests/views/test_create.py +++ b/src/proposals/tests/views/test_create.py @@ -105,7 +105,7 @@ def test_talk_proposal_create_post(agreed_user, agreed_user_client): title='Beyond the Style Guides
', ) assert response.redirect_chain == [ - ('/en-us/proposals/talk/{pk}/edit/'.format(pk=proposal.pk), 302), + (f'/en-us/proposals/talk/{proposal.pk}/edit/', 302), ], response.context['form'].errors msgs = [(m.level, m.message) for m in response.context['messages']] @@ -135,7 +135,7 @@ def test_tutorial_proposal_create_post(agreed_user, agreed_user_client): title='Beyond the Style Guides
', ) assert response.redirect_chain == [ - ('/en-us/proposals/tutorial/{pk}/edit/'.format(pk=proposal.pk), 302), + (f'/en-us/proposals/tutorial/{proposal.pk}/edit/', 302), ], response.context['form'].errors msgs = [(m.level, m.message) for m in response.context['messages']] diff --git a/src/proposals/tests/views/test_speakers.py b/src/proposals/tests/views/test_speakers.py index b82d0b5f4..b697ccd20 100644 --- a/src/proposals/tests/views/test_speakers.py +++ b/src/proposals/tests/views/test_speakers.py @@ -160,7 +160,7 @@ def test_remove_speaker_post(user_client, proposal_type, additional_speaker): follow=True, ) assert response.redirect_chain == [ - ('/en-us/proposals/{}/42/manage-speakers/'.format(proposal_type), 302), + (f'/en-us/proposals/{proposal_type}/42/manage-speakers/', 302), ] diff --git a/src/proposals/utils.py b/src/proposals/utils.py index bb2e2d818..bfa31f4c2 100644 --- a/src/proposals/utils.py +++ b/src/proposals/utils.py @@ -8,4 +8,4 @@ def format_names(names, sep_default=SEP_DEFAULT, sep_last=SEP_LAST): assert names if len(names) == 1: return names[0] - return '{}{}{}'.format(sep_default.join(names[:-1]), sep_last, names[-1]) + return f'{sep_default.join(names[:-1])}{sep_last}{names[-1]}' diff --git a/src/proposals/views/mixins.py b/src/proposals/views/mixins.py index 6e2348345..1df149f69 100644 --- a/src/proposals/views/mixins.py +++ b/src/proposals/views/mixins.py @@ -32,7 +32,8 @@ def dispatch(self, request, *args, **kwargs): class CocAgreementMixin: def dispatch(self, request, *args, **kwargs): if not self.request.user.has_agreed_coc: - return redirect('%s?next=%s' % (reverse('coc_agreement'), request.path)) + url = reverse('coc_agreement') + return redirect(f'{url}?next={request.path}') return super().dispatch(request, *args, **kwargs) diff --git a/src/pycontw2016/logger.py b/src/pycontw2016/logger.py index 20e1bb982..0aa999d68 100644 --- a/src/pycontw2016/logger.py +++ b/src/pycontw2016/logger.py @@ -17,7 +17,7 @@ import logging -class NewStyleLogMessage(object): +class NewStyleLogMessage: def __init__(self, message, *args, **kwargs): self.message = message self.args = args @@ -36,7 +36,7 @@ def __str__(self): class StyleAdapter(logging.LoggerAdapter): def __init__(self, logger, extra=None): - super(StyleAdapter, self).__init__(logger, extra or {}) + super().__init__(logger, extra or {}) def log(self, level, msg, *args, **kwargs): if self.isEnabledFor(level): diff --git a/src/sponsors/models.py b/src/sponsors/models.py index 6d9525563..c339cdcca 100644 --- a/src/sponsors/models.py +++ b/src/sponsors/models.py @@ -14,10 +14,7 @@ def select_storage(): def logo_upload_to(instance, filename): - return 'sponsors/{name}/{filename}'.format( - name=slugify(instance.name, allow_unicode=True), - filename=filename, - ) + return f'sponsors/{slugify(instance.name, allow_unicode=True)}/{filename}' class Sponsor(ConferenceRelated): diff --git a/src/sponsors/templatetags/sponsors.py b/src/sponsors/templatetags/sponsors.py index d8dbafb6d..4a2de2c26 100644 --- a/src/sponsors/templatetags/sponsors.py +++ b/src/sponsors/templatetags/sponsors.py @@ -14,7 +14,7 @@ def sponsor_jsonize(sponsors): sponsor_lists = {level: [] for level, _ in Sponsor.LEVEL_CHOICES} sponsor_info_dict = collections.OrderedDict( - ('level-{}'.format(level), { + (f'level-{level}', { 'name': name, 'sponsors': sponsor_lists[level], }) diff --git a/src/users/models.py b/src/users/models.py index b9865c4c4..3097900c4 100644 --- a/src/users/models.py +++ b/src/users/models.py @@ -103,11 +103,7 @@ def get_with_verification_key(self, verification_key): def photo_upload_to(instance, filename): - return 'avatars/{pk}/{date}-{filename}'.format( - pk=instance.pk, - date=str(datetime.date.today()), - filename=filename, - ) + return f'avatars/{instance.pk}/{str(datetime.date.today())}-{filename}' class User(AbstractBaseUser, PermissionsMixin): @@ -261,13 +257,13 @@ def cospeaking_info_set(self): def twitter_profile_url(self): if not self.twitter_id: return "" - return 'https://twitter.com/{}'.format(self.twitter_id) + return f'https://twitter.com/{self.twitter_id}' @property def github_profile_url(self): if not self.github_id: return "" - return 'https://github.com/{}'.format(self.github_id) + return f'https://github.com/{self.github_id}' def get_verification_key(self): key = signing.dumps( diff --git a/src/users/tests/test_views_signup.py b/src/users/tests/test_views_signup.py index 213932f5b..42f8c5a02 100644 --- a/src/users/tests/test_views_signup.py +++ b/src/users/tests/test_views_signup.py @@ -70,7 +70,7 @@ def test_verify(bare_user, bare_user_client): message, and redirected to dashboard. """ key = bare_user.get_verification_key() - link = '/en-us/accounts/verify/{key}/'.format(key=key) + link = f'/en-us/accounts/verify/{key}/' response = bare_user_client.get(link, follow=True) assert response.redirect_chain[0] == ('/en-us/dashboard/', 302) From 5472c9f873b68dd9ce73cc87755007514a2dfb5c Mon Sep 17 00:00:00 2001 From: Matt Wang Date: Sat, 13 Apr 2024 18:16:16 +0800 Subject: [PATCH 7/8] chore: add .git-blame-ignore-revs --- .git-blame-ignore-revs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..22d23217f --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,11 @@ +################# +# Linting +################# +# isort +0dcb6dd5973796cf12be34fdfd9fa761a6ba22d9 +# pep-naming +ef09dbe9a03ebf4f649fd8830224a6c93ab422e7 +# bugbear +e1dad3a0ca41d3f312f5be423711f577fd804f2f +# pyupgrade +399a7d64ddc2c2c857670c69890c24de8ba98610 From fca6fd240b0ea48b397e23eb0b4c5045c0a28c90 Mon Sep 17 00:00:00 2001 From: Matt Wang Date: Sat, 13 Apr 2024 19:51:13 +0800 Subject: [PATCH 8/8] chore: add instruction to .git-blame-ignore-revs --- .git-blame-ignore-revs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 22d23217f..65a2a973f 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,11 +1,10 @@ -################# -# Linting -################# -# isort -0dcb6dd5973796cf12be34fdfd9fa761a6ba22d9 -# pep-naming -ef09dbe9a03ebf4f649fd8830224a6c93ab422e7 -# bugbear -e1dad3a0ca41d3f312f5be423711f577fd804f2f -# pyupgrade -399a7d64ddc2c2c857670c69890c24de8ba98610 +# When making commits that are strictly formatting/style changes, add the +# commit hash here, so git blame can ignore the change. +# +# For more details, see: +# https://git-scm.com/docs/git-config#Documentation/git-config.txt-blameignoreRevsFile + +0dcb6dd5973796cf12be34fdfd9fa761a6ba22d9 # isort +ef09dbe9a03ebf4f649fd8830224a6c93ab422e7 # pep-naming +e1dad3a0ca41d3f312f5be423711f577fd804f2f # bugbear +399a7d64ddc2c2c857670c69890c24de8ba98610 # pyupgrade