'pip setup.py bdist_wheel'不再构建强制非纯轮子

Ant*_*hon 7 python windows pypi appveyor python-wheel

我有一个项目在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
Run Code Online (Sandbox Code Playgroud)

或通过子类化Distribution:

class BinaryDistribution(Distribution):
    def is_pure(self):
        return False
Run Code Online (Sandbox Code Playgroud)

setup()使用extra关键字参数在setup.py中 调用distclass=BinaryDistribution,.

这一切都在我的运行Windows XP 64的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
Run Code Online (Sandbox Code Playgroud)

pip当你pip在Windows上运行时,适当的软件包可以下载和安装,当你pip在Linux上运行时,你可以获得

pkg-1.0.tar.gz
Run Code Online (Sandbox Code Playgroud)

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

问题始于我没有备用Windows 7许可的机器,我可以安装Python 3.5(它不安装在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\*
Run Code Online (Sandbox Code Playgroud)

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

pkg-1.0-py2-none-any.whl
pkg-1.0-py3-none-any.whl
Run Code Online (Sandbox Code Playgroud)

如果你将它们上传到PyPI,Linux会优先.tar.gz考虑不包含C扩展代码.

是什么导致这种情况,我如何使用Appveyor构建我的.whl文件(或者至少是Python 3.5的文件?

小智 15

我刚刚在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)
Run Code Online (Sandbox Code Playgroud)


Cia*_*lsh 6

另一种选择似乎与已接受的答案相同,但更简洁的是:

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)
Run Code Online (Sandbox Code Playgroud)


Ant*_*hon 5

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

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

install:
  - |
    %PYTHON%\python.exe -m pip install --upgrade pip
    %PYTHON%\python.exe -m pip install wheel==0.24
Run Code Online (Sandbox Code Playgroud)

足以让它快速工作。

但是,您应该将 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
Run Code Online (Sandbox Code Playgroud)

这将产生:

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
Run Code Online (Sandbox Code Playgroud)

您可以将其上传到 PyPI 并.tar.gz在 Linux 上下载正确的 ( ) 文件,在 Windows 上下载相应的轮子。通过只是确保,如果--plat-name win...指定的被setup()称为有ext_modules=None。生成的轮文件有次要(以 3 个文件和它们的 SHA256SUM 结尾),但在 Windows 上正常安装。

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

对我来说,Nate Coraor 的这个改变使我的总构建时间从 15+ 分钟减少到大约 7