From f6fb1173666077d11f6077611d74e34ffa020d44 Mon Sep 17 00:00:00 2001 From: Meng Xiangzhuo Date: Sun, 17 Sep 2023 08:47:38 +0800 Subject: [PATCH 1/3] Raise ValueError on change encoding --- httpx/_models.py | 22 ++++++++++++++++++++++ tests/models/test_responses.py | 16 ++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/httpx/_models.py b/httpx/_models.py index e1e45cf06b..4ecd23bcc2 100644 --- a/httpx/_models.py +++ b/httpx/_models.py @@ -1,3 +1,4 @@ +import codecs import datetime import email.message import json as jsonlib @@ -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 diff --git a/tests/models/test_responses.py b/tests/models/test_responses.py index 9e65de8154..cdfe7bd9d1 100644 --- a/tests/models/test_responses.py +++ b/tests/models/test_responses.py @@ -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" + + with pytest.raises(ValueError): + response.encoding = "iso-8859-1" + + def test_read(): response = httpx.Response( 200, From d0e98dadf7558ae9120463488e8510bfed991656 Mon Sep 17 00:00:00 2001 From: Meng Xiangzhuo Date: Sun, 17 Sep 2023 20:21:09 +0800 Subject: [PATCH 2/3] Always raise ValueError for simplicity --- httpx/_models.py | 22 +++++----------------- tests/models/test_responses.py | 3 ++- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/httpx/_models.py b/httpx/_models.py index 4ecd23bcc2..8a6bda04bb 100644 --- a/httpx/_models.py +++ b/httpx/_models.py @@ -1,4 +1,3 @@ -import codecs import datetime import email.message import json as jsonlib @@ -607,24 +606,13 @@ 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 the `text` attribute has been accessed, attempting to set the + encoding will throw a ValueError. """ - 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}'" - ) + raise ValueError( + "Setting encoding after `text` has been accessed is not allowed." + ) self._encoding = value @property diff --git a/tests/models/test_responses.py b/tests/models/test_responses.py index cdfe7bd9d1..9177773a50 100644 --- a/tests/models/test_responses.py +++ b/tests/models/test_responses.py @@ -308,7 +308,8 @@ def test_response_force_encoding_after_text_accessed(): assert response.text == "Hello, world!" assert response.encoding == "utf-8" - response.encoding = "UTF8" + with pytest.raises(ValueError): + response.encoding = "UTF8" with pytest.raises(ValueError): response.encoding = "iso-8859-1" From ac0af3ed67d261181270ba1bf2684465010f8020 Mon Sep 17 00:00:00 2001 From: Meng Xiangzhuo Date: Tue, 19 Sep 2023 06:28:08 +0800 Subject: [PATCH 3/3] update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66d2b080cd..4842dfff82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## Unreleased + +### Fixed + +* Raise `ValueError` on `Response.encoding` being set after `Response.text` has been accessed. (#2852) + ## 0.25.0 (11th Sep, 2023) ### Removed