Skip to content

Commit 5846dac

Browse files
hoodmaneagronholm
andauthored
Support unpacking wheels that contain files with commas in their names (#427)
The csv module is now being used to read RECORD. Co-authored-by: Alex Grönholm <alex.gronholm@nextday.fi>
1 parent 0acd203 commit 5846dac

File tree

7 files changed

+42
-18
lines changed

7 files changed

+42
-18
lines changed

src/wheel/wheelfile.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import os.path
66
import re
77
import stat
8+
import sys
89
import time
910
from collections import OrderedDict
1011
from distutils import log as logger
@@ -13,6 +14,16 @@
1314
from wheel.cli import WheelError
1415
from wheel.util import urlsafe_b64decode, as_unicode, native, urlsafe_b64encode, as_bytes, StringIO
1516

17+
if sys.version_info >= (3,):
18+
from io import TextIOWrapper
19+
20+
def read_csv(fp):
21+
return csv.reader(TextIOWrapper(fp, newline='', encoding='utf-8'))
22+
else:
23+
def read_csv(fp):
24+
for line in csv.reader(fp):
25+
yield [column.decode('utf-8') for column in line]
26+
1627
# Non-greedy matching of an optional build number may be too clever (more
1728
# invalid wheel filenames will match). Separate regex for .dist-info?
1829
WHEEL_INFO_RE = re.compile(
@@ -60,23 +71,24 @@ def __init__(self, file, mode='r', compression=ZIP_DEFLATED):
6071
raise WheelError('Missing {} file'.format(self.record_path))
6172

6273
with record:
63-
for line in record:
64-
line = line.decode('utf-8')
65-
path, hash_sum, size = line.rsplit(u',', 2)
66-
if hash_sum:
67-
algorithm, hash_sum = hash_sum.split(u'=')
68-
try:
69-
hashlib.new(algorithm)
70-
except ValueError:
71-
raise WheelError('Unsupported hash algorithm: {}'.format(algorithm))
72-
73-
if algorithm.lower() in {'md5', 'sha1'}:
74-
raise WheelError(
75-
'Weak hash algorithm ({}) is not permitted by PEP 427'
76-
.format(algorithm))
77-
78-
self._file_hashes[path] = (
79-
algorithm, urlsafe_b64decode(hash_sum.encode('ascii')))
74+
for line in read_csv(record):
75+
path, hash_sum, size = line
76+
if not hash_sum:
77+
continue
78+
79+
algorithm, hash_sum = hash_sum.split(u'=')
80+
try:
81+
hashlib.new(algorithm)
82+
except ValueError:
83+
raise WheelError('Unsupported hash algorithm: {}'.format(algorithm))
84+
85+
if algorithm.lower() in {'md5', 'sha1'}:
86+
raise WheelError(
87+
'Weak hash algorithm ({}) is not permitted by PEP 427'
88+
.format(algorithm))
89+
90+
self._file_hashes[path] = (
91+
algorithm, urlsafe_b64decode(hash_sum.encode('ascii')))
8092

8193
def open(self, name_or_info, mode="r", pwd=None):
8294
def _update_crc(newdata, eof=None):

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
@pytest.fixture(scope='session')
1313
def wheels_and_eggs(tmpdir_factory):
1414
"""Build wheels and eggs from test distributions."""
15-
test_distributions = "complex-dist", "simple.dist", "headers.dist"
15+
test_distributions = "complex-dist", "simple.dist", "headers.dist", "commasinfilenames.dist"
1616
if sys.version_info >= (3, 6):
1717
# Only Python 3.6+ can handle packaging unicode file names reliably
1818
# across different platforms

tests/testdata/commasinfilenames.dist/mypackage/__init__.py

Whitespace-only changes.

tests/testdata/commasinfilenames.dist/mypackage/data/1,2,3.txt

Whitespace-only changes.

tests/testdata/commasinfilenames.dist/mypackage/data/__init__.py

Whitespace-only changes.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from setuptools import setup
2+
3+
setup(
4+
name='testrepo',
5+
version='0.1',
6+
packages=["mypackage"],
7+
description='A test package with commas in file names',
8+
include_package_data=True,
9+
package_data={
10+
"mypackage.data": ["*"]
11+
},
12+
)

tests/testdata/commasinfilenames.dist/testrepo-0.1.0/mypackage/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)