]> git.ipfire.org Git - thirdparty/httpx.git/commitdiff
Single consistent name for status codes (#1088)
authorTom Christie <tom@tomchristie.com>
Mon, 27 Jul 2020 13:35:01 +0000 (14:35 +0100)
committerGitHub <noreply@github.com>
Mon, 27 Jul 2020 13:35:01 +0000 (14:35 +0100)
* Single consistent name for status codes
* Gentle deprecation for httpx.StatusCode

httpx/__init__.py
httpx/_models.py
httpx/_status_codes.py
tests/test_status_codes.py

index b88c9a84a17c1b5f3af579efbaabde74960385c9..644656fd19bfb839675e46e0af80b2f60d3d1114 100644 (file)
@@ -80,6 +80,7 @@ __all__ = [
     "ResponseClosed",
     "ResponseNotRead",
     "RequestNotRead",
+    "StatusCode",
     "StreamConsumed",
     "StreamError",
     "ProxyError",
@@ -90,7 +91,6 @@ __all__ = [
     "URL",
     "URLLib3Transport",
     "URLLib3ProxyTransport",
-    "StatusCode",
     "Cookies",
     "Headers",
     "QueryParams",
index 785bf4721370907bd872281f9c085d09ea82693a..c8cbfbb449114b5e984c3bdd14828d9caf46ba36 100644 (file)
@@ -30,7 +30,7 @@ from ._exceptions import (
     ResponseNotRead,
     StreamConsumed,
 )
-from ._status_codes import StatusCode
+from ._status_codes import codes
 from ._types import (
     CookieTypes,
     HeaderTypes,
@@ -660,7 +660,7 @@ class Response:
 
     @property
     def reason_phrase(self) -> str:
-        return StatusCode.get_reason_phrase(self.status_code)
+        return codes.get_reason_phrase(self.status_code)
 
     @property
     def url(self) -> typing.Optional[URL]:
@@ -758,11 +758,11 @@ class Response:
 
     @property
     def is_error(self) -> bool:
-        return StatusCode.is_error(self.status_code)
+        return codes.is_error(self.status_code)
 
     @property
     def is_redirect(self) -> bool:
-        return StatusCode.is_redirect(self.status_code) and "location" in self.headers
+        return codes.is_redirect(self.status_code) and "location" in self.headers
 
     def raise_for_status(self) -> None:
         """
@@ -773,10 +773,10 @@ class Response:
             "For more information check: https://httpstatuses.com/{0.status_code}"
         )
 
-        if StatusCode.is_client_error(self.status_code):
+        if codes.is_client_error(self.status_code):
             message = message.format(self, error_type="Client Error")
             raise HTTPStatusError(message, response=self)
-        elif StatusCode.is_server_error(self.status_code):
+        elif codes.is_server_error(self.status_code):
             message = message.format(self, error_type="Server Error")
             raise HTTPStatusError(message, response=self)
 
index eda7c562d73daddafc4d71961b66fa746c636582..3b4ae6a98f74288909b5e3f722edd873472bad7d 100644 (file)
@@ -1,7 +1,8 @@
+import warnings
 from enum import IntEnum
 
 
-class StatusCode(IntEnum):
+class codes(IntEnum):
     """HTTP status codes and reason phrases
     Status codes from the following RFCs are all observed:
         * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616
@@ -17,7 +18,7 @@ class StatusCode(IntEnum):
         * RFC 7725: An HTTP Status Code to Report Legal Obstacles
     """
 
-    def __new__(cls, value: int, phrase: str = "") -> "StatusCode":
+    def __new__(cls, value: int, phrase: str = "") -> "codes":
         obj = int.__new__(cls, value)  # type: ignore
         obj._value_ = value
 
@@ -30,7 +31,7 @@ class StatusCode(IntEnum):
     @classmethod
     def get_reason_phrase(cls, value: int) -> str:
         try:
-            return StatusCode(value).phrase  # type: ignore
+            return codes(value).phrase  # type: ignore
         except ValueError:
             return ""
 
@@ -38,15 +39,15 @@ class StatusCode(IntEnum):
     def is_redirect(cls, value: int) -> bool:
         return value in (
             # 301 (Cacheable redirect. Method may change to GET.)
-            StatusCode.MOVED_PERMANENTLY,
+            codes.MOVED_PERMANENTLY,
             # 302 (Uncacheable redirect. Method may change to GET.)
-            StatusCode.FOUND,
+            codes.FOUND,
             # 303 (Client should make a GET or HEAD request.)
-            StatusCode.SEE_OTHER,
+            codes.SEE_OTHER,
             # 307 (Equiv. 302, but retain method)
-            StatusCode.TEMPORARY_REDIRECT,
+            codes.TEMPORARY_REDIRECT,
             # 308 (Equiv. 301, but retain method)
-            StatusCode.PERMANENT_REDIRECT,
+            codes.PERMANENT_REDIRECT,
         )
 
     @classmethod
@@ -132,8 +133,26 @@ class StatusCode(IntEnum):
     NETWORK_AUTHENTICATION_REQUIRED = 511, "Network Authentication Required"
 
 
-codes = StatusCode
-
 #  Include lower-case styles for `requests` compatibility.
 for code in codes:
     setattr(codes, code._name_.lower(), int(code))
+
+
+class StatusCodeCompat:
+    def __call__(self, *args, **kwargs):  # type: ignore
+        message = "`httpx.StatusCode` is deprecated. Use `httpx.codes` instead."
+        warnings.warn(message, DeprecationWarning)
+        return codes(*args, **kwargs)
+
+    def __getattr__(self, attr):  # type: ignore
+        message = "`httpx.StatusCode` is deprecated. Use `httpx.codes` instead."
+        warnings.warn(message, DeprecationWarning)
+        return getattr(codes, attr)
+
+    def __getitem__(self, item):  # type: ignore
+        message = "`httpx.StatusCode` is deprecated. Use `httpx.codes` instead."
+        warnings.warn(message, DeprecationWarning)
+        return codes[item]
+
+
+StatusCode = StatusCodeCompat()
index c53e95965d57d3c3f08f24a072703265b6184d00..722e83c527758a2a9d70fbaab53ba58435432440 100644 (file)
@@ -1,3 +1,5 @@
+import pytest
+
 import httpx
 
 
@@ -6,6 +8,14 @@ def test_status_code_as_int():
     assert str(httpx.codes.NOT_FOUND) == "404"
 
 
+def test_status_code_value_lookup():
+    assert httpx.codes(404) == 404
+
+
+def test_status_code_phrase_lookup():
+    assert httpx.codes["NOT_FOUND"] == 404
+
+
 def test_lowercase_status_code():
     assert httpx.codes.not_found == 404  # type: ignore
 
@@ -16,3 +26,14 @@ def test_reason_phrase_for_status_code():
 
 def test_reason_phrase_for_unknown_status_code():
     assert httpx.codes.get_reason_phrase(499) == ""
+
+
+def test_deprecated_status_code_class():
+    with pytest.warns(DeprecationWarning):
+        assert httpx.StatusCode.NOT_FOUND == 404
+
+    with pytest.warns(DeprecationWarning):
+        assert httpx.StatusCode(404) == 404
+
+    with pytest.warns(DeprecationWarning):
+        assert httpx.StatusCode["NOT_FOUND"] == 404