Merge pull request #8584 from McSinyx/range-unsupported-exc

This commit is contained in:
Pradyun Gedam 2020-07-21 13:53:20 +05:30 committed by GitHub
commit 982aac544e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 11 deletions

View File

@ -1,6 +1,6 @@
"""Lazy ZIP over HTTP"""
__all__ = ['dist_from_wheel_url']
__all__ = ['HTTPRangeRequestUnsupported', 'dist_from_wheel_url']
from bisect import bisect_left, bisect_right
from contextlib import contextmanager
@ -27,13 +27,18 @@ if MYPY_CHECK_RUNNING:
from pip._internal.network.session import PipSession
class HTTPRangeRequestUnsupported(Exception):
pass
def dist_from_wheel_url(name, url, session):
# type: (str, str, PipSession) -> Distribution
"""Return a pkg_resources.Distribution from the given wheel URL.
This uses HTTP range requests to only fetch the potion of the wheel
containing metadata, just enough for the object to be constructed.
If such requests are not supported, RuntimeError is raised.
If such requests are not supported, HTTPRangeRequestUnsupported
is raised.
"""
with LazyZipOverHTTP(url, session) as wheel:
# For read-only ZIP files, ZipFile only needs methods read,
@ -49,7 +54,8 @@ class LazyZipOverHTTP(object):
This uses HTTP range requests to lazily fetch the file's content,
which is supposed to be fed to ZipFile. If such requests are not
supported by the server, raise RuntimeError during initialization.
supported by the server, raise HTTPRangeRequestUnsupported
during initialization.
"""
def __init__(self, url, session, chunk_size=CONTENT_CHUNK_SIZE):
@ -64,7 +70,7 @@ class LazyZipOverHTTP(object):
self._left = [] # type: List[int]
self._right = [] # type: List[int]
if 'bytes' not in head.headers.get('Accept-Ranges', 'none'):
raise RuntimeError('range request is not supported')
raise HTTPRangeRequestUnsupported('range request is not supported')
self._check_zip()
@property

Binary file not shown.

View File

@ -3,9 +3,12 @@ from zipfile import BadZipfile
from pip._vendor.pkg_resources import Requirement
from pytest import fixture, mark, raises
from pip._internal.network.lazy_wheel import dist_from_wheel_url
from pip._internal.network.lazy_wheel import (
HTTPRangeRequestUnsupported,
dist_from_wheel_url,
)
from pip._internal.network.session import PipSession
from tests.lib.requests_mocks import MockResponse
from tests.lib.server import file_response
MYPY_0_782_WHL = (
'https://files.pythonhosted.org/packages/9d/65/'
@ -25,6 +28,16 @@ def session():
return PipSession()
@fixture
def mypy_whl_no_range(mock_server, shared_data):
mypy_whl = shared_data.packages / 'mypy-0.782-py3-none-any.whl'
mock_server.set_responses([file_response(mypy_whl)])
mock_server.start()
base_address = 'http://{}:{}'.format(mock_server.host, mock_server.port)
yield "{}/{}".format(base_address, 'mypy-0.782-py3-none-any.whl')
mock_server.stop()
@mark.network
def test_dist_from_wheel_url(session):
"""Test if the acquired distribution contain correct information."""
@ -35,12 +48,10 @@ def test_dist_from_wheel_url(session):
assert set(dist.requires(dist.extras)) == MYPY_0_782_REQS
@mark.network
def test_dist_from_wheel_url_no_range(session, monkeypatch):
def test_dist_from_wheel_url_no_range(session, mypy_whl_no_range):
"""Test handling when HTTP range requests are not supported."""
monkeypatch.setattr(session, 'head', lambda *a, **kw: MockResponse(b''))
with raises(RuntimeError):
dist_from_wheel_url('mypy', MYPY_0_782_WHL, session)
with raises(HTTPRangeRequestUnsupported):
dist_from_wheel_url('mypy', mypy_whl_no_range, session)
@mark.network