1111from  collections  import  OrderedDict 
1212from  collections .abc  import  Iterable 
1313from  types  import  TracebackType 
14- from  typing  import  TYPE_CHECKING , Protocol 
14+ from  typing  import  TYPE_CHECKING , Protocol ,  TypedDict 
1515
1616from  pip ._vendor .packaging .version  import  Version 
1717
1818from  pip  import  __file__  as  pip_location 
1919from  pip ._internal .cli .spinners  import  open_spinner 
2020from  pip ._internal .locations  import  get_platlib , get_purelib , get_scheme 
2121from  pip ._internal .metadata  import  get_default_environment , get_environment 
22+ from  pip ._internal .utils .deprecation  import  deprecated 
2223from  pip ._internal .utils .logging  import  VERBOSE 
2324from  pip ._internal .utils .packaging  import  get_requirement 
2425from  pip ._internal .utils .subprocess  import  call_subprocess 
2829    from  pip ._internal .index .package_finder  import  PackageFinder 
2930    from  pip ._internal .req .req_install  import  InstallRequirement 
3031
32+     class  ExtraEnviron (TypedDict , total = False ):
33+         extra_environ : dict [str , str ]
34+ 
35+ 
3136logger  =  logging .getLogger (__name__ )
3237
3338
@@ -101,8 +106,44 @@ class SubprocessBuildEnvironmentInstaller:
101106    Install build dependencies by calling pip in a subprocess. 
102107    """ 
103108
104-     def  __init__ (self , finder : PackageFinder ) ->  None :
109+     def  __init__ (
110+         self ,
111+         finder : PackageFinder ,
112+         build_constraints : list [str ] |  None  =  None ,
113+         build_constraint_feature_enabled : bool  =  False ,
114+     ) ->  None :
105115        self .finder  =  finder 
116+         self ._build_constraints  =  build_constraints  or  []
117+         self ._build_constraint_feature_enabled  =  build_constraint_feature_enabled 
118+ 
119+     def  _deprecation_constraint_check (self ) ->  None :
120+         """ 
121+         Check for deprecation warning: PIP_CONSTRAINT affecting build environments. 
122+ 
123+         This warns when build-constraint feature is NOT enabled and PIP_CONSTRAINT 
124+         is not empty. 
125+         """ 
126+         if  self ._build_constraint_feature_enabled  or  self ._build_constraints :
127+             return 
128+ 
129+         pip_constraint  =  os .environ .get ("PIP_CONSTRAINT" )
130+         if  not  pip_constraint  or  not  pip_constraint .strip ():
131+             return 
132+ 
133+         deprecated (
134+             reason = (
135+                 "Setting PIP_CONSTRAINT will not affect " 
136+                 "build constraints in the future," 
137+             ),
138+             replacement = (
139+                 "to specify build constraints using --build-constraint or " 
140+                 "PIP_BUILD_CONSTRAINT. To disable this warning without " 
141+                 "any build constraints set --use-feature=build-constraint or " 
142+                 'PIP_USE_FEATURE="build-constraint"' 
143+             ),
144+             gone_in = "26.2" ,
145+             issue = None ,
146+         )
106147
107148    def  install (
108149        self ,
@@ -112,6 +153,8 @@ def install(
112153        kind : str ,
113154        for_req : InstallRequirement  |  None ,
114155    ) ->  None :
156+         self ._deprecation_constraint_check ()
157+ 
115158        finder  =  self .finder 
116159        args : list [str ] =  [
117160            sys .executable ,
@@ -167,6 +210,26 @@ def install(
167210            args .append ("--pre" )
168211        if  finder .prefer_binary :
169212            args .append ("--prefer-binary" )
213+ 
214+         # Handle build constraints 
215+         if  self ._build_constraint_feature_enabled :
216+             args .extend (["--use-feature" , "build-constraint" ])
217+ 
218+         if  self ._build_constraints :
219+             # Build constraints must be passed as both constraints 
220+             # and build constraints, so that nested builds receive 
221+             # build constraints 
222+             for  constraint_file  in  self ._build_constraints :
223+                 args .extend (["--constraint" , constraint_file ])
224+                 args .extend (["--build-constraint" , constraint_file ])
225+ 
226+         extra_environ : ExtraEnviron  =  {}
227+         if  self ._build_constraint_feature_enabled  and  not  self ._build_constraints :
228+             # If there are no build constraints but the build constraints 
229+             # feature is enabled then we must ignore regular constraints 
230+             # in the isolated build environment 
231+             extra_environ  =  {"extra_environ" : {"_PIP_IN_BUILD_IGNORE_CONSTRAINTS" : "1" }}
232+ 
170233        args .append ("--" )
171234        args .extend (requirements )
172235
@@ -178,6 +241,7 @@ def install(
178241                args ,
179242                command_desc = f"installing { kind } { identify_requirement }  ,
180243                spinner = spinner ,
244+                 ** extra_environ ,
181245            )
182246
183247
0 commit comments