Fix linter problems
- Fix ruff check warnings - Fix mypy warnings - Move mypy config from setup.cfg to pyproject.toml and update it Fixes: #306 Assisted-by: Claude Code Co-authored-by: Kamil Páral <kparal@redhat.com>
This commit is contained in:
parent
de4c2ba778
commit
f79993230f
23 changed files with 56 additions and 68 deletions
|
|
@ -516,6 +516,4 @@ def main() -> None:
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit = main()
|
||||
if exit:
|
||||
sys.exit(exit)
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
import logging
|
||||
|
||||
from flask import flash, request, redirect, url_for
|
||||
from flask import flash
|
||||
from flask_admin.babel import gettext
|
||||
import flask_admin
|
||||
from blockerbugs import app, db
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ class ChoicesValidator(BaseValidator):
|
|||
super(ChoicesValidator, self).configure(args, kwargs)
|
||||
|
||||
def _check_data(self):
|
||||
if not self.raw_data in self.choices:
|
||||
if self.raw_data not in self.choices:
|
||||
raise ValidationError("%s must be one of %s" % (self.name, str(self.choices)))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ def get_milestone_updates(milestone: Milestone) -> list[Update]:
|
|||
.filter(
|
||||
Bug.milestone == milestone,
|
||||
Bug.active.is_(True),
|
||||
Bug.is_proposed_accepted.is_(True),
|
||||
Bug.is_proposed_accepted.is_(True), # type: ignore[attr-defined]
|
||||
)
|
||||
.all()
|
||||
)
|
||||
|
|
@ -562,7 +562,7 @@ def bugzilla_sync_proposal(bugid, milestone, blocker, fe):
|
|||
|
||||
|
||||
@main.route("/propose_bug", methods=["GET", "POST"])
|
||||
@oidc.require_login
|
||||
@oidc.require_login # type: ignore[has-type]
|
||||
def propose_bug():
|
||||
current_milestone = get_current_milestone()
|
||||
bugform = BugProposeForm()
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class Bug(db.Model):
|
|||
_depends_on: db.Mapped[str] = db.mapped_column("depends_on", db.Text, default="[]")
|
||||
"""A JSON list of bug numbers which this bug depends on"""
|
||||
updates: db.Mapped[List["Update"]] = db.relationship( # noqa: F821
|
||||
secondary=models.update_fixes,
|
||||
secondary=models.update_fixes, # type: ignore[has-type]
|
||||
back_populates="bugs",
|
||||
lazy="dynamic",
|
||||
order_by="[Update.status.desc(), Update.request.desc()]",
|
||||
|
|
@ -129,7 +129,7 @@ class Bug(db.Model):
|
|||
needinfo: Optional[bool],
|
||||
needinfo_requestee: Optional[str],
|
||||
last_whiteboard_change: Optional[datetime.datetime] = datetime.datetime.now(datetime.UTC),
|
||||
last_bug_sync: Optional[datetime] = datetime.datetime.now(datetime.UTC),
|
||||
last_bug_sync: Optional[datetime.datetime] = datetime.datetime.now(datetime.UTC),
|
||||
depends_on: Optional[list[int]] = None,
|
||||
) -> None:
|
||||
self.bugid = bugid
|
||||
|
|
|
|||
|
|
@ -84,7 +84,9 @@ class Update(db.Model):
|
|||
stable_karma: db.Mapped[Optional[int]]
|
||||
"""Target karma value for allowing the update to go stable (via auto or manual push)."""
|
||||
bugs: db.Mapped[List["Bug"]] = db.relationship( # noqa: F821
|
||||
secondary=models.update_fixes, back_populates="updates", cascade_backrefs=False
|
||||
secondary=models.update_fixes, # type: ignore[has-type]
|
||||
back_populates="updates",
|
||||
cascade_backrefs=False,
|
||||
)
|
||||
"""A list of bugs this update claims to fix *and* we track them"""
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class BlockerBugs:
|
|||
# &bug_status=POST&bug_status=MODIFIED&classification=Fedora&component=anaconda&f1=component
|
||||
# &o1=changedafter&product=Fedora&query_format=advanced&v1=2013-03-21%2012%3A25&version=19
|
||||
def get_bz_query(
|
||||
self, tracker: int, last_update: datetime.datetime = None, offset: int = 0
|
||||
self, tracker: int, last_update: Optional[datetime.datetime] = None, offset: int = 0
|
||||
) -> dict[str, Any]:
|
||||
"""Build a Bugzilla query to retrieve all necessary info about all bugs which block the
|
||||
`tracker` bug.
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ def agreed_revote_parser(line: str) -> List[Union[AgreedCommand, RevoteCommand]]
|
|||
if not words:
|
||||
return []
|
||||
|
||||
out = []
|
||||
out: List[Union[AgreedCommand, RevoteCommand]] = []
|
||||
command = words[0]
|
||||
for word in words[1:]:
|
||||
if command == "agreed":
|
||||
|
|
@ -200,7 +200,7 @@ class ForgejoComment:
|
|||
Returns:
|
||||
list: List of VoteCommand/AgreedCommand/RevoteCommand instances
|
||||
"""
|
||||
out = []
|
||||
out: List[Union[VoteCommand, AgreedCommand, RevoteCommand]] = []
|
||||
for line in self.text.lower().split("\n"):
|
||||
line = line.strip()
|
||||
if line.startswith("agreed") or line.startswith("revote"):
|
||||
|
|
@ -286,15 +286,18 @@ class BugVoteTracker:
|
|||
continue
|
||||
|
||||
if agreed:
|
||||
assert isinstance(command, AgreedCommand)
|
||||
self.open = False
|
||||
self.outcome = command.outcome
|
||||
self.need_summary_post = True
|
||||
elif revote:
|
||||
assert isinstance(command, RevoteCommand)
|
||||
self.open = True
|
||||
self.outcome = None
|
||||
self.need_summary_post = False
|
||||
self.votes = {}
|
||||
elif vote:
|
||||
assert isinstance(command, VoteCommand)
|
||||
if not self.open:
|
||||
continue
|
||||
self.votes[comment.user] = {"vote": command.vote, "comment_id": comment.id}
|
||||
|
|
@ -313,7 +316,7 @@ class BugVoteTracker:
|
|||
Returns:
|
||||
Dict mapping vote values to lists of (user, comment_id) tuples
|
||||
"""
|
||||
out = {vote: [] for vote in VOTES}
|
||||
out: Dict[str, List[Tuple[str, int]]] = {vote: [] for vote in VOTES}
|
||||
for user, vote_data in self.votes.items():
|
||||
out[vote_data["vote"]].append((user, vote_data["comment_id"]))
|
||||
|
||||
|
|
@ -456,7 +459,7 @@ def voting_info(
|
|||
"""
|
||||
# Find users who commented but didn't vote
|
||||
non_voting_users = {}
|
||||
all_voters = set()
|
||||
all_voters: set[str] = set()
|
||||
|
||||
for tracker in trackers.values():
|
||||
all_voters.update(tracker.votes.keys())
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ from flask import g, request, abort
|
|||
from blockerbugs import app, oidc
|
||||
|
||||
|
||||
@oidc.require_login
|
||||
@oidc.require_login # type: ignore[has-type]
|
||||
def check_admin_rights():
|
||||
if app.config["FAS_ADMIN_GROUP"] in g.oidc_user.groups:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ class UpdateSync(object):
|
|||
buglist.extend(
|
||||
milestone.bugs.filter( # type: ignore[attr-defined]
|
||||
Bug.active.is_(True),
|
||||
Bug.is_proposed_accepted.is_(True),
|
||||
Bug.is_proposed_accepted.is_(True), # type: ignore[attr-defined]
|
||||
).all()
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -38,3 +38,17 @@ log_file = "pytest.log"
|
|||
log_file_level = "INFO"
|
||||
log_file_format = "%(asctime)s [%(levelname)8s] (%(filename)s:%(lineno)s) %(message)s"
|
||||
log_file_date_format = "%Y-%m-%d %H:%M:%S"
|
||||
|
||||
[tool.mypy]
|
||||
# what directory/files to check
|
||||
files = "blockerbugs/, testing/, scripts/, *.py"
|
||||
# Target environment Python version, keep in sync with builder defined at:
|
||||
# https://forge.fedoraproject.org/infra/ansible/src/branch/main/roles/openshift-apps/blockerbugs/templates/buildconfig.yml.j2
|
||||
python_version = "3.11"
|
||||
# Ignore missing stubs/types for third-party libraries that don't provide them
|
||||
ignore_missing_imports = true
|
||||
# Exclude auto-generated and third-party vendored files
|
||||
exclude = [
|
||||
"^blockerbugs/_version\\.py$",
|
||||
"^versioneer\\.py$",
|
||||
]
|
||||
29
setup.cfg
29
setup.cfg
|
|
@ -1,32 +1,3 @@
|
|||
[mypy]
|
||||
files = blockerbugs/, testing/, scripts/, setup.py, wsgi.py
|
||||
# not our code ↓
|
||||
exclude = ^blockerbugs/_version\.py$
|
||||
|
||||
# There seem to be no typing stubs available for these libraries:
|
||||
[mypy-flask_sqlalchemy.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-flask_wtf.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-flask_oidc.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-flask_admin.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-alembic.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-wtforms.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-iso8601.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-koji.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-bugzilla.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-fedora.*]
|
||||
ignore_missing_imports = True
|
||||
[mypy-bodhi.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[coverage:run]
|
||||
source = blockerbugs
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import json
|
|||
import copy
|
||||
import http.client as httplib
|
||||
|
||||
import mock
|
||||
from unittest import mock
|
||||
import pytest
|
||||
|
||||
from blockerbugs import db
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import mock
|
||||
from unittest import mock
|
||||
import datetime
|
||||
from xmlrpc.client import Fault
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ class TestBugProposalTrackerCheck:
|
|||
test_bz = BlockerProposal(stubbz, self.ref_proposed, self.ref_trackers, is_blocker=True)
|
||||
test_result = test_bz.check_blocker_proposal()
|
||||
|
||||
assert test_result
|
||||
assert test_result is True
|
||||
|
||||
def test_check_propose_blocker_already(self):
|
||||
refbug = mock.MagicMock()
|
||||
|
|
@ -161,7 +161,7 @@ class TestBugProposalTrackerCheck:
|
|||
test_bz = BlockerProposal(stubbz, self.ref_proposed, self.ref_trackers, is_blocker=True)
|
||||
test_result = test_bz.check_blocker_proposal()
|
||||
|
||||
assert test_result == False
|
||||
assert test_result is False
|
||||
|
||||
def test_check_bothpropose_blocker_already(self):
|
||||
self.ref_tracker_type = "Blocker and Freeze Exception"
|
||||
|
|
@ -176,7 +176,7 @@ class TestBugProposalTrackerCheck:
|
|||
)
|
||||
test_result = test_bz.check_blocker_proposal()
|
||||
|
||||
assert test_result == False
|
||||
assert test_result is False
|
||||
|
||||
def test_check_bothpropose_blocker_already_fe_ok(self):
|
||||
self.ref_tracker_type = "Blocker and Freeze Exception"
|
||||
|
|
@ -191,7 +191,7 @@ class TestBugProposalTrackerCheck:
|
|||
)
|
||||
test_result = test_bz.check_fe_proposal()
|
||||
|
||||
assert test_result == True
|
||||
assert test_result is True
|
||||
|
||||
def test_check_bothpropose_fe_already(self):
|
||||
refbug = mock.MagicMock()
|
||||
|
|
@ -204,7 +204,7 @@ class TestBugProposalTrackerCheck:
|
|||
)
|
||||
test_result = test_bz.check_fe_proposal()
|
||||
|
||||
assert test_result == False
|
||||
assert test_result is False
|
||||
|
||||
def test_check_bothpropose_fe_already_blocker_ok(self):
|
||||
refbug = mock.MagicMock()
|
||||
|
|
@ -217,7 +217,7 @@ class TestBugProposalTrackerCheck:
|
|||
)
|
||||
test_result = test_bz.check_blocker_proposal()
|
||||
|
||||
assert test_result == True
|
||||
assert test_result is True
|
||||
|
||||
def test_proposed_bug_notexist(self):
|
||||
stubbz = mock.MagicMock()
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ import pytest
|
|||
from munch import Munch
|
||||
from copy import deepcopy
|
||||
from blockerbugs.util.bug_sync import BugSync
|
||||
from mock import MagicMock
|
||||
from unittest.mock import MagicMock
|
||||
import datetime
|
||||
|
||||
basicbug = Munch(
|
||||
basicbug: Munch = Munch(
|
||||
{
|
||||
"bug_id": 123456,
|
||||
"weburl": "https://bugzilla.redhat.com/show_bug.cgi?id=123456",
|
||||
|
|
@ -104,7 +104,7 @@ class TestSyncExtractInformation:
|
|||
|
||||
buginfo = self.testsync.extract_information(self.testbug, "Blocker")
|
||||
|
||||
assert buginfo["proposed"] == False
|
||||
assert buginfo["proposed"] is False
|
||||
|
||||
def test_bugid(self):
|
||||
buginfo = self.testsync.extract_information(self.testbug, "Blocker")
|
||||
|
|
@ -177,7 +177,7 @@ class TestSyncExtractInformation:
|
|||
self.testbug.flags = []
|
||||
buginfo = self.testsync.extract_information(self.testbug, "Blocker")
|
||||
|
||||
assert buginfo["needinfo"] == False
|
||||
assert buginfo["needinfo"] is False
|
||||
assert buginfo["needinfo_requestee"] == ""
|
||||
|
||||
def test_dependson(self):
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import mock
|
||||
from unittest import mock
|
||||
import pytest
|
||||
|
||||
from blockerbugs import db
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@ import pytest
|
|||
from munch import Munch
|
||||
from copy import deepcopy
|
||||
from blockerbugs.util.update_sync import UpdateSync
|
||||
from mock import MagicMock
|
||||
from unittest.mock import MagicMock
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
basicupdate = Munch(
|
||||
basicupdate: Munch = Munch(
|
||||
approved=None,
|
||||
close_bugs=True,
|
||||
critpath=False,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from blockerbugs.models.bug import Bug
|
|||
from blockerbugs import db
|
||||
from blockerbugs.util.bug_sync import BugSync
|
||||
|
||||
templatebug = Munch(
|
||||
templatebug: Munch = Munch(
|
||||
{
|
||||
"bug_id": 123456,
|
||||
"weburl": "https://bugzilla.redhat.com/show_bug.cgi?id=123456",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from copy import copy
|
|||
|
||||
import pytest
|
||||
from munch import Munch
|
||||
from mock import patch, Mock
|
||||
from unittest.mock import patch, Mock
|
||||
|
||||
from blockerbugs import db
|
||||
from blockerbugs.models.milestone import Milestone
|
||||
|
|
@ -15,7 +15,7 @@ from testing.test_controllers import add_bug
|
|||
|
||||
|
||||
# only required part of a Bodhi response
|
||||
base_update = Munch(
|
||||
base_update: Munch = Munch(
|
||||
title="anaconda-18.6.8-1.fc18",
|
||||
date_pushed="2012-09-13 16:40:28",
|
||||
date_submitted="2012-09-12 23:43:04",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""Tests for configuration validation"""
|
||||
|
||||
import pytest
|
||||
import mock
|
||||
from unittest import mock
|
||||
from werkzeug.datastructures import Headers
|
||||
|
||||
from blockerbugs.controllers.api.utils import check_forgejo_signature
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
from typing import Any
|
||||
from unittest.mock import Mock
|
||||
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from blockerbugs.util import forgejo_bot
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ from typing import Any
|
|||
from unittest.mock import Mock, MagicMock
|
||||
|
||||
import pytest
|
||||
import mock
|
||||
from unittest import mock
|
||||
|
||||
from blockerbugs.util import forgejo_interface
|
||||
|
||||
|
|
|
|||
2
wsgi.py
2
wsgi.py
|
|
@ -1 +1 @@
|
|||
from blockerbugs import app as application
|
||||
from blockerbugs import app as application # noqa: F401
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue