运行setup.py时,如何获取Python wheel的文件名? [英] How do you get the filename of a Python wheel when running setup.py?

查看:209
本文介绍了运行setup.py时,如何获取Python wheel的文件名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用以下命令创建Python轮子的构建过程:

I have a build process that creates a Python wheel using the following command:

python setup.py bdist_wheel

构建过程可以在许多平台(Windows,Linux,py2,py3等)上运行,希望保留默认的输出名称(例如 mapscript-7.2-cp27-cp27m-win_amd64.whl )以上传到PyPI。

The build process can be run on many platforms (Windows, Linux, py2, py3 etc.) and I'd like to keep the default output names (e.g. mapscript-7.2-cp27-cp27m-win_amd64.whl) to upload to PyPI.

是否仍然可以获取生成的转轮的文件名(例如 mapscript-7.2-cp27-cp27m-win_amd64.whl )并保存到变量中,这样我以后可以在脚本中进行测试了吗?

Is there anyway to get the generated wheel's filename (e.g. mapscript-7.2-cp27-cp27m-win_amd64.whl) and save to a variable so I can then install the wheel later on in the script for testing?

理想的解决方案是跨平台。我当前的方法是尝试清除文件夹,列出所有文件,然后选择列表中的第一个(也是唯一一个)文件,但是,这似乎是一个非常棘手的解决方案。

Ideally the solution would be cross platform. My current approach is to try and clear the folder, list all files and select the first (and only) file in the list, however this seems a very hacky solution.

推荐答案

setuptools



如果您使用 setup.py 脚本来构建wheel分布,则可以使用 bdist_wheel 命令查询滚轮文件名。这种方法的缺点是它使用 bdist_wheel 的专用API,因此代码可能会在 wheel 包更新时中断。

setuptools

If you are using a setup.py script to build the wheel distribution, you can use the bdist_wheel command to query the wheel file name. The drawback of this method is that it uses bdist_wheel's private API, so the code may break on wheel package update if the authors decide to change it.

from setuptools.dist import Distribution


def wheel_name(**kwargs):
    # create a fake distribution from arguments
    dist = Distribution(attrs=kwargs)
    # finalize bdist_wheel command
    bdist_wheel_cmd = dist.get_command_obj('bdist_wheel')
    bdist_wheel_cmd.ensure_finalized()
    # assemble wheel file name
    distname = bdist_wheel_cmd.wheel_dist_name
    tag = '-'.join(bdist_wheel_cmd.get_tag())
    return f'{distname}-{tag}.whl'

wheel_name 函数接受与传递给 setup()函数的参数相同的参数。用法示例:

The wheel_name function accepts the same arguments you pass to the setup() function. Example usage:

>>> wheel_name(name="mydist", version="1.2.3")
mydist-1.2.3-py3-none-any.whl
>>> wheel_name(name="mydist", version="1.2.3", ext_modules=[Extension("mylib", ["mysrc.pyx", "native.c"])])
mydist-1.2.3-cp36-cp36m-linux_x86_64.whl

请注意,本机库的源文件(<$ c $上面示例中的c> mysrc.pyx 或 native.c )不必存在来组装车轮名称。如果本机lib的源尚不存在(例如,稍后通过SWIG,Cython或其他方式生成它们),这将很有帮助。

Notice that the source files for native libs (mysrc.pyx or native.c in the above example) don't have to exist to assemble the wheel name. This is helpful in case the sources for the native lib don't exist yet (e.g. you are generating them later via SWIG, Cython or whatever).

这使得 wheel_name 可以在 setup.py 脚本中轻松重用,您可以在其中定义分发元数据:

This makes the wheel_name easily reusable in the setup.py script where you define the distribution metadata:

# setup.py
from setuptools import setup, find_packages, Extension
from setup_helpers import wheel_name

setup_kwargs = dict(
    name='mydist',
    version='1.2.3',
    packages=find_packages(),
    ext_modules=[Extension(...), ...],
    ...
)
file = wheel_name(**setup_kwargs)
...
setup(**setup_kwargs)

如果要在安装脚本之外使用它,则必须组织对 setup()的访问会使自己变大(例如,从 setup.cfg 脚本或任何其他内容中读取它们)。

If you want to use it outside of the setup script, you have to organize the access to setup() args yourself (e.g. reading them from a setup.cfg script or whatever).

这部分是基于我对setuptools,提前知道本机库的wheel文件名

如果使用诗歌,因为所有相关的元数据都存储在 pyproject.toml 中。再次,这使用了一个未记录的API:

Things can be simplified a lot (it's practically a one-liner) if you use poetry because all the relevant metadata is stored in the pyproject.toml. Again, this uses an undocumented API:

from clikit.io import NullIO

from poetry.factory import Factory
from poetry.masonry.builders.wheel import WheelBuilder
from poetry.utils.env import NullEnv


def wheel_name(rootdir='.'):
    builder = WheelBuilder(Factory().create_poetry(rootdir), NullEnv(), NullIO())
    return builder.wheel_filename

rootdir 参数是包含 pyproject.toml 脚本的目录。

The rootdir argument is the directory containing your pyproject.toml script.

AFAIK flit 无法使用本机扩展构建轮子,因此只能给您purelib名称。但是,如果您的项目使用 flit 进行发行版本构建,则可能会很有用。注意,这也使用了未公开的API:

AFAIK flit can't build wheels with native extensions, so it can give you only the purelib name. Nevertheless, it may be useful if your project uses flit for distribution building. Notice this also uses an undocumented API:

from flit_core.wheel import WheelBuilder
from io import BytesIO
from pathlib import Path


def wheel_name(rootdir='.'):
    config = str(Path(rootdir, 'pyproject.toml'))
    builder = WheelBuilder.from_ini_path(config, BytesIO())
    return builder.wheel_filename



实施您的自己的解决方案



我不确定是否值得。不过,如果您想选择此路径,请考虑使用 packaging.tags 之前,您会发现一些已过时的旧东西,甚至决定自己查询平台。不过,您仍然必须依靠私人工具来组装正确的车轮名称。

Implementing your own solution

I'm not sure whether it's worth it. Still, if you want to choose this path, consider using packaging.tags before you find some old deprecated stuff or even decide to query the platform yourself. You will still have to fall back to private stuff to assemble the correct wheel name, though.

这篇关于运行setup.py时,如何获取Python wheel的文件名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆