This should all be addressed in PEP 794: Clarify the default action when `Import-Name` et. al. are not specified by brettcannon · Pull Request #4545 · python/peps · GitHub (which is set to auto-merge).
The way I would expect it to play out is that build backends get updated to support the new format but most project maintainers haven’t heard of this PEP yet and keep producing wheels without setting the new keys rather than choosing not to set them, so tools should not interpret missing fields as confirmation that the project’s only import is its normalized package name. It is a minor point though. If it matters, users will ask the maintainers to add the keys to pyproject.toml. Perhaps some build backends will choose to warn loudly when the keys are missing as well.
I don’t know about anyone else but I don’t go checking the metadata version of my wheels then go read the changelog for the metadata standards in search for new fields to set every time I build a new wheel.
The fields in this PEP are set by the build tools (they’re not set manually by the library author), and the metadata standards have a general recommendation to publishing tool authors to only bump the reported metadata version when the new features are actually being used.
Not true. The fields are derived from the corresponding pyproject.toml fields. The PEP allows for the fields to be marked as “dynamic” so that the build backend can (attempt to) calculate the correct metadata, but this still requires the author to explicitly add something to pyproject.toml.
You’re right that if the project doesn’t use the new pyproject.toml fields, the build backend shouldn’t use the new metadata version. But what happens if we get another metadata version bump (to 2.6), and the package author uses the features added in that bump? There’s no ability to say “metadata version 2.6, but not the bits from 2.5”, so the package author would need to explicitly add import name data at that point.
I don’t think that’s unreasonable, but it is a limitation of the fact that the PEP doesn’t include a way to say “not specified” without the implication that “import name = package name” is a good guess to make. It’s only a guess, though, so it shouldn’t be a problem if it’s wrong ![]()
I did a quick update in PEP 794: Declare names can't be listed in both `import-names` and `im… · python/peps@395f4db · GitHub . The key changes are:
- Projects are explicitly allowed to list their own name to show they are opting into the new metadata instead of relying on the implicit opt-in
- Made it clear you can’t list the same name in both
Import-NameandImport-Namespacesince that’s ambiguous
Otherwise a bunch of grammar and spelling fixes.
Oh btw, is there a way for a package to say “I don’t provide any importable names”? I don’t recall this being discussed. CLI tools like pip come to mind that don’t really have an API that should be imported. Or plugins for e.g. pytest that don’t have a runtime API.
It wasn’t discussed because no one has brought it up until now.
This isn’t about what should be imported but what can be imported. This is why the PEP says that you should still list private module names in case you might have a name conflict (e.g. two project having a _utils module).
Do you have an example of a CLI tool that has absolutely no modules that could be imported, even accidentally? uv does, pip does, black does, ruff does, nodejs-wheel-binaries does. So this seems like a hypothetical that there are CLIs with absolutely no modules that couldn’t get imported (and I honestly expect they all do so that either -m works or for some entry point).
They still have code that pytest can import, so I would argue they do have a runtime API, just not a general purpose one. As such, they still take up space in the overall import namespace.
Nevertheless, I’d be very reluctant to explicitly include pip in pip’s Import-Name metadata. While I guess we can’t avoid the “if the project doesn’t state anything explicitly, it’s OK to assume that the project name is importable” rule, I would prefer it if the PEP was clear on how projects like pip that don’t want to advertise any importable modules should document their intent (even if it is just by noting somewhere in the docs that “despite what our Import-Name metadata says, we do not support importing the pip module”).
There are (non CLI) packages out there with no modules. e.g. oldest-supported-numpy which is just a metapackage with a dependency on an old numpy version or the placebo release of asyncio uploaded to prevent it from shadowing the stdlib version of ayncio. What should they do?
If you want to deal with public/private importable, perhaps extend the spec to allow the value of Import-Name to be suffixed with ; private. This matches the syntax of some HTTP headers, eg Content-Type.
Perhaps a simple way to specify a project installs no importables is if it only has one Import-Name entry with an empty value.
$ unzip -l dist/*.whl
Archive: dist/bids_validator_deno-2.0.9-py2.py3-none-linux_x86_64.whl
Length Date Time Name
--------- ---------- ----- ----
159130350 01-01-2016 00:00 bids_validator_deno-2.0.9.data/scripts/bids-validator-deno
5084 01-01-2016 00:00 bids_validator_deno-2.0.9.dist-info/METADATA
103 01-01-2016 00:00 bids_validator_deno-2.0.9.dist-info/WHEEL
34 01-01-2016 00:00 bids_validator_deno-2.0.9.dist-info/entry_points.txt
1128 01-01-2016 00:00 bids_validator_deno-2.0.9.dist-info/licenses/LICENSE
579 01-01-2016 00:00 bids_validator_deno-2.0.9.dist-info/RECORD
--------- -------
159137278 6 files
It’s similar to how you use Requires-Dist to specify what extra it’s attached to, e.g. numpy; extra == "stuff".
@pf_moore are you okay with that idea? I’m personally fine with it as it’s still easy to parse out and doesn’t lead to some separate key in pyproject.toml.
I was already thinking that the PEP could explicitly say an empty array is allowed and so you put an empty e.g. Import-Name in the metadata (which works with the email parser; I checked).
Yep, that works for me.
PEP 794: Introduce a way to specify private import names (#4567) · python/peps@0c883a7 · GitHub covers:
- Adding the
; privateidea from @EpicWink so people can delineate public from private import names - Explicitly said an empty
Import-Name, which you can make withimport-names = []means there are absolutely no modules in a distribution file
As a reminder, I will be submitting the PEP for pronouncement next week after the long weekend here in Canada.
Thank you for the work and the submission deadline @brettcannon. The PEP as a whole looks good to me; I did find a couple of small things.
My one substantial comment is about this requirement: “Tools SHOULD raise an error when two projects that are to be installed list names that overlap in each other’s Import-Name entries.” The interpretation of that is a little ambiguous:
- If you meant “installed as part of the same tool invocation" then it would be good to clarify that. And then I agree it’s a very reasonable thing to do, because the final installed tree of two packages installing the same files would otherwise depend on installation order.
- If you meant “installed in the same environment”, then that would also not be unreasonable, but it’d be a larger breaking change in various scenarios with forks, monkeypatching, or mixing package managers. Right now
pip installallows such overwrites, so I’d like to clarify whether you intend to havepipchange that or not (if so, it’d probably need an opt-in flag similar to--break-system-packagesfor such not-best-practice-but-sometimes-useful usage).
More nitpicky: the language in the PEP is mostly but not fully consistent in saying that packages modify pyproject.toml while tools write/modify core metadata. This sentence is an outlier in that respect: “Projects MAY leave Import-Name and Import-Namespace out of the core metadata for a project.“ I’d suggest changing that to be consistent with the other PEP language, since for normal packages there is no way to directly do anything with core metadata.
This is what I was thinking of (and I think what uv brought forward as the issue they have run into).
I can add this as a “MAY” possibility since, as you said, it isn’t unreasonable.
Yeah, that should be “Tools” instead of “Projects”. Thanks for catching that!
I made the changes I said I would in my response to Ralf in PEP 794: Address comments (#4571) · python/peps@e9e61ac · GitHub .
It is now September, and so it’s time to ask poor @pf_moore to pronounce on PEP 794 – Import Name Metadata | peps.python.org .
Those changes look good to me, thanks @brettcannon.