diff options
| author | Ira Lun <sammyrosajoe@gmail.com> | 2017-08-29 20:41:02 +0100 |
|---|---|---|
| committer | Ira Lun <sammyrosajoe@gmail.com> | 2017-08-29 20:41:02 +0100 |
| commit | fff89740b5c472b3b5a7229dfe2ddd463f7dbf09 (patch) | |
| tree | c0879665553684ecb3895e86a1bee96212287857 /src | |
| parent | f576cc863b16b41861eda315dd630c6119599b8d (diff) | |
| download | webob-fff89740b5c472b3b5a7229dfe2ddd463f7dbf09.tar.gz | |
Add _AcceptCharsetInvalidOrNoHeader class.
Diffstat (limited to 'src')
| -rw-r--r-- | src/webob/acceptparse.py | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/webob/acceptparse.py b/src/webob/acceptparse.py index c318f3f..3d685f1 100644 --- a/src/webob/acceptparse.py +++ b/src/webob/acceptparse.py @@ -769,6 +769,196 @@ class AcceptCharsetValidHeader(AcceptCharset): return bestq or None +class _AcceptCharsetInvalidOrNoHeader(AcceptCharset): + """ + Represent when an ``Accept-Charset`` header is invalid or not in request. + + This is the base class for the behaviour that + :class:`.AcceptCharsetInvalidHeader` and :class:`.AcceptCharsetNoHeader` + have in common. + + :rfc:`7231` does not provide any guidance on what should happen if the + ``Accept-Charset`` header has an invalid value. This implementation + disregards the header when the header is invalid, so + :class:`.AcceptCharsetInvalidHeader` and :class:`.AcceptCharsetNoHeader` + have much behaviour in common. + """ + + def __bool__(self): + """ + Return whether ``self`` represents a valid ``Accept-Charset`` header. + + Return ``True`` if ``self`` represents a valid header, and ``False`` if + it represents an invalid header, or the header not being in the + request. + + For this class, it always returns ``False``. + """ + return False + __nonzero__ = __bool__ # Python 2 + + def __contains__(self, offer): + """ + Return ``bool`` indicating whether `offer` is acceptable. + + .. warning:: + + The behavior of ``.__contains__`` for the ``AcceptCharset`` classes + is currently being maintained for backward compatibility, but it + will change in the future to better conform to the RFC. + + :param offer: (``str``) charset offer + :return: (``bool``) Whether ``offer`` is acceptable according to the + header. + + For this class, either there is no ``Accept-Charset`` header in the + request, or the header is invalid, so any charset is acceptable, and + this always returns ``True``. + """ + warnings.warn( + 'The behavior of .__contains__ for the AcceptCharset classes is ' + 'currently being maintained for backward compatibility, but it ' + 'will change in the future to better conform to the RFC.', + DeprecationWarning, + ) + return True + + def __iter__(self): + """ + Return all the items with non-0 qvalues, in order of preference. + + .. warning:: + + The behavior of this method is currently maintained for backward + compatibility, but will change in the future. + + :return: iterator of all the items (charset or ``*``) in the header + with non-0 qvalues, in descending order of qvalue. If two + items have the same qvalue, they are returned in the order of + their positions in the header, from left to right. + + When there is no ``Accept-Charset`` header in the request or the header + is invalid, there are no items, and this always returns an empty + iterator. + """ + warnings.warn( + 'The behavior of AcceptCharsetValidHeader.__iter__ is currently ' + 'maintained for backward compatibility, but will change in the ' + 'future.', + DeprecationWarning, + ) + return iter(()) + + def acceptable_offers(self, offers): + """ + Return the offers that are acceptable according to the header. + + The offers are returned in descending order of preference, where + preference is indicated by the qvalue of the charset or ``*`` in the + header matching the offer. + + This uses the matching rules described in :rfc:`RFC 7231, section 5.3.3 + <7231#section-5.3.3>`. + + :param offers: ``iterable`` of ``str`` charsets + :return: A list of tuples of the form (charset, qvalue), in descending + order of qvalue. Where two offers have the same qvalue, they + are returned in the same order as their order in `offers`. + + | When the header is invalid or there is no ``Accept-Charset`` + header in the request, all `offers` are considered + acceptable, so this method returns a list of (charset, + qvalue) tuples where each offer in `offers` is paired with + the qvalue of 1.0, in the same order as `offers`. + """ + return [(offer, 1.0) for offer in offers] + + def best_match(self, offers, default_match=None): + """ + Return the best match from the sequence of charset `offers`. + + This is the ``.best_match()`` method for when the header is invalid or + not found in the request, corresponding to + :meth:`AcceptCharsetValidHeader.best_match`. + + .. warning:: + + This is currently maintained for backward compatibility, and will be + deprecated in the future (see the documentation for + :meth:`AcceptCharsetValidHeader.best_match`). + + When the header is invalid, or there is no `Accept-Charset` header in + the request, all the charsets in `offers` are considered acceptable, so + the best match is the charset in `offers` with the highest server + quality value (if the server quality value is not supplied, it is 1). + + If more than one charsets in `offers` have the same highest server + quality value, then the one that shows up first in `offers` is the best + match. + + :param offers: (iterable) + + | Each item in the iterable may be a ``str`` charset, or + a (charset, server quality value) ``tuple`` or + ``list``. (The two may be mixed in the iterable.) + + :param default_match: (optional, any type) the value to be returned if + `offers` is empty. + + :return: (``str``, or the type of `default_match`) + + | The charset that has the highest server quality value. If + `offers` is empty, the value of `default_match` is returned. + """ + warnings.warn( + 'The behavior of .best_match for the AcceptCharset classes is ' + 'currently being maintained for backward compatibility, but the ' + 'method will be deprecated in the future, as its behavior is not ' + 'specified in (and currently does not conform to) RFC 7231.', + DeprecationWarning, + ) + best_quality = -1 + best_offer = default_match + for offer in offers: + if isinstance(offer, (list, tuple)): + offer, quality = offer + else: + quality = 1 + if quality > best_quality: + best_offer = offer + best_quality = quality + return best_offer + + def quality(self, offer): + """ + Return quality value of given offer, or ``None`` if there is no match. + + This is the ``.quality()`` method for when the header is invalid or not + found in the request, corresponding to + :meth:`AcceptCharsetValidHeader.quality`. + + .. warning:: + + This is currently maintained for backward compatibility, and will be + deprecated in the future (see the documentation for + :meth:`AcceptCharsetValidHeader.quality`). + + :param offer: (``str``) charset offer + :return: (``float``) ``1.0``. + + When the ``Accept-Charset`` header is invalid or not in the request, + all offers are equally acceptable, so 1.0 is always returned. + """ + warnings.warn( + 'The behavior of .quality for the Accept-Charset classes is ' + 'currently being maintained for backward compatibility, but the ' + 'method will be deprecated in the future, as its behavior does not' + ' conform to RFC 7231.', + DeprecationWarning, + ) + return 1.0 + + class AcceptEncoding(object): """ Represent an ``Accept-Encoding`` header. |
