⬆️ Upgrade Python to 3.14 (#2352)

This commit is contained in:
Sebastián Ramírez
2026-06-25 18:19:18 +02:00
committed by GitHub
parent a727535488
commit 14728b636c
14 changed files with 24 additions and 1083 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ jobs:
bun-version: 1.3.12 bun-version: 1.3.12
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version: '3.10' python-version-file: .python-version
- name: Setup tmate session - name: Setup tmate session
uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113 # v3.24 uses: mxschmitt/action-tmate@35b54afac29c97fb54faba5b513f8fbd1882f113 # v3.24
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }} if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled == 'true' }}
+1 -1
View File
@@ -44,7 +44,7 @@ jobs:
- name: Set up Python - name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version: "3.11" python-version-file: .python-version
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with: with:
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
persist-credentials: false persist-credentials: false
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version: "3.13" python-version-file: .python-version
- name: Setup uv - name: Setup uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with: with:
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
- name: Set up Python - name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with: with:
python-version: "3.10" python-version-file: .python-version
- name: Install uv - name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with: with:
+1
View File
@@ -0,0 +1 @@
3.14
+1 -1
View File
@@ -1,4 +1,4 @@
FROM python:3.10 FROM python:3.14
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1
+2 -2
View File
@@ -18,7 +18,7 @@ reusable_oauth2 = OAuth2PasswordBearer(
) )
def get_db() -> Generator[Session, None, None]: def get_db() -> Generator[Session]:
with Session(engine) as session: with Session(engine) as session:
yield session yield session
@@ -33,7 +33,7 @@ def get_current_user(session: SessionDep, token: TokenDep) -> User:
token, settings.SECRET_KEY, algorithms=[security.ALGORITHM] token, settings.SECRET_KEY, algorithms=[security.ALGORITHM]
) )
token_data = TokenPayload(**payload) token_data = TokenPayload(**payload)
except (InvalidTokenError, ValidationError): except InvalidTokenError, ValidationError:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN, status_code=status.HTTP_403_FORBIDDEN,
detail="Could not validate credentials", detail="Could not validate credentials",
+1 -2
View File
@@ -1,6 +1,6 @@
import secrets import secrets
import warnings import warnings
from typing import Annotated, Any, Literal from typing import Annotated, Any, Literal, Self
from pydantic import ( from pydantic import (
AnyUrl, AnyUrl,
@@ -12,7 +12,6 @@ from pydantic import (
model_validator, model_validator,
) )
from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic_settings import BaseSettings, SettingsConfigDict
from typing_extensions import Self
def parse_cors(v: Any) -> list[str] | str: def parse_cors(v: Any) -> list[str] | str:
+2 -2
View File
@@ -1,4 +1,4 @@
from datetime import datetime, timedelta, timezone from datetime import UTC, datetime, timedelta
from typing import Any from typing import Any
import jwt import jwt
@@ -20,7 +20,7 @@ ALGORITHM = "HS256"
def create_access_token(subject: str | Any, expires_delta: timedelta) -> str: def create_access_token(subject: str | Any, expires_delta: timedelta) -> str:
expire = datetime.now(timezone.utc) + expires_delta expire = datetime.now(UTC) + expires_delta
to_encode = {"exp": expire, "sub": str(subject)} to_encode = {"exp": expire, "sub": str(subject)}
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM) encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt return encoded_jwt
+3 -3
View File
@@ -1,5 +1,5 @@
import uuid import uuid
from datetime import datetime, timezone from datetime import UTC, datetime
from pydantic import EmailStr from pydantic import EmailStr
from sqlalchemy import DateTime from sqlalchemy import DateTime
@@ -7,7 +7,7 @@ from sqlmodel import Field, Relationship, SQLModel
def get_datetime_utc() -> datetime: def get_datetime_utc() -> datetime:
return datetime.now(timezone.utc) return datetime.now(UTC)
# Shared properties # Shared properties
@@ -53,7 +53,7 @@ class User(UserBase, table=True):
default_factory=get_datetime_utc, default_factory=get_datetime_utc,
sa_type=DateTime(timezone=True), # type: ignore sa_type=DateTime(timezone=True), # type: ignore
) )
items: list["Item"] = Relationship(back_populates="owner", cascade_delete=True) items: list[Item] = Relationship(back_populates="owner", cascade_delete=True)
# Properties to return via API, id is always required # Properties to return via API, id is always required
+2 -2
View File
@@ -1,6 +1,6 @@
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timedelta, timezone from datetime import UTC, datetime, timedelta
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
@@ -102,7 +102,7 @@ def generate_new_account_email(
def generate_password_reset_token(email: str) -> str: def generate_password_reset_token(email: str) -> str:
delta = timedelta(hours=settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS) delta = timedelta(hours=settings.EMAIL_RESET_TOKEN_EXPIRE_HOURS)
now = datetime.now(timezone.utc) now = datetime.now(UTC)
expires = now + delta expires = now + delta
exp = expires.timestamp() exp = expires.timestamp()
encoded_jwt = jwt.encode( encoded_jwt = jwt.encode(
+2 -2
View File
@@ -2,7 +2,7 @@
name = "app" name = "app"
version = "0.1.0" version = "0.1.0"
description = "" description = ""
requires-python = ">=3.10,<4.0" requires-python = ">=3.14,<4.0"
dependencies = [ dependencies = [
"fastapi[standard]<1.0.0,>=0.114.2", "fastapi[standard]<1.0.0,>=0.114.2",
"python-multipart<1.0.0,>=0.0.27", "python-multipart<1.0.0,>=0.0.27",
@@ -40,7 +40,7 @@ strict = true
exclude = ["venv", ".venv", "alembic"] exclude = ["venv", ".venv", "alembic"]
[tool.ruff] [tool.ruff]
target-version = "py310" target-version = "py314"
exclude = ["alembic"] exclude = ["alembic"]
[tool.ruff.lint] [tool.ruff.lint]
+2 -2
View File
@@ -13,7 +13,7 @@ from tests.utils.utils import get_superuser_token_headers
@pytest.fixture(scope="session", autouse=True) @pytest.fixture(scope="session", autouse=True)
def db() -> Generator[Session, None, None]: def db() -> Generator[Session]:
with Session(engine) as session: with Session(engine) as session:
init_db(session) init_db(session)
yield session yield session
@@ -25,7 +25,7 @@ def db() -> Generator[Session, None, None]:
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
def client() -> Generator[TestClient, None, None]: def client() -> Generator[TestClient]:
with TestClient(app) as c: with TestClient(app) as c:
yield c yield c
Generated
+4 -1063
View File
File diff suppressed because it is too large Load Diff