Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

_compat.py 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import sys
  2. from gunicorn import six
  3. PY26 = (sys.version_info[:2] == (2, 6))
  4. PY33 = (sys.version_info >= (3, 3))
  5. def _check_if_pyc(fname):
  6. """Return True if the extension is .pyc, False if .py
  7. and None if otherwise"""
  8. from imp import find_module
  9. from os.path import realpath, dirname, basename, splitext
  10. # Normalize the file-path for the find_module()
  11. filepath = realpath(fname)
  12. dirpath = dirname(filepath)
  13. module_name = splitext(basename(filepath))[0]
  14. # Validate and fetch
  15. try:
  16. fileobj, fullpath, (_, _, pytype) = find_module(module_name, [dirpath])
  17. except ImportError:
  18. raise IOError("Cannot find config file. "
  19. "Path maybe incorrect! : {0}".format(filepath))
  20. return pytype, fileobj, fullpath
  21. def _get_codeobj(pyfile):
  22. """ Returns the code object, given a python file """
  23. from imp import PY_COMPILED, PY_SOURCE
  24. result, fileobj, fullpath = _check_if_pyc(pyfile)
  25. # WARNING:
  26. # fp.read() can blowup if the module is extremely large file.
  27. # Lookout for overflow errors.
  28. try:
  29. data = fileobj.read()
  30. finally:
  31. fileobj.close()
  32. # This is a .pyc file. Treat accordingly.
  33. if result is PY_COMPILED:
  34. # .pyc format is as follows:
  35. # 0 - 4 bytes: Magic number, which changes with each create of .pyc file.
  36. # First 2 bytes change with each marshal of .pyc file. Last 2 bytes is "\r\n".
  37. # 4 - 8 bytes: Datetime value, when the .py was last changed.
  38. # 8 - EOF: Marshalled code object data.
  39. # So to get code object, just read the 8th byte onwards till EOF, and
  40. # UN-marshal it.
  41. import marshal
  42. code_obj = marshal.loads(data[8:])
  43. elif result is PY_SOURCE:
  44. # This is a .py file.
  45. code_obj = compile(data, fullpath, 'exec')
  46. else:
  47. # Unsupported extension
  48. raise Exception("Input file is unknown format: {0}".format(fullpath))
  49. # Return code object
  50. return code_obj
  51. if six.PY3:
  52. def execfile_(fname, *args):
  53. if fname.endswith(".pyc"):
  54. code = _get_codeobj(fname)
  55. else:
  56. code = compile(open(fname, 'rb').read(), fname, 'exec')
  57. return six.exec_(code, *args)
  58. def bytes_to_str(b):
  59. if isinstance(b, six.text_type):
  60. return b
  61. return str(b, 'latin1')
  62. import urllib.parse
  63. def unquote_to_wsgi_str(string):
  64. return _unquote_to_bytes(string).decode('latin-1')
  65. _unquote_to_bytes = urllib.parse.unquote_to_bytes
  66. else:
  67. def execfile_(fname, *args):
  68. """ Overriding PY2 execfile() implementation to support .pyc files """
  69. if fname.endswith(".pyc"):
  70. return six.exec_(_get_codeobj(fname), *args)
  71. return execfile(fname, *args)
  72. def bytes_to_str(s):
  73. if isinstance(s, unicode):
  74. return s.encode('utf-8')
  75. return s
  76. import urllib
  77. unquote_to_wsgi_str = urllib.unquote
  78. # The following code adapted from trollius.py33_exceptions
  79. def _wrap_error(exc, mapping, key):
  80. if key not in mapping:
  81. return
  82. new_err_cls = mapping[key]
  83. new_err = new_err_cls(*exc.args)
  84. # raise a new exception with the original traceback
  85. six.reraise(new_err_cls, new_err,
  86. exc.__traceback__ if hasattr(exc, '__traceback__') else sys.exc_info()[2])
  87. if PY33:
  88. import builtins
  89. BlockingIOError = builtins.BlockingIOError
  90. BrokenPipeError = builtins.BrokenPipeError
  91. ChildProcessError = builtins.ChildProcessError
  92. ConnectionRefusedError = builtins.ConnectionRefusedError
  93. ConnectionResetError = builtins.ConnectionResetError
  94. InterruptedError = builtins.InterruptedError
  95. ConnectionAbortedError = builtins.ConnectionAbortedError
  96. PermissionError = builtins.PermissionError
  97. FileNotFoundError = builtins.FileNotFoundError
  98. ProcessLookupError = builtins.ProcessLookupError
  99. def wrap_error(func, *args, **kw):
  100. return func(*args, **kw)
  101. else:
  102. import errno
  103. import select
  104. import socket
  105. class BlockingIOError(OSError):
  106. pass
  107. class BrokenPipeError(OSError):
  108. pass
  109. class ChildProcessError(OSError):
  110. pass
  111. class ConnectionRefusedError(OSError):
  112. pass
  113. class InterruptedError(OSError):
  114. pass
  115. class ConnectionResetError(OSError):
  116. pass
  117. class ConnectionAbortedError(OSError):
  118. pass
  119. class PermissionError(OSError):
  120. pass
  121. class FileNotFoundError(OSError):
  122. pass
  123. class ProcessLookupError(OSError):
  124. pass
  125. _MAP_ERRNO = {
  126. errno.EACCES: PermissionError,
  127. errno.EAGAIN: BlockingIOError,
  128. errno.EALREADY: BlockingIOError,
  129. errno.ECHILD: ChildProcessError,
  130. errno.ECONNABORTED: ConnectionAbortedError,
  131. errno.ECONNREFUSED: ConnectionRefusedError,
  132. errno.ECONNRESET: ConnectionResetError,
  133. errno.EINPROGRESS: BlockingIOError,
  134. errno.EINTR: InterruptedError,
  135. errno.ENOENT: FileNotFoundError,
  136. errno.EPERM: PermissionError,
  137. errno.EPIPE: BrokenPipeError,
  138. errno.ESHUTDOWN: BrokenPipeError,
  139. errno.EWOULDBLOCK: BlockingIOError,
  140. errno.ESRCH: ProcessLookupError,
  141. }
  142. def wrap_error(func, *args, **kw):
  143. """
  144. Wrap socket.error, IOError, OSError, select.error to raise new specialized
  145. exceptions of Python 3.3 like InterruptedError (PEP 3151).
  146. """
  147. try:
  148. return func(*args, **kw)
  149. except (socket.error, IOError, OSError) as exc:
  150. if hasattr(exc, 'winerror'):
  151. _wrap_error(exc, _MAP_ERRNO, exc.winerror)
  152. # _MAP_ERRNO does not contain all Windows errors.
  153. # For some errors like "file not found", exc.errno should
  154. # be used (ex: ENOENT).
  155. _wrap_error(exc, _MAP_ERRNO, exc.errno)
  156. raise
  157. except select.error as exc:
  158. if exc.args:
  159. _wrap_error(exc, _MAP_ERRNO, exc.args[0])
  160. raise
  161. if PY26:
  162. from urlparse import (
  163. _parse_cache, MAX_CACHE_SIZE, clear_cache, _splitnetloc, SplitResult,
  164. scheme_chars,
  165. )
  166. def urlsplit(url, scheme='', allow_fragments=True):
  167. """Parse a URL into 5 components:
  168. <scheme>://<netloc>/<path>?<query>#<fragment>
  169. Return a 5-tuple: (scheme, netloc, path, query, fragment).
  170. Note that we don't break the components up in smaller bits
  171. (e.g. netloc is a single string) and we don't expand % escapes."""
  172. allow_fragments = bool(allow_fragments)
  173. key = url, scheme, allow_fragments, type(url), type(scheme)
  174. cached = _parse_cache.get(key, None)
  175. if cached:
  176. return cached
  177. if len(_parse_cache) >= MAX_CACHE_SIZE: # avoid runaway growth
  178. clear_cache()
  179. netloc = query = fragment = ''
  180. i = url.find(':')
  181. if i > 0:
  182. if url[:i] == 'http': # optimize the common case
  183. scheme = url[:i].lower()
  184. url = url[i+1:]
  185. if url[:2] == '//':
  186. netloc, url = _splitnetloc(url, 2)
  187. if (('[' in netloc and ']' not in netloc) or
  188. (']' in netloc and '[' not in netloc)):
  189. raise ValueError("Invalid IPv6 URL")
  190. if allow_fragments and '#' in url:
  191. url, fragment = url.split('#', 1)
  192. if '?' in url:
  193. url, query = url.split('?', 1)
  194. v = SplitResult(scheme, netloc, url, query, fragment)
  195. _parse_cache[key] = v
  196. return v
  197. for c in url[:i]:
  198. if c not in scheme_chars:
  199. break
  200. else:
  201. # make sure "url" is not actually a port number (in which case
  202. # "scheme" is really part of the path)
  203. rest = url[i+1:]
  204. if not rest or any(c not in '0123456789' for c in rest):
  205. # not a port number
  206. scheme, url = url[:i].lower(), rest
  207. if url[:2] == '//':
  208. netloc, url = _splitnetloc(url, 2)
  209. if (('[' in netloc and ']' not in netloc) or
  210. (']' in netloc and '[' not in netloc)):
  211. raise ValueError("Invalid IPv6 URL")
  212. if allow_fragments and '#' in url:
  213. url, fragment = url.split('#', 1)
  214. if '?' in url:
  215. url, query = url.split('?', 1)
  216. v = SplitResult(scheme, netloc, url, query, fragment)
  217. _parse_cache[key] = v
  218. return v
  219. else:
  220. from gunicorn.six.moves.urllib.parse import urlsplit