44
55Original code by Pablo Galindo
66"""
7+ from __future__ import annotations
78
89import argparse
910import asyncio
2324import urllib .request
2425from dataclasses import dataclass
2526from shelve import DbfilenameShelf
26- from typing import Callable , Iterator , List , Optional
27+ from typing import Any , Callable , Generator , Iterator
2728
2829import aiohttp
2930import gnupg
3334
3435import release as release_mod
3536import sbom
36- from buildbotapi import BuildBotAPI
37+ from buildbotapi import BuildBotAPI , Builder
3738
3839API_KEY_REGEXP = re .compile (r"(?P<major>\w+):(?P<minor>\w+)" )
3940
@@ -184,7 +185,7 @@ class Task:
184185 function : Callable [[DbfilenameShelf ], None ]
185186 description : str
186187
187- def __call__ (self , db : DbfilenameShelf ) -> None :
188+ def __call__ (self , db : DbfilenameShelf ) -> Any :
188189 return getattr (self , "function" )(db )
189190
190191
@@ -195,13 +196,13 @@ class ReleaseException(Exception):
195196class ReleaseDriver :
196197 def __init__ (
197198 self ,
198- tasks : List [Task ],
199+ tasks : list [Task ],
199200 * ,
200201 release_tag : release_mod .Tag ,
201202 git_repo : str ,
202203 api_key : str ,
203204 ssh_user : str ,
204- first_state : Optional [ Task ] = None ,
205+ first_state : Task | None = None ,
205206 ) -> None :
206207 self .tasks = tasks
207208 dbfile = pathlib .Path .home () / ".python_release"
@@ -212,7 +213,7 @@ def __init__(
212213 self .db .close ()
213214 self .db = shelve .open (str (dbfile ), "n" )
214215
215- self .current_task : Optional [ Task ] = first_state
216+ self .current_task : Task | None = first_state
216217 self .completed_tasks = self .db .get ("completed_tasks" , [])
217218 self .remaining_tasks = iter (tasks [len (self .completed_tasks ) :])
218219 if self .db .get ("gpg_key" ):
@@ -282,7 +283,7 @@ def cd(path: str) -> Iterator[None]:
282283
283284
284285@contextlib .contextmanager
285- def supress_print ():
286+ def supress_print () -> Generator [ None , None , None ] :
286287 print_func = builtins .print
287288 builtins .print = lambda * args , ** kwargs : None
288289 yield
@@ -333,8 +334,10 @@ def check_ssh_connection(db: DbfilenameShelf) -> None:
333334
334335
335336def check_buildbots (db : DbfilenameShelf ) -> None :
336- async def _check ():
337- async def _get_builder_status (buildbot_api , the_builder ):
337+ async def _check () -> set [Builder ]:
338+ async def _get_builder_status (
339+ buildbot_api : BuildBotAPI , the_builder : Builder
340+ ) -> tuple [Builder , bool ]:
338341 return the_builder , await buildbot_api .is_builder_failing_currently (
339342 the_builder
340343 )
@@ -567,7 +570,7 @@ def build_sbom_artifacts(db):
567570
568571
569572class MySFTPClient (paramiko .SFTPClient ):
570- def put_dir (self , source , target , progress = None ):
573+ def put_dir (self , source : str , target : str , progress : Any = None ) -> None :
571574 for item in os .listdir (source ):
572575 if os .path .isfile (os .path .join (source , item )):
573576 progress .text (item )
@@ -581,7 +584,7 @@ def put_dir(self, source, target, progress=None):
581584 progress = progress ,
582585 )
583586
584- def mkdir (self , path , mode = 511 , ignore_existing = False ):
587+ def mkdir (self , path : str , mode : int = 511 , ignore_existing : bool = False ) -> None :
585588 try :
586589 super ().mkdir (path , mode )
587590 except OSError :
@@ -609,7 +612,7 @@ def upload_files_to_server(db: DbfilenameShelf) -> None:
609612
610613 shutil .rmtree (artifacts_path / f"Python-{ db ['release' ]} " , ignore_errors = True )
611614
612- def upload_subdir (subdir ) :
615+ def upload_subdir (subdir : str ) -> None :
613616 with contextlib .suppress (OSError ):
614617 ftp_client .mkdir (str (destination / subdir ))
615618 with alive_bar (len (tuple ((artifacts_path / subdir ).glob ("**/*" )))) as progress :
@@ -636,7 +639,7 @@ def place_files_in_download_folder(db: DbfilenameShelf) -> None:
636639 source = f"/home/psf-users/{ db ['ssh_user' ]} /{ db ['release' ]} "
637640 destination = f"/srv/www.python.org/ftp/python/{ db ['release' ].normalized ()} "
638641
639- def execute_command (command ) :
642+ def execute_command (command : str ) -> None :
640643 channel = client .get_transport ().open_session ()
641644 channel .exec_command (command )
642645 if channel .recv_exit_status () != 0 :
@@ -655,7 +658,7 @@ def execute_command(command):
655658 source = f"/home/psf-users/{ db ['ssh_user' ]} /{ db ['release' ]} "
656659 destination = f"/srv/www.python.org/ftp/python/doc/{ release_tag } "
657660
658- def execute_command (command ) :
661+ def execute_command (command : str ) -> None :
659662 channel = client .get_transport ().open_session ()
660663 channel .exec_command (command )
661664 if channel .recv_exit_status () != 0 :
@@ -690,7 +693,7 @@ def upload_docs_to_the_docs_server(db: DbfilenameShelf) -> None:
690693
691694 shutil .rmtree (artifacts_path / f"Python-{ db ['release' ]} " , ignore_errors = True )
692695
693- def upload_subdir (subdir ) :
696+ def upload_subdir (subdir : str ) -> None :
694697 with contextlib .suppress (OSError ):
695698 ftp_client .mkdir (str (destination / subdir ))
696699 with alive_bar (len (tuple ((artifacts_path / subdir ).glob ("**/*" )))) as progress :
@@ -719,7 +722,7 @@ def unpack_docs_in_the_docs_server(db: DbfilenameShelf) -> None:
719722 source = f"/home/psf-users/{ db ['ssh_user' ]} /{ db ['release' ]} "
720723 destination = f"/srv/docs.python.org/release/{ release_tag } "
721724
722- def execute_command (command ) :
725+ def execute_command (command : str ) -> None :
723726 channel = client .get_transport ().open_session ()
724727 channel .exec_command (command )
725728 if channel .recv_exit_status () != 0 :
@@ -926,8 +929,6 @@ def modify_the_release_to_the_prerelease_pages(db: DbfilenameShelf) -> None:
926929
927930
928931def post_release_merge (db : DbfilenameShelf ) -> None :
929- release_tag : release_mod .Tag = db ["release" ]
930-
931932 subprocess .check_call (
932933 ["git" , "fetch" , "--all" ],
933934 cwd = db ["git_repo" ],
@@ -1031,7 +1032,7 @@ def is_mirror(repo: pathlib.Path, remote: str) -> bool:
10311032
10321033
10331034def push_to_local_fork (db : DbfilenameShelf ) -> None :
1034- def _push_to_local (dry_run = False ):
1035+ def _push_to_local (dry_run : bool = False ) -> None :
10351036 git_command = ["git" , "push" ]
10361037 if dry_run :
10371038 git_command .append ("--dry-run" )
@@ -1057,7 +1058,7 @@ def _push_to_local(dry_run=False):
10571058def push_to_upstream (db : DbfilenameShelf ) -> None :
10581059 release_tag : release_mod .Tag = db ["release" ]
10591060
1060- def _push_to_upstream (dry_run = False ):
1061+ def _push_to_upstream (dry_run : bool = False ) -> None :
10611062 branch = f"{ release_tag .major } .{ release_tag .minor } "
10621063 git_command = ["git" , "push" ]
10631064 if dry_run :
@@ -1112,7 +1113,7 @@ def main() -> None:
11121113
11131114 parser = argparse .ArgumentParser (description = "Process some integers." )
11141115
1115- def _release_type (release ) :
1116+ def _release_type (release : str ) -> str :
11161117 if not RELEASE_REGEXP .match (release ):
11171118 raise argparse .ArgumentTypeError ("Invalid release string" )
11181119 return release
@@ -1132,7 +1133,7 @@ def _release_type(release):
11321133 type = str ,
11331134 )
11341135
1135- def _api_key (api_key ) :
1136+ def _api_key (api_key : str ) -> str :
11361137 if not API_KEY_REGEXP .match (api_key ):
11371138 raise argparse .ArgumentTypeError (
11381139 "Invalid api key format. It must be on the form USER:API_KEY"
0 commit comments