I am new to emacs and try to learn some elisp to configure it.
I wanted to automatically activate a python virtual environment when entering elpy-mode.
I have tried all kinds of variations of the following code
(use-package elpy
:init
(elpy-enable)
:config
(add-hook 'elpy-mode-hook
(lambda ()
(let* ((my-venv-root (locate-dominating-file buffer-file-name "venv"))
(my-venv (file-name-as-directory (file-name-concat my-venv-root "venv"))))
(message (concat "Venv Root: " my-venv-root))
(message (concat "Venv: " my-venv))
(when my-venv
(message "Try to activate Virtual Environment")
(pyvenv-activate my-venv))))))
The manual way M-x pyvenv-activate RET /path/to/project/venv RET followed by C-c C-c works just fine.
But if I put the above code in my init.el file I keep getting the Error Wrong type argument: stringp, nil when trying to run a python file/buffer using C-c C-c
The messages yield correct looking values for my-venv-root and my-venv. For Example:
Venv Root: ~/Documents/Code/Test/
Venv: ~/Documents/Code/Test/venv/
Try to activate Virtual Environment
I am using Debian 12 with emacs 28.2 installed from the debian repositories.
I found a/the solution.
TL;DR:
Wrapped the code inside
(when buffer-file-name ....A little more detailed:
For some reason the
elpy-mode-hookgets called whenC-c C-copens theInferior Python Shell(ButC-h mdidn't showelpy, ...). It triggered the hook again withbuffer-file-namereturningnil, because theInferior Python Shellhas no file name associated with it.My solution was to wrap everything in
(when buffer-file-name ....So my - now working - config looks like that:
I do not fully understand how this could happen, 'cause this is what
C-h mgives me in theInferior Python Shell:So no
Elpyhere, like inC-h min asomething.py-Buffer:But it works for me.