Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FR] Add support for PEP 643 - metadata for sdists #2685

Open
1 task done
pganssle opened this issue May 25, 2021 · 4 comments · May be fixed by #4698
Open
1 task done

[FR] Add support for PEP 643 - metadata for sdists #2685

pganssle opened this issue May 25, 2021 · 4 comments · May be fixed by #4698
Labels
enhancement help wanted major Needs Implementation Issues that are ready to be implemented.

Comments

@pganssle
Copy link
Member

What's the problem this feature will solve?

Some time ago we approved PEP 643, and I intended to implement it... eventually, but it's been a long time and this is actually a very powerful and useful tool for setuptools in particular to implement.

If done correctly, we should be able to silently and in the background start providing reliable metadata for source distributions to anyone building with new versions of setuptools.

Describe the solution you'd like

On the install/wheel building side, we need to be aware that if we are consuming an sdist that already has version 2.2+ metadata, we take all non-dynamic values from the sdist, and not from setup.py. That way if setup.py and the sdist metadata disagree about a given non-dynamic value, the sdist wins (and we are in compliance with the PEP).

For generating PEP 643 metadata (the bigger and more important job, I imagine), there are several implementations (and they can be progressively and backwards-compatibly implemented):

  1. The most naïve implementation: mark everything as Dynamic and bump the version to 2.2. (This is not a very useful implenentation, but a valid one).
  2. Mark everything as Dynamic if it comes from setup.py, but not if it comes from setup.cfg or pyproject.toml (when [FR] support pep-621 - storing core project metadata in pyproject.toml #2671 is resolved).
  3. Add a mechanism to explicitly mark a value as static or dynamic in setup.py — a wrapper like setuptools.literal_value, for when someone needs to generate something from code, but it's deterministic for any given release. We don't have to worry too much about this being inaccurate if we also ensure that when setup.py and the sdist metadata disagree, the final value from the wheel / installed version is taken from the metadata.
  4. Add heuristics to parse the AST of setup.py and determine when setup() is passed arguments that we can be sure are deterministic. Literal values, things not assigned in if blocks, that sort of thing. I suspect that even a small amount of this sort of thing will allow us to unlock a lot of currently deterministic metadata that we'll otherwise have to mark as dynamic, e.g. anything with a setup.py that looks like this:
setup(
    name="foo",
    version="0.0.1",
    install_requires = ["attrs"],
)

Alternative Solutions

No response

Additional context

See the discussion on the discourse.

Code of Conduct

  • I agree to follow the PSF Code of Conduct
@pganssle pganssle added enhancement Needs Triage Issues that need to be evaluated for severity and status. help wanted major Needs Implementation Issues that are ready to be implemented. and removed Needs Triage Issues that need to be evaluated for severity and status. labels May 25, 2021
@domdfcoding
Copy link
Contributor

This will ultimately need pypi/warehouse#9660 to be merged first, otherwise the sdists won't be uploadable to PyPI.

abravalheri added a commit to abravalheri/setuptools that referenced this issue Dec 11, 2021
In pypa#2685 the plan that the community seems to agree on is to always
automatically translate `setup.cfg` into a `pyproject.toml` equivalent
and then proceed reading/parsing the configuration.

The objective of this change is to open space so we can implement this
way of reading `setup.cfg` in a new `setuptools.config.setupcfg` module
while keeping the legacy way of handling `setup.cfg` around.

The rationale behind keeping the legacy way around is that, to avoid
breaking existing packages during a transition period, we can compare
the old and the new way of parsing the configuration (e.g. via
`setuptools.{metadata,options}.compare`) and in the case they are
conflicting, use the old way and emit a warning asking the user to
report the error.
abravalheri added a commit to abravalheri/setuptools that referenced this issue Dec 11, 2021
This is the initial implementation of the "configuration driver"
that indirectly reads `setup.cfg` by first converting it to a data
structure corresponding to `pyproject.toml` and then expanding it.

This idea is based on the approach defined in pypa#2685.

LIMITATION: Differently from the `legacy_setupcfg` "configuration driver",
`setupcfg` does not support reading other distutils file.
The `find_others` flag is removed because of that.
abravalheri added a commit to abravalheri/setuptools that referenced this issue Dec 20, 2021
In pypa#2685 the plan that the community seems to agree on is to always
automatically translate `setup.cfg` into a `pyproject.toml` equivalent
and then proceed reading/parsing the configuration.

The objective of this change is to open space so we can implement this
way of reading `setup.cfg` in a new `setuptools.config.setupcfg` module
while keeping the legacy way of handling `setup.cfg` around.

The rationale behind keeping the legacy way around is that, to avoid
breaking existing packages during a transition period, we can compare
the old and the new way of parsing the configuration (e.g. via
`setuptools.{metadata,options}.compare`) and in the case they are
conflicting, use the old way and emit a warning asking the user to
report the error.
abravalheri added a commit to abravalheri/setuptools that referenced this issue Dec 20, 2021
This is the initial implementation of the "configuration driver"
that indirectly reads `setup.cfg` by first converting it to a data
structure corresponding to `pyproject.toml` and then expanding it.

This idea is based on the approach defined in pypa#2685.

LIMITATION: Differently from the `legacy_setupcfg` "configuration driver",
`setupcfg` does not support reading other distutils file.
The `find_others` flag is removed because of that.
@GalaxySnail
Copy link
Contributor

FWIW, metadata 2.2 has been supported in warehouse: pypi/warehouse#13606

@abravalheri
Copy link
Contributor

abravalheri commented Sep 5, 2024

The outcome of the discussion in #4629 seems to indicate the following is a viable approach:

  1. Document that plugins are not allowed to dynamically generate inconsistent values for name and version metadata (they may generate these, but the values need to be exactly the same across all builds from both source tree or sdist)
  2. Document that plugins are not allowed to modify values provided statically as metadata in pyproject.toml
  3. When metadata is provided by pyproject.toml, setuptools will mark a field as dynamic only if it is marked as dynamic in pyproject.toml, following PEP 621
  4. When metadata is provided via setup.py, setuptools will add Dynamic for the metadata fields to ensure other tools do not accidentally trust them as static (just in case).

Originally posted in #4629 (comment)

@abravalheri abravalheri linked a pull request Oct 21, 2024 that will close this issue
2 tasks
@abravalheri
Copy link
Contributor

#4698 is an attempt to implement PEP 643. I am trying a slightly unorthodox approach by marking the static values coming from setup.cfg/pyproject.toml instead of the dynamic ones, in an attempt to identify when plugins/customisations overwrite them. I say the approach is unorthodox because I introduce sub-classes of built-in data types. That is a bit awkward, but it makes sure the change is backwards compatible with the existing codebase in both setuptools and distutils.

If anyone is interested in having a look on the approach, please let me know your ideas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement help wanted major Needs Implementation Issues that are ready to be implemented.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants