Skip to content

Commit

Permalink
When iterating over Zipfiles, always use the Unix file separator to f…
Browse files Browse the repository at this point in the history
…ix a Windows issue (#638)

Pex doesn't officially support windows, but there seems to be a regression in pex 1.6.0 with windows with respect to the way the vendoring works. Specifically, the regex for iterating the zip path in the vendoring uses the os separator, which has two problems on windows (where the separator is `\`):

1. `\` is an escape sequence, so unless the separator is added twice in the string, it uses it to escape the character immediately after the separator, causing the regex compilation to fail.
1. The path in the zip file uses unix separators (`/`), so using the os separator is actually wrong.

This PR addresses this by updating the regex to replace windows separators (`\`) in the prefix var with the unix separator.
  • Loading branch information
yorinasub17 authored and jsirois committed Apr 20, 2019
1 parent a4c5d96 commit 28869f6
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions pex/third_party/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,13 @@ def containing(cls, root):
prefix = ''
path = root
while path:
# We use '/' here because the zip file format spec specifies that paths must use
# forward slashes. See section 4.4.17 of
# https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT.
if zipfile.is_zipfile(path):
return cls(zipfile_path=path, prefix=prefix + os.sep if prefix else '')
prefix = os.path.join(prefix, os.path.basename(path))
return cls(zipfile_path=path, prefix='{}/'.format(prefix) if prefix else '')
path_base = os.path.basename(path)
prefix = '{}/{}'.format(path_base, prefix) if prefix else path_base
path = os.path.dirname(path)
raise ValueError('Could not find the zip file housing {}'.format(root))

Expand All @@ -114,10 +118,11 @@ def iter_root_packages(self, relpath):
yield package

def _filter_names(self, relpath, pattern, group):
pat = re.compile(r'^{prefix}{pattern}$'
.format(prefix=self.prefix + ((relpath + os.sep) if relpath else ''),
pattern=pattern))

# We use '/' here because the zip file format spec specifies that paths must use
# forward slashes. See section 4.4.17 of
# https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT.
relpath_pat = '' if not relpath else '{}/'.format(relpath.replace(os.sep, '/'))
pat = re.compile(r'^{}{}{}$'.format(self.prefix, relpath_pat, pattern))
with contextlib.closing(zipfile.ZipFile(self.zipfile_path)) as zf:
for name in zf.namelist():
match = pat.match(name)
Expand Down

0 comments on commit 28869f6

Please sign in to comment.