pyenv - how to get more info re: "system", including version - python

I'm on MacOS, and I have latest python installed via brew. A few months ago, I started using pyenv to be able to switch between latest python and a project that was fixed at python v3.8. I think I got it all set up but I'm confused. pyenv refuses to show me information about system:
$ pyenv versions
* system (set by /Users/<user>/.pyenv/version)
3.8.6
$ pyenv version system
system (set by /Users/<user>/.pyenv/version)
$ cat ~/.pyenv/version
system
How do I get pyenv to show me the version and/or location of system?? Obviously, I can get info about system python when it's the one in use, but why doesn't pyenv show anything about it? Showing info about the current config seems like basic functionality for a config management tool.
By comparison, when I run apt list --installed, it shows me what's installed, whether installed by me or bundled with the OS. It doesn't just show a placeholder for things installed by the system.
So I'm frustrated that pyenv is doing this.
Edit: Wow, nvm is the same way. How? Why? Why do these tools have a built-in disregard for the system config?

Pyenv is a shim tool. It's used to intercept calls to python and pip and transparently give the correct binaries for these commands. When you call python -m some_module, pyenv will find the correct python binary that makes sense for that call, either because it's locally set by a .python-version file or set by the current shell using pyenv shell or pyenv activate commands.
Pyenv tries to not mess up with current python installations, because the environment system may use these tools, and should keep using whatever version they are already using. Thus, it simply packs the currently existing binaries as "system" and does not touch it, so that the existing system prior to installing pyenv keeps working as it was before.
As a best practice, I recommend you to create a new environment and set it with pyenv global to something different of system (e.g. pyenv install 3.9.10 && pyenv virtualenv 3.9.10 myglobal && pyenv global myglobal) -- so that your default application python is different from the operating system python, and thus you can't mess with the system; just leave system as is. If you want to check what system is, you can activate it and call it normally, pyenv activate system ; python --version will show the version, but it's not something you should be doing in the first place, so pyenv doesn't support it.

Related

How can I improve my python environment setup on windows 10?

This is my current python environment setup on Windows 10:
For the remainder of this post I will assume you have chocolatey installed. Also I'm using the bash as admin terminal from cmder.
Install python3 with choco install python and/or choco install python3. Verify that you have the latest python3 version installed with python --version. Then type choco install pyenv-win. This is the easiest way to do this because it also configures the Environment Variables.
Now install the python version you want with pyenv. In this post I'll go with 3.9.0
pyenv update
pyenv install --list
pyenv install 3.9.0
It seems like no matter what you do, your path will always put /c/Python39/python aka not the pyenv version of python first. Even if you set the pyenv section of your path first by going to My Computer > Properties > Advanced System Settings > Environment Variables and move PYENV to the top of the path, your terminal will always see /c/Python39/python as the default version.
Then I install virtualenvwrapper with the pyenv version of python:
export "PATH=/c/Users/<myusername>/.pyenv/pyenv-win/shims/:$PATH"
/c/Users/<myusername>/.pyenv/pyenv-win/shims/pip install virtualenv
/c/Users/<myusername>/.pyenv/pyenv-win/shims/pip install virtualenvwrapper
source /c/Users/<myusername>/.pyenv/pyenv-win/versions/3.9.0/Scripts/virtualenvwrapper.sh
export "PATH=/c/Users/<myusername>/.pyenv/pyenv-win/shims/:/c/Users/<myusername>/.pyenv/pyenv-win/versions/3.9.0/Scripts/:$PATH"
I make a virtual environement like this mkvirtualenv test1. Now the terminal has a (test1) before the prompt so I know that the virtual env is active and working. Before you close out of this terminal, run the command deactivate to stop the virtualenv.
Now when I want to start a python project, I run these commands (Order is really important. If you do the first two commands out of order it won't work until you close and reopen the terminal).
export "PATH=/c/Users/<myusername>/.pyenv/pyenv-win/shims/:/c/Users/<myusername>/.pyenv/pyenv-win/versions/3.9.0/Scripts/:$PATH"
source /c/Users/<myusername>/.pyenv/pyenv-win/versions/3.9.0/Scripts/virtualenvwrapper.sh
workon test1
And finished! That's how I setup my virtual environments in Python.
See how inconvenient that was lol. On my mac it's easy I just run pyenv virtualenvwrapper then workon test1. So how can I do this better? Is there a simpler way to work with python on Windows 10?
P.S. I would prefer not to use PyCharm. I know a lot of people like it but I'm looking for a more text editor/IDE agnostic solution.

How to uninstall python 3.7 from Ubuntu 19.10?

I'm using Ubuntu 19.10, in which there is python of version 3.7. After the release of python 3.8, which I have installed, now I want to uninstall python 3.7 so that whenever I would call python3 in my terminal, it would always call python3.8?
You do not need to uninstall old version for this.
You need to update your update-alternatives , then you will be able to set your default python version.
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.4 1
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.6 2
Then run :
sudo update-alternatives --config python
Set python3.6 as default.
Or use the following command to set python3.6 as default:
sudo update-alternatives --set python /usr/bin/python3.6
This should do it.
I suggest you do not touch your default OS python instalation. Other parts of the system may depend on it and there is no way to know if an upgrade can break something, even if it should not.
I also suggest that you learn (if you haven't already, but I suppose you did not because of the question) about using a python virtual environment, like virtualenv. This allows you to setup specific python environments for each project you write. This means each environment can have its own python version, and, besides the standard python lib for that version, any other third-party python lib you would like to install with pip for that project. This isolates projects from each other. You won't break one because of an upgrade of another.
That said, if you want to keep cutting edge with Python versions, make an install from source, and then install it in the system with the altinstall parameter (see the README.rst of the Python distribution. This way all the installed versions are available with different names (the same for pip) and then you create each of your virtual environments with the wanted version. There is a parameter for virtualenv to apply a specific (older) version if you want.
Quoting the README on the "Installing multiple versions" section:
On Unix and Mac systems if you intend to install multiple versions of Python
using the same installation prefix (--prefix argument to the configure
script) you must take care that your primary python executable is not
overwritten by the installation of a different version. All files and
directories installed using make altinstall contain the major and minor
version and can thus live side-by-side. make install also creates
${prefix}/bin/python3 which refers to ${prefix}/bin/pythonX.Y. If you
intend to install multiple versions using the same prefix you must decide which
version (if any) is your "primary" version. Install that version using make
install. Install all other versions using make altinstall.
For example, if you want to install Python 2.7, 3.6, and 3.8 with 3.8 being the
primary version, you would execute make install in your 3.8 build directory
and make altinstall in the others.
Finally, the other answers are ok to do exactly what you asked, if you still want to.
so that whenever I would call python3 in my terminal, it would always call python3.8
You can simply create an alias for Python 3.8 in your .bashrc file in your /home path.
Open ~/.bashrc with your preferred editor, and go to the last line.
Append this line:
alias python='python3.8'
And whenever you call python in your terminal, it opens Python 3.8.
Note: This doesn't work as expected when creating virtual environments with specific version. You might want to keep that in mind.

Installing the same python environment on another machine

I'm developing a python project on my desktop (OS X) and it's running well. Now I need to run it on a computing cluster that is running Linux and I have no root access. On my Home in the computing cluster I installed Anaconda locally. Then when I run my project there I got so many strange bugs and errors. THe code runs fine on my desktop. So I thought probably the problem is that probably Anaconda has newr modules than what I have and that's probably causing errors. (backward compatibility issues)
Is there any way to use the same python modules versions I have in my desktop on the computing cluster?
I wonder if there is a command that produces all the packages and modules I have on my desktop with their versions and then import this file into some tool in that linux machine and then I get a cloned version of my setup. Is there something like that?
Use pyenv to control the python version
pyenv is designed for installing python into the home folder so you don't need root access (but even with root access it's a great idea), it lets you use a specified version of python within your home folder hierarchy rather than the OS version. You should also install pyenv virtualenv so you can use a virtual environment for your project (not strictly essential, but virtual environments are a great idea and you should always use one, with pyenv they're practically effortless).
One of the neat things about pyenv is the pyenv local command which specifies which version of python (or which virtualenv) should be used for a folder (and subfolders), once you've used pyenv local in your project folder to set the python version any time you use the python command it'll use the version set by pyenv local. It's not needed if you only install one version of python, and don't use a virtualenv (in that case you can use pyenv global to set the version for the user). The neatest thing about pyenv local/global setup is it works great with both scripts and manually invoking python, it is simply set-and-forget unlike other python environment managers which require activation.
In brief, once you've set up pyenv you control exactly what version of python will run, and as it is installed into the home folder the OS has no power to affect it.
Having installed pyenv and pyenv virtualenv, you would then use it to install the same version of python as is used on your development machine, the commands you'd run would be something like this:
pyenv install 3.4.2
pyenv virtualenv 3.4.2 my_project_env
cd my_project
pyenv local my_project_env
Install modules into python environment
To get a list of python module version use pip freeze, you can do this on your development machine:
pip freeze > requirements.txt
Now copy requirements.txt to your deployment machines (with pyenv already setup using pyenv local or pyenv global) and run:
pip install -r requirements.txt
Which will install the same modules into the python environment.
Duplicating a pyenv
While it's kind of dodgy, once you've done this, you can even copy the entire installation (i.e. at least the .bashrc file and .pyenv folder) onto other machines, and if the machines have the same OS and the home folders have the same name, the transplanted environment should work fine. It might be more responsible to use a setup script but I have copied pyenv environments without anything terrible happening.
If you have pip installed you could try this pip freeze.
If you want to get list of modules from python shell:
help('modules')

How do I use different Python version in venv from standard library? (Not virtualenv!)

I have installed Python 3.4.0 and created virtual environment with python -m venv myenv. How can I change Python version in my virtual environment? Documentation says:
Each virtual environment has its own Python binary (allowing creation
of environments with various Python versions) and can have its own
independent set of installed Python packages in its site directories.
UPDATE
Please, note that I ask about venv from standard library, not about virtualenv.
Let me provide some links.
This is PEP 405. http://legacy.python.org/dev/peps/pep-0405/
Python venv. http://docs.python.org/3.4/library/venv.html
Virtualenv. http://www.virtualenv.org/en/latest/
I don't see something like a --python flag in venv.
Are venv and virtualenv absolutely similar?
Is venv is so unpopular and no one uses it so that virtualenv remains the standard?
On Linux/Mac you can easily install multiple versions of Python next to the main one and you can use the venv package from the standard library to create virtual environments from each version >= 3.3.
Create venv
$ python3.3 -m venv myvenv_foo # Create a python3.4 venv named 'myvenv_foo'
$ python3.4 -m venv myvenv_bar # Create a python3.4 venv named 'myvenv_bar'
$ python3.5 -m venv myvenv_baz # Create a python3.5 venv named 'myvenv_baz'
# etc...
Activate venv
source myvenv_foo/bin/activate # Activates venv 'myvenv_foo'
Deactivate venv
deactivate
Notice: python vs pythonX.X
If you have multiple Python versions installed, you can access each one by adding the version num to the command e.g. python3.5, python3.6, etc. But keep in mind that when you activate a venv, you bind it to the clean/versionless python command, for as long as it's activated. E.g:
$ python -V # Use the *clean* 'python' command to show the main version of the OS.
Python 2.7.6
$ python3.5 -m venv myvenv_foo # Create a new venv from 'python3.5'.
$ source myvenv_foo/bin/activate # Activate venv.
$ python -V # The *clean* 'python' command is now bound to your activated venv.
Python 3.5.2
$ deactivate # Deactivate venv.
$ python -V # Now the *clean* command is bound back to the main version.
Python 2.7.6
Note
I suggest using Pipenv to create/handle virutal environments over the venv package.
From the offical docs:
Managing multiple virtual environments directly can become tedious, so the dependency management tutorial introduces a higher level tool, Pipenv, that automatically manages a separate virtual environment for each project and application that you work on.
This is a very good question as there are several python modules / libraries (built-in & third party) with similar names and purposes. Can completely sympathise with OP's confusion.
There are really two different behaviours / responsibilities:
1). The ability to switch between different versions of (System) Python Interpreter eg. 2.7.10 or 3.5.0 etc
2). The ability to create virtual environments (which is just a local folder containing all the plumbing (binaries and libs) for a particular version of python. Can sort of think of this as a frozen local instance of a particular python version. Essentially it is a self-contained, light-weight python installation.
A module like pyvenv provides 2) above. It will allow you to create a virtual environment that is set at the version of Python that was used to create it.
$ python --version
Python 3.5.0
$ pyvenv myenv # myenv is now a local environment using Python 3.5.0
For further infoormation on pyvenv, see library/venv
A module like pyenv (the names are confusing, right? Notice, pyenv, and not pyvenv) on the other hand, controls which VERSION of python your system is basically running. This provides 1) above. So, when not running a particular virtual env via pyvenv etc, this is the "global" version in use. In fact, it is slightly more convoluted than that (as you can also setup local configuration etc), but essentially that is enough for this discussion.
For further information on pyenv see github.com/yyuu/pyenv
Suppose I want to run Python versions 2.7.10 and 3.5.0, then I would use pyenv to install these two versions (here, I chose as globals), and can view this using:
$ pyenv versions
system
* 2.7.10 (set by ~/.pyenv/version)
* 3.5.0 (set by ~/.pyenv/version)
$ python --version
Python 3.5.0
$ which python
~/.pyenv/shims/python
$ python2.7 --version
Python 2.7.10
Yes, there are several prominant alternatives to each of the above referenced modules / libs. Heated discussions on Reddit / SOF etc detailing and arguing which is best. Many of them do very similar things...
It's simply impossible. To create a Python venv of a specific Python version, we need this specific version.
Obviously, a Python interpreter doesn't "include" all the previous versions with their behavior. Python 3.4.1 cannot contain Python 2.7.8 executable anywhere inside.
As another answer said, you need the specific version already there to create virtual env for it. So if you already have it somewhere in your system, you can do it. For example, OSX comes with Python2.7, and so to create a 2.7 virtual environment to avoid messing with the system one, do:
$ virtualenv -p /usr/local/opt/python#2/bin/python2.7 venv
Basically:
$ virtualenv -p <path/to/existing/python> <path/to/new/virtualenv/>
As of 2021, you can't use multiple Python versions with the standard library venv. It will use just the installed Python.
For alternatives you need other tools. You can use:
Conda distribution that has a very robust virtual environment tool. You will be able to easily use multiple Python versions. You'll need to take some care if your environments must be used in *nix and Windows (tip: use conda env export --from-history).
the pyenv module that tries to bring other systems more robust package handling to Python. I don't have experience with it, but the package description is sound. It looks like they are doing the right thing.

"Proper way" to manage multiple versions of Python on archlinux

So I have read this - https://wiki.archlinux.org/index.php/Python
And it is clear from this wiki that I can install Python 2.7.2 via
pacman -S python2
Is it reasonable for me to create a symlink to python2
ln -s python2 /usr/bin/python
if I don't forsee myself switching to python 3.0 any time soon? Or is there a better way of managing multiple python versions like what I usually use on a debian system (update-alternatives --config python) or on a mac os x system (python select)?
CLARIFICATION:
What I am trying to find out is - what is the "best practice" of managing various python versions on an archlinux system?
I am new to archlinux but familiar with ubuntu, debian and mac os x
I would argue you shouldn't create any symlinks like this at all. Especially if you are going to distribute some of your python code, you should not assume a user has python2 or python3 at /usr/bin/python.
If your script requires python2, just use:
#!/usr/bin/env python2
If your script requires python3, use:
#!/usr/bin/env python3
This way your scripts will work fine even through updates to Python. It will also be much more clear what version your script actually needs.
Most unices already have a /usr/bin/python. Overwriting that one is a bad idea, as this is the Python version used by all packages in the system, and changing that one may break them. When installing the Python 2.7 package the executable should be installed as /usr/bin/python2.7 (if not I would claim Archlinux is broken) and it's better to use that when you want to run Python 2.7.
Archlinux is a bit special, since it will use /usr/bin/python for Python 3, despite the default executable name for Python 3 being /usr/bin/python3. This is confusing and can be seen as a bug, but it does mean you can't use that symlink for Python 2, as any other Archlinux script that uses Python 3 will almost certainly break if you do.
So where on other Unices, symlinking /usr/bin/python to Python 2.7 is a bad idea, on Archlinux it is a terrible idea. Instead just install all version you need and call them with /usr/bin/pythonX.X.
There is a nice project on github what helps you with it's called pyenv
What helps you to manage multiple python instances
As others have said, the short answer is "don't do this, it will most likely break things on your system", however, if you mostly use Python 2 you can still set your personal default in your shell (and still have the option of switching to Python 3 at any time). To do this, first become root and install python2-virtualenv:
# pacman -S python2-virtualenv
Then create a virtual environment that uses Python 2 (this will automatically install Python, setuptools, wheel, and pip in the environment):
$ virtualenv -p /usr/bin/python2 --system-site-packages ~/env # (Or wherever you want your environment to live)
If you only want to use locally installed packages (eg. packages you install with pip and not the ones installed by pacman) remove the --system-site-packages option when creating your environment.
Now in your ~/.bash_profile or ~/.profile (or whatever your preferred shells configuration file is), set something like the following:\
source ~/env/bin/activate
This will activate the virtual environment, making your default version Python 2.
This could still break anything that is launched in a shell, but it's not likely that anything will be unless you're explicitly running it from a shell, at which point you can turn the virtual environment off by running:
deactivate
or simply manually run Python 3.
I just stumbled over this post, no necro-bumping intended but I was wondering nobody mentioned virtualenvs. I'm using ArchLinux as well and I use the python packages virtualenv and virtualenvwrapper to create multiple python environments. You can reference to the python 2 or python3 binaries in /usr/bin/ to determine the python version used in the virtual environment.
The benefit is that packages installed in a virtual environment don't mess with the python the system is using and there are many ways to automate project handling.
I know this may be a very old answer, but it took me two days to solve the problem so I'm going to share.
The proper way to manage python versions in your system to work on different projects without them driving you crazy is to use pyenv and its plugins pyenv-virtualenv and pyenv-virtualenvwrapper as described by Henrique Bastos into this blog post. Notice that this way to work is kinda platform independent, since pyenv is a python package and it can be run quite similarly on Windows, Linux and Mac OSx.
The problems start with Arch Linux. The OS doesn't provide a pacman version of pyenv, so you have to install it cloning it from github as described in the installation section of the release. The installation process is the same both for pyenv-virtualenv and pyenv-virtualenvwrapper. Notice that the shell initialization configuration may be different, in my case it didn't work for ~/.bash_profile, but worked for ~/.bashrc .
Running pyenv is not straightforward if your installation is very fresh like the one I'm setting up in these days, since pip requires openSSL and even if you install it via pacman, pyenv doesn't see it. So, if you want to install an older version of Python (namely 3.4.3), you will find the shell complaining about you haven't installed the openSSL plugin, even if you have it. To be honest, I didn't have the right packages the first time I tried to install it; you have to download the following packages
sudo pacman -S openssl
sudo pacman -S openssl-1.0
sudo pacman -S python-pyopenssl
sudo pacman -S python2-pyopenssl
The way I solved the problem is to add the flags as described in the pyenv installation FAQs: that solution eventually led me to install the python version I wanted:
LDFLAGS="-L/usr/lib/openssl-1.0" \
CFLAGS="-I/usr/include/openssl-1.0" \
pyenv install -v 3.4.3
To avoid to go on the FAQs page everytime you want to renew the python installation environment, you can add an alias in ~/.bashrc or whatever is you shell as follows:
echo alias pyenv='LDFLAGS="-L/usr/lib/openssl-1.0" \
CFLAGS="-I/usr/include/openssl-1.0" \
pyenv' >> ~/.bashrc
In this way you can install python properly with a clean pyenv syntax, and manage it via its plugins in the same way (since the syntax is pyenv [COMMAND] [OTHERSTUFF]).
No, there is no better way to do this. The python symlink is part of the Python 3 package.
I guess changing this link won't break anything for now but it might be possible that some packages will depend on it in the future.

Categories

Resources