jorgenschaefer / pyvenv Goto Github PK
View Code? Open in Web Editor NEWPython virtual environment interface for Emacs
Python virtual environment interface for Emacs
As a newbie to virtual environment usage in Emacs I would appreciate it if the README.md file showed some basic usage of this script. Without such documentation I don't even know where to start to use this myself.
Started with M-x jedi:install-server
it responded with-
python-environment--make-with-runner: Program named "virtualenv" does not exist.
... so downloaded pyvenv.el, which again wanted to know the directory address. Assuming it wants the address of some virtualenv created virtual environment through cmd.exe with command-
c:\Python34\python -m pyvenv akkenv
which created a directory (akkenv)at -
:\Windows\System32
Installed Pyvenv.el through M-x list-package tried to activate it through M-x pyvenv-activate
showed him akkenv however it seems he wants to go further deep down as [ ] was nowhere...where should I lead him to?
My akkenv directory shows following folders
Include
Lib
Scripts
pyvenv.cfg (which is not accessible when I am pointing towards it in minibuffer)
my .emacs related to jedi is something like this at present -
;;Jedi
(require 'jedi)
(setq jedi:server-command "~/.emacs.d/jediepcserver.py")
(add-hook 'python-mode-hook 'jedi:setup)
(setq python-environment-virtualenv "C:/Windows/System32/arunenv")
;; Hook up to autocomplete
(add-to-list 'ac-sources 'ac-sources-jedi-direct)
;; Enable for python-mode
;;(add-hook 'python-mode-hook 'jedi:setup)
;; python-interpreter
(setq python-shell-interpreter "C:/Python34/python.exe")
;; EPC for Jedi
(require 'epc)
;; Local Jedi keybindings
(defun jedi-config:setup-keys ()
(local-set-key (kbd "M-.") 'jedi:goto-definition)
(local-set-key (kbd "M-,") 'jedi:goto-definition-pop-marker)
(local-set-key (kbd "M-?") 'jedi:show-doc)
(local-set-key (kbd "M-/") 'jedi:get-in-function-call))
(add-hook 'python-mode-hook 'jedi-config:setup-keys)
;; Never show in-function call automatically
(setq jedi:get-in-function-call-delay 10000000)
;; Complete when type a dot
(setq jedi:complete-on-dot t)
Am I supposed to add/delete something ?
Where am I faulting ?
pyvenv version 20150503.941
Hi,
is there a way to show the name of the virtual environment currently used inside the mode line?
(Copied from #6.)
I was wondering if there was any way to cache project level Python processes (specifically for Jedi). Right now, if I switch between buffers that are in different Elpy projects, each switch triggers a Jedi restart. I'm wondering if it would be possible to start the process buffer with a project-specific suffix, with a variable that resolves to the name of the current process buffer. Then RPC calls could resolve it and pick it up. I don't know enough about Emacs to know if that's safe. Thoughts? More than happy to submit a patch.
As per elpy#1001, pyvenv-run-virtualenvwrapper-hook
should probably set shell-file-name
to /bin/sh
or something for sourcing the hook output …
pyvenv-activate errors if virtualenvwrapper is not installed.
Hi,
When using pyvenv-workon
you get to see the name of the activated virtualenv in the status bar ([envname]
). However it seems when using pyvenv-activate
to select a path you simply get []
instead of an env name.
It would be nice if it could show the basename of the environment. While this could conflict it could be possible to keep a list of previously activated environments and once the basename starts to conflict disambiguate it like emacs does for buffer names by finding the first parent which differs. E.g. for /tmp/foo/env/
and /tmp/bar/env/
once the 2nd env is activated one could show [foo/env]
and [bar/env]
instead of just [env]
.
Alternatively simply showing the full path might be suitable too, if a little verbose. Probably wouldn't work so well on small screens.
Regards,
Floris
Hi,
Just writing to let you know the following.
I installed pyvenv via elpa. I'm getting these errors:
Compiling file /home/roland/.emacs.d/elpa/pyvenv-20160527.442/pyvenv-pkg.el at Thu Dec 15 11:40:22 2016
Entering directory `/home/roland/.emacs.d/elpa/pyvenv-20160527.442/'
Compiling file /home/roland/.emacs.d/elpa/pyvenv-20160527.442/pyvenv.el at Thu Dec 15 11:40:22 2016
In pyvenv-activate:
pyvenv.el:153:9:Warning: assignment to free variable
`python-shell-virtualenv-root'
In pyvenv-deactivate:
pyvenv.el:214:9:Warning: assignment to free variable
`python-shell-virtualenv-root'
pyvenv.el:256:1:Warning: Unused lexical argument `unbound'
pyvenv.el:256:1:Warning: Unused lexical argument `value'
pyvenv.el:256:1:Warning: Unused lexical argument `widget'
pyvenv could provide a package browser.
This interface would list packages installed in the current virtualenv, with their current version, and note if a newer version is available from PyPI (using https://pypi.python.org/pypi/<package>/json
). A button would be provided to update the package.
This could also provide a way to update requirements*.txt
, so that packages listed in respective requirements files in the current project root would get updated.
Something like this:
Package | Installed | Available | Requirements |
---|---|---|---|
Django | 1.6.1 | 1.6.2 | requirements.txt |
elpy | 1.3.0 | 1.4.0 | requirements-dev.txt |
That is, pyvenv-activate
instead of pyvenv-workon
.
A function (e.g. for elpy-mode-hook
) that auto-detects the current virtualenv would be nice.
It should look through ~/.virtualenvs/*/.project
for a directory prefix of the current directory and activate said virtualenv.
In python3 they added single quotes around the module name in the message of ImportError
:
✔ ~/other_source/elpy [master|✔]
13:44 $ python2
Python 2.7.10 (default, Sep 7 2015, 13:51:49)
[GCC 5.2.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named foo
>>>
✔ ~/other_source/elpy [master|✔]
13:51 $ python
Python 3.5.0 (default, Sep 20 2015, 11:28:25)
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'foo'
>>>
This causes the check on https://github.com/jorgenschaefer/pyvenv/blob/master/pyvenv.el#L374 to pass which results in an un-needed buffer reporting the error.
I can see several ways to fix this, but don't know enough elisp conventions to know which one is preferred.
if i switch to a venv
in local system, elpy-config shows
Virtualenv........: d18 (/home/k3/.virtualenvs/d18)
RPC Python........: 2.7.6 (/home/k3/.virtualenvs/d18/bin/python)
if i switch to a venv
in ssh/vagrant, elpy config shows
Virtualenv........: pearl (/ssh:[email protected]:/home/xxx/.virtualenvs/pearl)
RPC Python........: 2.7.6 (/usr/bin/python)
pyvenv-set-file-virtualenv
calls virtualenv-workon
. Shouldn't it call pyvenv-workon
?
pyvenv-workon
results in all buffers showing the current virtual environment in the modline.
This is wrong - most of my buffers have nothing to do with python.
Also, this means that all my python buffers must be in the same projects at any given time, which is usually not the case.
(pyvenv-run-virtualenvwrapper-hook)
in pyvenv.el
sets shell-file-name
to /bin/sh
that leads to the error.
/bin/sh
on Ubuntu does not understand source
(it uses .
).
virtualenvwrapper
creates hooks that are presumed to be sourced using $SHELL
.
The hooks such as post_activate
may contain source
command explicitly:
$VIRTUALENVWRAPPER_PYTHON -c 'from virtualenvwrapper.hook_loader import main; main()' --source post_activate | nl
1 # project
2 #
3 # Change to the project directory, as long as we haven't been told not to.
4 #
5 [ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME" -a "$VIRTUALENVWRAPPER_PROJECT_CD" = 1 ] && virtualenvwrapper_cd "$(cat "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_PROJECT_FILENAME")"
6 # user_scripts
7 #
8 # Run user-provided scripts
9 #
10 [ -f "$VIRTUALENVWRAPPER_HOOK_DIR/postactivate" ] && source "$VIRTUALENVWRAPPER_HOOK_DIR/postactivate"
11 [ -f "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postactivate" ] && source "$VIRTUAL_ENV/$VIRTUALENVWRAPPER_ENV_BIN_DIR/postactivate"
The installed virtualenvwrapper version:
$VIRTUALENVWRAPPER_PYTHON -m pip show virtualenvwrapper | grep -i "^Version"
Version: 4.7.1
It is related to issue #36.
The mode line for pyvenv-mode could be enhanced to allow for switching between virtualenvs.
It would be useful for this tool to support Anaconda environments under Windows as well.
Anaconda environment however has a different structure, which looks like
$WORKON_HOME
|-- my-venv
| |-- Scripts
| | |-- activate.bat
| | |-- deactivate.bat
| | |-- pip.exe
| | +-- ...
| |-- python.exe
| |-- python.pdb
| +-- ...
|
+-- my-another-venv
which is neither covered by Unix nor Windows at
https://github.com/jorgenschaefer/pyvenv/blob/master/pyvenv.el#L161
since here no bin
exists, and python.exe
is not under Scripts
Adding one more when
option like:
(let ((new-directories (append
;; Unix
(when (file-exists-p (format "%s/bin" directory))
(list (format "%s/bin" directory)))
;; Windows
(when (file-exists-p (format "%s/Scripts" directory))
(list (format "%s/Scripts" directory)))
;; Anaconda Windows
(when (file-exists-p (format "%s/python.exe" directory))
(list directory)))))
would solve this.
I'm using pyenv virtualenv to create/manage virtualenvs, which means that they all get created in the same place (I'm using the suggested /usr/local/var/pyenv/versions/
).
Is there a way to set a default directory for pyenv-activate
to look in? It'd be nice if I didn't always have to navigate to /usr/local/var/pyenv/versions/
to tell pyenv which virtualenv to activate.
Or am I doing it wrong?
The .dir-locals.el file for my project has a line like this:
((nil . ((pyvenv-workon . "myvenv"))))
Every time I open a file in that directory, I'm asked if I want to switch to the virtualenv myvenv. I believe it's because the variable pyvenv-virtual-env is the full path of the virtualenv and not the virtualenv name. Should I be using the full path in dir-locals, or is this a bug?
I've set my pyvenv-activate via dir-local and I get the following output in the virtualenvwrapper hook output buffer:
Output from the virtualenvwrapper hook post_activate:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named virtualenvwrapper.hook_loader
In pyvenv I can comment out calling the virtualenv post-activate hook in pyvenv-activate
and things work. That said, I get the same error message as above with the exception of the output being from the pre_deactivate
hook.
In both cases it seems virtualenvwrapper is installed.
Hi,
Anaconda-mode tracks the status of the variable
python-shell-virtualenv-path
to automatically switch between virtual environments for autocompletion.
Would it be possible to set this variable to the path of the virtualenv when switching with pyvenv?
I've already hacked together a small function for spacemacs that does the trick but I guess out of the box compatibility would be nice.
(defun spacemacs/pyvenv-workon ()
"switch python virtualenvironment and restart anaconda server"
(interactive)
(call-interactively 'pyvenv-workon)
(setq python-shell-virtualenv-path pyvenv-virtual-env))
An option should be added to allow access to global binaries e.g. those install in .local/bin
by pip since it doesn't always make sense to install tools such as yapf multiple times.
I discovered the hard way that pyvenv-tracking-mode
performs very poorly when the pyvenv-activate
variable is set to a value without a trailing slash. pyvenv-track-virtualenv
will try to activate the virtualenv whenever (not (equal pyvenv-workon pyvenv-virtual-env-name))
, but pyvenv-virtual-env-name
is set to (file-name-as-directory pyvenv-activate)
. If file-name-as-directory
doesn't return pyvenv-activate
unchanged (i.e. if there is no trailing slash), the tracking hook will reactivate the virtualenv on every keystroke.
I think file-name-as-directory
should be used in the pyvenv-track-virtualenv
comparison as well as where the variable is set.
I just looked at the code, and noticed that pyvenv mode sets a virtualenv globally, by directly assigning to exec-path
and process-environment
, without making these variables local.
As such, there can only be a single virtualenv per Emacs session, which seems like a questionable limitation to me.
What's the rationale for this?
Recent versions of virtualenvwrapper – e.g. 4.3.1 – do not export this variable anymore, which means we can't rely on it in Emacs anymore.
Originally reported in jorgenschaefer/elpy#497
In zsh
, the equal sign can be used to get the full path of an executable, i.e. =ls
get expanded to /bin/ls
. However, this makes zsh incompatible with pyvenv-run-virtualenvwrapper-hook
.
Offending s-expr [lines 370-1]:
(format ". '%s' ; echo ; echo =-=-= ; python -c \"import os, json ; print(json.dumps(dict(os.environ)))\""
tmpfile)
where echo =-=-=
lacks quotation marks. Inserting those fixes this problem:
(format ". '%s' ; echo ; echo \"=-=-=\" ; python -c \"import os, json ; print(json.dumps(dict(os.environ)))\""
tmpfile)
I hit an issue where I was trying to set an environment var and it kept disappearing. I soon realised it was pyvenv-deactivate restoring the old process environment.
pyvenv-activate and pyvenv-deactivate should only replace and restore environment variables which are relevant to the virtualenv (PATH, VIRTUALENV and PYTHONHOME)
I use jedi for python development in Emacs.
But jedi searches files in its default virtualenv only, and I find no way to conveniently switch jedi's virtualenv
Have you tried to make pyvenv work with jedi?
When I try to activate a virtualenv environment by running M-x pyvenv-activate /path/to/venv RET
pyvenv prints an error from pre_activate
and post_activate
hooks with the an error looking like
Output from the virtualenvwrapper hook pre_activate:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'virtualenvwrapper'
Does pyvenv-activate
require virtualenvwrapper
? I had a quick look at the pyvenv.el
source and it looks to be the case. But I am raising this issue because I remember using pyvenv-activate
without having virtualenvwrapper
installed and it worked fine.
Feel free to change this issue into a question, if appropriate. Thanks!
I'm using VirtualFish on my fish terminal and it can automatically detect the .venv
file at the root of the project and can automatically activate the virtualenv accordingly.
But on Spacemacs, I always have to choose the virtualenv manually via pyvenv-workon
. Am i missing something here? Is there any other way to accomplish this?
I'm using an environment with a postactivate
hook given by virtualenvwrapper
. This hook sets some environment variables (e.g. PYTHONPATH
) required for executing the code I am developing.
I am using a .dir-locals.el
file at the base on my project with the following config:
((python-mode
(eval ignore-errors
"Setup python environment variables."
(make-local-variable 'process-environment)
(setq process-environment
(append process-environment
'("PYTHONPATH=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages"
"VIRTUALENVWRAPPER_ENV_BIN_DIR=bin"
"VIRTUALENVWRAPPER_HOOK_DIR=/Users/elemakil/.virtualenvs"
"VIRTUALENVWRAPPER_PYTHON=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/python"
"VIRTUALENVWRAPPER_SCRIPT=/opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/virtualenvwrapper.sh"
"VIRTUALENVWRAPPER_VIRTUALENV=virtualenv"))))))
As expected, this modifes the variables relevant for the hook procedure (VIRTUALENVWRAPPER_*
) only for the relevant buffers. However, when loading the environment using pyvenv
(pyvnev-workon
), these variables are not used.
For debugging, I've put an echo statement into the pyvenv-run-virtualenvwrapper-hook
function [L 370-2]:
(call-process-shell-command
(format ". '%s' ; echo \"PYTHONPATH = '$PYTHONPATH'\" >> /Users/elemakil/foo ; echo \"VIRTUALENVWRAPPER_HOOK_DIR = '$VIRTUALENVWRAPPER_HOOK_DIR\" >> /Users/elemakil/foo ; echo ; echo =-=-= ; python -c \"import os, json ; print(json.dumps(dict(os.environ)))\""
tmpfile)
nil t nil)
Both variables are empty. Consequently, an interactive session started from within emacs
will fail to work correctly since the code in the hook is not executed.
Please advise!
The title says it all, right now using pyvenv-activate or pyvenv-workon apply changes to all buffers and frames.
I saw from the other issue : #47 that it is a stretch for buffer local effects.
But is there a way to actually have different venvs in different frames at least?
This seems to happen every time. It is probably relevant that I haven't installed virtualenvwrapper
, since as far as I know that package isn't a requirement of pyvenv.
Output from the virtualenvwrapper hook post_deactivate:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named virtualenvwrapper.hook_loader
This is a feature request for pyvenv-workon
to work on Windows too. AFAICS, pyvenv-virtualenv-list
looks only for bin/activate
inside the $WORKON_HOME
folders. On Windows, this is instead in Scripts\activate
- see also variable virtualenv-executables-dir
in virtualenv
package.
If you do not have a Windows environment to test in, I could try a PR along the lines of mentioned virtualenv-executables-dir
.
Some environments – e.g. Mac OS X, Ubuntu Desktop – do not set the virtualenvwrapper environment correctly, so the user would need to do this manually. pyvenv could be used to automate this setup, e.g. by automatically setting the required environment variables when needed.
(let ((workon-home (expand-file-name "~/.virtualenvs/")))
(setenv "WORKON_HOME" workon-home)
(setenv "VIRTUALENVWRAPPER_HOOK_DIR" workon-home))
Hello,
when I activate the menu-bar I get the following error message:
Debugger entered--Lisp error: (error "Can't find a workon home directory, set $WORKON_HOME")
signal(error ("Can't find a workon home directory, set $WORKON_HOME"))
error("Can't find a workon home directory, set $WORKON_HOME")
pyvenv-virtualenv-list()
(mapcar (lambda (venv) (vector venv (\` (pyvenv-workon (\, venv))) :style (quote radio) :selected (\` (equal pyvenv-virtual-env-name (\, venv))))) (pyvenv-virtualenv-list))
(lambda (&optional ignored) (mapcar (lambda (venv) (vector venv (\` (pyvenv-workon (\, venv))) :style (quote radio) :selected (\` (equal pyvenv-virtual-env-name (\, venv))))) (pyvenv-virtualenv-list)))(nil)
#[257 "\302\301�!\300\"\207" ["Workon" (lambda (&optional ignored) (mapcar (lambda (venv) (vector venv (\` (pyvenv-workon ...)) :style (quote radio) :selected (\` (equal pyvenv-virtual-env-name ...)))) (pyvenv-virtualenv-list))) easy-menu-filter-return] 4 "\n\n(fn MENU)"](nil)
redisplay_internal\ \(C\ function\)()
$WORKON_HOME is properly defined; I use elpy1.6 but I never loaded pyvenv manually.
Best,
Dominik
Can pyvenv-workon
be marked as safe local variable, or does this variable cause some potentially risk code to be called?
Marking it as safe would avoid the prompt for unsafe local variables when this variable is set.
pyvenv should provide a list mode which shows all available (virtualenvwrapper) environments and also details on the current virtualenv.
When the virtualenv changes, pyvenv could warn about processes that ran from the old virtualenv.
That is, if (executable-find (car (process-command proc)))
changes for any proc
in (process-list)
by changing the virtualenv, then we should warn about this process still using the old virtualenv.
As noted in these comments, Python 3 on Windows apparently does not follow the standard virtualenv structure and puts python.exe
in the virtualenv root, while creating both bin
and Scripts
, but does not include python.exe
in Scripts
.
How do virtualenvs on Windows get activated? What directory/ies is/are put into PATH
?
Hello,
It seems like the function for virtualenvwrapper_cd is not being found inside my emacs. When pyvenv-run-virtualenvwrapper-hook is run I get this error:
Output from the virtualenvwrapper hook post_activate:
/var/folders/3t/kgfvxm6x49df9t0y0k4gx2140000gn/T/pyvenv-virtualenvwrapper-41735Zaa: line 6: virtualenvwrapper_cd: command not found
Otherwise things seem to be working. I am assuming this is working and an OS X environment thing. Any hints? It seems to be able to find virtualenvwrapper_cd from a shell within emacs.
I'm using Spacemacs and I run M-x pyvenv-workon
, then select my virtual environment. But when I run any tests from within the project, they cannot find my modules.
Would make interactive use of this package easier…
For me it seems that the pyvenv package is breaking my exec-path, when I activate the virtual environment. The exec-path looks like this originally:
("c:/Users/sam/Envs/test/Scripts" "c:/ProgramData/Oracle/Java/javapath"
...)
After I have activated the virtual environment my exec-path looks like this:
("c" "\\Users\\sam\\Envs\\test\\Scripts;c" "\\ProgramData\\Oracle\\Java\\javapath;c" ...)
Making it unable to find my bash, git, etc.
Do I miss something or is this a bug?
I'm not quite sure about this but it seems to me that postactivate
script of my virtualenvironment isn't run. I have created my venv with virtualenvwrapper and defined some environment variables in postactivate
. However, these variables are not available after running pyvenv-workon
although the virtual environment seems to be otherwise properly activated. Is this to be expected, is there a bug somewhere or am I doing something wrong?
Hi there,
Is there a way to make C-c C-c and C-c C-p start an instance of the virtualenv-local python interpreter, instead of the global one? This magically works as long as pytjon-shell-interpreter is set to Python, but it doesn't if python-shell-interpreter is set to, e.g., python3
.
I guess this would mean setting python-shell-interpreter variable locally when a virtualenv is activated?
Sorry if I'm misunderstanding something simple here.
Quotes around hashbangs are not recognised and are considered invalid syntax, at least on Bash on OS X 10.12. There's really no workaround to paths containing spaces, except maybe symlinking the directory in the path the contains the space. Maybe a warning message about this would be best.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.