This is an automated email from the ASF dual-hosted git repository.

sbp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tooling-atr-experiments.git


The following commit(s) were added to refs/heads/main by this push:
     new 352776e  Add some lints to ruff
352776e is described below

commit 352776eccf5815956d58dc40bbc660257d022222
Author: Sean B. Palmer <s...@miscoranda.com>
AuthorDate: Mon Feb 17 19:14:07 2025 +0200

    Add some lints to ruff
---
 atr/models.py                                      | 80 +++++++++++-----------
 atr/routes.py                                      | 41 +++++------
 atr/server.py                                      | 11 +--
 atr/templates/add-release-candidate.html           |  2 +-
 migrations/env.py                                  |  7 +-
 migrations/versions/15182b58521a_initial_schema.py |  9 ++-
 pyproject.toml                                     |  2 +-
 scripts/generate-certificates                      |  8 +--
 8 files changed, 80 insertions(+), 80 deletions(-)

diff --git a/atr/models.py b/atr/models.py
index 61c9dd4..ea56aa6 100644
--- a/atr/models.py
+++ b/atr/models.py
@@ -18,12 +18,12 @@
 "models.py"
 
 import datetime
-from typing import List, Optional
 from enum import Enum
+from typing import Optional
 
-from sqlmodel import SQLModel, Field, Relationship
-from sqlalchemy import Column, JSON
 from pydantic import BaseModel
+from sqlalchemy import JSON, Column
+from sqlmodel import Field, Relationship, SQLModel
 
 
 class UserRole(str, Enum):
@@ -45,70 +45,70 @@ class PublicSigningKey(SQLModel, table=True):
     public_key: str
     key_type: str
     expiration: datetime.datetime
-    pmcs: List["PMC"] = Relationship(back_populates="public_signing_keys", 
link_model=PMCKeyLink)
+    pmcs: list["PMC"] = Relationship(back_populates="public_signing_keys", 
link_model=PMCKeyLink)
 
 
 class VotePolicy(SQLModel, table=True):
-    id: Optional[int] = Field(default=None, primary_key=True)
-    mailto_addresses: List[str] = Field(default_factory=list, 
sa_column=Column(JSON))
+    id: int | None = Field(default=None, primary_key=True)
+    mailto_addresses: list[str] = Field(default_factory=list, 
sa_column=Column(JSON))
     manual_vote: bool = Field(default=False)
     min_hours: int = Field(default=0)
     release_checklist: str = Field(default="")
     pause_for_rm: bool = Field(default=False)
 
     # One-to-many: A vote policy can be used by multiple PMCs
-    pmcs: List["PMC"] = Relationship(back_populates="vote_policy")
+    pmcs: list["PMC"] = Relationship(back_populates="vote_policy")
     # One-to-many: A vote policy can be used by multiple product lines
-    product_lines: List["ProductLine"] = 
Relationship(back_populates="vote_policy")
+    product_lines: list["ProductLine"] = 
Relationship(back_populates="vote_policy")
     # One-to-many: A vote policy can be used by multiple releases
-    releases: List["Release"] = Relationship(back_populates="vote_policy")
+    releases: list["Release"] = Relationship(back_populates="vote_policy")
 
 
 class PMC(SQLModel, table=True):
-    id: Optional[int] = Field(default=None, primary_key=True)
+    id: int | None = Field(default=None, primary_key=True)
     project_name: str = Field(unique=True)
 
     # One-to-many: A PMC can have multiple product lines, each product line 
belongs to one PMC
-    product_lines: List["ProductLine"] = Relationship(back_populates="pmc")
+    product_lines: list["ProductLine"] = Relationship(back_populates="pmc")
 
-    pmc_members: List[str] = Field(default_factory=list, 
sa_column=Column(JSON))
-    committers: List[str] = Field(default_factory=list, sa_column=Column(JSON))
-    release_managers: List[str] = Field(default_factory=list, 
sa_column=Column(JSON))
+    pmc_members: list[str] = Field(default_factory=list, 
sa_column=Column(JSON))
+    committers: list[str] = Field(default_factory=list, sa_column=Column(JSON))
+    release_managers: list[str] = Field(default_factory=list, 
sa_column=Column(JSON))
 
     # Many-to-many: A PMC can have multiple signing keys, and a signing key 
can belong to multiple PMCs
-    public_signing_keys: List[PublicSigningKey] = 
Relationship(back_populates="pmcs", link_model=PMCKeyLink)
+    public_signing_keys: list[PublicSigningKey] = 
Relationship(back_populates="pmcs", link_model=PMCKeyLink)
 
     # Many-to-one: A PMC can have one vote policy, a vote policy can be used 
by multiple entities
-    vote_policy_id: Optional[int] = Field(default=None, 
foreign_key="votepolicy.id")
-    vote_policy: Optional[VotePolicy] = Relationship(back_populates="pmcs")
+    vote_policy_id: int | None = Field(default=None, 
foreign_key="votepolicy.id")
+    vote_policy: VotePolicy | None = Relationship(back_populates="pmcs")
 
     # One-to-many: A PMC can have multiple releases
-    releases: List["Release"] = Relationship(back_populates="pmc")
+    releases: list["Release"] = Relationship(back_populates="pmc")
 
 
 class ProductLine(SQLModel, table=True):
-    id: Optional[int] = Field(default=None, primary_key=True)
+    id: int | None = Field(default=None, primary_key=True)
 
     # Many-to-one: A product line belongs to one PMC, a PMC can have multiple 
product lines
-    pmc_id: Optional[int] = Field(default=None, foreign_key="pmc.id")
-    pmc: Optional[PMC] = Relationship(back_populates="product_lines")
+    pmc_id: int | None = Field(default=None, foreign_key="pmc.id")
+    pmc: PMC | None = Relationship(back_populates="product_lines")
 
     product_name: str
     latest_version: str
 
     # One-to-many: A product line can have multiple distribution channels, 
each channel belongs to one product line
-    distribution_channels: List["DistributionChannel"] = 
Relationship(back_populates="product_line")
+    distribution_channels: list["DistributionChannel"] = 
Relationship(back_populates="product_line")
 
     # Many-to-one: A product line can have one vote policy, a vote policy can 
be used by multiple entities
-    vote_policy_id: Optional[int] = Field(default=None, 
foreign_key="votepolicy.id")
-    vote_policy: Optional[VotePolicy] = 
Relationship(back_populates="product_lines")
+    vote_policy_id: int | None = Field(default=None, 
foreign_key="votepolicy.id")
+    vote_policy: VotePolicy | None = 
Relationship(back_populates="product_lines")
 
     # One-to-many: A product line can have multiple releases, each release 
belongs to one product line
-    releases: List["Release"] = Relationship(back_populates="product_line")
+    releases: list["Release"] = Relationship(back_populates="product_line")
 
 
 class DistributionChannel(SQLModel, table=True):
-    id: Optional[int] = Field(default=None, primary_key=True)
+    id: int | None = Field(default=None, primary_key=True)
     name: str = Field(index=True, unique=True)
     url: str
     credentials: str
@@ -116,18 +116,18 @@ class DistributionChannel(SQLModel, table=True):
     automation_endpoint: str
 
     # Many-to-one: A distribution channel belongs to one product line, a 
product line can have multiple channels
-    product_line_id: Optional[int] = Field(default=None, 
foreign_key="productline.id")
-    product_line: Optional[ProductLine] = 
Relationship(back_populates="distribution_channels")
+    product_line_id: int | None = Field(default=None, 
foreign_key="productline.id")
+    product_line: ProductLine | None = 
Relationship(back_populates="distribution_channels")
 
 
 class Package(SQLModel, table=True):
-    id: Optional[int] = Field(default=None, primary_key=True)
+    id: int | None = Field(default=None, primary_key=True)
     file: str
     signature: str
     checksum: str
 
     # Many-to-one: A package belongs to one release
-    release_key: Optional[str] = Field(default=None, 
foreign_key="release.storage_key")
+    release_key: str | None = Field(default=None, 
foreign_key="release.storage_key")
     release: Optional["Release"] = Relationship(back_populates="packages")
 
 
@@ -168,21 +168,21 @@ class Release(SQLModel, table=True):
     phase: ReleasePhase
 
     # Many-to-one: A release belongs to one PMC, a PMC can have multiple 
releases
-    pmc_id: Optional[int] = Field(default=None, foreign_key="pmc.id")
-    pmc: Optional[PMC] = Relationship(back_populates="releases")
+    pmc_id: int | None = Field(default=None, foreign_key="pmc.id")
+    pmc: PMC | None = Relationship(back_populates="releases")
 
     # Many-to-one: A release belongs to one product line, a product line can 
have multiple releases
-    product_line_id: Optional[int] = Field(default=None, 
foreign_key="productline.id")
-    product_line: Optional[ProductLine] = 
Relationship(back_populates="releases")
+    product_line_id: int | None = Field(default=None, 
foreign_key="productline.id")
+    product_line: ProductLine | None = Relationship(back_populates="releases")
 
-    package_managers: List[str] = Field(default_factory=list, 
sa_column=Column(JSON))
+    package_managers: list[str] = Field(default_factory=list, 
sa_column=Column(JSON))
     version: str
     # One-to-many: A release can have multiple packages
-    packages: List[Package] = Relationship(back_populates="release")
-    sboms: List[str] = Field(default_factory=list, sa_column=Column(JSON))
+    packages: list[Package] = Relationship(back_populates="release")
+    sboms: list[str] = Field(default_factory=list, sa_column=Column(JSON))
 
     # Many-to-one: A release can have one vote policy, a vote policy can be 
used by multiple releases
-    vote_policy_id: Optional[int] = Field(default=None, 
foreign_key="votepolicy.id")
-    vote_policy: Optional[VotePolicy] = Relationship(back_populates="releases")
+    vote_policy_id: int | None = Field(default=None, 
foreign_key="votepolicy.id")
+    vote_policy: VotePolicy | None = Relationship(back_populates="releases")
 
-    votes: List[VoteEntry] = Field(default_factory=list, 
sa_column=Column(JSON))
+    votes: list[VoteEntry] = Field(default_factory=list, 
sa_column=Column(JSON))
diff --git a/atr/routes.py b/atr/routes.py
index c5690fc..a1be503 100644
--- a/atr/routes.py
+++ b/atr/routes.py
@@ -25,33 +25,34 @@ import pprint
 import secrets
 import shutil
 import tempfile
-
 from contextlib import asynccontextmanager
 from io import BufferedReader
 from pathlib import Path
-from typing import Any, Dict, List, Optional, Tuple, cast
+from typing import Any, cast
 
 import aiofiles
 import aiofiles.os
 import gnupg
 import httpx
-
-from asfquart import APP
-from asfquart.auth import Requirements as R, require
-from asfquart.base import ASFQuartException
-from asfquart.session import read as session_read, ClientSession
-from quart import current_app, render_template, request, Request
-from sqlmodel import select
+from quart import Request, current_app, render_template, request
 from sqlalchemy.ext.asyncio import AsyncSession
 from sqlalchemy.orm import selectinload
 from sqlalchemy.orm.attributes import InstrumentedAttribute
+from sqlmodel import select
 from werkzeug.datastructures import FileStorage
 
+from asfquart import APP
+from asfquart.auth import Requirements as R
+from asfquart.auth import require
+from asfquart.base import ASFQuartException
+from asfquart.session import ClientSession
+from asfquart.session import read as session_read
+
 from .models import (
-    DistributionChannel,
     PMC,
-    PMCKeyLink,
+    DistributionChannel,
     Package,
+    PMCKeyLink,
     ProductLine,
     PublicSigningKey,
     Release,
@@ -348,10 +349,10 @@ async def root_release_signatures_verify(release_key: 
str) -> str:
     async_session = current_app.config["async_session"]
     async with async_session() as db_session:
         # Get the release and its packages, and PMC with its keys
-        release_packages = 
selectinload(cast(InstrumentedAttribute[List[Package]], Release.packages))
+        release_packages = 
selectinload(cast(InstrumentedAttribute[list[Package]], Release.packages))
         release_pmc = selectinload(cast(InstrumentedAttribute[PMC], 
Release.pmc))
         pmc_keys_loader = selectinload(cast(InstrumentedAttribute[PMC], 
Release.pmc)).selectinload(
-            cast(InstrumentedAttribute[List[PublicSigningKey]], 
PMC.public_signing_keys)
+            cast(InstrumentedAttribute[list[PublicSigningKey]], 
PMC.public_signing_keys)
         )
 
         # For now, for debugging, we'll just get all keys in the database
@@ -465,7 +466,7 @@ async def root_pmc_directory() -> str:
 
 
 @APP.route("/pmc/list")
-async def root_pmc_list() -> List[dict]:
+async def root_pmc_list() -> list[dict]:
     "List all PMCs in the database."
     async_session = current_app.config["async_session"]
     async with async_session() as db_session:
@@ -565,7 +566,7 @@ async def root_user_uploads() -> str:
         # TODO: We don't actually record who uploaded the release candidate
         # We should probably add that information!
         release_pmc = selectinload(cast(InstrumentedAttribute[PMC], 
Release.pmc))
-        release_packages = 
selectinload(cast(InstrumentedAttribute[List[Package]], Release.packages))
+        release_packages = 
selectinload(cast(InstrumentedAttribute[list[Package]], Release.packages))
         statement = (
             select(Release)
             .options(release_pmc, release_packages)
@@ -623,7 +624,7 @@ async def save_file_by_hash(base_dir: Path, file: 
FileStorage) -> str:
         raise e
 
 
-async def user_keys_add(session: ClientSession, public_key: str) -> Tuple[str, 
Optional[dict]]:
+async def user_keys_add(session: ClientSession, public_key: str) -> tuple[str, 
dict | None]:
     if not public_key:
         return ("Public key is required", None)
 
@@ -661,7 +662,7 @@ async def user_keys_add(session: ClientSession, public_key: 
str) -> Tuple[str, O
 
 async def user_keys_add_session(
     session: ClientSession, public_key: str, key: dict, db_session: 
AsyncSession
-) -> Tuple[str, Optional[dict]]:
+) -> tuple[str, dict | None]:
     # Check if key already exists
     statement = select(PublicSigningKey).where(PublicSigningKey.user_id == 
session.uid)
 
@@ -709,7 +710,7 @@ async def user_keys_add_session(
     )
 
 
-async def verify_gpg_signature(artifact_path: Path, signature_path: Path, 
public_keys: List[str]) -> Dict[str, Any]:
+async def verify_gpg_signature(artifact_path: Path, signature_path: Path, 
public_keys: list[str]) -> dict[str, Any]:
     """
     Verify a GPG signature for a release artifact.
     Returns a dictionary with verification results and debug information.
@@ -727,8 +728,8 @@ async def verify_gpg_signature(artifact_path: Path, 
signature_path: Path, public
 
 
 async def verify_gpg_signature_file(
-    sig_file: BufferedReader, artifact_path: Path, public_keys: List[str]
-) -> Dict[str, Any]:
+    sig_file: BufferedReader, artifact_path: Path, public_keys: list[str]
+) -> dict[str, Any]:
     # Run the blocking GPG verification in a thread
     async with ephemeral_gpg_home() as gpg_home:
         gpg = gnupg.GPG(gnupghome=gpg_home)
diff --git a/atr/server.py b/atr/server.py
index e3e80d0..83c938e 100644
--- a/atr/server.py
+++ b/atr/server.py
@@ -19,15 +19,16 @@
 
 import os
 
+from alembic import command
+from alembic.config import Config
+from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, 
create_async_engine
+from sqlalchemy.sql import text
+from sqlmodel import SQLModel
+
 import asfquart
 import asfquart.generics
 import asfquart.session
 from asfquart.base import QuartApp
-from sqlmodel import SQLModel
-from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, 
async_sessionmaker
-from alembic import command
-from alembic.config import Config
-from sqlalchemy.sql import text
 
 from .models import __file__ as data_models_file
 
diff --git a/atr/templates/add-release-candidate.html 
b/atr/templates/add-release-candidate.html
index c3f3497..84c1883 100644
--- a/atr/templates/add-release-candidate.html
+++ b/atr/templates/add-release-candidate.html
@@ -1,7 +1,7 @@
 {% extends "layouts/base.html" %}
 
 {% block title %}
-  Add Release Candidate ~ ATR
+  Add release candidate ~ ATR
 {% endblock title %}
 
 {% block description %}
diff --git a/migrations/env.py b/migrations/env.py
index efdaa9d..7ea3ab1 100644
--- a/migrations/env.py
+++ b/migrations/env.py
@@ -1,9 +1,8 @@
 from logging.config import fileConfig
-from typing import Any, Dict, cast
+from typing import Any, cast
 
-from sqlalchemy import engine_from_config, pool
 from alembic import context
-
+from sqlalchemy import engine_from_config, pool
 from sqlmodel import SQLModel
 
 # this is the Alembic Config object, which provides
@@ -47,7 +46,7 @@ def run_migrations_online() -> None:
     configuration = config.get_section(config.config_ini_section)
     if configuration is None:
         configuration = {}
-    configuration = cast(Dict[str, Any], configuration)
+    configuration = cast(dict[str, Any], configuration)
     configuration["sqlalchemy.url"] = sync_url
 
     connectable = engine_from_config(
diff --git a/migrations/versions/15182b58521a_initial_schema.py 
b/migrations/versions/15182b58521a_initial_schema.py
index d893727..6db694f 100644
--- a/migrations/versions/15182b58521a_initial_schema.py
+++ b/migrations/versions/15182b58521a_initial_schema.py
@@ -6,14 +6,13 @@ Create Date: 2025-02-11 20:09:20.011634
 
 """
 
-from typing import Sequence, Union
-
+from collections.abc import Sequence
 
 # revision identifiers, used by Alembic.
 revision: str = "15182b58521a"
-down_revision: Union[str, None] = None
-branch_labels: Union[str, Sequence[str], None] = None
-depends_on: Union[str, Sequence[str], None] = None
+down_revision: str | None = None
+branch_labels: str | Sequence[str] | None = None
+depends_on: str | Sequence[str] | None = None
 
 
 def upgrade() -> None:
diff --git a/pyproject.toml b/pyproject.toml
index 5b17146..68774e9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -74,7 +74,7 @@ executionEnvironments = [
 ]
 
 [tool.ruff]
-lint.select = ["E", "W", "F", "C90"]
+lint.select = ["I", "E", "W", "F", "C90", "UP"]
 lint.ignore = []
 line-length = 120
 exclude = ["asfquart"]
diff --git a/scripts/generate-certificates b/scripts/generate-certificates
index 951c646..7a5fa72 100755
--- a/scripts/generate-certificates
+++ b/scripts/generate-certificates
@@ -1,12 +1,12 @@
 #!/usr/bin/env python3
-import os
 import datetime
 import ipaddress
+import os
 
 from cryptography import x509
-from cryptography.x509.oid import NameOID
-from cryptography.hazmat.primitives import serialization, hashes
+from cryptography.hazmat.primitives import hashes, serialization
 from cryptography.hazmat.primitives.asymmetric import rsa
+from cryptography.x509.oid import NameOID
 
 # All state is placed in this directory
 STATE_DIR = "./state"
@@ -31,7 +31,7 @@ def generate_self_signed_cert() -> None:
     )
 
     # Use timezone-aware datetime objects for UTC
-    now = datetime.datetime.now(datetime.timezone.utc)
+    now = datetime.datetime.now(datetime.UTC)
 
     # Build a certificate with a SAN for 127.0.0.1
     cert = (


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tooling.apache.org
For additional commands, e-mail: dev-h...@tooling.apache.org

Reply via email to