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

Add support for pyproject.toml-style configuration (PEP 621) #2924

Closed
wants to merge 55 commits into from

Commits on Dec 20, 2021

  1. Rename config to config.setupcfg

    This will facilitate the implementation of other configuration formats
    (such as pyproject.toml as initially defined by PEP 621)
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    e97fd76 View commit details
    Browse the repository at this point in the history
  2. Extract post-processing functions from config

    We can split the process of interpreting configuration files into 2 steps:
    
    1. The parsing the file contents from strings to value objects
       that can be understand by Python (for example a string with a comma
       separated list of keywords into an actual Python list of strings).
    
    2. The expansion (or post-processing) of these values according to the
       semantics ``setuptools`` assign to them (for example a configuration field
       with the ``file:`` directive should be expanded from a list of file paths to
       a single string with the contents of those files concatenated)
    
    The idea of this change is to extract the functions responsible for (2.)
    into a new module, so they can be reused between different config file
    formats.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    e4b1f1f View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    55c0459 View commit details
    Browse the repository at this point in the history
  4. Configuration menu
    Copy the full SHA
    5fc5170 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    a6a2dea View commit details
    Browse the repository at this point in the history
  6. Extract function to normalise package_data

    … from config to expand
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    4664442 View commit details
    Browse the repository at this point in the history
  7. Extract function to normalise data_files

    … from config to expand
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    299632a View commit details
    Browse the repository at this point in the history
  8. Configuration menu
    Copy the full SHA
    925feb9 View commit details
    Browse the repository at this point in the history
  9. Add cmdclass to expand

    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    160c3a3 View commit details
    Browse the repository at this point in the history
  10. Configuration menu
    Copy the full SHA
    92b2a68 View commit details
    Browse the repository at this point in the history
  11. Configuration menu
    Copy the full SHA
    9dc0a8f View commit details
    Browse the repository at this point in the history
  12. Add tomli as vendorised dependency

    This eventually will allow reading project metadata directly from
    `pyproject.toml`
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    17802ef View commit details
    Browse the repository at this point in the history
  13. Add validate-pyproject as a vendored dependency

    In order to minimise dependencies, `validate-pyproject` has the ability
    to "dump" only the code necessary to run the validations to a given
    directory. This special strategy is used instead of the default
    `pip install -t`.
    
    The idea of using JSONSchema for validation was suggested in pypa#2671,
    and the rationale for that approach is further discussed in
    https://github.com/abravalheri/validate-pyproject/blob/main/docs/faq.rst
    
    Using a library such as `validate-pyproject` has the advantage of
    incentive sing reuse and collaboration with other projects.
    
    Currently `validate-pyproject` ships a JSONSchema for the proposed
    use of `pyproject.toml` as means of configuration for setuptools.
    In the future, if there is interest, setuptools could also ship its own
    schema and just use the shared infrastructure of `validate-pyproject`
    (by advertising the schemas via entry-points).
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    029b9c5 View commit details
    Browse the repository at this point in the history
  14. Implement read_configuration from pyproject.toml

    This is the first step towards making setuptools understand
    `pyproject.toml` as a configuration file.
    
    The implementation deliberately allows splitting the act of loading the
    configuration from a file in 2 stages: the reading of the file itself
    and the expansion of directives (and other derived information).
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    55a9eb7 View commit details
    Browse the repository at this point in the history
  15. Expand dynamic entry_points from pyproject.toml

    The user might specify dynamic `entry-points` via a `file:`
    directive (a similar feature for `setup.cfg` is documented in
    [declarative config]).
    
    The changes introduced here add the ability to expand them
    when reading the configuration from `pyproject.toml`.
    
    [declarative config]: https://setuptools.pypa.io/en/latest/userguide/declarative_config.html
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    ae06587 View commit details
    Browse the repository at this point in the history
  16. Add means to apply and compare pyproject.toml metadata

    The `setuptools.metadata` module contains functions that allows applying
    metadata-related configuration read from a `pyproject.toml` file into an
    existing `dist` object. It also allows comparing metadata obtained from
    different places to check if they are equivalent or not.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    a54da74 View commit details
    Browse the repository at this point in the history
  17. Add means to apply and compare options from pyproject.toml

    The `setuptools.options` module contains functions that allow applying
    non-metadata related configuration that comes from a `pyproject.toml`
    file into an existing `dist` object. Similarly to `setuptools.metadata`,
    comparing options is also allowed.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    8c5a4b7 View commit details
    Browse the repository at this point in the history
  18. Handle distutils command options in setuptools.options

    This change allows comparing and applying command options stored under
    the `[tool.distutils.<COMMAND NAME>]` table in `pyproject.toml`.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    9928786 View commit details
    Browse the repository at this point in the history
  19. Rename setuptools.config.{setupcfg => legacy_setupcfg}

    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 committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    39eeeae View commit details
    Browse the repository at this point in the history
  20. Add ini2toml as a vendored dependency

    Some `ini2toml` modules are removed, since they are not necessary for
    setuptools use case and might require extra dependencies (e.g. CLI
    usage, writing TOML files, format preserving).
    
    --
    
    The automatic conversion of `setup.cfg` into `pyproject.toml` as the
    *one true way* of doing declarative builds was first suggested in pypa#1688.
    
    --
    
    There are advantages and disadvantages in using an external tool such
    as `ini2toml` for the automatic conversion.
    
    The main advantage is that users can use the exact same tool for
    converting their old packages and it will work in the same way
    setuptools works. This means that on top of doing an automatic
    conversion, the users are also offered an alternative to explicitly
    update their package configuration.
    
    The main disadvantage is that `ini2toml` works in a way that is a bit
    more complex than simply parsing the `setup.cfg` file and dumping it as
    `pyproject.toml` (we can think about `ini2toml` as if it was
    transforming an "AST-equivalent" representation of the INI and TOML
    formats -- this is necessary for other use cases covered by the library).
    In order to minimise this complexity, some parts of the
    package are stripped out during the vendoring process.
    
    Also note that currently `ini2toml` ships a "built-in" plugin for
    setuptools. In the future, if there is interest, there is also the
    possibility of moving this plugin directly under setuptools repository.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    c63c58a View commit details
    Browse the repository at this point in the history
  21. Automatically convert setup.cfg => pyproject.toml

    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 committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    6e86080 View commit details
    Browse the repository at this point in the history
  22. Avoid manipulating sys.path in config.expand

    Instead we can used `importlib` to load modules directly from a specific
    path.
    
    (This also seems to prevent some order-dependent errors in the tests?)
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    36518e9 View commit details
    Browse the repository at this point in the history
  23. Configuration menu
    Copy the full SHA
    3c293b5 View commit details
    Browse the repository at this point in the history
  24. Configuration menu
    Copy the full SHA
    ce32429 View commit details
    Browse the repository at this point in the history
  25. Configuration menu
    Copy the full SHA
    f868ad2 View commit details
    Browse the repository at this point in the history
  26. Improve circular imports

    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    d134aaf View commit details
    Browse the repository at this point in the history
  27. Configuration menu
    Copy the full SHA
    a316958 View commit details
    Browse the repository at this point in the history
  28. Configuration menu
    Copy the full SHA
    25ddead View commit details
    Browse the repository at this point in the history
  29. Separate read and apply operations in config.legacy_setupcfg

    This make it easier to re-use the `_apply` function.
    
    The `_apply` function can be used to apply a `setup.cfg`
    file into an existing dist object, and then obtain the metadata and
    options using the `setuptools.{metadata,options}` modules.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    a307352 View commit details
    Browse the repository at this point in the history
  30. Add a way of displaying the diff between 2 objects

    This will be useful to display a message to the user
    if the configuration resulting from reading `setup.cfg` via
    config.legacy_setupcfg or via config.setupcfg differs.
    
    Knowing this diff also facilitates debugging.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    edc8992 View commit details
    Browse the repository at this point in the history
  31. Configuration menu
    Copy the full SHA
    c431c06 View commit details
    Browse the repository at this point in the history
  32. Add a new public API for reading setuptools configuration

    Additionally, deprecate the old `setup.cfg`-only API.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    045123a View commit details
    Browse the repository at this point in the history
  33. Configuration menu
    Copy the full SHA
    38db91c View commit details
    Browse the repository at this point in the history
  34. Configuration menu
    Copy the full SHA
    629d26b View commit details
    Browse the repository at this point in the history
  35. Configuration menu
    Copy the full SHA
    a401091 View commit details
    Browse the repository at this point in the history
  36. Use run_setup to obtain a dist object and apply the new configs

    The `run_setup` function from `distutils.core` allows retrieving the
    distribution object before the configuration is read.
    Then using the new functions from the `setuptools.config` package
    we can apply the TOML-style configuration (either from a
    `pyproject.toml` file or by an automatically converted `setup.cfg`).
    
    To ensure backward compatibility, in the case of discrepancies in the
    conversion of the `setup.cfg` files, the implementation falls back to
    the legacy configuration procedure.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    dabbbf1 View commit details
    Browse the repository at this point in the history
  37. Use the distribution object to run commands in build_meta

    Once we have access to the distribution object, it is no longer
    necessary to fully run the setup script.
    Instead the backend can have more control over the process.
    
    This change build on top of the `_get_dist` function and the
    `distutils.core.run_commands` to trigger commands on the distribution
    object.
    
    For the legacy backend the setup script still runs traditionally
    (but the corner cases are handled directly by `distutils.core.run_setup`)
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    972248f View commit details
    Browse the repository at this point in the history
  38. Replace _get_build_requires by using the dist object

    Now that the dist object is available for the backend, we can simplify
    the workarounds to obtain the `setup_requires` (just reading the
    equivalent attribute in the dist object should suffice)
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    a356376 View commit details
    Browse the repository at this point in the history
  39. Change test_build_meta accordingly

    After the changes in build_meta, some checks in the associated test
    suite are required.
    
    It seems that some assertions are not really needed, but it is important
    to clarify that. For the time being, some skips are added until further
    clarification.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    3dd56ed View commit details
    Browse the repository at this point in the history
  40. Prevent bootstrap problems with vendored dependencies in config

    The `setuptools.config` module needs at least 3 vendored dependencies to
    work, but it seems that this might cause some bootstrapping problems.
    
    This change implements a workaround for that (and add better debugging
    messages).
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    373e201 View commit details
    Browse the repository at this point in the history
  41. Prevent tests from copying the .git/.tox and other heavy folders

    The `tmp_src` fixture copies the setuptools directory to prevent errors
    that appear when running tests concurrently. However it seems that is
    copying everything including the `.git` directory (and possibly others
    like `.tox`). These directories can be quite heavy and error prone to
    copy.
    
    The changes introduced here prevent copying these unnecessary
    folders/files. As a side effect, the tests should run slightly faster.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    0c18c78 View commit details
    Browse the repository at this point in the history
  42. Configuration menu
    Copy the full SHA
    e128ba4 View commit details
    Browse the repository at this point in the history
  43. Make include_package_data=True for pyproject.toml configs

    There seems to be an opinion in the community that
    `include_package_data=True` would be a better default and a quality of
    life improvement.
    
    This change relies on the fact that `ini2toml` will automatically
    backfill `include_package_data=False` for converted `setup.cfg` files
    to implement this change in a backward compatible way.
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    1140792 View commit details
    Browse the repository at this point in the history
  44. Add news fragment

    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    b63a56a View commit details
    Browse the repository at this point in the history
  45. Configuration menu
    Copy the full SHA
    077c2be View commit details
    Browse the repository at this point in the history
  46. Configuration menu
    Copy the full SHA
    3758633 View commit details
    Browse the repository at this point in the history
  47. Configuration menu
    Copy the full SHA
    67f7ef9 View commit details
    Browse the repository at this point in the history
  48. Fix test_bdist_deprecations

    in _distutils/dist/_parse_command_opts a issubclass check is done
    to verify the given command is a subclass of distutils.cmd.Command.
    This check will fail if the command is mocked (the mock object is not a
    class object and will generate a TypeError).
    abravalheri committed Dec 20, 2021
    Configuration menu
    Copy the full SHA
    574cb20 View commit details
    Browse the repository at this point in the history
  49. Configuration menu
    Copy the full SHA
    30cdd31 View commit details
    Browse the repository at this point in the history

Commits on Dec 21, 2021

  1. Configuration menu
    Copy the full SHA
    2c6b144 View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    f765076 View commit details
    Browse the repository at this point in the history
  3. Configuration menu
    Copy the full SHA
    3179349 View commit details
    Browse the repository at this point in the history
  4. [WIP] Attempt to debug failures with cygwin CI

    For some reason it is not easy to replicate the cygwin failures pointed out
    by the CI in the local environment, this commit just adds some extra
    debugging statements so we can have more information about the problem
    abravalheri committed Dec 21, 2021
    Configuration menu
    Copy the full SHA
    fb3dc26 View commit details
    Browse the repository at this point in the history
  5. Configuration menu
    Copy the full SHA
    72904ab View commit details
    Browse the repository at this point in the history
  6. Manually add missing license files for vendored projects

    As pointed out in
    pypa#2924 (comment),
    license files are likely to be required for vendored packages.
    This change manually adds the missing license files for the dependencies
    introduced in the PR 2924.
    abravalheri committed Dec 21, 2021
    Configuration menu
    Copy the full SHA
    bfcafd5 View commit details
    Browse the repository at this point in the history