Problem
I have a situation where PYTHONPATH is set such that it contains a directory that has a build dependency in it, and running python -m build fails with the error "Backend 'X' is not available".
As an example:
$ cat <<EOF > pyproject.toml
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
[project]
name = "myemptypkg"
version = "0.1.0"
description = "Nothing"
EOF
$ python -m venv .venv
$ .venv/bin/pip install --upgrade pip build
$ .venv/bin/pip list
Package Version
--------------- -------
build 1.4.3
packaging 26.0
pip 26.0.1
pyproject_hooks 1.2.0
setuptools 65.5.1
$ PYTHONPATH=.venv/lib/python3.11/site-packages .venv/bin/python -m build
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
- setuptools
* Getting build dependencies for sdist...
Traceback (most recent call last):
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/pyproject_hooks/_impl.py", line 402, in _call_hook
raise BackendUnavailable(
pyproject_hooks._impl.BackendUnavailable: Cannot import 'setuptools.build_meta'
ERROR Backend 'setuptools.build_meta' is not available.
Note that the use of pip >=22.3 is important to trigger this code path:
|
if dist := _has_dependency('pip', '22.3'): # pragma: no cover |
Explanation of the issue
This comes about because the command to install the build dependencies has PYTHONPATH available to it, via _PipBackend.install_dependencies (
|
run_subprocess(cmd, env=_pip_env()) |
). This differs from the environment that is used to execute
pyproject_hooks, where PYTHONPATH is unset by
DefaultIsolatedEnv.make_extra_environ.
Here's the tracebacks of where the two different subprocesses occur:
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
- setuptools
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 643, in <module>
main(sys.argv[1:], 'python -m build')
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 622, in main
built = build(
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 325, in build_package_via_sdist
sdist = _build(
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 209, in _build
with _bootstrap_build_env(
File "/usr/lib64/python3.11/contextlib.py", line 137, in __enter__
return next(self.gen)
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 177, in _bootstrap_build_env
install(builder.build_system_requires)
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/env.py", line 180, in install
self._env_backend.install_dependencies(requirements, constraints)
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/env.py", line 358, in install_dependencies
import traceback; traceback.print_stack()
* Getting build dependencies for sdist...
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 643, in <module>
main(sys.argv[1:], 'python -m build')
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 622, in main
built = build(
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 325, in build_package_via_sdist
sdist = _build(
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 209, in _build
with _bootstrap_build_env(
File "/usr/lib64/python3.11/contextlib.py", line 137, in __enter__
return next(self.gen)
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/__main__.py", line 179, in _bootstrap_build_env
install(builder.get_requires_for_build(distribution, config_settings))
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/_builder.py", line 260, in get_requires_for_build
return set(get_requires(config_settings))
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/pyproject_hooks/_impl.py", line 356, in get_requires_for_build_sdist
return self._call_hook(
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/pyproject_hooks/_impl.py", line 392, in _call_hook
self._subprocess_runner(
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/_builder.py", line 153, in _invoke_wrapped_runner
runner(cmd, cwd, {**(env.make_extra_environ() or {}), **(extra_environ or {})})
File "/u/asw/temp/build_test/.venv/lib/python3.11/site-packages/build/env.py", line 153, in make_extra_environ
import traceback; traceback.print_stack()
Possible solution
I can't speak to the best way to structure code changes for a solution, but if I make the installation of build dependencies ignore PYTHONPATH then the package successfully builds.
--- a/.venv/lib/python3.11/site-packages/build/env.py 2026-04-14 13:53:29.496225357 -0400
+++ b/.venv/lib/python3.11/site-packages/build/env.py 2026-04-14 13:53:18.959692000 -0400
@@ -197,9 +197,11 @@
def _pip_env() -> dict[str, str] | None:
+ env = os.environ.copy()
+ env['PYTHONPATH'] = ''
if 'PIP_KEYRING_PROVIDER' not in os.environ and _has_keyring_cli():
- return {**os.environ, 'PIP_KEYRING_PROVIDER': 'subprocess'}
- return None
+ return {**env, 'PIP_KEYRING_PROVIDER': 'subprocess'}
+ return env
class _PipBackend(_EnvBackend):
Problem
I have a situation where PYTHONPATH is set such that it contains a directory that has a build dependency in it, and running
python -m buildfails with the error "Backend 'X' is not available".As an example:
Note that the use of pip >=22.3 is important to trigger this code path:
build/src/build/env.py
Line 218 in d0bb805
Explanation of the issue
This comes about because the command to install the build dependencies has PYTHONPATH available to it, via
_PipBackend.install_dependencies(build/src/build/env.py
Line 357 in d0bb805
pyproject_hooks, where PYTHONPATH is unset byDefaultIsolatedEnv.make_extra_environ.Here's the tracebacks of where the two different subprocesses occur:
Possible solution
I can't speak to the best way to structure code changes for a solution, but if I make the installation of build dependencies ignore PYTHONPATH then the package successfully builds.