Your message dated Tue, 16 Jun 2026 10:18:41 +0000
with message-id <[email protected]>
and subject line Bug#1084326: fixed in python-aiomodernforms 0.1.8-3
has caused the Debian Bug report #1084326,
regarding python-aiomodernforms: FTBFS: AttributeError: 'NoneType' object has 
no attribute 'prepare'
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
1084326: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1084326
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
Package: src:python-aiomodernforms
Version: 0.1.8-2
Severity: serious
Tags: ftbfs

Dear maintainer:

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

--------------------------------------------------------------------------------
[...]
 debian/rules build
make: pyversions: No such file or directory
py3versions: no X-Python3-Version in control file, using supported versions
dh build --buildsystem=pybuild --with python3
   dh_update_autotools_config -O--buildsystem=pybuild
   dh_autoreconf -O--buildsystem=pybuild
   dh_auto_configure -O--buildsystem=pybuild
   dh_auto_build -O--buildsystem=pybuild
I: pybuild plugin_pyproject:129: Building wheel for python3.12 with "build" 
module
I: pybuild base:311: python3.12 -m build --skip-dependency-check --no-isolation --wheel 
--outdir /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12
* Building wheel...
/usr/lib/python3/dist-packages/setuptools/_distutils/dist.py:261: UserWarning: 
Unknown distribution option: 'test_suite'
  warnings.warn(msg)
/<<PKGBUILDDIR>>/aiomodernforms/__version__.pyrunning bdist_wheel
running build
running build_py
creating build
creating build/lib
creating build/lib/aiomodernforms
copying aiomodernforms/exceptions.py -> build/lib/aiomodernforms
copying aiomodernforms/modernforms.py -> build/lib/aiomodernforms
copying aiomodernforms/__init__.py -> build/lib/aiomodernforms
copying aiomodernforms/const.py -> build/lib/aiomodernforms
copying aiomodernforms/models.py -> build/lib/aiomodernforms
copying aiomodernforms/__version__.py -> build/lib/aiomodernforms
running egg_info
creating aiomodernforms.egg-info
writing aiomodernforms.egg-info/PKG-INFO
writing dependency_links to aiomodernforms.egg-info/dependency_links.txt
writing requirements to aiomodernforms.egg-info/requires.txt
writing top-level names to aiomodernforms.egg-info/top_level.txt
writing manifest file 'aiomodernforms.egg-info/SOURCES.txt'
reading manifest file 'aiomodernforms.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
warning: no previously-included files matching '*.py[co]' found under directory 
'*'
adding license file 'LICENSE.md'
writing manifest file 'aiomodernforms.egg-info/SOURCES.txt'
installing to build/bdist.linux-x86_64/wheel
running install
running install_lib
creating build/bdist.linux-x86_64
creating build/bdist.linux-x86_64/wheel
creating build/bdist.linux-x86_64/wheel/aiomodernforms
copying build/lib/aiomodernforms/exceptions.py -> 
build/bdist.linux-x86_64/wheel/./aiomodernforms
copying build/lib/aiomodernforms/modernforms.py -> 
build/bdist.linux-x86_64/wheel/./aiomodernforms
copying build/lib/aiomodernforms/__init__.py -> 
build/bdist.linux-x86_64/wheel/./aiomodernforms
copying build/lib/aiomodernforms/const.py -> 
build/bdist.linux-x86_64/wheel/./aiomodernforms
copying build/lib/aiomodernforms/models.py -> 
build/bdist.linux-x86_64/wheel/./aiomodernforms
copying build/lib/aiomodernforms/__version__.py -> 
build/bdist.linux-x86_64/wheel/./aiomodernforms
running install_egg_info
Copying aiomodernforms.egg-info to 
build/bdist.linux-x86_64/wheel/./aiomodernforms-0.1.8.egg-info
running install_scripts
creating build/bdist.linux-x86_64/wheel/aiomodernforms-0.1.8.dist-info/WHEEL
creating 
'/<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/.tmp-0od3vf6_/aiomodernforms-0.1.8-py3-none-any.whl'
 and adding 'build/bdist.linux-x86_64/wheel' to it
adding 'aiomodernforms/__init__.py'
adding 'aiomodernforms/__version__.py'
adding 'aiomodernforms/const.py'
adding 'aiomodernforms/exceptions.py'
adding 'aiomodernforms/models.py'
adding 'aiomodernforms/modernforms.py'
adding 'aiomodernforms-0.1.8.dist-info/LICENSE.md'
adding 'aiomodernforms-0.1.8.dist-info/METADATA'
adding 'aiomodernforms-0.1.8.dist-info/WHEEL'
adding 'aiomodernforms-0.1.8.dist-info/top_level.txt'
adding 'aiomodernforms-0.1.8.dist-info/RECORD'
removing build/bdist.linux-x86_64/wheel
Successfully built aiomodernforms-0.1.8-py3-none-any.whl
I: pybuild plugin_pyproject:144: Unpacking wheel built for python3.12 with 
"installer" module
   dh_auto_test -O--buildsystem=pybuild
I: pybuild base:311: cd /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/build; 
python3.12 -m pytest -v
/usr/lib/python3/dist-packages/pytest_asyncio/plugin.py:208: PytestDeprecationWarning: 
The configuration option "asyncio_default_fixture_loop_scope" is unset.
The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future versions of pytest-asyncio will 
default the loop scope for asynchronous fixtures to function scope. Set the default fixture loop scope explicitly in order to 
avoid unexpected behavior in the future. Valid fixture loop scopes are: "function", "class", 
"module", "package", "session"

  warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET))
============================= test session starts ==============================
platform linux -- Python 3.12.7, pytest-8.3.3, pluggy-1.5.0 -- 
/usr/bin/python3.12
cachedir: .pytest_cache
rootdir: /<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/build
configfile: pytest.ini
testpaths: tests
plugins: typeguard-4.3.0, asyncio-0.24.0a1, aresponses-3.0.0, cov-5.0.0
asyncio: mode=Mode.STRICT, default_loop_scope=None
collecting ... collected 19 items

tests/test_aiomodernforms.py::test_basic_status PASSED                   [  5%]
tests/test_aiomodernforms.py::test_command PASSED                        [ 10%]
tests/test_aiomodernforms.py::test_light PASSED                          [ 15%]
tests/test_aiomodernforms.py::test_light_sleep_datetime PASSED           [ 21%]
tests/test_aiomodernforms.py::test_light_sleep_int PASSED                [ 26%]
tests/test_aiomodernforms.py::test_light_sleep_clear PASSED              [ 31%]
tests/test_aiomodernforms.py::test_fan PASSED                            [ 36%]
tests/test_aiomodernforms.py::test_fan_sleep_datetime PASSED             [ 42%]
tests/test_aiomodernforms.py::test_fan_sleep_int PASSED                  [ 47%]
tests/test_aiomodernforms.py::test_fan_sleep_clear PASSED                [ 52%]
tests/test_aiomodernforms.py::test_away PASSED                           [ 57%]
tests/test_aiomodernforms.py::test_adaptive_learning PASSED              [ 63%]
tests/test_aiomodernforms.py::test_invalid_setting PASSED                [ 68%]
tests/test_aiomodernforms.py::test_connection_error FAILED               [ 73%]
tests/test_aiomodernforms.py::test_server_error PASSED                   [ 78%]
tests/test_aiomodernforms.py::test_reboot PASSED                         [ 84%]
tests/test_aiomodernforms.py::test_status_not_initialized_response PASSED [ 89%]
tests/test_aiomodernforms.py::test_info_not_initialized_response PASSED  [ 94%]
tests/test_aiomodernforms.py::test_empty_response FAILED                 [100%]

=================================== FAILURES ===================================
____________________________ test_connection_error _____________________________

aresponses = <aresponses.main.ResponsesMockServer object at 0x7ff98a7ac560>

    @pytest.mark.asyncio
    async def test_connection_error(aresponses):
        """Test to make validate proper connection error handling."""
        aresponses.add("fan.local", "/mf", "POST", response=basic_info)
        with pytest.raises(aiomodernforms.ModernFormsConnectionError):
            async with aiomodernforms.ModernFormsDevice("fan.local") as device:
              await device.update()

tests/test_aiomodernforms.py:502:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/backoff/_async.py:151: in retry
    ret = await target(*args, **kwargs)
aiomodernforms/modernforms.py:97: in update
    state_data = await self._request()
/usr/lib/python3/dist-packages/backoff/_async.py:151: in retry
    ret = await target(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <aiomodernforms.modernforms.ModernFormsDevice object at 0x7ff98a7d68d0>
commands = {'queryDynamicShadowData': True}

    @backoff.on_exception(
        backoff.expo, ModernFormsConnectionError, max_tries=3, logger=None
    )
    async def _request(self, commands: Optional[dict] = None) -> Any:
        """Handle a request to a Modern Forms Fan device."""
        scheme = "https" if self._tls else "http"
        url = URL.build(
            scheme=scheme,
            host=self._host,
            port=self._port,
            path=self._base_path,
        )
auth = None
        if self._username and self._password:
            auth = aiohttp.BasicAuth(self._username, self._password)
headers = {
            "User-Agent": self._user_agent,
            "Accept": "application/json",
        }
if self._session is None:
            self._session = aiohttp.ClientSession()
            self._close_session = True
# If updating the state, always request for a state response
        if commands is None:
            commands = {COMMAND_QUERY_STATUS: True}
try:
            with async_timeout.timeout(self._request_timeout):
                response = await self._session.request(
                    "POST",
                    url,
                    auth=auth,
                    json=commands,
                    headers=headers,
                    ssl=self._verify_ssl,
                )
        except asyncio.TimeoutError as exception:
            raise ModernFormsConnectionTimeoutError(
                "Timeout occurred while connecting to Modern Forms device at"
                + f" {self._host}"
            ) from exception
        except (aiohttp.ClientError, socket.gaierror) as exception:
            raise ModernFormsConnectionError(
                "Error occurred while communicating with Modern Forms device at"
                + f" {self._host}"
            ) from exception
content_type = response.headers.get("Content-Type", "")
        if (response.status // 100) in [4, 5]:
            contents = await response.read()
            response.close()
if content_type == "application/json":
                raise ModernFormsError(
                    response.status, json.loads(contents.decode("utf8"))
                )
          raise ModernFormsError(
                response.status, {"message": contents.decode("utf8")}
            )
E           aiomodernforms.exceptions.ModernFormsError: (500, {'message': '500: 
Internal Server Error'})

aiomodernforms/modernforms.py:168: ModernFormsError
------------------------------ Captured log call -------------------------------
ERROR    aiohttp.server:web_protocol.py:448 Missing return statement on request 
handler
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/aiohttp/web_protocol.py", line 653, in 
finish_response
    prepare_meth = resp.prepare
                   ^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'prepare'
_____________________________ test_empty_response ______________________________

aresponses = <aresponses.main.ResponsesMockServer object at 0x7ff98a7d8470>

    @pytest.mark.asyncio
    async def test_empty_response(aresponses):
        """Test for an Empty Response."""
        aresponses.add("fan.local", "/mf", "POST", response=basic_info)
async def send_empty_state(request):
            await request.json()
            return aresponses.Response(
                status=200,
                content_type="application/json",
                text="{}",
            )
aresponses.add("fan.local", "/mf", "POST", response=send_empty_state)
        with pytest.raises(ModernFormsConnectionError):
            async with aiomodernforms.ModernFormsDevice("fan.local") as device:
              await device.update()

tests/test_aiomodernforms.py:568:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3/dist-packages/backoff/_async.py:151: in retry
    ret = await target(*args, **kwargs)
aiomodernforms/modernforms.py:96: in update
    info_data = await self._request({COMMAND_QUERY_STATIC_DATA: True})
/usr/lib/python3/dist-packages/backoff/_async.py:151: in retry
    ret = await target(*args, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <aiomodernforms.modernforms.ModernFormsDevice object at 0x7ff98a7d9820>
commands = {'queryStaticShadowData': True}

    @backoff.on_exception(
        backoff.expo, ModernFormsConnectionError, max_tries=3, logger=None
    )
    async def _request(self, commands: Optional[dict] = None) -> Any:
        """Handle a request to a Modern Forms Fan device."""
        scheme = "https" if self._tls else "http"
        url = URL.build(
            scheme=scheme,
            host=self._host,
            port=self._port,
            path=self._base_path,
        )
auth = None
        if self._username and self._password:
            auth = aiohttp.BasicAuth(self._username, self._password)
headers = {
            "User-Agent": self._user_agent,
            "Accept": "application/json",
        }
if self._session is None:
            self._session = aiohttp.ClientSession()
            self._close_session = True
# If updating the state, always request for a state response
        if commands is None:
            commands = {COMMAND_QUERY_STATUS: True}
try:
            with async_timeout.timeout(self._request_timeout):
                response = await self._session.request(
                    "POST",
                    url,
                    auth=auth,
                    json=commands,
                    headers=headers,
                    ssl=self._verify_ssl,
                )
        except asyncio.TimeoutError as exception:
            raise ModernFormsConnectionTimeoutError(
                "Timeout occurred while connecting to Modern Forms device at"
                + f" {self._host}"
            ) from exception
        except (aiohttp.ClientError, socket.gaierror) as exception:
            raise ModernFormsConnectionError(
                "Error occurred while communicating with Modern Forms device at"
                + f" {self._host}"
            ) from exception
content_type = response.headers.get("Content-Type", "")
        if (response.status // 100) in [4, 5]:
            contents = await response.read()
            response.close()
if content_type == "application/json":
                raise ModernFormsError(
                    response.status, json.loads(contents.decode("utf8"))
                )
          raise ModernFormsError(
                response.status, {"message": contents.decode("utf8")}
            )
E           aiomodernforms.exceptions.ModernFormsError: (500, {'message': '500: 
Internal Server Error'})

aiomodernforms/modernforms.py:168: ModernFormsError
------------------------------ Captured log call -------------------------------
ERROR    aiohttp.server:web_protocol.py:448 Missing return statement on request 
handler
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/aiohttp/web_protocol.py", line 653, in 
finish_response
    prepare_meth = resp.prepare
                   ^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'prepare'
=============================== warnings summary ===============================
tests/test_aiomodernforms.py: 47 warnings
  
/<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/build/aiomodernforms/modernforms.py:139:
 DeprecationWarning: with timeout() is deprecated, use async with timeout() instead
    with async_timeout.timeout(self._request_timeout):

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED tests/test_aiomodernforms.py::test_connection_error - aiomodernforms.e...
FAILED tests/test_aiomodernforms.py::test_empty_response - aiomodernforms.exc...
================== 2 failed, 17 passed, 47 warnings in 0.20s ===================
E: pybuild pybuild:389: test: plugin pyproject failed with: exit code=1: cd 
/<<PKGBUILDDIR>>/.pybuild/cpython3_3.12/build; python3.12 -m pytest -v
dh_auto_test: error: pybuild --test --test-pytest -i python{version} -p 3.12 
returned exit code 13
make: *** [debian/rules:9: build] Error 25
dpkg-buildpackage: error: debian/rules build 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/202410/

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.

--- End Message ---
--- Begin Message ---
Source: python-aiomodernforms
Source-Version: 0.1.8-3
Done: Edward Betts <[email protected]>

We believe that the bug you reported is fixed in the latest version of
python-aiomodernforms, which is due to be installed in the Debian FTP archive.

A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to [email protected],
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Edward Betts <[email protected]> (supplier of updated python-aiomodernforms 
package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [email protected])


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Format: 1.8
Date: Tue, 16 Jun 2026 10:51:29 +0100
Source: python-aiomodernforms
Architecture: source
Version: 0.1.8-3
Distribution: unstable
Urgency: medium
Maintainer: Home Assistant Team <[email protected]>
Changed-By: Edward Betts <[email protected]>
Closes: 1084326
Changes:
 python-aiomodernforms (0.1.8-3) unstable; urgency=medium
 .
   * Team upload.
 .
   [ Edward Betts ]
   * Fix FTBFS with newer aresponses by avoiding exhausted mock routes in
     tests.
   * Add <!nocheck> to test dependencies.
   * Update debian/watch to format version 5.
   * Update Standards-Version.
   * Switch to autopkgtest-pkg-pybuild.
 .
   [ Tianyu Chen ]
   * Replace async-timeout with asyncio.timeout. (Closes: #1084326)
   * Add debian/salsa-ci.yml.
Checksums-Sha1:
 2b610ec633b968163a525e72c4f2ec73a43583d3 2484 python-aiomodernforms_0.1.8-3.dsc
 2b33496ab089f9f5ac438eda50dd9cb0c63f2d3d 3852 
python-aiomodernforms_0.1.8-3.debian.tar.xz
 7033a8e8bba73168623bb877e8f3900ced5c6c11 7268 
python-aiomodernforms_0.1.8-3_source.buildinfo
Checksums-Sha256:
 d74c145313b05aa316f05b123cd08452846388e54622b41a6b3ee84af70e5aac 2484 
python-aiomodernforms_0.1.8-3.dsc
 778c6cc48219952ab13e4f09d87061964770e0c965cf1e1be0f7dbd05a1ce0b1 3852 
python-aiomodernforms_0.1.8-3.debian.tar.xz
 71b09da0f033344c44cf3159e73a9b6ee0778d7ee555a992625020644fdca53b 7268 
python-aiomodernforms_0.1.8-3_source.buildinfo
Files:
 199a96a623afad68a57610cbb325e320 2484 python optional 
python-aiomodernforms_0.1.8-3.dsc
 9cdd75b593e89d4f85b33ef95091b3bf 3852 python optional 
python-aiomodernforms_0.1.8-3.debian.tar.xz
 6c57eed64587e802a3ad26d589423a6c 7268 python optional 
python-aiomodernforms_0.1.8-3_source.buildinfo

-----BEGIN PGP SIGNATURE-----

iQIzBAEBCgAdFiEE+4rPp4xyYInDitAmlgWhCYxjuSoFAmoxHxcACgkQlgWhCYxj
uSrnlA//aSEYjgCzCQEeinn9m278ehNhb2hZzir0nqLJHx0TJ2uH0URiHyTSqTVt
eQc79p/vvxOpR4FLAFUflyPPnY3hDvB8gSTtgMMTEUTUl/th1oXNtEDvcu/ykfOI
dgecAG86hesDMu4DBQTZvWhnmYGX6uqtsz1Hrl2+q1+aVlq0PcBT3q42iK/EpvZ2
AXKNq6cQ4KgwKL2BeUitYQAyBbobljPonVY9jsWAM8kZdV/nGn/EOlr7U+lffK1e
k57dHiISvTxP4lmV0VJ0ch24YNOXCT5NN2WAEsDh3u1SSWTUMReQzzlFxmQXnlEn
08w0V1CLAz2OZVkvDE9B/ROYJ8UkRULTDqFaAu2I/xHasclxpxhRSWaVApjoAhJV
mNu1CuMGvwlXGDa+JzCGT5BTmkLtuV97h2kVPGfXjCMHt7HYzV6jzKZr9FGcxg+i
d0ADqf96SrbIRydqQWJQNnmAKBM5GYDo54D6DsK2QMEBwAXFqbLXuqQOUAe4WKFg
jNcKfUjDQwfXt8mdOhbW1O8S24nEN+IYn5Q8QvXJuS4UWr9E+2h5O4g7QINhRyrL
O3HTu9GtfKeKmGX7y15VFeF3v1FEIkttCSTMyHS9m15900xG6JKe+929jYPAq44o
+Ri/MAj3oyWgpuhmSFOXjek8eHbZWa3waZuVP68bSDXI2qfFYqs=
=S+iw
-----END PGP SIGNATURE-----

Attachment: pgpJxMvYG1Hnz.pgp
Description: PGP signature


--- End Message ---

Reply via email to