Skip to content

Commit

Permalink
Merge pull request #1 from abravalheri/avoid-overriding-zipfile
Browse files Browse the repository at this point in the history
Avoid overriding zipfile
  • Loading branch information
delijati committed Mar 15, 2022
2 parents 069735f + c9d369c commit d47c554
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 40 deletions.
50 changes: 29 additions & 21 deletions setuptools/archive_util.py
Expand Up @@ -100,29 +100,37 @@ def unpack_zipfile(filename, extract_dir, progress_filter=default_filter):
raise UnrecognizedFormat("%s is not a zip file" % (filename,))

with zipfile.ZipFile(filename) as z:
for info in z.infolist():
name = info.filename
_unpack_zipfile_obj(z, extract_dir, progress_filter)

# don't extract absolute paths or ones with .. in them
if name.startswith('/') or '..' in name.split('/'):
continue

target = os.path.join(extract_dir, *name.split('/'))
target = progress_filter(name, target)
if not target:
continue
if name.endswith('/'):
# directory
ensure_directory(target)
else:
# file
ensure_directory(target)
data = z.read(info.filename)
with open(target, 'wb') as f:
f.write(data)
unix_attributes = info.external_attr >> 16
if unix_attributes:
os.chmod(target, unix_attributes)
def _unpack_zipfile_obj(zipfile_obj, extract_dir, progress_filter=default_filter):
"""Internal/private API used by other parts of setuptools.
Similar to ``unpack_zipfile``, but receives an already opened :obj:`zipfile.ZipFile`
object instead of a filename.
"""
for info in zipfile_obj.infolist():
name = info.filename

# don't extract absolute paths or ones with .. in them
if name.startswith('/') or '..' in name.split('/'):
continue

target = os.path.join(extract_dir, *name.split('/'))
target = progress_filter(name, target)
if not target:
continue
if name.endswith('/'):
# directory
ensure_directory(target)
else:
# file
ensure_directory(target)
data = zipfile_obj.read(info.filename)
with open(target, 'wb') as f:
f.write(data)
unix_attributes = info.external_attr >> 16
if unix_attributes:
os.chmod(target, unix_attributes)


def _resolve_tar_file_or_dir(tar_obj, tar_member_obj):
Expand Down
5 changes: 3 additions & 2 deletions setuptools/tests/test_wheel.py
Expand Up @@ -618,7 +618,6 @@ def sys_tags():
'onnxruntime-0.1.2-cp36-cp36m-manylinux1_x86_64.whl').is_compatible()


@pytest.mark.skipif(sys.platform == 'win32', reason='non-Windows only')
def test_wheel_mode():
@contextlib.contextmanager
def build_wheel(extra_file_defs=None, **kwargs):
Expand Down Expand Up @@ -699,4 +698,6 @@ def build_wheel(extra_file_defs=None, **kwargs):
base = pathlib.Path(install_dir) / w.egg_name()
script_sh = base / "EGG-INFO" / "scripts" / "script.sh"
assert script_sh.exists()
assert oct(stat.S_IMODE(script_sh.stat().st_mode)) == "0o777"
if sys.platform != 'win32':
# Editable file mode has no effect on Windows
assert oct(stat.S_IMODE(script_sh.stat().st_mode)) == "0o777"
20 changes: 3 additions & 17 deletions setuptools/wheel.py
Expand Up @@ -15,6 +15,7 @@
from setuptools.extern.packaging.tags import sys_tags
from setuptools.extern.packaging.utils import canonicalize_name
from setuptools.command.egg_info import write_requirements
from setuptools.archive_util import _unpack_zipfile_obj


WHEEL_NAME = re.compile(
Expand All @@ -27,20 +28,6 @@
"__import__('pkg_resources').declare_namespace(__name__)\n"


class ZipFilePreserveMode(zipfile.ZipFile):
""" Extended ZipFile class to preserve file mode """
def _extract_member(self, member, targetpath, pwd):
if not isinstance(member, zipfile.ZipInfo):
member = self.getinfo(member)

targetpath = super()._extract_member(member, targetpath, pwd)

attr = member.external_attr >> 16
if attr != 0:
os.chmod(targetpath, attr)
return targetpath


def unpack(src_dir, dst_dir):
'''Move everything under `src_dir` to `dst_dir`, and delete the former.'''
for dirpath, dirnames, filenames in os.walk(src_dir):
Expand Down Expand Up @@ -105,7 +92,7 @@ def get_dist_info(self, zf):

def install_as_egg(self, destination_eggdir):
'''Install wheel as an egg directory.'''
with ZipFilePreserveMode(self.filename) as zf:
with zipfile.ZipFile(self.filename) as zf:
self._install_as_egg(destination_eggdir, zf)

def _install_as_egg(self, destination_eggdir, zf):
Expand Down Expand Up @@ -135,8 +122,7 @@ def get_metadata(name):
raise ValueError(
'unsupported wheel format version: %s' % wheel_version)
# Extract to target directory.
os.mkdir(destination_eggdir)
zf.extractall(destination_eggdir)
_unpack_zipfile_obj(zf, destination_eggdir)
# Convert metadata.
dist_info = os.path.join(destination_eggdir, dist_info)
dist = pkg_resources.Distribution.from_location(
Expand Down

0 comments on commit d47c554

Please sign in to comment.