Skip to content

Instantly share code, notes, and snippets.

@MichaelCurrin
Last active September 5, 2020 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MichaelCurrin/61c456f591af67d261cd40d0d6d6ec37 to your computer and use it in GitHub Desktop.
Save MichaelCurrin/61c456f591af67d261cd40d0d6d6ec37 to your computer and use it in GitHub Desktop.
Pip freeze alternative
#!/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