python-lsp / pylsp-mypy

Mypy plugin for the Python LSP Server.
MIT License
118 stars 35 forks source link

Unit test failure if `~/.config/mypy/config` exists #59

Open Wuestengecko opened 1 year ago

Wuestengecko commented 1 year ago

If the ~/.config/mypy/config file exists, the unit test test/test_plugin.py::test_option_overrides_dmypy fails. It no longer fails once I remove the file.

As you can see in the log below, it inserts the unexpected arguments '--config-file', '/home/wuestengecko/.config/mypy/config' into the dmypy subprocess call:

============================= test session starts ==============================
platform linux -- Python 3.10.10, pytest-7.2.2, pluggy-1.0.0
rootdir: /tmp/tmp.jLBPCZcK93/pylsp-mypy
plugins: typeguard-2.13.3, anyio-3.6.2
collected 1 item

test/test_plugin.py F                                                    [100%]

=================================== FAILURES ===================================
_________________________ test_option_overrides_dmypy __________________________

last_diagnostics_monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f5a13a048e0>
workspace = <pylsp.workspace.Workspace object at 0x7f5a13a04d30>

    def test_option_overrides_dmypy(last_diagnostics_monkeypatch, workspace):
        overrides = ["--python-executable", "/tmp/fake", True]
        last_diagnostics_monkeypatch.setattr(
            FakeConfig,
            "plugin_settings",
            lambda _, p: {
                "overrides": overrides,
                "dmypy": True,
                "live_mode": False,
            }
            if p == "pylsp_mypy"
            else {},
        )

        m = Mock(wraps=lambda a, **_: Mock(returncode=0, **{"stdout": ""}))
        last_diagnostics_monkeypatch.setattr(plugin.subprocess, "run", m)

        document = Document(DOC_URI, workspace, DOC_TYPE_ERR)

        config = FakeConfig(uris.to_fs_path(workspace.root_uri))
        plugin.pylsp_settings(config)

        plugin.pylsp_lint(
            config=config,
            workspace=workspace,
            document=document,
            is_saved=False,
        )
        expected = [
            "dmypy",
            "--status-file",
            ".dmypy.json",
            "run",
            "--",
            "--python-executable",
            "/tmp/fake",
            "--show-column-numbers",
            document.path,
        ]
>       m.assert_called_with(expected, capture_output=True, **windows_flag, encoding="utf-8")

test/test_plugin.py:232: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <Mock id='140024840053536'>
args = (['dmypy', '--status-file', '.dmypy.json', 'run', '--', '--python-executable', ...],)
kwargs = {'capture_output': True, 'encoding': 'utf-8'}
expected = call(['dmypy', '--status-file', '.dmypy.json', 'run', '--', '--python-executable', '/tmp/fake', '--show-column-numbers', '//tmp/tmp.jLBPCZcK93/pylsp-mypy/test/test_plugin.py'], capture_output=True, encoding='utf-8')
actual = call(['dmypy', '--status-file', '.dmypy.json', 'run', '--', '--python-executable', '/tmp/fake', '--show-column-numbers...ko/.config/mypy/config', '//tmp/tmp.jLBPCZcK93/pylsp-mypy/test/test_plugin.py'], capture_output=True, encoding='utf-8')
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x7f5a12d816c0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.

        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)

        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: mock(['dmypy', '--status-file', '.dmypy.json', 'run', '--', '--python-executable', '/tmp/fake', '--show-column-numbers', '//tmp/tmp.jLBPCZcK93/pylsp-mypy/test/test_plugin.py'], capture_output=True, encoding='utf-8')
E           Actual: mock(['dmypy', '--status-file', '.dmypy.json', 'run', '--', '--python-executable', '/tmp/fake', '--show-column-numbers', '--config-file', '/home/wuestengecko/.config/mypy/config', '//tmp/tmp.jLBPCZcK93/pylsp-mypy/test/test_plugin.py'], capture_output=True, encoding='utf-8')

/usr/lib/python3.10/unittest/mock.py:929: AssertionError
=============================== warnings summary ===============================
../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:121
  /usr/lib/python3.10/site-packages/pkg_resources/__init__.py:121: DeprecationWarning: pkg_resources is deprecated as an API
    warnings.warn("pkg_resources is deprecated as an API", DeprecationWarning)

../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870
../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870
  /usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('google')`.
  Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages
    declare_namespace(pkg)

../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870
  /usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('mpl_toolkits')`.
  Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages
    declare_namespace(pkg)

../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870
../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870
  /usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('ruamel')`.
  Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages
    declare_namespace(pkg)

../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870
../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870
../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870
../../../usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870
  /usr/lib/python3.10/site-packages/pkg_resources/__init__.py:2870: DeprecationWarning: Deprecated call to `pkg_resources.declare_namespace('sphinxcontrib')`.
  Implementing implicit namespace packages (as specified in PEP 420) is preferred to `pkg_resources.declare_namespace`. See https://setuptools.pypa.io/en/latest/references/keywords.html#keyword-namespace-packages
    declare_namespace(pkg)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
FAILED test/test_plugin.py::test_option_overrides_dmypy - AssertionError: exp...
======================== 1 failed, 10 warnings in 0.39s ========================
Richardk2n commented 1 year ago

Thanks for pointing this out. This will probably happen for other configs as well. As you probably know, this failure is safe to ignore. If I find a decent way to patch the test I will. Recommendations are welcome.