Extract everything in site-packages to a specified path. :param ZipFile archive: The zipfile object we are bootstrapping from. :param Path target_path: The path to extract our zip to. :param bool compile_pyc: A boolean to dictate whether we pre-compile pyc. :param int compile_worker
(archive, target_path, compile_pyc=False, compile_workers=0, force=False)
| 108 | |
| 109 | |
| 110 | def extract_site_packages(archive, target_path, compile_pyc=False, compile_workers=0, force=False): |
| 111 | """Extract everything in site-packages to a specified path. |
| 112 | |
| 113 | :param ZipFile archive: The zipfile object we are bootstrapping from. |
| 114 | :param Path target_path: The path to extract our zip to. |
| 115 | :param bool compile_pyc: A boolean to dictate whether we pre-compile pyc. |
| 116 | :param int compile_workers: An int representing the number of pyc compiler workers. |
| 117 | :param bool force: A boolean to dictate whether or not we force extraction. |
| 118 | """ |
| 119 | parent = target_path.parent |
| 120 | target_path_tmp = Path(parent, target_path.name + ".tmp") |
| 121 | lock = Path(parent, f".{target_path.name}_lock") |
| 122 | |
| 123 | # If this is the first time that a pyz is being extracted, we'll need to create the ~/.shiv dir |
| 124 | if not parent.exists(): |
| 125 | parent.mkdir(parents=True, exist_ok=True) |
| 126 | |
| 127 | with FileLock(lock): |
| 128 | |
| 129 | # we acquired a lock, it's possible that prior invocation was holding the lock and has |
| 130 | # completed bootstrapping, so let's check (again) if we need to do any work |
| 131 | if not target_path.exists() or force: |
| 132 | |
| 133 | # extract our site-packages |
| 134 | for fileinfo in archive.infolist(): |
| 135 | |
| 136 | if fileinfo.filename.startswith("site-packages"): |
| 137 | extracted = archive.extract(fileinfo.filename, target_path_tmp) |
| 138 | |
| 139 | # restore original permissions |
| 140 | os.chmod(extracted, fileinfo.external_attr >> 16) |
| 141 | |
| 142 | if compile_pyc: |
| 143 | compileall.compile_dir(target_path_tmp, quiet=2, workers=compile_workers) |
| 144 | |
| 145 | # if using `force` we will need to delete our target path |
| 146 | if target_path.exists(): |
| 147 | shutil.rmtree(str(target_path)) |
| 148 | |
| 149 | # atomic move |
| 150 | shutil.move(str(target_path_tmp), str(target_path)) |
| 151 | |
| 152 | |
| 153 | def get_first_sitedir_index(): |