Utku
Utku

Reputation: 2177

How to modify pip in a virtualenv?

I am trying to modify pip, so that after each install or uninstall, my requirements.txt will get updated.

To do so, I have modified the pip file in the bin/ of my virtual env.

pip:

#!/Users/username/ProjectEnv/bin/python3

# -*- coding: utf-8 -*-
import re
import sys

from pip import main

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    status = main()
    if status == 0 or status is None:
        sys.argv = ['pip', 'freeze', '>', '../Project/requirements.txt']
        sys.exit(main())

This didn't work. I have tried printing the command line arguments and putting a breakpoint, but they didn't work as well.

pip:

#!/Users/username/ProjectEnv/bin/python3

# -*- coding: utf-8 -*-
import re
import sys
import pdb
pdb.set_trace()

from pip import main

if __name__ == '__main__':
    for arg in sys.argv:
        print(arg)
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    status = main()
    if status == 0 or status is None:
        sys.argv = ['pip', 'freeze', '>', '../Project/requirements.txt']
        sys.exit(main())

What am I doing wrong here?

Upvotes: 1

Views: 134

Answers (3)

Harald Nordgren
Harald Nordgren

Reputation: 12391

I think you would be better off with a bash script like pip_with_autofreeze.sh:

#!/usr/bin/env sh
pip $@ && pip freeze > requirements.txt

Run it with ./pip_with_autofreeze.sh install flask, for example.

Place the script in some suitable location from your $PATH like ~/bin, and them you can call it from any virtualenv you create in the future. Pip will refer to whatever the virtualenv points it to.

Upvotes: 0

Utku
Utku

Reputation: 2177

The problem was that I was modifying the wrong file. I modified the pip in ProjectEnv/bin/, but that was not the file being executed when I typed, say, pip install some_module.

It took a while to discover this because which pip outputted /Users/username/ProjectEnv/bin/pip as well.

type pip has shown the truth. It outputted: pip is aliased to 'pip3'.

So, this is a nice example of why we should alias which to type. Or, why we should stop using which at all and always use type.

Upvotes: 0

2ps
2ps

Reputation: 15926

You can just call the freeze method yourself on the pip library. It will return a generator that gives you the line-by-line output of what gets printed to the screen in pip --freeze.

from pip.operations import freeze

packages = freeze.freeze()
with open('../Project/requirements.txt', 'w') as f:
    for x in packages:
        f.write(x)
        f.write('\n')

Upvotes: 1

Related Questions