12
12
import sysconfig
13
13
import types
14
14
15
+
16
+ CORE_VENV_DEPS = ('pip' , 'setuptools' )
15
17
logger = logging .getLogger (__name__ )
16
18
17
19
@@ -38,16 +40,19 @@ class EnvBuilder:
38
40
:param with_pip: If True, ensure pip is installed in the virtual
39
41
environment
40
42
:param prompt: Alternative terminal prefix for the environment.
43
+ :param upgrade_deps: Update the base venv modules to the latest on PyPI
41
44
"""
42
45
43
46
def __init__ (self , system_site_packages = False , clear = False ,
44
- symlinks = False , upgrade = False , with_pip = False , prompt = None ):
47
+ symlinks = False , upgrade = False , with_pip = False , prompt = None ,
48
+ upgrade_deps = False ):
45
49
self .system_site_packages = system_site_packages
46
50
self .clear = clear
47
51
self .symlinks = symlinks
48
52
self .upgrade = upgrade
49
53
self .with_pip = with_pip
50
54
self .prompt = prompt
55
+ self .upgrade_deps = upgrade_deps
51
56
52
57
def create (self , env_dir ):
53
58
"""
@@ -74,6 +79,8 @@ def create(self, env_dir):
74
79
# restore it and rewrite the configuration
75
80
self .system_site_packages = True
76
81
self .create_configuration (context )
82
+ if self .upgrade_deps :
83
+ self .upgrade_dependencies (context )
77
84
78
85
def clear_directory (self , path ):
79
86
for fn in os .listdir (path ):
@@ -105,7 +112,6 @@ def create_if_needed(d):
105
112
prompt = self .prompt if self .prompt is not None else context .env_name
106
113
context .prompt = '(%s) ' % prompt
107
114
create_if_needed (env_dir )
108
- env = os .environ
109
115
executable = getattr (sys , '_base_executable' , sys .executable )
110
116
dirname , exename = os .path .split (os .path .abspath (executable ))
111
117
context .executable = executable
@@ -363,13 +369,25 @@ def install_scripts(self, context, path):
363
369
f .write (data )
364
370
shutil .copymode (srcfile , dstfile )
365
371
372
+ def upgrade_dependencies (self , context ):
373
+ logger .debug (
374
+ f'Upgrading { CORE_VENV_DEPS } packages in { context .bin_path } '
375
+ )
376
+ if sys .platform == 'win32' :
377
+ pip_exe = os .path .join (context .bin_path , 'pip.exe' )
378
+ else :
379
+ pip_exe = os .path .join (context .bin_path , 'pip' )
380
+ cmd = [pip_exe , 'install' , '-U' ]
381
+ cmd .extend (CORE_VENV_DEPS )
382
+ subprocess .check_call (cmd )
383
+
366
384
367
385
def create (env_dir , system_site_packages = False , clear = False ,
368
- symlinks = False , with_pip = False , prompt = None ):
386
+ symlinks = False , with_pip = False , prompt = None , upgrade_deps = False ):
369
387
"""Create a virtual environment in a directory."""
370
388
builder = EnvBuilder (system_site_packages = system_site_packages ,
371
389
clear = clear , symlinks = symlinks , with_pip = with_pip ,
372
- prompt = prompt )
390
+ prompt = prompt , upgrade_deps = upgrade_deps )
373
391
builder .create (env_dir )
374
392
375
393
def main (args = None ):
@@ -432,6 +450,11 @@ def main(args=None):
432
450
parser .add_argument ('--prompt' ,
433
451
help = 'Provides an alternative prompt prefix for '
434
452
'this environment.' )
453
+ parser .add_argument ('--upgrade-deps' , default = False , action = 'store_true' ,
454
+ dest = 'upgrade_deps' ,
455
+ help = 'Upgrade core dependencies: {} to the latest '
456
+ 'version in PyPI' .format (
457
+ ' ' .join (CORE_VENV_DEPS )))
435
458
options = parser .parse_args (args )
436
459
if options .upgrade and options .clear :
437
460
raise ValueError ('you cannot supply --upgrade and --clear together.' )
@@ -440,7 +463,8 @@ def main(args=None):
440
463
symlinks = options .symlinks ,
441
464
upgrade = options .upgrade ,
442
465
with_pip = options .with_pip ,
443
- prompt = options .prompt )
466
+ prompt = options .prompt ,
467
+ upgrade_deps = options .upgrade_deps )
444
468
for d in options .dirs :
445
469
builder .create (d )
446
470
0 commit comments