summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Schetinin <sergey@maluke.com>2011-09-07 22:24:37 +0300
committerSergey Schetinin <sergey@maluke.com>2011-09-07 22:24:37 +0300
commit66ffc0b7a04ce5ef749b6c25f5d152fccb645ea0 (patch)
tree6c2591e3aa19b3985acada9eba9af4c9b6af8d9f
parent254b49df3508f78997906d885c0b5fc386223065 (diff)
downloadwebob-66ffc0b7a04ce5ef749b6c25f5d152fccb645ea0.tar.gz
* add AcceptCharset and AcceptLanguage subclasses instead of branching in Accept.__init__
* that allows us to remove Accept.header_name * and change Accept.__repr__ to be more straightforward
-rw-r--r--docs/reference.txt2
-rw-r--r--docs/test_request.txt4
-rw-r--r--tests/test_acceptparse.py163
-rw-r--r--webob/acceptparse.py115
-rw-r--r--webob/request.py6
5 files changed, 128 insertions, 162 deletions
diff --git a/docs/reference.txt b/docs/reference.txt
index 194589b..f44d80e 100644
--- a/docs/reference.txt
+++ b/docs/reference.txt
@@ -345,7 +345,7 @@ example means that ``text/html`` is okay, but
>>> req.accept = 'text/html;q=0.5, application/xhtml+xml;q=1'
>>> req.accept
- <MIMEAccept at ... Accept: text/html;q=0.5, application/xhtml+xml>
+ <MIMEAccept('text/html;q=0.5, application/xhtml+xml')>
>>> 'text/html' in req.accept
True
diff --git a/docs/test_request.txt b/docs/test_request.txt
index 5319592..f708e40 100644
--- a/docs/test_request.txt
+++ b/docs/test_request.txt
@@ -215,7 +215,7 @@ mime types are not supported.
>>> req = Request.blank('/')
>>> req.environ['HTTP_ACCEPT'] = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.1"
>>> req.accept # doctest: +ELLIPSIS
- <MIMEAccept at ... Accept: text/*;q=0.3, text/html;q=0.7, text/html, text/html;q=0.4, */*;q=0.1>
+ <MIMEAccept('text/*;q=0.3, text/html;q=0.7, text/html, text/html;q=0.4, */*;q=0.1')>
>>> for item, quality in req.accept._parsed:
... print '%s: %0.1f' % (item, quality)
text/*: 0.3
@@ -233,7 +233,7 @@ mime types are not supported.
True
>>> req.environ['HTTP_ACCEPT'] = "text/html, application/xml; q=0.7, text/*; q=0.5, */*; q=0.1"
>>> req.accept # doctest: +ELLIPSIS
- <MIMEAccept at ... Accept: text/html, application/xml;q=0.7, text/*;q=0.5, */*;q=0.1>
+ <MIMEAccept('text/html, application/xml;q=0.7, text/*;q=0.5, */*;q=0.1')>
>>> req.accept.best_match(['text/plain', 'application/xml'])
'application/xml'
>>> req.accept.first_match(['application/xml', 'text/html'])
diff --git a/tests/test_acceptparse.py b/tests/test_acceptparse.py
index a1e8adc..7fb1394 100644
--- a/tests/test_acceptparse.py
+++ b/tests/test_acceptparse.py
@@ -1,101 +1,78 @@
from webob import Request
-from webob.acceptparse import Accept, MIMEAccept, NilAccept, NoAccept, accept_property, parse_accept
+from webob.acceptparse import Accept, MIMEAccept, NilAccept, NoAccept, accept_property, AcceptLanguage, AcceptCharset
from nose.tools import eq_, assert_raises
def test_parse_accept_badq():
- assert parse_accept("value1; q=0.1.2") == [('value1', 1)]
+ assert list(Accept.parse("value1; q=0.1.2")) == [('value1', 1)]
def test_init_accept_content_type():
- name, value = ('Content-Type', 'text/html')
- accept = Accept(name, value)
- assert accept.header_name == name
- assert accept.header_value == value
+ accept = Accept('text/html')
assert accept._parsed == [('text/html', 1)]
def test_init_accept_accept_charset():
- name, value = ('Accept-Charset', 'iso-8859-5, unicode-1-1;q=0.8')
- accept = Accept(name, value)
- assert accept.header_name == name
- assert accept.header_value == value
+ accept = AcceptCharset('iso-8859-5, unicode-1-1;q=0.8')
assert accept._parsed == [('iso-8859-5', 1),
('unicode-1-1', 0.80000000000000004),
('iso-8859-1', 1)]
def test_init_accept_accept_charset_with_iso_8859_1():
- name, value = ('Accept-Charset', 'iso-8859-1')
- accept = Accept(name, value)
- assert accept.header_name == name
- assert accept.header_value == value
+ accept = Accept('iso-8859-1')
assert accept._parsed == [('iso-8859-1', 1)]
def test_init_accept_accept_charset_wildcard():
- name, value = ('Accept-Charset', '*')
- accept = Accept(name, value)
- assert accept.header_name == name
- assert accept.header_value == value
+ accept = Accept('*')
assert accept._parsed == [('*', 1)]
def test_init_accept_accept_language():
- name, value = ('Accept-Language', 'da, en-gb;q=0.8, en;q=0.7')
- accept = Accept(name, value)
- assert accept.header_name == name
- assert accept.header_value == value
+ accept = AcceptLanguage('da, en-gb;q=0.8, en;q=0.7')
assert accept._parsed == [('da', 1),
('en-gb', 0.80000000000000004),
('en', 0.69999999999999996)]
def test_init_accept_invalid_value():
- name, value = ('Accept-Language', 'da, q, en-gb;q=0.8')
- accept = Accept(name, value)
+ accept = AcceptLanguage('da, q, en-gb;q=0.8')
# The "q" value should not be there.
assert accept._parsed == [('da', 1),
('en-gb', 0.80000000000000004)]
def test_init_accept_invalid_q_value():
- name, value = ('Accept-Language', 'da, en-gb;q=foo')
- accept = Accept(name, value)
+ accept = AcceptLanguage('da, en-gb;q=foo')
# I can't get to cover line 40-41 (webob.acceptparse) as the regex
# will prevent from hitting these lines (aconrad)
assert accept._parsed == [('da', 1), ('en-gb', 1)]
def test_accept_repr():
- name, value = ('Content-Type', 'text/html')
- accept = Accept(name, value)
- assert repr(accept) == '<%s at 0x%x %s: %s>' % ('Accept',
- abs(id(accept)),
- name,
- str(accept))
+ accept = Accept('text/html')
+ assert repr(accept) == "<Accept('text/html')>"
def test_accept_str():
- name, value = ('Content-Type', 'text/html')
- accept = Accept(name, value)
- assert str(accept) == value
+ accept = Accept('text/html')
+ assert str(accept) == 'text/html'
def test_zero_quality():
- assert Accept('Accept-Encoding', 'bar, *;q=0').best_match(['foo']) is None
- assert 'foo' not in Accept('Accept-Encoding', '*;q=0')
- assert Accept('Accept-Encoding', 'foo, *;q=0').first_match(['bar', 'foo']) == 'foo'
+ assert Accept('bar, *;q=0').best_match(['foo']) is None
+ assert 'foo' not in Accept('*;q=0')
+ assert Accept('foo, *;q=0').first_match(['bar', 'foo']) == 'foo'
def test_accept_str_with_q_not_1():
- name, value = ('Content-Type', 'text/html;q=0.5')
- accept = Accept(name, value)
+ value = 'text/html;q=0.5'
+ accept = Accept(value)
assert str(accept) == value
def test_accept_str_with_q_not_1_multiple():
- name, value = ('Content-Type', 'text/html;q=0.5, foo/bar')
- accept = Accept(name, value)
+ value = 'text/html;q=0.5, foo/bar'
+ accept = Accept(value)
assert str(accept) == value
def test_accept_add_other_accept():
- accept = Accept('Content-Type', 'text/html') + \
- Accept('Content-Type', 'foo/bar')
+ accept = Accept('text/html') + Accept('foo/bar')
assert str(accept) == 'text/html, foo/bar'
- accept += Accept('Content-Type', 'bar/baz;q=0.5')
+ accept += Accept('bar/baz;q=0.5')
assert str(accept) == 'text/html, foo/bar, bar/baz;q=0.5'
def test_accept_add_other_list_of_tuples():
- accept = Accept('Content-Type', 'text/html')
+ accept = Accept('text/html')
accept += [('foo/bar', 1)]
assert str(accept) == 'text/html, foo/bar'
accept += [('bar/baz', 0.5)]
@@ -105,42 +82,42 @@ def test_accept_add_other_list_of_tuples():
'she/bangs, the/house')
def test_accept_add_other_dict():
- accept = Accept('Content-Type', 'text/html')
+ accept = Accept('text/html')
accept += {'foo/bar': 1}
assert str(accept) == 'text/html, foo/bar'
accept += {'bar/baz': 0.5}
assert str(accept) == 'text/html, foo/bar, bar/baz;q=0.5'
def test_accept_add_other_empty_str():
- accept = Accept('Content-Type', 'text/html')
+ accept = Accept('text/html')
accept += ''
assert str(accept) == 'text/html'
def test_accept_with_no_value_add_other_str():
- accept = Accept('Content-Type', '')
+ accept = Accept('')
accept += 'text/html'
assert str(accept) == 'text/html'
def test_contains():
- accept = Accept('Content-Type', 'text/html')
+ accept = Accept('text/html')
assert 'text/html' in accept
def test_contains_not():
- accept = Accept('Content-Type', 'text/html')
+ accept = Accept('text/html')
assert not 'foo/bar' in accept
def test_quality():
- accept = Accept('Content-Type', 'text/html')
+ accept = Accept('text/html')
assert accept.quality('text/html') == 1
- accept = Accept('Content-Type', 'text/html;q=0.5')
+ accept = Accept('text/html;q=0.5')
assert accept.quality('text/html') == 0.5
def test_quality_not_found():
- accept = Accept('Content-Type', 'text/html')
+ accept = Accept('text/html')
assert accept.quality('foo/bar') is None
def test_first_match():
- accept = Accept('Content-Type', 'text/html, foo/bar')
+ accept = Accept('text/html, foo/bar')
assert accept.first_match(['text/html', 'foo/bar']) == 'text/html'
assert accept.first_match(['foo/bar', 'text/html']) == 'foo/bar'
assert accept.first_match(['xxx/xxx', 'text/html']) == 'text/html'
@@ -151,7 +128,7 @@ def test_first_match():
assert_raises(ValueError, accept.first_match, [])
def test_best_match():
- accept = Accept('Content-Type', 'text/html, foo/bar')
+ accept = Accept('text/html, foo/bar')
assert accept.best_match(['text/html', 'foo/bar']) == 'text/html'
assert accept.best_match(['foo/bar', 'text/html']) == 'foo/bar'
assert accept.best_match([('foo/bar', 0.5),
@@ -161,25 +138,25 @@ def test_best_match():
assert_raises(ValueError, accept.best_match, ['text/*'])
def test_best_match_with_one_lower_q():
- accept = Accept('Content-Type', 'text/html, foo/bar;q=0.5')
+ accept = Accept('text/html, foo/bar;q=0.5')
assert accept.best_match(['text/html', 'foo/bar']) == 'text/html'
- accept = Accept('Content-Type', 'text/html;q=0.5, foo/bar')
+ accept = Accept('text/html;q=0.5, foo/bar')
assert accept.best_match(['text/html', 'foo/bar']) == 'foo/bar'
def test_best_matches():
- accept = Accept('Content-Type', 'text/html, foo/bar')
+ accept = Accept('text/html, foo/bar')
assert accept.best_matches() == ['text/html', 'foo/bar']
- accept = Accept('Content-Type', 'text/html, foo/bar;q=0.5')
+ accept = Accept('text/html, foo/bar;q=0.5')
assert accept.best_matches() == ['text/html', 'foo/bar']
- accept = Accept('Content-Type', 'text/html;q=0.5, foo/bar')
+ accept = Accept('text/html;q=0.5, foo/bar')
assert accept.best_matches() == ['foo/bar', 'text/html']
def test_best_matches_with_fallback():
- accept = Accept('Content-Type', 'text/html, foo/bar')
+ accept = Accept('text/html, foo/bar')
assert accept.best_matches('xxx/yyy') == ['text/html',
'foo/bar',
'xxx/yyy']
- accept = Accept('Content-Type', 'text/html;q=0.5, foo/bar')
+ accept = Accept('text/html;q=0.5, foo/bar')
assert accept.best_matches('xxx/yyy') == ['foo/bar',
'text/html',
'xxx/yyy']
@@ -188,8 +165,8 @@ def test_best_matches_with_fallback():
def test_accept_match():
for mask in ['*', 'text/html', 'TEXT/HTML']:
- assert 'text/html' in Accept('Content-Type', mask)
- assert 'text/html' not in Accept('Content-Type', 'foo/bar')
+ assert 'text/html' in Accept(mask)
+ assert 'text/html' not in Accept('foo/bar')
def test_accept_match_lang():
for mask, lang in [
@@ -198,16 +175,15 @@ def test_accept_match_lang():
('en', 'en-gb'),
('en-gb', 'en-gb'),
]:
- assert lang in Accept('Accept-Language', mask)
- assert 'fr-fr' not in Accept('Accept-Language', 'en-gb')
+ assert lang in AcceptLanguage(mask)
+ assert 'fr-fr' not in AcceptLanguage('en-gb')
# NilAccept tests
def test_nil():
- nilaccept = NilAccept('Connection-Close')
- assert nilaccept.header_name == 'Connection-Close'
+ nilaccept = NilAccept()
eq_(repr(nilaccept),
- "<NilAccept for Connection-Close: <class 'webob.acceptparse.Accept'>>"
+ "<NilAccept: <class 'webob.acceptparse.Accept'>>"
)
assert not nilaccept
assert str(nilaccept) == ''
@@ -217,21 +193,19 @@ def test_nil():
def test_nil_add():
- nilaccept = NilAccept('Connection-Close')
- accept = Accept('Content-Type', 'text/html')
+ nilaccept = NilAccept()
+ accept = Accept('text/html')
assert nilaccept + accept is accept
new_accept = nilaccept + nilaccept
assert isinstance(new_accept, accept.__class__)
- assert new_accept.header_name == 'Connection-Close'
assert new_accept.header_value == ''
new_accept = nilaccept + 'foo'
assert isinstance(new_accept, accept.__class__)
- assert new_accept.header_name == 'Connection-Close'
assert new_accept.header_value == 'foo'
def test_nil_radd():
- nilaccept = NilAccept('Connection-Close')
- accept = Accept('Content-Type', 'text/html')
+ nilaccept = NilAccept()
+ accept = Accept('text/html')
assert isinstance('foo' + nilaccept, accept.__class__)
assert ('foo' + nilaccept).header_value == 'foo'
# How to test ``if isinstance(item, self.MasterClass): return item``
@@ -239,22 +213,22 @@ def test_nil_radd():
def test_nil_radd_masterclass():
# Is this "reaching into" __radd__ legit?
- nilaccept = NilAccept('Connection-Close')
- accept = Accept('Content-Type', 'text/html')
+ nilaccept = NilAccept()
+ accept = Accept('text/html')
assert nilaccept.__radd__(accept) is accept
def test_nil_contains():
- nilaccept = NilAccept('Connection-Close')
+ nilaccept = NilAccept()
assert 'anything' in nilaccept
def test_nil_first_match():
- nilaccept = NilAccept('Connection-Close')
+ nilaccept = NilAccept()
# NilAccept.first_match always returns element 0 of the list
assert nilaccept.first_match(['dummy', '']) == 'dummy'
assert nilaccept.first_match(['', 'dummy']) == ''
def test_nil_best_match():
- nilaccept = NilAccept('Connection-Close')
+ nilaccept = NilAccept()
assert nilaccept.best_match(['foo', 'bar']) == 'foo'
assert nilaccept.best_match([('foo', 1), ('bar', 0.5)]) == 'foo'
assert nilaccept.best_match([('foo', 0.5), ('bar', 1)]) == 'bar'
@@ -268,33 +242,33 @@ def test_nil_best_match():
# NoAccept tests
def test_noaccept_contains():
- assert 'text/plain' not in NoAccept('Connection-Close')
+ assert 'text/plain' not in NoAccept()
# MIMEAccept tests
def test_mime_init():
- mimeaccept = MIMEAccept('Content-Type', 'image/jpg')
+ mimeaccept = MIMEAccept('image/jpg')
assert mimeaccept._parsed == [('image/jpg', 1)]
- mimeaccept = MIMEAccept('Content-Type', 'image/png, image/jpg;q=0.5')
+ mimeaccept = MIMEAccept('image/png, image/jpg;q=0.5')
assert mimeaccept._parsed == [('image/png', 1), ('image/jpg', 0.5)]
- mimeaccept = MIMEAccept('Content-Type', 'image, image/jpg;q=0.5')
+ mimeaccept = MIMEAccept('image, image/jpg;q=0.5')
assert mimeaccept._parsed == [('image/jpg', 0.5)]
- mimeaccept = MIMEAccept('Content-Type', '*/*')
+ mimeaccept = MIMEAccept('*/*')
assert mimeaccept._parsed == [('*/*', 1)]
- mimeaccept = MIMEAccept('Content-Type', '*/png')
+ mimeaccept = MIMEAccept('*/png')
assert mimeaccept._parsed == []
- mimeaccept = MIMEAccept('Content-Type', 'image/*')
+ mimeaccept = MIMEAccept('image/*')
assert mimeaccept._parsed == [('image/*', 1)]
def test_accept_html():
- mimeaccept = MIMEAccept('Content-Type', 'image/jpg')
+ mimeaccept = MIMEAccept('image/jpg')
assert not mimeaccept.accept_html()
- mimeaccept = MIMEAccept('Content-Type', 'image/jpg, text/html')
+ mimeaccept = MIMEAccept('image/jpg, text/html')
assert mimeaccept.accept_html()
def test_match():
- mimeaccept = MIMEAccept('Content-Type', 'image/jpg')
+ mimeaccept = MIMEAccept('image/jpg')
assert mimeaccept._match('image/jpg', 'image/jpg')
assert mimeaccept._match('image/*', 'image/jpg')
assert mimeaccept._match('*/*', 'image/jpg')
@@ -302,7 +276,7 @@ def test_match():
assert_raises(ValueError, mimeaccept._match, 'image/jpg', '*/*')
def test_accept_json():
- mimeaccept = MIMEAccept('Accept', 'text/html, *; q=.2, */*; q=.2')
+ mimeaccept = MIMEAccept('text/html, *; q=.2, */*; q=.2')
assert mimeaccept.best_match(['application/json']) == 'application/json'
# property tests
@@ -325,10 +299,9 @@ def test_accept_property_fset():
eq_(desc.fget(req).header_value, 'baz')
def test_accept_property_fset_acceptclass():
- desc = accept_property('Accept-Charset', '14.2')
req = Request.blank('/', environ={'envkey': 'envval'})
- desc.fset(req, ['utf-8', 'latin-11'])
- eq_(desc.fget(req).header_value, 'utf-8, latin-11, iso-8859-1')
+ req.accept_charset = ['utf-8', 'latin-11']
+ eq_(req.accept_charset.header_value, 'utf-8, latin-11, iso-8859-1')
def test_accept_property_fdel():
desc = accept_property('Accept-Charset', '14.2')
diff --git a/webob/acceptparse.py b/webob/acceptparse.py
index 062f793..eaed2d1 100644
--- a/webob/acceptparse.py
+++ b/webob/acceptparse.py
@@ -18,28 +18,6 @@ part_re = re.compile(
-def parse_accept(value):
- """
- Parses an ``Accept-*`` style header.
-
- A list of ``[(value, quality), ...]`` is returned. ``quality``
- will be 1 if it was not given.
- """
- result = []
- for match in part_re.finditer(','+value):
- name = match.group(1)
- if name == 'q':
- continue
- quality = match.group(2) or ''
- if not quality:
- quality = 1
- else:
- try:
- quality = max(min(float(quality), 1), 0)
- except ValueError:
- quality = 1
- result.append((name, quality))
- return result
def _warn_first_match():
# TODO: remove .first_match in version 1.3
@@ -53,26 +31,36 @@ class Accept(object):
``accept_obj + 'accept_thing'`` to get a new object
"""
- def __init__(self, header_name, header_value):
- self.header_name = header_name
+ def __init__(self, header_value):
self.header_value = header_value
- self._parsed = parse_accept(header_value)
- if header_name == 'Accept-Charset':
- for k, v in self._parsed:
- if k == '*' or k == 'iso-8859-1':
- break
- else:
- self._parsed.append(('iso-8859-1', 1))
- elif header_name == 'Accept-Language':
- self._match = self._match_lang
+ self._parsed = list(self.parse(header_value))
self._parsed_nonzero = [(m,q) for (m,q) in self._parsed if q]
+ @staticmethod
+ def parse(value):
+ """
+ Parse ``Accept-*`` style header.
+
+ Return iterator of ``(value, quality)`` pairs.
+ ``quality`` defaults to 1.
+ """
+ for match in part_re.finditer(','+value):
+ name = match.group(1)
+ if name == 'q':
+ continue
+ quality = match.group(2) or ''
+ if quality:
+ try:
+ quality = max(min(float(quality), 1), 0)
+ yield (name, quality)
+ continue
+ except ValueError:
+ pass
+ yield (name, 1)
+
def __repr__(self):
- return '<%s at 0x%x %s: %s>' % (
- self.__class__.__name__,
- abs(id(self)),
- self.header_name, str(self))
+ return '<%s(%r)>' % (self.__class__.__name__, str(self))
def __str__(self):
result = []
@@ -106,7 +94,7 @@ class Accept(object):
new_value = other
else:
new_value = my_value + ', ' + other
- return self.__class__(self.header_name, new_value)
+ return self.__class__(new_value)
def __radd__(self, other):
return self.__add__(other, True)
@@ -207,12 +195,6 @@ class Accept(object):
_check_offer(offer)
return mask == '*' or offer.lower() == mask.lower()
- def _match_lang(self, mask, item):
- return (mask == '*'
- or item.lower() == mask.lower()
- or item.lower().split('-')[0] == mask.lower()
- )
-
class NilAccept(object):
@@ -223,12 +205,8 @@ class NilAccept(object):
MasterClass = Accept
- def __init__(self, header_name):
- self.header_name = header_name
-
def __repr__(self):
- return '<%s for %s: %s>' % (
- self.__class__.__name__, self.header_name, self.MasterClass)
+ return '<%s: %s>' % (self.__class__.__name__, self.MasterClass)
def __str__(self):
return ''
@@ -240,13 +218,13 @@ class NilAccept(object):
if isinstance(item, self.MasterClass):
return item
else:
- return self.MasterClass(self.header_name, '') + item
+ return self.MasterClass('') + item
def __radd__(self, item):
if isinstance(item, self.MasterClass):
return item
else:
- return item + self.MasterClass(self.header_name, '')
+ return item + self.MasterClass('')
def __contains__(self, item):
_check_offer(item)
@@ -283,6 +261,24 @@ class NoAccept(NilAccept):
def __contains__(self, item):
return False
+class AcceptCharset(Accept):
+ @staticmethod
+ def parse(value):
+ latin1_found = False
+ for m, q in Accept.parse(value):
+ if m == '*' or m == 'iso-8859-1':
+ latin1_found = True
+ yield m, q
+ if not latin1_found:
+ yield ('iso-8859-1', 1)
+
+class AcceptLanguage(Accept):
+ def _match(self, mask, item):
+ return (mask == '*'
+ or item.lower() == mask.lower()
+ or item.lower().split('-')[0] == mask.lower()
+ )
+
class MIMEAccept(Accept):
"""
@@ -290,19 +286,16 @@ class MIMEAccept(Accept):
This class knows about mime wildcards, like ``image/*``
"""
- def __init__(self, header_name, header_value):
- Accept.__init__(self, header_name, header_value)
- parsed = []
- for mask, q in self._parsed:
+ @staticmethod
+ def parse(value):
+ for mask, q in Accept.parse(value):
try:
mask_major, mask_minor = mask.split('/')
except ValueError:
continue
if mask_major == '*' and mask_minor != '*':
continue
- parsed.append((mask, q))
- self._parsed = parsed
- self._parsed_nonzero = [(m,q) for (m,q) in self._parsed if q]
+ yield (mask, q)
def accept_html(self):
"""
@@ -349,12 +342,12 @@ def accept_property(header, rfc_section,
def fget(req):
value = req.environ.get(key)
if not value:
- return NilClass(header)
- return AcceptClass(header, value)
+ return NilClass()
+ return AcceptClass(value)
def fset(req, val):
if val:
if isinstance(val, (list, tuple, dict)):
- val = AcceptClass(header, '') + val
+ val = AcceptClass('') + val
val = str(val)
req.environ[key] = val or None
def fdel(req):
diff --git a/webob/request.py b/webob/request.py
index 4355122..3f7193f 100644
--- a/webob/request.py
+++ b/webob/request.py
@@ -6,7 +6,7 @@ else:
from cStringIO import StringIO # pragma nocover
from webob.headers import EnvironHeaders
-from webob.acceptparse import accept_property, Accept, MIMEAccept, NilAccept, MIMENilAccept, NoAccept
+from webob.acceptparse import accept_property, Accept, MIMEAccept, AcceptCharset, NilAccept, MIMENilAccept, NoAccept, AcceptLanguage
from webob.multidict import TrackableMultiDict, MultiDict, UnicodeMultiDict, NestedMultiDict, NoVars
from webob.cachecontrol import CacheControl, serialize_cache_control
from webob.etag import etag_property, AnyETag, NoETag
@@ -852,9 +852,9 @@ class BaseRequest(object):
accept = accept_property('Accept', '14.1', MIMEAccept, MIMENilAccept)
- accept_charset = accept_property('Accept-Charset', '14.2')
+ accept_charset = accept_property('Accept-Charset', '14.2', AcceptCharset)
accept_encoding = accept_property('Accept-Encoding', '14.3', NilClass=NoAccept)
- accept_language = accept_property('Accept-Language', '14.4')
+ accept_language = accept_property('Accept-Language', '14.4', AcceptLanguage)
authorization = converter(
environ_getter('HTTP_AUTHORIZATION', None, '14.8'),