TheR1D / shell_gpt

A command-line productivity tool powered by AI large language models like GPT-4, will help you accomplish your tasks faster and more efficiently.
MIT License
9.41k stars 741 forks source link

Test failure on Python 3.12 #553

Open carlsmedstad opened 5 months ago

carlsmedstad commented 5 months ago

Hey :wave:

I maintain the AUR package for shell-gpt. Arch Linux is in the process of migrating to Python 3.12, which identified the following issue in the test suite:

============================================================================================== test session starts ==============================================================================================
platform linux -- Python 3.12.2, pytest-8.1.1, pluggy-1.4.0
benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /tmp/makepkg/shell-gpt/src/shell_gpt-1.4.3
configfile: pyproject.toml
plugins: respx-0.21.0, anyio-4.3.0, typeguard-4.2.1, benchmark-4.0.0, asyncio-0.23.6, hypothesis-6.100.1, flaky-3.7.0, xdist-3.5.0, mock-3.14.0
asyncio: mode=Mode.STRICT
collected 29 items / 2 deselected / 27 selected

tests/test_code.py .......                                                                                                                                                                                [ 25%]
tests/test_default.py .........                                                                                                                                                                           [ 59%]
tests/test_roles.py .                                                                                                                                                                                     [ 62%]
tests/test_shell.py .......F..                                                                                                                                                                            [100%]

=================================================================================================== FAILURES ====================================================================================================
________________________________________________________________________________________________ test_shell_repl ________________________________________________________________________________________________

completion = <MagicMock name='completion' id='131931115547552'>, mock_system = <MagicMock name='system' id='131931115851408'>

    @patch("os.system")
    @patch("sgpt.handlers.handler.completion")
    def test_shell_repl(completion, mock_system):
        completion.side_effect = [mock_comp("ls"), mock_comp("ls | sort")]
        role = SystemRole.get(DefaultRoles.SHELL.value)
        chat_name = "_test"
        chat_path = Path(cfg.get("CHAT_CACHE_PATH")) / chat_name
        chat_path.unlink(missing_ok=True)

        args = {"--repl": chat_name, "--shell": True}
        inputs = ["__sgpt__eof__", "list folder", "sort by name", "e", "exit()"]
        result = runner.invoke(app, cmd_args(**args), input="\n".join(inputs))
        shell = os.environ.get("SHELL", "/bin/sh")
>       mock_system.called_once_with(f"{shell} -c 'ls | sort'")

tests/test_shell.py:149:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <MagicMock name='system' id='131931115851408'>, 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'?

/usr/lib/python3.12/unittest/mock.py:663: AttributeError
============================================================================================ short test summary info ============================================================================================
FAILED tests/test_shell.py::test_shell_repl - 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'?
================================================================================== 1 failed, 26 passed, 2 deselected in 1.23s ===================================================================================

This can be fixed quite easily by the following:

sed -i 's/mock_system.called_once_with/mock_system.assert_called_once_with/' tests/test_shell.py

Thanks!