-
Notifications
You must be signed in to change notification settings - Fork 169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
setup.py: build 'universal' py2.py3 wheels #595
setup.py: build 'universal' py2.py3 wheels #595
Conversation
unlike the case of a DLL that is dynamically loaded by the current process and thus needs to have the same bitness, in your case you always build 64-bit native executables (with the exception of autohintexe, I think), and then run them as subprocesses. This means that it doesn't matter if Python interpreter was compiled for 32-bit as long as the host machine can run 64-bit executables. This means we don't need two wheels for windows that have exactly the same content (same pure-python lib, and same 64-bit executables), but only differ because of the wheel platform tag. We can actually merge the two platform tags with a dot (like I did for the python version tag |
Nope. On Windows we're always building 32-bit executables. If you look at the Visual Studio files you'll see that there's no 64-bit configuration. |
ah, ok (why?). |
looks like cibuildwheel is failing on macos because it's assuming the names of the wheels generated by the different pythons are unique, whereas here the py36 produces a wheel which is identical (both in content, and now also in the filename) to the one produced by the previos py27 environment, and the two are sharing the same filesystem. |
Unfinished work.
Since it's not possible to make a fat wheel for Windows, I prefer you keep the distinction between 32- and 64-bit there. |
from the point of view of the afdko (where you want to build standalone executable once, with a relatively recent toolchain, unlike for python extensions without concerns with python ABI compatibility issues), the only advantage of cibuildwheel (or the similar one, multibuild) is that it makes it easier to build the manylinux1 wheels (pulls the docker image and runs the command inside the old CentOS 5 to make the wheel portable across distros). But for mac or windows it doesn't add anything to running the same commands in the Travis or Appveyor environments. Ideally, what you'd do is: build the py2.py3 wheel only once, and then install and test it on all the supported environments. You don't need to rebuild the same thing over and over, it's going to be exactly the same if you build it under py27, py36 or py37. And when I say exactly, I mean it. |
Also, I don't think the coverage numbers will be correct if the results don't go thru a |
@anthrotype it's not clear to me what you're trying to convey in this comment but what I'm trying to say above is that the goal on Windows is to have proper binaries inside those wheels instead of using the 32-bit executables for both. |
that "fat" thing is only for mac Mach-O binaries. I may be wrong but I don't think you're building 32+64 bit executables for mac. You're probably only building 64-bit ones, what xcode would default to nowadays. Sorry i'm digressing. The point is, the afdko wheels are actually "universal" wheel, in the sense that I can take the one tagged cp27-cp27m-win32 and literally rename it cp37-cp37-win_amd64 and pip will install it just fine (despite the metadata in the wheel is not in sync with the filename..), and it will work. Because it is the same! |
so what I'm proposing here is that you make the wheel filename itself reflect its content:
|
FWIW, I'm not making this things up. Other projects have used this very same approach of subclassing |
indeed, it does look suspicious that it fails like that. I'll investigate more tomorrow. what i was trying to say in that comment above was that cibuildwheel was primarily meant for packages that have extension module and need to build many wheels, each one with a different combination of python versions and corresponding compiler toolchains. In your case, the matrix is much simpler as I tried to explain, when you consider that the pure python part of the afdko is (or will be) both py2.py3, and that the native C part is independent of python itself. anyway, we'll discuss this things more next week in Antwerp, I hope ;) |
Sounds good. But for Windows use the architecture tag that reflects the nature of the binaries. It's fine if that tag is not present in the Mac or Linux wheels, since I expect most people are using 64-bit OSes these days anyway.
Never thought you were, especially on these matters. |
I'm not attending ATypI. I get your point about cibuildwheel and the reduced nature of our matrix. But I really enjoy how cibuildwheel takes care of building and testing the wheel, and how uncluttered the appveyor and Travis configuration files are because of that. Is there a way to tailor cibuildwheel to our matrix? We're already using a fork for Travis. |
Maybe related to the coverage combine fail after running pytest-cov with —parallel pytest-dev/pytest-cov#222 |
That seems like a different failure to me, possibly something that we'll run into. |
I’m pretty sure it’s the same thing. I’ve just restarted an Appveyor build from develop branch at the commit just before I created my PR branch, and you can see that with the current pytest-cov setup and the latest version of pytest-cov released two days ago the build fails with the same “No data to combine” error: It appears that new pytest-cov is running combine for us, so when we call it ourselves it fails (can’t be run twice). |
quoting from https://pytest-cov.readthedocs.io/en/latest/config.html
which means that the From time to time I try to use pytest-cov in my projects, then revert back to running plain coverage.py out of frustration.. |
What I meant was that that issue is a new failure that was not happening when I made this change: abd9282 Sure, now we have one more thing to deal with, and I see two options: cap the version of Nonetheless, my earlier comment about the Hope this part of the discussion is clear now. 😃 |
Yes, I understand the need for --parallel-mode. It's just that pytest-cov seems to be handling that somewhat differently from plain coverage.py.
https://pytest-cov.readthedocs.io/en/latest/readme.html but not now, I'll get back to this some other time. |
I've had my share of experimentation around coverage issues for the next six months, at least. So I'm pretty committed to not let anyone break it. 😁 |
@anthrotype sort of related topic: Any ideas on how to get an afdko Windows wheel that is correctly labeled |
the error from the PyPI server is because the filename contain a PEP440 local specifier (+something), which is not allowed to publish. That version string also seems to include a timestamp, and this is generated by setuptools_scm when the working directory is dirty, something is modifying the source files during the build. you can see that the first py27 wheel bears the correct name (from the tag), whereas the subsequent py36 one has the incorrect (local timestamped) version: not sure why this is happening.. |
we could make it build one, given how widespread using 32-bit Python on a 64-bit Windows is. |
honestly, I don't understand why building psautohint from source (which is a dependency in install_requires, so it gets build in a temp folder and installed in the current environment) would affect the source files in a way that makes the working dir "dirty"... |
I was trying to avoid asking for that since the psautohint AppVeyor build takes a long time already. But if you and @khaledhosny can cope with it for a bit —while I work on decommissioning the old autohintexe— I think it might be the simplest solution for now. |
again, we can make the psautohint win32 wheel, but why does that have any influence on this? Installing a dependency from source or from a binary wheel should not modify at all the source files that are committed to version control in a way that makes setuptools_scm generate a dirty version string. |
we could skip the test and only build the wheel for win32 :-P |
you're asking the wrong guy |
Skip the test suite on the py3.6/win32 config? That's fine. The tests on the other configs should be enough to catch any major problems. |
the modification seems to be... stupid carriage returns :( |
Perhaps adding |
which commands created that plist file? |
yes, let's add plist as text format in .gitattributes with eol=lf. |
err.. develop, I meant |
It may be |
yeah, I'll do it |
plist change is in https://ci.appveyor.com/project/adobe-type-tools/afdko/build/1.0.1244 |
In adobe-type-tools/afdko#595 we attempt to build a py2.py3 wheel thus the filename of the wheel is the same as the previous ones, and it causes a shutil.Error https://travis-ci.org/adobe-type-tools/afdko/jobs/424691105#L1460 just remove the previous existing file before moving the new one (they'll be identical anyway, or at least they *should*).
In adobe-type-tools/afdko#595 we attempt to build a py2.py3 wheel thus the filename of the wheel is the same as the previous ones, and it causes a shutil.Error https://travis-ci.org/adobe-type-tools/afdko/jobs/424691105#L1460 just remove the previous existing file before moving the new one (they'll be identical anyway, or at least they *should*).
@miguelsousa sorry Miguel, in the rush I left a syntax error in the previous cibuildwheel PR, so that Appveyor build is probably going to fail. Let's restart after merging https://github.com/adobe-type-tools/cibuildwheel/pull/3 |
oh it looks like you're using the upstream cibuildwheel in that branch, so it probably will not get the SyntaxError |
yep, cancelled. Let's try again... |
The plist change didn't fix it. The wheel is still |
it probably only affects line endings when you add/commit a file, not when the file is modified. Anyway, that .gitattribute modification is still good to have in nevertheless, in case one accidentally commits a plist which has CR in it. Basiclaly, to fix this we need to find out who actually creates that plist file with the CR in it, and make it use LF only. |
plist issue fixed by da23770 |
4b182f8
to
3dcdfec
Compare
I just rebased on |
@anthrotype I hear you, but my paranoid self really doesn't want to include this change in 2.8.0 😬 |
you're the boss :) |
just in case it wasn't clear, this change is only in the filename of the wheel and related metadata, to make pip accept the same wheel file for both major versions of python. It is the same as taking either of the wheel files generated by python2 or python3 and rename it (as in |
It was all very clear before, but thanks for the additional clarification. |
@anthrotype we're now generating a win64 wheel as well (see https://github.com/adobe-type-tools/afdko/releases/tag/2.8.2a). But the win32 wheel now contains 64-bit binaries. Do you know how to fix it? |
@miguelsousa I don't have a PC to check this right now, I will try when I'm back to London next week (do ping me in case I forget). |
@anthrotype thanks. Your comments gave me a few ideas to try out. It's working now. These are the changes I had to make: https://github.com/adobe-type-tools/cibuildwheel/commit/f58d6dac36f063f8442d04cdacb6bae3a333bb63 |
the afdko doesn't include any extenstion modules, only native C executables. These are independent from the Python version, they only depend on the system's platform and architecture (32 vs 64 bit).
You can greatly reduce the number of wheel packages that you build and publish if you name the wheels with a "universal"
py2.py3
tag, an ABI tag of "none" (meaning it does not depend on CPython ABI), and with a platform tag that reflects the different platforms and architecture supported (Linux, MacOS, Windows, 32 vs 64 bit, etc. all automatically selected by bdist_wheel command).I used the same approach in ttfautohint-py, where I bundle a DLL of libttfautohint (wrapped via ctypes). It reduced the number of wheels I publish to only 4: 1 for macOS (a fat "intel" binary including both 32 and 64 bits); 1 for linux (only the
manylinux1_x86_64
, thei686
or 32-bit version is not really needed on linux desktop any more); and finally 2 for windows,win32
andwin_amd64
(on Windows, 32 bit Pythons are still a thing, since the default url from Python.org is still thewin32
version, but I encourage everyone to download the 64 bit version instead).Since the wheel is universal, you can build it either with py27 or with py37 or whatever. It will be the same.