Skip to content

Uploading wheels first broken on macOS High Sierra (OR, wheels should always be uploaded first) #239

@jamadden

Description

@jamadden

It is important to upload .whl files to PyPI first (see pypa/twine#106 for motivation). Up until very recently, this always Just Worked for me. But now, using twine 1.9.1 and zest.releaser 6.12.4, I've been seeing the sdist get uploaded first. Example from this morning:

Upload to pypi (Y/n)?
Uploading zope.annotation-4.6.0.tar.gz
Uploading zope.annotation-4.6.0-py2.py3-none-any.whl

What changed? I'm now running macOS High Sierra on its new filesystem APFS.

twine ensures this happens when you use the command line and specify upload dist/*, but it looks like zest.releaser just does an os.listdir() and feeds the results of that, one filename at a time, to twine, so twine can't reorder the dists appropriately.

Why did this work before? Prior to APFS, the macOS filesystem was HFS+ which was internally organised as a BTree based on filenames. So os.listdir() would return results in sorted filename order, and the first differing character in the sdist and wheel filenames ('.' and '-') sort such that the wheel comes first:

In [1]: chars = ['.', '-']

In [2]: sorted(chars)
Out[2]: ['-', '.']

In [3]: filenames = ['zope.annotation-4.6.0.tar.gz', 'zope.annotation-4.6.0-py2.py3-none-any.whl']

In [4]: sorted(filenames)
Out[4]: ['zope.annotation-4.6.0-py2.py3-none-any.whl', 'zope.annotation-4.6.0.tar.gz']

Under APFS, filenames are returned apparently at random:

Calling readdir(2) on a directory in APFS returns filenames in hash order, whereas HFS+ returns filenames in lexicographical order.

This started as an unexplained support request trying to figure out what happened, but now it's turned into a feature request 😄 : can zest.releaser group wheels first, just like twine does? That would do the right thing on all filesystems (I know that most linux filesystems don't return filenames ordered).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions