Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Unified Diff: third_party/cython/src/Cython/Utils.py

Issue 385073004: Adding cython v0.20.2 in third-party. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Reference cython dev list thread. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/cython/src/Cython/Utility/arrayarray.h ('k') | third_party/cython/src/Cython/__init__.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/cython/src/Cython/Utils.py
diff --git a/third_party/cython/src/Cython/Utils.py b/third_party/cython/src/Cython/Utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..8594118f3294c309f47f4355ea3d9b76f594eda9
--- /dev/null
+++ b/third_party/cython/src/Cython/Utils.py
@@ -0,0 +1,415 @@
+#
+# Cython -- Things that don't belong
+# anywhere else in particular
+#
+
+import os, sys, re, codecs
+
+modification_time = os.path.getmtime
+
+def cached_function(f):
+ cache = {}
+ uncomputed = object()
+ def wrapper(*args):
+ res = cache.get(args, uncomputed)
+ if res is uncomputed:
+ res = cache[args] = f(*args)
+ return res
+ return wrapper
+
+def cached_method(f):
+ cache_name = '__%s_cache' % f.__name__
+ def wrapper(self, *args):
+ cache = getattr(self, cache_name, None)
+ if cache is None:
+ cache = {}
+ setattr(self, cache_name, cache)
+ if args in cache:
+ return cache[args]
+ res = cache[args] = f(self, *args)
+ return res
+ return wrapper
+
+def replace_suffix(path, newsuf):
+ base, _ = os.path.splitext(path)
+ return base + newsuf
+
+def open_new_file(path):
+ if os.path.exists(path):
+ # Make sure to create a new file here so we can
+ # safely hard link the output files.
+ os.unlink(path)
+
+ # we use the ISO-8859-1 encoding here because we only write pure
+ # ASCII strings or (e.g. for file names) byte encoded strings as
+ # Unicode, so we need a direct mapping from the first 256 Unicode
+ # characters to a byte sequence, which ISO-8859-1 provides
+ return codecs.open(path, "w", encoding="ISO-8859-1")
+
+def castrate_file(path, st):
+ # Remove junk contents from an output file after a
+ # failed compilation.
+ # Also sets access and modification times back to
+ # those specified by st (a stat struct).
+ try:
+ f = open_new_file(path)
+ except EnvironmentError:
+ pass
+ else:
+ f.write(
+ "#error Do not use this file, it is the result of a failed Cython compilation.\n")
+ f.close()
+ if st:
+ os.utime(path, (st.st_atime, st.st_mtime-1))
+
+def file_newer_than(path, time):
+ ftime = modification_time(path)
+ return ftime > time
+
+@cached_function
+def search_include_directories(dirs, qualified_name, suffix, pos,
+ include=False, sys_path=False):
+ # Search the list of include directories for the given
+ # file name. If a source file position is given, first
+ # searches the directory containing that file. Returns
+ # None if not found, but does not report an error.
+ # The 'include' option will disable package dereferencing.
+ # If 'sys_path' is True, also search sys.path.
+ if sys_path:
+ dirs = dirs + tuple(sys.path)
+ if pos:
+ file_desc = pos[0]
+ from Cython.Compiler.Scanning import FileSourceDescriptor
+ if not isinstance(file_desc, FileSourceDescriptor):
+ raise RuntimeError("Only file sources for code supported")
+ if include:
+ dirs = (os.path.dirname(file_desc.filename),) + dirs
+ else:
+ dirs = (find_root_package_dir(file_desc.filename),) + dirs
+
+ dotted_filename = qualified_name
+ if suffix:
+ dotted_filename += suffix
+ if not include:
+ names = qualified_name.split('.')
+ package_names = tuple(names[:-1])
+ module_name = names[-1]
+ module_filename = module_name + suffix
+ package_filename = "__init__" + suffix
+
+ for dir in dirs:
+ path = os.path.join(dir, dotted_filename)
+ if path_exists(path):
+ return path
+ if not include:
+ package_dir = check_package_dir(dir, package_names)
+ if package_dir is not None:
+ path = os.path.join(package_dir, module_filename)
+ if path_exists(path):
+ return path
+ path = os.path.join(dir, package_dir, module_name,
+ package_filename)
+ if path_exists(path):
+ return path
+ return None
+
+
+@cached_function
+def find_root_package_dir(file_path):
+ dir = os.path.dirname(file_path)
+ if file_path == dir:
+ return dir
+ elif is_package_dir(dir):
+ return find_root_package_dir(dir)
+ else:
+ return dir
+
+@cached_function
+def check_package_dir(dir, package_names):
+ for dirname in package_names:
+ dir = os.path.join(dir, dirname)
+ if not is_package_dir(dir):
+ return None
+ return dir
+
+@cached_function
+def is_package_dir(dir_path):
+ for filename in ("__init__.py",
+ "__init__.pyx",
+ "__init__.pxd"):
+ path = os.path.join(dir_path, filename)
+ if path_exists(path):
+ return 1
+
+@cached_function
+def path_exists(path):
+ # try on the filesystem first
+ if os.path.exists(path):
+ return True
+ # figure out if a PEP 302 loader is around
+ try:
+ loader = __loader__
+ # XXX the code below assumes a 'zipimport.zipimporter' instance
+ # XXX should be easy to generalize, but too lazy right now to write it
+ archive_path = getattr(loader, 'archive', None)
+ if archive_path:
+ normpath = os.path.normpath(path)
+ if normpath.startswith(archive_path):
+ arcname = normpath[len(archive_path)+1:]
+ try:
+ loader.get_data(arcname)
+ return True
+ except IOError:
+ return False
+ except NameError:
+ pass
+ return False
+
+# file name encodings
+
+def decode_filename(filename):
+ if isinstance(filename, unicode):
+ return filename
+ try:
+ filename_encoding = sys.getfilesystemencoding()
+ if filename_encoding is None:
+ filename_encoding = sys.getdefaultencoding()
+ filename = filename.decode(filename_encoding)
+ except UnicodeDecodeError:
+ pass
+ return filename
+
+# support for source file encoding detection
+
+_match_file_encoding = re.compile(u"coding[:=]\s*([-\w.]+)").search
+
+def detect_file_encoding(source_filename):
+ f = open_source_file(source_filename, encoding="UTF-8", error_handling='ignore')
+ try:
+ return detect_opened_file_encoding(f)
+ finally:
+ f.close()
+
+def detect_opened_file_encoding(f):
+ # PEPs 263 and 3120
+ # Most of the time the first two lines fall in the first 250 chars,
+ # and this bulk read/split is much faster.
+ lines = f.read(250).split("\n")
+ if len(lines) > 2:
+ m = _match_file_encoding(lines[0]) or _match_file_encoding(lines[1])
+ if m:
+ return m.group(1)
+ else:
+ return "UTF-8"
+ else:
+ # Fallback to one-char-at-a-time detection.
+ f.seek(0)
+ chars = []
+ for i in range(2):
+ c = f.read(1)
+ while c and c != u'\n':
+ chars.append(c)
+ c = f.read(1)
+ encoding = _match_file_encoding(u''.join(chars))
+ if encoding:
+ return encoding.group(1)
+ return "UTF-8"
+
+
+def skip_bom(f):
+ """
+ Read past a BOM at the beginning of a source file.
+ This could be added to the scanner, but it's *substantially* easier
+ to keep it at this level.
+ """
+ if f.read(1) != u'\uFEFF':
+ f.seek(0)
+
+
+normalise_newlines = re.compile(u'\r\n?|\n').sub
+
+
+class NormalisedNewlineStream(object):
+ """The codecs module doesn't provide universal newline support.
+ This class is used as a stream wrapper that provides this
+ functionality. The new 'io' in Py2.6+/3.x supports this out of the
+ box.
+ """
+
+ def __init__(self, stream):
+ # let's assume .read() doesn't change
+ self.stream = stream
+ self._read = stream.read
+ self.close = stream.close
+ self.encoding = getattr(stream, 'encoding', 'UTF-8')
+
+ def read(self, count=-1):
+ data = self._read(count)
+ if u'\r' not in data:
+ return data
+ if data.endswith(u'\r'):
+ # may be missing a '\n'
+ data += self._read(1)
+ return normalise_newlines(u'\n', data)
+
+ def readlines(self):
+ content = []
+ data = self.read(0x1000)
+ while data:
+ content.append(data)
+ data = self.read(0x1000)
+
+ return u''.join(content).splitlines(True)
+
+ def seek(self, pos):
+ if pos == 0:
+ self.stream.seek(0)
+ else:
+ raise NotImplementedError
+
+
+io = None
+if sys.version_info >= (2,6):
+ try:
+ import io
+ except ImportError:
+ pass
+
+
+def open_source_file(source_filename, mode="r",
+ encoding=None, error_handling=None,
+ require_normalised_newlines=True):
+ if encoding is None:
+ # Most of the time the coding is unspecified, so be optimistic that
+ # it's UTF-8.
+ f = open_source_file(source_filename, encoding="UTF-8", mode=mode, error_handling='ignore')
+ encoding = detect_opened_file_encoding(f)
+ if (encoding == "UTF-8"
+ and error_handling == 'ignore'
+ and require_normalised_newlines):
+ f.seek(0)
+ skip_bom(f)
+ return f
+ else:
+ f.close()
+ #
+ if not os.path.exists(source_filename):
+ try:
+ loader = __loader__
+ if source_filename.startswith(loader.archive):
+ return open_source_from_loader(
+ loader, source_filename,
+ encoding, error_handling,
+ require_normalised_newlines)
+ except (NameError, AttributeError):
+ pass
+ #
+ if io is not None:
+ stream = io.open(source_filename, mode=mode,
+ encoding=encoding, errors=error_handling)
+ else:
+ # codecs module doesn't have universal newline support
+ stream = codecs.open(source_filename, mode=mode,
+ encoding=encoding, errors=error_handling)
+ if require_normalised_newlines:
+ stream = NormalisedNewlineStream(stream)
+ skip_bom(stream)
+ return stream
+
+
+def open_source_from_loader(loader,
+ source_filename,
+ encoding=None, error_handling=None,
+ require_normalised_newlines=True):
+ nrmpath = os.path.normpath(source_filename)
+ arcname = nrmpath[len(loader.archive)+1:]
+ data = loader.get_data(arcname)
+ if io is not None:
+ return io.TextIOWrapper(io.BytesIO(data),
+ encoding=encoding,
+ errors=error_handling)
+ else:
+ try:
+ import cStringIO as StringIO
+ except ImportError:
+ import StringIO
+ reader = codecs.getreader(encoding)
+ stream = reader(StringIO.StringIO(data))
+ if require_normalised_newlines:
+ stream = NormalisedNewlineStream(stream)
+ return stream
+
+def str_to_number(value):
+ # note: this expects a string as input that was accepted by the
+ # parser already
+ if len(value) < 2:
+ value = int(value, 0)
+ elif value[0] == '0':
+ if value[1] in 'xX':
+ # hex notation ('0x1AF')
+ value = int(value[2:], 16)
+ elif value[1] in 'oO':
+ # Py3 octal notation ('0o136')
+ value = int(value[2:], 8)
+ elif value[1] in 'bB':
+ # Py3 binary notation ('0b101')
+ value = int(value[2:], 2)
+ else:
+ # Py2 octal notation ('0136')
+ value = int(value, 8)
+ else:
+ value = int(value, 0)
+ return value
+
+def long_literal(value):
+ if isinstance(value, basestring):
+ value = str_to_number(value)
+ return not -2**31 <= value < 2**31
+
+# all() and any() are new in 2.5
+try:
+ # Make sure to bind them on the module, as they will be accessed as
+ # attributes
+ all = all
+ any = any
+except NameError:
+ def all(items):
+ for item in items:
+ if not item:
+ return False
+ return True
+
+ def any(items):
+ for item in items:
+ if item:
+ return True
+ return False
+
+@cached_function
+def get_cython_cache_dir():
+ """get the cython cache dir
+
+ Priority:
+
+ 1. CYTHON_CACHE_DIR
+ 2. (OS X): ~/Library/Caches/Cython
+ (posix not OS X): XDG_CACHE_HOME/cython if XDG_CACHE_HOME defined
+ 3. ~/.cython
+
+ """
+ if 'CYTHON_CACHE_DIR' in os.environ:
+ return os.environ['CYTHON_CACHE_DIR']
+
+ parent = None
+ if os.name == 'posix':
+ if sys.platform == 'darwin':
+ parent = os.path.expanduser('~/Library/Caches')
+ else:
+ # this could fallback on ~/.cache
+ parent = os.environ.get('XDG_CACHE_HOME')
+
+ if parent and os.path.isdir(parent):
+ return os.path.join(parent, 'cython')
+
+ # last fallback: ~/.cython
+ return os.path.expanduser(os.path.join('~', '.cython'))
« no previous file with comments | « third_party/cython/src/Cython/Utility/arrayarray.h ('k') | third_party/cython/src/Cython/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698