(
wheel, # type: InstallableWheel
install_paths, # type: InstallPaths
copy_mode=CopyMode.LINK, # type: CopyMode.Value
interpreter=None, # type: Optional[PythonInterpreter]
rel_extra_path=None, # type: Optional[str]
compile=False, # type: bool
requested=True, # type: bool
install_entry_point_scripts=True, # type: bool
record_entry_info=False, # type: bool
normalize_file_stat=False, # type: bool
re_hash=False, # type: bool
hermetic_scripts=False, # type: bool
)
| 833 | |
| 834 | |
| 835 | def install_wheel( |
| 836 | wheel, # type: InstallableWheel |
| 837 | install_paths, # type: InstallPaths |
| 838 | copy_mode=CopyMode.LINK, # type: CopyMode.Value |
| 839 | interpreter=None, # type: Optional[PythonInterpreter] |
| 840 | rel_extra_path=None, # type: Optional[str] |
| 841 | compile=False, # type: bool |
| 842 | requested=True, # type: bool |
| 843 | install_entry_point_scripts=True, # type: bool |
| 844 | record_entry_info=False, # type: bool |
| 845 | normalize_file_stat=False, # type: bool |
| 846 | re_hash=False, # type: bool |
| 847 | hermetic_scripts=False, # type: bool |
| 848 | ): |
| 849 | # type: (...) -> Tuple[Tuple[Text, Text], ...] |
| 850 | |
| 851 | # See: https://packaging.python.org/en/latest/specifications/binary-distribution-format/#installing-a-wheel-distribution-1-0-py32-none-any-whl |
| 852 | |
| 853 | dest = install_paths.purelib if wheel.root_is_purelib else install_paths.platlib |
| 854 | if rel_extra_path: |
| 855 | dest = os.path.join(dest, rel_extra_path) |
| 856 | if wheel.root_is_purelib: |
| 857 | install_paths = attr.evolve(install_paths, purelib=dest) |
| 858 | else: |
| 859 | install_paths = attr.evolve(install_paths, platlib=dest) |
| 860 | |
| 861 | data_dir = None # type: Optional[str] |
| 862 | if wheel.is_whl: |
| 863 | whl = wheel.location |
| 864 | zip_metadata = None # type: Optional[ZipMetadata] |
| 865 | with open_zip(whl) as zf: |
| 866 | # 1. Unpack |
| 867 | zf.extractall(dest) |
| 868 | data_dir = os.path.join(dest, wheel.data_dir) |
| 869 | if record_entry_info: |
| 870 | zip_metadata = ZipMetadata.from_zip( |
| 871 | filename=whl, info_list=zf.infolist(), normalize_file_stat=normalize_file_stat |
| 872 | ) |
| 873 | |
| 874 | # TODO(John Sirois): Consider verifying signatures. |
| 875 | # N.B.: Pip does not and its also not clear what good this does. A zip can be easily |
| 876 | # poked on a per-entry basis allowing forging a RECORD entry and its associated file. |
| 877 | # Only an outer fingerprint of the whole wheel really solves this sort of tampering. |
| 878 | |
| 879 | unpacked_wheel = Wheel.load(dest, project_name=wheel.project_name, known_tags=wheel.tags) |
| 880 | wheel = InstallableWheel( |
| 881 | wheel=unpacked_wheel, |
| 882 | install_paths=InstallPaths.wheel(dest, wheel=unpacked_wheel), |
| 883 | zip_metadata=zip_metadata, |
| 884 | ) |
| 885 | |
| 886 | # Deal with bad whl `RECORD`s. We happen to hit one from selenium-4.1.2-py3-none-any.whl |
| 887 | # in our tests. The selenium >=4,<4.1.3 wheels are all published with absolute paths for |
| 888 | # all the .py file RECORD entries. The .dist-info and .data entries are fine though. |
| 889 | record_data = wheel.metadata_files.read("RECORD") |
| 890 | |
| 891 | record_lines = [] # type: List[Text] |
| 892 | eol = os.sep |
no test coverage detected