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)
另一种选择似乎与已接受的答案相同,但更简洁的是:
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)
当然,不同之处在于环境,在正常工作的 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秒