Fix flake8 per-file settings, the fallback interpreter, and the undocumented flake8 settings - #985
Open
ZayanKhan-12 wants to merge 2 commits into
Open
ZayanKhan-12 wants to merge 2 commits into
ZayanKhan-12 wants to merge 2 commits into
Conversation
Two bugs in the flake8 plugin, both of which make flake8 configuration silently not apply. The document is piped to flake8 over stdin so unsaved changes are linted, but nothing told flake8 what the file is called, so it saw the name "stdin". Any setting flake8 resolves per filename then cannot match, which silently disabled per-file-ignores and exclude. Verified against flake8 3.8.4: with a setup.cfg declaring "per-file-ignores = legacy.py: E501,F401", linting that file over stdin reports both codes, and passing --stdin-display-name reports neither. The same applies to exclude. The plugin now passes the document path, and omits it for an unsaved or non-file document that has no path. Separately, when the configured executable is not on PATH the plugin fell back to running "python -m flake8". Bare "python" does not exist on a Python 3 only system, so the fallback raised as well, and because it was not guarded the user saw a FileNotFoundError naming flake8 rather than anything actionable. It now falls back to sys.executable, which is both guaranteed to exist and the interpreter that pip install python-language-server[flake8] installed flake8 into. If that also fails it logs what to do instead of raising. That second fix makes test_flake8_lint and test_flake8_unsaved pass; they fail on develop on any machine without flake8 on PATH. Refs palantir#190 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The README points at vscode-client/package.json for "the full set of supported configuration options", but the flake8 plugin added in palantir#656 was never listed there, so none of its settings were discoverable. The thread on palantir#190 is largely people guessing at setting names. Adds the nine settings the plugin actually reads, recording that it is disabled by default. Also corrects the configurationSources enum, which was wrong in both directions: it omitted flake8, which is a real source and the one the README tells people to select, and listed pyflakes, which is not one. Config sources are registered in pyls/config/config.py and only flake8 and pycodestyle exist. Refs palantir#190 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Member
|
Thanks for your interest in palantir/python-language-server, @ZayanKhan-12! Before we can accept your pull request, you need to sign our contributor license agreement - just visit https://cla.palantir.com/ and follow the instructions. Once you sign, I'll automatically update this pull request. |
ZayanKhan-12
pushed a commit
to ZayanKhan-12/python-language-server
that referenced
this pull request
Sep 16, 2026
…d-fallback Fix flake8 per-file settings, the fallback interpreter, and the undocumented flake8 settings (refs palantir#190) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Refs #190.
The headline ask on #190 — run flake8 itself, so flake8 plugins work — was resolved by @youben11's #656.
pyls/plugins/flake8_lint.pyshells out to the realflake8, soflake8-isortand friends load normally. What is left is the second half of the title, configuration, and it is genuinely broken in three ways. All three are things people in this thread hit and worked around by guesswork.1.
per-file-ignoresandexcludesilently never applyThe document is piped to flake8 over stdin so unsaved changes get linted, but nothing tells flake8 what the file is called, so it sees the name
stdin. Every setting flake8 resolves per filename then cannot match.Verified against flake8 3.8.4 with a
setup.cfgcontainingper-file-ignores = pkg/legacy.py: E501,F401:flake8 -(what pyls does today)F401andE501both reportedflake8 --stdin-display-name=pkg/legacy.py -excludebehaves the same way: a file the user excluded is still linted today, and is correctly skipped once flake8 knows its name.The plugin now passes
--stdin-display-name, and omits it when the document has no path (unsaved, or a non-file URI).To be precise about the limit of this fix: it does not change flake8's config discovery, which flake8 3.8 still does from the working directory. Passing an absolute display name from an unrelated cwd still failed to find the project config in my testing, so that is a separate problem and I have not claimed to fix it.
2. The fallback interpreter does not exist on Python 3 only systems
When the configured executable is not on
PATH, the plugin fell back topython -m flake8. Barepythondoes not exist on a modern macOS or on most current Linux distributions. That secondPopenwas not guarded, so it raised too — and the error the user saw wasFileNotFoundError: [Errno 2] No such file or directory: 'flake8', which names the wrong thing and suggests nothing.This matters more than it looks, because installing pyls and flake8 into different environments is the normal case:
pipx install python-language-serverplus a project virtualenv. The fallback exists precisely for that, and it never worked.It now falls back to
sys.executable -m flake8, which is guaranteed to exist and is the interpreter thatpip install python-language-server[flake8]put flake8 into. If that fails too it logs what to do rather than raising.This fixes two tests that currently fail on
develop:test_flake8_lintandtest_flake8_unsavedfail on any machine withoutflake8onPATH, for exactly this reason.3. None of the flake8 settings were discoverable
The README says to see
vscode-client/package.jsonfor "the full set of supported configuration options". The flake8 plugin has been in the tree since #656 and had zero entries there, which is why this thread is mostly people guessing at names — and why @horseinthesky'smax-line-lengthwas ignored whilemaxLineLengthworked.The second commit adds the nine settings the plugin actually reads, recording that it is disabled by default.
It also corrects
pyls.configurationSources, whose enum was wrong in both directions: it omittedflake8, the value the README tells people to use, and listedpyflakes, which is not a config source at all.pyls/config/config.pyregisters onlyflake8andpycodestyle, and there is nopyflakes_conf.py.Tests
Five new tests: the display name is passed with the document path; it is omitted when there is no path; the fallback uses
sys.executableand not barepython; both attempts failing logs something actionable instead of raising; and an end-to-end test running the real flake8 against a project whoseper-file-ignoresshould suppress a code.I checked they hold the line by re-breaking each fix: removing
--stdin-display-namefails 2 (including the end-to-end one), restoring the barepythonfallback fails 3 — including the two pre-existing failures, which is direct evidence that bug caused them — and always sending a display name fails the no-path test.Verification
Python 3.8 with
jedi 0.17.2, matching the CI matrix.developpytest test/test_flake8_lintandtest_flake8_unsaved, both now passingpycodestyle pyls testpyflakes pyls test_utils.py)pylint pyls testconsider-using-f-string, no new message typesThat one added message is a
.format()call, which Python 2.7 support requires; the baseline already has eleven. I fixed the one genuinely new message type I had introduced.The
package.jsonchange is insert-only apart from the single enum line — I reverted a first attempt that round-tripped the JSON and reformatted unrelated entries.Notes
I have not touched the README here. It already points at
package.json, and that pointer becomes accurate with this change; my other open PR (#984) edits the README, and I did not want the two to conflict.CLAUDE.mdlives in #982 and is not duplicated here.