Skip to content

Commit cad97f4

Browse files
google-labs-jules[bot]esafak
authored andcommitted
feat: Add PKG_CONFIG_PATH to venv activation scripts
This change adds support for `pkg-config` to virtualenv by adding the virtual environment's `lib/pkgconfig` directory to the `PKG_CONFIG_PATH` environment variable upon activation. This is done for all supported shells: - Bash (`activate.sh`) - Batch (`activate.bat`, `deactivate.bat`) - C Shell (`activate.csh`) - Fish (`activate.fish`) - Nushell (`activate.nu`) - PowerShell (`activate.ps1`) - Python (`activate_this.py`) The implementation follows the style of the existing activation scripts for each shell, saving the original `PKG_CONFIG_PATH` on activation and restoring it on deactivation. Unit tests for each shell's activation have been updated to verify that `PKG_CONFIG_PATH` is set and unset correctly. Fixes #2637
1 parent 683e5db commit cad97f4

File tree

16 files changed

+172
-14
lines changed

16 files changed

+172
-14
lines changed

docs/changelog/2637.feature.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add support for `pkg-config` to virtualenv by adding the virtual environment's `lib/pkgconfig` directory to the `PKG_CONFIG_PATH` environment variable upon activation.
2+
Contributed by :user:esafak.

src/virtualenv/activation/bash/activate.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ deactivate () {
2222
export PYTHONHOME
2323
unset _OLD_VIRTUAL_PYTHONHOME
2424
fi
25+
if ! [ -z "${_OLD_PKG_CONFIG_PATH:+_}" ]; then
26+
PKG_CONFIG_PATH="$_OLD_PKG_CONFIG_PATH"
27+
export PKG_CONFIG_PATH
28+
unset _OLD_PKG_CONFIG_PATH
29+
fi
2530

2631
# The hash command must be called to get it to forget past
2732
# commands. Without forgetting past commands the $PATH changes
@@ -55,6 +60,10 @@ _OLD_VIRTUAL_PATH="$PATH"
5560
PATH="$VIRTUAL_ENV/"__BIN_NAME__":$PATH"
5661
export PATH
5762

63+
_OLD_PKG_CONFIG_PATH="${PKG_CONFIG_PATH}"
64+
PKG_CONFIG_PATH="$VIRTUAL_ENV/lib/pkgconfig${PKG_CONFIG_PATH:+:}${PKG_CONFIG_PATH}"
65+
export PKG_CONFIG_PATH
66+
5867
if [ "x"__VIRTUAL_PROMPT__ != x ] ; then
5968
VIRTUAL_ENV_PROMPT=__VIRTUAL_PROMPT__
6069
else

src/virtualenv/activation/batch/activate.bat

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@
4444

4545
@set "PATH=%VIRTUAL_ENV%\__BIN_NAME__;%PATH%"
4646

47+
@if not defined _OLD_VIRTUAL_PKG_CONFIG_PATH @set "_OLD_VIRTUAL_PKG_CONFIG_PATH=%PKG_CONFIG_PATH%"
48+
@if defined PKG_CONFIG_PATH (
49+
@set "PKG_CONFIG_PATH=%VIRTUAL_ENV%\lib\pkgconfig;%PKG_CONFIG_PATH%"
50+
) else (
51+
@set "PKG_CONFIG_PATH=%VIRTUAL_ENV%\lib\pkgconfig"
52+
)
53+
4754
@if defined _OLD_CODEPAGE (
4855
"%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul
4956
@set _OLD_CODEPAGE=

src/virtualenv/activation/batch/deactivate.bat

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
@set _OLD_VIRTUAL_PYTHONHOME=
1313
:ENDIFVHOME
1414

15+
@if not defined _OLD_VIRTUAL_PKG_CONFIG_PATH @goto ENDIFPKGPATH
16+
@set "PKG_CONFIG_PATH=%_OLD_VIRTUAL_PKG_CONFIG_PATH%"
17+
@set _OLD_VIRTUAL_PKG_CONFIG_PATH=
18+
:ENDIFPKGPATH
19+
1520
@if not defined _OLD_VIRTUAL_PATH @goto ENDIFVPATH
1621
@set "PATH=%_OLD_VIRTUAL_PATH%"
1722
@set _OLD_VIRTUAL_PATH=

src/virtualenv/activation/cshell/activate.csh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
set newline='\
66
'
77

8-
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH:q" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT:q" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc'
8+
alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH:q" && unset _OLD_VIRTUAL_PATH; test $?_OLD_VIRTUAL_PKG_CONFIG_PATH != 0 && setenv PKG_CONFIG_PATH "$_OLD_VIRTUAL_PKG_CONFIG_PATH:q" && unset _OLD_VIRTUAL_PKG_CONFIG_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT:q" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc'
99

1010
# Unset irrelevant variables.
1111
deactivate nondestructive
@@ -15,6 +15,13 @@ setenv VIRTUAL_ENV __VIRTUAL_ENV__
1515
set _OLD_VIRTUAL_PATH="$PATH:q"
1616
setenv PATH "$VIRTUAL_ENV:q/"__BIN_NAME__":$PATH:q"
1717

18+
if ( $?PKG_CONFIG_PATH ) then
19+
set _OLD_VIRTUAL_PKG_CONFIG_PATH="$PKG_CONFIG_PATH:q"
20+
setenv PKG_CONFIG_PATH "$VIRTUAL_ENV:q/lib/pkgconfig:$PKG_CONFIG_PATH:q"
21+
else
22+
setenv PKG_CONFIG_PATH "$VIRTUAL_ENV:q/lib/pkgconfig"
23+
endif
24+
1825

1926

2027
if (__VIRTUAL_PROMPT__ != "") then

src/virtualenv/activation/fish/activate.fish

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ function deactivate -d 'Exit virtualenv mode and return to the normal environmen
3131
set -e _OLD_VIRTUAL_PYTHONHOME
3232
end
3333

34+
if test -n "$_OLD_VIRTUAL_PKG_CONFIG_PATH"
35+
set -gx PKG_CONFIG_PATH $_OLD_VIRTUAL_PKG_CONFIG_PATH
36+
set -e _OLD_VIRTUAL_PKG_CONFIG_PATH
37+
end
38+
3439
if test -n "$_OLD_FISH_PROMPT_OVERRIDE"
3540
and functions -q _old_fish_prompt
3641
# Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`.
@@ -68,6 +73,13 @@ else
6873
end
6974
set -gx PATH "$VIRTUAL_ENV"'/'__BIN_NAME__ $PATH
7075

76+
if set -q PKG_CONFIG_PATH
77+
set -gx _OLD_VIRTUAL_PKG_CONFIG_PATH $PKG_CONFIG_PATH
78+
set -gx PKG_CONFIG_PATH "$VIRTUAL_ENV/lib/pkgconfig" $PKG_CONFIG_PATH
79+
else
80+
set -gx PKG_CONFIG_PATH "$VIRTUAL_ENV/lib/pkgconfig"
81+
end
82+
7183
# Prompt override provided?
7284
# If not, just use the environment name.
7385
if test -n __VIRTUAL_PROMPT__

src/virtualenv/activation/nushell/activate.nu

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ export-env {
7474
}
7575
$new_env | merge { PROMPT_COMMAND: $new_prompt VIRTUAL_PREFIX: $virtual_prefix }
7676
}
77+
let pkg_config_path = ([$virtual_env 'lib' 'pkgconfig'] | path join)
78+
let new_pkg_config_path = ($env | get --optional PKG_CONFIG_PATH | default [] | prepend $pkg_config_path)
79+
let new_env = ($new_env | upsert 'PKG_CONFIG_PATH' $new_pkg_config_path)
7780
load-env $new_env
7881
}
7982

src/virtualenv/activation/powershell/activate.ps1

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ function global:deactivate([switch] $NonDestructive) {
77
Remove-Variable "_OLD_VIRTUAL_PATH" -Scope global
88
}
99

10+
if (Test-Path variable:_OLD_VIRTUAL_PKG_CONFIG_PATH) {
11+
$env:PKG_CONFIG_PATH = $variable:_OLD_VIRTUAL_PKG_CONFIG_PATH
12+
Remove-Variable "_OLD_VIRTUAL_PKG_CONFIG_PATH" -Scope global
13+
}
14+
1015
if (Test-Path function:_old_virtual_prompt) {
1116
$function:prompt = $function:_old_virtual_prompt
1217
Remove-Item function:\_old_virtual_prompt
@@ -47,6 +52,13 @@ else {
4752
New-Variable -Scope global -Name _OLD_VIRTUAL_PATH -Value $env:PATH
4853

4954
$env:PATH = "$env:VIRTUAL_ENV/" + __BIN_NAME__ + __PATH_SEP__ + $env:PATH
55+
56+
New-Variable -Scope global -Name _OLD_VIRTUAL_PKG_CONFIG_PATH -Value $env:PKG_CONFIG_PATH
57+
if ($env:PKG_CONFIG_PATH) {
58+
$env:PKG_CONFIG_PATH = "$env:VIRTUAL_ENV\lib\pkgconfig" + __PATH_SEP__ + $env:PKG_CONFIG_PATH
59+
} else {
60+
$env:PKG_CONFIG_PATH = "$env:VIRTUAL_ENV\lib\pkgconfig"
61+
}
5062
if (!$env:VIRTUAL_ENV_DISABLE_PROMPT) {
5163
function global:_old_virtual_prompt {
5264
""

src/virtualenv/activation/python/activate_this.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
os.environ["VIRTUAL_ENV"] = base # virtual env is right above bin directory
2828
os.environ["VIRTUAL_ENV_PROMPT"] = __VIRTUAL_PROMPT__ or os.path.basename(base)
2929

30+
# prepend pkg-config path
31+
pkg_config_path = os.path.join(base, "lib", "pkgconfig")
32+
os.environ["PKG_CONFIG_PATH"] = os.pathsep.join(
33+
[pkg_config_path, *os.environ.get("PKG_CONFIG_PATH", "").split(os.pathsep)],
34+
).rstrip(os.pathsep)
35+
3036
# add the virtual environments libraries to the host python import mechanism
3137
prev_length = len(sys.path)
3238
for lib in __LIB_FOLDERS__.split(os.pathsep):

tests/unit/activation/test_bash.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,21 @@ def activate_call(self, script):
2828
def print_prompt(self):
2929
return self.print_os_env_var("PS1")
3030

31+
def _get_test_lines(self, activate_script):
32+
lines = super()._get_test_lines(activate_script)
33+
lines.insert(3, self.print_os_env_var("PKG_CONFIG_PATH"))
34+
i = next(i for i, line in enumerate(lines) if "pydoc" in line)
35+
lines.insert(i, self.print_os_env_var("PKG_CONFIG_PATH"))
36+
lines.insert(-1, self.print_os_env_var("PKG_CONFIG_PATH"))
37+
return lines
38+
39+
def assert_output(self, out, raw, tmp_path):
40+
assert out[3] == "None"
41+
42+
pkg_config_path = self.norm_path(self._creator.dest / "lib" / "pkgconfig")
43+
assert self.norm_path(out[9]) == pkg_config_path
44+
45+
assert out[-2] == "None" # shell has no value
46+
super().assert_output(out[:3] + out[4:9] + out[10:-2] + [out[-1]], raw, tmp_path)
47+
3148
activation_tester(Bash)

0 commit comments

Comments
 (0)