Taking into account everyoneās the feedback here, hereās a proposal for a followup to handle the use cases presented and making the project/distribution/specific artifact license clear and explicit, balanced with trying to minimize additional complexity for the simple cases and requiring further churn for projects already adopting PEP 639.
Pyproject metadata
Keep the semantics of license = str the same as now, i.e. this is the license of all distributions.
To handle the more complex cases discussed here (and also be more explicit), allow table subkeys containing license expressions under license, which may be included in any combination to express the specificity required:
project - License(s) under which code is contributed to the project, i.e. the āproject licenseā
distribution - License(s) that apply to all distributions of the project;
sdist - License(s) that apply specifically to the source distribution, in addition to those in distribution
wheels - Licenses that apply specifically to all wheels, in addition to those in distribution
wheeltag - Table, which subkeys that are each a wheel tag, containing an additional license expression specific to that tag.
Keys other than project and distribution can be specified as empty strings if desired to be explicit that the relevant context has no additional licenses.
Making sdist, wheels, etc. additive minimizes extra verbosity and duplication, while still giving an equivalent result if users do duplicate the rest of the distribution license, and allowing specifying disjoint/complete sdist and wheel licenses as distribution is not required.
Alternatively, we could have wheel(s) be a table with the tags as subkeys, with a special all key for what wheels is now and possibly still allowing wheels to be a string value if all wheels have the same licenses.
In distribution core metadata
License-Expression is clarified to mean specifically the license expression that applies to the distribution artifact containing said core metadata (currently it is the same for all artifacts). For an sdist, license.distribution + license.sdist, for a wheel license.distribution + license.wheels + any matching license.wheeltags.
Project-License is added, the license expression for new code contributed to the project/the root LICENSE.txt. (Or in theory we could reuse the old LICENSE field for this, loosening the constraint that it must be a SPDX expression, though upon further thought probably not worth it).
Dynamic behavior
For the case described above where everything is specified statically in pyproject.toml, License-Expression would not need to be marked dynamic there. It would seem to need to be either marked dynamic or special-cased in the PEP 643 sdist metadata, since it cannot be copied verbatim into the wheel (instead, it needs to be retrieved from the static pyproject.toml instead).
Ideally, tools would be able to automatically determine the licenses of code/binaries they vendor into wheels, or perhaps the sdist as well. License-Expression could be marked dynamic in these cases, and with @henryiii 's PEP for partially-dynamic metadata, conceivably baseline license(s) could be specified in pyproject.toml up to the desired degree of specificity, and/or licenses not detected by standard tools manually added, with the rest added automatically at build time in the appropriate contexts. Alternatively, tooling could be used pre-build to update the static values in pyproject.toml, without the need for dynamic.
PyPI UI/UX
On the project main page, PyPI would if provided display āproject licenseā and ādistribution licenseā. āProject licenseā is Project-License (project.license), while ādistribution licenseā is License-Expression if it is identical between all artifacts for the latest release (or equivalently, if only either license = str or license.distribution is specified in the pyproject.toml with no further per-distribution specificity).
If distribution license varies between distributions, then the value of āDistribution licenseā is the link āSee distributionsā (or equivalent wording, e.g. āSee per-file informationā), which links to the Files page that would now list the license next to each artifact (or, less ideally, at least list this on the view details page).