]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-95149: Enhance `http.HTTPStatus` with properties that indicate the HTTP status...
authorAlexandru Mărășteanu <alexei@users.noreply.github.com>
Tue, 30 Aug 2022 18:11:44 +0000 (21:11 +0300)
committerGitHub <noreply@github.com>
Tue, 30 Aug 2022 18:11:44 +0000 (11:11 -0700)
Doc/library/http.rst
Lib/enum.py
Lib/http/__init__.py
Lib/test/test_httplib.py
Misc/NEWS.d/next/Library/2022-08-07-14-56-23.gh-issue-95149.U0c6Ib.rst [new file with mode: 0644]

index 5895a41d849bd19ff1aaa9333dc33f1b1004b3ec..521fd1b7f50cdc49b651eb343017f4e062589abb 100644 (file)
@@ -137,6 +137,31 @@ equal to the constant name (i.e. ``http.HTTPStatus.OK`` is also available as
 .. versionadded:: 3.9
    Added ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` status codes.
 
+HTTP status category
+--------------------
+
+.. versionadded:: 3.11
+
+The enum values have several properties to indicate the HTTP status category:
+
+==================== ======================== ===============================
+Property             Indicates that           Details
+==================== ======================== ===============================
+``is_informational`` ``100 <= status <= 199`` HTTP/1.1 :rfc:`7231`, Section 6
+``is_success``       ``200 <= status <= 299`` HTTP/1.1 :rfc:`7231`, Section 6
+``is_redirection``   ``300 <= status <= 399`` HTTP/1.1 :rfc:`7231`, Section 6
+``is_client_error``  ``400 <= status <= 499`` HTTP/1.1 :rfc:`7231`, Section 6
+``is_server_error``  ``500 <= status <= 599`` HTTP/1.1 :rfc:`7231`, Section 6
+==================== ======================== ===============================
+
+   Usage::
+
+      >>> from http import HTTPStatus
+      >>> HTTPStatus.OK.is_success
+      True
+      >>> HTTPStatus.OK.is_client_error
+      False
+
 .. class:: HTTPMethod
 
    .. versionadded:: 3.11
index 8ef69589a14699d7cf4e485525ae56217b5bd77f..e7375e1eae691f915ed7143a73a2da46f06fd43c 100644 (file)
@@ -1887,7 +1887,7 @@ def _test_simple_enum(checked_enum, simple_enum):
             else:
                 checked_value = checked_dict[key]
                 simple_value = simple_dict[key]
-                if callable(checked_value):
+                if callable(checked_value) or isinstance(checked_value, bltns.property):
                     continue
                 if key == '__doc__':
                     # remove all spaces/tabs
index cd2885dc7757b4530ed7d97852c17f3f28cddd8a..e093a1fec4dffca320d4078572904a8a32c36ca5 100644 (file)
@@ -31,6 +31,26 @@ class HTTPStatus:
         obj.description = description
         return obj
 
+    @property
+    def is_informational(self):
+        return 100 <= self <= 199
+
+    @property
+    def is_success(self):
+        return 200 <= self <= 299
+
+    @property
+    def is_redirection(self):
+        return 300 <= self <= 399
+
+    @property
+    def is_client_error(self):
+        return 400 <= self <= 499
+
+    @property
+    def is_server_error(self):
+        return 500 <= self <= 599
+
     # informational
     CONTINUE = 100, 'Continue', 'Request received, please continue'
     SWITCHING_PROTOCOLS = (101, 'Switching Protocols',
index 15dab0356f5e35e759ea2c5c8800dea564baf87f..b3d94e0a21cb6a9e3834153a0a38f2499f76eac8 100644 (file)
@@ -553,6 +553,27 @@ class BasicTest(TestCase):
                 obj.phrase = phrase
                 obj.description = description
                 return obj
+
+            @property
+            def is_informational(self):
+                return 100 <= self <= 199
+
+            @property
+            def is_success(self):
+                return 200 <= self <= 299
+
+            @property
+            def is_redirection(self):
+                return 300 <= self <= 399
+
+            @property
+            def is_client_error(self):
+                return 400 <= self <= 499
+
+            @property
+            def is_server_error(self):
+                return 500 <= self <= 599
+
             # informational
             CONTINUE = 100, 'Continue', 'Request received, please continue'
             SWITCHING_PROTOCOLS = (101, 'Switching Protocols',
@@ -669,6 +690,30 @@ class BasicTest(TestCase):
                 'The client needs to authenticate to gain network access')
         enum._test_simple_enum(CheckedHTTPStatus, HTTPStatus)
 
+    def test_httpstatus_range(self):
+        """Checks that the statuses are in the 100-599 range"""
+
+        for member in HTTPStatus.__members__.values():
+            self.assertGreaterEqual(member, 100)
+            self.assertLessEqual(member, 599)
+
+    def test_httpstatus_category(self):
+        """Checks that the statuses belong to the standard categories"""
+
+        categories = (
+            ((100, 199), "is_informational"),
+            ((200, 299), "is_success"),
+            ((300, 399), "is_redirection"),
+            ((400, 499), "is_client_error"),
+            ((500, 599), "is_server_error"),
+        )
+        for member in HTTPStatus.__members__.values():
+            for (lower, upper), category in categories:
+                category_indicator = getattr(member, category)
+                if lower <= member <= upper:
+                    self.assertTrue(category_indicator)
+                else:
+                    self.assertFalse(category_indicator)
 
     def test_status_lines(self):
         # Test HTTP status lines
diff --git a/Misc/NEWS.d/next/Library/2022-08-07-14-56-23.gh-issue-95149.U0c6Ib.rst b/Misc/NEWS.d/next/Library/2022-08-07-14-56-23.gh-issue-95149.U0c6Ib.rst
new file mode 100644 (file)
index 0000000..6393444
--- /dev/null
@@ -0,0 +1,2 @@
+The :class:`HTTPStatus <http.HTTPStatus>` enum offers a couple of properties
+to indicate the HTTP status category e.g. ``HTTPStatus.OK.is_success``.