diff --git a/pex/third_party/__init__.py b/pex/third_party/__init__.py index f25a700da..46837b06c 100644 --- a/pex/third_party/__init__.py +++ b/pex/third_party/__init__.py @@ -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)) @@ -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)