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

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
1# code stolen from "six"
3import sys
4import types
5from cgi import parse_header
7# True if we are running on Python 3.
8PY3 = sys.version_info[0] == 3
9PY2 = sys.version_info[0] == 2
11if PY3:
12 string_types = str,
13 integer_types = int,
14 class_types = type,
15 text_type = str
16 long = int
17else:
18 string_types = basestring,
19 integer_types = (int, long)
20 class_types = (type, types.ClassType)
21 text_type = unicode
22 long = long
24# TODO check if errors is ever used
26def text_(s, encoding='latin-1', errors='strict'):
27 if isinstance(s, bytes):
28 return s.decode(encoding, errors)
29 return s
31def bytes_(s, encoding='latin-1', errors='strict'):
32 if isinstance(s, text_type):
33 return s.encode(encoding, errors)
34 return s
36if PY3:
37 def native_(s, encoding='latin-1', errors='strict'):
38 if isinstance(s, text_type):
39 return s
40 return str(s, encoding, errors)
41else:
42 def native_(s, encoding='latin-1', errors='strict'):
43 if isinstance(s, text_type):
44 return s.encode(encoding, errors)
45 return str(s)
47try:
48 from queue import Queue, Empty
49except ImportError:
50 from Queue import Queue, Empty
52try:
53 from collections.abc import MutableMapping
54 from collections.abc import Iterable
55except ImportError:
56 from collections import MutableMapping
57 from collections import Iterable
59if PY3:
60 from urllib import parse
61 urlparse = parse
62 from urllib.parse import quote as url_quote
63 from urllib.parse import urlencode as url_encode, quote_plus
64 from urllib.request import urlopen as url_open
65else:
66 import urlparse
67 from urllib import quote_plus
68 from urllib import quote as url_quote
69 from urllib import unquote as url_unquote
70 from urllib import urlencode as url_encode
71 from urllib2 import urlopen as url_open
73if PY3: # pragma: no cover
74 def reraise(exc_info):
75 etype, exc, tb = exc_info
76 if exc.__traceback__ is not tb:
77 raise exc.with_traceback(tb)
78 raise exc
79else:
80 exec("def reraise(exc): raise exc[0], exc[1], exc[2]")
83if PY3:
84 def iteritems_(d):
85 return d.items()
86 def itervalues_(d):
87 return d.values()
88else:
89 def iteritems_(d):
90 return d.iteritems()
91 def itervalues_(d):
92 return d.itervalues()
95if PY3: # pragma: no cover
96 def unquote(string):
97 if not string:
98 return b''
99 res = string.split(b'%')
100 if len(res) != 1:
101 string = res[0]
102 for item in res[1:]:
103 try:
104 string += bytes([int(item[:2], 16)]) + item[2:]
105 except ValueError:
106 string += b'%' + item
107 return string
109 def url_unquote(s):
110 return unquote(s.encode('ascii')).decode('latin-1')
112 def parse_qsl_text(qs, encoding='utf-8'):
113 qs = qs.encode('latin-1')
114 qs = qs.replace(b'+', b' ')
115 pairs = [s2 for s1 in qs.split(b'&') for s2 in s1.split(b';') if s2]
116 for name_value in pairs:
117 nv = name_value.split(b'=', 1)
118 if len(nv) != 2:
119 nv.append('')
120 name = unquote(nv[0])
121 value = unquote(nv[1])
122 yield (name.decode(encoding), value.decode(encoding))
124else:
125 from urlparse import parse_qsl
127 def parse_qsl_text(qs, encoding='utf-8'):
128 qsl = parse_qsl(
129 qs,
130 keep_blank_values=True,
131 strict_parsing=False
132 )
133 for (x, y) in qsl:
134 yield (x.decode(encoding), y.decode(encoding))
137if PY3:
138 from html import escape
139else:
140 from cgi import escape
143if PY3:
144 import cgi
145 import tempfile
146 from cgi import FieldStorage as _cgi_FieldStorage
148 # Various different FieldStorage work-arounds required on Python 3.x
149 class cgi_FieldStorage(_cgi_FieldStorage): # pragma: no cover
151 # Work around https://bugs.python.org/issue27777
152 def make_file(self):
153 if self._binary_file or self.length >= 0:
154 return tempfile.TemporaryFile("wb+")
155 else:
156 return tempfile.TemporaryFile(
157 "w+",
158 encoding=self.encoding, newline='\n'
159 )
161 # Work around http://bugs.python.org/issue23801
162 # This is taken exactly from Python 3.5's cgi.py module
163 def read_multi(self, environ, keep_blank_values, strict_parsing):
164 """Internal: read a part that is itself multipart."""
165 ib = self.innerboundary
166 if not cgi.valid_boundary(ib):
167 raise ValueError(
168 'Invalid boundary in multipart form: %r' % (ib,))
169 self.list = []
170 if self.qs_on_post:
171 query = cgi.urllib.parse.parse_qsl(
172 self.qs_on_post, self.keep_blank_values,
173 self.strict_parsing,
174 encoding=self.encoding, errors=self.errors)
175 for key, value in query:
176 self.list.append(cgi.MiniFieldStorage(key, value))
178 klass = self.FieldStorageClass or self.__class__
179 first_line = self.fp.readline() # bytes
180 if not isinstance(first_line, bytes):
181 raise ValueError("%s should return bytes, got %s"
182 % (self.fp, type(first_line).__name__))
183 self.bytes_read += len(first_line)
185 # Ensure that we consume the file until we've hit our innerboundary
186 while (first_line.strip() != (b"--" + self.innerboundary) and
187 first_line):
188 first_line = self.fp.readline()
189 self.bytes_read += len(first_line)
191 while True:
192 parser = cgi.FeedParser()
193 hdr_text = b""
194 while True:
195 data = self.fp.readline()
196 hdr_text += data
197 if not data.strip():
198 break
199 if not hdr_text:
200 break
201 # parser takes strings, not bytes
202 self.bytes_read += len(hdr_text)
203 parser.feed(hdr_text.decode(self.encoding, self.errors))
204 headers = parser.close()
205 # Some clients add Content-Length for part headers, ignore them
206 if 'content-length' in headers:
207 filename = None
208 if 'content-disposition' in self.headers:
209 cdisp, pdict = parse_header(self.headers['content-disposition'])
210 if 'filename' in pdict:
211 filename = pdict['filename']
212 if filename is None:
213 del headers['content-length']
214 part = klass(self.fp, headers, ib, environ, keep_blank_values,
215 strict_parsing, self.limit-self.bytes_read,
216 self.encoding, self.errors)
217 self.bytes_read += part.bytes_read
218 self.list.append(part)
219 if part.done or self.bytes_read >= self.length > 0:
220 break
221 self.skip_lines()
222else:
223 from cgi import FieldStorage as cgi_FieldStorage