@@ -410,6 +410,8 @@ def add_ui(db):
410410
411411 compileargs = r'-Wi "[TARGETDIR]Lib\compileall.py" -f -x "bad_coding|badsyntax|site-packages|py3_" "[TARGETDIR]Lib"'
412412 lib2to3args = r'-c "import lib2to3.pygram, lib2to3.patcomp;lib2to3.patcomp.PatternCompiler()"'
413+ updatepipargs = r'-m ensurepip -U --default-pip'
414+ removepipargs = r'-B -m ensurepip._uninstall'
413415 # See "CustomAction Table"
414416 add_data (db , "CustomAction" , [
415417 # msidbCustomActionTypeFirstSequence + msidbCustomActionTypeTextData + msidbCustomActionTypeProperty
@@ -421,9 +423,13 @@ def add_ui(db):
421423 ("SetDLLDirToSystem32" , 307 , "DLLDIR" , SystemFolderName ),
422424 # msidbCustomActionTypeExe + msidbCustomActionTypeSourceFile
423425 # See "Custom Action Type 18"
424- ("CompilePyc" , 18 , "python.exe" , compileargs ),
425- ("CompilePyo" , 18 , "python.exe" , "-O " + compileargs ),
426- ("CompileGrammar" , 18 , "python.exe" , lib2to3args ),
426+ # msidbCustomActionTypeInScript (1024); run during actual installation
427+ # msidbCustomActionTypeNoImpersonate (2048); run action in system account, not user account
428+ ("CompilePyc" , 18 + 1024 + 2048 , "python.exe" , compileargs ),
429+ ("CompilePyo" , 18 + 1024 + 2048 , "python.exe" , "-O " + compileargs ),
430+ ("CompileGrammar" , 18 + 1024 + 2048 , "python.exe" , lib2to3args ),
431+ ("UpdatePip" , 18 + 1024 + 2048 , "python.exe" , updatepipargs ),
432+ ("RemovePip" , 18 + 1024 + 2048 , "python.exe" , removepipargs ),
427433 ])
428434
429435 # UI Sequences, see "InstallUISequence Table", "Using a Sequence Table"
@@ -447,24 +453,27 @@ def add_ui(db):
447453
448454 # Prepend TARGETDIR to the system path, and remove it on uninstall.
449455 add_data (db , "Environment" ,
450- [("PathAddition" , "=-*Path" , "[TARGETDIR];[~]" , "REGISTRY.path" )])
456+ [("PathAddition" , "=-*Path" , "[TARGETDIR];[TARGETDIR]Scripts;[ ~]" , "REGISTRY.path" )])
451457
452458 # Execute Sequences
453459 add_data (db , "InstallExecuteSequence" ,
454460 [("InitialTargetDir" , 'TARGETDIR=""' , 750 ),
455461 ("SetDLLDirToSystem32" , 'DLLDIR="" and ' + sys32cond , 751 ),
456462 ("SetDLLDirToTarget" , 'DLLDIR="" and not ' + sys32cond , 752 ),
457463 ("UpdateEditIDLE" , None , 1050 ),
458- ("CompilePyc" , "COMPILEALL" , 6800 ),
459- ("CompilePyo" , "COMPILEALL" , 6801 ),
460- ("CompileGrammar" , "COMPILEALL" , 6802 ),
464+ # run command if install state of pip changes to INSTALLSTATE_LOCAL
465+ # run after InstallFiles
466+ ("UpdatePip" , "&pip_feature=3" , 4001 ),
467+ # remove pip when state changes to INSTALLSTATE_ABSENT
468+ # run before RemoveFiles
469+ ("RemovePip" , "&pip_feature=2" , 3499 ),
470+ ("CompilePyc" , "COMPILEALL" , 4002 ),
471+ ("CompilePyo" , "COMPILEALL" , 4003 ),
472+ ("CompileGrammar" , "COMPILEALL" , 4004 ),
461473 ])
462474 add_data (db , "AdminExecuteSequence" ,
463475 [("InitialTargetDir" , 'TARGETDIR=""' , 750 ),
464476 ("SetDLLDirToTarget" , 'DLLDIR=""' , 751 ),
465- ("CompilePyc" , "COMPILEALL" , 6800 ),
466- ("CompilePyo" , "COMPILEALL" , 6801 ),
467- ("CompileGrammar" , "COMPILEALL" , 6802 ),
468477 ])
469478
470479 #####################################################################
@@ -830,7 +839,8 @@ def add_features(db):
830839 # (i.e. additional Python libraries) need to follow the parent feature.
831840 # Features that have no advertisement trigger (e.g. the test suite)
832841 # must not support advertisement
833- global default_feature , tcltk , htmlfiles , tools , testsuite , ext_feature , private_crt , prepend_path
842+ global default_feature , tcltk , htmlfiles , tools , testsuite
843+ global ext_feature , private_crt , prepend_path , pip_feature
834844 default_feature = Feature (db , "DefaultFeature" , "Python" ,
835845 "Python Interpreter and Libraries" ,
836846 1 , directory = "TARGETDIR" )
@@ -852,16 +862,20 @@ def add_features(db):
852862 tools = Feature (db , "Tools" , "Utility Scripts" ,
853863 "Python utility scripts (Tools/" , 9 ,
854864 parent = default_feature , attributes = 2 )
865+ pip_feature = Feature (db , "pip_feature" , "pip" ,
866+ "Install or upgrade pip, a tool for installing and managing "
867+ "Python packages." , 11 ,
868+ parent = default_feature , attributes = 2 | 8 )
855869 testsuite = Feature (db , "Testsuite" , "Test suite" ,
856- "Python test suite (Lib/test/)" , 11 ,
870+ "Python test suite (Lib/test/)" , 13 ,
857871 parent = default_feature , attributes = 2 | 8 )
858872 # prepend_path is an additional feature which is to be off by default.
859873 # Since the default level for the above features is 1, this needs to be
860874 # at least level higher.
861875 prepend_path = Feature (db , "PrependPath" , "Add python.exe to Path" ,
862876 "Prepend [TARGETDIR] to the system Path variable. "
863877 "This allows you to type 'python' into a command "
864- "prompt without needing the full path." , 13 ,
878+ "prompt without needing the full path." , 15 ,
865879 parent = default_feature , attributes = 2 | 8 ,
866880 level = 2 )
867881
@@ -1188,6 +1202,8 @@ def add_registry(db):
11881202 "Documentation" ),
11891203 ("REGISTRY.path" , msilib .gen_uuid (), "TARGETDIR" , registry_component , None ,
11901204 None ),
1205+ ("REGISTRY.ensurepip" , msilib .gen_uuid (), "TARGETDIR" , registry_component , "EnsurePipRun" ,
1206+ None ),
11911207 ("REGISTRY.def" , msilib .gen_uuid (), "TARGETDIR" , registry_component ,
11921208 None , None )] + tcldata )
11931209 # See "FeatureComponents Table".
@@ -1205,6 +1221,7 @@ def add_registry(db):
12051221 [(default_feature .id , "REGISTRY" ),
12061222 (htmlfiles .id , "REGISTRY.doc" ),
12071223 (prepend_path .id , "REGISTRY.path" ),
1224+ (pip_feature .id , "REGISTRY.ensurepip" ),
12081225 (ext_feature .id , "REGISTRY.def" )] +
12091226 tcldata
12101227 )
@@ -1287,7 +1304,9 @@ def add_registry(db):
12871304 "" , r"[TARGETDIR]Python.exe" , "REGISTRY.def" ),
12881305 ("DisplayIcon" , - 1 ,
12891306 r"Software\Microsoft\Windows\CurrentVersion\Uninstall\%s" % product_code ,
1290- "DisplayIcon" , "[TARGETDIR]python.exe" , "REGISTRY" )
1307+ "DisplayIcon" , "[TARGETDIR]python.exe" , "REGISTRY" ),
1308+ # Fake registry entry to allow installer to track whether ensurepip has been run
1309+ ("EnsurePipRun" , - 1 , prefix + r"\EnsurePipRun" , "" , "#1" , "REGISTRY.ensurepip" ),
12911310 ])
12921311 # Shortcuts, see "Shortcut Table"
12931312 add_data (db , "Directory" ,
0 commit comments