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
3132logger = logging .getLogger (__name__ )
3233
3334
35+ class ExtraEnviron (TypedDict , total = False ):
36+ extra_environ : dict [str , str ]
37+
38+
3439def _dedup (a : str , b : str ) -> tuple [str ] | tuple [str , str ]:
3540 return (a , b ) if a != b else (a ,)
3641
@@ -101,8 +106,49 @@ 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+ constraints : list [str ] | None = None ,
115+ ) -> None :
105116 self .finder = finder
117+ self ._build_constraints = build_constraints or []
118+ self ._build_constraint_feature_enabled = build_constraint_feature_enabled
119+ self ._constraints = constraints or []
120+
121+ def _deprecation_constraint_check (self ) -> None :
122+ """
123+ Check for deprecation warning: PIP_CONSTRAINT affecting build environments.
124+
125+ This warns when build-constraint feature is NOT enabled but regular constraints
126+ match what PIP_CONSTRAINT environment variable points to.
127+ """
128+ if self ._build_constraint_feature_enabled :
129+ return
130+
131+ if not self ._constraints :
132+ return
133+
134+ if not os .environ .get ("PIP_CONSTRAINT" ):
135+ return
136+
137+ pip_constraint_files = [
138+ f .strip () for f in os .environ ["PIP_CONSTRAINT" ].split () if f .strip ()
139+ ]
140+ if pip_constraint_files and set (pip_constraint_files ) == set (self ._constraints ):
141+ deprecated (
142+ reason = (
143+ "Setting PIP_CONSTRAINT will not affect "
144+ "build constraints in the future,"
145+ ),
146+ replacement = (
147+ 'PIP_BUILD_CONSTRAINT with PIP_USE_FEATURE="build-constraint"'
148+ ),
149+ gone_in = "26.2" ,
150+ issue = None ,
151+ )
106152
107153 def install (
108154 self ,
@@ -112,6 +158,8 @@ def install(
112158 kind : str ,
113159 for_req : InstallRequirement | None ,
114160 ) -> None :
161+ self ._deprecation_constraint_check ()
162+
115163 finder = self .finder
116164 args : list [str ] = [
117165 sys .executable ,
@@ -167,13 +215,32 @@ def install(
167215 args .append ("--pre" )
168216 if finder .prefer_binary :
169217 args .append ("--prefer-binary" )
218+
219+ # Handle build constraints
220+ extra_environ : ExtraEnviron = {}
221+ if self ._build_constraint_feature_enabled :
222+ # Build constraints must be passed as both constraints
223+ # and build constraints to the subprocess
224+ for constraint_file in self ._build_constraints :
225+ args .extend (["--constraint" , constraint_file ])
226+ args .extend (["--build-constraint" , constraint_file ])
227+ args .extend (["--use-feature" , "build-constraint" ])
228+
229+ # If there are no build constraints but the build constraint
230+ # process is enabled then we must ignore regular constraints
231+ if not self ._build_constraints :
232+ extra_environ = {
233+ "extra_environ" : {"_PIP_IN_BUILD_IGNORE_CONSTRAINTS" : "1" }
234+ }
235+
170236 args .append ("--" )
171237 args .extend (requirements )
172238 with open_spinner (f"Installing { kind } " ) as spinner :
173239 call_subprocess (
174240 args ,
175241 command_desc = f"pip subprocess to install { kind } " ,
176242 spinner = spinner ,
243+ ** extra_environ ,
177244 )
178245
179246
0 commit comments