-
Notifications
You must be signed in to change notification settings - Fork 3k
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
--config-settings
recognizes only the last option
#11681
Comments
--config-settings recognizes
only recognizes the last option
--config-settings recognizes
only recognizes the last option--config-settings
recognizes only the last option
This command solves the problem. pip wheel --config-settings="--build-option=--cffi --avx2" -v . |
I think there's a genuine bug here. Does your workaround work for all backends or does it just happen to work for setuptools because it's splitting ( |
Yes, the behavior is different from the document, reopen the issue. My workaround works for |
Note the following in the
Specifically, there's no requirement on frontends to provide a mechanism for users to specify anything other than a string value. The pip example in the PEP is just an example of how pip might implement For example, what if a user wants to pass a 1-element list to a backend? How would they do that? We can't mandate that backends have to treat a string value the same as a 1-element list containing that value. When I implemented the feature, I toyed with the idea of allowing JSON-encoded non-string values somehow. But supplying such values on the command line rapidly turns into a quoting nightmare, so I backed off and stuck with the minimum required by the standard. Setuptools currently accepts lists by splitting. Maybe all backends should do that? I don't know, and it's not really my choice. It would be a lot simpler for frontends if that was the decision, of course. Having said all of the above, I'm not necessarily against someone trying to implement something more complex. But if you do, be aware that any such behaviour will be very much pip-specific, and you can't assume that other frontends (such as |
My chief concern is that the homonymous option in build does behave differently. Somebody coming from pip to build, or from build to pip, as I assume has happened here, will find the discrepancy between the two tools surprising. I don't have a preference, but I think we shouldn't diverge without good reason. That could very well mean that build adopts pip's model for parsing config settings. |
Good point. IMO, sticking with what's standardised is the correct approach here, which probably means string values only for now. If more complex values are important, then I think the standard needs updating to define the minimal set of types frontends should support. For instance, the build API is a Python API, so there's no reason a backend couldn't choose to interpret strings and numbers differently. |
We ran also into this issue in
+1 - also timely given the "unification of interfaces would be really nice" discussion happening on Discourse.
I don't think there is anything in PEP 517 about this case either way, aside from the example which explicitly shows that |
Agreed, I'd be happy with a simple PR to change the spec. Unfortunately, it looks like no-one has migrated PEP 517 to https://packaging.python.org/en/latest/specifications/ yet, so it would have to be a PR changing the PEP itself (which is less than ideal, but what we've done in the past so I'm not bothered by it). A quick post on discourse, asking if any backend would have a problem with frontends treating duplicated keys as a list of values, should be sufficient to confirm consensus. It might also be worth pointing out that this would mean that backends will never receive a single-element list for an option - instead, that would be passed as a non-list string argument. That's the thing I'm most concerned about (a backend saying "this option is always a list", and not expecting this quirk). To be clear, I'm not expecting any arguments here, I just want to make sure we don't suddenly start sending unexpected config values to backends. |
What do we want to change in the spec? If it's to provide a schema for config settings, I think that'd be a positive change. But if it's to define how command-line options in frontends should behave, that seems a little excessive. It's not unthinkable that another, unaffiliated frontend might wish to read config settings from JSON, like Paul's described above. Personally, I think it's sufficient for pip and build to decide on a common strategy. If we're unsure whether build's or pip's approach is better, or if we believe there's room for improvement, we can continue on Discourse. |
I think this (part in italics is added): "Build frontends SHOULD provide some mechanism for users to specify arbitrary string-key/string-value pairs to be placed in this dictionary. In case a user provides duplicate string-key's, build frontends SHOULD combine the corresponding string-value's into a list of string-values. For example ..."
Either way works for me. It seems like a minimal clarification. |
The one thing that still bugs me is that backends will have to special-case a string value as equivalent to a 1-element list containing that value. I assume setuptools does that, as otherwise the proposed new behaviour wouldn't work at all (and from what I understand it does work in build). But it seems like a weird condition to impose on backends, that they have to allow this. Given that using a space-separated list of values In reality, of course, hardly anyone supports config options, and the setuptools |
Backends do not have to allow this. If they have no use for it, and hence not implement it, then there is also no valid reason for users to provide duplicate keys to the build frontend.
Meson-python for one: mesonbuild/meson-python#235. A single-item list works fine with what both It's possible I think to have a |
So meson-python also translates singe strings to 1-item lists here. Cool. I think the next step is probably for someone to propose a PR to the spec, and a PR for pip. |
Meson (not the PEP 517 build backend) definitely supports receiving config values that contain embedded spaces. In fact, it also supports receiving array types like this: In short, people can put weird things into an option, and having some form of reliably transcribing that is probably useful. One method is of course --config-settings=json-blob. Another method is having --config-settings=shlex-parsed-string. But they're both quoting hell, just to different degrees, so, I agree -- it's probably best to get out of that game as rapidly as possible and just accumulate opaque values to the right side of an equals sign. |
If we’re to change the spec, wouldn’t a simpler solution to make |
@uranusjr that does seem like a nicer design, but it runs the risk of backwards compat issues for some backends I think. If they don't support list of string input, they need to be updated first and then pip would only be able to make that change much later. If it's |
IMO we can adopt the above discussion: Another question, does the key should be stripped? pip wheel --config-settings="--build-option = --cffi" -v . |
If a user is relying on the current behaviour (a later assignment overwrites the previous value), this would still make the backend crash in a weird way since the backend is only expecting to receive str values. If we want to eliminate this, some sort of flags would be needed in the backend anyway for compatibility. Unless we don’t feel this is worth supporting (by telling users that overwriting values was an accident and considered a bug). |
This behavior is different from doc, can be seem as a bug.
Backends probably allow the examples in PEP-517. |
I don't think it's worth supporting, FWIW. |
|
Signed-off-by: Filipe Laíns <[email protected]>
Bumps [pip](https://github.com/pypa/pip) from 23.0.1 to 23.1. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/pypa/pip/blob/main/NEWS.rst">pip's changelog</a>.</em></p> <blockquote> <h1>23.1 (2023-04-15)</h1> <h2>Deprecations and Removals</h2> <ul> <li>Remove support for the deprecated <code>--install-options</code>. (<code>[#11358](pypa/pip#11358) <https://github.com/pypa/pip/issues/11358></code>_)</li> <li><code>--no-binary</code> does not imply <code>setup.py install</code> anymore. Instead a wheel will be built locally and installed. (<code>[#11451](pypa/pip#11451) <https://github.com/pypa/pip/issues/11451></code>_)</li> <li><code>--no-binary</code> does not disable the cache of locally built wheels anymore. It only means "don't download wheels". (<code>[#11453](pypa/pip#11453) <https://github.com/pypa/pip/issues/11453></code>_)</li> <li>Deprecate <code>--build-option</code> and <code>--global-option</code>. Users are invited to switch to <code>--config-settings</code>. (<code>[#11859](pypa/pip#11859) <https://github.com/pypa/pip/issues/11859></code>_)</li> <li>Using <code>--config-settings</code> with projects that don't have a <code>pyproject.toml</code> now print a deprecation warning. In the future the presence of config settings will automatically enable the default build backend for legacy projects and pass the setttings to it. (<code>[#11915](pypa/pip#11915) <https://github.com/pypa/pip/issues/11915></code>_)</li> <li>Remove <code>setup.py install</code> fallback when building a wheel failed for projects without <code>pyproject.toml</code>. (<code>[#8368](pypa/pip#8368) <https://github.com/pypa/pip/issues/8368></code>_)</li> <li>When the <code>wheel</code> package is not installed, pip now uses the default build backend instead of <code>setup.py install</code> for project without <code>pyproject.toml</code>. (<code>[#8559](pypa/pip#8559) <https://github.com/pypa/pip/issues/8559></code>_)</li> </ul> <h2>Features</h2> <ul> <li>Specify egg-link location in assertion message when it does not match installed location to provide better error message for debugging. (<code>[#10476](pypa/pip#10476) <https://github.com/pypa/pip/issues/10476></code>_)</li> <li>Present conflict information during installation after each choice that is rejected (pass <code>-vv</code> to <code>pip install</code> to show it) (<code>[#10937](pypa/pip#10937) <https://github.com/pypa/pip/issues/10937></code>_)</li> <li>Display dependency chain on each Collecting/Processing log line. (<code>[#11169](pypa/pip#11169) <https://github.com/pypa/pip/issues/11169></code>_)</li> <li>Support a per-requirement <code>--config-settings</code> option in requirements files. (<code>[#11325](pypa/pip#11325) <https://github.com/pypa/pip/issues/11325></code>_)</li> <li>The <code>--config-settings</code>/<code>-C</code> option now supports using the same key multiple times. When the same key is specified multiple times, all values are passed to the build backend as a list, as opposed to the previous behavior, where pip would only pass the last value if the same key was used multiple times. (<code>[#11681](pypa/pip#11681) <https://github.com/pypa/pip/issues/11681></code>_)</li> <li>Add <code>-C</code> as a short version of the <code>--config-settings</code> option. (<code>[#11786](pypa/pip#11786) <https://github.com/pypa/pip/issues/11786></code>_)</li> <li>Reduce the number of resolver rounds, since backjumping makes the resolver more efficient in finding solutions. This also makes pathological cases fail quicker. (<code>[#11908](pypa/pip#11908) <https://github.com/pypa/pip/issues/11908></code>_)</li> <li>Warn if <code>--hash</code> is used on a line without requirement in a requirements file. (<code>[#11935](pypa/pip#11935) <https://github.com/pypa/pip/issues/11935></code>_)</li> <li>Stop propagating CLI <code>--config-settings</code> to the build dependencies. They already did not propagate to requirements provided in requirement files. To pass the same config settings to several requirements, users should provide the requirements as CLI arguments. (<code>[#11941](pypa/pip#11941) <https://github.com/pypa/pip/issues/11941></code>_)</li> <li>Support wheel cache when using <code>--require-hashes</code>. (<code>[#5037](pypa/pip#5037) <https://github.com/pypa/pip/issues/5037></code>_)</li> <li>Add <code>--keyring-provider</code> flag. See the Authentication page in the documentation for more info. (<code>[#8719](pypa/pip#8719) <https://github.com/pypa/pip/issues/8719></code>_)</li> <li>In the case of virtual environments, configuration files are now also included from the base installation. (<code>[#9752](pypa/pip#9752) <https://github.com/pypa/pip/issues/9752></code>_)</li> </ul> <h2>Bug Fixes</h2> <ul> <li>Fix grammar by changing "A new release of pip available:" to "A new release of pip is available:" in the notice used for indicating that. (<code>[#11529](pypa/pip#11529) <https://github.com/pypa/pip/issues/11529></code>_)</li> <li>Normalize paths before checking if installed scripts are on PATH. (<code>[#11719](pypa/pip#11719) <https://github.com/pypa/pip/issues/11719></code>_)</li> <li>Correct the way to decide if keyring is available. (<code>[#11774](pypa/pip#11774) <https://github.com/pypa/pip/issues/11774></code>_)</li> <li>More consistent resolution backtracking by removing legacy hack related to setuptools resolution (<code>[#11837](pypa/pip#11837) <https://github.com/pypa/pip/issues/11837></code>_)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/pypa/pip/commit/6424ac4600265490462015c2fc7f9a402dba9ed8"><code>6424ac4</code></a> Bump for release</li> <li><a href="https://github.com/pypa/pip/commit/868338f9f79b58eff34dafb168aed65480d080d5"><code>868338f</code></a> Update AUTHORS.txt</li> <li><a href="https://github.com/pypa/pip/commit/4f3a4f72697299da1a412cf10c919a989e0692f5"><code>4f3a4f7</code></a> Merge pull request <a href="https://redirect.github.com/pypa/pip/issues/11919">#11919</a> from sbidoul/deprecate-legacy-ignore-config-setting...</li> <li><a href="https://github.com/pypa/pip/commit/dbf4e6842c9603792f6d3944a5c9cec17bd0a92a"><code>dbf4e68</code></a> Merge pull request <a href="https://redirect.github.com/pypa/pip/issues/11897">#11897</a> from sbidoul/cache-hash-checking-sbi</li> <li><a href="https://github.com/pypa/pip/commit/efe2d27451d50b165df78093bf5885da713fbdf8"><code>efe2d27</code></a> Further refactor is_wheel_from_cache</li> <li><a href="https://github.com/pypa/pip/commit/4beca6b4c9c510b19dbb6180e962425b89e8c839"><code>4beca6b</code></a> Improve test</li> <li><a href="https://github.com/pypa/pip/commit/bd746e3136e5e1be2374a079bac66071dd967a8c"><code>bd746e3</code></a> Introduce ireq.cached_wheel_source_link</li> <li><a href="https://github.com/pypa/pip/commit/caafe6e87d4f2998a77b194297e1c204cf6e10c2"><code>caafe6e</code></a> Add a couple of asserts</li> <li><a href="https://github.com/pypa/pip/commit/a6ef6485be9512f18121298b058797c578f65d45"><code>a6ef648</code></a> Rename original_link_is_in_wheel_cache to is_wheel_from_cache</li> <li><a href="https://github.com/pypa/pip/commit/ff8c8e38887880ad81ffd7cfc6a8373213c087b7"><code>ff8c8e3</code></a> Cosmetics</li> <li>Additional commits viewable in <a href="https://github.com/pypa/pip/compare/23.0.1...23.1">compare view</a></li> </ul> </details> <br /> [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=pip&package-manager=pip&previous-version=23.0.1&new-version=23.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Description
The doc said:
If setting multiple times like this:
Only the last option is passed to backend:
{'--build-option': '--avx2'}
It seems these code let the last option override the previous options:
pip/src/pip/_internal/cli/cmdoptions.py
Lines 803 to 806 in c987c68
Expected behavior
All options are passed to backend:
{'--build-option': ['--cffi', '--avx2']}
Modify the code like this:
pip version
22.3.1
Python version
3.10
OS
Windows 11
How to Reproduce
get_requires_for_build_wheel
config_settings
argumentOutput
No response
Code of Conduct
The text was updated successfully, but these errors were encountered: