How can I make my PATH more succinct in ZSH? - python

I am using ZSH. I was having trouble running the Anaconda package manager commands in my terminal. I found that I could add the bin to my PATH using this code:
export PATH="$HOME/anaconda3/bin:$PATH"
That worked. All of the Anaconda and associated commands work and it left me with this PATH:
/Users/USER/anaconda3/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
But the PATH variable would reset each time I closed the terminal window. After some research, I figured out how modify my .zshrc to make it permanent. I simply pasted this into my .zshrc:
export PATH=/Users/USER/anaconda3/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin
All the commands work and are permanent, but aren't I setting myself up for failure down the road? Everything in the PATH, minus the "/Users/USER/anaconda3/bin" were set automatically. What happens when I update Python, for example? How can I include the "USER/anaconda3/bin" portion of my PATH in my .zshrc without being so explicit?

Your PATH concern is not zsh specific. You could organize things differently.
For example, you could decide to add a directory $HOME/bin/ early in your PATH and put inside that $HOME/bin/ symbolic links to the executables (or scripts) that you want to use. BTW, I recommend to have a short PATH (containing some $HOME/bin/ etc...) since it is more efficient and less messy to understand.
What happens when I update Python, for example?
Let's suppose that Python is installed in your system in /usr/bin/python (and that you use some Linux distribution -or some other Unix- with a good package manager dealing with that;on MacOSX consider homebrew). When that file /usr/bin/python is updated, any future exec of it (e.g. by some shell) will use the new version. Read carefully execve(2).
If ou have several Python-s and the one you want to use is under /Library/Frameworks/Python.framework/Versions/3.6/bin and you upgraded it to some Python 3.7 installed under /Library/Frameworks/Python.framework/Versions/3.7/bin you would need to change your PATH.
If you followed my suggestion, you would (for example) just have a symlink from $HOME/bin/python to /Library/Frameworks/Python.framework/Versions/3.6/bin/python and you would upgrade that symlink when installing Python3.7 using for example:
# remove the old symlink
rm -v $HOME/bin/python
# add the new one
ln -sv /Library/Frameworks/Python.framework/Versions/3.7/bin/python \
$HOME/bin/python
In all cases, you are responsible of having a good enough PATH (and preferably a short one).

Related

Confusion using path, multiple versions of python on mac osx

I'm new to using terminal for python. And I am struggling to understand this environment after installing sublimetext to test and develop codes conveniently.
Below is one question. If I command the following,
echo $PATH
Returns,
/usr/local/bin:/Library/Frameworks/Python.framework/Versions/3.5/bin:/usr/local/bin:/usr/local/bin:/usr/local/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
It seems like I have python 3.5 and I want to completely remove it since I only want 2.7 on my osx. If I check the version of python using -V, it returns 2.7. Further from the following command,
open ~/.bash_profile
Returns,
export PATH=/usr/local/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
export PATH=/usr/local/bin:$PATH
export PATH="$HOME/.rbenv/bin:$PATH"
export PATH=/usr/local/bin:$PATH
export PATH
export PATH=/usr/local/bin:/usr/local/bin:/usr/local/bin:/usr/local/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
I don't seem to have 3.5 anywhere. I was recommended to check path environment to remove whatever bits left of 3.5 python but I can't. I seem to be missing a lot of something I can't figure on my own. I would appreciate some experts' advise..
Thanks in advance.
There is no need to uninstall Python 3; it coexists with Python 2 with no interference.
The last export PATH=... statement compiletely overrides all of the previous ones. You don't need to explicitly export PATH at all from your personal settings anyway, because the system alseady does this. The multiple additions of /usr/local/bin are obviously redundant.
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
export PATH="$HOME/.rbenv/bin:$PATH"
would fix the problems and allow the Ruby uninstaller to remove itself at a later time (so I left in the useless export there in case it looks for that when removing itself).

Remove old Python Installation in MAC OS

I installed python using MacPort and I am satisfied with the result, but found that there are other versions of Python installed in other directories, and can not remember how they were instaldas, it's been five years that use this notebook and perhaps installed by other means a few years.
I tried to remove all references to extra Python, beyond that were installed with MacPorts, but do not think like, I tried to remove the directories with the command rm -rfmas even using sudo rm -rf have success.
The old instalation are in directories:
/System/Library/Frameworks/Python.framework/Versions/
/Library/Python/
How to discover the origin of such facilities and remove permanently?
Don't remove the system Pythons. They may be used by other programs. (I don't know if anything on OS X actually uses them, but it's best to keep them.)
Instead, just make sure that your MacPorts bin directory (at /opt/local/bin) is first on your $PATH.
Don't! The name /Library and /System suggest that they are OS-level directories. Nobody installed them. Instead, Mac and other linux-based systems use them by default for system-level services (and they should not be even manually upgraded or system stability may suffer).
For all what matters, you should just prepend your installation directory to a system variable called PATH in your $HOME/.bashrc file. Then, whenever YOU use python, the system will always search for the first occurrence of python on PATH, which is your python. Open terminal, enter the following command (once in a life time):
echo "PATH={a-path-to-the-folder-containing-your-executable-python}:\$PATH" >> $HOME/.bashrc
To explain it, the quoted command prepends your installation directory as the first place to search for executable files. The >> $HOME/.bashrc write this command to the last line of .bashrc, which is a file that setup your terminal environment automatically upon login.

Git bash uses wrong python, other solutions don't work

I've seen a couple solution so far but they don't work. I'm trying to run (in git bash, on windows)
bash scripts/test.sh
But it's supposed to use Python27, and I have that, and Python34. when I type python --version, it tells me it's using Python34. I tried doing
PATH=$PATH:/c/Python27/
But it still tells me I'm using Python34. I know it's in my environment variables, so what am I missing?
$PATH:/c/Python27/ adds /c/Python27/ to the end of your PATH. The directory containing the Python34 executable must be already in your $PATH. So you need to add /c/Python27/ before the other directories listed in $PATH, so it is checked before the directory containing Python34.
PATH=/c/Python27/:$PATH

Install a different version of Python

this might be a very simple question but I need your help. I work in a network and I cannot install the programs I want. Anyway, I need to use another version of python, which is installed in the directory /new_version/.
Now, when I type "python" in a shell (I use bash) the command point to the version of python installed in the machine I'm working with. I'd love that when I type "python" this command point to the /new_version/ which I've installed. It would be also better if I can call this "new version" with another command, i.e. python2.
I tried changing the PYTHONPATH in the .bashrc but it didn't work.
alias newpython="/path/to/your/new_version/python"
Add this to your .bashrc, you can then start the new python with newpython and the standard one with python.
Add the line
export PATH=/new_version/:$PATH
to your ~/.bashrc (or ~/.bash_profile) file. Then, whenever you run python, it will find the new version first in your PATH. Note this is PATH, not PYTHONPATH. See the comment by #Aaron.
Edit: Only do it this way if you want python to point to the new version. Use an alias as #cularis suggested if you want to call it something different, or make a symlink with:
ln -s /new_version/python /path/to/a/dir/you/add/to/your/path/newpython
Install virtualenv. With this you can easily set up different Python versions like that:
virtualenv -p /new_version/bin/python
Also, virtualenv enables you to easily install other Python packages via pip install.
And finally, there's a package called tox which can automate testing with different Python versions...

Permanently add a directory to PYTHONPATH?

Whenever I use sys.path.append, the new directory will be added. However, once I close python, the list will revert to the previous (default?) values. How do I permanently add a directory to PYTHONPATH?
If you're using bash (on a Mac or GNU/Linux distro), add this to your ~/.bashrc
export PYTHONPATH="${PYTHONPATH}:/my/other/path"
You need to add your new directory to the environment variable PYTHONPATH, separated by a colon from previous contents thereof. In any form of Unix, you can do that in a startup script appropriate to whatever shell you're using (.profile or whatever, depending on your favorite shell) with a command which, again, depends on the shell in question; in Windows, you can do it through the system GUI for the purpose.
superuser.com may be a better place to ask further, i.e. for more details if you need specifics about how to enrich an environment variable in your chosen platform and shell, since it's not really a programming question per se.
Instead of manipulating PYTHONPATH you can also create a path configuration file. First find out in which directory Python searches for this information:
python -m site --user-site
For some reason this doesn't seem to work in Python 2.7. There you can use:
python -c 'import site; site._script()' --user-site
Then create a .pth file in that directory containing the path you want to add (create the directory if it doesn't exist).
For example:
# find directory
SITEDIR=$(python -m site --user-site)
# create if it doesn't exist
mkdir -p "$SITEDIR"
# create new .pth file with our path
echo "$HOME/foo/bar" > "$SITEDIR/somelib.pth"
This works on Windows
On Windows, with Python 2.7 go to the Python setup folder.
Open Lib/site-packages.
Add an example.pth empty file to this folder.
Add the required path to the file, one per each line.
Then you'll be able to see all modules within those paths from your scripts.
In case anyone is still confused - if you are on a Mac, do the following:
Open up Terminal
Type open .bash_profile
In the text file that pops up, add this line at the end:
export PYTHONPATH=$PYTHONPATH:foo/bar
Save the file, restart the Terminal, and you're done
You could add the path via your pythonrc file, which defaults to ~/.pythonrc on linux. ie.
import sys
sys.path.append('/path/to/dir')
You could also set the PYTHONPATH environment variable, in a global rc file, such ~/.profile on mac or linux, or via Control Panel -> System -> Advanced tab -> Environment Variables on windows.
To give a bit more explanation, Python will automatically construct its search paths (as mentioned above and here) using the site.py script (typically located in sys.prefix + lib/python<version>/site-packages as well as lib/site-python). One can obtain the value of sys.prefix:
python -c 'import sys; print(sys.prefix)'
The site.py script then adds a number of directories, dependent upon the platform, such as /usr/{lib,share}/python<version>/dist-packages, /usr/local/lib/python<version>/dist-packages to the search path and also searches these paths for <package>.pth config files which contain specific additional search paths. For example easy-install maintains its collection of installed packages which are added to a system specific file e.g on Ubuntu it's /usr/local/lib/python2.7/dist-packages/easy-install.pth. On a typical system there are a bunch of these .pth files around which can explain some unexpected paths in sys.path:
python -c 'import sys; print(sys.path)'
So one can create a .pth file and put in any of these directories (including the sitedir as mentioned above). This seems to be the way most packages get added to the sys.path as opposed to using the PYTHONPATH.
Note: On OSX there's a special additional search path added by site.py for 'framework builds' (but seems to work for normal command line use of python): /Library/Python/<version>/site-packages (e.g. for Python2.7: /Library/Python/2.7/site-packages/) which is where 3rd party packages are supposed to be installed (see the README in that dir). So one can add a path configuration file in there containing additional search paths e.g. create a file called /Library/Python/2.7/site-packages/pip-usr-local.pth which contains /usr/local/lib/python2.7/site-packages/ and then the system python will add that search path.
On MacOS, Instead of giving path to a specific library. Giving full path to the root project folder in
~/.bash_profile
made my day, for example:
export PYTHONPATH="${PYTHONPATH}:/Users/<myuser>/project_root_folder_path"
after this do:
source ~/.bash_profile
On linux you can create a symbolic link from your package to a directory of the PYTHONPATH without having to deal with the environment variables. Something like:
ln -s /your/path /usr/lib/pymodules/python2.7/
For me it worked when I changed the .bash_profile file. Just changing .bashrc file worked only till I restarted the shell.
For python 2.7 it should look like:
export PYTHONPATH="$PYTHONPATH:/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python"
at the end of the .bash_profile file.
Adding export PYTHONPATH="${PYTHONPATH}:/my/other/path" to the ~/.bashrc might not work if PYTHONPATH does not currently exist (because of the :).
export PYTHONPATH="/my/other/path1"
export PYTHONPATH="${PYTHONPATH}:/my/other/path2"
Adding the above to my ~/.bashrc did the trick for me on Ubuntu 16.04
This is an update to this thread which has some old answers.
For those using MAC-OS Catalina or some newer (>= 10.15), it was introduced a new Terminal named zsh (a substitute to the old bash).
I had some problems with the answers above due to this change, and I somewhat did a workaround by creating the file ~/.zshrc and pasting the file directory to the $PATH and $PYTHONPATH
So, first I did:
nano ~/.zshrc
When the editor opened I pasted the following content:
export PATH="${PATH}:/Users/caio.hc.oliveira/Library/Python/3.7/bin"
export PYTHONPATH="${PYTHONPATH}:/Users/caio.hc.oliveira/Library/Python/3.7/bin"
saved it, and restarted the terminal.
IMPORTANT: The path above is set to my computer's path, you would have to adapt it to your python.
The script below works on all platforms as it's pure Python. It makes use of the pathlib Path, documented here https://docs.python.org/3/library/pathlib.html, to make it work cross-platform. You run it once, restart the kernel and that's it. Inspired by https://medium.com/#arnaud.bertrand/modifying-python-s-search-path-with-pth-files-2a41a4143574. In order to run it it requires administrator privileges since you modify some system files.
from pathlib import Path
to_add=Path(path_of_directory_to_add)
from sys import path
if str(to_add) not in path:
minLen=999999
for index,directory in enumerate(path):
if 'site-packages' in directory and len(directory)<=minLen:
minLen=len(directory)
stpi=index
pathSitePckgs=Path(path[stpi])
with open(str(pathSitePckgs/'current_machine_paths.pth'),'w') as pth_file:
pth_file.write(str(to_add))
Just to add on awesomo's answer, you can also add that line into your ~/.bash_profile or ~/.profile
The add a new path to PYTHONPATH is doing in manually by:
adding the path to your ~/.bashrc profile, in terminal by:
vim ~/.bashrc
paste the following to your profile
export PYTHONPATH="${PYTHONPATH}:/User/johndoe/pythonModule"
then, make sure to source your bashrc profile when ever you run your code in terminal:
source ~/.bashrc
Hope this helps.
I added permanently in Windows Vista, Python 3.5
System > Control Panel > Advanced system settings > Advanced (tap) Environment Variables > System variables > (if you don't see PYTHONPATH in Variable column) (click) New > Variable name: PYTHONPATH > Variable value:
Please, write the directory in the Variable value. It is details of Blue Peppers' answer.
Fix Python Path issues when you switch from bash to zsh
I ran into Python Path problems when I switched to zsh from bash.
The solution was simple, but I failed to notice.
Pip was showing me, that the scripts blah blah or package blah blah is installed in ~/.local/bin which is not in path.
After reading some solutions to this question, I opened my .zshrc to find that the solution already existed.
I had to simply uncomment a line:
Take a look
I found a solution to do this in a anaconda environment here: https://datacomy.com/python/anaconda/add_folder_to_path/
Just:
conda develop /your_path
In Python 3.6.4 you can persist sys.path across python sessions like this:
import sys
import os
print(str(sys.path))
dir_path = os.path.dirname(os.path.realpath(__file__))
print(f"current working dir: {dir_path}")
root_dir = dir_path.replace("/util", '', 1)
print(f"root dir: {root_dir}")
sys.path.insert(0, root_dir)
print(str(sys.path))
I strongly suggest you use virtualenv and virtualenvwrapper otherwise you will clutter your path
Inspired by andrei-deusteanu answer, here is my version. This allows you to create a number of additional paths in your site-packages directory.
import os
# Add paths here. Then Run this block of code once and restart kernel. Paths should now be set.
paths_of_directories_to_add = [r'C:\GIT\project1', r'C:\GIT\project2', r'C:\GIT\project3']
# Find your site-packages directory
pathSitePckgs = os.path.join(os.path.dirname(os.__file__), 'site-packages')
# Write a .pth file in your site-packages directory
pthFile = os.path.join(pathSitePckgs,'current_machine_paths.pth')
with open(pthFile,'w') as pth_file:
pth_file.write('\n'.join(paths_of_directories_to_add))
print(pthFile)
After multiple bashing into wall. Finally resolved, in my CentOS 8 the pip3 was old, which was showing error to install the recent packages.
Now, I had downloaded the Python source package, which is Python-3.10.4 and installed the usual way, however the post-installation check generated errors in bash.
And I could not remove the existing Python, because that would break the CentOS desktop features.
Solution:
For building
./configure //don't not add --prefix=/usr, which you need to set proper care
make -j8
sudo make install
Now, as you have multiple Python installed, you can set alias python=python3
And for setting PYTHONPATH
export PYTHONPATH="/usr/local/bin/python3.10:/usr/local/lib/python3.10/lib-dynload:/usr/local/lib/python3.10/site-packages"
Don't add PYTHONHOME
For those who (like me) don't want to get too deeply involved in Python file management (which seems hopelessly overcomplicated), creating a .pth file works perfectly on my Windows 11 laptop (I'm using Visual Studio Code in Windows). So just go to the folder for your virtual environment site packages - there's mine:
Create a text file with a .pth extension - I called mine wheal.pth:
Add paths to it:
The best thing about this in VS Code is that import statements recognise this path (I had to exit VS Code and go back in), so now more typing # type: ignore to suppress linting warning messages!
on Mac :
user#terminal$ env PYTHONPATH=module_path python3
>>> import sys
>>> sys.path
['module_path', 'plus_other_python3_paths',...]
Shortest path between A <-> B is a straight line;
import sys
if not 'NEW_PATH' in sys.path:
sys.path += ['NEW_PATH']

Categories

Resources