From 7313bc4e0a2968848e72dbe1f1397e35e21db04d Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 7 May 2025 22:11:04 +0300 Subject: [PATCH] [3.13] gh-133403: Type `Tools/build/update_file.py` and check it with `mypy` (GH-133404) (cherry picked from commit 50b52cba2d13a1854bc835412ac3f3c0ad42b5ba) Co-authored-by: sobolevn --- Tools/build/mypy.ini | 8 +++++++- Tools/build/update_file.py | 24 +++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Tools/build/mypy.ini b/Tools/build/mypy.ini index 0e5d6e874a72e5..db546c6fb3481c 100644 --- a/Tools/build/mypy.ini +++ b/Tools/build/mypy.ini @@ -1,5 +1,9 @@ [mypy] -files = Tools/build/generate_sbom.py +files = + Tools/build/compute-changes.py, + Tools/build/generate_sbom.py, + Tools/build/update_file.py + pretty = True # Make sure Python can still be built @@ -8,6 +12,8 @@ python_version = 3.10 # ...And be strict: strict = True +strict_bytes = True +local_partial_types = True extra_checks = True enable_error_code = ignore-without-code,redundant-expr,truthy-bool,possibly-undefined warn_unreachable = True diff --git a/Tools/build/update_file.py b/Tools/build/update_file.py index b4182c1d0cb638..b4a5fb6e778ae8 100644 --- a/Tools/build/update_file.py +++ b/Tools/build/update_file.py @@ -6,14 +6,27 @@ actually change the in-tree generated code. """ +from __future__ import annotations + import contextlib import os import os.path import sys +TYPE_CHECKING = False +if TYPE_CHECKING: + import typing + from collections.abc import Iterator + from io import TextIOWrapper + + _Outcome: typing.TypeAlias = typing.Literal['created', 'updated', 'same'] + @contextlib.contextmanager -def updating_file_with_tmpfile(filename, tmpfile=None): +def updating_file_with_tmpfile( + filename: str, + tmpfile: str | None = None, +) -> Iterator[tuple[TextIOWrapper, TextIOWrapper]]: """A context manager for updating a file via a temp file. The context manager provides two open files: the source file open @@ -46,13 +59,18 @@ def updating_file_with_tmpfile(filename, tmpfile=None): update_file_with_tmpfile(filename, tmpfile) -def update_file_with_tmpfile(filename, tmpfile, *, create=False): +def update_file_with_tmpfile( + filename: str, + tmpfile: str, + *, + create: bool = False, +) -> _Outcome: try: targetfile = open(filename, 'rb') except FileNotFoundError: if not create: raise # re-raise - outcome = 'created' + outcome: _Outcome = 'created' os.replace(tmpfile, filename) else: with targetfile: