🏠 Home About Archive Tags RSS
25 mars 2026

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. This works for me since I tend to call virtual environment directories venv. The point of the function is to get access to the packages within that virtual environment when using the python shell to evaluate code from a file or interact with its functions, classes and variables through the REPL. I usually write my code and then test it through the REPL and do the necessary adjustments when there are mistakes. (I probably do this since I learned basic programming principles by teaching myself HyperTalk by reading the Help stack and experimenting in the Message Box (a REPL) in HyperCard in the late 80s.) I think a lot of people overlook this great way of working in interpreted languages.

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 found that this would work:

(defun einar-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)))))

I 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 since the mode hook is run every time you open a python file:

(add-hook 'python-mode-hook 'einar-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.

Tags: emacs computers python
© 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.