1919import tempfile
2020import time
2121from collections import namedtuple
22- from collections .abc import Generator , Sequence
2322from contextlib import contextmanager
2423from datetime import datetime , timedelta , timezone
2524from email .mime .application import MIMEApplication
2827from enum import Enum
2928from pathlib import Path
3029from subprocess import PIPE
31- from typing import Any , Final , IO
30+ from typing import Any , Dict , Final , Generator , IO , List , Optional , Sequence , Tuple
3231
3332import dateutil .parser
3433import git
@@ -161,7 +160,7 @@ def __str__(self):
161160 )
162161
163162
164- def get_ci_base (series : Series ) -> dict :
163+ def get_ci_base (series : Series ) -> Dict :
165164 """Retrieve the object (cover letter or patch) that we use as the base for
166165 sending emails in response to.
167166 """
@@ -260,7 +259,7 @@ def build_email(
260259 msg_id : str ,
261260 body : str ,
262261 boundary : str = "" ,
263- ) -> tuple [ list [str ], str ]:
262+ ) -> Tuple [ List [str ], str ]:
264263 """
265264 Builds complete email (including headers) to be sent along with curl command
266265 necessary to send it.
@@ -354,11 +353,13 @@ def execute_command(cmd: str) -> None:
354353 os .system (cmd )
355354
356355
357- def _uniq_tmp_folder (url : str | None , branch : str | None , base_directory : str ) -> str :
356+ def _uniq_tmp_folder (
357+ url : Optional [str ], branch : Optional [str ], base_directory : str
358+ ) -> str :
358359 # use same folder for multiple invocation to avoid cloning whole tree every time
359360 # but use different folder for different workers identified by url and branch name
360361 sha = hashlib .sha256 ()
361- sha .update (f"{ url } /{ branch } " .encode ())
362+ sha .update (f"{ url } /{ branch } " .encode ("utf-8" ))
362363 # pyre-fixme[6]: For 1st argument expected `PathLike[Variable[AnyStr <: [str,
363364 # bytes]]]` but got `Optional[str]`.
364365 repo_name = remove_unsafe_chars (os .path .basename (url ))
@@ -379,9 +380,9 @@ def temporary_patch_file(content: bytes) -> Generator[IO, None, None]:
379380 tmp_patch_file .close ()
380381
381382
382- def create_color_labels (labels_cfg : dict [str , str ], repo : Repository ) -> None :
383- repo_labels : dict [str , GithubLabel ] = {x .name .lower (): x for x in repo .get_labels ()}
384- labels_cfg : dict [str , str ] = {k .lower (): v for k , v in labels_cfg .items ()}
383+ def create_color_labels (labels_cfg : Dict [str , str ], repo : Repository ) -> None :
384+ repo_labels : Dict [str , GithubLabel ] = {x .name .lower (): x for x in repo .get_labels ()}
385+ labels_cfg : Dict [str , str ] = {k .lower (): v for k , v in labels_cfg .items ()}
385386
386387 for label , color in labels_cfg .items ():
387388 if repo_label := repo_labels .get (label ):
@@ -503,7 +504,7 @@ def slugify_context(s: str):
503504 def __init__ (
504505 self ,
505506 patchwork : Patchwork ,
506- labels_cfg : dict [str , Any ],
507+ labels_cfg : Dict [str , Any ],
507508 repo_branch : str ,
508509 repo_url : str ,
509510 upstream_url : str ,
@@ -512,10 +513,10 @@ def __init__(
512513 ci_repo_url : str ,
513514 ci_branch : str ,
514515 log_extractor : GithubLogExtractor ,
515- github_oauth_token : str | None = None ,
516- app_auth : Auth .AppInstallationAuth | None = None ,
517- email : EmailConfig | None = None ,
518- http_retries : int | None = None ,
516+ github_oauth_token : Optional [ str ] = None ,
517+ app_auth : Optional [ Auth .AppInstallationAuth ] = None ,
518+ email : Optional [ EmailConfig ] = None ,
519+ http_retries : Optional [ int ] = None ,
519520 ) -> None :
520521 super ().__init__ (
521522 repo_url = repo_url ,
@@ -547,7 +548,7 @@ def __init__(
547548 create_color_labels (labels_cfg , self .repo )
548549 # member variables
549550 self .branches = {}
550- self .prs : dict [str , PullRequest ] = {}
551+ self .prs : Dict [str , PullRequest ] = {}
551552 self .all_prs = {}
552553 self ._closed_prs = None
553554
@@ -564,7 +565,7 @@ def _add_pull_request_comment(self, pr: PullRequest, message: str) -> None:
564565 try :
565566 pr .create_issue_comment (message )
566567 except GithubException as e :
567- if not isinstance (e .data , dict ):
568+ if not isinstance (e .data , Dict ):
568569 raise e
569570 emsg = e .data .get ("message" )
570571 if emsg is not None and emsg in KNOWN_OK_COMMENT_EXCEPTIONS :
@@ -576,7 +577,7 @@ def _add_pull_request_comment(self, pr: PullRequest, message: str) -> None:
576577
577578 def _update_e2e_pr (
578579 self , title : str , base_branch : str , branch : str , has_codechange : bool
579- ) -> PullRequest | None :
580+ ) -> Optional [ PullRequest ] :
580581 """Check if there is open PR on e2e branch, reopen if necessary."""
581582 pr = None
582583
@@ -597,7 +598,9 @@ def _update_e2e_pr(
597598
598599 return pr
599600
600- def update_e2e_test_branch_and_update_pr (self , branch : str ) -> PullRequest | None :
601+ def update_e2e_test_branch_and_update_pr (
602+ self , branch : str
603+ ) -> Optional [PullRequest ]:
601604 base_branch = branch + "_base"
602605 branch_name = branch + "_test"
603606
@@ -721,8 +724,8 @@ def _close_pr(self, pr: PullRequest) -> None:
721724 pr .edit (state = "closed" )
722725
723726 async def _guess_pr (
724- self , series : Series , branch : str | None = None
725- ) -> PullRequest | None :
727+ self , series : Series , branch : Optional [ str ] = None
728+ ) -> Optional [ PullRequest ] :
726729 """
727730 Series could change name
728731 first series in a subject could be changed as well
@@ -754,11 +757,11 @@ async def _comment_series_pr(
754757 self ,
755758 series : Series ,
756759 branch_name : str ,
757- message : str | None = None ,
760+ message : Optional [ str ] = None ,
758761 can_create : bool = False ,
759762 close : bool = False ,
760763 has_merge_conflict : bool = False ,
761- ) -> PullRequest | None :
764+ ) -> Optional [ PullRequest ] :
762765 """
763766 Appends comment to a PR.
764767 """
@@ -894,7 +897,7 @@ def _add_ci_files(self) -> None:
894897
895898 async def try_apply_mailbox_series (
896899 self , branch_name : str , series : Series
897- ) -> tuple [bool , Exception | None , Any | None ]:
900+ ) -> Tuple [bool , Optional [ Exception ], Optional [ Any ] ]:
898901 """Try to apply a mailbox series and return (True, None, None) if successful"""
899902 # The pull request will be created against `repo_pr_base_branch`. So
900903 # prepare it for that.
@@ -916,7 +919,7 @@ async def try_apply_mailbox_series(
916919
917920 async def apply_push_comment (
918921 self , branch_name : str , series : Series
919- ) -> PullRequest | None :
922+ ) -> Optional [ PullRequest ] :
920923 comment = (
921924 f"Upstream branch: { self .upstream_sha } \n series: { series .web_url } \n "
922925 f"version: { series .version } \n "
@@ -999,7 +1002,7 @@ async def apply_push_comment(
9991002
10001003 async def checkout_and_patch (
10011004 self , branch_name : str , series_to_apply : Series
1002- ) -> PullRequest | None :
1005+ ) -> Optional [ PullRequest ] :
10031006 """
10041007 Patch in place and push.
10051008 Returns true if whole series applied.
@@ -1049,7 +1052,7 @@ def _is_relevant_pr(self, pr: PullRequest) -> bool:
10491052 return True
10501053 return False
10511054
1052- def closed_prs (self ) -> list [Any ]:
1055+ def closed_prs (self ) -> List [Any ]:
10531056 # GH api is not working: https://github.community/t/is-api-head-filter-even-working/135530
10541057 # so i have to implement local cache
10551058 # and local search
@@ -1061,7 +1064,7 @@ def closed_prs(self) -> list[Any]:
10611064 )
10621065 return self ._closed_prs
10631066
1064- def filter_closed_pr (self , head : str ) -> PullRequest | None :
1067+ def filter_closed_pr (self , head : str ) -> Optional [ PullRequest ] :
10651068 # this assumes only the most recent one closed PR per head
10661069 res = None
10671070 for pr in self .closed_prs ():
@@ -1092,7 +1095,7 @@ async def sync_checks(self, pr: PullRequest, series: Series) -> None:
10921095
10931096 logger .info (f"Fetching workflow runs for { pr } : { pr .head .ref } (@ { pr .head .sha } )" )
10941097
1095- statuses : list [Status ] = []
1098+ statuses : List [Status ] = []
10961099 jobs = []
10971100
10981101 # Note that we are interested in listing *all* runs and not just, say,
@@ -1162,7 +1165,7 @@ async def sync_checks(self, pr: PullRequest, series: Series) -> None:
11621165 await self .evaluate_ci_result (status , series , pr , jobs )
11631166
11641167 async def evaluate_ci_result (
1165- self , status : Status , series : Series , pr : PullRequest , jobs : list [WorkflowJob ]
1168+ self , status : Status , series : Series , pr : PullRequest , jobs : List [WorkflowJob ]
11661169 ) -> None :
11671170 """Evaluate the result of a CI run and send an email as necessary."""
11681171 email = self .email
0 commit comments