Open
Description
Description
pip-25.0.1 appears to run setup.py in such a way that import platform
picks up a local platform/
directory if it exists, instead of the built-in module.
This happens if platform/
is empty, or if it contains other files and directories without a __init__.py
file.
I include a Python script that shows the broken behaviour.
- Run with no args:
./pipbug.py
. - If not run in a venv it reruns itself inside a new venv.
- Then it creates a new project directory with a
pyproject.toml
file, a (non-working)setup.py
and an emptyplatform/
directory. - Then it attempts to build a wheel with pip-24.3.1 and pip-25.0.1.
Expected behavior
import platform
should get the built-in module regardless of whether there is a local platform
directory.
pip version
25.0.1
Python version
3.11 and 3.12.
OS
Linux, OpenBSD.
How to Reproduce
Run this Python script as file pipbug.py
:
#!/usr/bin/env python3
'''
pip-25.0.1 runs setup.py in such a way that `import platform` picks up local
`platform/` directory, not the built-in module.
'''
import os
import shlex
import shutil
import subprocess
import sys
import textwrap
filep = os.path.normpath(__file__)
def run(command, check=1):
print(f'Running: {command}', flush=1)
return subprocess.run(command, shell=1, check=check)
def main():
# Create project directory {filep}_testdir
testdir = f'{filep}_testdir'
shutil.rmtree(testdir, ignore_errors=1)
os.mkdir(testdir)
# Create empty `platform/` directory.
os.mkdir(f'{testdir}/platform')
# Create (non-working) setup.py.
with open(f'{testdir}/setup.py', 'w') as f:
f.write(
textwrap.dedent('''
import os
import platform
import sys
print(f'setup.py: {sys.path=}')
print(f'setup.py: {os.getcwd()=}')
print(f'setup.py: {dir(platform)=}')
print(f'setup.py: {platform.__file__=}')
print(f'setup.py: {getattr(platform, "__path__", None)=}')
print(f'setup.py: {platform.system()=}')
''')
)
# Create pyproject.toml.
with open(f'{testdir}/pyproject.toml', 'w') as f:
f.write(
textwrap.dedent('''
[build-system]
requires = []
# See pep-517.
#
build-backend = "setup"
backend-path = ["."]
''')
)
# Attempt to create wheel with pip-24.3.1. This gives expected error:
# AttributeError: module 'setup' has no attribute 'build_wheel'
print('=' * 80)
print(f'Testing with pip-24.3.1')
run(f'pip install pip==24.3.1')
run(f'pip wheel -v {os.path.abspath(testdir)}', check=0)
# Attempt to create wheel with pip-25.0.1. This gives different error:
# AttributeError: module 'platform' has no attribute 'system'
print('=' * 80)
print(f'Testing with pip-25.0.1')
run(f'pip install pip==25.0.1')
run(f'pip wheel -v {os.path.abspath(testdir)}', check=0)
if __name__ == '__main__':
if sys.prefix == sys.base_prefix:
# Not running in a venv. Rerun ourselves in a venv.
command = f'{sys.executable} -m venv {filep}_venv'
command += f' && . {filep}_venv/bin/activate'
command += f' && python'
for arg in sys.argv:
command += f' {shlex.quote(arg)}'
run(command)
else:
main()
Output
Example output on Linux is below.
- With pip-24.3.1 we get expected error `AttributeError: module 'setup' has no attribute 'build_wheel'.
- With pip-25.0.1 we get earlier error
AttributeError: module 'platform' has no attribute 'system'
, becauseimport platform
has picked up the local emptyplatform
directory instead of the built-in moduleplatform
.
> ./pipbug.py
Running: /usr/bin/python3 -m venv [...]/pipbug.py_venv && . [...]/pipbug.py_venv/bin/activate && python ./pipbug.py
================================================================================
Testing with pip-24.3.1
Running: pip install pip==24.3.1
Collecting pip==24.3.1
Using cached pip-24.3.1-py3-none-any.whl.metadata (3.7 kB)
Using cached pip-24.3.1-py3-none-any.whl (1.8 MB)
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 25.0.1
Uninstalling pip-25.0.1:
Successfully uninstalled pip-25.0.1
Successfully installed pip-24.3.1
[notice] A new release of pip is available: 24.3.1 -> 25.0.1
[notice] To update, run: pip install --upgrade pip
Running: pip wheel -v [...]/pipbug.py_testdir
Processing ./pipbug.py_testdir
Getting requirements to build wheel: started
Running command Getting requirements to build wheel
setup.py: sys.path=['[...]/pipbug.py_testdir', '[...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process', '/tmp/pip-build-env-4awji4kl/site', '/usr/lib/python312.zip', '/usr/lib/python3.12', '/usr/lib/python3.12/lib-dynload', '/tmp/pip-build-env-4awji4kl/overlay/lib/python3.12/site-packages', '/tmp/pip-build-env-4awji4kl/normal/lib/python3.12/site-packages']
setup.py: os.getcwd()='[...]/pipbug.py_testdir'
setup.py: dir(platform)=['_Processor', '_WIN32_CLIENT_RELEASES', '_WIN32_SERVER_RELEASES', '__builtins__', '__cached__', '__copyright__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_comparable_version', '_default_architecture', '_follow_symlinks', '_get_machine_win32', '_java_getprop', '_mac_ver_xml', '_node', '_norm_version', '_os_release_cache', '_os_release_candidates', '_parse_os_release', '_platform', '_platform_cache', '_sys_version', '_sys_version_cache', '_syscmd_file', '_syscmd_ver', '_uname_cache', '_unknown_as_blank', '_ver_stages', '_win32_ver', '_wmi_query', 'architecture', 'collections', 'freedesktop_os_release', 'functools', 'itertools', 'java_ver', 'libc_ver', 'mac_ver', 'machine', 'node', 'os', 'platform', 'processor', 'python_branch', 'python_build', 'python_compiler', 'python_implementation', 'python_revision', 'python_version', 'python_version_tuple', 're', 'release', 'sys', 'system', 'system_alias', 'uname', 'uname_result', 'version', 'win32_edition', 'win32_is_iot', 'win32_ver']
Getting requirements to build wheel: finished with status 'done'
Preparing metadata (pyproject.toml): started
setup.py: platform.__file__='/usr/lib/python3.12/platform.py'
setup.py: getattr(platform, "__path__", None)=None
setup.py: platform.system()='Linux'
Running command Preparing metadata (pyproject.toml)
setup.py: sys.path=['[...]/pipbug.py_testdir', '[...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process', '/tmp/pip-build-env-4awji4kl/site', '/usr/lib/python312.zip', '/usr/lib/python3.12', '/usr/lib/python3.12/lib-dynload', '/tmp/pip-build-env-4awji4kl/overlay/lib/python3.12/site-packages', '/tmp/pip-build-env-4awji4kl/normal/lib/python3.12/site-packages']
setup.py: os.getcwd()='[...]/pipbug.py_testdir'
setup.py: dir(platform)=['_Processor', '_WIN32_CLIENT_RELEASES', '_WIN32_SERVER_RELEASES', '__builtins__', '__cached__', '__copyright__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_comparable_version', '_default_architecture', '_follow_symlinks', '_get_machine_win32', '_java_getprop', '_mac_ver_xml', '_node', '_norm_version', '_os_release_cache', '_os_release_candidates', '_parse_os_release', '_platform', '_platform_cache', '_sys_version', '_sys_version_cache', '_syscmd_file', '_syscmd_ver', '_uname_cache', '_unknown_as_blank', '_ver_stages', '_win32_ver', '_wmi_query', 'architecture', 'collections', 'freedesktop_os_release', 'functools', 'itertools', 'java_ver', 'libc_ver', 'mac_ver', 'machine', 'node', 'os', 'platform', 'processor', 'python_branch', 'python_build', 'python_compiler', 'python_implementation', 'python_revision', 'python_version', 'python_version_tuple', 're', 'release', 'sys', 'system', 'system_alias', 'uname', 'uname_result', 'version', 'win32_edition', 'win32_is_iot', 'win32_ver']
setup.py: platform.__file__='/usr/lib/python3.12/platform.py'
setup.py: getattr(platform, "__path__", None)=None
setup.py: platform.system()='Linux'
Traceback (most recent call last):
File "[...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
main()
File "[...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 152, in prepare_metadata_for_build_wheel
whl_basename = backend.build_wheel(metadata_directory, config_settings)
^^^^^^^^^^^^^^^^^^^
AttributeError: module 'setup' has no attribute 'build_wheel'
Preparing metadata (pyproject.toml): finished with status 'error'
error: subprocess-exited-with-error
� Preparing metadata (pyproject.toml) did not run successfully.
� exit code: 1
��> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
full command: [...]/pipbug.py_venv/bin/python3 [...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py prepare_metadata_for_build_wheel /tmp/tmpoiz5wz0s
cwd: [...]/pipbug.py_testdir
[notice] A new release of pip is available: 24.3.1 -> 25.0.1
[notice] To update, run: pip install --upgrade pip
error: metadata-generation-failed
� Encountered error while generating package metadata.
��> See above for output.
note: This is an issue with the package mentioned above, not pip.
hint: See above for details.
================================================================================
Testing with pip-25.0.1
Running: pip install pip==25.0.1
Collecting pip==25.0.1
Using cached pip-25.0.1-py3-none-any.whl.metadata (3.7 kB)
Using cached pip-25.0.1-py3-none-any.whl (1.8 MB)
Installing collected packages: pip
Attempting uninstall: pip
Found existing installation: pip 24.3.1
Uninstalling pip-24.3.1:
Successfully uninstalled pip-24.3.1
Successfully installed pip-25.0.1
Running: pip wheel -v [...]/pipbug.py_testdir
Processing ./pipbug.py_testdir
Getting requirements to build wheel: started
Running command Getting requirements to build wheel
setup.py: sys.path=['/tmp/pip-build-env-9swhkfon/site', '/usr/lib/python312.zip', '/usr/lib/python3.12', '/usr/lib/python3.12/lib-dynload', '/tmp/pip-build-env-9swhkfon/overlay/lib/python3.12/site-packages', '/tmp/pip-build-env-9swhkfon/normal/lib/python3.12/site-packages']
setup.py: os.getcwd()='[...]/pipbug.py_testdir'
setup.py: dir(platform)=['__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
setup.py: platform.__file__=None
setup.py: getattr(platform, "__path__", None)=_NamespacePath(['[...]/pipbug.py_testdir/platform'])
Traceback (most recent call last):
File "[...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 389, in <module>
main()
File "[...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 373, in main
json_out["return_val"] = hook(**hook_input["kwargs"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "[...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 137, in get_requires_for_build_wheel
backend = _build_backend()
^^^^^^^^^^^^^^^^
File "[...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 70, in _build_backend
obj = import_module(mod_path)
^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.12/importlib/__init__.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 999, in exec_module
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
File "[...]/pipbug.py_testdir/setup.py", line 10, in <module>
print(f'setup.py: {platform.system()=}')
^^^^^^^^^^^^^^^
AttributeError: module 'platform' has no attribute 'system'
error: subprocess-exited-with-error
� Getting requirements to build wheel did not run successfully.
� exit code: 1
��> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
full command: [...]/pipbug.py_venv/bin/python3 [...]/pipbug.py_venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py get_requires_for_build_wheel /tmp/tmp1lbpiwek
cwd: [...]/pipbug.py_testdir
Getting requirements to build wheel: finished with status 'error'
error: subprocess-exited-with-error
� Getting requirements to build wheel did not run successfully.
� exit code: 1
��> See above for output.
note: This error originates from a subprocess, and is likely not a problem with pip.
Code of Conduct
- I agree to follow the PSF Code of Conduct.