PEP 794: Import name metadata

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).

2 Likes

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.

1 Like

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.

1 Like

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 :slightly_smiling_face:

3 Likes

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-Name and Import-Namespace since that’s ambiguous

Otherwise a bunch of grammar and spelling fixes.

3 Likes

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.

2 Likes

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.

1 Like

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”).

3 Likes

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?

3 Likes

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.

1 Like
$ 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
1 Like

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).

2 Likes

Yep, that works for me.

1 Like

PEP 794: Introduce a way to specify private import names (#4567) · python/peps@0c883a7 · GitHub covers:

  • Adding the ; private idea from @EpicWink so people can delineate public from private import names
  • Explicitly said an empty Import-Name, which you can make with import-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.

5 Likes

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 nowpip install allows such overwrites, so I’d like to clarify whether you intend to have pip change 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.

4 Likes

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!

3 Likes

I made the changes I said I would in my response to Ralf in PEP 794: Address comments (#4571) · python/peps@e9e61ac · GitHub .

1 Like

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 .

7 Likes

Those changes look good to me, thanks @brettcannon.

1 Like