Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a4ed88d

Browse files
committed
Simplify setupext.download_or_cache.
Instead of repeatedly unwrapping and rewrapping the file contents in a BytesIO that needs to be seek()ed, just pass around the bytes object itself.
1 parent 7bba84b commit a4ed88d

File tree

1 file changed

+32
-74
lines changed

1 file changed

+32
-74
lines changed

setupext.py

Lines changed: 32 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,10 @@ def _get_xdg_cache_dir():
3636
return pathlib.Path(cache_dir, 'matplotlib')
3737

3838

39-
def get_fd_hash(fd):
40-
"""
41-
Compute the sha256 hash of the bytes in a file-like
42-
"""
43-
BLOCKSIZE = 1 << 16
39+
def _get_hash(data):
40+
"""Compute the sha256 hash of *data*."""
4441
hasher = hashlib.sha256()
45-
old_pos = fd.tell()
46-
fd.seek(0)
47-
buf = fd.read(BLOCKSIZE)
48-
while buf:
49-
hasher.update(buf)
50-
buf = fd.read(BLOCKSIZE)
51-
fd.seek(old_pos)
42+
hasher.update(data)
5243
return hasher.hexdigest()
5344

5445

@@ -59,64 +50,48 @@ def download_or_cache(url, sha):
5950
Parameters
6051
----------
6152
url : str
62-
The url to download
63-
53+
The url to download.
6454
sha : str
65-
The sha256 of the file
55+
The sha256 of the file.
6656
6757
Returns
6858
-------
69-
BytesIO
70-
The file loaded into memory.
59+
bytes
60+
The file contents.
7161
"""
7262
cache_dir = _get_xdg_cache_dir()
7363

74-
def get_from_cache(local_fn):
75-
if cache_dir is None:
76-
raise Exception("no cache dir")
77-
buf = BytesIO((cache_dir / local_fn).read_bytes())
78-
if get_fd_hash(buf) != sha:
79-
return None
80-
buf.seek(0)
81-
return buf
82-
83-
def write_cache(local_fn, data):
84-
if cache_dir is None:
85-
raise Exception("no cache dir")
86-
cache_dir.mkdir(parents=True, exist_ok=True)
87-
old_pos = data.tell()
88-
data.seek(0)
89-
with open(cache_dir / local_fn, "xb") as fout:
90-
fout.write(data.read())
91-
data.seek(old_pos)
92-
93-
try:
94-
return get_from_cache(sha)
95-
except Exception:
96-
pass
64+
if cache_dir is not None: # Try to read from cache.
65+
try:
66+
data = (cache_dir / sha).read_bytes()
67+
except IOError:
68+
pass
69+
else:
70+
if _get_hash(data) == sha:
71+
return data
9772

9873
# jQueryUI's website blocks direct downloads from urllib.request's
9974
# default User-Agent, but not (for example) wget; so I don't feel too
10075
# bad passing in an empty User-Agent.
10176
with urllib.request.urlopen(
10277
Request(url, headers={"User-Agent": ""})) as req:
103-
file_contents = BytesIO(req.read())
104-
file_contents.seek(0)
105-
106-
file_sha = get_fd_hash(file_contents)
78+
data = req.read()
10779

80+
file_sha = _get_hash(data)
10881
if file_sha != sha:
10982
raise Exception(
11083
f"The download file does not match the expected sha. {url} was "
11184
f"expected to have {sha} but it had {file_sha}")
11285

113-
try:
114-
write_cache(sha, file_contents)
115-
except Exception:
116-
pass
86+
if cache_dir is not None: # Try to cache the downloaded file.
87+
try:
88+
cache_dir.mkdir(parents=True, exist_ok=True)
89+
with open(cache_dir / sha, "xb") as fout:
90+
fout.write(data)
91+
except IOError:
92+
pass
11793

118-
file_contents.seek(0)
119-
return file_contents
94+
return data
12095

12196

12297
# SHA256 hashes of the FreeType tarballs
@@ -192,16 +167,6 @@ def print_status(package, status):
192167
subsequent_indent=indent))
193168

194169

195-
def get_buffer_hash(fd):
196-
BLOCKSIZE = 1 << 16
197-
hasher = hashlib.sha256()
198-
buf = fd.read(BLOCKSIZE)
199-
while buf:
200-
hasher.update(buf)
201-
buf = fd.read(BLOCKSIZE)
202-
return hasher.hexdigest()
203-
204-
205170
def deplib(libname):
206171
if sys.platform != 'win32':
207172
return libname
@@ -545,18 +510,13 @@ def do_custom_build(self):
545510
if not src_path.exists():
546511
os.makedirs('build', exist_ok=True)
547512

548-
url_fmts = [
549-
('https://downloads.sourceforge.net/project/freetype'
550-
'/freetype2/{version}/{tarball}'),
551-
('https://download.savannah.gnu.org/releases/freetype'
552-
'/{tarball}')
553-
]
554513
tarball = f'freetype-{LOCAL_FREETYPE_VERSION}.tar.gz'
555-
556514
target_urls = [
557-
url_fmt.format(version=LOCAL_FREETYPE_VERSION,
558-
tarball=tarball)
559-
for url_fmt in url_fmts]
515+
(f'https://downloads.sourceforge.net/project/freetype'
516+
f'/freetype2/{LOCAL_FREETYPE_VERSION}/{tarball}'),
517+
(f'https://download.savannah.gnu.org/releases/freetype'
518+
f'/{tarball}')
519+
]
560520

561521
for tarball_url in target_urls:
562522
try:
@@ -572,10 +532,8 @@ def do_custom_build(self):
572532
f"top-level of the source repository.")
573533

574534
print(f"Extracting {tarball}")
575-
# just to be sure
576-
tar_contents.seek(0)
577-
with tarfile.open(tarball, mode="r:gz",
578-
fileobj=tar_contents) as tgz:
535+
with tarfile.open(fileobj=BytesIO(tar_contents),
536+
mode="r:gz") as tgz:
579537
tgz.extractall("build")
580538

581539
print(f"Building freetype in {src_path}")

0 commit comments

Comments
 (0)