Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature request] get python.pythonPath from cwd rather than system wide. #363

Closed
specter119 opened this issue Dec 7, 2017 · 20 comments
Closed
Labels
feature-request Request for new features or functionality

Comments

@specter119
Copy link

Environment data

VS Code version: 1.8.1
Python Extension version: 0.8.0
Python Version: 3.6.3
OS and version: macOS 10.13.2

Actual behavior

use system python if I leave python.pythonPath blank

Expected behavior

find python at current path

use python set py pyenv
I can set .python-version in some parent-folder

Steps to reproduce:

  • pyenv local <some-version> at ~/dev
  • open ~/dev/project1 as a project
  • current python.pythonPath is the system-wide, not read from current folder.
@brettcannon brettcannon added awaiting 1-decision feature-request Request for new features or functionality labels Dec 7, 2017
@brettcannon
Copy link
Member

Not quite sure what you are after here as I don't use pyenv. Are you creating a virtual environment or something locally in the directory and you don't want that being picked up? Or do you not want the changes made by pyenv to be detected?

@brettcannon brettcannon added info-needed Issue requires more information from poster and removed awaiting 1-decision labels Dec 7, 2017
@specter119
Copy link
Author

@brettcannon Thanks, this plugin doesn't pick-up the python-version which pyenv customized for current folder, it will use the version set for the system.

@gwax
Copy link

gwax commented Dec 8, 2017

pyenv is a tool that replaces python and installed python tools (pylint, flake8, etc.) with symbolic links and routes requests to different commands based on global/local configuration.

It is used as an alternative to virtualenvs and is one of the more common ways of managing python versions on OSX.

So, for example:

pyenv install 2.7.14
pyenv install 3.5.0
pyenv install 3.6.3
pyenv virtualenv 3.5.0 somepython
pyenv global 3.6.3
which python  # /Users/waksman/.pyenv/shims/python
python --version  # Python 3.6.3
pyenv which python  # /Users/waksman/.pyenv/versions/3.6.3/bin/python
mkdir -P two/subdir threefive/subdir

cd two
pyenv local 2.7.14
# Inside two/** python, pip, etc. will point to pyenv 2.7.14
python --version  # Python 2.7.14
pyenv which python  # /Users/waksman/.pyenv/versions/2.7.14/bin/python
cat .python-version  # 2.7.14
cd subdir
python --version  # Python 2.7.14
cd ../..

cd threefive
pyenv local somepython
# Inside threefive/** python, pip, etc. will point to pyenv somepython, which is 3.5.0 but with package installs specific to somepython
python --version  # Python 3.5.0
pyenv which python  # /Users/waksman/.pyenv/versions/somepython/bin/python
cat .python-version  # somepython
cd subdir
python --version  # Python 3.5.0
cd ../..

The crux of it is that executing a command from a given folder will result in pyenv routing it to the correct environment (assuming bash_profile/bashrc has been run and set up pyenv).

So, the ask (I think) is that when linting/executing/whatever a given source file, execute the command from the location of that file. Alternatively, the interpreter could be set by using pyenv which python for any given path.

@specter119
Copy link
Author

@gwax Thanks @brettcannon I find that this plugin now works as I expected. So this issue can be closed.

@gwax
Copy link

gwax commented Dec 11, 2017

I continue to have trouble with this, requiring me to manually select interpreter whenever I look at a different workspace and would appreciate if this issue could be re-opened.

@brettcannon brettcannon added awaiting 1-verification and removed info-needed Issue requires more information from poster closed-invalid labels Dec 11, 2017
@brettcannon brettcannon reopened this Dec 11, 2017
@brettcannon brettcannon added info-needed Issue requires more information from poster and removed awaiting 1-verification labels Dec 11, 2017
@brettcannon
Copy link
Member

I assume you're executing pyenv before you launch VS Code from the shell? I.e. your example is missing a code . command or something?

@gwax
Copy link

gwax commented Dec 11, 2017

I am not opening VS Code from the terminal, I am opening it via a shortcut. I am also using a multi-root workspace and different root folders have different pyenv environments.

My examples were to illustrate the behavior of pyenv.

Essentially, pyenv knows how to route to the appropriate virtualenv and it would be great if the interpreter could be taken from pyenv instead of having to be specified manually. After pyenv init (usually in .bash_profile or .bashrc), running pyenv which python from the same folder as an open file yields the full path to the expected interpreter.

@gwax
Copy link

gwax commented Dec 11, 2017

For prioritization context: pyenv is (to my knowledge) on of the more common ways of managing Python environments on OSX; and, it is possible to work around this by manually associating the appropriate interpreter with the project root.

@brettcannon
Copy link
Member

So the issue is that pyenv mutates your environment, so if you're aren't launching code from that same shell that pyenv mutated we won't pick up what version of Python you chose implicitly (unless you create a virtual environment in the project which we will pick up).

But we could bake in explicit support for pyenv. That would mean using pyenv root to notice what versions of Python are installed, pyenv global to detect when a global version of Python has been set, and pyenv local to pick up a local specification of a Python version.

@brettcannon brettcannon added awaiting 1-decision and removed info-needed Issue requires more information from poster labels Dec 11, 2017
@gwax
Copy link

gwax commented Dec 12, 2017

Yeah, and problematically, the environment mutation is working directory dependent so even if I launch code from a given folder, if I open a file from a different folder, that folder's pyenv might be entirely different.

Explicit pyenv support seems reasonable and it's probably a good way to avoid having to pull pyenv setup from an enclosing environment (running code from a terminal or sourcing .bash_profile).

@rcarmo
Copy link

rcarmo commented Jan 3, 2018

I have a variant of this issue which is that I use pyenv on both the Mac and the Windows Subsystem for Linux, and even if I start code from the project directory it doesn't pick up the right Python version (that is a confirmation that the issue still exists in the Mac and a different issue with the same functional impact in WSL, since there code has to cope with picking up Python from the subsystem as well).

Note: Dealing with Python on WSL is being tracked on #67.

I (and other folk) have been moving away from virtualenv in favor of pyenv on Linux as well because we often need to use older Python versions than what the OS ships with, use Anaconda instead of "plain" Python (which is also supported by pyenv), or just use the same set of specific dependencies across multiple projects -- so it makes sense to have a single install with them all rather than multiple virtualenvs all over the place.

Edited to add: Also, pylint needs to take pyenv into account, since it might be linting the wrong Python version.

@neverfox
Copy link

neverfox commented Apr 2, 2018

Same issue here, and it's currently preventing me from using VSCode as my Python IDE since I always use pyenv and virtualenvs (so instead I'm using Spacemacs, which handles all this just fine). More specifically, I don't just use pyenv but pyenv with the pyenv-virtualenv plugin. So you have installed pyenv versions, which VSCode picks up as valid interpreters in its list (though not automatically the way pyenv would do it), but then you have virtualenvs under each version. pyenv handles this by using shims. The shims are first in the path so you always go through them to get to pyenv, which then handles interpreting your environment to find the right version and location.

I tried setting my python.pythonPath to /usr/local/opt/pyenv/shims/python but VSCode always assumes I'm in pyenv's "global" state, which means that when pyenv is doing whatever it does to settle on a version, it lacks sufficient information inside of VSCode to do anything but settle on the default global setting for pyenv. What it needs to do (not just for the interpreter but for all executables like pylint) is give pyenv all the information it needs to do the right thing, which probably just means calling the shim as if it were being called from the folder the open file is in.

@neverfox
Copy link

neverfox commented Apr 2, 2018

Yes, pyenv does mutate the environment but I don't think that mutation is essential to how it works (though I could be wrong). Instead, as I said, it works through a shim executable (which you could set in your python.pythonPath) and when that shim is executed, it goes through a four step process that depends on the directory you're in, particularly steps two and three. This also raises the question of why VSCode doesn't just automatically choose the first interpreter on your path rather than searching a pre-specified list of paths (that don't happen to include $(pyenv root)/shims). That way there would be no need to even touch the user settings out of the box.

@gwax
Copy link

gwax commented Apr 2, 2018

Having lived with this a bit longer, I find it's a lot less difficult to work around than I previously thought but there are a few minor issues that make things annoying and some other possible nice to haves.

pyenv, pylint, flake8, and VSCode works perfectly well together if you set the appropriate interpreter (Python: Select Interpreter). If you're using pyenv all of your python versions and pyenv-virtualenv virtual environments will show up on the list (with a caveat detailed below). All of this works without touching python.pythonPath.

Annoyances and nice to haves:

  • If you add a new pyenv interpreter, it won't show up in VSCode until you restart the application
  • I have to set an interpreter for every one of my project folders (which creates a .vscode folder in each)
    • it would be great if this was autodetected from pyenv or the .python-version file
  • interpreter can only be set at the project level
    • sometimes I have single projects that use different Python versions in project subfolders

@brettcannon
Copy link
Member

See #1167 for tracking the request to add support for .python-version to auto-select the interpreter. And I think these issues are now duplicates of each other so I'm going to close this one and move the discussion over.

@neverfox
Copy link

neverfox commented Apr 2, 2018

@gwax All of mine aren't showing up, so I'm curious how you accomplished (or lucked into) that. I'd be fine with most of the issues you mention if I at least got a complete list, but look at this:

> pyenv versions
* system (set by /usr/local/opt/pyenv/version)
  3.6.5
  /usr/local/Cellar/pyenv/1.2.3/versions/3.6.5/envs/NDF
  /usr/local/Cellar/pyenv/1.2.3/versions/3.6.5/envs/PonyGE2
  /usr/local/Cellar/pyenv/1.2.3/versions/3.6.5/envs/nrf
  NDF
  PonyGE2
  nrf

Now:
Screenshot of Python: Select Interpreter
Notice that the PonyGE2 and nrf venvs are nowhere to be seen. It's almost like it's taking the first one in order under the 3.6.5 parent and ignoring the rest.

@gadams999
Copy link

@neverfox I see the same behavior. I created a pyenv virtualenv and set that to global. vscode does see that as an interpreter. However, any other virtualenvs do not show up.

At present I use the Select Interpreter to reference the exact python version for the workspace/directory which does work. Will start tracking the other open issue for completion.

@neverfox
Copy link

neverfox commented Apr 3, 2018

@gadams999 Thanks for confirming. Sounds like this should be its own issue.

@brettcannon
Copy link
Member

@neverfox please open a separate issue as that is a feature request since we only detect virtual environments that are kept in your workspace folder or created by pipenv.

@neverfox
Copy link

neverfox commented Apr 5, 2018

@gwax I'm actually really curious how that's able to do the trick for the other executables like pylint, flake8, etc since you're not telling the extension about where to find the right copy like you are with the interpreter. Perhaps it works because the extension sets something in the environment that effects the shims for them to be directed appropriately?

@lock lock bot locked as resolved and limited conversation to collaborators Jul 11, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature-request Request for new features or functionality
Projects
None yet
Development

No branches or pull requests

6 participants