Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: default body encoding #287

Merged
merged 2 commits into from
Oct 1, 2016
Merged
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
16 changes: 14 additions & 2 deletions tests/test_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,13 @@ def test_body_del():

def test_text_get_no_charset():
res = Response(charset=None)
assert '' == res.text

def test_text_get_no_default_body_encoding():
res = Response(charset=None)
res.default_body_encoding = None
with pytest.raises(AttributeError):
res.__getattribute__('text')
assert '' == res.text

def test_unicode_body():
res = Response()
Expand All @@ -717,8 +722,15 @@ def test_text_get_decode():
def test_text_set_no_charset():
res = Response()
res.charset = None
res.text = text_('abc')
assert res.text == 'abc'

def test_text_set_no_default_body_encoding():
res = Response()
res.charset = None
res.default_body_encoding = None
with pytest.raises(AttributeError):
res.__setattr__('text', 'abc')
res.text = text_('abc')

def test_text_set_not_unicode():
res = Response()
Expand Down
27 changes: 19 additions & 8 deletions webob/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,17 @@ class Response(object):
set to True so that all ``Response`` objects will attempt to check
the original request for conditional response headers. See
:meth:`~Response.conditional_response_app` for more information.

* ``default_body_encoding`` is set to 'UTF-8' by default, it exists to
allow users to get/set the Response object using .text, even if no
charset has been set for the Content-Type.
"""

default_content_type = 'text/html'
default_charset = 'UTF-8'
unicode_errors = 'strict'
default_conditional_response = False
default_body_encoding = 'UTF-8'

# These two are only around so that when people pass them into the
# constructor they correctly get saved and set, however they are not used
Expand Down Expand Up @@ -556,24 +561,30 @@ def _has_body__get(self):

def _text__get(self):
"""
Get/set the text value of the body (using the charset of the
Content-Type)
Get/set the text value of the body using the charset of the
Content-Type or the default_body_encoding.
"""
if not self.charset:
if not self.charset and not self.default_body_encoding:
raise AttributeError(
"You cannot access Response.text unless charset is set")
"You cannot access Response.text unless charset or default_body_encoding"
" is set"
)
decoding = self.charset or self.default_body_encoding
body = self.body
return body.decode(self.charset, self.unicode_errors)
return body.decode(decoding, self.unicode_errors)

def _text__set(self, value):
if not self.charset:
if not self.charset and not self.default_body_encoding:
raise AttributeError(
"You cannot access Response.text unless charset is set")
"You cannot access Response.text unless charset or default_body_encoding"
" is set"
)
if not isinstance(value, text_type):
raise TypeError(
"You can only set Response.text to a unicode string "
"(not %s)" % type(value))
self.body = value.encode(self.charset)
encoding = self.charset or self.default_body_encoding
self.body = value.encode(encoding)

def _text__del(self):
del self.body
Expand Down