4

I am starting a Python virtualenv through init.el (or so I would like):

(require 'virtualenvwrapper)
(venv-workon "my-python-project")

However, flycheck does not find flake8 or pylint, which are installed there. Starting emacs in a terminal with the virtualenv loaded works fine.

Is it possible to configure init.el to start a virtualenv for flycheck to use?

EDIT

Seems that this is related to an open bug in python-mode.el

  • Have you tried using elpy? It includes pyvenv which is able to switch virtualenvs automatically. – elarson Dec 17 '14 at 2:46
  • I don't think that the bug report is related. You neither mention virtualenv.el nor python-mode in your question. – lunaryorn Dec 17 '14 at 14:38
5

I don't think there's a prebuilt way to do this. I hacked around it like so. This depends on having all of your virtualenvs in ~/.virtualenvs, and having projectile installed.

(defvar my:virtualenv-directory "~/.virtualenvs/"
  "The directory of virtualenvs.")

(defun my:configure-python-venv ()
  "Set `python-shell-virtualenv-path' to the virtualenv directory."
  (interactive)
  (require 'projectile)
  (let* ((project-name (projectile-project-name))
         (virtualenv-path
          (file-truename
           (concat my:virtualenv-directory project-name))))
    (when (file-directory-p virtualenv-path)
      (setq python-shell-virtualenv-path virtualenv-path))))

(defun my:flycheck-python-set-executables ()
  "Set flycheck python executables for the current virtualenv."
  (let ((exec-path (python-shell-calculate-exec-path)))
    (setq-local flycheck-python-pylint-executable (executable-find "pylint"))
    (setq-local flycheck-python-flake8-executable (executable-find "flake8"))))

(defun my:flycheck-python-setup ()
  "Setup flycheck for Python with virtualenvs. "
  ;; my:flycheck-python-set-executables uses buffer-local variables
  (add-hook 'hack-local-variables-hook #'my:flycheck-python-set-executables
            nil 'local))

(add-hook 'python-mode-hook #'my:configure-python-venv)
(add-hook 'python-mode-hook #'my:flycheck-python-setup)
0

For some unknown reason, today this works (without projectile or elpy):

;;;; Syntax checking (Flycheck)
(add-hook 'after-init-hook #'global-flycheck-mode)
(setq flycheck-check-syntax-automatically '(mode-enabled save new-line idle-change))

;; Default virtualenv (notice I didn't require virtualenvwrapper
;; python-environment or pyvenv prior to loading it. I have
;; all of them installed.)
(if (equal (getenv "VIRTUAL_ENV") nil)
    (venv-workon "my-python-project"))

;; Python autocompletion and doc browsing (Jedi, requires jedi and ipc
;; installed in the Python environment emacs is working in)
(add-hook 'python-mode-hook 'jedi:setup)
(setq jedi:setup-keys t)                      ; optional
(setq jedi:complete-on-dot t)                 ; optional

I included the flycheck (first) and jedi (last) blocks because that is the closest thing to requiring anything remotely related to Python before I set the default virtual environment. I tested it starting emacs from a shell running no virtualenv (works); running the default virtualenv (works); and running a virtualenv without jedi installed (does not work). So I'm confident this is actually working as expected.

  • You can use unless to simplify your if expression, and you can remove the assignment to flycheck-check-syntax-automatically, since that's the default value anyway. – lunaryorn Dec 24 '14 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.