From b1cc86e0c209a5a3444fffbc90eedd07a8294ed2 Mon Sep 17 00:00:00 2001 From: "Michiel W. Beijen" Date: Wed, 15 Jul 2026 22:30:56 +0200 Subject: [PATCH] Add RFC 9110 status code constants RFC 9110 (HTTP Semantics) renamed several status phrases and obsoletes RFC 7231/7238. Add the new constant names and phrases, keeping the old constant names as aliases for backwards compatibility: - REQUEST_ENTITY_TOO_LARGE -> CONTENT_TOO_LARGE (413) - REQUEST_URI_TOO_LONG -> URI_TOO_LONG (414) - REQUESTED_RANGE_NOT_SATISFIABLE -> RANGE_NOT_SATISFIABLE (416) - UNPROCESSABLE_ENTITY -> UNPROCESSABLE_CONTENT (422) --- src/httpx2/httpx2/_status_codes.py | 18 ++++++++++++------ tests/httpx2/test_status_codes.py | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/httpx2/httpx2/_status_codes.py b/src/httpx2/httpx2/_status_codes.py index 133a6231..5567b42a 100644 --- a/src/httpx2/httpx2/_status_codes.py +++ b/src/httpx2/httpx2/_status_codes.py @@ -10,12 +10,12 @@ class codes(IntEnum): Status codes from the following RFCs are all observed: - * RFC 7231: Hypertext Transfer Protocol (HTTP/1.1), obsoletes 2616 + * RFC 9110: HTTP Semantics + obsoletes 7231, which obsoletes 2616. Obsoletes 7238 * RFC 6585: Additional HTTP Status Codes * RFC 3229: Delta encoding in HTTP * RFC 4918: HTTP Extensions for WebDAV, obsoletes 2518 * RFC 5842: Binding Extensions to WebDAV - * RFC 7238: Permanent Redirect * RFC 2295: Transparent Content Negotiation in HTTP * RFC 2774: An HTTP Extension Framework * RFC 7540: Hypertext Transfer Protocol Version 2 (HTTP/2) @@ -126,14 +126,14 @@ def is_error(cls, value: int) -> bool: GONE = 410, "Gone" LENGTH_REQUIRED = 411, "Length Required" PRECONDITION_FAILED = 412, "Precondition Failed" - REQUEST_ENTITY_TOO_LARGE = 413, "Request Entity Too Large" - REQUEST_URI_TOO_LONG = 414, "Request-URI Too Long" + CONTENT_TOO_LARGE = 413, "Content Too Large" + URI_TOO_LONG = 414, "URI Too Long" UNSUPPORTED_MEDIA_TYPE = 415, "Unsupported Media Type" - REQUESTED_RANGE_NOT_SATISFIABLE = 416, "Requested Range Not Satisfiable" + RANGE_NOT_SATISFIABLE = 416, "Range Not Satisfiable" EXPECTATION_FAILED = 417, "Expectation Failed" IM_A_TEAPOT = 418, "I'm a teapot" MISDIRECTED_REQUEST = 421, "Misdirected Request" - UNPROCESSABLE_ENTITY = 422, "Unprocessable Entity" + UNPROCESSABLE_CONTENT = 422, "Unprocessable Content" LOCKED = 423, "Locked" FAILED_DEPENDENCY = 424, "Failed Dependency" TOO_EARLY = 425, "Too Early" @@ -156,6 +156,12 @@ def is_error(cls, value: int) -> bool: NOT_EXTENDED = 510, "Not Extended" NETWORK_AUTHENTICATION_REQUIRED = 511, "Network Authentication Required" + # for backwards compatibility, keep the old constants around + REQUEST_ENTITY_TOO_LARGE = CONTENT_TOO_LARGE + REQUEST_URI_TOO_LONG = URI_TOO_LONG + REQUESTED_RANGE_NOT_SATISFIABLE = RANGE_NOT_SATISFIABLE + UNPROCESSABLE_ENTITY = UNPROCESSABLE_CONTENT + # Include lower-case styles for `requests` compatibility. for code in codes: diff --git a/tests/httpx2/test_status_codes.py b/tests/httpx2/test_status_codes.py index 56dcafa3..945637f1 100644 --- a/tests/httpx2/test_status_codes.py +++ b/tests/httpx2/test_status_codes.py @@ -25,3 +25,18 @@ def test_reason_phrase_for_status_code() -> None: def test_reason_phrase_for_unknown_status_code() -> None: assert httpx2.codes.get_reason_phrase(499) == "" + + +def test_rfc9110_status_texts() -> None: + assert httpx2.codes.get_reason_phrase(413) == "Content Too Large" + assert httpx2.codes.get_reason_phrase(414) == "URI Too Long" + assert httpx2.codes.get_reason_phrase(416) == "Range Not Satisfiable" + assert httpx2.codes.get_reason_phrase(422) == "Unprocessable Content" + + +def test_pre_rfc9110_aliases_still_work() -> None: + # kept for backwards compatibility with the pre-RFC 9110 constant names + assert httpx2.codes.REQUEST_ENTITY_TOO_LARGE == httpx2.codes.CONTENT_TOO_LARGE # type: ignore[comparison-overlap] + assert httpx2.codes.REQUEST_URI_TOO_LONG == httpx2.codes.URI_TOO_LONG + assert httpx2.codes.REQUESTED_RANGE_NOT_SATISFIABLE == httpx2.codes.RANGE_NOT_SATISFIABLE + assert httpx2.codes.UNPROCESSABLE_ENTITY == httpx2.codes.UNPROCESSABLE_CONTENT