hermancaldara
hermancaldara

Reputation: 491

deactivate virtualenv on Makefile

I am writing a Makefile and I wanna call the virtualenvwrapper command "deactivate" inside Makefile.

The anwser of this thread How to leave/exit/deactivate a python virtualenv? has a comment saying that "deactivate" command is not a binary, nor a script, it's a dinamyc alias shell created when you activate your virtualenv.

So, how can I do that?

Upvotes: 6

Views: 2841

Answers (2)

Vaillancourt
Vaillancourt

Reputation: 1408

Although the currently accepted answer proposes the right approach to being able to deactivate a virtual environment, the reason why it doesn't work as you may have though is not technically right.

As described in the documentation:

When it is time to execute recipes to update a target, they are executed by invoking a new sub-shell for each line of the recipe [...]
Please note: this implies that setting shell variables and invoking shell commands such as cd that set a context local to each process will not affect the following lines in the recipe[...]

So the reason that you can't deactivate a virtual environment on its own recipe line is that the deactivate function that is stored in the caller shell memory does not exist in the shell Make creates for that line.

Assuming that I have these versions of Python installed on my workstation:

temp% py -0
 -V:3.11 *        Python 3.11 (64-bit)
 -V:3.8           Python 3.8 (64-bit)
 -V:3.7           Python 3.7 (64-bit)
 -V:2.7           Python 2.7

We assume that my default Python version is 3.11, and we'll create a virtual environment using version 3.8, just so that when we do python -V, we printout the currently used version. With the Makefile:

pymakevenv:
    @py -3.8 -m venv myvenv

pyvenvtestgood:
    @source myvenv/Scripts/activate;python -V;deactivate;python -V

pyvenvtestbad:
    @source myvenv/Scripts/activate;python -V
    @python -V;deactivate;python -V

We can get the following results:

temp% gmake pymakevenv
temp% gmake pyvenvtestgood
Python 3.8.10
Python 3.11.3
temp% gmake pyvenvtestbad
Python 3.8.10
Python 3.11.3
/usr/bin/sh: deactivate: command not found
Python 3.11.3
temp%

In pyvenvtestbad, we see that the deactivate function set on the first line is no longer there on the second line.

Upvotes: 1

André Augusto
André Augusto

Reputation: 1375

As seen in virtualenvwrapper code, deactivate is a function that is sourced into your env when you use workon.

I think that, for security reasons, make does not give access inside Makefile to current users functions and alias. So, inside your Makefile, you should source virtualenvwrapper.sh, workon on the virtualenv you want and then you'll have access to your deactivate command.

Being axe a target you have on your Makefile and brings_axe a virtualenv you already have, you should do something like this:

axe:
    source virtualenvwrapper.sh; workon brings_axe; deactivate

Upvotes: 5

Related Questions