Skip to content

Commit

Permalink
Merge pull request #8684 from uranusjr/zipfile-unicode-path-python2
Browse files Browse the repository at this point in the history
  • Loading branch information
pradyunsg authored Aug 4, 2020
2 parents 0c48ec0 + a12e2f1 commit 70768de
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
2 changes: 2 additions & 0 deletions news/8684.bugfix
Original file line number Diff line number Diff line change
@@ -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.
15 changes: 13 additions & 2 deletions src/pip/_internal/operations/install/wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
Union,
cast,
)
from zipfile import ZipInfo

from pip._vendor.pkg_resources import Distribution

Expand Down Expand Up @@ -420,6 +421,15 @@ def __init__(self, src_record_path, dest_path, zip_file):
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
Expand All @@ -439,11 +449,12 @@ def save(self):
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)

Expand Down

0 comments on commit 70768de

Please sign in to comment.