Environment
Description
I made a bad guess for the syntax of how to enable two pip features permanently, and rendered pip completely broken with a simple pip config set
command.
Expected behavior
One or both of the following:
pip config set
would reject an invalid valueHow to Reproduce
pip config set global.use-feature <feature>
pip
)Output
$ pip config set global.use-feature 2020-resolver,fast-deps
Writing to /home/akaihola/.config/pip/pip.conf
$ pip
An error occurred during configuration: option use-feature: invalid choice: '2020-resolver,fast-deps' (choose from '2020-resolver', 'fast-deps')
$ pip config unset --user global.use-feature
An error occurred during configuration: option use-feature: invalid choice: '2020-resolver,fast-deps' (choose from '2020-resolver', 'fast-deps')
The work-around:
$ rm $HOME/.config/pip/pip.conf
The error originates from:https://github.com/pypa/pip/blob/930aa5c70855a150a98503119d18536f91dfcc61/src/pip/_internal/cli/parser.py#L150-L155
Perhaps we can do option.check_value(key, val)
, which essentially is the syntax check mentioned in the first bullet point of the expected behaviour, when setting a value via pip config set
This will avoid us from setting invalid values for valid options, and avoid such scenarios, by showing the error during pip config set
$ pip config set global.use-feature 2020-resolver,fast-deps
ERROR: An error occurred during configuration: option use-feature: invalid choice: '2020-resolver,fast-deps' (choose from '2020-resolver', 'fast-deps')
I will let other maintainers chime in with their suggestions before putting together a PR for the same.
Also, it seems that the proper way to enable multiple features is:
pip config set --user global.use-feature "
2020-resolver
fast-deps"
I couldn't find a way to embed the newlines on the command line in bash, but opening a double quote and hitting Enter does continue to accept additional lines of input until a closing double quote, and this results in a good pip.conf
file:
[global]
use-feature =
2020-resolver
fast-deps
You don鈥檛 have to use newlines; any space would do (pip just splits with str.split()
).
Thanks for filing this issue @akaihola! ^>^
@deveshks's suggestion sounds good to me.
The only concern I have is: should we error out or is printing a warning sufficient? I don't think anyone depends on pip's behavior around how pip config set
works with invalid values, so I don't have backwards compatibility concerns here.
@pradyunsg regarding pip config set
: If there is just a warning, but the invalid values are still inserted pip.conf
, it will currently render pip completely unusable. The only way to make it work again is to find the correct pip.conf
file and fix it by hand. Also, you won't even be able to ask pip config debug
where pip.conf
might be located.
That is, of course, unless pip is simultaneously modified to not crash but just warn about and ignore invalid values it reads from pip.conf
. That would solve the biggest issue, and IMO be already a huge improvement.
So in my mind a warning is sufficient, provided that it's displayed both for pip config set
given invalid values on the command line, and also for any other pip
invocations when invalid values in pip.conf
are ignored.
FWIW most interactive applications I am aware of have an option to run without the config, which may helps the users debug situations like this. Personally I +1 on pip config set
guarding the field integrity, but that might not be sufficient in case pip upgrades and introduces/removes options so that the config could trigger an error. The worst case is when the error is with the global config file which the user cannot touch.
FWIW most interactive applications I am aware of have an option to run without the config, which may helps the users debug situations like this.
Would pip --isolated
help here?
@uranusjr, pip --isolated
doesn't seem to help, at least in a virtualenv:
$ pip config set --site global.use-feature invalid
Writing to /home/akaihola/.virtualenvs/tmp-b2918f420593727/pip.conf
$ pip config list
An error occurred during configuration: option use-feature: invalid choice: 'invalid' (choose from '2020-resolver', 'fast-deps')
$ pip config debug
An error occurred during configuration: option use-feature: invalid choice: 'invalid' (choose from '2020-resolver', 'fast-deps')
$ pip --isolated config list
An error occurred during configuration: option use-feature: invalid choice: 'invalid' (choose from '2020-resolver', 'fast-deps')
$ pip --isolated config debug
An error occurred during configuration: option use-feature: invalid choice: 'invalid' (choose from '2020-resolver', 'fast-deps')
@akaihola Weird, this seems to contradict its help message. I鈥檒l take a look at it (independent to this issue). Thanks!
@uranusjr,
--isolated
Run pip in an isolated mode, ignoring environment variables and user configuration.`
Maybe it just skips whatever configuration has been set using --user
, but not the ones set using --site
in a virtualenv?
I just checked, it seems like --isolated
only applies to distutils config files (a historical artifact that I don鈥檛 think many ever used), not pip config files.
All pip configuration files are always loaded; you can see the function that gets those files received no flags at all:
We should have a discussion on this 馃檨 But also independent to this issue.
All pip configuration files are always loaded;
Not true. :P
The user configuration files are not loaded when --isolated is passed. Why is it that way? IDK, and I wrote this bit of code [^1].
Most helpful comment
I just checked, it seems like
--isolated
only applies to distutils config files (a historical artifact that I don鈥檛 think many ever used), not pip config files.All pip configuration files are always loaded; you can see the function that gets those files received no flags at all:
https://github.com/pypa/pip/blob/ea10d0e253f497c9fc08097f14cdba6b94b45541/src/pip/_internal/configuration.py#L76-L96
We should have a discussion on this 馃檨 But also independent to this issue.