# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""
Like :py:mod:`os.path`, with a reduced set of functions, andwith normalized path
separators (always use forward slashes).
Also contains a few additional utilities not found in :py:mod:`os.path`. """
import ctypes import os import posixpath import re import sys
def normsep(path): """
Normalize path separators, by using forward slashes instead of whatever
:py:const:`os.sep` is. """ if os.sep != "/": # Python 2 is happy to do things like byte_string.replace(u'foo', # u'bar'), but not Python 3. if isinstance(path, bytes):
path = path.replace(os.sep.encode("ascii"), b"/") else:
path = path.replace(os.sep, "/") if os.altsep and os.altsep != "/": if isinstance(path, bytes):
path = path.replace(os.altsep.encode("ascii"), b"/") else:
path = path.replace(os.altsep, "/") return path
def relpath(path, start):
path = normsep(path)
start = normsep(start) if sys.platform == "win32": # os.path.relpath can't handle relative paths between UNC and non-UNC # paths, so strip a //?/ prefix if present (bug 1581248)
path = cargo_workaround(path)
start = cargo_workaround(start) try:
rel = os.path.relpath(path, start) except ValueError: # On Windows this can throw a ValueError if the two paths are on # different drives. In that case, just return the path. return abspath(path)
rel = normsep(rel) return""if rel == "."else rel
def basedir(path, bases): """
Given a list of directories (`bases`), return which one contains the given
path. If several matches are found, the deepest base directory is returned.
``basedir('foo/bar/baz', ['foo', 'baz', 'foo/bar'])`` returns ``'foo/bar'``
(`'foo'` and `'foo/bar'` both match, but `'foo/bar'` is the deepest match) """
path = normsep(path)
bases = [normsep(b) for b in bases] if path in bases: return path for b in sorted(bases, reverse=True): if b == ""or path.startswith(b + "/"): return b
def match(path, pattern): """ Return whether the given path matches the given pattern.
An asterisk can be used to match any string, including the null string, in
one part of the path:
``foo`` matches ``*``, ``f*`` or ``fo*o``
However, an asterisk matching a subdirectory may not match the null string:
``foo/bar`` does *not* match ``foo/*/bar``
If the pattern matches one of the ancestor directories of the path, the
patch is considered matching:
``foo/bar`` matches ``foo``
Two adjacent asterisks can be used to match files and zero or more
directories and subdirectories.
``foo/bar`` matches ``foo/**/bar``, or ``**/bar`` """ ifnot pattern: returnTrue if pattern notin re_cache:
p = re.escape(pattern)
p = MATCH_STAR_STAR_RE.sub(r"\1(?:.+/)?", p)
p = MATCH_STAR_STAR_END_RE.sub(r"(?:\1.+)?", p)
p = p.replace(r"\*", "[^/]*") + "(?:/.*)?$"
re_cache[pattern] = re.compile(p) return re_cache[pattern].match(path) isnotNone
def rebase(oldbase, base, relativepath): """ Return `relativepath` relative to `base` instead of `oldbase`. """ if base == oldbase: return relativepath if len(base) < len(oldbase): assert basedir(oldbase, [base]) == base
relbase = relpath(oldbase, base)
result = join(relbase, relativepath) else: assert basedir(base, [oldbase]) == oldbase
relbase = relpath(base, oldbase)
result = relpath(relativepath, relbase)
result = normpath(result) if relativepath.endswith("/") andnot result.endswith("/"):
result += "/" return result
def readlink(path): if hasattr(os, "readlink"): return normsep(os.readlink(path))
# Unfortunately os.path.realpath doesn't support symlinks on Windows, and os.readlink # is only available on Windows with Python 3.2+. We have to resort to ctypes...
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.