Hide keyboard shortcuts

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 inspect 

2import platform 

3import sys 

4import types 

5 

6WIN = platform.system() == 'Windows' 

7 

8try: # pragma: no cover 

9 import __pypy__ 

10 

11 PYPY = True 

12except BaseException: # pragma: no cover 

13 __pypy__ = None 

14 PYPY = False 

15 

16try: 

17 import cPickle as pickle 

18except ImportError: # pragma: no cover 

19 import pickle 

20 

21try: 

22 from functools import lru_cache 

23except ImportError: 

24 from repoze.lru import lru_cache 

25 

26# PY3 is left as bw-compat but PY2 should be used for most checks. 

27PY2 = sys.version_info[0] == 2 

28PY3 = sys.version_info[0] == 3 

29 

30if PY2: 

31 string_types = (basestring,) 

32 integer_types = (int, long) 

33 class_types = (type, types.ClassType) 

34 text_type = unicode 

35 binary_type = str 

36 long = long 

37else: 

38 string_types = (str,) 

39 integer_types = (int,) 

40 class_types = (type,) 

41 text_type = str 

42 binary_type = bytes 

43 long = int 

44 

45 

46def text_(s, encoding='latin-1', errors='strict'): 

47 """ If ``s`` is an instance of ``binary_type``, return 

48 ``s.decode(encoding, errors)``, otherwise return ``s``""" 

49 if isinstance(s, binary_type): 

50 return s.decode(encoding, errors) 

51 return s 

52 

53 

54def bytes_(s, encoding='latin-1', errors='strict'): 

55 """ If ``s`` is an instance of ``text_type``, return 

56 ``s.encode(encoding, errors)``, otherwise return ``s``""" 

57 if isinstance(s, text_type): 

58 return s.encode(encoding, errors) 

59 return s 

60 

61 

62if PY2: 

63 

64 def ascii_native_(s): 

65 if isinstance(s, text_type): 

66 s = s.encode('ascii') 

67 return str(s) 

68 

69 

70else: 

71 

72 def ascii_native_(s): 

73 if isinstance(s, text_type): 

74 s = s.encode('ascii') 

75 return str(s, 'ascii', 'strict') 

76 

77 

78ascii_native_.__doc__ = """ 

79Python 3: If ``s`` is an instance of ``text_type``, return 

80``s.encode('ascii')``, otherwise return ``str(s, 'ascii', 'strict')`` 

81 

82Python 2: If ``s`` is an instance of ``text_type``, return 

83``s.encode('ascii')``, otherwise return ``str(s)`` 

84""" 

85 

86 

87if PY2: 

88 

89 def native_(s, encoding='latin-1', errors='strict'): 

90 """ If ``s`` is an instance of ``text_type``, return 

91 ``s.encode(encoding, errors)``, otherwise return ``str(s)``""" 

92 if isinstance(s, text_type): 

93 return s.encode(encoding, errors) 

94 return str(s) 

95 

96 

97else: 

98 

99 def native_(s, encoding='latin-1', errors='strict'): 

100 """ If ``s`` is an instance of ``text_type``, return 

101 ``s``, otherwise return ``str(s, encoding, errors)``""" 

102 if isinstance(s, text_type): 

103 return s 

104 return str(s, encoding, errors) 

105 

106 

107native_.__doc__ = """ 

108Python 3: If ``s`` is an instance of ``text_type``, return ``s``, otherwise 

109return ``str(s, encoding, errors)`` 

110 

111Python 2: If ``s`` is an instance of ``text_type``, return 

112``s.encode(encoding, errors)``, otherwise return ``str(s)`` 

113""" 

114 

115if PY2: 

116 import urlparse 

117 from urllib import quote as url_quote 

118 from urllib import quote_plus as url_quote_plus 

119 from urllib import unquote as url_unquote 

120 from urllib import urlencode as url_encode 

121 from urllib2 import urlopen as url_open 

122 

123 def url_unquote_text( 

124 v, encoding='utf-8', errors='replace' 

125 ): # pragma: no cover 

126 v = url_unquote(v) 

127 return v.decode(encoding, errors) 

128 

129 def url_unquote_native( 

130 v, encoding='utf-8', errors='replace' 

131 ): # pragma: no cover 

132 return native_(url_unquote_text(v, encoding, errors)) 

133 

134 

135else: 

136 from urllib import parse 

137 

138 urlparse = parse 

139 from urllib.parse import quote as url_quote 

140 from urllib.parse import quote_plus as url_quote_plus 

141 from urllib.parse import unquote as url_unquote 

142 from urllib.parse import urlencode as url_encode 

143 from urllib.request import urlopen as url_open 

144 

145 url_unquote_text = url_unquote 

146 url_unquote_native = url_unquote 

147 

148 

149if PY2: # pragma: no cover 

150 

151 def exec_(code, globs=None, locs=None): 

152 """Execute code in a namespace.""" 

153 if globs is None: 

154 frame = sys._getframe(1) 

155 globs = frame.f_globals 

156 if locs is None: 

157 locs = frame.f_locals 

158 del frame 

159 elif locs is None: 

160 locs = globs 

161 exec("""exec code in globs, locs""") 

162 

163 exec_( 

164 """def reraise(tp, value, tb=None): 

165 raise tp, value, tb 

166""" 

167 ) 

168 

169else: # pragma: no cover 

170 import builtins 

171 

172 exec_ = getattr(builtins, "exec") 

173 

174 def reraise(tp, value, tb=None): 

175 if value is None: 

176 value = tp 

177 if value.__traceback__ is not tb: 

178 raise value.with_traceback(tb) 

179 raise value 

180 

181 del builtins 

182 

183 

184if PY2: # pragma: no cover 

185 

186 def iteritems_(d): 

187 return d.iteritems() 

188 

189 def itervalues_(d): 

190 return d.itervalues() 

191 

192 def iterkeys_(d): 

193 return d.iterkeys() 

194 

195 

196else: # pragma: no cover 

197 

198 def iteritems_(d): 

199 return d.items() 

200 

201 def itervalues_(d): 

202 return d.values() 

203 

204 def iterkeys_(d): 

205 return d.keys() 

206 

207 

208if PY2: 

209 map_ = map 

210else: 

211 

212 def map_(*arg): 

213 return list(map(*arg)) 

214 

215 

216if PY2: 

217 

218 def is_nonstr_iter(v): 

219 return hasattr(v, '__iter__') 

220 

221 

222else: 

223 

224 def is_nonstr_iter(v): 

225 if isinstance(v, str): 

226 return False 

227 return hasattr(v, '__iter__') 

228 

229 

230if PY2: 

231 im_func = 'im_func' 

232 im_self = 'im_self' 

233else: 

234 im_func = '__func__' 

235 im_self = '__self__' 

236 

237try: 

238 import configparser 

239except ImportError: 

240 import ConfigParser as configparser 

241 

242try: 

243 from http.cookies import SimpleCookie 

244except ImportError: 

245 from Cookie import SimpleCookie 

246 

247if PY2: 

248 from cgi import escape 

249else: 

250 from html import escape 

251 

252if PY2: 

253 input_ = raw_input 

254else: 

255 input_ = input 

256 

257if PY2: 

258 from io import BytesIO as NativeIO 

259else: 

260 from io import StringIO as NativeIO 

261 

262# "json" is not an API; it's here to support older pyramid_debugtoolbar 

263# versions which attempt to import it 

264import json 

265 

266if PY2: 

267 

268 def decode_path_info(path): 

269 return path.decode('utf-8') 

270 

271 

272else: 

273 # see PEP 3333 for why we encode WSGI PATH_INFO to latin-1 before 

274 # decoding it to utf-8 

275 def decode_path_info(path): 

276 return path.encode('latin-1').decode('utf-8') 

277 

278 

279if PY2: 

280 from urlparse import unquote as unquote_to_bytes 

281 

282 def unquote_bytes_to_wsgi(bytestring): 

283 return unquote_to_bytes(bytestring) 

284 

285 

286else: 

287 # see PEP 3333 for why we decode the path to latin-1 

288 from urllib.parse import unquote_to_bytes 

289 

290 def unquote_bytes_to_wsgi(bytestring): 

291 return unquote_to_bytes(bytestring).decode('latin-1') 

292 

293 

294def is_bound_method(ob): 

295 return inspect.ismethod(ob) and getattr(ob, im_self, None) is not None 

296 

297 

298# support annotations and keyword-only arguments in PY3 

299if PY2: 

300 from inspect import getargspec 

301else: 

302 from inspect import getfullargspec as getargspec 

303 

304if PY2: 

305 from itertools import izip_longest as zip_longest 

306else: 

307 from itertools import zip_longest 

308 

309 

310def is_unbound_method(fn): 

311 """ 

312 This consistently verifies that the callable is bound to a 

313 class. 

314 """ 

315 is_bound = is_bound_method(fn) 

316 

317 if not is_bound and inspect.isroutine(fn): 

318 spec = getargspec(fn) 

319 has_self = len(spec.args) > 0 and spec.args[0] == 'self' 

320 

321 if PY2 and inspect.ismethod(fn): 

322 return True 

323 elif inspect.isfunction(fn) and has_self: 

324 return True 

325 

326 return False