Grade against 3.14 too, not just run on it

The pre-commit workflow already installs `python-version: "3.x"`, but ruff was
still grading the archive against py310 -- so it kept withholding the pyupgrade
and type-checking fixes that only become safe at the newer target.
`pin_ci_python.py` rewrites the knob.

The 17 findings that appeared are what the stale target was hiding:
`datetime.timezone.utc` where `datetime.UTC` is now correct (UP017), and 14
imports used only in annotations that belong under `TYPE_CHECKING` (TC002,
TC003) -- safe here precisely because 3.14's PEP 649 defers annotation
evaluation, which is the same reason ruff would not offer them at py310.

`ruff check` and `ruff format --check` are clean again, so the zero-findings
state this repo reached earlier today holds at the new target.

Still contradictory and deliberately untouched: the four
`Programming/ERSMS-project/*/Dockerfile` files say `FROM python:3.10-slim`.
They build an archived coursework service against its own era's pinned
dependencies, and nothing in this repo runs them; bumping the base image would
be a rewrite of that project, not a lint-target change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfnJmxxsZ534AKk16rC2Gr
This commit is contained in:
Krzysztof Rudnicki 2026-08-29 11:55:43 +02:00
parent 42fa8228b0
commit 8798105aa1
12 changed files with 42 additions and 18 deletions

View File

@ -9,13 +9,16 @@ import logging
import sys import sys
import tempfile import tempfile
import time import time
from collections.abc import Callable
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
import cv2 import cv2
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
if TYPE_CHECKING:
from collections.abc import Callable
# cv2.waitKey returns the ASCII code of the key pressed; 'q' quits. # cv2.waitKey returns the ASCII code of the key pressed; 'q' quits.
KEY_Q = ord("q") KEY_Q = ord("q")
# NumPy's legacy np.random.* functions share one global state; Generator is # NumPy's legacy np.random.* functions share one global state; Generator is

View File

@ -466,7 +466,7 @@ def write_test_results(title: str, result: object = "") -> None:
Path("test_results").mkdir(parents=True) Path("test_results").mkdir(parents=True)
# Generate timestamped filename # Generate timestamped filename
timestamp = datetime.datetime.now(tz=datetime.timezone.utc).strftime( timestamp = datetime.datetime.now(tz=datetime.UTC).strftime(
"%Y%m%d%H%M%S" "%Y%m%d%H%M%S"
) # e.g., 20230611235959 ) # e.g., 20230611235959
filename = f"{title}_{timestamp}.txt" filename = f"{title}_{timestamp}.txt"

View File

@ -14,7 +14,7 @@ import os
import time import time
from configparser import ConfigParser from configparser import ConfigParser
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timezone from datetime import UTC, datetime
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import pandas as pd import pandas as pd
@ -89,9 +89,7 @@ MOVIES = Movies()
@cache.cached(timeout=69) @cache.cached(timeout=69)
def hello() -> ResponseReturnValue: def hello() -> ResponseReturnValue:
"""Liveness check.""" """Liveness check."""
return jsonify( return jsonify({"response": "Hello there", "time": datetime.now(tz=UTC)}), HTTP_OK
{"response": "Hello there", "time": datetime.now(tz=timezone.utc)}
), HTTP_OK
# endpoint do wyciągania danych o userze # endpoint do wyciągania danych o userze

View File

@ -8,10 +8,13 @@ them here would put newlines into the middle of the prompt itself.
import os import os
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
import pandas as pd
from openai import OpenAI from openai import OpenAI
if TYPE_CHECKING:
import pandas as pd
PROMPTS = Path(__file__).parent / "prompts" PROMPTS = Path(__file__).parent / "prompts"
THE_PROMPT = (PROMPTS / "alignment.txt").read_text(encoding="utf-8") THE_PROMPT = (PROMPTS / "alignment.txt").read_text(encoding="utf-8")
THE_PROMPT_WITH_COMMENT = (PROMPTS / "alignment_with_comment.txt").read_text( THE_PROMPT_WITH_COMMENT = (PROMPTS / "alignment_with_comment.txt").read_text(

View File

@ -4,11 +4,15 @@
import logging import logging
import os import os
import re import re
from collections.abc import Callable
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING
from openai import OpenAI from openai import OpenAI
from openai.types.chat import ChatCompletion
if TYPE_CHECKING:
from collections.abc import Callable
from openai.types.chat import ChatCompletion
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
logging.basicConfig(format="%(message)s", level=logging.INFO) logging.basicConfig(format="%(message)s", level=logging.INFO)

View File

@ -4,13 +4,16 @@
import gc import gc
import logging import logging
import time import time
from typing import TYPE_CHECKING
import linear_algebra_utils as lin_alg import linear_algebra_utils as lin_alg
import numpy as np import numpy as np
from processing_type import ProcessingType from processing_type import ProcessingType
from richardson_problem import Problem, Settings
from time_measurement import tests_time, time_accumulator, time_measurement from time_measurement import tests_time, time_accumulator, time_measurement
if TYPE_CHECKING:
from richardson_problem import Problem, Settings
# These helpers are called with numpy arrays in some backends and plain # These helpers are called with numpy arrays in some backends and plain
# Python lists in others, which is the point of the comparison this course # Python lists in others, which is the point of the comparison this course
# is about, so the aliases name both. # is about, so the aliases name both.

View File

@ -4,17 +4,20 @@
import gc import gc
import logging import logging
import time import time
from typing import TYPE_CHECKING
import linear_algebra_utils as lin_alg import linear_algebra_utils as lin_alg
import numpy as np import numpy as np
from numba import njit, prange from numba import njit, prange
from richardson_problem import Problem, Settings
from time_measurement import ( from time_measurement import (
longest_threads_time_accumulator, longest_threads_time_accumulator,
tests_time, tests_time,
time_measurement_longest, time_measurement_longest,
) )
if TYPE_CHECKING:
from richardson_problem import Problem, Settings
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Called with numpy arrays here and with plain lists in the sequential # Called with numpy arrays here and with plain lists in the sequential

View File

@ -5,18 +5,22 @@ import gc
import logging import logging
import multiprocessing import multiprocessing
import time import time
from collections.abc import Callable
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
from typing import TYPE_CHECKING
import linear_algebra_utils as lin_alg import linear_algebra_utils as lin_alg
import numpy as np import numpy as np
from richardson_problem import Problem, Settings
from time_measurement import ( from time_measurement import (
longest_threads_time_accumulator, longest_threads_time_accumulator,
tests_time, tests_time,
time_measurement_longest, time_measurement_longest,
) )
if TYPE_CHECKING:
from collections.abc import Callable
from richardson_problem import Problem, Settings
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Called with numpy arrays here and with plain lists in the sequential # Called with numpy arrays here and with plain lists in the sequential

View File

@ -7,15 +7,18 @@ import multiprocessing
import sys import sys
import threading import threading
import time import time
from typing import TYPE_CHECKING
import numpy as np import numpy as np
from richardson_problem import Problem, Settings
from time_measurement import ( from time_measurement import (
longest_time_accumulator, longest_time_accumulator,
tests_time, tests_time,
time_measurement_longest, time_measurement_longest,
) )
if TYPE_CHECKING:
from richardson_problem import Problem, Settings
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
# Called with numpy arrays here and with plain lists in the sequential # Called with numpy arrays here and with plain lists in the sequential

View File

@ -3,7 +3,10 @@
import sys import sys
import time import time
from collections.abc import Callable from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Callable
class TimeAccumulator: class TimeAccumulator:

View File

@ -14,7 +14,7 @@ import sys
import threading import threading
import tkinter as tk import tkinter as tk
from collections import Counter from collections import Counter
from datetime import datetime, timezone from datetime import UTC, datetime
from pathlib import Path from pathlib import Path
from tkinter import ttk from tkinter import ttk
@ -97,7 +97,7 @@ class AlarmVisualizer:
# Format the timestamp # Format the timestamp
timestamp_dt = datetime.fromtimestamp( timestamp_dt = datetime.fromtimestamp(
alarm.timestamp / MILLISECONDS, tz=timezone.utc alarm.timestamp / MILLISECONDS, tz=UTC
).astimezone() ).astimezone()
formatted_date = timestamp_dt.strftime("%Y-%m-%d %H:%M:%S") formatted_date = timestamp_dt.strftime("%Y-%m-%d %H:%M:%S")

View File

@ -7,7 +7,7 @@
# on its own, or the gates start disagreeing about what is kuhy's code. # on its own, or the gates start disagreeing about what is kuhy's code.
[tool.ruff] [tool.ruff]
target-version = "py310" target-version = "py314"
line-length = 88 line-length = 88
include = ["*.py", "**/*.py", "*.ipynb", "**/*.ipynb"] include = ["*.py", "**/*.py", "*.ipynb", "**/*.ipynb"]