Repository: yt-dlp/yt-dlp
File: test/test_networking.py (Python)

Code before:
        ),
        # https://github.com/python/cpython/blob/987b712b4aeeece336eed24fcc87a950a756c3e2/Lib/http/client.py#L1265
        # bpo-38576: Check implemented in 3.7.8+, 3.8.3+
        (
            Request('http://127.0.0. 1', method='GET'),
            'URL can\'t contain control characters',
            lambda v: v < (3, 7, 8) or (3, 8, 0) <= v < (3, 8, 3),
        ),
        # https://github.com/python/cpython/blob/987b712b4aeeece336eed24fcc87a950a756c3e2/Lib/http/client.py#L1288C31-L1288C50
        (Request('http://127.0.0.1', headers={'foo\n': 'bar'}), 'Invalid header name', None),
    ])
    def test_httplib_validation_errors(self, handler, req, match, version_check):
        if version_check and version_check(sys.version_info):
            pytest.skip(f'Python {sys.version} version does not have the required validation for this test.')

        with handler() as rh:
            with pytest.raises(RequestError, match=match) as exc_info:
                validate_and_send(rh, req)
            assert not isinstance(exc_info.value, TransportError)


@pytest.mark.parametrize('handler', ['Requests'], indirect=True)
class TestRequestsRequestHandler(TestRequestHandlerBase):
    @pytest.mark.parametrize('raised,expected', [
        # `requests` and/or `urllib3` may not be available
        # ruff: disable[PLW0108]
        (lambda: requests.exceptions.ConnectTimeout(), TransportError),
        (lambda: requests.exceptions.ReadTimeout(), TransportError),
        (lambda: requests.exceptions.Timeout(), TransportError),
        (lambda: requests.exceptions.ConnectionError(), TransportError),
        (lambda: requests.exceptions.ProxyError(), ProxyError),
        (lambda: requests.exceptions.SSLError('12[CERTIFICATE_VERIFY_FAILED]34'), CertificateVerifyError),
        (lambda: requests.exceptions.SSLError(), SSLError),
        (lambda: requests.exceptions.InvalidURL(), RequestError),
        (lambda: requests.exceptions.InvalidHeader(), RequestError),
        # catch-all: https://github.com/psf/requests/blob/main/src/requests/adapters.py#L535
        (lambda: urllib3.exceptions.HTTPError(), TransportError),
        (lambda: requests.exceptions.RequestException(), RequestError),
        # Needs a response object
        # (lambda: requests.exceptions.TooManyRedirects(), HTTPError),
        # ruff: enable[PLW0108]
    ])
    def test_request_error_mapping(self, handler, monkeypatch, raised, expected):
        with handler() as rh:
            def mock_get_instance(*args, **kwargs):
                class MockSession:
                    def request(self, *args, **kwargs):
                        raise raised()
                return MockSession()

            monkeypatch.setattr(rh, '_get_instance', mock_get_instance)

Review comment (suggestion):
```suggestion
        # ruff: disable[PLW0108] `requests` and/or `urllib3` may not be available
```

Code after:
        ),
        # https://github.com/python/cpython/blob/987b712b4aeeece336eed24fcc87a950a756c3e2/Lib/http/client.py#L1265
        # bpo-38576: Check implemented in 3.7.8+, 3.8.3+
        (
            Request('http://127.0.0. 1', method='GET'),
            'URL can\'t contain control characters',
            lambda v: v < (3, 7, 8) or (3, 8, 0) <= v < (3, 8, 3),
        ),
        # https://github.com/python/cpython/blob/987b712b4aeeece336eed24fcc87a950a756c3e2/Lib/http/client.py#L1288C31-L1288C50
        (Request('http://127.0.0.1', headers={'foo\n': 'bar'}), 'Invalid header name', None),
    ])
    def test_httplib_validation_errors(self, handler, req, match, version_check):
        if version_check and version_check(sys.version_info):
            pytest.skip(f'Python {sys.version} version does not have the required validation for this test.')

        with handler() as rh:
            with pytest.raises(RequestError, match=match) as exc_info:
                validate_and_send(rh, req)
            assert not isinstance(exc_info.value, TransportError)


@pytest.mark.parametrize('handler', ['Requests'], indirect=True)
class TestRequestsRequestHandler(TestRequestHandlerBase):
    # ruff: disable[PLW0108] `requests` and/or `urllib3` may not be available
    @pytest.mark.parametrize('raised,expected', [
        (lambda: requests.exceptions.ConnectTimeout(), TransportError),
        (lambda: requests.exceptions.ReadTimeout(), TransportError),
        (lambda: requests.exceptions.Timeout(), TransportError),
        (lambda: requests.exceptions.ConnectionError(), TransportError),
        (lambda: requests.exceptions.ProxyError(), ProxyError),
        (lambda: requests.exceptions.SSLError('12[CERTIFICATE_VERIFY_FAILED]34'), CertificateVerifyError),
        (lambda: requests.exceptions.SSLError(), SSLError),
        (lambda: requests.exceptions.InvalidURL(), RequestError),
        (lambda: requests.exceptions.InvalidHeader(), RequestError),
        # catch-all: https://github.com/psf/requests/blob/main/src/requests/adapters.py#L535
        (lambda: urllib3.exceptions.HTTPError(), TransportError),
        (lambda: requests.exceptions.RequestException(), RequestError),
        # Needs a response object
        # (lambda: requests.exceptions.TooManyRedirects(), HTTPError),
    ])
    # ruff: enable[PLW0108]
    def test_request_error_mapping(self, handler, monkeypatch, raised, expected):
        with handler() as rh:
            def mock_get_instance(*args, **kwargs):
                class MockSession:
                    def request(self, *args, **kwargs):
                        raise raised()
                return MockSession()

            monkeypatch.setattr(rh, '_get_instance', mock_get_instance)