-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add PKG_CONFIG_PATH environment variable support to all activation scripts
#3023
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
Merged
gaborbernat
merged 8 commits into
pypa:main
from
rahuldevikar:users/rahuldevikar/fix2637
Feb 7, 2026
Merged
Changes from 6 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
79099ec
Add PKG_CONFIG_PATH to venv activation scripts
rahuldevikar 659ded0
add changelog
rahuldevikar 59850a0
update changelog
rahuldevikar 008e67c
fix tests
rahuldevikar c675a36
Merge branch 'main' into users/rahuldevikar/fix2637
rahuldevikar c367712
add condition and fix tests
rahuldevikar cd7bbc6
add test to existing tests
rahuldevikar 3d00897
Retrigger CI
rahuldevikar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Add ``PKG_CONFIG_PATH`` environment variable support to all activation scripts (Bash, Batch, PowerShell, Fish, C Shell, Nushell, and Python). The virtualenv's ``lib/pkgconfig`` directory is now automatically prepended to ``PKG_CONFIG_PATH`` on activation and restored on deactivation, enabling packages that use ``pkg-config`` during build/install to find their configuration files - by :user:`rahuldevikar`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,177 @@ | ||
| """Test that PKG_CONFIG_PATH is properly set and restored during activation/deactivation.""" | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from argparse import Namespace | ||
|
|
||
| import pytest | ||
|
|
||
| from virtualenv.activation import ( | ||
| BashActivator, | ||
| BatchActivator, | ||
| CShellActivator, | ||
| FishActivator, | ||
| NushellActivator, | ||
| PowerShellActivator, | ||
| PythonActivator, | ||
| ) | ||
| from virtualenv.info import IS_WIN | ||
|
|
||
|
|
||
| def _create_test_env(tmp_path): | ||
| """Helper to create a mock virtualenv environment for testing.""" | ||
|
|
||
| class MockInterpreter: | ||
| tcl_lib = None | ||
| tk_lib = None | ||
|
|
||
| class MockCreator: | ||
| def __init__(self, dest): | ||
| self.dest = dest | ||
| self.bin_dir = dest / ("Scripts" if IS_WIN else "bin") | ||
| self.bin_dir.mkdir(parents=True) | ||
| self.interpreter = MockInterpreter() | ||
| self.pyenv_cfg = {} | ||
| self.env_name = "test-env" | ||
|
|
||
| return MockCreator(tmp_path) | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| ("activator_class", "script_name", "search_patterns"), | ||
| [ | ||
| ( | ||
| BashActivator, | ||
| "activate", | ||
| { | ||
| "save": '_OLD_PKG_CONFIG_PATH="${PKG_CONFIG_PATH}"', | ||
| "set": 'PKG_CONFIG_PATH="${VIRTUAL_ENV}/lib/pkgconfig:${PKG_CONFIG_PATH}"', | ||
| "export": "export PKG_CONFIG_PATH", | ||
| "restore": 'PKG_CONFIG_PATH="$_OLD_PKG_CONFIG_PATH"', | ||
| "unset": "unset _OLD_PKG_CONFIG_PATH", | ||
| }, | ||
| ), | ||
| ( | ||
| FishActivator, | ||
| "activate.fish", | ||
| { | ||
| "save": "set -gx _OLD_PKG_CONFIG_PATH", | ||
| "set": 'set -gx PKG_CONFIG_PATH "$VIRTUAL_ENV/lib/pkgconfig:$PKG_CONFIG_PATH"', | ||
| "restore": "set -gx PKG_CONFIG_PATH", | ||
| "erase": "set -e _OLD_PKG_CONFIG_PATH", | ||
| }, | ||
| ), | ||
| ( | ||
| CShellActivator, | ||
| "activate.csh", | ||
| { | ||
| "save": 'set _OLD_PKG_CONFIG_PATH="$PKG_CONFIG_PATH"', | ||
| "set_with_existing": 'setenv PKG_CONFIG_PATH "${VIRTUAL_ENV}/lib/pkgconfig:${PKG_CONFIG_PATH}"', | ||
| "set_without_existing": 'setenv PKG_CONFIG_PATH "${VIRTUAL_ENV}/lib/pkgconfig"', | ||
| "deactivate_test": "test $?_OLD_PKG_CONFIG_PATH != 0", | ||
| "restore": 'setenv PKG_CONFIG_PATH "$_OLD_PKG_CONFIG_PATH:q"', | ||
| "unset": "unset _OLD_PKG_CONFIG_PATH", | ||
| }, | ||
| ), | ||
| ], | ||
| ) | ||
| def test_pkg_config_path_unix_shells(tmp_path, activator_class, script_name, search_patterns): | ||
| """Test PKG_CONFIG_PATH is set for Unix-like shells.""" | ||
| if IS_WIN and activator_class in {BashActivator, FishActivator, CShellActivator}: | ||
| pytest.skip("Unix shell test on Windows") | ||
|
|
||
| creator = _create_test_env(tmp_path) | ||
| options = Namespace(prompt=None) | ||
| activator = activator_class(options) | ||
|
|
||
| # Generate the activation script | ||
| activator.generate(creator) | ||
|
|
||
| # Read the generated script | ||
| script_path = creator.bin_dir / script_name | ||
| content = script_path.read_text(encoding="utf-8") | ||
|
|
||
| # Verify all expected patterns are present | ||
| for pattern_name, pattern in search_patterns.items(): | ||
| assert pattern in content, f"Missing {pattern_name} pattern: {pattern}\nScript content:\n{content}" | ||
|
|
||
|
|
||
| @pytest.mark.skipif(not IS_WIN, reason="Windows-only test") | ||
| @pytest.mark.parametrize( | ||
| ("activator_class", "script_name", "search_patterns"), | ||
| [ | ||
| ( | ||
| BatchActivator, | ||
| "activate.bat", | ||
| { | ||
| "save": 'set "_OLD_PKG_CONFIG_PATH=%PKG_CONFIG_PATH%"', | ||
| "set": 'set "PKG_CONFIG_PATH=%VIRTUAL_ENV%\\lib\\pkgconfig;%PKG_CONFIG_PATH%"', | ||
| }, | ||
| ), | ||
| ( | ||
| PowerShellActivator, | ||
| "activate.ps1", | ||
| { | ||
| "save": "New-Variable -Scope global -Name _OLD_PKG_CONFIG_PATH", | ||
| "set": '$env:PKG_CONFIG_PATH = "$env:VIRTUAL_ENV\\lib\\pkgconfig;$env:PKG_CONFIG_PATH"', | ||
| "restore": "$env:PKG_CONFIG_PATH = $variable:_OLD_PKG_CONFIG_PATH", | ||
| "remove": 'Remove-Variable "_OLD_PKG_CONFIG_PATH" -Scope global', | ||
| }, | ||
| ), | ||
| ], | ||
| ) | ||
| def test_pkg_config_path_windows_shells(tmp_path, activator_class, script_name, search_patterns): | ||
| """Test PKG_CONFIG_PATH is set for Windows shells.""" | ||
| creator = _create_test_env(tmp_path) | ||
| options = Namespace(prompt=None) | ||
| activator = activator_class(options) | ||
|
|
||
| # Generate the activation script | ||
| activator.generate(creator) | ||
|
|
||
| # Read the generated script | ||
| script_path = creator.bin_dir / script_name | ||
| content = script_path.read_text(encoding="utf-8") | ||
|
|
||
| # Verify all expected patterns are present | ||
| for pattern_name, pattern in search_patterns.items(): | ||
| assert pattern in content, f"Missing {pattern_name} pattern: {pattern}\nScript content:\n{content}" | ||
|
|
||
|
|
||
| def test_pkg_config_path_python_activator(tmp_path): | ||
| """Test PKG_CONFIG_PATH is set in Python activator.""" | ||
| creator = _create_test_env(tmp_path) | ||
| # Add libs attribute needed by PythonActivator | ||
| creator.libs = [tmp_path / "Lib" / "site-packages"] | ||
| options = Namespace(prompt=None) | ||
| activator = PythonActivator(options) | ||
|
|
||
| # Generate the activation script | ||
| activator.generate(creator) | ||
|
|
||
| # Read the generated script | ||
| script_path = creator.bin_dir / "activate_this.py" | ||
| content = script_path.read_text(encoding="utf-8") | ||
|
|
||
| # Verify PKG_CONFIG_PATH is handled | ||
| assert "PKG_CONFIG_PATH" in content, f"PKG_CONFIG_PATH not found in activate_this.py:\n{content}" | ||
| assert "pkg_config_path" in content, f"pkg_config_path variable not found in activate_this.py:\n{content}" | ||
|
|
||
|
|
||
| def test_pkg_config_path_nushell(tmp_path): | ||
| """Test PKG_CONFIG_PATH is set in Nushell.""" | ||
| creator = _create_test_env(tmp_path) | ||
| options = Namespace(prompt=None) | ||
| activator = NushellActivator(options) | ||
|
|
||
| # Generate the activation script | ||
| activator.generate(creator) | ||
|
|
||
| # Read the generated script | ||
| script_path = creator.bin_dir / "activate.nu" | ||
| content = script_path.read_text(encoding="utf-8") | ||
|
|
||
| # Verify PKG_CONFIG_PATH is handled | ||
| assert "PKG_CONFIG_PATH" in content, f"PKG_CONFIG_PATH not found in activate.nu:\n{content}" | ||
| assert "old_pkg_config_path" in content, f"old_pkg_config_path variable not saved in activate.nu:\n{content}" | ||
| assert "new_pkg_config_path" in content, f"new_pkg_config_path variable not found in activate.nu:\n{content}" | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.