smart_open
smart_open copied to clipboard
Test failures with urllib3 2.0.4
Problem description
We are building smart-open 0.4.0 for nixpkgs, thereby running the test suite. After updating urllib3 from 1.26.16 to 2.0.4 we started seeing failures in the smart-open testsuite.
=========================== short test summary info ============================
FAILED smart_open/tests/test_http.py::HttpTest::test_https_seek_forward - requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRe...
FAILED smart_open/tests/test_http.py::HttpTest::test_seek_from_current - requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRe...
FAILED smart_open/tests/test_http.py::HttpTest::test_seek_from_end - requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRe...
FAILED smart_open/tests/test_http.py::HttpTest::test_seek_from_start - requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRe...
======= 4 failed, 368 passed, 4 skipped, 27 warnings in 70.45s (0:01:10) =======
Test protocol
smart-open> _______________________ HttpTest.test_https_seek_forward _______________________ smart-open> smart-open> self =smart-open> smart-open> @contextmanager smart-open> def _error_catcher(self) -> typing.Generator[None, None, None]: smart-open> """ smart-open> Catch low-level python exceptions, instead re-raising urllib3 smart-open> variants, so that low-level exceptions are not leaked in the smart-open> high-level api. smart-open> smart-open> On exit, release the connection back to the pool. smart-open> """ smart-open> clean_exit = False smart-open> smart-open> try: smart-open> try: smart-open> > yield smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:710: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> self = , amt = 131072 smart-open> smart-open> def _raw_read( smart-open> self, smart-open> amt: int | None = None, smart-open> ) -> bytes: smart-open> """ smart-open> Reads `amt` of bytes from the socket. smart-open> """ smart-open> if self._fp is None: smart-open> return None # type: ignore[return-value] smart-open> smart-open> fp_closed = getattr(self._fp, "closed", False) smart-open> smart-open> with self._error_catcher(): smart-open> data = self._fp_read(amt) if not fp_closed else b"" smart-open> if amt is not None and amt != 0 and not data: smart-open> # Platform-specific: Buggy versions of Python. smart-open> # Close the connection when no data is returned smart-open> # smart-open> # This is redundant to what httplib/http.client _should_ smart-open> # already do. However, versions of python released before smart-open> # December 15, 2012 (http://bugs.python.org/issue16298) do smart-open> # not properly close the connection in all cases. There is smart-open> # no harm in redundantly calling close. smart-open> self._fp.close() smart-open> if ( smart-open> self.enforce_content_length smart-open> and self.length_remaining is not None smart-open> and self.length_remaining != 0 smart-open> ): smart-open> # This is an edge case that httplib failed to cover due smart-open> # to concerns of backward compatibility. We're smart-open> # addressing it here to make sure IncompleteRead is smart-open> # raised during streaming, so all calls with incorrect smart-open> # Content-Length are caught. smart-open> > raise IncompleteRead(self._fp_bytes_read, self.length_remaining) smart-open> E urllib3.exceptions.IncompleteRead: IncompleteRead(58 bytes read, 10 more expected) smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:835: IncompleteRead smart-open> smart-open> The above exception was the direct cause of the following exception: smart-open> smart-open> def generate(): smart-open> # Special case for urllib3. smart-open> if hasattr(self.raw, "stream"): smart-open> try: smart-open> > yield from self.raw.stream(chunk_size, decode_content=True) smart-open> smart-open> /nix/store/0ywyi98av0590s5idss3c13zas1cd1a0-python3.11-requests-2.31.0/lib/python3.11/site-packages/requests/models.py:816: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:940: in stream smart-open> data = self.read(amt=amt, decode_content=decode_content) smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:911: in read smart-open> data = self._raw_read(amt) smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:813: in _raw_read smart-open> with self._error_catcher(): smart-open> /nix/store/15djm2sxy19yyvicydzwrzfchq7nkmh1-python3-3.11.5/lib/python3.11/contextlib.py:155: in __exit__ smart-open> self.gen.throw(typ, value, traceback) smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> self = smart-open> smart-open> @contextmanager smart-open> def _error_catcher(self) -> typing.Generator[None, None, None]: smart-open> """ smart-open> Catch low-level python exceptions, instead re-raising urllib3 smart-open> variants, so that low-level exceptions are not leaked in the smart-open> high-level api. smart-open> smart-open> On exit, release the connection back to the pool. smart-open> """ smart-open> clean_exit = False smart-open> smart-open> try: smart-open> try: smart-open> yield smart-open> smart-open> except SocketTimeout as e: smart-open> # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but smart-open> # there is yet no clean way to get at it from this context. smart-open> raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] smart-open> smart-open> except BaseSSLError as e: smart-open> # FIXME: Is there a better way to differentiate between SSLErrors? smart-open> if "read operation timed out" not in str(e): smart-open> # SSL errors related to framing/MAC get wrapped and reraised here smart-open> raise SSLError(e) from e smart-open> smart-open> raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] smart-open> smart-open> except (HTTPException, OSError) as e: smart-open> # This includes IncompleteRead. smart-open> > raise ProtocolError(f"Connection broken: {e!r}", e) from e smart-open> E urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(58 bytes read, 10 more expected)', IncompleteRead(58 bytes read, 10 more expected)) smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:727: ProtocolError smart-open> smart-open> During handling of the above exception, another exception occurred: smart-open> smart-open> self = smart-open> smart-open> @responses.activate smart-open> def test_https_seek_forward(self): smart-open> """Did the seek forward over HTTPS work?""" smart-open> responses.add_callback(responses.GET, HTTPS_URL, callback=request_callback) smart-open> smart-open> with smart_open.open(HTTPS_URL, "rb") as fin: smart-open> fin.seek(10) smart-open> > read_bytes = fin.read(size=10) smart-open> smart-open> smart_open/tests/test_http.py:142: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart_open/http.py:183: in read smart-open> bytes_read = self._read_buffer.fill(self._read_iter) smart-open> smart_open/bytebuffer.py:155: in fill smart-open> for more_bytes in source: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> def generate(): smart-open> # Special case for urllib3. smart-open> if hasattr(self.raw, "stream"): smart-open> try: smart-open> yield from self.raw.stream(chunk_size, decode_content=True) smart-open> except ProtocolError as e: smart-open> > raise ChunkedEncodingError(e) smart-open> E requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(58 bytes read, 10 more expected)', IncompleteRead(58 bytes read, 10 more expected)) smart-open> smart-open> /nix/store/0ywyi98av0590s5idss3c13zas1cd1a0-python3.11-requests-2.31.0/lib/python3.11/site-packages/requests/models.py:818: ChunkedEncodingError smart-open> _______________________ HttpTest.test_seek_from_current ________________________ smart-open> smart-open> self = smart-open> smart-open> @contextmanager smart-open> def _error_catcher(self) -> typing.Generator[None, None, None]: smart-open> """ smart-open> Catch low-level python exceptions, instead re-raising urllib3 smart-open> variants, so that low-level exceptions are not leaked in the smart-open> high-level api. smart-open> smart-open> On exit, release the connection back to the pool. smart-open> """ smart-open> clean_exit = False smart-open> smart-open> try: smart-open> try: smart-open> > yield smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:710: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> self = , amt = 131072 smart-open> smart-open> def _raw_read( smart-open> self, smart-open> amt: int | None = None, smart-open> ) -> bytes: smart-open> """ smart-open> Reads `amt` of bytes from the socket. smart-open> """ smart-open> if self._fp is None: smart-open> return None # type: ignore[return-value] smart-open> smart-open> fp_closed = getattr(self._fp, "closed", False) smart-open> smart-open> with self._error_catcher(): smart-open> data = self._fp_read(amt) if not fp_closed else b"" smart-open> if amt is not None and amt != 0 and not data: smart-open> # Platform-specific: Buggy versions of Python. smart-open> # Close the connection when no data is returned smart-open> # smart-open> # This is redundant to what httplib/http.client _should_ smart-open> # already do. However, versions of python released before smart-open> # December 15, 2012 (http://bugs.python.org/issue16298) do smart-open> # not properly close the connection in all cases. There is smart-open> # no harm in redundantly calling close. smart-open> self._fp.close() smart-open> if ( smart-open> self.enforce_content_length smart-open> and self.length_remaining is not None smart-open> and self.length_remaining != 0 smart-open> ): smart-open> # This is an edge case that httplib failed to cover due smart-open> # to concerns of backward compatibility. We're smart-open> # addressing it here to make sure IncompleteRead is smart-open> # raised during streaming, so all calls with incorrect smart-open> # Content-Length are caught. smart-open> > raise IncompleteRead(self._fp_bytes_read, self.length_remaining) smart-open> E urllib3.exceptions.IncompleteRead: IncompleteRead(58 bytes read, 10 more expected) smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:835: IncompleteRead smart-open> smart-open> The above exception was the direct cause of the following exception: smart-open> smart-open> def generate(): smart-open> # Special case for urllib3. smart-open> if hasattr(self.raw, "stream"): smart-open> try: smart-open> > yield from self.raw.stream(chunk_size, decode_content=True) smart-open> smart-open> /nix/store/0ywyi98av0590s5idss3c13zas1cd1a0-python3.11-requests-2.31.0/lib/python3.11/site-packages/requests/models.py:816: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:940: in stream smart-open> data = self.read(amt=amt, decode_content=decode_content) smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:911: in read smart-open> data = self._raw_read(amt) smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:813: in _raw_read smart-open> with self._error_catcher(): smart-open> /nix/store/15djm2sxy19yyvicydzwrzfchq7nkmh1-python3-3.11.5/lib/python3.11/contextlib.py:155: in __exit__ smart-open> self.gen.throw(typ, value, traceback) smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> self = smart-open> smart-open> @contextmanager smart-open> def _error_catcher(self) -> typing.Generator[None, None, None]: smart-open> """ smart-open> Catch low-level python exceptions, instead re-raising urllib3 smart-open> variants, so that low-level exceptions are not leaked in the smart-open> high-level api. smart-open> smart-open> On exit, release the connection back to the pool. smart-open> """ smart-open> clean_exit = False smart-open> smart-open> try: smart-open> try: smart-open> yield smart-open> smart-open> except SocketTimeout as e: smart-open> # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but smart-open> # there is yet no clean way to get at it from this context. smart-open> raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] smart-open> smart-open> except BaseSSLError as e: smart-open> # FIXME: Is there a better way to differentiate between SSLErrors? smart-open> if "read operation timed out" not in str(e): smart-open> # SSL errors related to framing/MAC get wrapped and reraised here smart-open> raise SSLError(e) from e smart-open> smart-open> raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] smart-open> smart-open> except (HTTPException, OSError) as e: smart-open> # This includes IncompleteRead. smart-open> > raise ProtocolError(f"Connection broken: {e!r}", e) from e smart-open> E urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(58 bytes read, 10 more expected)', IncompleteRead(58 bytes read, 10 more expected)) smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:727: ProtocolError smart-open> smart-open> During handling of the above exception, another exception occurred: smart-open> smart-open> self = smart-open> smart-open> @responses.activate smart-open> def test_seek_from_current(self): smart-open> responses.add_callback(responses.GET, URL, callback=request_callback) smart-open> reader = smart_open.http.SeekableBufferedInputBase(URL) smart-open> smart-open> reader.seek(10) smart-open> > read_bytes = reader.read(size=10) smart-open> smart-open> smart_open/tests/test_http.py:79: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart_open/http.py:183: in read smart-open> bytes_read = self._read_buffer.fill(self._read_iter) smart-open> smart_open/bytebuffer.py:155: in fill smart-open> for more_bytes in source: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> def generate(): smart-open> # Special case for urllib3. smart-open> if hasattr(self.raw, "stream"): smart-open> try: smart-open> yield from self.raw.stream(chunk_size, decode_content=True) smart-open> except ProtocolError as e: smart-open> > raise ChunkedEncodingError(e) smart-open> E requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(58 bytes read, 10 more expected)', IncompleteRead(58 bytes read, 10 more expected)) smart-open> smart-open> /nix/store/0ywyi98av0590s5idss3c13zas1cd1a0-python3.11-requests-2.31.0/lib/python3.11/site-packages/requests/models.py:818: ChunkedEncodingError smart-open> _________________________ HttpTest.test_seek_from_end __________________________ smart-open> smart-open> self = smart-open> smart-open> @contextmanager smart-open> def _error_catcher(self) -> typing.Generator[None, None, None]: smart-open> """ smart-open> Catch low-level python exceptions, instead re-raising urllib3 smart-open> variants, so that low-level exceptions are not leaked in the smart-open> high-level api. smart-open> smart-open> On exit, release the connection back to the pool. smart-open> """ smart-open> clean_exit = False smart-open> smart-open> try: smart-open> try: smart-open> > yield smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:710: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> self = , amt = 131072 smart-open> smart-open> def _raw_read( smart-open> self, smart-open> amt: int | None = None, smart-open> ) -> bytes: smart-open> """ smart-open> Reads `amt` of bytes from the socket. smart-open> """ smart-open> if self._fp is None: smart-open> return None # type: ignore[return-value] smart-open> smart-open> fp_closed = getattr(self._fp, "closed", False) smart-open> smart-open> with self._error_catcher(): smart-open> data = self._fp_read(amt) if not fp_closed else b"" smart-open> if amt is not None and amt != 0 and not data: smart-open> # Platform-specific: Buggy versions of Python. smart-open> # Close the connection when no data is returned smart-open> # smart-open> # This is redundant to what httplib/http.client _should_ smart-open> # already do. However, versions of python released before smart-open> # December 15, 2012 (http://bugs.python.org/issue16298) do smart-open> # not properly close the connection in all cases. There is smart-open> # no harm in redundantly calling close. smart-open> self._fp.close() smart-open> if ( smart-open> self.enforce_content_length smart-open> and self.length_remaining is not None smart-open> and self.length_remaining != 0 smart-open> ): smart-open> # This is an edge case that httplib failed to cover due smart-open> # to concerns of backward compatibility. We're smart-open> # addressing it here to make sure IncompleteRead is smart-open> # raised during streaming, so all calls with incorrect smart-open> # Content-Length are caught. smart-open> > raise IncompleteRead(self._fp_bytes_read, self.length_remaining) smart-open> E urllib3.exceptions.IncompleteRead: IncompleteRead(10 bytes read, 58 more expected) smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:835: IncompleteRead smart-open> smart-open> The above exception was the direct cause of the following exception: smart-open> smart-open> def generate(): smart-open> # Special case for urllib3. smart-open> if hasattr(self.raw, "stream"): smart-open> try: smart-open> > yield from self.raw.stream(chunk_size, decode_content=True) smart-open> smart-open> /nix/store/0ywyi98av0590s5idss3c13zas1cd1a0-python3.11-requests-2.31.0/lib/python3.11/site-packages/requests/models.py:816: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:940: in stream smart-open> data = self.read(amt=amt, decode_content=decode_content) smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:911: in read smart-open> data = self._raw_read(amt) smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:813: in _raw_read smart-open> with self._error_catcher(): smart-open> /nix/store/15djm2sxy19yyvicydzwrzfchq7nkmh1-python3-3.11.5/lib/python3.11/contextlib.py:155: in __exit__ smart-open> self.gen.throw(typ, value, traceback) smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> self = smart-open> smart-open> @contextmanager smart-open> def _error_catcher(self) -> typing.Generator[None, None, None]: smart-open> """ smart-open> Catch low-level python exceptions, instead re-raising urllib3 smart-open> variants, so that low-level exceptions are not leaked in the smart-open> high-level api. smart-open> smart-open> On exit, release the connection back to the pool. smart-open> """ smart-open> clean_exit = False smart-open> smart-open> try: smart-open> try: smart-open> yield smart-open> smart-open> except SocketTimeout as e: smart-open> # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but smart-open> # there is yet no clean way to get at it from this context. smart-open> raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] smart-open> smart-open> except BaseSSLError as e: smart-open> # FIXME: Is there a better way to differentiate between SSLErrors? smart-open> if "read operation timed out" not in str(e): smart-open> # SSL errors related to framing/MAC get wrapped and reraised here smart-open> raise SSLError(e) from e smart-open> smart-open> raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] smart-open> smart-open> except (HTTPException, OSError) as e: smart-open> # This includes IncompleteRead. smart-open> > raise ProtocolError(f"Connection broken: {e!r}", e) from e smart-open> E urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(10 bytes read, 58 more expected)', IncompleteRead(10 bytes read, 58 more expected)) smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:727: ProtocolError smart-open> smart-open> During handling of the above exception, another exception occurred: smart-open> smart-open> self = smart-open> smart-open> @responses.activate smart-open> def test_seek_from_end(self): smart-open> responses.add_callback(responses.GET, URL, callback=request_callback) smart-open> reader = smart_open.http.SeekableBufferedInputBase(URL) smart-open> smart-open> reader.seek(-10, whence=smart_open.constants.WHENCE_END) smart-open> self.assertEqual(reader.tell(), len(BYTES) - 10) smart-open> > read_bytes = reader.read(size=10) smart-open> smart-open> smart_open/tests/test_http.py:96: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart_open/http.py:183: in read smart-open> bytes_read = self._read_buffer.fill(self._read_iter) smart-open> smart_open/bytebuffer.py:155: in fill smart-open> for more_bytes in source: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> def generate(): smart-open> # Special case for urllib3. smart-open> if hasattr(self.raw, "stream"): smart-open> try: smart-open> yield from self.raw.stream(chunk_size, decode_content=True) smart-open> except ProtocolError as e: smart-open> > raise ChunkedEncodingError(e) smart-open> E requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(10 bytes read, 58 more expected)', IncompleteRead(10 bytes read, 58 more expected)) smart-open> smart-open> /nix/store/0ywyi98av0590s5idss3c13zas1cd1a0-python3.11-requests-2.31.0/lib/python3.11/site-packages/requests/models.py:818: ChunkedEncodingError smart-open> ________________________ HttpTest.test_seek_from_start _________________________ smart-open> smart-open> self = smart-open> smart-open> @contextmanager smart-open> def _error_catcher(self) -> typing.Generator[None, None, None]: smart-open> """ smart-open> Catch low-level python exceptions, instead re-raising urllib3 smart-open> variants, so that low-level exceptions are not leaked in the smart-open> high-level api. smart-open> smart-open> On exit, release the connection back to the pool. smart-open> """ smart-open> clean_exit = False smart-open> smart-open> try: smart-open> try: smart-open> > yield smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:710: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> self = , amt = 131072 smart-open> smart-open> def _raw_read( smart-open> self, smart-open> amt: int | None = None, smart-open> ) -> bytes: smart-open> """ smart-open> Reads `amt` of bytes from the socket. smart-open> """ smart-open> if self._fp is None: smart-open> return None # type: ignore[return-value] smart-open> smart-open> fp_closed = getattr(self._fp, "closed", False) smart-open> smart-open> with self._error_catcher(): smart-open> data = self._fp_read(amt) if not fp_closed else b"" smart-open> if amt is not None and amt != 0 and not data: smart-open> # Platform-specific: Buggy versions of Python. smart-open> # Close the connection when no data is returned smart-open> # smart-open> # This is redundant to what httplib/http.client _should_ smart-open> # already do. However, versions of python released before smart-open> # December 15, 2012 (http://bugs.python.org/issue16298) do smart-open> # not properly close the connection in all cases. There is smart-open> # no harm in redundantly calling close. smart-open> self._fp.close() smart-open> if ( smart-open> self.enforce_content_length smart-open> and self.length_remaining is not None smart-open> and self.length_remaining != 0 smart-open> ): smart-open> # This is an edge case that httplib failed to cover due smart-open> # to concerns of backward compatibility. We're smart-open> # addressing it here to make sure IncompleteRead is smart-open> # raised during streaming, so all calls with incorrect smart-open> # Content-Length are caught. smart-open> > raise IncompleteRead(self._fp_bytes_read, self.length_remaining) smart-open> E urllib3.exceptions.IncompleteRead: IncompleteRead(58 bytes read, 10 more expected) smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:835: IncompleteRead smart-open> smart-open> The above exception was the direct cause of the following exception: smart-open> smart-open> def generate(): smart-open> # Special case for urllib3. smart-open> if hasattr(self.raw, "stream"): smart-open> try: smart-open> > yield from self.raw.stream(chunk_size, decode_content=True) smart-open> smart-open> /nix/store/0ywyi98av0590s5idss3c13zas1cd1a0-python3.11-requests-2.31.0/lib/python3.11/site-packages/requests/models.py:816: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:940: in stream smart-open> data = self.read(amt=amt, decode_content=decode_content) smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:911: in read smart-open> data = self._raw_read(amt) smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:813: in _raw_read smart-open> with self._error_catcher(): smart-open> /nix/store/15djm2sxy19yyvicydzwrzfchq7nkmh1-python3-3.11.5/lib/python3.11/contextlib.py:155: in __exit__ smart-open> self.gen.throw(typ, value, traceback) smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> self = smart-open> smart-open> @contextmanager smart-open> def _error_catcher(self) -> typing.Generator[None, None, None]: smart-open> """ smart-open> Catch low-level python exceptions, instead re-raising urllib3 smart-open> variants, so that low-level exceptions are not leaked in the smart-open> high-level api. smart-open> smart-open> On exit, release the connection back to the pool. smart-open> """ smart-open> clean_exit = False smart-open> smart-open> try: smart-open> try: smart-open> yield smart-open> smart-open> except SocketTimeout as e: smart-open> # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but smart-open> # there is yet no clean way to get at it from this context. smart-open> raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] smart-open> smart-open> except BaseSSLError as e: smart-open> # FIXME: Is there a better way to differentiate between SSLErrors? smart-open> if "read operation timed out" not in str(e): smart-open> # SSL errors related to framing/MAC get wrapped and reraised here smart-open> raise SSLError(e) from e smart-open> smart-open> raise ReadTimeoutError(self._pool, None, "Read timed out.") from e # type: ignore[arg-type] smart-open> smart-open> except (HTTPException, OSError) as e: smart-open> # This includes IncompleteRead. smart-open> > raise ProtocolError(f"Connection broken: {e!r}", e) from e smart-open> E urllib3.exceptions.ProtocolError: ('Connection broken: IncompleteRead(58 bytes read, 10 more expected)', IncompleteRead(58 bytes read, 10 more expected)) smart-open> smart-open> /nix/store/dxqvdy0rggdg8zqja3m3wf34dx5wqq3q-python3.11-urllib3-2.0.4/lib/python3.11/site-packages/urllib3/response.py:727: ProtocolError smart-open> smart-open> During handling of the above exception, another exception occurred: smart-open> smart-open> self = smart-open> smart-open> @responses.activate smart-open> def test_seek_from_start(self): smart-open> responses.add_callback(responses.GET, URL, callback=request_callback) smart-open> reader = smart_open.http.SeekableBufferedInputBase(URL) smart-open> smart-open> reader.seek(10) smart-open> self.assertEqual(reader.tell(), 10) smart-open> > read_bytes = reader.read(size=10) smart-open> smart-open> smart_open/tests/test_http.py:61: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart_open/http.py:183: in read smart-open> bytes_read = self._read_buffer.fill(self._read_iter) smart-open> smart_open/bytebuffer.py:155: in fill smart-open> for more_bytes in source: smart-open> _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ smart-open> smart-open> def generate(): smart-open> # Special case for urllib3. smart-open> if hasattr(self.raw, "stream"): smart-open> try: smart-open> yield from self.raw.stream(chunk_size, decode_content=True) smart-open> except ProtocolError as e: smart-open> > raise ChunkedEncodingError(e) smart-open> E requests.exceptions.ChunkedEncodingError: ('Connection broken: IncompleteRead(58 bytes read, 10 more expected)', IncompleteRead(58 bytes read, 10 more expected)) smart-open> smart-open> /nix/store/0ywyi98av0590s5idss3c13zas1cd1a0-python3.11-requests-2.31.0/lib/python3.11/site-packages/requests/models.py:818: ChunkedEncodingError
Steps/code to reproduce the problem
Install requests, with urllib3>2 and run the test suite.
Versions
- Linux-6.1.46-x86_64-with-glibc2.37
- Python 3.11.5 (main, Aug 24 2023, 12:23:19) [GCC 12.3.0]
- smart_open 6.4.0
Checklist
Before you create the issue, please make sure you have:
- [x] Described the problem clearly
- [x] Provided a minimal reproducible example, including any required data
- [x] Provided the version numbers of the relevant software
I'm also experiencing this issue, does anyone have an update?
Can you post full stack traces? The original error report truncates the error messages.
Did you see the "Test protocol" detail fold-out? It is too easy to miss.
I missed that. Thank you!
Hello, we are also seeing this on Debian. I can provide a Dockerfile to reproduce the bug if that would be helpful
https://bugs.debian.org/1073421
interestingly pip install smart_open[test] is selecting urllib3 v1 in the CI pipeline (hence this is being missed).
there is however no package that explicitly disallows urllib3 v2, so the pip resolver is choosing some interesting branch of the dependency tree to end up with urllib3 v1 🤔
pipgrip --tree -vv smart_open[test] shows no need to fallback to urllib3 v1:
Dependency tree
smart-open[test] (7.0.4)
├── azure-common (1.1.28)
├── azure-core (1.30.2)
│ ├── requests>=2.21.0 (2.32.3)
│ │ ├── certifi>=2017.4.17 (2024.6.2)
│ │ ├── charset-normalizer<4,>=2 (3.3.2)
│ │ ├── idna<4,>=2.5 (3.7)
│ │ └── urllib3<3,>=1.21.1 (2.2.2)
│ ├── six>=1.11.0 (1.16.0)
│ └── typing-extensions>=4.6.0 (4.12.2)
├── azure-storage-blob (12.20.0)
│ ├── azure-core>=1.28.0 (1.30.2)
│ │ ├── requests>=2.21.0 (2.32.3)
│ │ │ ├── certifi>=2017.4.17 (2024.6.2)
│ │ │ ├── charset-normalizer<4,>=2 (3.3.2)
│ │ │ ├── idna<4,>=2.5 (3.7)
│ │ │ └── urllib3<3,>=1.21.1 (2.2.2)
│ │ ├── six>=1.11.0 (1.16.0)
│ │ └── typing-extensions>=4.6.0 (4.12.2)
│ ├── cryptography>=2.1.4 (42.0.8)
│ │ └── cffi>=1.12 (1.16.0)
│ │ └── pycparser (2.22)
│ ├── isodate>=0.6.1 (0.6.1)
│ │ └── six (1.16.0)
│ └── typing-extensions>=4.6.0 (4.12.2)
├── boto3 (1.34.135)
│ ├── botocore<1.35.0,>=1.34.135 (1.34.135)
│ │ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ │ ├── python-dateutil<3.0.0,>=2.1 (2.9.0.post0)
│ │ │ └── six>=1.5 (1.16.0)
│ │ └── urllib3!=2.2.0,<3,>=1.25.4 (2.2.2)
│ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ └── s3transfer<0.11.0,>=0.10.0 (0.10.2)
│ └── botocore<2.0a.0,>=1.33.2 (1.34.135)
│ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ ├── python-dateutil<3.0.0,>=2.1 (2.9.0.post0)
│ │ └── six>=1.5 (1.16.0)
│ └── urllib3!=2.2.0,<3,>=1.25.4 (2.2.2)
├── google-cloud-storage>=2.6.0 (2.17.0)
│ ├── google-api-core<3.0.0dev,>=2.15.0 (2.19.1)
│ │ ├── google-auth<3.0.dev0,>=2.14.1 (2.30.0)
│ │ │ ├── cachetools<6.0,>=2.0.0 (5.3.3)
│ │ │ ├── pyasn1-modules>=0.2.1 (0.4.0)
│ │ │ │ └── pyasn1<0.7.0,>=0.4.6 (0.6.0)
│ │ │ └── rsa<5,>=3.1.4 (4.9)
│ │ │ └── pyasn1>=0.1.3 (0.6.0)
│ │ ├── googleapis-common-protos<2.0.dev0,>=1.56.2 (1.63.2)
│ │ │ └── protobuf!=3.20.0,!=3.20.1,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0.dev0,>=3.20.2 (5.27.2)
│ │ ├── proto-plus<2.0.0dev,>=1.22.3 (1.24.0)
│ │ │ └── protobuf<6.0.0dev,>=3.19.0 (5.27.2)
│ │ ├── protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0.dev0,>=3.19.5 (5.27.2)
│ │ └── requests<3.0.0.dev0,>=2.18.0 (2.32.3)
│ │ ├── certifi>=2017.4.17 (2024.6.2)
│ │ ├── charset-normalizer<4,>=2 (3.3.2)
│ │ ├── idna<4,>=2.5 (3.7)
│ │ └── urllib3<3,>=1.21.1 (2.2.2)
│ ├── google-auth<3.0dev,>=2.26.1 (2.30.0)
│ │ ├── cachetools<6.0,>=2.0.0 (5.3.3)
│ │ ├── pyasn1-modules>=0.2.1 (0.4.0)
│ │ │ └── pyasn1<0.7.0,>=0.4.6 (0.6.0)
│ │ └── rsa<5,>=3.1.4 (4.9)
│ │ └── pyasn1>=0.1.3 (0.6.0)
│ ├── google-cloud-core<3.0dev,>=2.3.0 (2.4.1)
│ │ ├── google-api-core!=2.0.*,!=2.1.*,!=2.2.*,!=2.3.0,<3.0.0dev,>=1.31.6 (2.19.1)
│ │ │ ├── google-auth<3.0.dev0,>=2.14.1 (2.30.0)
│ │ │ │ ├── cachetools<6.0,>=2.0.0 (5.3.3)
│ │ │ │ ├── pyasn1-modules>=0.2.1 (0.4.0)
│ │ │ │ │ └── pyasn1<0.7.0,>=0.4.6 (0.6.0)
│ │ │ │ └── rsa<5,>=3.1.4 (4.9)
│ │ │ │ └── pyasn1>=0.1.3 (0.6.0)
│ │ │ ├── googleapis-common-protos<2.0.dev0,>=1.56.2 (1.63.2)
│ │ │ │ └── protobuf!=3.20.0,!=3.20.1,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0.dev0,>=3.20.2 (5.27.2)
│ │ │ ├── proto-plus<2.0.0dev,>=1.22.3 (1.24.0)
│ │ │ │ └── protobuf<6.0.0dev,>=3.19.0 (5.27.2)
│ │ │ ├── protobuf!=3.20.0,!=3.20.1,!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0.dev0,>=3.19.5 (5.27.2)
│ │ │ └── requests<3.0.0.dev0,>=2.18.0 (2.32.3)
│ │ │ ├── certifi>=2017.4.17 (2024.6.2)
│ │ │ ├── charset-normalizer<4,>=2 (3.3.2)
│ │ │ ├── idna<4,>=2.5 (3.7)
│ │ │ └── urllib3<3,>=1.21.1 (2.2.2)
│ │ └── google-auth<3.0dev,>=1.25.0 (2.30.0)
│ │ ├── cachetools<6.0,>=2.0.0 (5.3.3)
│ │ ├── pyasn1-modules>=0.2.1 (0.4.0)
│ │ │ └── pyasn1<0.7.0,>=0.4.6 (0.6.0)
│ │ └── rsa<5,>=3.1.4 (4.9)
│ │ └── pyasn1>=0.1.3 (0.6.0)
│ ├── google-crc32c<2.0dev,>=1.0 (1.5.0)
│ ├── google-resumable-media>=2.6.0 (2.7.1)
│ │ └── google-crc32c<2.0dev,>=1.0 (1.5.0)
│ └── requests<3.0.0dev,>=2.18.0 (2.32.3)
│ ├── certifi>=2017.4.17 (2024.6.2)
│ ├── charset-normalizer<4,>=2 (3.3.2)
│ ├── idna<4,>=2.5 (3.7)
│ └── urllib3<3,>=1.21.1 (2.2.2)
├── moto[server] (5.0.9)
│ ├── antlr4-python3-runtime (4.13.1)
│ ├── aws-xray-sdk!=0.96,>=0.93 (2.14.0)
│ │ ├── botocore>=1.11.3 (1.34.135)
│ │ │ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ │ │ ├── python-dateutil<3.0.0,>=2.1 (2.9.0.post0)
│ │ │ │ └── six>=1.5 (1.16.0)
│ │ │ └── urllib3!=2.2.0,<3,>=1.25.4 (2.2.2)
│ │ └── wrapt (1.16.0)
│ ├── boto3>=1.9.201 (1.34.135)
│ │ ├── botocore<1.35.0,>=1.34.135 (1.34.135)
│ │ │ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ │ │ ├── python-dateutil<3.0.0,>=2.1 (2.9.0.post0)
│ │ │ │ └── six>=1.5 (1.16.0)
│ │ │ └── urllib3!=2.2.0,<3,>=1.25.4 (2.2.2)
│ │ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ │ └── s3transfer<0.11.0,>=0.10.0 (0.10.2)
│ │ └── botocore<2.0a.0,>=1.33.2 (1.34.135)
│ │ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ │ ├── python-dateutil<3.0.0,>=2.1 (2.9.0.post0)
│ │ │ └── six>=1.5 (1.16.0)
│ │ └── urllib3!=2.2.0,<3,>=1.25.4 (2.2.2)
│ ├── botocore>=1.14.0 (1.34.135)
│ │ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ │ ├── python-dateutil<3.0.0,>=2.1 (2.9.0.post0)
│ │ │ └── six>=1.5 (1.16.0)
│ │ └── urllib3!=2.2.0,<3,>=1.25.4 (2.2.2)
│ ├── cfn-lint>=0.40.0 (1.4.2)
│ │ ├── aws-sam-translator>=1.89.0 (1.89.0)
│ │ │ ├── boto3==1.*,>=1.19.5 (1.34.135)
│ │ │ │ ├── botocore<1.35.0,>=1.34.135 (1.34.135)
│ │ │ │ │ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ │ │ │ │ ├── python-dateutil<3.0.0,>=2.1 (2.9.0.post0)
│ │ │ │ │ │ └── six>=1.5 (1.16.0)
│ │ │ │ │ └── urllib3!=2.2.0,<3,>=1.25.4 (2.2.2)
│ │ │ │ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ │ │ │ └── s3transfer<0.11.0,>=0.10.0 (0.10.2)
│ │ │ │ └── botocore<2.0a.0,>=1.33.2 (1.34.135)
│ │ │ │ ├── jmespath<2.0.0,>=0.7.1 (1.0.1)
│ │ │ │ ├── python-dateutil<3.0.0,>=2.1 (2.9.0.post0)
│ │ │ │ │ └── six>=1.5 (1.16.0)
│ │ │ │ └── urllib3!=2.2.0,<3,>=1.25.4 (2.2.2)
│ │ │ ├── jsonschema<5,>=3.2 (4.22.0)
│ │ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ │ ├── jsonschema-specifications>=2023.03.6 (2023.12.1)
│ │ │ │ │ └── referencing>=0.31.0 (0.35.1)
│ │ │ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ │ │ └── rpds-py>=0.7.0 (0.18.1)
│ │ │ │ ├── referencing>=0.28.4 (0.35.1)
│ │ │ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ │ │ └── rpds-py>=0.7.0 (0.18.1)
│ │ │ │ └── rpds-py>=0.7.1 (0.18.1)
│ │ │ ├── pydantic<3,>=1.8 (2.7.4)
│ │ │ │ ├── annotated-types>=0.4.0 (0.7.0)
│ │ │ │ ├── pydantic-core==2.18.4 (2.18.4)
│ │ │ │ │ └── typing-extensions!=4.7.0,>=4.6.0 (4.12.2)
│ │ │ │ └── typing-extensions>=4.6.1 (4.12.2)
│ │ │ └── typing-extensions>=4.4 (4.12.2)
│ │ ├── jsonpatch (1.33)
│ │ │ └── jsonpointer>=1.9 (3.0.0)
│ │ ├── networkx<4,>=2.4 (3.3)
│ │ ├── pyyaml>5.4 (6.0.1)
│ │ ├── regex (2024.5.15)
│ │ ├── sympy>=1.0.0 (1.12.1)
│ │ │ └── mpmath<1.4.0,>=1.1.0 (1.3.0)
│ │ └── typing-extensions (4.12.2)
│ ├── cryptography>=3.3.1 (42.0.8)
│ │ └── cffi>=1.12 (1.16.0)
│ │ └── pycparser (2.22)
│ ├── docker>=3.0.0 (7.1.0)
│ │ ├── requests>=2.26.0 (2.32.3)
│ │ │ ├── certifi>=2017.4.17 (2024.6.2)
│ │ │ ├── charset-normalizer<4,>=2 (3.3.2)
│ │ │ ├── idna<4,>=2.5 (3.7)
│ │ │ └── urllib3<3,>=1.21.1 (2.2.2)
│ │ └── urllib3>=1.26.0 (2.2.2)
│ ├── flask!=2.2.0,!=2.2.1 (3.0.3)
│ │ ├── blinker>=1.6.2 (1.8.2)
│ │ ├── click>=8.1.3 (8.1.7)
│ │ ├── itsdangerous>=2.1.2 (2.2.0)
│ │ ├── jinja2>=3.1.2 (3.1.4)
│ │ │ └── markupsafe>=2.0 (2.1.5)
│ │ └── werkzeug>=3.0.0 (3.0.3)
│ │ └── markupsafe>=2.1.1 (2.1.5)
│ ├── flask-cors (4.0.1)
│ │ └── flask>=0.9 (3.0.3)
│ │ ├── blinker>=1.6.2 (1.8.2)
│ │ ├── click>=8.1.3 (8.1.7)
│ │ ├── itsdangerous>=2.1.2 (2.2.0)
│ │ ├── jinja2>=3.1.2 (3.1.4)
│ │ │ └── markupsafe>=2.0 (2.1.5)
│ │ └── werkzeug>=3.0.0 (3.0.3)
│ │ └── markupsafe>=2.1.1 (2.1.5)
│ ├── graphql-core (3.2.3)
│ ├── jinja2>=2.10.1 (3.1.4)
│ │ └── markupsafe>=2.0 (2.1.5)
│ ├── joserfc>=0.9.0 (0.12.0)
│ │ └── cryptography (42.0.8)
│ │ └── cffi>=1.12 (1.16.0)
│ │ └── pycparser (2.22)
│ ├── jsondiff>=1.1.2 (2.0.0)
│ ├── jsonpath-ng (1.6.1)
│ │ └── ply (3.11)
│ ├── openapi-spec-validator>=0.5.0 (0.7.1)
│ │ ├── jsonschema-path<0.4.0,>=0.3.1 (0.3.3)
│ │ │ ├── pathable<0.5.0,>=0.4.1 (0.4.3)
│ │ │ ├── pyyaml>=5.1 (6.0.1)
│ │ │ ├── referencing<0.36.0,>=0.28.0 (0.35.1)
│ │ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ │ └── rpds-py>=0.7.0 (0.18.1)
│ │ │ └── requests<3.0.0,>=2.31.0 (2.32.3)
│ │ │ ├── certifi>=2017.4.17 (2024.6.2)
│ │ │ ├── charset-normalizer<4,>=2 (3.3.2)
│ │ │ ├── idna<4,>=2.5 (3.7)
│ │ │ └── urllib3<3,>=1.21.1 (2.2.2)
│ │ ├── jsonschema<5.0.0,>=4.18.0 (4.22.0)
│ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ ├── jsonschema-specifications>=2023.03.6 (2023.12.1)
│ │ │ │ └── referencing>=0.31.0 (0.35.1)
│ │ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ │ └── rpds-py>=0.7.0 (0.18.1)
│ │ │ ├── referencing>=0.28.4 (0.35.1)
│ │ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ │ └── rpds-py>=0.7.0 (0.18.1)
│ │ │ └── rpds-py>=0.7.1 (0.18.1)
│ │ ├── lazy-object-proxy<2.0.0,>=1.7.1 (1.10.0)
│ │ └── openapi-schema-validator<0.7.0,>=0.6.0 (0.6.2)
│ │ ├── jsonschema-specifications<2024.0.0,>=2023.5.2 (2023.12.1)
│ │ │ └── referencing>=0.31.0 (0.35.1)
│ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ └── rpds-py>=0.7.0 (0.18.1)
│ │ ├── jsonschema<5.0.0,>=4.19.1 (4.22.0)
│ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ ├── jsonschema-specifications>=2023.03.6 (2023.12.1)
│ │ │ │ └── referencing>=0.31.0 (0.35.1)
│ │ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ │ └── rpds-py>=0.7.0 (0.18.1)
│ │ │ ├── referencing>=0.28.4 (0.35.1)
│ │ │ │ ├── attrs>=22.2.0 (23.2.0)
│ │ │ │ └── rpds-py>=0.7.0 (0.18.1)
│ │ │ └── rpds-py>=0.7.1 (0.18.1)
│ │ └── rfc3339-validator (0.1.4)
│ │ └── six (1.16.0)
│ ├── py-partiql-parser==0.5.5 (0.5.5)
│ ├── pyparsing>=3.0.7 (3.1.2)
│ ├── python-dateutil<3.0.0,>=2.1 (2.9.0.post0)
│ │ └── six>=1.5 (1.16.0)
│ ├── pyyaml>=5.1 (6.0.1)
│ ├── requests>=2.5 (2.32.3)
│ │ ├── certifi>=2017.4.17 (2024.6.2)
│ │ ├── charset-normalizer<4,>=2 (3.3.2)
│ │ ├── idna<4,>=2.5 (3.7)
│ │ └── urllib3<3,>=1.21.1 (2.2.2)
│ ├── responses>=0.15.0 (0.25.3)
│ │ ├── pyyaml (6.0.1)
│ │ ├── requests<3.0,>=2.30.0 (2.32.3)
│ │ │ ├── certifi>=2017.4.17 (2024.6.2)
│ │ │ ├── charset-normalizer<4,>=2 (3.3.2)
│ │ │ ├── idna<4,>=2.5 (3.7)
│ │ │ └── urllib3<3,>=1.21.1 (2.2.2)
│ │ └── urllib3<3.0,>=1.25.10 (2.2.2)
│ ├── setuptools (70.1.1)
│ ├── werkzeug!=2.2.0,!=2.2.1,>=0.5 (3.0.3)
│ │ └── markupsafe>=2.1.1 (2.1.5)
│ └── xmltodict (0.13.0)
├── paramiko (3.4.0)
│ ├── bcrypt>=3.2 (4.1.3)
│ ├── cryptography>=3.3 (42.0.8)
│ │ └── cffi>=1.12 (1.16.0)
│ │ └── pycparser (2.22)
│ └── pynacl>=1.5 (1.5.0)
│ └── cffi>=1.4.1 (1.16.0)
│ └── pycparser (2.22)
├── pytest (8.2.2)
│ ├── iniconfig (2.0.0)
│ ├── packaging (24.1)
│ └── pluggy<2.0,>=1.5 (1.5.0)
├── pytest-rerunfailures (14.0)
│ ├── packaging>=17.1 (24.1)
│ └── pytest>=7.2 (8.2.2)
│ ├── iniconfig (2.0.0)
│ ├── packaging (24.1)
│ └── pluggy<2.0,>=1.5 (1.5.0)
├── requests (2.32.3)
│ ├── certifi>=2017.4.17 (2024.6.2)
│ ├── charset-normalizer<4,>=2 (3.3.2)
│ ├── idna<4,>=2.5 (3.7)
│ └── urllib3<3,>=1.21.1 (2.2.2)
├── responses (0.25.3)
│ ├── pyyaml (6.0.1)
│ ├── requests<3.0,>=2.30.0 (2.32.3)
│ │ ├── certifi>=2017.4.17 (2024.6.2)
│ │ ├── charset-normalizer<4,>=2 (3.3.2)
│ │ ├── idna<4,>=2.5 (3.7)
│ │ └── urllib3<3,>=1.21.1 (2.2.2)
│ └── urllib3<3.0,>=1.25.10 (2.2.2)
├── wrapt (1.16.0)
└── zstandard (0.22.0)
@mr-c I worked ont the Debian packaging today, stumbled on this too. I don't want to rush anything before my Holliday, so I left it as-is.
this commit is likely to blame as it was introduced in v2 and touches the IncompleteRead error from the traceback: https://github.com/urllib3/urllib3/commit/c35033f6cc54106ca66ef2d48a9e3564d4fb0e07
however, if you blame further, it turns out we're looking at 8 years old code: https://github.com/urllib3/urllib3/blame/9763f09d2ca93c2e10150bfddba341b6a54993ad/src/urllib3/response.py#L782
so there's no obvious change to account for here AFAICT
I figured out why CI was running urllib3 v1: the CI python-package.yml had a typo, causing all the tests to run on python 3.7 instead of on 3.8--3.12. fixing in #828