88

I'm poking around the various options to setup.py for including non-python files, and they're somewhat less than intuitive. I'd like to be able to check the package generated by bdist_wheel to see what's actually in it--not so much to make sure that it will work (that's what tests are for) but to see the effects of the options I've set.

How do I list the files contained in a .whl?

kmario23
  • 57,311
  • 13
  • 161
  • 150
Andrew
  • 4,058
  • 4
  • 25
  • 37
  • 7
    Pretty sure [it's a zip file](https://pypi.python.org/pypi/wheel). – Peter Wood Oct 03 '15 at 15:07
  • Regarding the "not so much to make sure that it will work": some checklist items are unusual subjects for testing, for example making sure that any additional license files accompanying external C libraries that are included in compiled form within the wheel. These items are best checked by listing the wheel's contents. See also: https://stackoverflow.com/questions/24347450/how-do-you-add-additional-files-to-a-wheel – 0 _ Oct 16 '17 at 19:21

6 Answers6

91

You can take the wheel file change the extension to .zip and then extract the contents like any other zip file.

from PEP 427

A wheel is a ZIP-format archive with a specially formatted file name and the .whl extension.

Example

the Django python package has a wheel file. Try Django-1.8.4-py2.py3-none-any.whl as an example. Their package contains non-python files if you wanted to see where they end up being stored in the archive.

Code

The following code works correctly using python2 and python3. It will list the files in any wheel package. I use the pep8 wheel package as an example, whose wheel can be downloaded with pip download --no-deps pep8==1.7.0.

import pprint
from zipfile import ZipFile

path = 'pep8-1.7.0-py2.py3-none-any.whl'
names = ZipFile(path).namelist()
pprint.pprint(names)

Output

['pep8.py',
 'pep8-1.7.0.dist-info/DESCRIPTION.rst',
 'pep8-1.7.0.dist-info/entry_points.txt',
 'pep8-1.7.0.dist-info/metadata.json',
 'pep8-1.7.0.dist-info/namespace_packages.txt',
 'pep8-1.7.0.dist-info/top_level.txt',
 'pep8-1.7.0.dist-info/WHEEL',
 'pep8-1.7.0.dist-info/METADATA',
 'pep8-1.7.0.dist-info/RECORD']
0 _
  • 10,524
  • 11
  • 77
  • 109
Marwan Alsabbagh
  • 25,364
  • 9
  • 55
  • 65
53
unzip -l dist/*.whl

(credit)

Since a wheel is a ZIP file, unzip works. Tab completion for the file name won't work, unless the extension is renamed to zip. The from zipfile import ZipFile approach assumes only the presence of Python in the system, but a one-liner in the shell is more practical.


Another option is to view the contents of the wheel file using vim. This can be done by first adding to the file ~/.vimrc the line:

au BufReadCmd *.whl call zip#Browse(expand("<amatch>"))

(vimrc and BufReadCmd documentation) and then using:

vim filename.whl

within vim, files can be entered by pressing the key ENTER, and exited by typing :q. vim can be exited by typing :q when viewing the directory listing within the wheel file.

0 _
  • 10,524
  • 11
  • 77
  • 109
18

One could use Python's own zipfile module and CLI to list the files in a wheel (or any other zip file):

python -m zipfile --list path/to/my-wheel-file.whl

Or to extract:

python -m zipfile --extract path/to/my-wheel-file.whl path/to/output/directory

There is also tarfile and its CLI. This can be used for source distributions (sdist) for example.

python -m tarfile --list path/to/my-sdist-file.tar.gz
sinoroc
  • 18,409
  • 2
  • 39
  • 70
1

As others have pointed out in the answers, any .whl file can be extracted using unzip or by right clicking on the file and extracting using the Extract Here graphical interface in Ubuntu/Debian systems.

After extracting, one can inspect the source code of .py files and the contents of metadata files which will be located in library-name-with-version.dist-info directory. However, the source code of shared object (.so) files can not be inspected since that's a binary file.


Another handy option would be to use the wheel-inspect package which is specifically built for this purpose. The description of the package is stated as:

wheel-inspect examines Python wheel files & *.dist-info directories and outputs various information about their contents as JSON-serializable objects.

A sample command is:

$ wheel2json some_lib_wheel_file.whl

That would spit out the contents in a json file. If this json file needs to be stored locally, then redirect the output to a json file.

$ wheel2json some_lib_wheel_file.whl > some_lib.json
kmario23
  • 57,311
  • 13
  • 161
  • 150
-1

A simple way (in Windows) is to append a .zip extension to the end of the filename. For example:

somepackage-1.0.0-py3-none-any.whl --> somepackage-1.0.0-py3-none-any.whl.zip

Then just open the file with Windows file explorer and see what files are there. You should change the name back if you need to still use the original file.

RexBarker
  • 1,456
  • 16
  • 14
-3

whl file is just a zip archive, so you can use tar to interact with it:

list contents:

tar -tf dist/somepackage-1.0.0-py3-none-any.whl

print a particular file's contents into the stdout (eg. somepackage-1.0.0.dist_info/METADATA)

tar -Oxf dist/somepackage-1.0.0-py3-none-any.whl somepackage-1.0.0.dist_info/METADATA
botchniaque
  • 4,698
  • 3
  • 35
  • 63
  • 1
    Not true. Wheel is a Zip archive: https://peps.python.org/pep-0427/#abstract -- And then, this answer adds nothing new compared to already existing answers. – sinoroc Sep 20 '22 at 10:25
  • 1
    Thanks for pointing out the format being zip (and not tar). I. would argue that an example of how to use a _built in shell tools_ to inspect your package is valuable (would have been for me). – botchniaque Sep 20 '22 at 11:51
  • `python -m zipfile --list dist/somepackage-1.0.0-py3-none-any.whl` and `unzip -l dist/somepackage-1.0.0-py3-none-any.whl` are already mentioned in other answers. – sinoroc Sep 20 '22 at 11:56