23

I am debugging some python code in emacs using pdb and getting some import issues. The dependencies are installed in one of my bespoked virtualenv environments.

Pdb is stubbornly using /usr/bin/python and not the python process from my virtualenv.

I use virtualenv.el to support switching of environments within emacs and via the postactivate hooks described in

http://jesselegg.com/archives/2010/03/14/emacs-python-programmers-2-virtualenv-ipython-daemon-mode/

This works well when running M-x python-shell

>>> import sys
>>> print sys.path 

This points to all of my virtualenv libraries indicating that the python-shell is that of my virtualenv.

This is contradicted however by M-! which python, which gives /usr/bin/python

Does anyone know how I can tell M-x pdb to adopt the python process from the currently active virtualenv?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
codeasone
  • 1,953
  • 2
  • 23
  • 30
  • 2
    Your post refers to [my old virtualenv package](https://github.com/aculich/virtualenv.el) that I no longer maintain; there are at least 3 newer, actively maintained packages: [virtualenvwrapper](https://github.com/porterjamesj/virtualenvwrapper.el), [pyvenv](https://github.com/jorgenschaefer/pyvenv), [python-environment](https://github.com/tkf/emacs-python-environment) – aculich Feb 20 '14 at 23:07

4 Answers4

19

Invoke pdb like this:

python -m pdb myscript.py

Instead of

pdb myscript.py
spookylukey
  • 6,380
  • 1
  • 31
  • 34
8

python-shell uses variable python-default-interpreter to determine which python interpreter to use. When the value of this variable is cpython, the variables python-python-command and python-python-command-args are consulted to determine the interpreter and arguments to use. Those two variables are manipulated by virtualenv.el to set the current virtual environment.

So when you use python-shell command, it uses your virtual environments without any problem.

But, when you do M-! python, you're not using the variables python-python-command and python-python-command-args. So it uses the python tools it finds in your path.

When you call M-x pdb it uses gud-pdb-command-name as the default pdb tool. To redefine this variable, each time you activate an environment, you could do something like this :

(defadvice virtualenv-activate (after virtual-pdb)
  (custom-set-variables
     '(gud-pdb-command-name
        (concat virtualenv-active "/bin/pdb" ))))

(ad-activate 'virtualenv-activate)

To have pdb in your virtual environment, do the following :

cp /usr/bin/pdb /path/to/virtual/env/bin

Then edit the first line of /path/to/virtual/env/bin/pdb to have :

#! /usr/bin/env python

Reactivate your env and Pdb should now use your virtualenv python instead of the system-wide python.

Jérôme Radix
  • 10,285
  • 4
  • 34
  • 40
  • Thanks Jerome. For others trying to get this working note that I had to cp /usr/bin/pdb to /bin and change the shebang to use the virtualenv python executable. This is because mkvirtualenv --no-site-packages does not deposit the necessary pdb into the /bin directory of the newly created environment. – codeasone Sep 17 '10 at 16:16
  • Thx for those details. You could also create a symbolic link to avoid copying of files. – Jérôme Radix Sep 17 '10 at 19:44
2

Possibly, your pdb command is tied to a certain specific version.

$ ls -ald /usr/bin/pdb
lrwxrwxrwx 1 root root 6 Jun  2 23:02 /usr/bin/pdb -> pdb2.6

Then, look at the first line of pdb2.6. It contains

#! /usr/bin/python2.6

This is why pdb is stubborn and always seems to run under a specific version of Python. Because it really is! Actually, this sort of dependency makes sense for a piece of software like a symbolic debugger.

I've compiled python2.7 from sources and pdb is not there, apparently. After some scrutiny, I found pdb.py for python-2.7, under the lib folder. I've then created some symlinks to it, for convenience:

$ cd /opt/python-dev   ##-- this is where I installed from sources
$ cd bin
$ sudo ln -s ../lib/python2.7/pdb.py pdb2.7
$ sudo ln -s pdb2.7 pdb

Now observe the first line of pdb2.7. It reads:

#! /usr/bin/env python

... which looks better than the previous version. It basically means that pdb will be launched under the current Python you have defined in your environment, whatever it is, instead of anything hardcoded, like /usr/bin/python or /usr/bin/python2.6 are. Good to know!

I've also removed pdb and pdb2.6 from system files, once I prefer to develop/debug inside virtualenv. Doing that, I will not be caught again by the same trick.

I hope it helps.

Richard Gomes
  • 5,675
  • 2
  • 44
  • 50
2

A quick work-around is to explicitly call the python interpreter in you virtual env.

M-x pdb, then:

path/to/your/virtualenv/python3 -m pdb your_source.py
Gauthier
  • 40,309
  • 11
  • 63
  • 97