PEP 660 and setuptools

This is a pretty good summary about the lack of consensus: Standardising editable mode installs (runtime layout - not hooks!).

Some developers consider the behaviour as a “serious long-standing bug” while others are very happy with the trade-off[1] and would experience frustration with a stricter approach, since it can potentially disturb their workflow.

My opinion is that all depends on the target audience and intended usage:

  1. A user that wants to develop incrementally a package and play/tinker with it in the CLI is probably interested in a “loose/lax” implementation that automatically picks up new files (this is required to support important workflows like splitting existing files in smaller pieces or general refactoring).

    • a) Since the existing setuptools behaviour is to allow new files to be automatically recognized, changing the default implementation to a “strict” approach is very likely to be disruptive and frustrate this audience.
    • b) The existing approach to implement this workflow without editable installs is to perform a full-blown install and then manipulate PYTHONPATH to point to the source tree in development (or relevant subdirectory)
      • When specifically talking about setuptools, this alternative approach might not work because of the subtleties and flexibility of package_dir and the arbitrary mappings it allows between the file system tree and the package tree.
  2. A user that wants to test[2] the package (either the final version or an intermediate version after a big chunk of work) is probably interested in a “strict” implementation that emulates as close as possible the installed behaviour of the final distribution artifact.

    • a) AFAIK a “strict” implementation is not provided by the major build backends or by setuptoolsdevelop command. Therefore there is no expectation that an editable install would behave this way[3].
    • b) The existing approach to implement this workflow without editable installs is to run tests[2:1] on top of a full-blown installation of the package after it is build. Tools like tox and nox facilitate this, and the advantages/disadvantages of this approach are relatively well known by the community[4].
    • c) Even if a “strict” editable install is performed, chances are that unwary users[5] would end up invertedly “poisoning” PYTHONPATH during the tests and loosing the benefits of the “strict” approach (e.g. by running the tests directly from the top folder in a flat-layout project).

Because of the reasons in (2.c), I would argue that the main benefits of having a “strict” editable install by default are (unfortunately) undermined. To actively take advantage of an “strict” editable install, the users also need to be aware of PYTHONPATH “poisoning” and all the tricks to prevent it.

Therefore, since these users already have to actively take extra measures to perform a “strict” test methodology, I don’t think it would be problematic to require an “opt in” for “strict” editable installs.

On the other hand, as previously mentioned in (1), if we make the “strict” editable install the default, users would be probably be frustrated by setuptools not fulfilling the existing expectations. (In summary it would be a “breaking change” that would likely upset a lot of users).

It is also important to notice that the audience in (1) has pretty good reasons for wanting editable installs to be “lax/loose”, therefore I think that classifying this trade-off behaviour simply as a long standing bug is an oversimplification.

Proposal

In order to address the comments and concerns presented in the preceding discussions about the theme, my proposal is that setuptools should implement both the “strict” and the “lax/loose” approaches for editable installs. However, when not specified otherwise by the users, the installation should be perfomed in the “lax/loose” mode.

Initially, setuptools can expose an environment variable (e.g. SETUPTOOLS_EDITABLE=strict) to allow users to opt-into the “strict” mode, just as a transitional measure. But after some time, it would be nice if the existing installers provide an interface for the users to change the editable mode to “strict” without having to set environment variable[6]. Merely illustrative example of how that could be done:

pip install -e --strict .
# OR
pip install -e --mode=strict .
# OR
pip install --editable=strict .
# etc…

The installer/build-frontend would then call the PEP 660 hooks passing an appropriate/pre-agreed key/value pair in config_settings. Merely illustrative example:

config_settings = {“editable_mode”: “strict”}
# OR
config_settings = {“strict”: True}
# etc …

  1. In order to automatically pick up new files the implementation also looses the ability of recognizing when a file would not be present in the final distribution. ↩︎

  2. tests here mean not only automated tests but also checks performed manually/in a ad-hoc way by the user. ↩︎ ↩︎

  3. The word expectation is used here in the same meaning as in “managing expectations”. Users may wish editable installs would work in a strict way, but currently when they do pip install -e . they don’t expect it to be strict. ↩︎

  4. There are popular blog posts, conference talks, videos, etc that date as far as 2015 (or even further). For example: Tox tricks and patterns | ionel's codelog ↩︎

  5. In this text I use the unwary user expression to refer to users that (a) are not aware that they should be testing the packages as if it was installed to prevent accidental errors, OR that (b) are not actively interested in taking this extra measures. ↩︎

  6. It seems that there is already some positive support in the pip team about improving the UI for this use case: Implement PEP 660 hooks in setuptools/build_meta.py by ichard26 · Pull Request #2872 · pypa/setuptools · GitHub, Implement PEP 660 hooks in setuptools/build_meta.py by ichard26 · Pull Request #2872 · pypa/setuptools · GitHub. ↩︎

2 Likes