Make VS Code terminal match debug environment on a Mac - python

I'm teaching a beginners python class, the environment is Anaconda, VS Code and git (plus a few extras from a requirements.txt).
For the windows students this runs perfectly, however the mac students have an existing python (2.7) to contend with.
The windows students (i.e. they have a windows computer), their environment when they debug matches their console environment. However the mac students seem to be locked to their 2.7 environment.
I've tried aliasing, as suggested here and here
alias python2='python'
alias python='python3'
alias pip2='pip'
alias pip='pip3'
I've modified the .bash_profile file
echo 'export PATH="/Users/$USER/anaconda3/bin:$PATH"' >>.bash_profile
Both of these seem to work perfectly to modify their Terminal environments, when launched externally to VS Code. Neither seem to do anything to the environment launched from [cmd]+[`].
I've also tried conda activate base in the terminal, which seems to have no effect on a python --version or a which python
They can run things using python 3, but that means that they need to remember that they are different to the other 2/3 of the students. It's othering for them, and more work for me!
The students are doing fine, launching things from their external terminal, but it would streamline things greatly if the environments could be as consistent as possible across the OSs.
Whilst they are complete beginners, they can run a shell script. They currently have one that installs pip requirements and vs code extensions.
Is there a configuration that will keep the terminal in line with the debug env?

In my opinion the best practice is to create Python virtual environments (personally I love using conda environments, especially on Mac where you stuck with unremovable old Python version). Then VSCode will automatically (after installing very powerful Python extension) find all your virtual environments. This way you will teach your students a good practice of handling Python zoo a.k.a. package incompatibilities. Terminal environments settings will be consistent with VSCode, without being dependent on unneeded any more aliases. Obviously, virtual environments are OS independent, so you will be more consistent and remove unnecessary confusion between different students.
The additional bonus of the virtenvs is that you can create one exactly according to your requirements.txt and switch from one to another with a single click (in terminal it takes two commands: deactivate -> activate).
You can read more about how to handle Python virtual environments on VSCode site

Given the aliases are run just once and are not persistent in .bash_profile, python targets the default interpreter rather than the expected conda python3 interpreter.
Try to symlink conda's python3 executable to capture the python namespace
ln -sf /Users/$USER/anaconda3/bin/python3 /Users/$USER/anaconda3/bin/python
This will create or update the symlink. Use the same approach for pip and pip3.

Python in vscode let's you select which interpreter will be used to run the scripts.
It is in settings under "python.pythonPath", just set it to point to the interpreter of choice.
It can be set on a project basis as well (which is how you ensure that a project that has a virtual environment will execute using that interpreter and packages), you just select Workspace in the settings pane and add the desired python interpreter there.

Related

Python Virtual Environment Shebang for Window and Linux

I have a python file that I'd like to execute using the virtual environment (venv) in the same directory as the file. I'd like it to use this venv regardless of whether the user has activated it or not to avoid accidentally running it without the proper environment. I'd like this to work on both Linux and Windows (via Git Bash).
The issue is that venv puts python under the "bin" directory on Linux but under "Scripts" on Windows and I can't seem to find a way to change this behavior when creating it. I tried creating it with Git Bash in hopes that it would "trick" python into using a bin directory instead of Scripts, but that didn't work.
The following shebang works well on Linux:
#!.venv3/bin/python
And this one works well on Windows:
#!.venv3/Scripts/python
But what will work on both? I know that one option would be to create a shell script that activates the environment based on the detected os (using $OSTYPE), but I'd like to avoid this if possible as it isn't otherwise necessary.
You could use the Windows version of the shebang:
#!.venv3/Scripts/python
and then create a symbolic link on the Linux side:
.venv3/Scripts -> .venv3/bin
I just tried this with one of my virtual envs. It worked fine for me. I didn't test the Windows case, but of course, that has to work as we're using the correct shebang for Windows to begin with.

Emacs and conda workaround

I'm using emacs and anaconda.
I have this in my init.el:
(setenv "WORKON_HOME" "/home/user/anaconda3/envs/")
And conda on my path:
# added by Anaconda3 installer
export PATH="/home/user/anaconda3/bin:$PATH"
but emacs can't find my conda environments, which I understand it is supposed to be able to do..
So, when I run C-c C-p to start a new session, and C-c C-c, it fails to import my packages which are installed in a conda environment, with ModuleNotFoundError.
Since I have added this to my path and it still doesn't work, I am trying to work around this, and still be able to run my conda applications from emacs.
I can open a shell in emacs with M-x shell, then source activate myenv, and run python.
I now want C-c C-c to copy into /this/ shell. How do I mark this shell buffer as a python process to send my file.py's text to on C-c C-c, rather than just a shell shell?
Update1
I've also looked at the following references:
https://emacs.stackexchange.com/questions/20092/using-conda-environments-in-emacs
How does conda-env list / conda info --envs find environments?
But neither package works for me. I still get, when I try:
conda-env-list
*Conda envs*
Produces a blank buffer.
And this for pyvenv-workon:
pyvenv-workon
Work on: (empty)
These environments very much exist, and it makes it impossible to use emacs as a python IDE if I can't run my code.
What I found works for me is to use the conda package from ELPA and set two of its configuration variables to point to my Conda directory. The following snippet does the trick in my .emacs:
(use-package conda
:ensure t
:init
(setq conda-anaconda-home (expand-file-name "~/miniconda3"))
(setq conda-env-home-directory (expand-file-name "~/miniconda3")))
conda-anaconda-home is the equivalent to the ANACONDA_HOME environment variable (i.e. contains all files of your Anaconda installation)
conda-env-home-directory - is the directory where your virtual environments get stored (within the envs subdirectory)
With this configuration I'm able to run M-x conda-env-activate and have access to all previously created envs.
Programs inherit the environment variables from the shell that spawned them. The way conda and virtualenv work is by overriding the shell's PATH variable. They do this so that the OS finds the new version of the app (conda's or virtualenv's) instead of the default one installed with the OS (Macs come with an ancient version of python).
So, what is happening here? If you start Emacs by double clicking on the OS icon it will inherit the default shell environment variables. So when you try to call a library that you installed with conda (or equivalently with virtualenv and pip), because you are using the default OS path, the OS is finding the default version of python (and crucially the default version's libraries). The default version of python is going to respond "I have no idea what library that is."
How to fix? One reliable way is to not start Emacs by double clicking on the OS Icon. Here is what I do most days:
1) start a console/terminal
2) switch to the conda environment `activate py37`
(or with virtualenv: `source .py37dev/bin/activate`)
3) start Emacs from that same shell that has the modified environment variables.
On a Mac its: `/Applications/Emacs.app/Contents/MacOS/Emacs`
(I use a installed version of Emacs on the Mac because the one that
comes with Mac is ancient).
On Linux and Windows the path to EMacs will be different but the idea is the same.
4) start a shell inside Emacs and you should see the shell looks the way it does
in your conda shell (or virtualenv shell)
here it what it looks like for me:
see how the version of python is not the default OS python? Its the one from the virtualenv + pip environment (conda works the exact same way, just the start envirmonment is a different command)
I tested the solutions given in the answers of Wojciech Gac, of Mittenchops and James Anderson.
While solution of James Anderson's solution is by far the easiest, it comes with a few problems:
First, you have to reactivate the environment in each shell process you spawn in emacs. There is also the possibility that emacs has a different pythonpath, therefor reluctantly using system python and not venv python.
The solution with conda.el is somehow weird. In Melpa it is listed as obsolete and with instructions of https://github.com/necaris/conda.el it won't recognize the environments on my certain machine.
On the same machine the solution with pyenv as mentioned in https://emacs.stackexchange.com/a/20093/28567 is working like a charm.
Therefor you only need to install with M-x package-install search for pyenv and then insert following two lines into .emacs:
(setenv "WORKON_HOME" "~/anaconda3/envs") ; /anaconda3 || /miniconda || wathever path your conda installation is located at
(pyvenv-mode 1)
This is my minimal solution to this problem:
create a batch file like this
conda activate <yourEnv>
python -i
set (local) python-shell-interpreter pointing to the batch-file
run-python as always (C-c C-p ...)
I know this is not exactly an answer to your question. But If you JUST want to run your code, open the directory in the terminal where your files are located (e.g. cd /Downloads/Chapter01/yourfile.py) . Then, activate the environment (conda activate *your env*) and pass this command (python yourfile.py). Your code will be executed within that environment by python.
I edit remote files with emacs and run code like this in another terminal window. You may wanna open the two terminal windows side by side while debugging your code.

How to deploy python programs in Anaconda environments on Windows?

I am trying to use Anaconda and conda environments to allow Python programs for data acquisition* etc. to run from the (Anaconda) command line on Windows. The set up will be that the Python programs are installed to a particular location (cloned from Github), within %PATH% or whichever environment variable is more appropriate.
From an Anaconda command prompt in another directory and a particular conda environment, I want (both myself and other users) to be able run either python test.py <args> or test.py <args> (either solution is acceptable) and have a system wide conda environment run its Python to execute the program. test.py can/will have an appropriate shebang set.
Right now the python test.py calls the correct Python within the active conda environment, but cannot find the test.py program as Python won't search the %PATH% or similar looking for the program. test.py does something (Windows does not complain that the executable can't be found, and I've been playing with the file associations to get this far), but doesn't appear to start Python - a simple print function or raise statement as the only entry in the file does nothing.
I've tried setting file associations in Windows, but this hasn't changed anything. I've copied the py.exe/pyw.exe across to the Anaconda environments, with no change.
Is this something that can be done within Anaconda, or am I going to have to fall back on installing base Python directly and trying to use the launcher mechanism there?
Note that I'm also intending to deploy these programs on Raspbian, so any solutions, including non-Anaconda ones, that will work cross platform there would be worth extra effort on my part.
*these programs have significant usage of library packages for accessing external USB/GPIB/serial/ethernet connected lab equipment and use matplotlib, scipy, etc., hence the desire for a cloneable conda environment as the base environment.
It turns out the correct answer to this is fairly simple, but is fairly hard to find explained well. This might be a little clearer than the other answers I found:
Install the standalone launcher from pylauncher and add #!/usr/bin/env python shebangs to your scripts.
This should register .py files to Python.File and will find your Anaconda Pythons in appropriate environments. If you don't have a non-Anaconda python, it will use the Anaconda base environment (these two facts were the key element I was missing from various other answers around this problem that I had looked at, including the documents on python.org).
If you have a Python from python.org installed, then a standalone command line shell will use that, defaulting to Python 2.x, then Python 3.x. With #!/usr/bin/env python shebang, then a regular command shell will try to use python.org pythons first, then the Anaconda base environment. An Anaconda prompt will use the active environment. #! /usr/bin/env python2 or python3 will try to use python.org pythons only and fail if they are not found.
Installing Python 2.7 from python.org installers (and letting the installer set the file associations) will break pylauncher, and reinstalling will not fix it. Instead, set Computer\HKEY_CLASSES_ROOT\Python.File\Shell\open\command default value to "C:\WINDOWS\py.exe" "%L" %* to revert back to the pylauncher set up (assuming you used the launchwin.* packages to install it).

How to tell VScode, on my Mac running high Sierra, which version of python to use

I use VScode to write and run python. I use it with a Jupyter extension. I have 2 virtual environments created using Anaconda. One py27, for python 2.7.13 and the other, py36, for Python 3.6.5.
I have a simple code which I edited to only run in python2. When I run VScode, the virtual environment I run it in does not seem to matter. VScode seems to run but I can't figure out how to make it use py36 (python 3.6.5) or py27 (python 2.7.13).
By using different commands in the command palette, or double-clicking on phrases in the bottom border of VScode I can eventually get it to run which version I want. But I have not found a reproducible method.
I have tried about 100 times with no luck. I thought I found a method that would repeat but I tried it again and it didn't work.
I know this question is very vague but it would take pages to explain what I've tried. I have about 5 or 6 settings which I've tried a plethora of combinations. One of the commands I tried is to select a python interpreter. I have several options but none seem to have an effect. Also, in the bottom border of the VScode window, there is the name of a specific python interpreter. You can click on this to select a different python interpreter. As far as I can tell this doesn't do anything. Actually, it's a hindrance because a user may think they are actually using that interpreter.
I've tried both py27 and p36 but I get no difference. If I can get visual studio code to start out in py27, I can make it change to py36 and back to py27. But how to make it start in py27 seems random. My virtual environments are in my home directory, /User/myname/py27 for example along with the VScode app.
The documentation at https://code.visualstudio.com/docs/python/environments explains how to select your virtual environment. Without knowing where you installed the virtual environments the best I can tell you is you can manually specify what interpreter to use with the python.pythonPath setting or if you have both virtual environments in a directory outside of your workspace folder you can specify the common folder with the python.venvPath setting.

Associating a python project with a virtual environment

been searching for this with no success, i don't know if i am missing something but i have a virtualenv already but how do i create a project to associate the virtualenv with, thanks
P.S. Am on windows
I could be wrong here, but I do not believe that a virtualenv is something that is by its very nature something that you associate with a project. When you use a virtualenv, you're basically saying, "I'm taking this Python interpreter, installing what I want on it, and setting it aside from the Python interpreter that the entire computer uses by default." Virtualenv does not have a concept of a Python "project"; it is just a custom version of a Python interpreter that you run code through. There are tools in IDEs like PyCharm that enable you to associate a project with a virtualenv, but those are another layer on top of the base software.
In order to use a virtualenv with a project, you will need to "activate" it every time you wish to use it. The documentation for activating a virtualenv on Windows is found here.
EDIT:
Saw that you had virtualenvwrapper tagged in your post, so I did a bit of hunting on that. It would appear that there is the mkproject command, which creates a project folder and then associates it with a virtualenv interpreter. Documentation on it can be found here.
Requirements:
Virtual Env
Pycharm
Go to Virtual env and type which python
Add remote project interpreter (File > Default Settings > Project Interpreter (cog) add remote)
You'll need to set up your file system so that PyCharm can also open the project.
NOTE:
do not turn off your virtual environment without saving your run configurations that will cause pycharm to see your run configurations as corrupt
There's a button on the top right that reads share enable this and your run configs will be saved to a .idea file and you'll have a lot less issues
If you already have your virtualenv installed you just need to start using it.
Create your projects virtual environment using virtualenv env_name on cmd. To associate a specific version of python with your environment use: virtualenv env_name -p pythonx.x;
Activate your environment by navigating into its Scripts folder and executing activate.
Your terminal now is using your virtual environment, that means every python package you install and the python version you run will be the ones you configured inside your env.
I like to create environments with the names similar to my projects, I always use one environment to each project, that helps keeping track of which packages my specific projects need to run.
If you haven't read much about venvs yet, try googling about requirements.txt along with pip freeze command those are pretty useful to keep track of your project's packages.
I like Pipenv: Python Dev Workflow for Humans to manage environments:
Pipenv is a tool that aims to bring the best of all packaging worlds (bundler, composer, npm, cargo, yarn, etc.) to the Python world. Windows is a first-class citizen, in our world.
It automatically creates and manages a virtualenv for your projects, as well as adds/removes packages from your Pipfile as you install/uninstall packages. It also generates the ever-important Pipfile.lock, which is used to produce deterministic builds.
Pipenv is primarily meant to provide users and developers of applications with an easy method to setup a working environment.

Categories

Resources