🏠 About Now Archive Tags RSS

Use python shell from virtual environment if there is one in Emacs

About a week ago, I made a function to use python from a virtual environment if there existed a directory called venv within the project the file is inside. The point is to get access to the packages within that virtual environment when using the python shell to evaluate code from a file. Today, I had a look at that function again. I thought it would be really nice if I could find the python executable within a virtual environment no matter what the virtual environment directory is called.

I looked around a bit and found a built in function in Emacs to search based on a regular expression within a directory recursively (within subdirectories) that solved the problem. I am not very experienced with Emacs Lisp, so this is a function I haven't met before.

(defun emo-python-virtualenv ()
  "Sets the python shell to python from a virtual environment if one exists."
  (when (project-current)
    (let ((pythonpath
           (nth 0 (directory-files-recursively
                   (nth 2 (project-current))
                   (if (eq system-type 'gnu/linux) "python$" "python.exe$")))))
      (when (file-exists-p pythonpath)
        (setq-local python-shell-interpreter pythonpath)))))

As mentioned last time I wrote about this, I also need to run this function whenever I open a python file to set the correct path to the python shell for that file. This is done by adding the function to the python-mode hook like this:

(add-hook 'python-mode-hook 'emo-python-virtualenv))

With this in place, whenever I open a python shell with C-c C-p from a python file, I get a python shell from within the virtual environment of that file's project, or I get the system python if there isn't a virtual environment within the project the file is part of.

© Einar Mostad 2010 - 2026. Content is licensed under the terms of CC BY SA except code which is GNU GPL v3 or later.
Made with GNU Emacs, Org-Static-Blog, and Codeberg Pages on GNU/Linux.