PageRenderTime 57ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/EMORY_globus_dnaComplete_optimized_bk/pymodules/python2.7/lib/python/Cython/Utils.py

https://gitlab.com/pooja043/Globus_Docker_3
Python | 438 lines | 340 code | 48 blank | 50 comment | 82 complexity | c182f7df742fc5cf8a63c969212cc8fb MD5 | raw file
  1. #
  2. # Cython -- Things that don't belong
  3. # anywhere else in particular
  4. #
  5. from __future__ import absolute_import
  6. try:
  7. from __builtin__ import basestring
  8. except ImportError:
  9. basestring = str
  10. import os
  11. import sys
  12. import re
  13. import io
  14. import codecs
  15. from contextlib import contextmanager
  16. modification_time = os.path.getmtime
  17. def cached_function(f):
  18. cache = {}
  19. uncomputed = object()
  20. def wrapper(*args):
  21. res = cache.get(args, uncomputed)
  22. if res is uncomputed:
  23. res = cache[args] = f(*args)
  24. return res
  25. wrapper.uncached = f
  26. return wrapper
  27. def cached_method(f):
  28. cache_name = '__%s_cache' % f.__name__
  29. def wrapper(self, *args):
  30. cache = getattr(self, cache_name, None)
  31. if cache is None:
  32. cache = {}
  33. setattr(self, cache_name, cache)
  34. if args in cache:
  35. return cache[args]
  36. res = cache[args] = f(self, *args)
  37. return res
  38. return wrapper
  39. def replace_suffix(path, newsuf):
  40. base, _ = os.path.splitext(path)
  41. return base + newsuf
  42. def open_new_file(path):
  43. if os.path.exists(path):
  44. # Make sure to create a new file here so we can
  45. # safely hard link the output files.
  46. os.unlink(path)
  47. # we use the ISO-8859-1 encoding here because we only write pure
  48. # ASCII strings or (e.g. for file names) byte encoded strings as
  49. # Unicode, so we need a direct mapping from the first 256 Unicode
  50. # characters to a byte sequence, which ISO-8859-1 provides
  51. # note: can't use io.open() in Py2 as we may be writing str objects
  52. return codecs.open(path, "w", encoding="ISO-8859-1")
  53. def castrate_file(path, st):
  54. # Remove junk contents from an output file after a
  55. # failed compilation.
  56. # Also sets access and modification times back to
  57. # those specified by st (a stat struct).
  58. try:
  59. f = open_new_file(path)
  60. except EnvironmentError:
  61. pass
  62. else:
  63. f.write(
  64. "#error Do not use this file, it is the result of a failed Cython compilation.\n")
  65. f.close()
  66. if st:
  67. os.utime(path, (st.st_atime, st.st_mtime-1))
  68. def file_newer_than(path, time):
  69. ftime = modification_time(path)
  70. return ftime > time
  71. @cached_function
  72. def search_include_directories(dirs, qualified_name, suffix, pos,
  73. include=False, sys_path=False):
  74. # Search the list of include directories for the given
  75. # file name. If a source file position is given, first
  76. # searches the directory containing that file. Returns
  77. # None if not found, but does not report an error.
  78. # The 'include' option will disable package dereferencing.
  79. # If 'sys_path' is True, also search sys.path.
  80. if sys_path:
  81. dirs = dirs + tuple(sys.path)
  82. if pos:
  83. file_desc = pos[0]
  84. from Cython.Compiler.Scanning import FileSourceDescriptor
  85. if not isinstance(file_desc, FileSourceDescriptor):
  86. raise RuntimeError("Only file sources for code supported")
  87. if include:
  88. dirs = (os.path.dirname(file_desc.filename),) + dirs
  89. else:
  90. dirs = (find_root_package_dir(file_desc.filename),) + dirs
  91. dotted_filename = qualified_name
  92. if suffix:
  93. dotted_filename += suffix
  94. if not include:
  95. names = qualified_name.split('.')
  96. package_names = tuple(names[:-1])
  97. module_name = names[-1]
  98. module_filename = module_name + suffix
  99. package_filename = "__init__" + suffix
  100. for dir in dirs:
  101. path = os.path.join(dir, dotted_filename)
  102. if path_exists(path):
  103. return path
  104. if not include:
  105. package_dir = check_package_dir(dir, package_names)
  106. if package_dir is not None:
  107. path = os.path.join(package_dir, module_filename)
  108. if path_exists(path):
  109. return path
  110. path = os.path.join(dir, package_dir, module_name,
  111. package_filename)
  112. if path_exists(path):
  113. return path
  114. return None
  115. @cached_function
  116. def find_root_package_dir(file_path):
  117. dir = os.path.dirname(file_path)
  118. if file_path == dir:
  119. return dir
  120. elif is_package_dir(dir):
  121. return find_root_package_dir(dir)
  122. else:
  123. return dir
  124. @cached_function
  125. def check_package_dir(dir, package_names):
  126. for dirname in package_names:
  127. dir = os.path.join(dir, dirname)
  128. if not is_package_dir(dir):
  129. return None
  130. return dir
  131. @cached_function
  132. def is_package_dir(dir_path):
  133. for filename in ("__init__.py",
  134. "__init__.pyc",
  135. "__init__.pyx",
  136. "__init__.pxd"):
  137. path = os.path.join(dir_path, filename)
  138. if path_exists(path):
  139. return 1
  140. @cached_function
  141. def path_exists(path):
  142. # try on the filesystem first
  143. if os.path.exists(path):
  144. return True
  145. # figure out if a PEP 302 loader is around
  146. try:
  147. loader = __loader__
  148. # XXX the code below assumes a 'zipimport.zipimporter' instance
  149. # XXX should be easy to generalize, but too lazy right now to write it
  150. archive_path = getattr(loader, 'archive', None)
  151. if archive_path:
  152. normpath = os.path.normpath(path)
  153. if normpath.startswith(archive_path):
  154. arcname = normpath[len(archive_path)+1:]
  155. try:
  156. loader.get_data(arcname)
  157. return True
  158. except IOError:
  159. return False
  160. except NameError:
  161. pass
  162. return False
  163. # file name encodings
  164. def decode_filename(filename):
  165. if isinstance(filename, bytes):
  166. try:
  167. filename_encoding = sys.getfilesystemencoding()
  168. if filename_encoding is None:
  169. filename_encoding = sys.getdefaultencoding()
  170. filename = filename.decode(filename_encoding)
  171. except UnicodeDecodeError:
  172. pass
  173. return filename
  174. # support for source file encoding detection
  175. _match_file_encoding = re.compile(u"coding[:=]\s*([-\w.]+)").search
  176. def detect_file_encoding(source_filename):
  177. f = open_source_file(source_filename, encoding="UTF-8", error_handling='ignore')
  178. try:
  179. return detect_opened_file_encoding(f)
  180. finally:
  181. f.close()
  182. def detect_opened_file_encoding(f):
  183. # PEPs 263 and 3120
  184. # Most of the time the first two lines fall in the first 250 chars,
  185. # and this bulk read/split is much faster.
  186. lines = f.read(250).split(u"\n")
  187. if len(lines) > 1:
  188. m = _match_file_encoding(lines[0])
  189. if m:
  190. return m.group(1)
  191. elif len(lines) > 2:
  192. m = _match_file_encoding(lines[1])
  193. if m:
  194. return m.group(1)
  195. else:
  196. return "UTF-8"
  197. # Fallback to one-char-at-a-time detection.
  198. f.seek(0)
  199. chars = []
  200. for i in range(2):
  201. c = f.read(1)
  202. while c and c != u'\n':
  203. chars.append(c)
  204. c = f.read(1)
  205. encoding = _match_file_encoding(u''.join(chars))
  206. if encoding:
  207. return encoding.group(1)
  208. return "UTF-8"
  209. def skip_bom(f):
  210. """
  211. Read past a BOM at the beginning of a source file.
  212. This could be added to the scanner, but it's *substantially* easier
  213. to keep it at this level.
  214. """
  215. if f.read(1) != u'\uFEFF':
  216. f.seek(0)
  217. def open_source_file(source_filename, mode="r",
  218. encoding=None, error_handling=None):
  219. if encoding is None:
  220. # Most of the time the coding is unspecified, so be optimistic that
  221. # it's UTF-8.
  222. f = open_source_file(source_filename, encoding="UTF-8", mode=mode, error_handling='ignore')
  223. encoding = detect_opened_file_encoding(f)
  224. if encoding == "UTF-8" and error_handling == 'ignore':
  225. f.seek(0)
  226. skip_bom(f)
  227. return f
  228. else:
  229. f.close()
  230. if not os.path.exists(source_filename):
  231. try:
  232. loader = __loader__
  233. if source_filename.startswith(loader.archive):
  234. return open_source_from_loader(
  235. loader, source_filename,
  236. encoding, error_handling)
  237. except (NameError, AttributeError):
  238. pass
  239. stream = io.open(source_filename, mode=mode,
  240. encoding=encoding, errors=error_handling)
  241. skip_bom(stream)
  242. return stream
  243. def open_source_from_loader(loader,
  244. source_filename,
  245. encoding=None, error_handling=None):
  246. nrmpath = os.path.normpath(source_filename)
  247. arcname = nrmpath[len(loader.archive)+1:]
  248. data = loader.get_data(arcname)
  249. return io.TextIOWrapper(io.BytesIO(data),
  250. encoding=encoding,
  251. errors=error_handling)
  252. def str_to_number(value):
  253. # note: this expects a string as input that was accepted by the
  254. # parser already, with an optional "-" sign in front
  255. is_neg = False
  256. if value[:1] == '-':
  257. is_neg = True
  258. value = value[1:]
  259. if len(value) < 2:
  260. value = int(value, 0)
  261. elif value[0] == '0':
  262. literal_type = value[1] # 0'o' - 0'b' - 0'x'
  263. if literal_type in 'xX':
  264. # hex notation ('0x1AF')
  265. value = int(value[2:], 16)
  266. elif literal_type in 'oO':
  267. # Py3 octal notation ('0o136')
  268. value = int(value[2:], 8)
  269. elif literal_type in 'bB':
  270. # Py3 binary notation ('0b101')
  271. value = int(value[2:], 2)
  272. else:
  273. # Py2 octal notation ('0136')
  274. value = int(value, 8)
  275. else:
  276. value = int(value, 0)
  277. return -value if is_neg else value
  278. def long_literal(value):
  279. if isinstance(value, basestring):
  280. value = str_to_number(value)
  281. return not -2**31 <= value < 2**31
  282. @cached_function
  283. def get_cython_cache_dir():
  284. """get the cython cache dir
  285. Priority:
  286. 1. CYTHON_CACHE_DIR
  287. 2. (OS X): ~/Library/Caches/Cython
  288. (posix not OS X): XDG_CACHE_HOME/cython if XDG_CACHE_HOME defined
  289. 3. ~/.cython
  290. """
  291. if 'CYTHON_CACHE_DIR' in os.environ:
  292. return os.environ['CYTHON_CACHE_DIR']
  293. parent = None
  294. if os.name == 'posix':
  295. if sys.platform == 'darwin':
  296. parent = os.path.expanduser('~/Library/Caches')
  297. else:
  298. # this could fallback on ~/.cache
  299. parent = os.environ.get('XDG_CACHE_HOME')
  300. if parent and os.path.isdir(parent):
  301. return os.path.join(parent, 'cython')
  302. # last fallback: ~/.cython
  303. return os.path.expanduser(os.path.join('~', '.cython'))
  304. @contextmanager
  305. def captured_fd(stream=2, encoding=None):
  306. pipe_in = t = None
  307. orig_stream = os.dup(stream) # keep copy of original stream
  308. try:
  309. pipe_in, pipe_out = os.pipe()
  310. os.dup2(pipe_out, stream) # replace stream by copy of pipe
  311. try:
  312. os.close(pipe_out) # close original pipe-out stream
  313. data = []
  314. def copy():
  315. try:
  316. while True:
  317. d = os.read(pipe_in, 1000)
  318. if d:
  319. data.append(d)
  320. else:
  321. break
  322. finally:
  323. os.close(pipe_in)
  324. def get_output():
  325. output = b''.join(data)
  326. if encoding:
  327. output = output.decode(encoding)
  328. return output
  329. from threading import Thread
  330. t = Thread(target=copy)
  331. t.daemon = True # just in case
  332. t.start()
  333. yield get_output
  334. finally:
  335. os.dup2(orig_stream, stream) # restore original stream
  336. if t is not None:
  337. t.join()
  338. finally:
  339. os.close(orig_stream)
  340. def print_bytes(s, end=b'\n', file=sys.stdout, flush=True):
  341. file.flush()
  342. try:
  343. out = file.buffer # Py3
  344. except AttributeError:
  345. out = file # Py2
  346. out.write(s)
  347. if end:
  348. out.write(end)
  349. if flush:
  350. out.flush()
  351. class LazyStr:
  352. def __init__(self, callback):
  353. self.callback = callback
  354. def __str__(self):
  355. return self.callback()
  356. def __repr__(self):
  357. return self.callback()
  358. def __add__(self, right):
  359. return self.callback() + right
  360. def __radd__(self, left):
  361. return left + self.callback()
  362. # Class decorator that adds a metaclass and recreates the class with it.
  363. # Copied from 'six'.
  364. def add_metaclass(metaclass):
  365. """Class decorator for creating a class with a metaclass."""
  366. def wrapper(cls):
  367. orig_vars = cls.__dict__.copy()
  368. slots = orig_vars.get('__slots__')
  369. if slots is not None:
  370. if isinstance(slots, str):
  371. slots = [slots]
  372. for slots_var in slots:
  373. orig_vars.pop(slots_var)
  374. orig_vars.pop('__dict__', None)
  375. orig_vars.pop('__weakref__', None)
  376. return metaclass(cls.__name__, cls.__bases__, orig_vars)
  377. return wrapper