Strange pip wheel error in pip 26.2.1

I have a setup.py based package that has a bespoke bdist_wheel class

class BDistWheel(bdist_wheel):
	def run(self):
		if DEBUG: print('+++++ start BDistWheel')
		hgid = pjoin('src','rlextra','.hgid')
		with open(hgid,'w') as f:
			f.write(subprocess.check_output(["hg","id","-i"]).decode('ascii').replace('+',''))
		bdist_wheel.run(self)
		unwanted = pjoin(pkgDir,'rlextra.egg-info')
		if isdir(unwanted):
			if DEBUG: print(f'+++++ rmtree {unwanted!r}')
			shutil.rmtree(unwanted)
		if isfile(hgid): os.remove(hgid)
		if DEBUG: print('----- end	 BDistWheel')

this works fine in pip 26.1.2 & python 3.14 eg

$ pip --version
pip 26.1.2 from /home/robin/devel/reportlab/.py314/lib/python3.14/site-packages/pip (python 3.14)

$ pip wheel -w ./tmp . --no-deps
Looking in indexes: Simple index , Welcome to ReportLab's pypiserver!
Processing ./.
Installing build dependencies … done
Getting requirements to build wheel … done
Preparing metadata (pyproject.toml) … done
Building wheels for collected packages: rlextra
Building wheel for rlextra (pyproject.toml) … done
Created wheel for rlextra: filename=rlextra-5.0.1-py3-none-any.whl size=4285030 sha256=9c8a76d9619f55eebb121d64ef0f8f4ff9972bd7bfdf5571240c432e07e96931
Stored in directory: /tmp/pip-ephem-wheel-cache-3j3tcjnt/wheels/16/75/ae/dc65b58deeb115d70d389a4bb83447a32386c6a27d2730eaec
Successfully built rlextra

However if I upgrade pip it fails

$ pip --version
pip 26.2.1 from /home/robin/devel/reportlab/.py314/lib/python3.14/site-packages/pip (python 3.14)
$ pip wheel -w ./tmp . --no-deps
Looking in indexes: https://pypi.org/simple, https://beta:****@www.reportlab.com/pypi
Processing ./.
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: rlextra
  Building wheel for rlextra (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Building wheel for rlextra (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [72 lines of output]
      /tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/wheel/bdist_wheel.py:4: FutureWarning: The 'wheel' package is no longer the canonical location of the 'bdist_wheel' command, and will be removed in a future release. Please update to setuptools v70.1 or later which contains an integrated version of this command.
        warn(
      running bdist_wheel
      Error processing line 1 of /home/robin/devel/reportlab/.py314/lib/python3.14/site-packages/__editable__.preppy-5.2.1.pth:
      
      Error in sitecustomize; set PYTHONVERBOSE for traceback:
      ModuleNotFoundError: No module named 'traceback'
      Traceback (most recent call last):
        File "/usr/bin/hg", line 10, in <module>
          from __future__ import annotations
      ModuleNotFoundError: No module named '__future__'
      Traceback (most recent call last):
        File "/home/robin/devel/reportlab/.py314/lib/python3.14/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 389, in <module>
          main()
          ~~~~^^
        File "/home/robin/devel/reportlab/.py314/lib/python3.14/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 373, in main
          json_out["return_val"] = hook(**hook_input["kwargs"])
                                   ~~~~^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/robin/devel/reportlab/.py314/lib/python3.14/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 280, in build_wheel
          return _build_backend().build_wheel(
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
              wheel_directory, config_settings, metadata_directory
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          )
          ^
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/build_meta.py", line 441, in build_wheel
          return _build(['bdist_wheel', '--dist-info-dir', str(metadata_directory)])
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/build_meta.py", line 429, in _build
          return self._build_with_temp_dir(
                 ~~~~~~~~~~~~~~~~~~~~~~~~~^
              cmd,
              ^^^^
          ...<3 lines>...
              self._arbitrary_args(config_settings),
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          )
          ^
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/build_meta.py", line 410, in _build_with_temp_dir
          self.run_setup()
          ~~~~~~~~~~~~~~^^
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/build_meta.py", line 317, in run_setup
          exec(code, locals())  # noqa: S102 # exec is intentional here
          ~~~~^^^^^^^^^^^^^^^^
        File "<string>", line 251, in <module>
        File "<string>", line 192, in main
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/__init__.py", line 117, in setup
          return distutils.core.setup(**attrs)  # type: ignore[return-value]
                 ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/_distutils/core.py", line 168, in setup
          return run_commands(dist)
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/_distutils/core.py", line 184, in run_commands
          dist.run_commands()
          ~~~~~~~~~~~~~~~~~^^
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/_distutils/dist.py", line 1028, in run_commands
          self.run_command(cmd)
          ~~~~~~~~~~~~~~~~^^^^^
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/dist.py", line 1106, in run_command
          super().run_command(command)
          ~~~~~~~~~~~~~~~~~~~^^^^^^^^^
        File "/tmp/pip-build-env-44xuv01n/overlay/lib/python3.14/site-packages/setuptools/_distutils/dist.py", line 1047, in run_command
          cmd_obj.run()
          ~~~~~~~~~~~^^
        File "<string>", line 157, in run
        File "/home/robin/LOCAL/3.14.7/lib/python3.14/subprocess.py", line 473, in check_output
          return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
                 ~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                     **kwargs).stdout
                     ^^^^^^^^^
        File "/home/robin/LOCAL/3.14.7/lib/python3.14/subprocess.py", line 578, in run
          raise CalledProcessError(retcode, process.args,
                                   output=stdout, stderr=stderr)
      subprocess.CalledProcessError: Command '['hg', 'id', '-i']' returned non-zero exit status 1.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for rlextra

It seems this latest pip is interfering with mercurial in some way

There’s code that clears sys.path in Fix `sitecustomize.py` used for build isolation on Python 3.15+ by ichard26 · Pull Request #14033 · pypa/pip · GitHub , so it might be related.

--no-build-isolation will probably work around it for now.

How about filing this on the pypa/pip issue tracker?

I find that if I put this into setup.py

myenv = os.environ.copy()
del myenv['PYTHONPATH']

and use env=myenv in all the subprocess popen type calls that the build works fine. It seems that the latest pip has done something differently, and added some variables eg

PYTHONNOUSERSITE=1
PYPROJECT_HOOKS_BUILD_BACKEND=setuptools.build_meta
PLAT=linux-x86_64
PYTHONPATH=/tmp/pip-build-env-s3h3kq7k/site
PIP_BUILD_TRACKER=/tmp/pip-build-tracker-w2rcrj58

Changing the PYTHONPATH seems to mess with python behaviour enough to make all my python subprocess commands fail.

The --no-build-isolationflag seems to work, but it ought to be possible to run commands with a known environment that’s uncorrupted by pip. If that last is True then this is a bug.

1 Like

Can you please report to Issues · pypa/pip · GitHub

This looks like it might be an issue in trying to fix up our legacy build isolation, I think our new build isolation system should work: --use-feature=venv-isolation

pip wheel -w ./tmp . --no-deps --use-feature=venv-isolation works.

I would raise a bug, but I cannot put in steps to reproduce as the failing package is private and I will not create an artificial case. The github issue mechanism is too complex and requiring steps to reproduce is often impossible.

I can of course continue to just use setup.py bdist_wheel or add --no-build-isolationor --use-feature=venv-isolationto the pip command.

Regardless, this is completely the wrong forum, this category is for discussing the the Python packaging standards and ecosystem, not a pip discussion or support channel.

The issue template can be filled out on a best effort basis, it doesn’t have to be perfect, it’s just trying to avoid low quality reports like “I got an error, help”, what you’ve reported here is sufficiently high quality to work on.

4 Likes

Sorry I must have misread this

Packaging

A place to talk about packaging Python software and the tooling to make that possible. Use this category for discussions relating to anything packaging in Python, including but not limited to: PyPI / Warehouse pip s…read more

1 Like

The key is

For bugs and similar issues, please use the relevant issue tracker for the project in question.

It’s fine to talk about pip behaviour here if you want to, but there’s no guarantee that a pip maintainer will read or respond to your post, and without an issue in our tracker, it’s highly unlikely we’ll do anything to fix a problem.

I have now raised an issue in the pypa git.

I really wanted some positive assertion that this behaviour is a bug or not.

My assumption is that sub-commands would normally run with the same environment as that which pip starts in. ie pip would be environment transparent.

1 Like

We try not to modify the environment, but our current isolation mechanism achieves the Python-level isolation via PYTHONPATH and a custom sitecustomize.py that drops system site paths.

Of course, this is fragile and interacts poorly with system level tools that happen to be written in Python. There’s a reason why we’re aiming to transition to using proper virtual environments for isolation. The first step is having feature available experimentally via --use-feature=venv-isolation. Unfortunately, there is a good chunk of work left remaining before we can enable it by default.

I’ll reply in more detail on the pip issue: pip 26.2.1 wheel corrupts subprocess environment · Issue #14278 · pypa/pip · GitHub

4 Likes