Skip to content

DOC: Added Docstrings to announce.py and contributors.py #58848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 189 additions & 1 deletion doc/sphinxext/announce.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,52 @@


def get_authors(revision_range):
"""
Get authors from git log.

This function retrieves the authors from the git log within the specified
revision range. It compares the authors from the current release to those
from the previous release to determine the authors for the current release.

Parameters
----------
revision_range : str
The revision range to get the authors from, specified in the format
'previous_revision..current_revision'.

Returns
-------
authors : list
A list of authors sorted alphabetically, with new authors (not present
in the previous release) marked with a '+'.

See Also
--------
CONTRIBUTOR_MAPPING : dict
A mapping of contributors' names for renaming purposes.

Notes
-----
- The function assumes that the `this_repo` object is an instance of a Git
repository and that it has methods like `git.log` and `git.shortlog` to
fetch commit logs and short logs, respectively.
- The `revision_range` parameter should be a valid range in the format
'previous_revision..current_revision'. If the current revision includes
`HEAD`, it should be specified as 'previous_revision..current_revision|HEAD'.
- The function handles `Co-authored-by` commits separately to account for
backported changes, which are typically merged by bots.
- The function discards contributions by automated merge bots (e.g., 'Homu')
to provide a cleaner list of human contributors.
- Contributor names are updated according to the `CONTRIBUTOR_MAPPING` to
ensure consistent naming.

Examples
--------
>>> get_authors('v1.0.0..v1.0.1')
['Joris Van den Bossche', 'Tom Augspurger', 'Jeff Reback', 'Philip Cloud', 'Stephan Hoyer']
>>> get_authors('v1.0.1..HEAD')
['Joris Van den Bossche', 'Tom Augspurger', 'Jeff Reback', 'Philip Cloud', 'Stephan Hoyer', 'Simon Hawkins +']
"""
pat = "^.*\\t(.*)$"
lst_release, cur_release = (r.strip() for r in revision_range.split(".."))

Expand Down Expand Up @@ -109,6 +155,42 @@ def get_authors(revision_range):


def get_pull_requests(repo, revision_range):
"""
Retrieve a list of pull requests merged in a given revision range of a repository.

This function identifies pull requests from regular merges, Homu auto merges,
and fast forward squash-merges within the specified revision range, and returns
a list of pull request objects from the GitHub repository.

Parameters
----------
repo : object
A GitHub repository object that provides the method `get_pull` to retrieve pull request data.
revision_range : str
The revision range to search for merged pull requests, specified in the format
'start_revision..end_revision'.

Returns
-------
list
A list of pull request objects corresponding to the pull request numbers found in the specified
revision range.

Notes
-----
- The function assumes that the `this_repo` object is an instance of a Git repository
and that it has a method `git.log` to fetch commit logs.
- Pull request numbers are identified from commit messages that follow specific patterns:
- "Merge pull request #<number>"
- "Auto merge of #<number>"
- "fast forward squash-merge (#<number>)"
- The function sorts the pull request numbers before retrieving the pull request objects.

Examples
--------
>>> get_pull_requests(repo, 'v1.0.0..v1.1.0')
[<PullRequest #123>, <PullRequest #124>, <PullRequest #125>]
"""
prnums = []

# From regular merges
Expand All @@ -134,6 +216,45 @@ def get_pull_requests(repo, revision_range):


def build_components(revision_range, heading="Contributors"):
"""
Build components for the contributors section based on a revision range.

This function generates the components needed for constructing a formatted
contributors section. It extracts the list of authors who contributed within
the specified revision range and prepares a dictionary with the heading, a
message about the authors, and the list of authors.

Parameters
----------
revision_range : str
The revision range to get the contributors from, specified in the format
'start_revision..end_revision'.
heading : str, optional
The heading for the contributors section. Default is "Contributors".

Returns
-------
dict
A dictionary with the following keys:
- "heading" : str
The heading for the contributors section.
- "author_message" : str
A message about the number of authors.
- "authors" : list
A list of authors who contributed within the specified revision range.

Notes
-----
- The function assumes that the `get_authors` function is available and returns a list of authors
for the given revision range.
- The `author_msg` string is assumed to be a template string that takes a single integer, representing
the number of authors.

Examples
--------
>>> build_components('v1.0.0..v1.1.0')
{'heading': 'Contributors', 'author_message': 'There are 5 contributors:', 'authors': ['Author One', 'Author Two']}
"""
lst_release, cur_release = (r.strip() for r in revision_range.split(".."))
authors = get_authors(revision_range)

Expand All @@ -145,6 +266,39 @@ def build_components(revision_range, heading="Contributors"):


def build_string(revision_range, heading="Contributors"):
"""
Build a formatted string of contributors for a given revision range.

This function constructs a formatted string listing the contributors within the specified
revision range, including a heading and a list of authors. The heading is underlined for
emphasis, and the authors are listed with bullet points.

Parameters
----------
revision_range : str
The revision range to get the contributors from, specified in the format
'start_revision..end_revision'.
heading : str, optional
The heading for the contributors section. Default is "Contributors".

Returns
-------
str
A formatted string with the heading, underlined heading, a message, and a list of authors.

Notes
-----
- The function assumes that the `build_components` function is available and returns a dictionary
with keys "heading", "author_message", and "authors".
- The length of the underline is dynamically set to match the length of the heading.
- Authors are listed with bullet points, each preceded by an asterisk (*) and a newline character.
- The `textwrap.dedent` method is used to maintain proper formatting of the template string.

Examples
--------
>>> build_string('v1.0.0..v1.1.0')
'Contributors\n============\n\nList of authors who contributed:\n* Author One\n* Author Two'
"""
components = build_components(revision_range, heading=heading)
components["uline"] = "=" * len(components["heading"])
components["authors"] = "* " + "\n* ".join(components["authors"])
Expand All @@ -162,7 +316,41 @@ def build_string(revision_range, heading="Contributors"):


def main(revision_range):
# document authors
"""
Generate and print the contributors list for a given revision range.

This function builds a formatted string of contributors who have made changes
within the specified revision range and prints it to the standard output.

Parameters
----------
revision_range : str
The revision range to get the contributors from, specified in the format
'start_revision..end_revision'.

Returns
-------
None

Notes
-----
- The function relies on `build_string` to generate the formatted contributors list.
- The contributors list includes a heading, an underlined heading, a message about the authors,
and a list of authors with new contributors marked.

Examples
--------
>>> main('v1.0.0..v1.1.0')

Authors
============
- TomAugspurger
- gfyoung
- datapythonista
- jreback
- jschendel
- ...
"""
text = build_string(revision_range)
print(text)

Expand Down
31 changes: 31 additions & 0 deletions doc/sphinxext/contributors.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ class ContributorsDirective(Directive):
name = "contributors"

def run(self):
"""
Execute the contributors directive.

This method processes the provided revision range and generates the corresponding
list of contributors.

Returns
-------
list
A list of nodes representing the message indicating the number of contributors
and commits, and a bullet list containing each contributor individually.
"""
range_ = self.arguments[0]
if range_.endswith("x..HEAD"):
return [nodes.paragraph(), nodes.bullet_list()]
Expand Down Expand Up @@ -53,6 +65,25 @@ def run(self):


def setup(app):
"""
Setup function for the Sphinx extension.

This function registers the `contributors` directive with the Sphinx application.

Parameters
----------
app : sphinx.application.Sphinx
The Sphinx application object.

Returns
-------
dict
A dictionary containing metadata about the extension.

Notes
-----
- This function is typically called by Sphinx during the initialization phase.
"""
app.add_directive("contributors", ContributorsDirective)

return {"version": "0.1", "parallel_read_safe": True, "parallel_write_safe": True}
Loading