Mercurial > repos > shellac > guppy_basecaller
diff env/lib/python3.7/site-packages/glob2/impl.py @ 0:26e78fe6e8c4 draft
"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author | shellac |
---|---|
date | Sat, 02 May 2020 07:14:21 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/env/lib/python3.7/site-packages/glob2/impl.py Sat May 02 07:14:21 2020 -0400 @@ -0,0 +1,216 @@ +"""Filename globbing utility.""" + +from __future__ import absolute_import + +import sys +import os +import re +from os.path import join +from . import fnmatch + +try: + from itertools import imap +except ImportError: + imap = map + + +class Globber(object): + + listdir = staticmethod(os.listdir) + isdir = staticmethod(os.path.isdir) + islink = staticmethod(os.path.islink) + exists = staticmethod(os.path.lexists) + + def walk(self, top, followlinks=False, sep=None): + """A simplified version of os.walk (code copied) that uses + ``self.listdir``, and the other local filesystem methods. + + Because we don't care about file/directory distinctions, only + a single list is returned. + """ + try: + names = self.listdir(top) + except os.error as err: + return + + items = [] + for name in names: + items.append(name) + + yield top, items + + for name in items: + new_path = _join_paths([top, name], sep=sep) + if followlinks or not self.islink(new_path): + for x in self.walk(new_path, followlinks): + yield x + + def glob(self, pathname, with_matches=False, include_hidden=False, recursive=True, + norm_paths=True, case_sensitive=True, sep=None): + """Return a list of paths matching a pathname pattern. + + The pattern may contain simple shell-style wildcards a la + fnmatch. However, unlike fnmatch, filenames starting with a + dot are special cases that are not matched by '*' and '?' + patterns. + + If ``include_hidden`` is True, then files and folders starting with + a dot are also returned. + """ + return list(self.iglob(pathname, with_matches, include_hidden, + norm_paths, case_sensitive, sep)) + + def iglob(self, pathname, with_matches=False, include_hidden=False, recursive=True, + norm_paths=True, case_sensitive=True, sep=None): + """Return an iterator which yields the paths matching a pathname + pattern. + + The pattern may contain simple shell-style wildcards a la + fnmatch. However, unlike fnmatch, filenames starting with a + dot are special cases that are not matched by '*' and '?' + patterns. + + If ``with_matches`` is True, then for each matching path + a 2-tuple will be returned; the second element if the tuple + will be a list of the parts of the path that matched the individual + wildcards. + + If ``include_hidden`` is True, then files and folders starting with + a dot are also returned. + """ + result = self._iglob(pathname, True, include_hidden, + norm_paths, case_sensitive, sep) + if with_matches: + return result + return imap(lambda s: s[0], result) + + def _iglob(self, pathname, rootcall, include_hidden, + norm_paths, case_sensitive, sep): + """Internal implementation that backs :meth:`iglob`. + + ``rootcall`` is required to differentiate between the user's call to + iglob(), and subsequent recursive calls, for the purposes of resolving + certain special cases of ** wildcards. Specifically, "**" is supposed + to include the current directory for purposes of globbing, but the + directory itself should never be returned. So if ** is the lastmost + part of the ``pathname`` given the user to the root call, we want to + ignore the current directory. For this, we need to know which the root + call is. + """ + + # Short-circuit if no glob magic + if not has_magic(pathname): + if self.exists(pathname): + yield pathname, () + return + + # If no directory part is left, assume the working directory + dirname, basename = os.path.split(pathname) + + # If the directory is globbed, recurse to resolve. + # If at this point there is no directory part left, we simply + # continue with dirname="", which will search the current dir. + # `os.path.split()` returns the argument itself as a dirname if it is a + # drive or UNC path. Prevent an infinite recursion if a drive or UNC path + # contains magic characters (i.e. r'\\?\C:'). + if dirname != pathname and has_magic(dirname): + # Note that this may return files, which will be ignored + # later when we try to use them as directories. + # Prefiltering them here would only require more IO ops. + dirs = self._iglob(dirname, False, include_hidden, + norm_paths, case_sensitive, sep) + else: + dirs = [(dirname, ())] + + # Resolve ``basename`` expr for every directory found + for dirname, dir_groups in dirs: + for name, groups in self.resolve_pattern(dirname, basename, + not rootcall, include_hidden, + norm_paths, case_sensitive, sep): + yield _join_paths([dirname, name], sep=sep), dir_groups + groups + + def resolve_pattern(self, dirname, pattern, globstar_with_root, include_hidden, + norm_paths, case_sensitive, sep): + """Apply ``pattern`` (contains no path elements) to the + literal directory in ``dirname``. + + If pattern=='', this will filter for directories. This is + a special case that happens when the user's glob expression ends + with a slash (in which case we only want directories). It simpler + and faster to filter here than in :meth:`_iglob`. + """ + + if sys.version_info[0] == 3: + if isinstance(pattern, bytes): + dirname = bytes(os.curdir, 'ASCII') + else: + if isinstance(pattern, unicode) and not isinstance(dirname, unicode): + dirname = unicode(dirname, sys.getfilesystemencoding() or + sys.getdefaultencoding()) + + # If no magic, short-circuit, only check for existence + if not has_magic(pattern): + if pattern == '': + if self.isdir(dirname): + return [(pattern, ())] + else: + if self.exists(_join_paths([dirname, pattern], sep=sep)): + return [(pattern, ())] + return [] + + if not dirname: + dirname = os.curdir + + try: + if pattern == '**': + # Include the current directory in **, if asked; by adding + # an empty string as opposed to '.', we spare ourselves + # having to deal with os.path.normpath() later. + names = [''] if globstar_with_root else [] + for top, entries in self.walk(dirname, sep=sep): + _mkabs = lambda s: _join_paths([top[len(dirname) + 1:], s], sep=sep) + names.extend(map(_mkabs, entries)) + # Reset pattern so that fnmatch(), which does not understand + # ** specifically, will only return a single group match. + pattern = '*' + else: + names = self.listdir(dirname) + except os.error: + return [] + + if not include_hidden and not _ishidden(pattern): + # Remove hidden files, but take care to ensure + # that the empty string we may have added earlier remains. + # Do not filter out the '' that we might have added earlier + names = filter(lambda x: not x or not _ishidden(x), names) + return fnmatch.filter(names, pattern, norm_paths, case_sensitive, sep) + + +default_globber = Globber() +glob = default_globber.glob +iglob = default_globber.iglob +del default_globber + + +magic_check = re.compile('[*?[]') +magic_check_bytes = re.compile(b'[*?[]') + + +def has_magic(s): + if isinstance(s, bytes): + match = magic_check_bytes.search(s) + else: + match = magic_check.search(s) + return match is not None + + +def _ishidden(path): + return path[0] in ('.', b'.'[0]) + + +def _join_paths(paths, sep=None): + path = join(*paths) + if sep: + path = re.sub(r'\/', sep, path) # cached internally + return path +