Last active
September 5, 2020 16:49
-
-
Save MichaelCurrin/61c456f591af67d261cd40d0d6d6ec37 to your computer and use it in GitHub Desktop.
Pip freeze alternative
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
""" | |
Pip freeze alternative. | |
Show exact versions of Python packages in a virtual environment, matching | |
ONLY libraries named in the requirements file, in order to give a shorter version | |
of pip freeze output. | |
The logic in this script: | |
- requirements.txt doesn't always have versions or exact versions it. | |
- pip freeze can be long because of the subdependencies which you don't care | |
about mostly. | |
- do a join of the above two with this script, then you see just the libraries | |
listed in requirements but with exact installed version numbers extracted | |
from pip freeze. | |
Matches are done case insensitively but note that if the installed name is | |
different from the requirement it will not show up. | |
e.g. Installing bs4 will install bs4 and then beautifulsoup4 | |
The output order is alphabetical (based on pip freeze output). As using the | |
order of requirements file and looking up against installed packages is more | |
involved. | |
This is a python3 script which should exist in your ~/bin directory as an | |
executable to be run from anywhere. | |
This is intended to be run from a directory which is the the root of a | |
Python project (i.e. it contains a requirements.txt file) and where the | |
project's virtual environment is activated. | |
Usage: | |
$ cd <PATH_TO_PYTHON_PROJECT> | |
$ source venv/bin/activate | |
$ freeze_short | |
... | |
For comparison with output above: | |
$ cat requirements.txt | |
... | |
$ pip freeze | |
... | |
This could be extended to not just work with requirements.txt such as | |
to handle test-requirements.txt but that usecase is not useful enough now to | |
make this worth extending. | |
""" | |
import re | |
import subprocess | |
PATTERN = re.compile(r'(\w*)(\W.*)?') | |
FREEZE = 'pip freeze'.split(' ') | |
def main(): | |
""" | |
Main command-line function. | |
""" | |
installed_capture = subprocess.run(FREEZE, capture_output=True) | |
installed_list = [x.decode('utf-8') for x in installed_capture.stdout.splitlines()] | |
with open('requirements.txt') as f_in: | |
required_list = [PATTERN.match(line).group(1) for line in f_in] | |
required_set = set(x.lower() for x in required_list) | |
for i in installed_list: | |
name = PATTERN.match(i).group(1) | |
if name.lower() in required_set: | |
print(i) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment