11
11
import textwrap
12
12
13
13
from contextlib import contextmanager
14
+ from copy import deepcopy
14
15
from pathlib import Path
15
16
from subprocess import CalledProcessError
16
17
from typing import Any
@@ -1143,15 +1144,13 @@ def execute(self, bin: str, *args: str, **kwargs: Any) -> Optional[int]:
1143
1144
return self .run_pip (* args , ** kwargs )
1144
1145
1145
1146
bin = self ._bin (bin )
1147
+ env = kwargs .pop ("env" , {k : v for k , v in os .environ .items ()})
1146
1148
1147
1149
if not self ._is_windows :
1148
1150
args = [bin ] + list (args )
1149
- if "env" in kwargs :
1150
- return os .execvpe (bin , args , kwargs ["env" ])
1151
- else :
1152
- return os .execvp (bin , args )
1151
+ return os .execvpe (bin , args , env = env )
1153
1152
else :
1154
- exe = subprocess .Popen ([bin ] + list (args ), ** kwargs )
1153
+ exe = subprocess .Popen ([bin ] + list (args ), env = env , ** kwargs )
1155
1154
exe .communicate ()
1156
1155
return exe .returncode
1157
1156
@@ -1388,24 +1387,35 @@ def is_sane(self) -> bool:
1388
1387
return os .path .exists (self .python )
1389
1388
1390
1389
def _run (self , cmd : List [str ], ** kwargs : Any ) -> Optional [int ]:
1391
- with self .temp_environ ():
1392
- os .environ ["PATH" ] = self ._updated_path ()
1393
- os .environ ["VIRTUAL_ENV" ] = str (self ._path )
1390
+ kwargs ["env" ] = self .get_temp_environ (environ = kwargs .get ("env" ))
1391
+ return super (VirtualEnv , self )._run (cmd , ** kwargs )
1394
1392
1395
- self .unset_env ("PYTHONHOME" )
1396
- self .unset_env ("__PYVENV_LAUNCHER__" )
1393
+ def get_temp_environ (
1394
+ self ,
1395
+ environ : Optional [Dict [str , str ]] = None ,
1396
+ exclude : Optional [List [str ]] = None ,
1397
+ ** kwargs : str ,
1398
+ ) -> Dict [str , str ]:
1399
+ exclude = exclude or []
1400
+ exclude .extend (["PYTHONHOME" , "__PYVENV_LAUNCHER__" ])
1401
+
1402
+ if environ :
1403
+ environ = deepcopy (environ )
1404
+ for key in exclude :
1405
+ environ .pop (key , None )
1406
+ else :
1407
+ environ = {k : v for k , v in os .environ .items () if k not in exclude }
1397
1408
1398
- return super ( VirtualEnv , self ). _run ( cmd , ** kwargs )
1409
+ environ . update ( kwargs )
1399
1410
1400
- def execute (self , bin : str , * args : str , ** kwargs : Any ) -> Optional [int ]:
1401
- with self .temp_environ ():
1402
- os .environ ["PATH" ] = self ._updated_path ()
1403
- os .environ ["VIRTUAL_ENV" ] = str (self ._path )
1411
+ environ ["PATH" ] = self ._updated_path ()
1412
+ environ ["VIRTUAL_ENV" ] = str (self ._path )
1404
1413
1405
- self .unset_env ("PYTHONHOME" )
1406
- self .unset_env ("__PYVENV_LAUNCHER__" )
1414
+ return environ
1407
1415
1408
- return super (VirtualEnv , self ).execute (bin , * args , ** kwargs )
1416
+ def execute (self , bin : str , * args : str , ** kwargs : Any ) -> Optional [int ]:
1417
+ kwargs ["env" ] = self .get_temp_environ (environ = kwargs .get ("env" ))
1418
+ return super (VirtualEnv , self ).execute (bin , * args , ** kwargs )
1409
1419
1410
1420
@contextmanager
1411
1421
def temp_environ (self ) -> Iterator [None ]:
@@ -1416,10 +1426,6 @@ def temp_environ(self) -> Iterator[None]:
1416
1426
os .environ .clear ()
1417
1427
os .environ .update (environ )
1418
1428
1419
- def unset_env (self , key : str ) -> None :
1420
- if key in os .environ :
1421
- del os .environ [key ]
1422
-
1423
1429
def _updated_path (self ) -> str :
1424
1430
return os .pathsep .join ([str (self ._bin_dir ), os .environ .get ("PATH" , "" )])
1425
1431
0 commit comments