diff options
author | Pradyun Gedam <3275593+pradyunsg@users.noreply.github.com> | 2020-08-04 06:50:38 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-04 06:50:38 +0530 |
commit | 70768de0a8f8cd8148bbfadac7fdc179e7f8a10a (patch) | |
tree | 4823225ec808ab0de2ad6164e625b2300eb9e0e4 | |
parent | 0c48ec06968f169b03103037aa235391cfe325ae (diff) | |
parent | a12e2f147997dd0932727150ae596ca489a41e78 (diff) | |
download | pip-70768de0a8f8cd8148bbfadac7fdc179e7f8a10a.tar.gz |
Merge pull request #8684 from uranusjr/zipfile-unicode-path-python2
-rw-r--r-- | news/8684.bugfix | 2 | ||||
-rw-r--r-- | src/pip/_internal/operations/install/wheel.py | 15 |
2 files changed, 15 insertions, 2 deletions
diff --git a/news/8684.bugfix b/news/8684.bugfix new file mode 100644 index 000000000..528291d73 --- /dev/null +++ b/news/8684.bugfix @@ -0,0 +1,2 @@ +Use UTF-8 to handle ZIP archive entries on Python 2 according to PEP 427, so +non-ASCII paths can be resolved as expected. diff --git a/src/pip/_internal/operations/install/wheel.py b/src/pip/_internal/operations/install/wheel.py index 681fc0aa8..e91b1b8d5 100644 --- a/src/pip/_internal/operations/install/wheel.py +++ b/src/pip/_internal/operations/install/wheel.py @@ -78,6 +78,7 @@ else: Union, cast, ) + from zipfile import ZipInfo from pip._vendor.pkg_resources import Distribution @@ -420,6 +421,15 @@ class ZipBackedFile(object): self._zip_file = zip_file self.changed = False + def _getinfo(self): + # type: () -> ZipInfo + if not PY2: + return self._zip_file.getinfo(self.src_record_path) + # Python 2 does not expose a way to detect a ZIP's encoding, but the + # wheel specification (PEP 427) explicitly mandates that paths should + # use UTF-8, so we assume it is true. + return self._zip_file.getinfo(self.src_record_path.encode("utf-8")) + def save(self): # type: () -> None # directory creation is lazy and after file filtering @@ -439,11 +449,12 @@ class ZipBackedFile(object): if os.path.exists(self.dest_path): os.unlink(self.dest_path) - with self._zip_file.open(self.src_record_path) as f: + zipinfo = self._getinfo() + + with self._zip_file.open(zipinfo) as f: with open(self.dest_path, "wb") as dest: shutil.copyfileobj(f, dest) - zipinfo = self._zip_file.getinfo(self.src_record_path) if zip_item_is_executable(zipinfo): set_extracted_file_to_default_mode_plus_executable(self.dest_path) |