packaging-problems icon indicating copy to clipboard operation
packaging-problems copied to clipboard

How to set a complete wheel filename ?

Open frchalaoux opened this issue 2 years ago • 18 comments

Problem description

I'm looking for to create a wheel filnameme with complete a wheel filename as I can see on Pypi wheel files of many projects and avoid to use setup.cfg or other tools as it is describe at https://packaging.python.org/en/latest/tutorials/packaging-projects/

Actually I'm using the build package and the build-backend Hatch to generate my wheel file (pyprojectfile.toml).

I wish to obtain a shape wheel filename as {dist}-{version}(-{build})?-{python.version}-{os_platform}.whl, i.e for my project, cleanmysurface-0.0.3-cp310-cp310-macosx_10_9_x86_64.whl

with my build command :

python -m build

I obtain a wheel filename cleanmysurface-0.0.3-py3-none-any.whl

As I understand the effecting mapping is :

name --> cleanmysurface version --> 0.0.3 build --> py3 python.version --> none os_platform} --> any

but I want to obtain :

name --> cleanmysurface version --> 0.0.3 build --> py310 python.version --> py310 os_platform --> macosx_10_9_x86_64

Are my metadata correct ? Do I need an another tool to create this wheel (Poetry, Flit, ...) ?

pyproject.toml :

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "cleanmysurface"
version = "0.0.3"
authors = [
{ name="blabla", email="[email protected]" },
]
description = "A melange package to calculate your mixture to clean surfaces"
readme = "README.md"
requires-python = ">=3.10"
platform = "macosx_10_9_x86_64"

classifiers = [
"Programming Language :: Python :: 3.10",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
]

[project.urls]
"Homepage" = "https://github.com/blabla/melange"
"Bug Tracker" = "https://github.com/blabla/melange/issues"`

frchalaoux avatar Dec 29 '22 13:12 frchalaoux

I don’t think it’s correct to expect py3 or py310 twice in the filename — there is one tag that indicates python version compatiblity.

For the platform, the tag is only needed if the project is not OS-independent, meaning it contains compiled modules: is that the case for you? Your classifier indicates the contrary. And we don’t add platform in the project metadata, it’s the build backend that adds if necessary. This is a distinction to make: tags in wheel filenames are metadata about this build, distinct from the project metadata in pyproject.toml.

merwok avatar Dec 29 '22 16:12 merwok

Thanks Eric, it's a bit clearer but how to set in the wheel filename py310 to indicate the wheel is specific to a particular release ? I want to create wheels for 3.8, 3.9, 3.10 ! Should I do it manually after the build ?

You said : "This is a distinction to make: tags in wheel filenames are metadata about this build, distinct from the project metadata in pyproject.toml." However, where are set the metadata about the build ?

frchalaoux avatar Dec 29 '22 16:12 frchalaoux

That’s what I’m saying, you don’t define wheel metadata directly, it’s the job of the wheel build tool to create the correct filename depending on inputs. You define whether the build has compiled modules or not, if it’s compatible with multiple python versions or just one, etc (following the docs of your chosen build backend), then you get one or more wheels.

What is the goal you want to achieve here by manually controlling wheel tags?

merwok avatar Dec 29 '22 17:12 merwok

The goal of the my wheel tags is to produce wheel filename for specific to each version of python (3.8, 3.9, 3.10)

frchalaoux avatar Dec 30 '22 04:12 frchalaoux

I have a PR to wheel that would allow this to be retagged later (https://github.com/pypa/wheel/pull/422, waiting on me to add one more change) - that would allow this to be changed easily after producing the wheel. Otherwise, it's quite tricky to get this done in a supported way, as it's very, very rarely needed. The build backend can add support for a configuration option to change this output; scikit-build-core can output python-indpendenct but platform dependent wheels via a configuration option, for example. I don't know if hatching has a setting for Python version only (CC @ofek) - I know setuptools does not, and you have to override private wheel-building implementation details to do it there. There are very few reasons to tag a wheel with Python version only - it's usually detrimental. The only one I know of is if you need to store something generated from the Python version-specific unicode table as a data file (~~wcmatch~~ backrefs does this).

henryiii avatar Dec 30 '22 14:12 henryiii

I don't know if hatching has a setting for Python version only

No there is no such option. You can either infer the most specific tag or set the full tag. I could add such an option but it seems like a rather fringe use case.

ofek avatar Dec 30 '22 14:12 ofek

rather fringe use case

Yes, I think this is why setuptools doesn't have it either. I think it's easy to misuse, too. I could see users wanting to set this even though they don't need it. You really specifically need to be generating something from the current version of Python that can't be made from a different one. (And in ~~wcmatch~~ backrefs's case, it's only a speed optimization & working around the fact you can't run an arbitrary prepare step on install)

henryiii avatar Dec 30 '22 15:12 henryiii

Just a small correction, wcmatch does not require this, it is the much lesser-used package backrefs that was previously used as a dependency for wcmatch with the intent to leverage its Unicode tables for named groups.

The reality was that I had never actually plugged the ability into wcmatch to leverage the Unicode tables and was still unknowingly using ASCII results for named groups in wcmatch. backrefs has since been removed as a dependency of wcmatch, since the Unicode support was never actually used and no one ever noticed or requested to have Unicode named group support added in wcmatch in the all the time I've supported the package. If users ever push for Unicode named groups in wcmatch over the current ASCII ones, I'll probably just always use the latest Unicode version at the time, regardless of Python version.

As backrefs is injecting Unicode properties into regular expression support (as a wrapper around RE) it needed to be consistent with that version of regular expression which is tied to a very specific Unicode support. This package is very niche and probably not used by many, to be fair.

With all of that said, while I think it would be nice to have support, I can also see why there may not be interest in adding such support. As it is so niche, I found the custom build hook to be fine: https://github.com/facelessuser/backrefs/blob/master/hatch_build.py#L62.

facelessuser avatar Dec 30 '22 15:12 facelessuser

Ahh, that's nice that hatchling supports this via a custom build hook. That's similar to the way you can do it with setuptools + wheel, but with those, you have to use a private API.

henryiii avatar Dec 30 '22 15:12 henryiii

Ahh, that's nice that hatchling supports this via a custom build hook. That's similar to the way you can do it with setuptools + wheel, but with those, you have to use a private API.

Agreed. I'd be interested to see if anyone beyond my single package requires this though 🙃.

If I'm not the only outlier case, then I can see some formal, non-private API solution being a nice addition. If I'm the only special case, then I guess I'm happy as long as I am still using Hatchling as it provides what I currently need.

facelessuser avatar Dec 30 '22 16:12 facelessuser

The goal of the my wheel tags is to produce wheel filename for specific to each version of python (3.8, 3.9, 3.10)

But what is the goal of that?

merwok avatar Dec 30 '22 19:12 merwok

Like that the distribution on PyPi will easer to choose the right version to install

frchalaoux avatar Dec 31 '22 09:12 frchalaoux

Like that the distribution on PyPi will easer to choose the right version to install

That simply isn't true. Any tool capable of installing a wheel knows how to handle py3-none-any wheels, and having fewer wheels (i.e., one) will be easier for end users. Unless there is an actual difference in the code you distribute for the Python 3.10 and Python 3.11 wheels, there is no benefit in having separate py310 and py311 wheels.

pfmoore avatar Dec 31 '22 10:12 pfmoore

But if my wheel contains some pyc !?

frchalaoux avatar Jan 02 '23 14:01 frchalaoux

Your wheel shouldn't contain pyc files. The installer will typically build the pyc files when installing the package, and in any case, Python will automatically build them as needed.

pfmoore avatar Jan 02 '23 15:01 pfmoore

The propose of my work is to make tests with my future customers. As I have not choosed my company model of development I will not give my code at the beginning. Can you understand ?

frchalaoux avatar Jan 02 '23 17:01 frchalaoux

It's pretty trivial to reverse engineer pyc files to python code, so I don'ty think you're doing much more than lightly obfuscating your code, but sure. If that's why you're shipping wheels containing only pyc files, then for that you will need to tag explicitly for the Python version. But you'll be fighting the tools a lot, as this is not a common use case and isn't specifically supported by the tools. So yes, you will have to do a lot of things, like setting the tags, manually.

Presumably you are distributing the code privately, not via PyPI? If you ship your code on PyPI, distributing just pyc files won't be very effective for protecting your private code...

pfmoore avatar Jan 02 '23 18:01 pfmoore

"It's pretty trivial to reverse engineer pyc files", yes it seems but it's only for the beginning, after I will certainly share the code with an another model to sale this software and certainly in Open Source. Thanks a lot for the discussion on this topic !

frchalaoux avatar Jan 03 '23 10:01 frchalaoux