Package: src:servefile
Version: 0.5.4-3.1
Severity: serious
Tags: ftbfs

Dear maintainer:

During a rebuild of all packages in unstable, your package failed to build:

--------------------------------------------------------------------------------
[...]
 debian/rules binary
dh binary --with python3 --buildsystem=pybuild
   dh_update_autotools_config -O--buildsystem=pybuild
   dh_autoreconf -O--buildsystem=pybuild
   dh_auto_configure -O--buildsystem=pybuild
I: pybuild base:311: python3.13 setup.py config 
/usr/lib/python3/dist-packages/setuptools/_distutils/dist.py:261: UserWarning: 
Unknown distribution option: 'tests_require'
  warnings.warn(msg)
running config
I: pybuild base:311: python3.12 setup.py config 
/usr/lib/python3/dist-packages/setuptools/_distutils/dist.py:261: UserWarning: 
Unknown distribution option: 'tests_require'
  warnings.warn(msg)
running config
   dh_auto_build -O--buildsystem=pybuild

[... snipped ...]

                    self._raise_timeout(
                        err=e, url=self.proxy.url, timeout_value=conn.timeout
                    )
                    raise
    
            # If we're going to release the connection in ``finally:``, then
            # the response doesn't need to know about the connection. Otherwise
            # it will also try to release it and we'll have a double-release
            # mess.
            response_conn = conn if not release_conn else None
    
            # Make the request on the HTTPConnection object
>           response = self._make_request(
                conn,
                method,
                url,
                timeout=timeout_obj,
                body=body,
                headers=headers,
                chunked=chunked,
                retries=retries,
                response_conn=response_conn,
                preload_content=preload_content,
                decode_content=decode_content,
                **response_kw,
            )

/usr/lib/python3/dist-packages/urllib3/connectionpool.py:789: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:490: in _make_request
    raise new_e
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:466: in _make_request
    self._validate_conn(conn)
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:1095: in _validate_conn
    conn.connect()
/usr/lib/python3/dist-packages/urllib3/connection.py:693: in connect
    self.sock = sock = self._new_conn()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <urllib3.connection.HTTPSConnection object at 0x7f5c845c6850>

    def _new_conn(self) -> socket.socket:
        """Establish a socket connection and set nodelay settings on it.
    
        :return: New socket connection.
        """
        try:
            sock = connection.create_connection(
                (self._dns_host, self.port),
                self.timeout,
                source_address=self.source_address,
                socket_options=self.socket_options,
            )
        except socket.gaierror as e:
            raise NameResolutionError(self.host, self, e) from e
        except SocketTimeout as e:
            raise ConnectTimeoutError(
                self,
                f"Connection to {self.host} timed out. (connect 
timeout={self.timeout})",
            ) from e
    
        except OSError as e:
>           raise NewConnectionError(
                self, f"Failed to establish a new connection: {e}"
            ) from e
E           urllib3.exceptions.NewConnectionError: 
<urllib3.connection.HTTPSConnection object at 0x7f5c845c6850>: Failed to 
establish a new connection: [Errno 111] Connection refused

/usr/lib/python3/dist-packages/urllib3/connection.py:214: NewConnectionError

The above exception was the direct cause of the following exception:

self = <requests.adapters.HTTPAdapter object at 0x7f5c8446a750>
request = <PreparedRequest [GET]>, stream = False
timeout = Timeout(connect=None, read=None, total=None), verify = False
cert = None, proxies = OrderedDict()

    def send(
        self, request, stream=False, timeout=None, verify=True, cert=None, 
proxies=None
    ):
        """Sends PreparedRequest object. Returns Response object.
    
        :param request: The :class:`PreparedRequest <PreparedRequest>` being 
sent.
        :param stream: (optional) Whether to stream the request content.
        :param timeout: (optional) How long to wait for the server to send
            data before giving up, as a float, or a :ref:`(connect timeout,
            read timeout) <timeouts>` tuple.
        :type timeout: float or tuple or urllib3 Timeout object
        :param verify: (optional) Either a boolean, in which case it controls 
whether
            we verify the server's TLS certificate, or a string, in which case 
it
            must be a path to a CA bundle to use
        :param cert: (optional) Any user-provided SSL certificate to be trusted.
        :param proxies: (optional) The proxies dictionary to apply to the 
request.
        :rtype: requests.Response
        """
    
        try:
            conn = self.get_connection_with_tls_context(
                request, verify, proxies=proxies, cert=cert
            )
        except LocationValueError as e:
            raise InvalidURL(e, request=request)
    
        self.cert_verify(conn, request.url, verify, cert)
        url = self.request_url(request, proxies)
        self.add_headers(
            request,
            stream=stream,
            timeout=timeout,
            verify=verify,
            cert=cert,
            proxies=proxies,
        )
    
        chunked = not (request.body is None or "Content-Length" in 
request.headers)
    
        if isinstance(timeout, tuple):
            try:
                connect, read = timeout
                timeout = TimeoutSauce(connect=connect, read=read)
            except ValueError:
                raise ValueError(
                    f"Invalid timeout {timeout}. Pass a (connect, read) timeout 
tuple, "
                    f"or a single float to set both timeouts to the same value."
                )
        elif isinstance(timeout, TimeoutSauce):
            pass
        else:
            timeout = TimeoutSauce(connect=timeout, read=timeout)
    
        try:
>           resp = conn.urlopen(
                method=request.method,
                url=url,
                body=request.body,
                headers=request.headers,
                redirect=False,
                assert_same_host=False,
                preload_content=False,
                decode_content=False,
                retries=self.max_retries,
                timeout=timeout,
                chunked=chunked,
            )

/usr/lib/python3/dist-packages/requests/adapters.py:667: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python3/dist-packages/urllib3/connectionpool.py:843: in urlopen
    retries = retries.increment(
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = Retry(total=0, connect=None, read=False, redirect=None, status=None)
method = 'GET', url = '/', response = None
error = NewConnectionError('<urllib3.connection.HTTPSConnection object at 
0x7f5c845c6850>: Failed to establish a new connection: [Errno 111] Connection 
refused')
_pool = <urllib3.connectionpool.HTTPSConnectionPool object at 0x7f5c843dad70>
_stacktrace = <traceback object at 0x7f5c83ec1580>

    def increment(
        self,
        method: str | None = None,
        url: str | None = None,
        response: BaseHTTPResponse | None = None,
        error: Exception | None = None,
        _pool: ConnectionPool | None = None,
        _stacktrace: TracebackType | None = None,
    ) -> Self:
        """Return a new Retry object with incremented retry counters.
    
        :param response: A response object, or None, if the server did not
            return a response.
        :type response: :class:`~urllib3.response.BaseHTTPResponse`
        :param Exception error: An error encountered during the request, or
            None if the response was received successfully.
    
        :return: A new ``Retry`` object.
        """
        if self.total is False and error:
            # Disabled, indicate to re-raise the error.
            raise reraise(type(error), error, _stacktrace)
    
        total = self.total
        if total is not None:
            total -= 1
    
        connect = self.connect
        read = self.read
        redirect = self.redirect
        status_count = self.status
        other = self.other
        cause = "unknown"
        status = None
        redirect_location = None
    
        if error and self._is_connection_error(error):
            # Connect retry?
            if connect is False:
                raise reraise(type(error), error, _stacktrace)
            elif connect is not None:
                connect -= 1
    
        elif error and self._is_read_error(error):
            # Read retry?
            if read is False or method is None or not 
self._is_method_retryable(method):
                raise reraise(type(error), error, _stacktrace)
            elif read is not None:
                read -= 1
    
        elif error:
            # Other retry?
            if other is not None:
                other -= 1
    
        elif response and response.get_redirect_location():
            # Redirect retry?
            if redirect is not None:
                redirect -= 1
            cause = "too many redirects"
            response_redirect_location = response.get_redirect_location()
            if response_redirect_location:
                redirect_location = response_redirect_location
            status = response.status
    
        else:
            # Incrementing because of a server error like a 500 in
            # status_forcelist and the given method is in the allowed_methods
            cause = ResponseError.GENERIC_ERROR
            if response and response.status:
                if status_count is not None:
                    status_count -= 1
                cause = 
ResponseError.SPECIFIC_ERROR.format(status_code=response.status)
                status = response.status
    
        history = self.history + (
            RequestHistory(method, url, error, status, redirect_location),
        )
    
        new_retry = self.new(
            total=total,
            connect=connect,
            read=read,
            redirect=redirect,
            status=status_count,
            other=other,
            history=history,
        )
    
        if new_retry.is_exhausted():
            reason = error or ResponseError(cause)
>           raise MaxRetryError(_pool, url, reason) from reason  # type: 
> ignore[arg-type]
E           urllib3.exceptions.MaxRetryError: 
HTTPSConnectionPool(host='localhost', port=40953): Max retries exceeded with 
url: / (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection 
object at 0x7f5c845c6850>: Failed to establish a new connection: [Errno 111] 
Connection refused'))

/usr/lib/python3/dist-packages/urllib3/util/retry.py:519: MaxRetryError

During handling of the above exception, another exception occurred:

run_servefile = <function run_servefile.<locals>._run_servefile at 
0x7f5c84442de0>
datadir = <function datadir.<locals>._datadir at 0x7f5c84443a60>

    def test_https_big_download(run_servefile, datadir):
        # test with about 10 mb of data
        data = "x" * (10 * 1024 ** 2)
        p = datadir({'testfile': data}) / 'testfile'
        run_servefile(['--ssl', str(p)])
    
        urllib3.disable_warnings()
>       _retry_while(ConnectionError, check_download)(data, protocol='https', 
> verify=False)

tests/test_servefile.py:437: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
tests/test_servefile.py:127: in wrapped
    return function(*args, **kwargs)
tests/test_servefile.py:109: in check_download
    r = make_request(path, **kwargs)
tests/test_servefile.py:98: in make_request
    r = getattr(requests, method)(url, **kwargs)
/usr/lib/python3/dist-packages/requests/api.py:73: in get
    return request("get", url, params=params, **kwargs)
/usr/lib/python3/dist-packages/requests/api.py:59: in request
    return session.request(method=method, url=url, **kwargs)
/usr/lib/python3/dist-packages/requests/sessions.py:589: in request
    resp = self.send(prep, **send_kwargs)
/usr/lib/python3/dist-packages/requests/sessions.py:703: in send
    r = adapter.send(request, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <requests.adapters.HTTPAdapter object at 0x7f5c8446a750>
request = <PreparedRequest [GET]>, stream = False
timeout = Timeout(connect=None, read=None, total=None), verify = False
cert = None, proxies = OrderedDict()

    def send(
        self, request, stream=False, timeout=None, verify=True, cert=None, 
proxies=None
    ):
        """Sends PreparedRequest object. Returns Response object.
    
        :param request: The :class:`PreparedRequest <PreparedRequest>` being 
sent.
        :param stream: (optional) Whether to stream the request content.
        :param timeout: (optional) How long to wait for the server to send
            data before giving up, as a float, or a :ref:`(connect timeout,
            read timeout) <timeouts>` tuple.
        :type timeout: float or tuple or urllib3 Timeout object
        :param verify: (optional) Either a boolean, in which case it controls 
whether
            we verify the server's TLS certificate, or a string, in which case 
it
            must be a path to a CA bundle to use
        :param cert: (optional) Any user-provided SSL certificate to be trusted.
        :param proxies: (optional) The proxies dictionary to apply to the 
request.
        :rtype: requests.Response
        """
    
        try:
            conn = self.get_connection_with_tls_context(
                request, verify, proxies=proxies, cert=cert
            )
        except LocationValueError as e:
            raise InvalidURL(e, request=request)
    
        self.cert_verify(conn, request.url, verify, cert)
        url = self.request_url(request, proxies)
        self.add_headers(
            request,
            stream=stream,
            timeout=timeout,
            verify=verify,
            cert=cert,
            proxies=proxies,
        )
    
        chunked = not (request.body is None or "Content-Length" in 
request.headers)
    
        if isinstance(timeout, tuple):
            try:
                connect, read = timeout
                timeout = TimeoutSauce(connect=connect, read=read)
            except ValueError:
                raise ValueError(
                    f"Invalid timeout {timeout}. Pass a (connect, read) timeout 
tuple, "
                    f"or a single float to set both timeouts to the same value."
                )
        elif isinstance(timeout, TimeoutSauce):
            pass
        else:
            timeout = TimeoutSauce(connect=timeout, read=timeout)
    
        try:
            resp = conn.urlopen(
                method=request.method,
                url=url,
                body=request.body,
                headers=request.headers,
                redirect=False,
                assert_same_host=False,
                preload_content=False,
                decode_content=False,
                retries=self.max_retries,
                timeout=timeout,
                chunked=chunked,
            )
    
        except (ProtocolError, OSError) as err:
            raise ConnectionError(err, request=request)
    
        except MaxRetryError as e:
            if isinstance(e.reason, ConnectTimeoutError):
                # TODO: Remove this in 3.0.0: see #2811
                if not isinstance(e.reason, NewConnectionError):
                    raise ConnectTimeout(e, request=request)
    
            if isinstance(e.reason, ResponseError):
                raise RetryError(e, request=request)
    
            if isinstance(e.reason, _ProxyError):
                raise ProxyError(e, request=request)
    
            if isinstance(e.reason, _SSLError):
                # This branch is for urllib3 v1.22 and later.
                raise SSLError(e, request=request)
    
>           raise ConnectionError(e, request=request)
E           requests.exceptions.ConnectionError: 
HTTPSConnectionPool(host='localhost', port=40953): Max retries exceeded with 
url: / (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection 
object at 0x7f5c845c6850>: Failed to establish a new connection: [Errno 111] 
Connection refused'))

/usr/lib/python3/dist-packages/requests/adapters.py:700: ConnectionError
----------------------------- Captured stdout call -----------------------------
running -m, servefile with args ['--ssl', 
'/tmp/pytest-of-buildd/pytest-0/test_https_big_download0/testfile', '-p', 
'40953']
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
Calling get on https://localhost:40953/ with {'verify': False}
----------------------------- Captured stderr call -----------------------------
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File 
"/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_servefile/build/servefile/__main__.py",
 line 1, in <module>
    from . import servefile
  File 
"/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_servefile/build/servefile/servefile.py",
 line 49, in <module>
    import cgi
ModuleNotFoundError: No module named 'cgi'
_____________________________ test_abort_download ______________________________

run_servefile = <function run_servefile.<locals>._run_servefile at 
0x7f5c84442340>
datadir = <function datadir.<locals>._datadir at 0x7f5c84442fc0>

    def test_abort_download(run_servefile, datadir):
        data = "x" * (10 * 1024 ** 2)
        p = datadir({'testfile': data}) / 'testfile'
        env = os.environ.copy()
        env['PYTHONUNBUFFERED'] = '1'
        proc = run_servefile(str(p), stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT, env=env)
    
        # provoke a connection abort
        # hopefully the buffers will not fill up with all of the 10mb
        sock = socket.socket(socket.AF_INET)
>       _retry_while(connrefused_exc, sock.connect)(("localhost", 
> SERVEFILE_DEFAULT_PORT))

tests/test_servefile.py:450: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

args = (('localhost', 40953),), kwargs = {}, timeout_after = 1734196301.7870321

    def wrapped(*args, **kwargs):
        timeout_after = now() + timeout
        while True:
            try:
>               return function(*args, **kwargs)
E               ConnectionRefusedError: [Errno 111] Connection refused

tests/test_servefile.py:127: ConnectionRefusedError
----------------------------- Captured stdout call -----------------------------
running -m, servefile with args 
['/tmp/pytest-of-buildd/pytest-0/test_abort_download0/testfile', '-p', '40953']
=========================== short test summary info ============================
FAILED tests/test_servefile.py::test_version - AssertionError: assert 'Traceb...
FAILED tests/test_servefile.py::test_version_standalone - AssertionError: ass...
FAILED tests/test_servefile.py::test_correct_headers - requests.exceptions.Co...
FAILED tests/test_servefile.py::test_redirect_and_download - requests.excepti...
FAILED tests/test_servefile.py::test_redirect_and_download_with_umlaut - requ...
FAILED tests/test_servefile.py::test_specify_port - requests.exceptions.Conne...
FAILED tests/test_servefile.py::test_ipv4_only - requests.exceptions.Connecti...
FAILED tests/test_servefile.py::test_big_download - requests.exceptions.Conne...
FAILED tests/test_servefile.py::test_authentication - requests.exceptions.Con...
FAILED tests/test_servefile.py::test_serve_directory - requests.exceptions.Co...
FAILED tests/test_servefile.py::test_serve_relative_directory - requests.exce...
FAILED tests/test_servefile.py::test_upload - requests.exceptions.ConnectionE...
FAILED tests/test_servefile.py::test_upload_size_limit - requests.exceptions....
FAILED tests/test_servefile.py::test_upload_large_file - requests.exceptions....
FAILED tests/test_servefile.py::test_tar_mode - requests.exceptions.Connectio...
FAILED tests/test_servefile.py::test_tar_compression - requests.exceptions.Co...
FAILED tests/test_servefile.py::test_https - requests.exceptions.ConnectionEr...
FAILED tests/test_servefile.py::test_https_big_download - requests.exceptions...
FAILED tests/test_servefile.py::test_abort_download - ConnectionRefusedError:...
============================= 19 failed in 35.81s ==============================
E: pybuild pybuild:389: test: plugin distutils failed with: exit code=1: cd 
/<<PKGBUILDDIR>>/.pybuild/cpython3_3.13_servefile/build; python3.13 -m pytest 
tests
I: pybuild base:311: cd 
/<<PKGBUILDDIR>>/.pybuild/cpython3_3.12_servefile/build; python3.12 -m pytest 
tests
============================= test session starts ==============================
platform linux -- Python 3.12.8, pytest-8.3.4, pluggy-1.5.0
rootdir: /<<PKGBUILDDIR>>
plugins: typeguard-4.4.1
collected 19 items

tests/test_servefile.py ...................                              [100%]

============================== 19 passed in 2.51s ==============================
dh_auto_test: error: pybuild --test -i python{version} -p "3.13 3.12" 
--test-pytest returned exit code 13
make[1]: *** [debian/rules:11: override_dh_auto_test] Error 25
make[1]: Leaving directory '/<<PKGBUILDDIR>>'
make: *** [debian/rules:8: binary] Error 2
dpkg-buildpackage: error: debian/rules binary subprocess returned exit status 2
--------------------------------------------------------------------------------

The above is just how the build ends and not necessarily the most relevant part.
If required, the full build log is available here:

https://people.debian.org/~sanvila/build-logs/202412/

About the archive rebuild: The build was made on virtual machines from AWS,
using sbuild and a reduced chroot with only build-essential packages.

If you could not reproduce the bug please contact me privately, as I
am willing to provide ssh access to a virtual machine where the bug is
fully reproducible.

If this is really a bug in one of the build-depends, please use
reassign and affects, so that this is still visible in the BTS web
page for this package.

Thanks.

Reply via email to