1616
1717import requests
1818import requests_cache
19+ import tomli
1920from github import Github
2021from github .Commit import Commit
2122from github .NamedUser import NamedUser
@@ -205,6 +206,25 @@ def contributors(
205206 return authors , reviewers
206207
207208
209+ def pyproject_dependencies (
210+ gh : Github ,
211+ org_repo : str ,
212+ rev : str ,
213+ ):
214+ """Fetch runtime dependencies from pyproject.toml at the given revision."""
215+ repo = gh .get_repo (org_repo )
216+ file = repo .get_contents ("pyproject.toml" , ref = rev )
217+ meta_data = tomli .loads (file .decoded_content .decode ())
218+
219+ runtime_dependencies = []
220+ python_dep = meta_data .get ("project" , {}).get ("requires-python" )
221+ if python_dep :
222+ runtime_dependencies += [f"python{ python_dep } " ]
223+ runtime_dependencies += meta_data .get ("project" , {}).get ("dependencies" , [])
224+
225+ return runtime_dependencies
226+
227+
208228@dataclass (frozen = True , kw_only = True )
209229class MdFormatter :
210230 """Format release notes in Markdown from PRs, authors and reviewers."""
@@ -213,6 +233,7 @@ class MdFormatter:
213233 pull_requests : set [PullRequest ]
214234 authors : set [Union [NamedUser ]]
215235 reviewers : set [NamedUser ]
236+ runtime_dependencies : list [str ]
216237
217238 version : str = "x.y.z"
218239 title_template : str = "{repo_name} {version}"
@@ -262,6 +283,7 @@ def iter_lines(self) -> Iterable[str]:
262283 yield from self ._format_intro ()
263284 for title , pull_requests in self ._prs_by_section .items ():
264285 yield from self ._format_pr_section (title , pull_requests )
286+ yield from self ._format_dependencies_section (self .runtime_dependencies )
265287 yield from self ._format_contributor_section (self .authors , self .reviewers )
266288 yield from self ._format_outro ()
267289
@@ -342,6 +364,17 @@ def _format_user_line(self, user: Union[NamedUser]) -> str:
342364 line = f"{ user .name } ({ line } )"
343365 return line + ",\n "
344366
367+ def _format_dependencies_section (self , runtime_dependencies ):
368+ """Format dependencies section."""
369+ if runtime_dependencies :
370+ yield from self ._format_section_title ("Dependencies" , level = 2 )
371+ yield "\n "
372+
373+ yield "These dependencies are required at runtime if PyPI is used:\n "
374+ for dep in runtime_dependencies :
375+ yield self ._sanitize_text (f"- `{ dep } `" ) + "\n "
376+ yield "\n "
377+
345378 def _format_contributor_section (
346379 self ,
347380 authors : set [Union [NamedUser ]],
@@ -495,6 +528,8 @@ def main(
495528 commits = lazy_tqdm (commits , desc = "Fetching authors" ),
496529 pull_requests = lazy_tqdm (pull_requests , desc = "Fetching reviewers" ),
497530 )
531+ print ("Fetching dependencies from pyproject.toml..." )
532+ runtime_dependencies = pyproject_dependencies (gh , org_repo , stop_rev )
498533
499534 Formatter = {"md" : MdFormatter , "rst" : RstFormatter }[format ]
500535 formatter = Formatter (
@@ -503,6 +538,7 @@ def main(
503538 authors = authors ,
504539 reviewers = reviewers ,
505540 version = version ,
541+ runtime_dependencies = runtime_dependencies ,
506542 )
507543
508544 if out :
0 commit comments