Skip to content

Missing ruff executable breaks other linters#69

@chris-reeves

Description

@chris-reeves

If the executable configuration param is specified but points to an executable that does not exist then run_ruff() throws an exception and prevents other python-lsp-server linters from running. With a valid executable specified multiple lint errors are flagged from multiple linters (including ruff). With an invalid executable specified no lint errors are flagged (not even from other linters).

For example:

2023-12-22 13:21:14,431 GMT - DEBUG - pylsp_ruff.plugin - Calling ruff with args: ['--quiet', '--exit-zero', '--output-format=json', '--extension=ipynb:python', '--no-fix', '--force-exclude', '--stdin-filename=<redacted>', '--preview', '--extend-select=E,W,F', '--', '-'] on '<redacted>'' 2023-12-22 13:21:14,439 GMT - ERROR - pylsp_ruff.plugin - Can't execute ruff with given executable 'ruff'. 2023-12-22 13:21:14,440 GMT - WARNING - pylsp.config.config - Failed to load hook pylsp_lint: cannot access local variable 'p' where it is not associated with a value Traceback (most recent call last): File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pylsp/config/config.py", line 40, in _hookexec return self._inner_hookexec(hook_name, methods, kwargs, firstresult) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pluggy/_manager.py", line 457, in traced_hookexec return outcome.get_result() ^^^^^^^^^^^^^^^^^^^^ File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pluggy/_result.py", line 114, in get_result raise exc.with_traceback(exc.__traceback__) File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pluggy/_result.py", line 76, in from_call result = func() ^^^^^^ File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pluggy/_manager.py", line 454, in <lambda> lambda: oldcall(hook_name, hook_impls, caller_kwargs, firstresult) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pluggy/_callers.py", line 113, in _multicall raise exception.with_traceback(exception.__traceback__) File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pluggy/_callers.py", line 77, in _multicall res = hook_impl.function(*args) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pylsp_ruff/plugin.py", line 172, in pylsp_lint checks = run_ruff_check(document=document, settings=settings) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pylsp_ruff/plugin.py", line 442, in run_ruff_check result = run_ruff( ^^^^^^^^^ File "/<redacted>/.config/coc/extensions/@yaegassy/coc-pylsp-data/pylsp/venv/lib/python3.11/site-packages/pylsp_ruff/plugin.py", line 525, in run_ruff (stdout, stderr) = p.communicate(document_source.encode()) ^ UnboundLocalError: cannot access local variable 'p' where it is not associated with a value 

Versions:

  • python: 3.11.6
  • python-lsp-server: 1.9.0
  • python-lsp-ruff: 2.0.0

Prior to commit ea5f874a, python-lsp-ruff would silently (apart from a debug message) fall back to running ruff via the python module if the specified executable was not found. Now an error message is logged following the Popen() failure, but the code still attempts to use the pipe (which is not defined following the exception). That throws an exception which is not caught and as a result any subsequent linters aren't run (so not only do we not se

I see two options for resolving this (other than making sure the executable config param is set correctly :-p):

  • return an empty string after logging the error on line 520;
  • fall back to running ruff via the python module (similar to previous behaviour, but with the option to not even attempt to run the executable if it's not specified).

I'd suggest the second option as that will provide a better user experience. That assumes commit ea5f874a was simply intended to shortcut the attempt to call the executable if it was not set, rather than intended to remove the fallback behaviour.

This issue was discovered while investigating yaegassy/coc-pylsp#24.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions