annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/lib/python3.8/site-packages/setuptools/glob.py @ 68:5028fdace37b

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 16:23:26 -0400
parents
children
rev   line source
jpayne@68 1 """
jpayne@68 2 Filename globbing utility. Mostly a copy of `glob` from Python 3.5.
jpayne@68 3
jpayne@68 4 Changes include:
jpayne@68 5 * `yield from` and PEP3102 `*` removed.
jpayne@68 6 * Hidden files are not ignored.
jpayne@68 7 """
jpayne@68 8
jpayne@68 9 import fnmatch
jpayne@68 10 import os
jpayne@68 11 import re
jpayne@68 12
jpayne@68 13 __all__ = ["glob", "iglob", "escape"]
jpayne@68 14
jpayne@68 15
jpayne@68 16 def glob(pathname, recursive: bool = False):
jpayne@68 17 """Return a list of paths matching a pathname pattern.
jpayne@68 18
jpayne@68 19 The pattern may contain simple shell-style wildcards a la
jpayne@68 20 fnmatch. However, unlike fnmatch, filenames starting with a
jpayne@68 21 dot are special cases that are not matched by '*' and '?'
jpayne@68 22 patterns.
jpayne@68 23
jpayne@68 24 If recursive is true, the pattern '**' will match any files and
jpayne@68 25 zero or more directories and subdirectories.
jpayne@68 26 """
jpayne@68 27 return list(iglob(pathname, recursive=recursive))
jpayne@68 28
jpayne@68 29
jpayne@68 30 def iglob(pathname, recursive: bool = False):
jpayne@68 31 """Return an iterator which yields the paths matching a pathname pattern.
jpayne@68 32
jpayne@68 33 The pattern may contain simple shell-style wildcards a la
jpayne@68 34 fnmatch. However, unlike fnmatch, filenames starting with a
jpayne@68 35 dot are special cases that are not matched by '*' and '?'
jpayne@68 36 patterns.
jpayne@68 37
jpayne@68 38 If recursive is true, the pattern '**' will match any files and
jpayne@68 39 zero or more directories and subdirectories.
jpayne@68 40 """
jpayne@68 41 it = _iglob(pathname, recursive)
jpayne@68 42 if recursive and _isrecursive(pathname):
jpayne@68 43 s = next(it) # skip empty string
jpayne@68 44 assert not s
jpayne@68 45 return it
jpayne@68 46
jpayne@68 47
jpayne@68 48 def _iglob(pathname, recursive):
jpayne@68 49 dirname, basename = os.path.split(pathname)
jpayne@68 50 glob_in_dir = glob2 if recursive and _isrecursive(basename) else glob1
jpayne@68 51
jpayne@68 52 if not has_magic(pathname):
jpayne@68 53 if basename:
jpayne@68 54 if os.path.lexists(pathname):
jpayne@68 55 yield pathname
jpayne@68 56 else:
jpayne@68 57 # Patterns ending with a slash should match only directories
jpayne@68 58 if os.path.isdir(dirname):
jpayne@68 59 yield pathname
jpayne@68 60 return
jpayne@68 61
jpayne@68 62 if not dirname:
jpayne@68 63 yield from glob_in_dir(dirname, basename)
jpayne@68 64 return
jpayne@68 65 # `os.path.split()` returns the argument itself as a dirname if it is a
jpayne@68 66 # drive or UNC path. Prevent an infinite recursion if a drive or UNC path
jpayne@68 67 # contains magic characters (i.e. r'\\?\C:').
jpayne@68 68 if dirname != pathname and has_magic(dirname):
jpayne@68 69 dirs = _iglob(dirname, recursive)
jpayne@68 70 else:
jpayne@68 71 dirs = [dirname]
jpayne@68 72 if not has_magic(basename):
jpayne@68 73 glob_in_dir = glob0
jpayne@68 74 for dirname in dirs:
jpayne@68 75 for name in glob_in_dir(dirname, basename):
jpayne@68 76 yield os.path.join(dirname, name)
jpayne@68 77
jpayne@68 78
jpayne@68 79 # These 2 helper functions non-recursively glob inside a literal directory.
jpayne@68 80 # They return a list of basenames. `glob1` accepts a pattern while `glob0`
jpayne@68 81 # takes a literal basename (so it only has to check for its existence).
jpayne@68 82
jpayne@68 83
jpayne@68 84 def glob1(dirname, pattern):
jpayne@68 85 if not dirname:
jpayne@68 86 if isinstance(pattern, bytes):
jpayne@68 87 dirname = os.curdir.encode('ASCII')
jpayne@68 88 else:
jpayne@68 89 dirname = os.curdir
jpayne@68 90 try:
jpayne@68 91 names = os.listdir(dirname)
jpayne@68 92 except OSError:
jpayne@68 93 return []
jpayne@68 94 return fnmatch.filter(names, pattern)
jpayne@68 95
jpayne@68 96
jpayne@68 97 def glob0(dirname, basename):
jpayne@68 98 if not basename:
jpayne@68 99 # `os.path.split()` returns an empty basename for paths ending with a
jpayne@68 100 # directory separator. 'q*x/' should match only directories.
jpayne@68 101 if os.path.isdir(dirname):
jpayne@68 102 return [basename]
jpayne@68 103 else:
jpayne@68 104 if os.path.lexists(os.path.join(dirname, basename)):
jpayne@68 105 return [basename]
jpayne@68 106 return []
jpayne@68 107
jpayne@68 108
jpayne@68 109 # This helper function recursively yields relative pathnames inside a literal
jpayne@68 110 # directory.
jpayne@68 111
jpayne@68 112
jpayne@68 113 def glob2(dirname, pattern):
jpayne@68 114 assert _isrecursive(pattern)
jpayne@68 115 yield pattern[:0]
jpayne@68 116 yield from _rlistdir(dirname)
jpayne@68 117
jpayne@68 118
jpayne@68 119 # Recursively yields relative pathnames inside a literal directory.
jpayne@68 120 def _rlistdir(dirname):
jpayne@68 121 if not dirname:
jpayne@68 122 if isinstance(dirname, bytes):
jpayne@68 123 dirname = os.curdir.encode('ASCII')
jpayne@68 124 else:
jpayne@68 125 dirname = os.curdir
jpayne@68 126 try:
jpayne@68 127 names = os.listdir(dirname)
jpayne@68 128 except OSError:
jpayne@68 129 return
jpayne@68 130 for x in names:
jpayne@68 131 yield x
jpayne@68 132 path = os.path.join(dirname, x) if dirname else x
jpayne@68 133 for y in _rlistdir(path):
jpayne@68 134 yield os.path.join(x, y)
jpayne@68 135
jpayne@68 136
jpayne@68 137 magic_check = re.compile('([*?[])')
jpayne@68 138 magic_check_bytes = re.compile(b'([*?[])')
jpayne@68 139
jpayne@68 140
jpayne@68 141 def has_magic(s):
jpayne@68 142 if isinstance(s, bytes):
jpayne@68 143 match = magic_check_bytes.search(s)
jpayne@68 144 else:
jpayne@68 145 match = magic_check.search(s)
jpayne@68 146 return match is not None
jpayne@68 147
jpayne@68 148
jpayne@68 149 def _isrecursive(pattern):
jpayne@68 150 if isinstance(pattern, bytes):
jpayne@68 151 return pattern == b'**'
jpayne@68 152 else:
jpayne@68 153 return pattern == '**'
jpayne@68 154
jpayne@68 155
jpayne@68 156 def escape(pathname):
jpayne@68 157 """Escape all special characters."""
jpayne@68 158 # Escaping is done by wrapping any of "*?[" between square brackets.
jpayne@68 159 # Metacharacters do not work in the drive part and shouldn't be escaped.
jpayne@68 160 drive, pathname = os.path.splitdrive(pathname)
jpayne@68 161 if isinstance(pathname, bytes):
jpayne@68 162 pathname = magic_check_bytes.sub(rb'[\1]', pathname)
jpayne@68 163 else:
jpayne@68 164 pathname = magic_check.sub(r'[\1]', pathname)
jpayne@68 165 return drive + pathname