【问题标题】:'pip setup.py bdist_wheel' no longer builds forced non-pure wheels'pip setup.py bdist_wheel' 不再构建强制的非纯车轮
【发布时间】:2016-05-08 20:10:14
【问题描述】:

我有一个在 Linux 上使用 C 扩展编译的项目,但没有 它们在 Windows 上。当我第一次在 Windows 上使用 python setup.py bdist_wheel 生成轮子文件时,它们变得通用,我无法将它们上传到 PyPI,因为这些通用轮子是 pip 首选用于安装 在.tar.gz 上传(python setup.py sdist 的结果)。

解决这个问题的诀窍是在setup.py 中指定:

Distribution.is_pure = lambda *args: False

或通过子类化Distribution:

class BinaryDistribution(Distribution):
    def is_pure(self):
        return False

并在 setup.py 中使用额外的关键字参数 distclass=BinaryDistribution, 调用 setup()

这一切都在我运行 Windows XP 64 的 VM 上运行良好,该 VM 安装了 32 位和 64 位版本的 Python 2.6/2.7/3.3/3.4 和 pypy。一个简单的批处理文件给了我:

dist/pkg-1.0-cp26-none-win32.whl
dist/pkg-1.0-cp26-none-win_amd64.whl
dist/pkg-1.0-cp27-none-win32.whl
dist/pkg-1.0-cp27-none-win_amd64.whl
dist/pkg-1.0-cp33-none-win32.whl
dist/pkg-1.0-cp33-none-win_amd64.whl
dist/pkg-1.0-cp34-none-win32.whl
dist/pkg-1.0-cp34-none-win_amd64.whl

当您在 Windows 上运行 pip 和在 Linux 上运行 pip 时,pip 会下载并安装相应的软件包

pkg-1.0.tar.gz

其中包括在安装过程中编译的 C 源代码。

问题始于我没有可以安装 Python 3.5 的备用 Windows 7 许可机器(它不安装在 EOL XP 上)。于是我调查了Appveyor并创建了appveyor.yml

environment:
  matrix:
    - PYTHON: C:\Python27
    - PYTHON: C:\Python33
    - PYTHON: C:\Python34
    - PYTHON: C:\Python35
    - PYTHON: C:\Python27-x64
    - PYTHON: C:\Python33-x64
      DISTUTILS_USE_SDK: '1'
    - PYTHON: 'C:\Python34-x64'
      DISTUTILS_USE_SDK: '1'
    - PYTHON: 'C:\Python35-x64'

install:
  - |
    %PYTHON%\python.exe -m pip install --upgrade pip
    %PYTHON%\python.exe -m pip install wheel

build: off

test_script:
  - echo Skipped for now

after_test:
  - |
    %PYTHON%\python.exe setup.py bdist_wheel

artifacts:
  - path: dist\*

使用完全相同的来源,上述八次调用python setup.py bdist_wheel 的结果是:

pkg-1.0-py2-none-any.whl
pkg-1.0-py3-none-any.whl

如果您将这些上传到 PyPI,Linux 会更喜欢它们而不是 .tar.gz,从而导致不包含 C 扩展代码。

是什么原因造成的,如何使用 Appveyor 构建我的 .whl 文件(或者至少是 Python 3.5 的文件?

【问题讨论】:

  • 我刚刚遇到了完全相同的问题,使用 Windows 7 和 python 3.5。恢复到车轮 0.24.0 确实解决了这个问题。我尝试查找 Wheel 0.25+ 何时发布,但在 bitbucket repo 上找不到标签。有什么想法吗?
  • @Overdrivr 那是 2015 年 9 月 17 日。通过在pypi 上查找轮子可以轻松找到此类信息(搜索 pypi 本身会显示一些旧版本,或者您自己将 URL 的末尾从 0.26.0 更改)

标签: python windows pypi python-wheel appveyor


【解决方案1】:

我自己在 Windows 7 x64 上使用 Python v2.7 和 Wheel v0.29.0 时遇到了这个问题,我在其中构建了一个带有一些预编译扩展的 Python 包(使用 SWIG 和外部 DLL 进行复杂的 VisualStudio 设置)。

检查源代码后,我发现覆盖 Distribution.has_ext_modules 有效(自动包含平台名称和 ABI 标记):

from setuptools import setup
from setuptools.dist import Distribution

DISTNAME = "packagename"
DESCRIPTION = ""
MAINTAINER = ""
MAINTAINER_EMAIL = ""
URL = ""
LICENSE = ""
DOWNLOAD_URL = ""
VERSION = '1.2'
PYTHON_VERSION = (2, 7)


# Tested with wheel v0.29.0
class BinaryDistribution(Distribution):
    """Distribution which always forces a binary package with platform name"""
    def has_ext_modules(foo):
        return True


setup(name=DISTNAME,
      description=DESCRIPTION,
      maintainer=MAINTAINER,
      maintainer_email=MAINTAINER_EMAIL,
      url=URL,
      license=LICENSE,
      download_url=DOWNLOAD_URL,
      version=VERSION,
      packages=["packagename"],

      # Include pre-compiled extension
      package_data={"packagename": ["_precompiled_extension.pyd"]},
      distclass=BinaryDistribution)

【讨论】:

    【解决方案2】:

    当然,不同之处在于环境,在正常工作的 Win XP 上安装了旧版本的 wheel 软件包 (0.24.0),而在 Appveyor 上安装了最新和最好的(和损坏的)版本 0.26车轮已安装(0.25 也已损坏)。

    更改 YAML 文件中的安装节以修复 wheel 版本:

    install:
      - |
        %PYTHON%\python.exe -m pip install --upgrade pip
        %PYTHON%\python.exe -m pip install wheel==0.24
    

    足以让它快速工作。

    但是,您应该将 Linux 机器上的 wheel 包升级到版本 0.28,然后使用新的命令行选项 --plat-name

    python setup.py sdist
    python2 setup.py bdist_wheel --plat-name win32
    python2 setup.py bdist_wheel --plat-name win_amd64
    python3 setup.py bdist_wheel --plat-name win32
    python3 setup.py bdist_wheel --plat-name win_amd64
    

    这将产生:

    pkg-1.1.tar.gz
    dist/pkg-1.1-py2-none-win32.whl
    dist/pkg-1.1-py2-none-win32.whl
    dist/pkg-1.1-py3-none-win_amd64.whl
    dist/pkg-1.1-py3-none-win32.whl
    dist/pkg-1.0-cp34-none-win_amd64.whl
    

    您可以将其上传到 PyPI 并在 Linux 上下载正确的 (.tar.gz) 文件,并在 Windows 上下载相应的滚轮。通过制作 确保如果指定了 --plat-name win...,则使用 ext_modules=None 调用 setup()。生成的 wheel 文件具有较小的(3 个文件及其 SHA256SUM 中的行结尾),但可以在 Windows 上正常安装。

    这样您就不再需要在 Windows 机器上构建这些包,它们本质上是纯包

    对我来说,Nate Coraor 所做的这一更改使我的总构建时间从 15 多分钟减少到大约 7

    【讨论】:

      【解决方案3】:

      似乎与接受的答案相同但更简洁的替代方法是:

      from setuptools import setup
      
      DISTNAME = "packagename"
      DESCRIPTION = ""
      MAINTAINER = ""
      MAINTAINER_EMAIL = ""
      URL = ""
      LICENSE = ""
      DOWNLOAD_URL = ""
      VERSION = '1.2'
      PYTHON_VERSION = (2, 7)
      
      
      setup(name=DISTNAME,
            description=DESCRIPTION,
            maintainer=MAINTAINER,
            maintainer_email=MAINTAINER_EMAIL,
            url=URL,
            license=LICENSE,
            download_url=DOWNLOAD_URL,
            version=VERSION,
            packages=["packagename"],
      
            # Include pre-compiled extension
            package_data={"packagename": ["_precompiled_extension.pyd"]},
            has_ext_modules=lambda: True)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-29
        • 2020-08-02
        • 1970-01-01
        • 2018-10-02
        • 2019-07-01
        • 1970-01-01
        • 2019-07-09
        • 1970-01-01
        相关资源
        最近更新 更多