Repository: brettcannon/gidgethub (python)

Issue:
202 ACCEPTED considered as error
From here, it looks like the only correct HTTP status codes are 200 OK, 201 CREATED, and 204 NO CONTENT:

https://github.com/brettcannon/gidgethub/blob/8724568f87efe1a13c8e0e2251969c1ba9940c7a/gidgethub/sansio.py#L316-L318

However, some endpoints may also return 202 ACCEPTED, like `POST /repos/{owner}/{repo}/forks`:

https://docs.github.com/en/rest/reference/repos#create-a-fork

From [RFC7231 Section 6.3.3](https://datatracker.ietf.org/doc/html/rfc7231#section-6.3.3) I read

> The 202 (Accepted) status code indicates that the request has been
   accepted for processing, but the processing has not been completed.
   The request might or might not eventually be acted upon, as it might
   be disallowed when processing actually takes place.

> The 202 response is intentionally noncommittal.  Its purpose is to
   allow a server to accept a request for some other process (perhaps a
   batch-oriented process that is only run once per day) without
   requiring that the user agent's connection to the server persist
   until the process is completed.

This is consistent with what the GH docs say:

> **Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Support.

Should 202 be treated as successful instead?

Pull request:
Properly handle HTTP 202 ACCEPTED as successful
Closes #171.

Patch:
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 5f76395..ecc17c5 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -27,6 +27,8 @@ branch.
 
 Ensure that the tests are all passing, and that the coverage remains at 100%.
 
+Ensure that the code the quality checks by running ``nox --session lint``.
+
 Update the documentation as needed.
 
 Update the changelog as needed.
diff --git a/docs/changelog.rst b/docs/changelog.rst
index 52d484e..1e94e88 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -14,6 +14,9 @@ Changelog
   in order to support the Checks API.
   (`Issue #164 <https://github.com/brettcannon/gidgethub/issues/164>`_)
 
+- Accept HTTP 202 ACCEPTED as successful.
+  (`PR #174 <https://github.com/brettcannon/gidgethub/pull/174>`_)
+
 5.0.1
 -----
 
diff --git a/gidgethub/sansio.py b/gidgethub/sansio.py
index 5641920..c8ac72e 100644
--- a/gidgethub/sansio.py
+++ b/gidgethub/sansio.py
@@ -323,7 +323,7 @@ def decipher_response(
     an HTTPException is raised.
     """
     data = _decode_body(headers.get("content-type"), body)
-    if status_code in {200, 201, 204}:
+    if status_code in {200, 201, 202, 204}:
         return data, RateLimit.from_http(headers), _next_link(headers.get("link"))
     else:
         try:


Test patch:
diff --git a/tests/test_sansio.py b/tests/test_sansio.py
index 34e1ab3..2a8d521 100644
--- a/tests/test_sansio.py
+++ b/tests/test_sansio.py
@@ -442,6 +442,28 @@ class TestDecipherResponse:
         assert rate_limit.limit == 60
         assert returned_data == data
 
+    def test_202(self):
+        # https://github.com/brettcannon/gidgethub/issues/171
+        status_code = 202
+        headers = {
+            "x-ratelimit-limit": "5000",
+            "x-ratelimit-remaining": "4987",
+            "x-ratelimit-reset": "1641847010",
+            "content-type": "application/json; charset=utf-8",
+        }
+        data = {
+            "id": 446_568_946,
+            "name": "Hello-World",
+            "fork": True,
+            "forks": 0,
+        }
+        body = json.dumps(data).encode("UTF-8")
+        returned_data, rate_limit, more = sansio.decipher_response(
+            status_code, headers, body
+        )
+        assert more is None
+        assert returned_data == data
+
     def test_204(self):
         """Test both a 204 response and an empty response body."""
         status_code = 204