Skip to content

Conversation

@ghpzin
Copy link

@ghpzin ghpzin commented Aug 10, 2024

Fixes incorrect use of assert with mock object that became error on python 3.12:
python/cpython#100690

Error while running tests before this fix:
============================= test session starts ==============================
platform linux -- Python 3.12.4, pytest-8.2.2, pluggy-1.5.0
rootdir: /build/stm32loader-0.7.1
configfile: pyproject.toml
collected 49 items                                                             

tests/unit/test_arguments.py .....                                       [ 10%]
tests/unit/test_bootloader.py ..............................FFF......... [ 95%]
.                                                                        [ 97%]
tests/unit/test_hexfile.py .                                             [100%]

=================================== FAILURES ===================================
__________ test_get_uid_for_known_family_reads_at_correct_address[F1] __________

connection = <MagicMock id='140737318300720'>, family = 'F1'

    @pytest.mark.parametrize(
        "family", ["F1", "F3", "F7"],
    )
    def test_get_uid_for_known_family_reads_at_correct_address(connection, family):
        bootloader = Stm32Bootloader(connection, device_family=family)
        bootloader.read_memory = MagicMock()
        bootloader.get_uid()
        uid_address = bootloader.UID_ADDRESS[family]
>       assert bootloader.read_memory.called_once_with(uid_address)

tests/unit/test_bootloader.py:216: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MagicMock id='140737318289632'>, name = 'called_once_with'

    def __getattr__(self, name):
        if name in {'_mock_methods', '_mock_unsafe'}:
            raise AttributeError(name)
        elif self._mock_methods is not None:
            if name not in self._mock_methods or name in _all_magics:
                raise AttributeError("Mock object has no attribute %r" % name)
        elif _is_magic(name):
            raise AttributeError(name)
        if not self._mock_unsafe and (not self._mock_methods or name not in self._mock_methods):
            if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')) or name in _ATTRIB_DENY_LIST:
>               raise AttributeError(
                    f"{name!r} is not a valid assertion. Use a spec "
                    f"for the mock if {name!r} is meant to be an attribute.")
E               AttributeError: 'called_once_with' is not a valid assertion. Use a spec for the mock if 'called_once_with' is meant to be an attribute.. Did you mean: 'assert_called_once_with'?

/nix/store/l014xp1qxdl6gim3zc0jv3mpxhbp346s-python3-3.12.4/lib/python3.12/unittest/mock.py:663: AttributeError
__________ test_get_uid_for_known_family_reads_at_correct_address[F3] __________

connection = <MagicMock id='140737324790560'>, family = 'F3'

    @pytest.mark.parametrize(
        "family", ["F1", "F3", "F7"],
    )
    def test_get_uid_for_known_family_reads_at_correct_address(connection, family):
        bootloader = Stm32Bootloader(connection, device_family=family)
        bootloader.read_memory = MagicMock()
        bootloader.get_uid()
        uid_address = bootloader.UID_ADDRESS[family]
>       assert bootloader.read_memory.called_once_with(uid_address)

tests/unit/test_bootloader.py:216: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MagicMock id='140737318384608'>, name = 'called_once_with'

    def __getattr__(self, name):
        if name in {'_mock_methods', '_mock_unsafe'}:
            raise AttributeError(name)
        elif self._mock_methods is not None:
            if name not in self._mock_methods or name in _all_magics:
                raise AttributeError("Mock object has no attribute %r" % name)
        elif _is_magic(name):
            raise AttributeError(name)
        if not self._mock_unsafe and (not self._mock_methods or name not in self._mock_methods):
            if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')) or name in _ATTRIB_DENY_LIST:
>               raise AttributeError(
                    f"{name!r} is not a valid assertion. Use a spec "
                    f"for the mock if {name!r} is meant to be an attribute.")
E               AttributeError: 'called_once_with' is not a valid assertion. Use a spec for the mock if 'called_once_with' is meant to be an attribute.. Did you mean: 'assert_called_once_with'?

/nix/store/l014xp1qxdl6gim3zc0jv3mpxhbp346s-python3-3.12.4/lib/python3.12/unittest/mock.py:663: AttributeError
__________ test_get_uid_for_known_family_reads_at_correct_address[F7] __________

connection = <MagicMock id='140737318373664'>, family = 'F7'

    @pytest.mark.parametrize(
        "family", ["F1", "F3", "F7"],
    )
    def test_get_uid_for_known_family_reads_at_correct_address(connection, family):
        bootloader = Stm32Bootloader(connection, device_family=family)
        bootloader.read_memory = MagicMock()
        bootloader.get_uid()
        uid_address = bootloader.UID_ADDRESS[family]
>       assert bootloader.read_memory.called_once_with(uid_address)

tests/unit/test_bootloader.py:216: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <MagicMock id='140737318299712'>, name = 'called_once_with'

    def __getattr__(self, name):
        if name in {'_mock_methods', '_mock_unsafe'}:
            raise AttributeError(name)
        elif self._mock_methods is not None:
            if name not in self._mock_methods or name in _all_magics:
                raise AttributeError("Mock object has no attribute %r" % name)
        elif _is_magic(name):
            raise AttributeError(name)
        if not self._mock_unsafe and (not self._mock_methods or name not in self._mock_methods):
            if name.startswith(('assert', 'assret', 'asert', 'aseert', 'assrt')) or name in _ATTRIB_DENY_LIST:
>               raise AttributeError(
                    f"{name!r} is not a valid assertion. Use a spec "
                    f"for the mock if {name!r} is meant to be an attribute.")
E               AttributeError: 'called_once_with' is not a valid assertion. Use a spec for the mock if 'called_once_with' is meant to be an attribute.. Did you mean: 'assert_called_once_with'?

/nix/store/l014xp1qxdl6gim3zc0jv3mpxhbp346s-python3-3.12.4/lib/python3.12/unittest/mock.py:663: AttributeError
=========================== short test summary info ============================
FAILED tests/unit/test_bootloader.py::test_get_uid_for_known_family_reads_at_correct_address[F1] - AttributeError: 'called_once_with' is not a valid assertion. Use a spec for...
FAILED tests/unit/test_bootloader.py::test_get_uid_for_known_family_reads_at_correct_address[F3] - AttributeError: 'called_once_with' is not a valid assertion. Use a spec for...
FAILED tests/unit/test_bootloader.py::test_get_uid_for_known_family_reads_at_correct_address[F7] - AttributeError: 'called_once_with' is not a valid assertion. Use a spec for...
========================= 3 failed, 46 passed in 0.88s =========================

Second arg (12) seems to come from inside get_uid, which I assume is the one that was tested with this mock:

uid = self.read_memory(uid_address, 12)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant