Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/webob/util.py : 35%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import warnings
3from webob.compat import (
4 escape,
5 string_types,
6 text_,
7 text_type,
8 )
10from webob.headers import _trans_key
12def html_escape(s):
13 """HTML-escape a string or object
15 This converts any non-string objects passed into it to strings
16 (actually, using ``unicode()``). All values returned are
17 non-unicode strings (using ``&#num;`` entities for all non-ASCII
18 characters).
20 None is treated specially, and returns the empty string.
21 """
22 if s is None:
23 return ''
24 __html__ = getattr(s, '__html__', None)
25 if __html__ is not None and callable(__html__):
26 return s.__html__()
27 if not isinstance(s, string_types):
28 __unicode__ = getattr(s, '__unicode__', None)
29 if __unicode__ is not None and callable(__unicode__):
30 s = s.__unicode__()
31 else:
32 s = str(s)
33 s = escape(s, True)
34 if isinstance(s, text_type):
35 s = s.encode('ascii', 'xmlcharrefreplace')
36 return text_(s)
38def header_docstring(header, rfc_section):
39 if header.isupper():
40 header = _trans_key(header)
41 major_section = rfc_section.split('.')[0]
42 link = 'http://www.w3.org/Protocols/rfc2616/rfc2616-sec%s.html#sec%s' % (
43 major_section, rfc_section)
44 return "Gets and sets the ``%s`` header (`HTTP spec section %s <%s>`_)." % (
45 header, rfc_section, link)
48def warn_deprecation(text, version, stacklevel):
49 # version specifies when to start raising exceptions instead of warnings
50 if version in ('1.2', '1.3', '1.4', '1.5', '1.6', '1.7'):
51 raise DeprecationWarning(text)
52 else:
53 cls = DeprecationWarning
54 warnings.warn(text, cls, stacklevel=stacklevel + 1)
56status_reasons = {
57 # Status Codes
58 # Informational
59 100: 'Continue',
60 101: 'Switching Protocols',
61 102: 'Processing',
63 # Successful
64 200: 'OK',
65 201: 'Created',
66 202: 'Accepted',
67 203: 'Non-Authoritative Information',
68 204: 'No Content',
69 205: 'Reset Content',
70 206: 'Partial Content',
71 207: 'Multi Status',
72 226: 'IM Used',
74 # Redirection
75 300: 'Multiple Choices',
76 301: 'Moved Permanently',
77 302: 'Found',
78 303: 'See Other',
79 304: 'Not Modified',
80 305: 'Use Proxy',
81 307: 'Temporary Redirect',
82 308: 'Permanent Redirect',
84 # Client Error
85 400: 'Bad Request',
86 401: 'Unauthorized',
87 402: 'Payment Required',
88 403: 'Forbidden',
89 404: 'Not Found',
90 405: 'Method Not Allowed',
91 406: 'Not Acceptable',
92 407: 'Proxy Authentication Required',
93 408: 'Request Timeout',
94 409: 'Conflict',
95 410: 'Gone',
96 411: 'Length Required',
97 412: 'Precondition Failed',
98 413: 'Request Entity Too Large',
99 414: 'Request URI Too Long',
100 415: 'Unsupported Media Type',
101 416: 'Requested Range Not Satisfiable',
102 417: 'Expectation Failed',
103 418: "I'm a teapot",
104 422: 'Unprocessable Entity',
105 423: 'Locked',
106 424: 'Failed Dependency',
107 426: 'Upgrade Required',
108 428: 'Precondition Required',
109 429: 'Too Many Requests',
110 451: 'Unavailable for Legal Reasons',
111 431: 'Request Header Fields Too Large',
113 # Server Error
114 500: 'Internal Server Error',
115 501: 'Not Implemented',
116 502: 'Bad Gateway',
117 503: 'Service Unavailable',
118 504: 'Gateway Timeout',
119 505: 'HTTP Version Not Supported',
120 507: 'Insufficient Storage',
121 510: 'Not Extended',
122 511: 'Network Authentication Required',
123}
125# generic class responses as per RFC2616
126status_generic_reasons = {
127 1: 'Continue',
128 2: 'Success',
129 3: 'Multiple Choices',
130 4: 'Unknown Client Error',
131 5: 'Unknown Server Error',
132}
134try:
135 # py3.3+ have native comparison support
136 from hmac import compare_digest
137except ImportError: # pragma: nocover (Python 2.7.7 backported this)
138 compare_digest = None
140def strings_differ(string1, string2, compare_digest=compare_digest):
141 """Check whether two strings differ while avoiding timing attacks.
143 This function returns True if the given strings differ and False
144 if they are equal. It's careful not to leak information about *where*
145 they differ as a result of its running time, which can be very important
146 to avoid certain timing-related crypto attacks:
148 http://seb.dbzteam.org/crypto/python-oauth-timing-hmac.pdf
150 .. versionchanged:: 1.5
151 Support :func:`hmac.compare_digest` if it is available (Python 2.7.7+
152 and Python 3.3+).
154 """
155 len_eq = len(string1) == len(string2)
156 if len_eq:
157 invalid_bits = 0
158 left = string1
159 else:
160 invalid_bits = 1
161 left = string2
162 right = string2
164 if compare_digest is not None:
165 invalid_bits += not compare_digest(left, right)
166 else:
167 for a, b in zip(left, right):
168 invalid_bits += a != b
169 return invalid_bits != 0