Skip to content

Commit e56b38a

Browse files
dalebrydonfridex
authored andcommitted
Rework the functionality of PIP_CONFIG_FILE (pypa#11850)
1 parent 26d2418 commit e56b38a

File tree

3 files changed

+27
-19
lines changed

3 files changed

+27
-19
lines changed

docs/html/topics/configuration.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,24 @@ and how they are related to pip's various command line options.
1919

2020
## Configuration Files
2121

22-
Configuration files can change the default values for command line option.
23-
They are written using a standard INI style configuration files.
22+
Configuration files can change the default values for command line options.
23+
The files are written using standard INI format.
2424

2525
pip has 3 "levels" of configuration files:
2626

2727
- `global`: system-wide configuration file, shared across users.
2828
- `user`: per-user configuration file.
2929
- `site`: per-environment configuration file; i.e. per-virtualenv.
3030

31+
Additionally, environment variables can be specified which will override any of the above.
32+
3133
### Location
3234

3335
pip's configuration files are located in fairly standard locations. This
3436
location is different on different operating systems, and has some additional
35-
complexity for backwards compatibility reasons.
37+
complexity for backwards compatibility reasons. Note that if user config files
38+
exist in both the legacy and current locations, values in the current file
39+
will override values in the legacy file.
3640

3741
```{tab} Unix
3842
@@ -88,9 +92,10 @@ Site
8892
### `PIP_CONFIG_FILE`
8993

9094
Additionally, the environment variable `PIP_CONFIG_FILE` can be used to specify
91-
a configuration file that's loaded first, and whose values are overridden by
92-
the values set in the aforementioned files. Setting this to {any}`os.devnull`
93-
disables the loading of _all_ configuration files.
95+
a configuration file that's loaded last, and whose values override the values
96+
set in the aforementioned files. Setting this to {any}`os.devnull`
97+
disables the loading of _all_ configuration files. Note that if a file exists
98+
at the location that this is set to, the user config file will not be loaded.
9499

95100
(config-precedence)=
96101

@@ -99,10 +104,10 @@ disables the loading of _all_ configuration files.
99104
When multiple configuration files are found, pip combines them in the following
100105
order:
101106

102-
- `PIP_CONFIG_FILE`, if given.
103107
- Global
104108
- User
105109
- Site
110+
- `PIP_CONFIG_FILE`, if given.
106111

107112
Each file read overrides any values read from previous files, so if the
108113
global timeout is specified in both the global file and the per-user file

news/11815.doc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix explanation of how PIP_CONFIG_FILE works

src/pip/_internal/configuration.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -327,33 +327,35 @@ def get_environ_vars(self) -> Iterable[Tuple[str, str]]:
327327
def iter_config_files(self) -> Iterable[Tuple[Kind, List[str]]]:
328328
"""Yields variant and configuration files associated with it.
329329
330-
This should be treated like items of a dictionary.
330+
This should be treated like items of a dictionary. The order
331+
here doesn't affect what gets overridden. That is controlled
332+
by OVERRIDE_ORDER. However this does control the order they are
333+
displayed to the user. It's probably most ergononmic to display
334+
things in the same order as OVERRIDE_ORDER
331335
"""
332336
# SMELL: Move the conditions out of this function
333337

334-
# environment variables have the lowest priority
335-
config_file = os.environ.get("PIP_CONFIG_FILE", None)
336-
if config_file is not None:
337-
yield kinds.ENV, [config_file]
338-
else:
339-
yield kinds.ENV, []
340-
338+
env_config_file = os.environ.get("PIP_CONFIG_FILE", None)
341339
config_files = get_configuration_files()
342340

343-
# at the base we have any global configuration
344341
yield kinds.GLOBAL, config_files[kinds.GLOBAL]
345342

346-
# per-user configuration next
343+
# per-user config is not loaded when env_config_file exists
347344
should_load_user_config = not self.isolated and not (
348-
config_file and os.path.exists(config_file)
345+
env_config_file and os.path.exists(env_config_file)
349346
)
350347
if should_load_user_config:
351348
# The legacy config file is overridden by the new config file
352349
yield kinds.USER, config_files[kinds.USER]
353350

354-
# finally virtualenv configuration first trumping others
351+
# virtualenv config
355352
yield kinds.SITE, config_files[kinds.SITE]
356353

354+
if env_config_file is not None:
355+
yield kinds.ENV, [env_config_file]
356+
else:
357+
yield kinds.ENV, []
358+
357359
def get_values_in_config(self, variant: Kind) -> Dict[str, Any]:
358360
"""Get values present in a config file"""
359361
return self._config[variant]

0 commit comments

Comments
 (0)