Skip to content

Conversation

chrysle
Copy link
Contributor

@chrysle chrysle commented Aug 3, 2023

Fixes #12099

This pull requests extends the pip configuration dictionary to be nested, allowing the configuration keys to be connected with the origin files. It will look like this:

{'/etc/xdg/pip/pip.conf': {'install.require-virtualenv': 'true'}, '/etc/pip.conf': {'global.timeout': '60'}, '/home/user/.pip/pip.conf': {'install.require-virtualenv': 'true'}, '/home/user/.config/pip/pip.conf': {'global.timeout': '60', 'test.blah': '1', 'test.blaha': '1'}}

pip config debug correctly separates the configuration:

$ python -m pip config debug
env_var:
env:
global:
  /etc/xdg/xdg-ubuntu/pip/pip.conf, exists: False
  /etc/xdg/pip/pip.conf, exists: True
    install.require-virtualenv: true
  /etc/pip.conf, exists: True
    global.timeout: 60
site:
  /home/user/.virtualenvs/pip-dev/pip.conf, exists: False
user:
  /home/user/.pip/pip.conf, exists: True
    install.require-virtualenv: true
  /home/user/.config/pip/pip.conf, exists: True
    global.timeout: 60
    test.blah: 1
    test.blaha: 1

I'm not satisfied with the implementation, though... Happy about review feedback!

@chrysle chrysle force-pushed the separate-config-same-level branch from 14b5170 to 683d7cd Compare August 10, 2023 17:19
@chrysle
Copy link
Contributor Author

chrysle commented Aug 10, 2023

Thank you, updated!

@pradyunsg
Copy link
Member

pradyunsg commented Aug 10, 2023

Thanks for filing this PR! ^>^

Could you update the output to indent the configuration values by one level more compared to the output line about the origin file?

i.e.

$ python -m pip config debug
env_var:
env:
global:
  /etc/xdg/xdg-ubuntu/pip/pip.conf, exists: False
  /etc/xdg/pip/pip.conf, exists: True
    install.require-virtualenv: true
  /etc/pip.conf, exists: True
    global.timeout: 60
site:
  /home/user/.virtualenvs/pip-dev/pip.conf, exists: False
user:
  /home/user/.pip/pip.conf, exists: True
    install.require-virtualenv: true
  /home/user/.config/pip/pip.conf, exists: True
    global.timeout: 60
    test.blah: 1
    test.blaha: 1

@chrysle
Copy link
Contributor Author

chrysle commented Aug 11, 2023

Thanks for filing this PR! ^>^

You're welcome!

Could you update the output to indent the configuration values by one level more compared to the output line about the origin file?

I'm sorry, that's actually the default behaviour - my sed call messed that up :/

Updated the example. I sure agree it looks better!

@chrysle
Copy link
Contributor Author

chrysle commented Aug 14, 2023

Thank you for the code refinery suggestions! I've applied them.

@chrysle chrysle requested a review from uranusjr August 30, 2023 14:23
@uranusjr
Copy link
Member

Looks good. Can we add some tests for this?

@chrysle chrysle force-pushed the separate-config-same-level branch from dcf53da to d9b5a9d Compare September 5, 2023 17:16
@chrysle
Copy link
Contributor Author

chrysle commented Sep 5, 2023

@uranusjr I have added a test. Do you have a suggestion how to touch the configuration file platform-independent?

@uranusjr
Copy link
Member

uranusjr commented Sep 7, 2023

Looks like there’s some problem with test setup, the config is not where you expect it to be.

@chrysle
Copy link
Contributor Author

chrysle commented Sep 7, 2023

Don't know why, but on Windows the the new_config_file is in a subdirectory of the one used for the preceding test_user_values test:

new_config_file = 'C:\\Temp\\pytest-of-runneradmin\\pytest-1\\popen-gw1\\test_user_values0\\home\\AppData\\Roaming\\pip\\pip.ini'

Can I run a simple replace on that?

@pfmoore
Copy link
Member

pfmoore commented Sep 7, 2023

Can I run a simple replace on that?

IMO, only if you add a comment to the test explaining why you needed to do so for future maintainers. And if you can write such a comment, you'd probably be better just fixing the test to look in the correct place 🙂

@pradyunsg
Copy link
Member

pradyunsg commented Sep 7, 2023

I think that's actually state leaking between tests, which is what is causing the failure here. Doing a replace seems like a bodge and, ideally, we would instead change test_user_values to not leak state into other tests...

Maybe, that should delete new_config_file before exiting. @chrysle Could you try adding an os.remove(new_config_file) to the end of test_user_values?

@chrysle chrysle force-pushed the separate-config-same-level branch 2 times, most recently from 87e2b83 to 8d6c282 Compare September 9, 2023 15:10
@pradyunsg
Copy link
Member

pradyunsg commented Sep 9, 2023

@chrysle Please run git pull locally on this branch, before making any more changes. :)

@chrysle
Copy link
Contributor Author

chrysle commented Sep 10, 2023

Sure, done; I wanted to rebase after checking if your solution would work.

Do you have another suggestion how to handle the issue? I can't test on Windows, unfortunately.

@chrysle chrysle requested a review from pradyunsg October 1, 2023 13:49
@pradyunsg
Copy link
Member

Could you try adding an os.remove(new_config_file) to the end of test_user_values?

Have you tried this yet?

chrysle and others added 2 commits February 25, 2024 09:04
Co-authored-by: Tzu-ping Chung <[email protected]>
Co-authored-by: Pradyun Gedam <[email protected]>
@chrysle chrysle force-pushed the separate-config-same-level branch from af49b81 to 0fa9647 Compare February 25, 2024 08:11
@ichard26
Copy link
Member

@chrysle are you interested in fixing the failing test on Windows CI and fixing the merge conflicts? This PR looks pretty close to be ready to be merged. It's okay if you aren't!

@chrysle
Copy link
Contributor Author

chrysle commented May 12, 2024

@chrysle are you interested in fixing the failing test on Windows CI

I am, unfortunately I don't know how to do that. I don't use Windows and thus can not investigate this properly. Any help would be greatly appreciated.

@ichard26 ichard26 added the state: up for grabs (PR) Good idea, but needs a new champion as the PR author is busy or unreachable. label Apr 24, 2025
@ichard26 ichard26 self-assigned this Jul 9, 2025
@ichard26 ichard26 force-pushed the separate-config-same-level branch from 60298c8 to 061dbbd Compare July 9, 2025 02:19
@ichard26
Copy link
Member

ichard26 commented Jul 9, 2025

I was confused with the code duplication. I tried to remove it and realized that envvars were not migrated to the dict[Kind, dict[Filename, Any]] format. Fixing envvars to use a fake file was enough to eliminate all of the weird duplication. I've reviewed the rest of the changes and they look great!

I'm trying my darnest to fix the tests on Windows. It looks like state leaks between the tests conditionally (probably based off whether the OS global configuration directory is writable or not). Once that's fixed, I'll merge this.

Thank you @chrysle for the contribution!

@ichard26 ichard26 enabled auto-merge (squash) July 9, 2025 02:26
@ichard26
Copy link
Member

ichard26 commented Jul 9, 2025

I think I figured it out, platformdirs is caching the Windows user site directory which obviously is not going to end well here. I added a teardown fixture that clears this cache. Sigh.

@ichard26 ichard26 force-pushed the separate-config-same-level branch from 46632f4 to 226ef40 Compare July 9, 2025 02:52
@ichard26
Copy link
Member

ichard26 commented Jul 9, 2025

That did not fix it. Whelp. I give up for the night. Will come back to this later.

@ichard26
Copy link
Member

ichard26 commented Jul 11, 2025

I'm going to add a replace call to this test because nothing in test_configuration.py seems to be suspect. However, on my Windows machine, I added an assert to check what the internal platformdirs functions are returning as the user configuration directory at test teardown, and the ctypes function seems to be caching, lagging on, or ignoring updates to envvar APPDATA.

image

The ctypes function is the default one that platformdirs uses when ctypes/windll is available.

It's also possible that our test suite isolation fixture is broken on Windows and perhaps APPDATA is an unsupported way of updating the user app data folder...

@ichard26
Copy link
Member

Oh wait, updating APPDATA and friends is only going to affect the Windows APIs in a new subprocess. This is noted within the test isolation logic.

pip/tests/conftest.py

Lines 236 to 248 in 8c3a68d

if sys.platform == "win32":
# Note: this will only take effect in subprocesses...
home_drive, home_path = os.path.splitdrive(home_dir)
monkeypatch.setenv("USERPROFILE", home_dir)
monkeypatch.setenv("HOMEDRIVE", home_drive)
monkeypatch.setenv("HOMEPATH", home_path)
for env_var, sub_path in (
("APPDATA", "AppData/Roaming"),
("LOCALAPPDATA", "AppData/Local"),
):
path = os.path.join(home_dir, *sub_path.split("/"))
monkeypatch.setenv(env_var, path)
os.makedirs(path)

The better fix is to run get_configuration_files() in a subprocess... great.

@ichard26 ichard26 merged commit 9f082bc into pypa:main Jul 11, 2025
29 checks passed
@ichard26
Copy link
Member

image

Sorry. I didn't mean to use my time travel abilities on pip :P

In all seriousness. I dual boot Ubuntu and Windows and every time I switch OSes, the system time shifts 4 hours back or forth. Ubuntu resyncs the system time quickly, but Windows doesn't 😕. I've stopped manually digging through the settings to resync the time so now my commit times on Windows are all out of wack, haha.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 2, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bot:chronographer:provided state: up for grabs (PR) Good idea, but needs a new champion as the PR author is busy or unreachable.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

pip config debug doesn't separate the configuration shown for different files at the same "level"
5 participants