Using pdb in emacs with a miniconda install - python

I am trying to use pdb as a python debugger in emacs
I'm getting the import error issues, as in:
https://emacs.stackexchange.com/questions/18190/missing-modules-when-debugging-python-code-in-emacs
How to specifiy path when using pdb in emacs?
the suggested solution, i.e.
(setenv "PYTHONPATH" "lib")
in .emacs or emacs.d/init.el
This seems very unsatisfactory as you are effectively duplicating the pythonpath data which will trip you up at some point when you update one but not the other.
How can one get the pythonpath as used by pdb to be exactly the same as that is used say if I open an ipython shell.
In other words I want pdb to reflect the path locations that get automatically loaded from my .bashrc and miniconda installation when I open ipython
also, how does ipython know which miniconda dirs to pull into the pythonpath? which file is that specified in?

Find out where your miniconda install is, for me it was:
~/miniconda2
Ensure that your .bashrc PATH is picking up the miniconda python install before any of the default linux installations, i.e. its looking in ~/miniconda2/bin prior to /usr/bin/
Dired into ~/miniconda2/lib/python2.7
'S' to create a soft symlink to pdb.py, place the link in ~/miniconda2/bin and call it pdb2.7
Dired into ~/miniconda2/bin
'S' to create a soft symlink to pdb2.7, place link in same dir and call it pdb
Now when you run M-x pdb to invoke the python debugger it should pick up the correct version and not complain of any missing modules
Prior to this it was picking up pdb from /usr/bin, hence all the module import failures. These steps just copy the set of symlinks found in that dir but using the miniconda equivalent files and dirs

Related

Fixing PATH for Python libraries using Bash

I am attempting to install some Python libraries by executing variations of the following command in Bash:
pip install --user -U numpy
I installed Python3 using Homebrew.
I then get variations of the following message each time:
WARNING: The scripts f2py, f2py3 and f2py3.7 are installed in '/Users/x/Library/Python/3.7/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
How can I fix this issue to avoid problems in the future?
The error message is telling you to add Python 3 to your path.
To do that, use a text editor to open /Users/<you>/.profile, and as the very last line add:
export PATH=/Users/<you>/Library/Python/3.8/bin:$PATH
Then you'll need to launch a new Terminal window for those settings to take effect. (you could make it take effect in your current shell by entering the line directly into your shell)
[Edit: now that macOS 12.3 has removed all versions of Python, Homebrew is the easiest way to install Python. Fortunately things are simpler because there's only one version of Python on your system and you won't need to override the system's version (because there isn't one any longer).]
Update: As of python 3.8, the following path should be used:
export PATH=/Library/Frameworks/Python.framework/Versions/3.8/bin:$PATH
If you're using bash, you can store this in your /.bashrc
If you're using zsh, you can store this in your /.zshrc
You have to update the seeking path location, to needed bin folder, in your .zshrc, .bashrc etc.
Example
For /Library/Python/3.8/bin,
you can prepend the variable $HOME, and use with the needed path:
export PATH="$HOME/Library/Python/3.8/bin:$PATH"
Epilogue
In current Terminal tab, you have to reload your shell, with the config, by . ~/.zshrc, or .bashrc etc

how to set different PYTHONPATH variables for python3 and python2 respectively

I want to add a specific library path only to python2. After adding export PYTHONPATH="/path/to/lib/" to my .bashrc, however, executing python3 gets the error: Your PYTHONPATH points to a site-packages dir for Python 2.x but you are running Python 3.x!
I think it is due to that python2 and python3 share the common PYTHONPATH variable.
So, can I set different PYTHONPATH variables respectively for python2 and python3. If not, how can I add a library path exclusively to a particular version of python?
PYTHONPATH is somewhat of a hack as far as package management is concerned. A "pretty" solution would be to package your library and install it.
This could sound more tricky than it is, so let me show you how it works.
Let us assume your "package" has a single file named wow.py and you keep it in /home/user/mylib/wow.py.
Create the file /home/user/mylib/setup.py with the following content:
from setuptools import setup
setup(name="WowPackage",
packages=["."],
)
That's it, now you can "properly install" your package into the Python distribution of your choice without the need to bother about PYTHONPATH. As far as "proper installation" is concerned, you have at least three options:
"Really proper". Will copy your code to your python site-packages directory:
$ python setup.py install
"Development". Will only add a link from the python site-packages to /home/user/mylib. This means that changes to code in your directory will have effect.
$ python setup.py develop
"User". If you do not want to write to the system directories, you can install the package (either "properly" or "in development mode") to /home/user/.local directory, where Python will also find them on its own. For that, just add --user to the command.
$ python setup.py install --user
$ python setup.py develop --user
To remove a package installed in development mode, do
$ python setup.py develop -u
or
$ python setup.py develop -u --user
To remove a package installed "properly", do
$ pip uninstall WowPackage
If your package is more interesting than a single file (e.g. you have subdirectories and such), just list those in the packages parameter of the setup function (you will need to list everything recursively, hence you'll use a helper function for larger libraries). Once you get a hang of it, make sure to read a more detailed manual as well.
In the end, go and contribute your package to PyPI -- it is as simple as calling python setup.py sdist register upload (you'll need a PyPI username, though).
You can create a configuration file mymodule.pth under lib/site-packages (on Windows) or lib/pythonX.Y/site-packages (on Unix and Macintosh), then add one line containing the directory to add to python path.
From docs.python2 and docs.python3:
A path configuration file is a file whose name has the form name.pth and exists in one of the four directories mentioned above; its contents are additional items (one per line) to be added to sys.path. Non-existing items are never added to sys.path, and no check is made that the item refers to a directory rather than a file. No item is added to sys.path more than once. Blank lines and lines beginning with # are skipped. Lines starting with import (followed by space or tab) are executed.
I found that there is no way to modify PYTHONPATH that is only for python2 or only for python3. I had to use a .pth file.
What I had to do was:
make sure directory is created in my home: $HOME/.local/lib/python${MAJOR_VERSION}.${MINOR_VERSION}/site-packages
create a .pth file in that directory
test that your .pth file is work
done
For more info on `.pth. file syntax and how they work please see: python2 docs and python3 docs.
(.pth files in a nutshell: when your python interpreter starts it will look in certain directories and see the .pth file, open those files, parse the files, and add those directories to your sys.path (i.e. the same behavior as PYTHONPATH) and make any python modules located on those directories available for normal importing.)
If you don't want to bother with moving/adding documents in lib/site-packages, try adding two lines of code in the python2.7 script you would like to run (below.)
import sys
sys.path = [p for p in sys.path if p.startswith(r'C:\Python27')]
This way, PYTHONPATH will be updated (ignore all python3.x packages) every time you run your code.

Virtual Env on Mac with python 3.4

I am trying to get a django project up and running, and I have django running, but I am having trouble with python's virtualenv.
here is my error (on terminal open this shows up)
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python: No module named virtualenvwrapper
virtualenvwrapper.sh: There was a problem running the initialization hooks.
If Python could not import the module virtualenvwrapper.hook_loader,
check that virtualenvwrapper has been installed for
VIRTUALENVWRAPPER_PYTHON=/Library/Frameworks/Python.framework/Versions/2.7/bin/python and that PATH is
set properly.
Here is what My .bash profile looks like:
# Setting PATH for Python 3.4
# The orginal version is saved in .bash_profile.pysave
PATH="/Library/Frameworks/Python.framework/Versions/3.4/bin:${PATH}"
export PATH
# Setting PATH for Python 2.7
# The orginal version is saved in .bash_profile.pysave
PATH="/Library/Frameworks/Python.framework/Versions/2.7/bin:${PATH}"
export PATH
export WORKON_HOME=$HOME/.virtualenvs
source /Library/Frameworks/Python.framework/Versions/3.4/bin/virtualenvwrapper.sh
export PIP_VIRTUALENV_BASE=$WORKON_HOME
if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi
I am pretty new to command line stuff and virtual environments, so I might not know some "obvious" things I am doing wrong. Thanks.
First some basics of the command-line shell:
PATH is an environment variable that contains a list of filesystem directories. When you type a command such as ls, python or virtualenvwrapper.sh your shell will search each directory starting from the first one listed. To see your current PATH type:
$ echo $PATH
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
To see what a given command is going to resolve to the location of the program that is going to be run, use the which command:
$ which ls
/bin/ls
Now in your example you are first adding a Python 3.4 location to your PATH and then a Python 2.7 location. The latter location is going to be first on your PATH. So all your Python related commands are first going to try and run Python 2.7, if a command isn't found there, it next searches in your Python 3.4 installation.
You appear to have installed virtualenvwrapper for Python 3.4, but when you run virtualenvwrapper.sh from the line:
source /Library/Frameworks/Python.framework/Versions/3.4/bin/virtualenvwrapper.sh
You are explicitly running the virtualenvwrapper.sh installed for Python 3.4. This runs a python command where your Python 2.7 is run, which does not appear to have virtualenvwrapper installed, as shown by this error message:
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python: No module named virtualenvwrapper
If you tried removing the Python 2.7 location addition to your PATH and it didn't work, you have to remember that changes to your .bash_profile are not automatically reflected in your terminal. You have to create a new terminal session and that new session will read your new .bash_profile.
If you are trying to get the command virtualenv to resolve to two different Pythons, it's simply not possible. It will always resolve to one specific Python based on the ordering of the locations on your PATH. VirtualEnv does install alternate versions of the command with the version of the Python built into the name. Use the commands virtualenv-3.4 and virtualenv-2.7 to create virtual environments for each different Python.
The key to all of this is remembering that PATH is used to resolve to an absolute path location of a program this is run. Use the echo $PATH and which commands to help you understand how that final path is being resolved.
It may seem tedious, but typing out the full absolute path is always going to side-step the magic of PATH resolution:
$ /Library/Frameworks/Python.framework/Versions/2.7/bin/virtualenv
Try using smaller steps on your way to manipulating the path. Use just virutalenv-3.4 to make a Python 3.4 virtual environment and only bring in virtualenvwrapper as you need it and after your understanding of shell environments is more solid.
Finally, even pro's can get tripped up by playing games manipulating the path. You are ultimately trying to take a bunch of different application locations and flatten them all into one namespace. At some point conflicts can become unresolveable. A Python installation tool such as Buildout has it's own learning curve, but it hard-codes the absolute path to the python of each python script that it installs. Hard-coding absolute paths is the only way to deal with extreme corner cases such as having two builds of Python 3.4 side-by-side where you have two scripts which each need to run on two different builds of the same Python. Hard-coding absolute locations is also desirable in production environments, because then your application is immune to any changes to the bash shell. If you forget about a required ordering of your PATH, or another sysadmin tinkers with the PATH, you won't find your application breaking unexpectedly.

Python 3, sys.path doesn't work, how to permenantly append a path? [duplicate]

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']

Can't find my PYTHONPATH

I'm trying to change my PYTHONPATH. I've tried to change it in "My Computer" etc, but it doesn't exist there. I searched in the registry in some places, and even ran a whole search for the word 'PYTHONPATH', but to no avail.
However, it Python I can easily see it exists. So where is it?
At runtime, you can change it with:
import sys
sys.path.append('...')
In My Computer, right-click Properties (or press Win-Break), System tab, Environment Variables, System. You can add it if it's not already there.
Finally, in the CMD prompt:
set PYTHONPATH C:\Python25\Lib;C:\MyPythonLib
Or in bash:
PYTHONPATH=/usr/share/python/lib:/home/me/python
export PYTHONPATH
Or, more succinctly:
export PYTHONPATH=/home/me/python
Python does some stuff up front when it is started, probably also setting that path in windows. Just set it and see, if it is changed in sys.path.
Setting environment variables in the Python docs say:
My Computer ‣ Properties ‣ Advanced ‣ Environment Variables
You can add it under "My Computer" if it doesn't exist. PYTHONPATH just adds to the default sys.path.
On unix/linux/osx you can:
$ export PYTHONPATH=/to/my/python/libs
You can also use .pth files to point to libraries:
http://docs.python.org/library/site.html#module-site
And of course:
import sys
sys.path.append('/path/to/libs/')
Also, check out virtualenv for managing libraries for multiple projects.
Here's how I solved it.
First, get the current path. There's a lot more there than I expected.
import sys
print ';'.join(sys.path)
Copy that result to the clipboard. Go to My Computer and create the new environment variable PYTHONPATH, and for the value paste from the clipboard. Modify as necessary.
MacOS 10.5.8, Python 2.6, Eclipse+Pydev 1.5.7
Python installation's site-package is, for example:
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages
create symlinks YOUR LIBRARY inside into site-package, for example:
cd /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages
ln -s /path/to/YOUR/LIBRARY/ YOUR_LIBRARY_NAME
Now You can use in commandline: import YOUR_LIBRARY_NAME
run Eclipse with Pydev, go to Preferences->Pydev->Interpreter Python
remove Your Python interpreter record, if exists;
click New and add Python 2.6 interpreter path, for example:
/Library/Frameworks/Python.framework/Versions/2.6/bin/python2.6
notice, that Eclipse Pydev display Python System Library, accept that
in Library section click New Folder and write path to YOUR LIBRARY, for example:
/path/to/YOUR/LIBRARY/
click Apply - it is essential, because Eclipse Pydev built now his own "library map", when this operation finish - click [OK]
close Eclipse
run Eclipse again - now You should use in Pydev: import YOUR_LIBRARY_NAME
And, as with all good things in life, you can find it in the documentation:
http://docs.python.org/install/index.html#modifying-python-s-search-path
What's it set to? Have you tried creating a PYTHONPATH environment variable?
You need modify your environment variables. How to do this depends on which version of Windows you have.
If the PYTHONPATH variable doesn't exist, you have to create it. It might not exist if you haven't already created it.
I had same problem and oliver-zehentleitner's answer in github solved my problem.
He said: Maybe You install package with pip for python2 and run with python3, just try to install with pip3 or python3 -m pip install python-binance and then run your script again.
I hope this can solve yours too.

Categories