diff --git a/scrapy/http/response/text.py b/scrapy/http/response/text.py
index dc8a96d27..c062521b1 100644
--- a/scrapy/http/response/text.py
+++ b/scrapy/http/response/text.py
@@ -37,7 +37,7 @@ class TextResponse(Response):
body = property(lambda x: x._body, set_body)
def replace(self, *args, **kwargs):
- kwargs.setdefault('encoding', self.encoding)
+ kwargs.setdefault('encoding', getattr(self, '_encoding', None))
return Response.replace(self, *args, **kwargs)
@property
diff --git a/scrapy/tests/test_http_response.py b/scrapy/tests/test_http_response.py
index 1737a7690..ac89c5ae6 100644
--- a/scrapy/tests/test_http_response.py
+++ b/scrapy/tests/test_http_response.py
@@ -193,10 +193,20 @@ class ResponseTest(unittest.TestCase):
r2 = XmlResponse("http://www.example.com", body=body)
self._assert_response_values(r2, 'iso-8859-1', body)
- # make sure replace() preserves the encoding of the original response
- body = "New body \xa3"
- r3 = r2.replace(body=body)
- self._assert_response_values(r3, 'iso-8859-1', body)
+ # make sure replace() preserves the explicit encoding passed in the constructor
+ body = """"""
+ r3 = XmlResponse("http://www.example.com", body=body, encoding='utf-8')
+ body2 = "New body"
+ r4 = r3.replace(body=body2)
+ self._assert_response_values(r4, 'utf-8', body2)
+
+ # make sure replace() rediscovers the encoding (if not given explicitly) when changing the body
+ body = """"""
+ r5 = XmlResponse("http://www.example.com", body=body)
+ body2 = """"""
+ r6 = r5.replace(body=body2)
+ self._assert_response_values(r5, 'iso-8859-1', body)
+ self._assert_response_values(r6, 'utf-8', body2)
if __name__ == "__main__":