nsubiron
nsubiron

Reputation: 923

setuptools, know in advance the wheel filename of a native library

Is there an easy way to know the filename of a Python wheel before running the setup script?

I'm trying to generate a Bazel rule that builds a .whl for each Python version installed in the machine, the library contains native code so it needs to be compiled for each version separately. The thing with Bazel is that it requires to declare any outputs in advance, and what I'm observing is that each Python version generates a different filename without obvious consistency (different prefixes for malloc and unicode)

2.7  --> lib-0.0.0-cp27-cp27mu-linux_x86_64.whl
3.6m --> lib-0.0.0-cp36-cp36m-linux_x86_64.whl
3.8  --> lib-0.0.0-cp36-cp38-linux_x86_64.whl

I know as a workaround I could zip the wheel to pass it around, but I was wondering if there is a cleaner way to do it.

Upvotes: 7

Views: 2034

Answers (1)

hoefling
hoefling

Reputation: 66241

Update

See also a more detailed answer here.

You can get the name by querying the bdist_wheel command, for that you don't even need to build anything or writing a setup.py script (but you need the metadata you pass to the setup function). Example:

from distutils.core import Extension
from setuptools.dist import Distribution


fuzzlib = Extension('fuzzlib', ['fuzz.pyx'])  # the files don't need to exist
dist = Distribution(attrs={'name': 'so', 'version': '0.1.2', 'ext_modules': [fuzzlib]})
bdist_wheel_cmd = dist.get_command_obj('bdist_wheel')
bdist_wheel_cmd.ensure_finalized()

distname = bdist_wheel_cmd.wheel_dist_name
tag = '-'.join(bdist_wheel_cmd.get_tag())
wheel_name = f'{distname}-{tag}.whl'
print(wheel_name)

will print you the desired name. Notice that attrs passed to Distribution should contain the same metadata you pass to the setup function, otherwise you will likely get a wrong tag. To reuse the metadata, in a setup.py script this could be combined like e.g.

setup_kwargs = {'name': 'so', 'version': '0.1.2', ...}

dist = Distribution(attrs=setup_kwargs)
...
setup(**setup_kwargs)

Upvotes: 4

Related Questions