2727)
2828
2929
30+ PipAuditEntry = dict [str , str | list [str ] | tuple [str , ...]]
31+
32+
3033@dataclass
3134class PipAuditException (Exception ):
32- return_code : int
35+ returncode : int
3336 stdout : str
3437 stderr : str
3538
36- def __init__ (self , subprocess_output : subprocess .CompletedProcess ) -> None :
37- self .return_code = subprocess_output .returncode
38- self .stdout = subprocess_output .stdout
39- self .stderr = subprocess_output .stderr
39+ @classmethod
40+ def from_subprocess (cls , proc : subprocess .CompletedProcess ) -> PipAuditException :
41+ return cls (proc .returncode , proc .stdout , proc .stderr )
4042
4143
4244class VulnerabilitySource (str , Enum ):
@@ -102,7 +104,7 @@ def reference_links(self) -> tuple[str, ...]:
102104 )
103105
104106 @property
105- def security_issue_entry (self ) -> dict [ str , str | list [ str ] | tuple [ str , ...]] :
107+ def security_issue_entry (self ) -> PipAuditEntry :
106108 return {
107109 "name" : self .package .name ,
108110 "version" : str (self .package .version ),
@@ -132,10 +134,20 @@ def subsection_for_changelog_summary(self) -> str:
132134 """
133135 Create a subsection to be included in the Summary section of a versioned changelog.
134136 """
135- links_join = "\n * " .join (sorted (self .reference_links ))
136- references_subsection = f"\n #### References:\n \n * { links_join } \n \n "
137- subsection = f"### { self .vulnerability_id } in { self .package .coordinates } \n \n { self .description } \n { references_subsection } "
138- return cleandoc (subsection .strip ())
137+ indent = " " * 12
138+ references = f"\n { indent } " .join (
139+ f"* { link } " for link in sorted (self .reference_links )
140+ )
141+ description = self .description .replace ("\n " , f"\n { indent } " )
142+ return cleandoc (f"""
143+ ### { self .vulnerability_id } in { self .package .coordinates }
144+
145+ { description }
146+
147+ #### References
148+
149+ { references }
150+ """ )
139151
140152
141153def audit_poetry_files (working_directory : Path ) -> str :
@@ -159,7 +171,7 @@ def audit_poetry_files(working_directory: Path) -> str:
159171 cwd = working_directory ,
160172 ) # nosec
161173 if output .returncode != 0 :
162- raise PipAuditException ( subprocess_output = output )
174+ raise PipAuditException . from_subprocess ( output )
163175
164176 with tempfile .TemporaryDirectory () as path :
165177 tmpdir = Path (path )
@@ -179,7 +191,7 @@ def audit_poetry_files(working_directory: Path) -> str:
179191 # they both map to returncode = 1, so we have our own logic to raise errors
180192 # for the case of 2) and not 1).
181193 if not search (PIP_AUDIT_VULNERABILITY_PATTERN , output .stderr .strip ()):
182- raise PipAuditException ( subprocess_output = output )
194+ raise PipAuditException . from_subprocess ( output )
183195 return output .stdout
184196
185197
@@ -215,7 +227,7 @@ def load_from_pip_audit(cls, working_directory: Path) -> Vulnerabilities:
215227 return Vulnerabilities (vulnerabilities = vulnerabilities )
216228
217229 @property
218- def security_issue_dict (self ) -> list [dict [ str , str | list [ str ] | tuple [ str , ...]] ]:
230+ def security_issue_dict (self ) -> list [PipAuditEntry ]:
219231 return [
220232 vulnerability .security_issue_entry for vulnerability in self .vulnerabilities
221233 ]
0 commit comments