Skip to content

Commit 0ed7788

Browse files
authored
gh-95149: Enhance http.HTTPStatus with properties that indicate the HTTP status category (GH-95453)
1 parent 13c309f commit 0ed7788

File tree

5 files changed

+93
-1
lines changed

5 files changed

+93
-1
lines changed

Doc/library/http.rst

+25
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,31 @@ equal to the constant name (i.e. ``http.HTTPStatus.OK`` is also available as
137137
.. versionadded:: 3.9
138138
Added ``103 EARLY_HINTS``, ``418 IM_A_TEAPOT`` and ``425 TOO_EARLY`` status codes.
139139

140+
HTTP status category
141+
--------------------
142+
143+
.. versionadded:: 3.11
144+
145+
The enum values have several properties to indicate the HTTP status category:
146+
147+
==================== ======================== ===============================
148+
Property Indicates that Details
149+
==================== ======================== ===============================
150+
``is_informational`` ``100 <= status <= 199`` HTTP/1.1 :rfc:`7231`, Section 6
151+
``is_success`` ``200 <= status <= 299`` HTTP/1.1 :rfc:`7231`, Section 6
152+
``is_redirection`` ``300 <= status <= 399`` HTTP/1.1 :rfc:`7231`, Section 6
153+
``is_client_error`` ``400 <= status <= 499`` HTTP/1.1 :rfc:`7231`, Section 6
154+
``is_server_error`` ``500 <= status <= 599`` HTTP/1.1 :rfc:`7231`, Section 6
155+
==================== ======================== ===============================
156+
157+
Usage::
158+
159+
>>> from http import HTTPStatus
160+
>>> HTTPStatus.OK.is_success
161+
True
162+
>>> HTTPStatus.OK.is_client_error
163+
False
164+
140165
.. class:: HTTPMethod
141166

142167
.. versionadded:: 3.11

Lib/enum.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1887,7 +1887,7 @@ def _test_simple_enum(checked_enum, simple_enum):
18871887
else:
18881888
checked_value = checked_dict[key]
18891889
simple_value = simple_dict[key]
1890-
if callable(checked_value):
1890+
if callable(checked_value) or isinstance(checked_value, bltns.property):
18911891
continue
18921892
if key == '__doc__':
18931893
# remove all spaces/tabs

Lib/http/__init__.py

+20
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@ def __new__(cls, value, phrase, description=''):
3131
obj.description = description
3232
return obj
3333

34+
@property
35+
def is_informational(self):
36+
return 100 <= self <= 199
37+
38+
@property
39+
def is_success(self):
40+
return 200 <= self <= 299
41+
42+
@property
43+
def is_redirection(self):
44+
return 300 <= self <= 399
45+
46+
@property
47+
def is_client_error(self):
48+
return 400 <= self <= 499
49+
50+
@property
51+
def is_server_error(self):
52+
return 500 <= self <= 599
53+
3454
# informational
3555
CONTINUE = 100, 'Continue', 'Request received, please continue'
3656
SWITCHING_PROTOCOLS = (101, 'Switching Protocols',

Lib/test/test_httplib.py

+45
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,27 @@ def __new__(cls, value, phrase, description=''):
553553
obj.phrase = phrase
554554
obj.description = description
555555
return obj
556+
557+
@property
558+
def is_informational(self):
559+
return 100 <= self <= 199
560+
561+
@property
562+
def is_success(self):
563+
return 200 <= self <= 299
564+
565+
@property
566+
def is_redirection(self):
567+
return 300 <= self <= 399
568+
569+
@property
570+
def is_client_error(self):
571+
return 400 <= self <= 499
572+
573+
@property
574+
def is_server_error(self):
575+
return 500 <= self <= 599
576+
556577
# informational
557578
CONTINUE = 100, 'Continue', 'Request received, please continue'
558579
SWITCHING_PROTOCOLS = (101, 'Switching Protocols',
@@ -669,6 +690,30 @@ def __new__(cls, value, phrase, description=''):
669690
'The client needs to authenticate to gain network access')
670691
enum._test_simple_enum(CheckedHTTPStatus, HTTPStatus)
671692

693+
def test_httpstatus_range(self):
694+
"""Checks that the statuses are in the 100-599 range"""
695+
696+
for member in HTTPStatus.__members__.values():
697+
self.assertGreaterEqual(member, 100)
698+
self.assertLessEqual(member, 599)
699+
700+
def test_httpstatus_category(self):
701+
"""Checks that the statuses belong to the standard categories"""
702+
703+
categories = (
704+
((100, 199), "is_informational"),
705+
((200, 299), "is_success"),
706+
((300, 399), "is_redirection"),
707+
((400, 499), "is_client_error"),
708+
((500, 599), "is_server_error"),
709+
)
710+
for member in HTTPStatus.__members__.values():
711+
for (lower, upper), category in categories:
712+
category_indicator = getattr(member, category)
713+
if lower <= member <= upper:
714+
self.assertTrue(category_indicator)
715+
else:
716+
self.assertFalse(category_indicator)
672717

673718
def test_status_lines(self):
674719
# Test HTTP status lines
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The :class:`HTTPStatus <http.HTTPStatus>` enum offers a couple of properties
2+
to indicate the HTTP status category e.g. ``HTTPStatus.OK.is_success``.

0 commit comments

Comments
 (0)