TransWikia.com

Automatically activating python virtual environments with pyvenv

Emacs Asked by Jacob Pavlock on September 2, 2021

I am using pyvenv with doom and am trying to have my python virtual environments automatically loaded when I enter a certain project.

I saw this relevant issue on pyvenv and have added the following code to my config.el

;; autoload python virtual environments
;; https://github.com/jorgenschaefer/pyvenv/issues/51#issuecomment-474785730
(defun pyvenv-autoload ()
  "Activates pyvenv version if .venv directory exists."
  (f-traverse-upwards
   (lambda (path)
     (let ((venv-path (f-expand ".venv" path)))
       (if (f-exists? venv-path)
           (progn
             (pyvenv-workon venv-path))
         t)))))
(add-hook 'python-mode-hook 'pyvenv-autoload)

I expect that whenever I enter a python file inside a project with a .venv directory, it would automatically activate the appropriate virtual environment. However, running M-x shell-command RET which python returns /usr/bin/python when I would expect it to return something like /home/jacob/src/beets/.venv/bin/python

Some debugging:

python-mode-hook‘s value is

(er/add-python-mode-expansions
 doom--setq-tab-width-for-python-mode-h
 +python-use-correct-flycheck-executables-h
 evil-collection-python-set-evil-shift-width
 doom-modeline-env-setup-python
 pyvenv-autoload
 pipenv-mode)

Which looks good to me.

However,
pyvenv-workon‘s value is nil which could be the issue.

Activating and deactivating the virtual environment through pyvenv-activate and pyvenv-deactivate works as normal. If I use this method, which python returns the expected /home/jacob/src/beets/.venv/bin/python

One Answer

I've found that using 'projectile-after-switch-project-hook with the following function works well. The downside is that you do have to add conditional statements to the autoload-venv function as you add new projects and virtual environments. The upside is that you don't need to have a completely consistent approach to storing and naming virtual environments, i.e. you could have some in your home directory and others in the project itself.

(defun autoload-venv()
(cond
 ((string= (projectile-project-name) "project_one")
        (pyvenv-activate "~/.virtualenvs/proj1_venv"))
 ((string= (projectile-project-name) "project_two")
        (pyvenv-activate "~/project_two/proj2_venv"))))

(add-hook 'projectile-after-switch-project-hook #'autoload-venv)

Answered by tomh on September 2, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP