Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions src/httpx2/httpx2/_status_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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"
Expand All @@ -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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The alias definitions preserve the original UPPERCASE constant names, but codes.request_entity_too_large etc. (the lowercase requests-compatible forms) are silently dropped because the for code in codes: loop only iterates over canonical members, not aliases. Anyone migrating from httpx.codes.request_entity_too_large will get an AttributeError. Consider preserving these too, either via explicit setattr calls after the loop or by adding them as additional alias entries.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/httpx2/httpx2/_status_codes.py, line 160:

<comment>The alias definitions preserve the original UPPERCASE constant names, but `codes.request_entity_too_large` etc. (the lowercase `requests`-compatible forms) are silently dropped because the `for code in codes:` loop only iterates over canonical members, not aliases. Anyone migrating from `httpx.codes.request_entity_too_large` will get an `AttributeError`. Consider preserving these too, either via explicit `setattr` calls after the loop or by adding them as additional alias entries.</comment>

<file context>
@@ -156,6 +156,12 @@ def is_error(cls, value: int) -> bool:
     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
</file context>

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:
Expand Down
15 changes: 15 additions & 0 deletions tests/httpx2/test_status_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading