2929import os
3030import re
3131import sys
32- from typing import Dict , List , Optional , Sequence , Tuple , NamedTuple
32+ from typing import List , Optional , Sequence , Tuple , NamedTuple , DefaultDict
33+ from collections import defaultdict
3334from operator import itemgetter
3435
3536# Matches a :doc:`label <path>` or :doc:`label` reference anywhere in text and
@@ -133,10 +134,9 @@ def _normalize_list_rst_lines(lines: Sequence[str]) -> List[str]:
133134 n = len (lines )
134135
135136 def check_name (line : str ):
136- m = DOC_LINE_RE .match (line )
137- if not m :
138- return (1 , "" )
139- return (0 , m .group ("label" ))
137+ if m := DOC_LINE_RE .match (line ):
138+ return (0 , m .group ("label" ))
139+ return (1 , "" )
140140
141141 while i < n :
142142 line = lines [i ]
@@ -182,8 +182,11 @@ def find_heading(lines: Sequence[str], title: str) -> Optional[int]:
182182 """
183183 for i in range (len (lines ) - 1 ):
184184 if lines [i ].rstrip ("\n " ) == title :
185- underline = lines [i + 1 ].rstrip ("\n " )
186- if underline and set (underline ) == {"^" } and len (underline ) == len (title ):
185+ if (
186+ (underline := lines [i + 1 ].rstrip ("\n " ))
187+ and set (underline ) == {"^" }
188+ and len (underline ) == len (title )
189+ ):
187190 return i
188191 return None
189192
@@ -249,9 +252,9 @@ def find_duplicate_entries(
249252 key = extract_label (block [0 ])
250253 blocks_with_pos .append ((key , bstart , block ))
251254
252- grouped : Dict [CheckLabel , DuplicateOccurrences ] = {}
255+ grouped : DefaultDict [CheckLabel , DuplicateOccurrences ] = defaultdict ( list )
253256 for key , start , block in blocks_with_pos :
254- grouped . setdefault ( key , []) .append ((start , block ))
257+ grouped [ key ] .append ((start , block ))
255258
256259 result : List [Tuple [CheckLabel , DuplicateOccurrences ]] = []
257260 for key , occs in grouped .items ():
@@ -271,16 +274,14 @@ def _find_section_bounds(
271274 - sec_start: index of the first content line after underline
272275 - sec_end: index of the first line of the next section title (or end)
273276 """
274- h_start = find_heading (lines , title )
275- if h_start is None :
277+ if (h_start := find_heading (lines , title )) is None :
276278 return None
277279
278280 sec_start = h_start + 2
279281
280282 # Determine end of section either from next_title or by scanning.
281283 if next_title is not None :
282- h_end = find_heading (lines , next_title )
283- if h_end is None :
284+ if (h_end := find_heading (lines , next_title )) is None :
284285 # Scan forward to the next heading-like underline.
285286 h_end = sec_start
286287 while h_end + 1 < len (lines ):
@@ -304,8 +305,7 @@ def _normalize_release_notes_section(
304305 lines : Sequence [str ], title : str , next_title : Optional [str ]
305306) -> List [str ]:
306307 """Normalize a single release-notes section and return updated lines."""
307- bounds = _find_section_bounds (lines , title , next_title )
308- if bounds is None :
308+ if (bounds := _find_section_bounds (lines , title , next_title )) is None :
309309 return list (lines )
310310 _ , sec_start , sec_end = bounds
311311
@@ -339,8 +339,7 @@ def normalize_release_notes(lines: Sequence[str]) -> str:
339339
340340
341341def _emit_duplicate_report (lines : Sequence [str ], title : str ) -> Optional [str ]:
342- dups_detail = find_duplicate_entries (lines , title )
343- if not dups_detail :
342+ if not (dups_detail := find_duplicate_entries (lines , title )):
344343 return None
345344 out : List [str ] = []
346345 out .append (f"Error: Duplicate entries in '{ title } ':\n " )
@@ -367,8 +366,7 @@ def process_release_notes(out_path: str, rn_doc: str) -> int:
367366 return 0
368367
369368 # Ordering is clean then enforce duplicates.
370- report = _emit_duplicate_report (lines , "Changes in existing checks" )
371- if report :
369+ if report := _emit_duplicate_report (lines , "Changes in existing checks" ):
372370 sys .stderr .write (report )
373371 return 3
374372 return 0
0 commit comments