Skip to content

Commit e80dc8d

Browse files
committed
Use compile_dir to compile
1 parent e98cc5c commit e80dc8d

File tree

1 file changed

+34
-6
lines changed
  • src/pip/_internal/operations/install

1 file changed

+34
-6
lines changed

src/pip/_internal/operations/install/wheel.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ def save(self) -> None:
7676
RecordPath = NewType("RecordPath", str)
7777
InstalledCSVRow = Tuple[RecordPath, str, Union[int, str]]
7878

79+
IS_NOT_PYTHON_FILE_RE = re.compile(r'^.*(?<!\.py)$')
80+
7981

8082
def rehash(path: str, blocksize: int = 1 << 20) -> Tuple[str, str]:
8183
"""Return (encoded_digest, length) for path using hashlib.sha256()"""
@@ -596,13 +598,34 @@ def pyc_source_file_paths() -> Generator[str, None, None]:
596598
# Sorting installation paths makes it easier to reproduce and debug
597599
# issues related to permissions on existing files.
598600
for installed_path in sorted(set(installed.values())):
601+
if not installed_path.endswith(".py"):
602+
continue
603+
599604
full_installed_path = os.path.join(lib_dir, installed_path)
600605
if not os.path.isfile(full_installed_path):
601606
continue
602-
if not full_installed_path.endswith(".py"):
603-
continue
604607
yield full_installed_path
605608

609+
def pyc_source_root_dirs() -> Generator[str, None, None]:
610+
# All root source directories of the install (i.e. those that
611+
# are direct children of lib_dir) that the source Python files
612+
# are located within. Typically this is just one directory.
613+
source_root_dirs = set()
614+
for installed_path in installed.values():
615+
if not installed_path.endswith(".py"):
616+
continue
617+
618+
full_installed_path = os.path.join(lib_dir, installed_path)
619+
if not os.path.isfile(full_installed_path):
620+
continue
621+
622+
parent_full_installed_path = os.path.dirname(full_installed_path)
623+
if os.path.dirname(parent_full_installed_path) == lib_dir:
624+
if parent_full_installed_path in source_root_dirs:
625+
continue
626+
source_root_dirs.add(parent_full_installed_path)
627+
yield parent_full_installed_path
628+
606629
def pyc_output_path(path: str) -> str:
607630
"""Return the path the pyc file would have been written to."""
608631
return importlib.util.cache_from_source(path)
@@ -614,11 +637,16 @@ def pyc_output_path(path: str) -> str:
614637
) as stdout:
615638
with warnings.catch_warnings():
616639
warnings.filterwarnings("ignore")
640+
# Use compile_dir on the root directories in the package,
641+
# as compile_dir uses multiprocess this will be quicker
642+
# than using compile_file on each file.
643+
for dir in pyc_source_root_dirs():
644+
compileall.compile_dir(dir, force=True, quiet=2, workers=0, rx=IS_NOT_PYTHON_FILE_RE)
645+
646+
# Now check indivdual files were created
617647
for path in pyc_source_file_paths():
618-
success = compileall.compile_file(path, force=True, quiet=True)
619-
if success:
620-
pyc_path = pyc_output_path(path)
621-
assert os.path.exists(pyc_path)
648+
pyc_path = pyc_output_path(path)
649+
if os.path.exists(pyc_path):
622650
pyc_record_path = cast(
623651
"RecordPath", pyc_path.replace(os.path.sep, "/")
624652
)

0 commit comments

Comments
 (0)