vscode-python: Setting `python.sortImports.path` to `isort` or setting it to a relative path does not work from within virtual environment

Error: Either spawn isort ENOENT" is thrown or isort hangs indefinitely.

Workspace Settings

"python.sortImports.path": "isort",

Using Pipenv, I can do this in the VS Code terminal:

$ which isort
/home/username/project/.venv/bin/isort

If I reload the VS Code window with these settings the Python extension gives an error that says ``spawn isort ENOENT` indicating it cannot find isort.

What am I missing to use a custom isort? In https://github.com/microsoft/vscode-python/issues/6369 I understood there is an inner version, but since users of a project can use different editors it’s better to point out the specific version that we install with pipenv.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 22
  • Comments: 50 (3 by maintainers)

Most upvoted comments

but what if you use e.g. conda or poetry without in-project venvs?

You can use the full paths in those cases

I’m facing an issue with this workaround as well. It appears that when simply using the full path to the binary, isort runs outside of the virtual env in which it was installed, and as such it cannot identify which installed modules from within the env are 3rd party and sorts them improperly. I now have pylint throwing warnings that 3d party libraries aren’t preceding local packages as they should.

When simply calling isort . from the integrated terminal with the env activated it works as it should tho.

I think I found out what the issue is:

The extension seems to use an old version of isort since that version still is just a .py script that is passed to the interpreter. but setting python.sortImports.path to isort loads a newer version which is called directly (isort instead of python isort.py or whatever the script’s name was).

This results in the extension passing the arguments after a single dash python isort.py - --diff, while the isort binary (let’s call it a binary from now on for simplicity) doesn’t need the single dash and gets confused by it (it just hangs indefintiely expecting a stream).

Another issue is that the allowed arguments are wildly different: I compared the help text from isort 5.9.3 and whatever version the extension has built in and the allowed argument list is different, and the arguments for the same things differ between the 2 versions. (for instance a lot of the verbose arguments (--max-line-length instead of -l) are not available in the builtin version.

For a fix I suggest either updating the version that the extension has built-in or detecting whether the path set in python.sortImports.path is a python file or a “binary” and remove the single dash accordingly.

I am able to confirm this is an issue from within virtual environment.

Does the vscode team hear about these bug reports?

Yes we do. Actually the entire team sees every bug report (we triage as a team in our stand-up).

It’s a bit odd to just let this things linger for several years.

Not when you have 262 bugs to deal with on top of large amounts of technical debt to clear out. And this is the 8th most requested bug to fix, so it isn’t at the top of the list. So I expect we will get to it eventually, but we have other stuff to work through first.

We can try to mention @brettcannon or @karrtikr as it’s still really annoying and prevent sharing a proper VSCode config with colleagues.

One thing to know is we are in the process of breaking out tool support into their own extensions, and that includes isort. We are putting the tools behind LSP for performance, but it also gives us the chance to rewrite the code from scratch. Based on how we have been structuring things, I suspect that will fix this issue implicitly.

Is there any way I can help with some contributions?

Sure! You can check out https://github.com/microsoft/vscode-python/wiki/Submitting-a-pull-request and the wiki for contributing. Otherwise you can wait for the new extension and give it a try when we announce it.

Using full path works! This works as well "python.sortImports.path": "${workspaceFolder}/.venv/bin/isort"

Question is then, is it a bug that just "python.sortImports.path": "isort" does not work?

I see. As a workaround try using the full path instead. "python.sortImports.path": "/home/username/project/.venv/bin/isort",

Let me know if that works. Also can you please paste settings.json.

So if anyone’s interested in a “sharable” settings.json file, the following worked for me:

"python.sortImports.path": "${env.HOME}/.virtualenvs/my-proj/bin/isort

@karrtikr Not to steal @thernstig’s thunder, I have the same problem and ran isort from the cli — it works as expected.

The ${workspaceFolder}/.venv/bin/isort solution also worked for me too.

@smitthakkar1 that does not work if users have different locations for the virtual env

@thernstig we are actually planning to go through the repo to clean up all the linter and formatter issues once we dropped built-in support, but thanks to the nudge I’ve gone ahead and close this now.

@thernstig

Why is it that this extension does not use the default isort found in the env, but instead requires "python.sortImports.path" to be set?

FYI, I asked a similar question just yesterday at https://github.com/microsoft/vscode-python/issues/4922#issuecomment-1121651459 regarding the similar Black extension.

Does the vscode team hear about these bug reports? It’s a bit odd to just let this things linger for several years. I would think Microsoft has a decent amount of engineering capacity.

I had the same issue. Here’s how I fixed it:

  1. find out the location of isort
which isort
/Users/abc/.pyenv/shims/isort
  1. Set this path as python.sortImports.path: /Users/abc/.pyenv/shims/isort in VS Code.

I had thought that setting the python.sortImports.path option to ${env:CONDA_PREFIX}/bin/isort would have done it, but this only works if you are using your base conda environment (I’m using a different conda environment typically). It appears that for whatever reason the settings.json file is parsed after the base conda environment is activated, but before the selected environment is activated.