From 6a0cd4d96f86e7b453e7b1fdd25ac2f8ab4d91f0 Mon Sep 17 00:00:00 2001 From: Ben Du Date: Fri, 26 Jun 2026 21:53:42 -0700 Subject: [PATCH] feat(github): add `get_issues` method to `Repository` --- github_rest_api/github.py | 27 +++++++++++++++++++++++++++ tests/test_github.py | 19 +++++++++++++++++++ uv.lock | 2 +- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/github_rest_api/github.py b/github_rest_api/github.py index 2f263f5..852a4a6 100644 --- a/github_rest_api/github.py +++ b/github_rest_api/github.py @@ -203,6 +203,12 @@ def _extract_all( params["page"] += 1 +class IssueState(StrEnum): + OPEN = "open" + CLOSED = "closed" + ALL = "all" + + class Repository(GitHub): """Abstraction of a GitHub repository.""" @@ -282,6 +288,19 @@ def get_pull_requests(self, n: int = 0) -> list[dict[str, Any]]: """List pull requests in this repository.""" return self._extract_all(url=self._url_pull, n=n) + def get_issues( + self, state: IssueState = IssueState.OPEN, n: int = 0 + ) -> list[dict[str, Any]]: + """List issues in this repository. + + :param state: Filter issues by state: ``open`` (the default), + ``closed``, or ``all``. Note that GitHub's issues endpoint also + returns pull requests; each pull request carries a + ``pull_request`` key. + :param n: The maximum number of issues to return (0 means all). + """ + return self._extract_all(url=self._url_issues, params={"state": state}, n=n) + def _generate_pull_request_content( self, base: str, head: str, model: str ) -> tuple[str, str] | None: @@ -499,6 +518,14 @@ def pr_has_rust_change( """ return self.pr_has_change(pr_number=pr_number, pred=pred) + def get_issue_comments(self, issue_number: int, n: int = 0) -> list[dict[str, Any]]: + """List comments on an issue in this repository. + + :param issue_number: The number of the issue. + :param n: The maximum number of comments to return (0 means all). + """ + return self._extract_all(url=f"{self._url_issues}/{issue_number}/comments", n=n) + def create_issue_comment(self, issue_number: int, body: str) -> dict[str, Any]: """Add a new comment to an issue. diff --git a/tests/test_github.py b/tests/test_github.py index 5b38d07..a032bd2 100644 --- a/tests/test_github.py +++ b/tests/test_github.py @@ -76,6 +76,25 @@ def test_repository_get_branch(): assert branch["name"] == "main" +def test_get_issues_passes_url_and_state(): + repo = Repository("token", "owner/name") + with patch.object(repo, "_extract_all", return_value=[]) as mock_extract: + repo.get_issues() + assert mock_extract.call_args.kwargs["url"] == ( + "https://api.github.com/repos/owner/name/issues" + ) + assert mock_extract.call_args.kwargs["params"] == {"state": "open"} + + +def test_get_issue_comments_passes_url(): + repo = Repository("token", "owner/name") + with patch.object(repo, "_extract_all", return_value=[]) as mock_extract: + repo.get_issue_comments(7) + assert mock_extract.call_args.kwargs["url"] == ( + "https://api.github.com/repos/owner/name/issues/7/comments" + ) + + def test_compare_url_encodes_branch_names(): repo = Repository("token", "owner/name") response = MagicMock() diff --git a/uv.lock b/uv.lock index 7d5df6b..5ee520e 100644 --- a/uv.lock +++ b/uv.lock @@ -542,7 +542,7 @@ wheels = [ [[package]] name = "github-rest-api" -version = "0.42.1" +version = "0.43.0" source = { editable = "." } dependencies = [ { name = "dulwich" },