[3.9] bpo-41043: Escape literal part of the path for glob(). (GH-20994). (GH-21275)

(cherry picked from commit 935586845815f5b4c7814794413f6a812d4bd45f)
diff --git a/Tools/c-analyzer/c_analyzer/common/files.py b/Tools/c-analyzer/c_analyzer/common/files.py
index ab551a8..f630afe 100644
--- a/Tools/c-analyzer/c_analyzer/common/files.py
+++ b/Tools/c-analyzer/c_analyzer/common/files.py
@@ -41,6 +41,8 @@
 def glob_tree(root, *,
               suffix=None,
               _glob=glob.iglob,
+              _escape=glob.escape,
+              _join=os.path.join,
               ):
     """Yield each file in the tree under the given directory name.
 
@@ -51,9 +53,9 @@
     if not isinstance(suffix, str):
         raise ValueError('suffix must be a string')
 
-    for filename in _glob(f'{root}/*{suffix}'):
+    for filename in _glob(_join(_escape(root), f'*{suffix}')):
         yield filename
-    for filename in _glob(f'{root}/**/*{suffix}'):
+    for filename in _glob(_join(_escape(root), f'**/*{suffix}')):
         yield filename
 
 
diff --git a/Tools/c-analyzer/check-c-globals.py b/Tools/c-analyzer/check-c-globals.py
index e68ed92..1371f92 100644
--- a/Tools/c-analyzer/check-c-globals.py
+++ b/Tools/c-analyzer/check-c-globals.py
@@ -37,7 +37,9 @@
 def find_capi_vars(root):
     capi_vars = {}
     for dirname in SOURCE_DIRS:
-        for filename in glob.glob(os.path.join(ROOT_DIR, dirname, '**/*.[hc]'),
+        for filename in glob.glob(os.path.join(
+                                  glob.escape(os.path.join(ROOT_DIR, dirname)),
+                                  '**/*.[hc]'),
                                   recursive=True):
             with open(filename) as file:
                 for name in _find_capi_vars(file):
diff --git a/Tools/peg_generator/scripts/test_parse_directory.py b/Tools/peg_generator/scripts/test_parse_directory.py
index 63204ce..100db1d 100755
--- a/Tools/peg_generator/scripts/test_parse_directory.py
+++ b/Tools/peg_generator/scripts/test_parse_directory.py
@@ -7,8 +7,12 @@
 import time
 import traceback
 import tokenize
+<<<<<<< HEAD
 import _peg_parser
 from glob import glob
+=======
+from glob import glob, escape
+>>>>>>> 9355868458... bpo-41043: Escape literal part of the path for glob(). (GH-20994)
 from pathlib import PurePath
 
 from typing import List, Optional, Any, Tuple
@@ -183,7 +187,7 @@
     trees = {}  # Trees to compare (after everything else is done)
     total_seconds = 0
 
-    for file in sorted(glob(f"{directory}/**/*.py", recursive=True)):
+    for file in sorted(glob(os.path.join(escape(directory), f"**/*.py"), recursive=True)):
         # Only attempt to parse Python files and files that are not excluded
         if any(PurePath(file).match(pattern) for pattern in excluded_files):
             continue
diff --git a/Tools/ssl/make_ssl_data.py b/Tools/ssl/make_ssl_data.py
index a29c04a..1dc234f 100755
--- a/Tools/ssl/make_ssl_data.py
+++ b/Tools/ssl/make_ssl_data.py
@@ -39,7 +39,7 @@
     f = sys.stdout if use_stdout else open(outfile, "w")
     # mnemonic -> (library code, error prefix, header file)
     error_libraries = {}
-    for error_header in glob.glob(os.path.join(openssl_inc, 'include/openssl/*err.h')):
+    for error_header in glob.glob(os.path.join(glob.escape(openssl_inc), 'include/openssl/*err.h')):
         base = os.path.basename(error_header)
         if base in ('buffererr.h', 'objectserr.h', 'storeerr.h'):
             # Deprecated in 3.0.