ยปCore Development>Code coverage>Lib/glob.py

Python code coverage for Lib/glob.py

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