Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_special_escapes(self, mock__iscase_sensitive):
"""Test wildcard character notations."""
flags = self.flags | fnmatch.U
_wcparse._compile.cache_clear()
p1, p2 = fnmatch.translate(
r'test\x70\u0070\U00000070\160\N{LATIN SMALL LETTER P}', flags=flags | fnmatch.R
)
if util.PY36:
self.assertEqual(p1, [r'^(?s:testppppp)$'])
self.assertEqual(p2, [])
else:
self.assertEqual(p1, [r'(?s)^(?:testppppp)$'])
self.assertEqual(p2, [])
p1, p2 = fnmatch.translate(
r'test[\x70][\u0070][\U00000070][\160][\N{LATIN SMALL LETTER P}]', flags=flags | fnmatch.R
)
if util.PY36:
self.assertEqual(p1, [r'^(?s:test[p][p][p][p][p])$'])
def norm_files(files, flags):
"""Normalize files."""
flags = glob._flag_transform(flags)
unix = _wcparse.is_unix_style(flags)
return [(_wcparse.norm_slash(x, flags) if not unix else x) for x in files]
# Treat the inverse pattern as a normal pattern if it matches, we will exclude.
# This is faster as compiled patterns usually compare the include patterns first,
# and then the exclude, but glob will already know it wants to include the file.
self.npatterns.append(_wcparse._compile(p, self.negate_flags))
else:
self.pattern.append(_wcparse.WcPathSplit(p, self.flags).split())
if not self.pattern and self.npatterns:
if self.negateall:
default = '**'
if self.is_bytes:
default = os.fsencode(default)
self.pattern.append(_wcparse.WcPathSplit(default, self.flags | GLOBSTAR).split())
if self.nodir:
ptype = _wcparse.BYTES if self.is_bytes else _wcparse.UNICODE
nodir = _wcparse.RE_WIN_NO_DIR[ptype] if self.flags & FORCEWIN else _wcparse.RE_NO_DIR[ptype]
self.npatterns.append(nodir)
# A single positive pattern will not find multiples of the same file
# disable unique mode so that we won't waste time or memory computing unique returns.
if (
len(self.pattern) <= 1 and
not self.flags & NODOTDIR and
not self.nounique and
not (self.pathlib and self.scandotdir)
):
self.nounique = True
def glob(self, patterns, *, flags=0, limit=_wcparse.PATTERN_LIMIT):
"""
Search the file system.
`GLOBSTAR` is enabled by default in order match the default behavior of `pathlib`.
"""
if self.is_dir():
scandotdir = flags & SCANDOTDIR
flags = self._translate_flags(flags | _NOABSOLUTE) | ((_PATHLIB | SCANDOTDIR) if scandotdir else _PATHLIB)
for filename in glob.iglob(patterns, flags=flags, root_dir=str(self), limit=limit):
yield self.joinpath(filename)
def _compile(self, file_pattern, folder_exclude_pattern):
"""Compile patterns."""
if not isinstance(file_pattern, _wcparse.WcRegexp):
file_pattern = self._compile_wildcard(file_pattern, self.file_pathname)
if not isinstance(folder_exclude_pattern, _wcparse.WcRegexp):
folder_exclude_pattern = self._compile_wildcard(folder_exclude_pattern, self.dir_pathname)
return file_pattern, folder_exclude_pattern
__all__ = (
"CASE", "IGNORECASE", "RAWCHARS", "DOTGLOB", "DOTMATCH",
"EXTGLOB", "EXTMATCH", "NEGATE", "MINUSNEGATE", "BRACE",
"REALPATH", "FOLLOW", "MATCHBASE", "NEGATEALL", "NODIR", "NOUNIQUE",
"NODOTDIR", "SCANDOTDIR",
"C", "I", "R", "D", "E", "G", "N", "B", "M", "P", "L", "S", "X", "O", "A", "Q", "Z", "SD",
"Path", "PurePath", "WindowsPath", "PosixPath", "PurePosixPath", "PureWindowsPath"
)
C = CASE = glob.CASE
I = IGNORECASE = glob.IGNORECASE
R = RAWCHARS = glob.RAWCHARS
D = DOTGLOB = DOTMATCH = glob.DOTMATCH
E = EXTGLOB = EXTMATCH = glob.EXTMATCH
G = GLOBSTAR = _wcparse.GLOBSTAR
N = NEGATE = glob.NEGATE
B = BRACE = glob.BRACE
M = MINUSNEGATE = glob.MINUSNEGATE
P = REALPATH = glob.REALPATH
L = FOLLOW = glob.FOLLOW
S = SPLIT = glob.SPLIT
X = MATCHBASE = glob.MATCHBASE
O = NODIR = glob.NODIR
A = NEGATEALL = glob.NEGATEALL
Q = NOUNIQUE = glob.NOUNIQUE
Z = NODOTDIR = glob.NODOTDIR
SD = SCANDOTDIR = glob.SCANDOTDIR
# Internal flags
_EXTMATCHBASE = _wcparse._EXTMATCHBASE
L = FOLLOW = glob.FOLLOW
S = SPLIT = glob.SPLIT
X = MATCHBASE = glob.MATCHBASE
O = NODIR = glob.NODIR
A = NEGATEALL = glob.NEGATEALL
Q = NOUNIQUE = glob.NOUNIQUE
Z = NODOTDIR = glob.NODOTDIR
SD = SCANDOTDIR = glob.SCANDOTDIR
# Internal flags
_EXTMATCHBASE = _wcparse._EXTMATCHBASE
_RTL = _wcparse._RTL
_NOABSOLUTE = _wcparse._NOABSOLUTE
_PATHNAME = _wcparse.PATHNAME
_FORCEWIN = _wcparse.FORCEWIN
_FORCEUNIX = _wcparse.FORCEUNIX
_PATHLIB = glob._PATHLIB
FLAG_MASK = (
CASE |
IGNORECASE |
RAWCHARS |
DOTMATCH |
EXTMATCH |
GLOBSTAR |
NEGATE |
MINUSNEGATE |
BRACE |
REALPATH |
FOLLOW |
)
# We don't use `util.platform` only because we mock it in tests,
# and `scandir` will not work with bytes on the wrong system.
WIN = sys.platform.startswith('win')
NO_SCANDIR_WORKAROUND = util.PY36
C = CASE = _wcparse.CASE
I = IGNORECASE = _wcparse.IGNORECASE
R = RAWCHARS = _wcparse.RAWCHARS
D = DOTGLOB = DOTMATCH = _wcparse.DOTMATCH
E = EXTGLOB = EXTMATCH = _wcparse.EXTMATCH
G = GLOBSTAR = _wcparse.GLOBSTAR
N = NEGATE = _wcparse.NEGATE
M = MINUSNEGATE = _wcparse.MINUSNEGATE
B = BRACE = _wcparse.BRACE
P = REALPATH = _wcparse.REALPATH
L = FOLLOW = _wcparse.FOLLOW
S = SPLIT = _wcparse.SPLIT
X = MATCHBASE = _wcparse.MATCHBASE
O = NODIR = _wcparse.NODIR
A = NEGATEALL = _wcparse.NEGATEALL
W = FORCEWIN = _wcparse.FORCEWIN
U = FORCEUNIX = _wcparse.FORCEUNIX
T = GLOBTILDE = _wcparse.GLOBTILDE
Q = NOUNIQUE = _wcparse.NOUNIQUE
Z = NODOTDIR = _wcparse.NODOTDIR
K = MARK = 0x1000000
SD = SCANDOTDIR = 0x2000000
_PATHLIB = 0x8000000
IN THE SOFTWARE.
"""
import os
import re
from . import _wcparse
from . import util
__all__ = (
"CASE", "IGNORECASE", "RAWCHARS", "FILEPATHNAME", "DIRPATHNAME", "PATHNAME",
"EXTMATCH", "GLOBSTAR", "BRACE", "MINUSNEGATE", "SYMLINKS", "HIDDEN", "RECURSIVE",
"MATCHBASE",
"C", "I", "R", "P", "E", "G", "M", "DP", "FP", "SL", "HD", "RV", "X", "B",
"WcMatch"
)
C = CASE = _wcparse.CASE
I = IGNORECASE = _wcparse.IGNORECASE
R = RAWCHARS = _wcparse.RAWCHARS
E = EXTMATCH = _wcparse.EXTMATCH
G = GLOBSTAR = _wcparse.GLOBSTAR
B = BRACE = _wcparse.BRACE
M = MINUSNEGATE = _wcparse.MINUSNEGATE
X = MATCHBASE = _wcparse.MATCHBASE
# Control `PATHNAME` individually for folder exclude and files
DP = DIRPATHNAME = 0x1000000
FP = FILEPATHNAME = 0x2000000
SL = SYMLINKS = 0x4000000
HD = HIDDEN = 0x8000000
RV = RECURSIVE = 0x10000000
# Internal flags
def _iter_patterns(self, patterns):
"""Iterate expanded patterns."""
seen = set()
for p in patterns:
p = util.norm_pattern(p, not self.unix, self.raw_chars)
for count, expanded in enumerate(_wcparse.expand(p, self.flags), 1):
if 0 < self.limit < count:
raise _wcparse.PatternLimitException(
"Pattern limit exceeded the limit of {:d}".format(self.limit)
)
# Filter out duplicate patterns. If `NOUNIQUE` is enabled,
# we only want to filter on negative patterns as they are
# only filters.
is_neg = _wcparse.is_negative(expanded, self.flags)
if not self.nounique or is_neg:
if expanded in seen:
continue
seen.add(expanded)
yield is_neg, expanded