-
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
Add a configuration command #4240
Conversation
@dstufft @xavfernandez RFC? (other than the lack of tests) |
pip/baseparser.py
Outdated
@@ -132,7 +132,7 @@ def __init__(self, *args, **kwargs): | |||
self.name = kwargs.pop('name') | |||
|
|||
isolated = kwargs.pop("isolated", False) | |||
self.config = Configuration(isolated) | |||
self._configuration_obj = Configuration(isolated) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already know it's an object here, by convention (and pretty much everything in python is one), so this naming is redundant.
If you really wish to indicate it's a private member then I'd just rename it _config
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. It's exactly why I put that there.
I had changed it to prevent collisions if I write that while cracking out the implementation because I don't use _obj
suffix either. Forgot to revert that change.
Thanks @Ivoz. Any other comments? |
I'm going to put this on hold for now.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just went through this to make some notes.
I don't have much time at hand for this PR in the very near future.
pip/commands/configuration.py
Outdated
return ERROR | ||
|
||
# Determine which configuration files are to be loaded | ||
if options.user_file and options.global_file: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for all 3 (global, venv, user)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pip/commands/configuration.py
Outdated
try: | ||
self.configuration.save() | ||
except Exception: | ||
logger.error("Houston, we have a problem", exc_info=1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Decide how to handle this correctly...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ask the user to report as bug.
pip/configuration.py
Outdated
logger = logging.getLogger(__name__) | ||
|
||
|
||
# NOTE: Maybe use the optionx attribtue to normalize keynames. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot me. 😛
pip/configuration.py
Outdated
def _make_key(variant, name): | ||
return ".".join((variant, name)) | ||
|
||
# Some terminology: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this stay separate as a comment or be added to a doc-string?
Maybe, because it involves terminology only for this module - keep it as it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added to docstring.
pip/configuration.py
Outdated
if load_only not in ["user", "site-wide", "venv", None]: | ||
raise ValueError( | ||
"Got invalid value for load_only - should be one of 'user', " | ||
"'site-wide', 'venv'" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Include None in the error message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pip/configuration.py
Outdated
section, name = _disassemble_key(key) | ||
|
||
# Remove the key in the parser | ||
modified_something = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this less terse? Or have a comment explaining why this works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It serves the intent. Comments get outdated easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit hard to follow, I generally prefer not to have methods with side effects in a boolean expression because it's easy to miss what's going on. I think this would be more readable as:
modified_something = False
if parser_has_section(section):
modified_something = parser.remove_option(section, name)
I actually missed that this was having any side effect at first and it took me a minute to understand why you wanted a comment here to start with.
pip/commands/__init__.py
Outdated
@@ -19,6 +20,7 @@ | |||
|
|||
commands_dict = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be changed into a dict constructor call with a list comprehension... DRY.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we've dropped 2.6 support, it can be a dict comprehension!! :)
pip/commands/configuration.py
Outdated
|
||
def set_name_value(self, options): | ||
key, value = options.set_name_value.split("=", 1) | ||
self.configuration.set_value(key, value) # Error here is propagated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Print a nice message instead of propagating the error? Or is something doing that?
Same on line 212.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
57b510d
to
b76d4e7
Compare
@dstufft @xavfernandez @pfmoore I'm writing the tests for this and I am a little confused - how extensive should the tests be and what exact functionalities should be tested? As such, there are so many things related to configuration that it cannot be verified to be working without modifying the entire environment. The earlier suite only tested precedence and overriding of configuration options. Things like which configuration files would be loaded, the exact contents of the files etc were not tested earlier. I'm thinking they should not be tested now either. Thoughts? |
@pradyunsg I'd have assumed the best way to test would be
I wouldn't try to test that the behaviour changes as expected. In theory we should already have tests that check "if the config says do X, then we do it", so that side of the problem should already be handled. In practice we likely haven't covered all such cases, but it's not the issue for this PR to address that problem. |
I am writing those tests right now - that run the command and check the result. I was wondering about the exact degree that the tests check things... Not checking behaviour changes sounds good to me. |
The functional tests check the behaviour by doing a subprocess run. This means that if a configuration file has to be loaded, it needs to be in one of the standard locations in order to be used by the test => if I want to check if the user file can be modified using the config command in pip, I will need the modify the actual user file - since I cannot patch in the sub process to change what file it opens. Further, it means that to check if the "site-wide" files can be modified, the test would have to be run escalated and would modify the global file somewhere in /etc/ or something. This cannot be done as it might involve modifying a file that possibly already exists and contains probably useful contents. And well, escalation to run a test - no. I'm not able to come up with any way to make the subprocess to use a different path for the test run. I don't want to be touching the default files when running the tests (no modify in-place or move-replace). 😕 |
PS: Travis failed due to some network issues IIUC. |
@xavfernandez Could you add this to v10.0 milestone? Since #4193 depends on the changes made here, it means that either this also should be a part of v10.0 or that should be removed. |
FWIW, I just pushed what test code I have. I think the tests can look the same regardless of how the patching is done but I think I'll try to figure out how to patch the files then proceed to actually writing the rest of the tests. |
I apologize if I'm being noisy. /ping @dstufft @xavfernandez @pfmoore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it's going in a good direction. I've marked some changes I'd like to see. One that I didn't mark everywhere is not shadowing builtins like file
.
pip/baseparser.py
Outdated
@@ -160,6 +160,9 @@ def _update_defaults(self, defaults): | |||
# ignore empty values | |||
if not val: | |||
continue | |||
section, key = key.split(".", 1) | |||
if section not in [self.name, "global", ":env:"]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nit, but this can be a set literal now which is slightly nicer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger!
pip/commands/configuration.py
Outdated
if action is None: | ||
logger.error( | ||
"Need exactly one action (--list, --edit, " | ||
"--get, --set, --unset) to perform." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like it would be better to instead of using a mandatory flag like this, to make this a positional argument to the command. So basically, instead of pip config --list ...
, you would do pip config list ...
. Positional arguments feel like a better fit for mandatory arguments to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree and it would also prevent the (twisted) corner case where you put:
[config]
list = 1
making the use of the config command rather complicated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good.
pip/commands/configuration.py
Outdated
if sum([options.user_file, options.global_file, options.venv_file]): | ||
logger.error( | ||
"Need at-most one configuration file to use - pass " | ||
"only one of --global, --user, --venv." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably just default to one of these files. Either the user file, or if we want to be smarter, we could say the venv file if one exists, and otherwise the user file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The smarter variant sounds better. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only time assuming a file could be useful is when we have to modify something. At the other times - list and get, it makes more sense to be asking the user to specify if they want to load a specific file - in which case we only load that file.
I feel it makes more sense to require the user to pass which file is to be modified or used since it gives them the ability to inspect the effect of each level or overridding as well as a fine degree of control.
pip/commands/configuration.py
Outdated
kwargs["load_only"] = "venv" | ||
elif action in ["set", "unset", "edit"]: | ||
logger.error( | ||
"Need one configuration file to modify - pass one of " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be duplicate logic to the above since you can't get to this point without one of these files existing. However, my same comment up above applies, I think we should just pick something to default to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. This'll be redundant.
pip/commands/configuration.py
Outdated
if options.editor is None: | ||
logger.error( | ||
"--edit requires an editor to be passed, either using " | ||
"--editor or by setting it in a configuration file." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see an --editor
flag defined up above, did I miss it? It would also be nice to support the semi standard $EDITOR
environment variable.
pip/commands/configuration.py
Outdated
) | ||
return ERROR | ||
|
||
file = self.configuration.get_file() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nit: I prefer not using the name file
because it shadows a builtin, file_
is ok, or filename
or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WHooops!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quite long PR, I'll try to re-review it soon.
pip/commands/configuration.py
Outdated
if options.editor is None: | ||
logger.error( | ||
"--edit requires an editor to be passed, either using " | ||
"--editor or by setting it in a configuration file." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @dstufft, it would make sense to default on the value of $VISUAL
or $EDITOR
(at least for POSIX systems).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
--editor
- I think I dropped it by mistake while doing the rebase with master. Oops. I have added it back.
Made the change to check $EDITOR
if --editor is not passed. I don't think we need to differ our behaviour across OSs.
pip/commands/configuration.py
Outdated
return ERROR | ||
|
||
# Determine which configuration files are to be loaded | ||
if sum([options.user_file, options.global_file, options.venv_file]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it missing a >1
or a not
or am I missing something ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not having it compare with anything is equivalent to checking the falsiness.
Sum of bools gives an integer. All non-zero integers are true-ish.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyway, I changed this part.
pip/commands/configuration.py
Outdated
if action is None: | ||
logger.error( | ||
"Need exactly one action (--list, --edit, " | ||
"--get, --set, --unset) to perform." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree and it would also prevent the (twisted) corner case where you put:
[config]
list = 1
making the use of the config command rather complicated.
pip/configuration.py
Outdated
import os | ||
import sys | ||
import logging |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: alphabetical order ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually like this increasing length form... :/
Made the change though. :)
pip/commands/configuration.py
Outdated
subprocess.check_call([options.editor, file]) | ||
except subprocess.CalledProcessError as e: | ||
logger.error( | ||
"Subprocess exited with exit code %d", e.returncode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also add the editor
used in the error msg (so that it is clear that we are not refering to pip, which will also return an error code).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good.
pip/configuration.py
Outdated
def __init__(self, isolated, load_only=None): | ||
super(Configuration, self).__init__() | ||
|
||
if load_only not in ["user", "site-wide", "venv", None]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are using these values in quite a few places, I'd rather we use some constants USER
, SITEWIDE
, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Umm, I don't feel very strongly about it... I guess.
Will do.
pip/configuration.py
Outdated
raise ConfigurationError("Needed a specific file to be modifying.") | ||
|
||
@property | ||
def _dictionary(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A chainmap
would have been nice but the need of a vendored backport in python2.7 would maybe make it a little overkill though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah... I was thinking about it but decided it was overkill too.
pip/commands/configuration.py
Outdated
try: | ||
self.configuration.unset_value(key) | ||
except ConfigurationError: | ||
logger.error("Could not unset value in configuration") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a return ERROR
here would be cleaner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger!
pip/commands/configuration.py
Outdated
try: | ||
self.configuration.set_value(key, value) | ||
except ConfigurationError: | ||
logger.error("Could not set value in configuration") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a return ERROR
here would be cleaner
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger!
Hello! I am an automated bot and I have noticed that this pull request is not currently able to be merged. If you are able to either merge the |
Will this configuration command also allow setting additional places to download or search for packages that may or may not be on PyPi? Also, it would be nice if the confirmation format was in json in case people want a list of multiple places for pip to look in additionally to PyPi for packages with source or wheel distributions. (Like if they use an github repository to store source distributions / wheels they make in an cental location separate from PyPi for potentially multiple packages. |
Do you mean adding to a list or removing from it? As of now, it doesn't. If that's not what you mean, I'm afraid it's not clear to me what you're asking.
I think there will be support for TOML based configuration soon (tracking issue: #3809). |
Do we have options that expect their values to be lists? If so, they'll need special handling, correct? |
@dstufft @xavfernandez Thanks for the reviews! ^.^ I think I addressed all the review comments. Should I write more tests for the command? |
The reason why I wanted additional paths to be lists is because they can be easy to append / remove entries on and so then people can do things like specify a specific location in the edit command to add or remove entries on the list. Like for example what if they want pip to look for wheels / source distributions at https://github.com/AraHaan/wheels/blob/master/ without clowning the git repository and a list of other ones from certain other groups doing something similar to other packages. |
pip/commands/configuration.py
Outdated
# Load a new configuration | ||
isolated = options.isolated_mode | ||
self.configuration = Configuration( | ||
isolated=isolated, load_only=load_only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: isolated
does not seem very useful
""" | ||
|
||
import pytest | ||
import textwrap |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: standard library imports first, then library
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger!
tests/lib/configuration_helpers.py
Outdated
import textwrap | ||
import tempfile | ||
import functools | ||
import contextlib |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
import orders 🙄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops!
pip/commands/configuration.py
Outdated
|
||
# Error handling happens here, not in the action-handlers. | ||
try: | ||
handlers[action](options, args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
args[1:]
would make more sense to me: no need to pass args[0]
to the handler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Roger!
pip/configuration.py
Outdated
|
||
|
||
_environ_prefix_re = re.compile(r"^PIP_", re.I) | ||
def _make_key(variant, name): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it is only used in one place and quite simple, I'd say you could ditch it.
pip/configuration.py
Outdated
# at the base we have any site-wide configuration | ||
files = list(site_config_files) | ||
# environment variables have the lowest priority | ||
config_file = os.environ.get('kinds.PIP_CONFIG', None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like a sed
gone wrong ^^
pip/configuration.py
Outdated
yield kinds.GLOBAL, list(site_config_files) | ||
|
||
# per-kinds.user configuration next | ||
kinds.should_load_user_config = not self.isolated and not ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no kinds
pip/configuration.py
Outdated
kinds.should_load_user_config = not self.isolated and not ( | ||
config_file and os.path.exists(config_file) | ||
) | ||
if kinds.should_load_user_config: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
@xavfernandez Thanks for this! ^.^ I had made that change in a hurry and pushed. |
ac6c367
to
19fd2db
Compare
/request-review @dstufft @xavfernandez @pfmoore |
pip/baseparser.py
Outdated
|
||
# Pool the options into different groups | ||
section_items = {name: [] for name in override_order} | ||
for key, val in self.config.items(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use for section_key, val in self.config.items():
here and section, key = section_key.split(".", 1)
a line below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep!
pip/baseparser.py
Outdated
section_items = {name: [] for name in override_order} | ||
for key, val in self.config.items(): | ||
# ignore empty values | ||
if not val: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a logger.debug stating that we are ignoring empty value for such (section, key)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no logger in this module. I'll add one. :)
pip/commands/configuration.py
Outdated
.format(e.returncode) | ||
) | ||
|
||
def _get_n_args(self, args, n): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add an help/example text, which would allow key, value = self._get_n_args(args, n=2, example="config set timeout 20")
in def set_name_value
and a nicer error message like:
Got unexpected number of arguments, expected 2 (example: "pip config set timeout 20")
(using pip.utils.get_prog)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
pip/commands/configuration.py
Outdated
if options.editor is not None: | ||
return options.editor | ||
elif "EDITOR" in os.environ: | ||
return os.environ["EDITOR"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
support for the standard $VISUAL would be nice also (git for example supports both)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On it!
pip/configuration.py
Outdated
from pip.utils import appdirs | ||
from pip.utils import ensure_dir, enum | ||
|
||
_need_file_err_msg = "Needed a specific file to be modifying." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not seem to be used
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed.
pip/configuration.py
Outdated
"""Loads configuration | ||
# The order here determines the override order. | ||
self._override_order = [ | ||
kinds.GLOBAL, kinds.USER, kinds.VENV, kinds.ENV, kinds.ENV_VAR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A comment explaining the difference between kinds.ENV (the config from the file from PIP_CONFIG_FILE) and kinds.ENV_VAR (the config from environment vars) would have helped :o
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add one where kinds
is defined.
pip/configuration.py
Outdated
if not self.isolated: | ||
self._load_environment_vars() | ||
|
||
def get_file(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_file_to_edit()
maybe ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made the change.
""" | ||
self._ensure_have_load_only() | ||
|
||
if key not in self._config[self.load_only]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe a logger.debug recalling the value of load_only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added in _ensure_have_load_only
.
pip/configuration.py
Outdated
for file_ in files: | ||
# If there's specific variant set in `load_only`, load only | ||
# that variant, not the others. | ||
if self.load_only is not None and variant != self.load_only: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
logger.debug ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added.
pip/configuration.py
Outdated
|
||
# XXX: This is patched in the tests. | ||
def _get_config_files(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe iter_config_files
would be a better name for a generator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
Some external change broke the CI builds. |
dfa1f9a
to
b75e7c6
Compare
Is there anything outstanding on this PR? |
pip/configuration.py
Outdated
section, name = _disassemble_key(key) | ||
|
||
# Remove the key in the parser | ||
modified_something = ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a bit hard to follow, I generally prefer not to have methods with side effects in a boolean expression because it's easy to miss what's going on. I think this would be more readable as:
modified_something = False
if parser_has_section(section):
modified_something = parser.remove_option(section, name)
I actually missed that this was having any side effect at first and it took me a minute to understand why you wanted a comment here to start with.
Ref: #1736
This is a configuration command for managing configuration files for pip through pip's CLI. It makes configuration more discoverable and easier to manage.
TODO:
pip.configuration
config
command