36
36
class InstallRequirement (object ):
37
37
38
38
def __init__ (self , req , comes_from , source_dir = None , editable = False ,
39
- url = None , as_egg = False , update = True ):
39
+ url = None , as_egg = False , update = True , is_extra = False ):
40
40
self .extras = ()
41
41
if isinstance (req , string_types ):
42
42
req = pkg_resources .Requirement .parse (req )
@@ -58,6 +58,8 @@ def __init__(self, req, comes_from, source_dir=None, editable=False,
58
58
self ._is_bundle = None
59
59
# True if the editable should be updated:
60
60
self .update = update
61
+ # True if the requirement comes from another requirement's extras
62
+ self .is_extra = is_extra
61
63
# Set to True after successful installation
62
64
self .install_succeeded = None
63
65
# UninstallPathSet of uninstalled distribution (for possible rollback)
@@ -208,6 +210,10 @@ def url_name(self):
208
210
def setup_py (self ):
209
211
return os .path .join (self .source_dir , 'setup.py' )
210
212
213
+ @property
214
+ def is_subrequirement (self ):
215
+ return self .req and self .comes_from .__class__ is self .__class__
216
+
211
217
def run_egg_info (self , force_root_egg_info = False ):
212
218
assert self .source_dir
213
219
if self .name :
@@ -353,7 +359,7 @@ def requirements(self, extras=()):
353
359
logger .debug ('skipping extra %s' % in_extra )
354
360
# Skip requirement for an extra we aren't requiring
355
361
continue
356
- yield line
362
+ yield line , bool ( in_extra in extras )
357
363
358
364
@property
359
365
def absolute_versions (self ):
@@ -808,13 +814,15 @@ def __repr__(self):
808
814
class RequirementSet (object ):
809
815
810
816
def __init__ (self , build_dir , src_dir , download_dir , download_cache = None ,
811
- upgrade = False , ignore_installed = False , as_egg = False ,
812
- ignore_dependencies = False , force_reinstall = False , use_user_site = False ):
817
+ ignore_installed = False , as_egg = False , force_reinstall = False ,
818
+ ignore_dependencies = False , use_user_site = False , upgrade = False ,
819
+ upgrade_recursive = False ):
813
820
self .build_dir = build_dir
814
821
self .src_dir = src_dir
815
822
self .download_dir = download_dir
816
823
self .download_cache = download_cache
817
- self .upgrade = upgrade
824
+ self .upgrade = upgrade or upgrade_recursive
825
+ self .upgrade_recursive = upgrade_recursive
818
826
self .ignore_installed = ignore_installed
819
827
self .force_reinstall = force_reinstall
820
828
self .requirements = Requirements ()
@@ -908,15 +916,19 @@ def locate_files(self):
908
916
if not self .ignore_installed and not req_to_install .editable :
909
917
req_to_install .check_if_exists ()
910
918
if req_to_install .satisfied_by :
911
- if self .upgrade :
919
+ if self .is_upgradeable ( req_to_install ) :
912
920
req_to_install .conflicts_with = req_to_install .satisfied_by
913
921
req_to_install .satisfied_by = None
914
922
else :
915
923
install_needed = False
916
924
if req_to_install .satisfied_by :
925
+ if self .upgrade and not self .upgrade_recursive :
926
+ upgrade_cmd = '--upgrade-recursive'
927
+ else :
928
+ upgrade_cmd = '--upgrade'
917
929
logger .notify ('Requirement already satisfied '
918
- '(use --upgrade to upgrade): %s'
919
- % req_to_install )
930
+ '(use %s to upgrade): %s'
931
+ % ( upgrade_cmd , req_to_install ) )
920
932
921
933
if req_to_install .editable :
922
934
if req_to_install .source_dir is None :
@@ -946,11 +958,11 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
946
958
if not self .ignore_installed and not req_to_install .editable :
947
959
req_to_install .check_if_exists ()
948
960
if req_to_install .satisfied_by :
949
- if self .upgrade :
961
+ if self .is_upgradeable ( req_to_install ) :
950
962
if not self .force_reinstall and not req_to_install .url :
951
963
try :
952
964
url = finder .find_requirement (
953
- req_to_install , self . upgrade )
965
+ req_to_install , upgrade = True )
954
966
except BestVersionAlreadyInstalled :
955
967
best_installed = True
956
968
install = False
@@ -970,9 +982,13 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
970
982
logger .notify ('Requirement already up-to-date: %s'
971
983
% req_to_install )
972
984
else :
985
+ if self .upgrade and not self .upgrade_recursive :
986
+ upgrade_cmd = '--upgrade-recursive'
987
+ else :
988
+ upgrade_cmd = '--upgrade'
973
989
logger .notify ('Requirement already satisfied '
974
- '(use --upgrade to upgrade): %s'
975
- % req_to_install )
990
+ '(use %s to upgrade): %s'
991
+ % ( upgrade_cmd , req_to_install ) )
976
992
if req_to_install .editable :
977
993
logger .notify ('Obtaining %s' % req_to_install )
978
994
elif install :
@@ -1012,7 +1028,8 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
1012
1028
if req_to_install .url is None :
1013
1029
if not_found :
1014
1030
raise not_found
1015
- url = finder .find_requirement (req_to_install , upgrade = self .upgrade )
1031
+ url = finder .find_requirement (req_to_install ,
1032
+ upgrade = self .is_upgradeable (req_to_install ))
1016
1033
else :
1017
1034
## FIXME: should req_to_install.url already be a link?
1018
1035
url = Link (req_to_install .url )
@@ -1057,7 +1074,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
1057
1074
# repeat check_if_exists to uninstall-on-upgrade (#14)
1058
1075
req_to_install .check_if_exists ()
1059
1076
if req_to_install .satisfied_by :
1060
- if self .upgrade or self .ignore_installed :
1077
+ if self .ignore_installed or self .is_upgradeable ( req_to_install ) :
1061
1078
req_to_install .conflicts_with = req_to_install .satisfied_by
1062
1079
req_to_install .satisfied_by = None
1063
1080
else :
@@ -1068,7 +1085,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
1068
1085
if (req_to_install .extras ):
1069
1086
logger .notify ("Installing extra requirements: %r" % ',' .join (req_to_install .extras ))
1070
1087
if not self .ignore_dependencies :
1071
- for req in req_to_install .requirements (req_to_install .extras ):
1088
+ for req , is_extra in req_to_install .requirements (req_to_install .extras ):
1072
1089
try :
1073
1090
name = pkg_resources .Requirement .parse (req ).project_name
1074
1091
except ValueError :
@@ -1079,7 +1096,7 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
1079
1096
if self .has_requirement (name ):
1080
1097
## FIXME: check for conflict
1081
1098
continue
1082
- subreq = InstallRequirement (req , req_to_install )
1099
+ subreq = InstallRequirement (req , req_to_install , is_extra = is_extra )
1083
1100
reqs .append (subreq )
1084
1101
self .add_requirement (subreq )
1085
1102
if req_to_install .name not in self .requirements :
@@ -1096,6 +1113,12 @@ def prepare_files(self, finder, force_root_egg_info=False, bundle=False):
1096
1113
finally :
1097
1114
logger .indent -= 2
1098
1115
1116
+ def is_upgradeable (self , requirement ):
1117
+ if requirement .is_subrequirement and not requirement .is_extra :
1118
+ return self .upgrade_recursive
1119
+ else :
1120
+ return self .upgrade
1121
+
1099
1122
def cleanup_files (self , bundle = False ):
1100
1123
"""Clean up files, remove builds."""
1101
1124
logger .notify ('Cleaning up...' )
0 commit comments