Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
22 changes: 22 additions & 0 deletions httpx/_models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import codecs
import datetime
import email.message
import json as jsonlib
Expand Down Expand Up @@ -603,6 +604,27 @@ def encoding(self) -> typing.Optional[str]:

@encoding.setter
def encoding(self, value: str) -> None:
"""
Set the encoding to use for decoding the byte content into text.

If the `text` attribute has been accessed, the encoding is not
allowed to be changed and will raise a ValueError if doing so.
"""

if hasattr(self, "_text"):
encoding = self.encoding or "utf-8"
if (
is_known_encoding(value)
and is_known_encoding(encoding)
and codecs.lookup(value) == codecs.lookup(encoding)
):
self._encoding = value
return
else:
raise ValueError(
f"Attempt to set encoding to '{value}' is not allowed,"
f"because the content has been decoded with encoding '{self.encoding}'"
)
self._encoding = value

@property
Expand Down
16 changes: 16 additions & 0 deletions tests/models/test_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,22 @@ def test_response_force_encoding():
assert response.encoding == "iso-8859-1"


def test_response_force_encoding_after_text_accessed():
response = httpx.Response(
200,
content=b"Hello, world!",
)
assert response.status_code == 200
assert response.reason_phrase == "OK"
assert response.text == "Hello, world!"
assert response.encoding == "utf-8"

response.encoding = "UTF8"
Comment thread
xzmeng marked this conversation as resolved.
Outdated

with pytest.raises(ValueError):
response.encoding = "iso-8859-1"


def test_read():
response = httpx.Response(
200,
Expand Down