Skip to content

Commit 9344349

Browse files
Copilotryanking13
andauthored
Add PIP_BUILD_CONSTRAINT support for pip 26.2+ compatibility (#292)
* Initial plan * Add PIP_BUILD_CONSTRAINT alongside PIP_CONSTRAINT Co-authored-by: ryanking13 <[email protected]> * Update test xbuildenv to include PIP_BUILD_CONSTRAINT Co-authored-by: ryanking13 <[email protected]> * Remove pip_build_constraint from config mapping and revert xbuildenv binary Co-authored-by: ryanking13 <[email protected]> * Add support for PIP_BUILD_CONSTRAINT env variable in config and _create_constraints_file Co-authored-by: ryanking13 <[email protected]> * Improve comment clarity in _create_constraints_file Co-authored-by: ryanking13 <[email protected]> * Add tests for PIP_BUILD_CONSTRAINT and update CHANGELOG Co-authored-by: ryanking13 <[email protected]> * Remove placeholder PR reference from CHANGELOG Co-authored-by: ryanking13 <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: ryanking13 <[email protected]>
1 parent 1267150 commit 9344349

File tree

5 files changed

+81
-4
lines changed

5 files changed

+81
-4
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Added support for `PIP_BUILD_CONSTRAINT` environment variable for pip 26.2+ compatibility.
13+
The build system now prioritizes `PIP_BUILD_CONSTRAINT` over `PIP_CONSTRAINT` when determining
14+
build-time constraints, while maintaining backward compatibility.
15+
1016
## [0.31.2] - 2026/01/26
1117

1218
### Added

pyodide_build/build_env.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,17 +328,21 @@ def local_versions() -> dict[str, str]:
328328

329329

330330
def _create_constraints_file() -> str:
331+
# PIP_BUILD_CONSTRAINT takes precedence; fall back to PIP_CONSTRAINT for backward compatibility
331332
try:
332-
constraints = get_build_flag("PIP_CONSTRAINT")
333+
constraints = get_build_flag("PIP_BUILD_CONSTRAINT")
333334
except ValueError:
334-
return ""
335+
try:
336+
constraints = get_build_flag("PIP_CONSTRAINT")
337+
except ValueError:
338+
return ""
335339

336340
if not constraints:
337341
return ""
338342

339343
if len(constraints.split(maxsplit=1)) > 1:
340344
raise ValueError(
341-
"PIP_CONSTRAINT contains spaces so pip will misinterpret it. Make sure the path to pyodide has no spaces.\n"
345+
"PIP_BUILD_CONSTRAINT/PIP_CONSTRAINT contains spaces so pip will misinterpret it. Make sure the path to pyodide has no spaces.\n"
342346
"See https://github.com/pypa/pip/issues/13283"
343347
)
344348

pyodide_build/config.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ def _parse_makefile_envs(
216216
"pyodide_package_index": "PYODIDE_PACKAGE_INDEX",
217217
"platform_triplet": "PLATFORM_TRIPLET",
218218
"pip_constraint": "PIP_CONSTRAINT",
219+
"pip_build_constraint": "PIP_BUILD_CONSTRAINT",
219220
"pymajor": "PYMAJOR",
220221
"pymicro": "PYMICRO",
221222
"pyminor": "PYMINOR",
@@ -320,6 +321,8 @@ def _parse_makefile_envs(
320321
"pyodide_interpreter": "$(PYODIDE_ROOT)/dist/python",
321322
"pyodide_package_index": "$(PYODIDE_ROOT)/package_index",
322323
"dist_dir": "$(PYODIDE_ROOT)/dist",
324+
# Pip constraints - defaults to PIP_CONSTRAINT if not set
325+
"pip_build_constraint": "$(PIP_CONSTRAINT)",
323326
}
324327

325328

pyodide_build/recipe/builder.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,9 @@ def _compile(
476476
)
477477
build_env = runner.env
478478

479-
build_env["PIP_CONSTRAINT"] = str(self._create_constraints_file())
479+
constraints_file = str(self._create_constraints_file())
480+
build_env["PIP_CONSTRAINT"] = constraints_file
481+
build_env["PIP_BUILD_CONSTRAINT"] = constraints_file
480482

481483
wheel_path = pypabuild.build(
482484
self.src_extract_dir, self.src_dist_dir, build_env, config_settings

pyodide_build/tests/test_build_env.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,65 @@ def test_wheel_paths(dummy_xbuildenv):
237237
f"{current_version}-none-any",
238238
]
239239
)
240+
241+
242+
def test_create_constraints_file_with_pip_build_constraint(
243+
tmp_path, dummy_xbuildenv, monkeypatch, reset_env_vars, reset_cache
244+
):
245+
"""Test that _create_constraints_file prioritizes PIP_BUILD_CONSTRAINT."""
246+
# Set up a test constraints file
247+
constraints_file = tmp_path / "build_constraints.txt"
248+
constraints_file.write_text("numpy<2.0\n")
249+
250+
# Set PIP_BUILD_CONSTRAINT via environment - this will override the computed default
251+
monkeypatch.setenv("PIP_BUILD_CONSTRAINT", str(constraints_file))
252+
253+
# Clear caches to pick up the new environment variable
254+
build_env.get_build_environment_vars.cache_clear()
255+
build_env.get_pyodide_root.cache_clear()
256+
257+
result = build_env._create_constraints_file()
258+
# Should use PIP_BUILD_CONSTRAINT when explicitly set
259+
assert result == str(constraints_file)
260+
261+
262+
def test_create_constraints_file_uses_default_from_xbuildenv(
263+
dummy_xbuildenv, reset_env_vars, reset_cache
264+
):
265+
"""Test that _create_constraints_file uses values from xbuildenv when no override is provided."""
266+
# Don't set any environment overrides - use what comes from xbuildenv
267+
# The xbuildenv has PIP_CONSTRAINT set, and pip_build_constraint defaults to it
268+
269+
# Clear caches
270+
build_env.get_build_environment_vars.cache_clear()
271+
build_env.get_pyodide_root.cache_clear()
272+
273+
result = build_env._create_constraints_file()
274+
# Should get the default constraint file path from xbuildenv
275+
assert "constraints.txt" in result
276+
assert result # Should not be empty
277+
278+
279+
def test_create_constraints_file_pip_build_constraint_takes_precedence(
280+
tmp_path, dummy_xbuildenv, monkeypatch, reset_env_vars, reset_cache
281+
):
282+
"""Test that PIP_BUILD_CONSTRAINT takes precedence over PIP_CONSTRAINT."""
283+
# Set up two different constraints files
284+
build_constraints_file = tmp_path / "build_constraints.txt"
285+
build_constraints_file.write_text("numpy<2.0\n")
286+
287+
regular_constraints_file = tmp_path / "constraints.txt"
288+
regular_constraints_file.write_text("scipy<2.0\n")
289+
290+
# Set both environment variables
291+
monkeypatch.setenv("PIP_BUILD_CONSTRAINT", str(build_constraints_file))
292+
monkeypatch.setenv("PIP_CONSTRAINT", str(regular_constraints_file))
293+
294+
# Clear caches to pick up the new environment variables
295+
build_env.get_build_environment_vars.cache_clear()
296+
build_env.get_pyodide_root.cache_clear()
297+
298+
# PIP_BUILD_CONSTRAINT should take precedence
299+
result = build_env._create_constraints_file()
300+
assert result == str(build_constraints_file)
301+
assert result != str(regular_constraints_file)

0 commit comments

Comments
 (0)