@@ -15,6 +15,25 @@ def __init__(self):
1515 self .DAYS_BEFORE_UNASSIGN = 14
1616 self .DAYS_BEFORE_CLOSE = 60
1717
18+ @staticmethod
19+ def _commit_activity_date_for_author (commit , pr_author ):
20+ dates = []
21+ if (
22+ commit .author
23+ and commit .author .login == pr_author
24+ and commit .commit .author
25+ and commit .commit .author .date
26+ ):
27+ dates .append (commit .commit .author .date )
28+ if (
29+ commit .committer
30+ and commit .committer .login == pr_author
31+ and commit .commit .committer
32+ and commit .commit .committer .date
33+ ):
34+ dates .append (commit .commit .committer .date )
35+ return max (dates , default = None )
36+
1837 def _get_last_author_activity (
1938 self ,
2039 pr ,
@@ -32,21 +51,11 @@ def _get_last_author_activity(
3251 return None
3352 last_activity = None
3453 for commit in pr .get_commits ():
35- author_date = commit .commit .author .date if commit .commit .author else None
36- committer_date = (
37- commit .commit .committer .date if commit .commit .committer else None
38- )
39- if author_date and committer_date :
40- commit_date = max (author_date , committer_date )
41- else :
42- commit_date = author_date or committer_date
54+ commit_date = self ._commit_activity_date_for_author (commit , pr_author )
4355 if not commit_date or commit_date <= after_date :
4456 continue
45- author_login = commit .author .login if commit .author else None
46- committer_login = commit .committer .login if commit .committer else None
47- if author_login == pr_author or committer_login == pr_author :
48- if not last_activity or commit_date > last_activity :
49- last_activity = commit_date
57+ if not last_activity or commit_date > last_activity :
58+ last_activity = commit_date
5059 if issue_comments is None :
5160 issue_comments = list (pr .get_issue_comments ())
5261 for comment in issue_comments :
@@ -167,28 +176,33 @@ def is_waiting_for_maintainer(
167176 return False
168177
169178 def get_last_changes_requested (self , pr , all_reviews = None ):
179+ """Timestamp of the latest CHANGES_REQUESTED that still represents
180+ a human reviewer's current stance, or ``None``.
181+ """
170182 try :
171183 if all_reviews is None :
172184 all_reviews = list (pr .get_reviews ())
185+ # Bot reviews are advisory; COMMENTED does not change stance.
173186 latest_per_reviewer = {}
174- for r in all_reviews :
175- if not r .user or not r .submitted_at :
176- continue
177- if r .user .type == "Bot" :
178- continue
179- if r .state == "COMMENTED" :
187+ for review in all_reviews :
188+ if (
189+ not review .user
190+ or not review .submitted_at
191+ or review .user .type == "Bot"
192+ or review .state == "COMMENTED"
193+ ):
180194 continue
181- current = latest_per_reviewer .get (r .user .login )
182- if current is None or r .submitted_at > current .submitted_at :
183- latest_per_reviewer [r .user .login ] = r
184- blocking = [
185- r
186- for r in latest_per_reviewer . values ()
187- if r . state == "CHANGES_REQUESTED"
188- ]
189- if not blocking :
190- return None
191- return max ( blocking , key = lambda r : r . submitted_at ). submitted_at
195+ current = latest_per_reviewer .get (review .user .login )
196+ if current is None or review .submitted_at > current .submitted_at :
197+ latest_per_reviewer [review .user .login ] = review
198+ return max (
199+ (
200+ review . submitted_at
201+ for review in latest_per_reviewer . values ()
202+ if review . state == "CHANGES_REQUESTED"
203+ ),
204+ default = None ,
205+ )
192206 except Exception as e :
193207 print ("Error getting reviews" f" for PR #{ pr .number } : { e } " )
194208 return None
0 commit comments