DebugClients/Python/coverage/files.py

changeset 5141
bc64243b7672
parent 5126
d28b92dabc2b
parent 5140
01484c0afbc6
child 5144
1ab536d25072
--- a/DebugClients/Python/coverage/files.py	Fri Sep 02 19:08:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,381 +0,0 @@
-# Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
-# For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
-
-"""File wrangling."""
-
-import fnmatch
-import ntpath
-import os
-import os.path
-import posixpath
-import re
-import sys
-
-from coverage import env
-from coverage.backward import unicode_class
-from coverage.misc import contract, CoverageException, join_regex, isolate_module
-
-
-os = isolate_module(os)
-
-
-def set_relative_directory():
-    """Set the directory that `relative_filename` will be relative to."""
-    global RELATIVE_DIR, CANONICAL_FILENAME_CACHE
-
-    # The absolute path to our current directory.
-    RELATIVE_DIR = os.path.normcase(abs_file(os.curdir) + os.sep)
-
-    # Cache of results of calling the canonical_filename() method, to
-    # avoid duplicating work.
-    CANONICAL_FILENAME_CACHE = {}
-
-
-def relative_directory():
-    """Return the directory that `relative_filename` is relative to."""
-    return RELATIVE_DIR
-
-
-@contract(returns='unicode')
-def relative_filename(filename):
-    """Return the relative form of `filename`.
-
-    The file name will be relative to the current directory when the
-    `set_relative_directory` was called.
-
-    """
-    fnorm = os.path.normcase(filename)
-    if fnorm.startswith(RELATIVE_DIR):
-        filename = filename[len(RELATIVE_DIR):]
-    return unicode_filename(filename)
-
-
-@contract(returns='unicode')
-def canonical_filename(filename):
-    """Return a canonical file name for `filename`.
-
-    An absolute path with no redundant components and normalized case.
-
-    """
-    if filename not in CANONICAL_FILENAME_CACHE:
-        if not os.path.isabs(filename):
-            for path in [os.curdir] + sys.path:
-                if path is None:
-                    continue
-                f = os.path.join(path, filename)
-                if os.path.exists(f):
-                    filename = f
-                    break
-        cf = abs_file(filename)
-        CANONICAL_FILENAME_CACHE[filename] = cf
-    return CANONICAL_FILENAME_CACHE[filename]
-
-
-def flat_rootname(filename):
-    """A base for a flat file name to correspond to this file.
-
-    Useful for writing files about the code where you want all the files in
-    the same directory, but need to differentiate same-named files from
-    different directories.
-
-    For example, the file a/b/c.py will return 'a_b_c_py'
-
-    """
-    name = ntpath.splitdrive(filename)[1]
-    return re.sub(r"[\\/.:]", "_", name)
-
-
-if env.WINDOWS:
-
-    _ACTUAL_PATH_CACHE = {}
-    _ACTUAL_PATH_LIST_CACHE = {}
-
-    def actual_path(path):
-        """Get the actual path of `path`, including the correct case."""
-        if env.PY2 and isinstance(path, unicode_class):
-            path = path.encode(sys.getfilesystemencoding())
-        if path in _ACTUAL_PATH_CACHE:
-            return _ACTUAL_PATH_CACHE[path]
-
-        head, tail = os.path.split(path)
-        if not tail:
-            # This means head is the drive spec: normalize it.
-            actpath = head.upper()
-        elif not head:
-            actpath = tail
-        else:
-            head = actual_path(head)
-            if head in _ACTUAL_PATH_LIST_CACHE:
-                files = _ACTUAL_PATH_LIST_CACHE[head]
-            else:
-                try:
-                    files = os.listdir(head)
-                except OSError:
-                    files = []
-                _ACTUAL_PATH_LIST_CACHE[head] = files
-            normtail = os.path.normcase(tail)
-            for f in files:
-                if os.path.normcase(f) == normtail:
-                    tail = f
-                    break
-            actpath = os.path.join(head, tail)
-        _ACTUAL_PATH_CACHE[path] = actpath
-        return actpath
-
-else:
-    def actual_path(filename):
-        """The actual path for non-Windows platforms."""
-        return filename
-
-
-if env.PY2:
-    @contract(returns='unicode')
-    def unicode_filename(filename):
-        """Return a Unicode version of `filename`."""
-        if isinstance(filename, str):
-            encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
-            filename = filename.decode(encoding, "replace")
-        return filename
-else:
-    @contract(filename='unicode', returns='unicode')
-    def unicode_filename(filename):
-        """Return a Unicode version of `filename`."""
-        return filename
-
-
-@contract(returns='unicode')
-def abs_file(filename):
-    """Return the absolute normalized form of `filename`."""
-    path = os.path.expandvars(os.path.expanduser(filename))
-    path = os.path.abspath(os.path.realpath(path))
-    path = actual_path(path)
-    path = unicode_filename(path)
-    return path
-
-
-RELATIVE_DIR = None
-CANONICAL_FILENAME_CACHE = None
-set_relative_directory()
-
-
-def isabs_anywhere(filename):
-    """Is `filename` an absolute path on any OS?"""
-    return ntpath.isabs(filename) or posixpath.isabs(filename)
-
-
-def prep_patterns(patterns):
-    """Prepare the file patterns for use in a `FnmatchMatcher`.
-
-    If a pattern starts with a wildcard, it is used as a pattern
-    as-is.  If it does not start with a wildcard, then it is made
-    absolute with the current directory.
-
-    If `patterns` is None, an empty list is returned.
-
-    """
-    prepped = []
-    for p in patterns or []:
-        if p.startswith(("*", "?")):
-            prepped.append(p)
-        else:
-            prepped.append(abs_file(p))
-    return prepped
-
-
-class TreeMatcher(object):
-    """A matcher for files in a tree."""
-    def __init__(self, directories):
-        self.dirs = list(directories)
-
-    def __repr__(self):
-        return "<TreeMatcher %r>" % self.dirs
-
-    def info(self):
-        """A list of strings for displaying when dumping state."""
-        return self.dirs
-
-    def match(self, fpath):
-        """Does `fpath` indicate a file in one of our trees?"""
-        for d in self.dirs:
-            if fpath.startswith(d):
-                if fpath == d:
-                    # This is the same file!
-                    return True
-                if fpath[len(d)] == os.sep:
-                    # This is a file in the directory
-                    return True
-        return False
-
-
-class ModuleMatcher(object):
-    """A matcher for modules in a tree."""
-    def __init__(self, module_names):
-        self.modules = list(module_names)
-
-    def __repr__(self):
-        return "<ModuleMatcher %r>" % (self.modules)
-
-    def info(self):
-        """A list of strings for displaying when dumping state."""
-        return self.modules
-
-    def match(self, module_name):
-        """Does `module_name` indicate a module in one of our packages?"""
-        if not module_name:
-            return False
-
-        for m in self.modules:
-            if module_name.startswith(m):
-                if module_name == m:
-                    return True
-                if module_name[len(m)] == '.':
-                    # This is a module in the package
-                    return True
-
-        return False
-
-
-class FnmatchMatcher(object):
-    """A matcher for files by file name pattern."""
-    def __init__(self, pats):
-        self.pats = pats[:]
-        # fnmatch is platform-specific. On Windows, it does the Windows thing
-        # of treating / and \ as equivalent. But on other platforms, we need to
-        # take care of that ourselves.
-        fnpats = (fnmatch.translate(p) for p in pats)
-        fnpats = (p.replace(r"\/", r"[\\/]") for p in fnpats)
-        if env.WINDOWS:
-            # Windows is also case-insensitive.  BTW: the regex docs say that
-            # flags like (?i) have to be at the beginning, but fnmatch puts
-            # them at the end, and having two there seems to work fine.
-            fnpats = (p + "(?i)" for p in fnpats)
-        self.re = re.compile(join_regex(fnpats))
-
-    def __repr__(self):
-        return "<FnmatchMatcher %r>" % self.pats
-
-    def info(self):
-        """A list of strings for displaying when dumping state."""
-        return self.pats
-
-    def match(self, fpath):
-        """Does `fpath` match one of our file name patterns?"""
-        return self.re.match(fpath) is not None
-
-
-def sep(s):
-    """Find the path separator used in this string, or os.sep if none."""
-    sep_match = re.search(r"[\\/]", s)
-    if sep_match:
-        the_sep = sep_match.group(0)
-    else:
-        the_sep = os.sep
-    return the_sep
-
-
-class PathAliases(object):
-    """A collection of aliases for paths.
-
-    When combining data files from remote machines, often the paths to source
-    code are different, for example, due to OS differences, or because of
-    serialized checkouts on continuous integration machines.
-
-    A `PathAliases` object tracks a list of pattern/result pairs, and can
-    map a path through those aliases to produce a unified path.
-
-    """
-    def __init__(self):
-        self.aliases = []
-
-    def add(self, pattern, result):
-        """Add the `pattern`/`result` pair to the list of aliases.
-
-        `pattern` is an `fnmatch`-style pattern.  `result` is a simple
-        string.  When mapping paths, if a path starts with a match against
-        `pattern`, then that match is replaced with `result`.  This models
-        isomorphic source trees being rooted at different places on two
-        different machines.
-
-        `pattern` can't end with a wildcard component, since that would
-        match an entire tree, and not just its root.
-
-        """
-        # The pattern can't end with a wildcard component.
-        pattern = pattern.rstrip(r"\/")
-        if pattern.endswith("*"):
-            raise CoverageException("Pattern must not end with wildcards.")
-        pattern_sep = sep(pattern)
-
-        # The pattern is meant to match a filepath.  Let's make it absolute
-        # unless it already is, or is meant to match any prefix.
-        if not pattern.startswith('*') and not isabs_anywhere(pattern):
-            pattern = abs_file(pattern)
-        pattern += pattern_sep
-
-        # Make a regex from the pattern.  fnmatch always adds a \Z to
-        # match the whole string, which we don't want.
-        regex_pat = fnmatch.translate(pattern).replace(r'\Z(', '(')
-
-        # We want */a/b.py to match on Windows too, so change slash to match
-        # either separator.
-        regex_pat = regex_pat.replace(r"\/", r"[\\/]")
-        # We want case-insensitive matching, so add that flag.
-        regex = re.compile(r"(?i)" + regex_pat)
-
-        # Normalize the result: it must end with a path separator.
-        result_sep = sep(result)
-        result = result.rstrip(r"\/") + result_sep
-        self.aliases.append((regex, result, pattern_sep, result_sep))
-
-    def map(self, path):
-        """Map `path` through the aliases.
-
-        `path` is checked against all of the patterns.  The first pattern to
-        match is used to replace the root of the path with the result root.
-        Only one pattern is ever used.  If no patterns match, `path` is
-        returned unchanged.
-
-        The separator style in the result is made to match that of the result
-        in the alias.
-
-        Returns the mapped path.  If a mapping has happened, this is a
-        canonical path.  If no mapping has happened, it is the original value
-        of `path` unchanged.
-
-        """
-        for regex, result, pattern_sep, result_sep in self.aliases:
-            m = regex.match(path)
-            if m:
-                new = path.replace(m.group(0), result)
-                if pattern_sep != result_sep:
-                    new = new.replace(pattern_sep, result_sep)
-                new = canonical_filename(new)
-                return new
-        return path
-
-
-def find_python_files(dirname):
-    """Yield all of the importable Python files in `dirname`, recursively.
-
-    To be importable, the files have to be in a directory with a __init__.py,
-    except for `dirname` itself, which isn't required to have one.  The
-    assumption is that `dirname` was specified directly, so the user knows
-    best, but sub-directories are checked for a __init__.py to be sure we only
-    find the importable files.
-
-    """
-    for i, (dirpath, dirnames, filenames) in enumerate(os.walk(dirname)):
-        if i > 0 and '__init__.py' not in filenames:
-            # If a directory doesn't have __init__.py, then it isn't
-            # importable and neither are its files
-            del dirnames[:]
-            continue
-        for filename in filenames:
-            # We're only interested in files that look like reasonable Python
-            # files: Must end with .py or .pyw, and must not have certain funny
-            # characters that probably mean they are editor junk.
-            if re.match(r"^[^.#~!$@%^&*()+=,]+\.pyw?$", filename):
-                yield os.path.join(dirpath, filename)
-
-#
-# eflag: FileType = Python2

eric ide

mercurial