PEP 517 provides a method, config settings, for supplying arbitrary configuration to a build backend. There are no defined semantics for this argument, although there is an example in the PEP showing how pip "might" map command line arguments onto config_settings
.
The setuptools backend appears to implement a part of this suggested interface (it processes a --global-option
key in essentially the way the PEP implies). The flit backend completely ignores config_settings
.
Pip needs a user interface (command line options) to allow users to supply config settings to a backend - but without any agreed semantics, there's probably not much we can do beyond allowing users to specify key/value pairs. It's possible that PEP 518 (or some similar standard) should be extended to allow projects to specify config_settings
in the project build metadata?
Finally, there's pip's --python-tag
option. This currently maps directly to a specific setuptools command line option. Due to the lack of common semantics, there's currently no way to support this under PEP 517 in a backend-neutral way. It may be worth (for the fallback use of the setuptools backend only? as a "better than nothing" approach for all backends?) mapping it to
config_settings = {'--global-option': ['--python-tag', python_tag]}
So, actions to consider:
config_settings
(my view: out of scope for pip)config_settings
(my view: a minimal --build-settings key:value
for now)requirements.txt
(my view: allow --build-settings
in there)--python-tag
(my view: translate to --global-option
for now, review later)Also, apart from the short-term approach for --python-tag
, I propose not implementing any of this until after base PEP 517 support is released. Without more comprehensive buy in from backends, it's hard to see what form config_settings
usage will ultimately take, and it's backends that should drive this, not frontends.
Command line interface for config_settings (my view: a minimal --build-settings key:value for now)
The config_settings
is likely to be specific to a package, so we might want to directly provide: --build-settings package:key:value
?
I'm just going to go ahead and pin this, because we should really remember that this has to be done still.
I still don't think this is urgent. There's been little or no movement on backends making use of the config settings options, and essentially no demand from pip's end users. I'm inclined to think that it might have been better if PEP 517 hadn't included config_settings
, treating it as YAGNI until genuine use cases came up.
If implemented this would give us a route to deprecate and remove the special cases we have for --install-option
, --build-option
, and --global-option
in several places in the code. It is blocked on pypa/setuptools#1928, though, since the way the setuptools backend interprets the options is not currently compatible with the way we do. This also gives us a path to address #2677.
I'm inclined to think that it might have been better if PEP 517 hadn't included
config_settings
, treating it as YAGNI until genuine use cases came up.
Perhaps, but we've crossed that bridge now. :(
TBH, I don't think most users would discover that unimplemented functionality that is "only documented in a PEP", which could be the reason for the lack of end-user demand -- I don't know that I want something, if I don't know that thing exists.
What about: --config-setting=pkg:{"setting1": "value1"}
? That is:
and we can accept it multiple times.
This gives us a few nice properties:
__global__
or *
){
). This would let us support a shorter syntax in requirements files or simple command-lines without ambiguity, like pkg --config-setting={"setting1": "value1"}
\uXXXX
), which may be useful since ensuring the terminal properly accepts (and apps properly read) unicode input may be a challenge on some platforms or environmentsThere are also a few downsides:
\n
in an argument for example, we could get
{"setting1":"va
lue1"}
{"setting1":"va\nlue1"}
This could be mitigated by only supporting --config-setting
in requirements files.
A few other things to consider, in general:
I just stumbled upon this issue when I tried to pass some extra arguments to the setuptools backend.
It took a while until I released that the config settings have not been implemented at all in pip.
When passing --build-option
pip will stop processing.
https://github.com/pypa/pip/blob/master/src/pip/_internal/operations/build/wheel.py#L27..L31
Anything passed in --global-option
is silently dropped later on in the process:
https://github.com/pypa/pip/blob/master/src/pip/_internal/wheel_builder.py#L191..L206
Is there a specific reason why build_options
and global_options
is not passed on as suggested in the PEP? Are you waiting for a more complete design?
Potentially, the documentation could be expanded as well. It still reads as if --build-option
and --global-option
have the effects described in the PEP.
https://github.com/pypa/pip/blob/master/docs/html/reference/pip_wheel.rst#customising-the-build
On a related note, the new config UI should probably be designed to still allow installing wheels of PEP 518 build dependencies (?).
As for my use case: I have a Cython project and have implemented an extra command to transpile the .pyx
sources to the .cpp
outputs. Performing this operation in the isolated build environment simplifies the build process - it's one pip wheel
call. It also avoids another tool for dependency management during building, as the Cython dependency is declared through build-system/requires
.
@pskopnik I think it's a matter of designing + implementing the behavior in pip's implementation.