{"id":288,"library":"wheel","title":"wheel","description":"wheel is the PyPA reference implementation of the Python wheel binary distribution format (PEP 427), providing a command-line tool for inspecting, unpacking, repacking, converting, and retagging .whl files. As of v0.46.0, it no longer ships the setuptools bdist_wheel command — that implementation now lives in setuptools ≥70.1. Current stable version is 0.46.3, released on a roughly quarterly cadence with occasional patch releases for CVEs and compatibility fixes.","status":"active","version":"0.46.3","language":"python","source_language":"en","source_url":"https://github.com/pypa/wheel","tags":["packaging","build","wheel","whl","pypa","distribution","cli","bdist_wheel"],"install":[{"cmd":"pip install wheel","lang":"bash","label":"pip"},{"cmd":"uv add wheel","lang":"bash","label":"uv"}],"dependencies":[{"reason":"Run-time dependency for wheel tag parsing; was vendored before v0.46.0, now a required external dep.","package":"packaging","optional":false}],"imports":[{"note":"wheel exposes no stable public Python API. All functionality is through the 'wheel' CLI or 'python -m wheel'. Do not import internal modules like wheel.cli or wheel.metadata — both are private as of v0.46.0.","wrong":"import wheel; wheel.unpack(...)","symbol":"wheel (CLI entry point)","correct":"import subprocess; subprocess.run(['wheel', 'unpack', 'some.whl'])"},{"note":"wheel.bdist_wheel is now only an alias that emits a FutureWarning (changed from DeprecationWarning in v0.46.2). The real implementation lives in setuptools ≥70.1. Subclass from setuptools.command.bdist_wheel.bdist_wheel directly.","wrong":"from wheel.bdist_wheel import bdist_wheel","symbol":"bdist_wheel (setuptools command)","correct":"from setuptools.command.bdist_wheel import bdist_wheel"},{"note":"wheel.metadata was made a private module in v0.46.0 and emits a DeprecationWarning on import. Use the 'packaging' library for metadata operations instead.","wrong":"from wheel.metadata import pkginfo_to_metadata","symbol":"wheel.metadata (private module)","correct":"from packaging.metadata import Metadata"}],"quickstart":{"code":"import subprocess\nimport sys\n\n# Demonstrate the four main wheel CLI operations\n\n# 1. Unpack a wheel (verifies RECORD hashes)\n# subprocess.run(['wheel', 'unpack', 'someproject-1.0-py3-none-any.whl', '--dest', '/tmp/unpacked'], check=True)\n\n# 2. Repack a previously unpacked wheel directory\n# subprocess.run(['wheel', 'pack', '/tmp/unpacked/someproject-1.0', '--dest-dir', '/tmp/repacked'], check=True)\n\n# 3. Retag a wheel (e.g. mark as universal py3)\n# subprocess.run(['wheel', 'tags', '--python-tag', 'py3', 'someproject-1.0-py2-none-any.whl'], check=True)\n\n# 4. Convert a legacy .egg to .whl\n# subprocess.run(['wheel', 'convert', 'someproject-1.0-py3.egg'], check=True)\n\n# Show installed wheel version\nresult = subprocess.run(\n    [sys.executable, '-m', 'wheel', 'version'],\n    capture_output=True, text=True\n)\nprint(result.stdout.strip())\n","lang":"python","description":"wheel is a CLI-only tool. The four commands are: unpack (extract + verify hashes), pack (repack + regenerate RECORD), tags (retag for platform/interpreter/abi), and convert (egg→whl). All invoked via 'wheel <cmd>' or 'python -m wheel <cmd>'."},"warnings":[{"fix":"Upgrade setuptools to ≥70.1 — it now ships bdist_wheel natively. Remove 'wheel' from build-system.requires unless you actually use the wheel CLI itself.","message":"v0.46.0 removed the bdist_wheel setuptools command implementation from wheel entirely. Projects with setuptools <70.1 that relied on wheel providing the bdist_wheel command will see 'error: invalid command bdist_wheel'. wheel.bdist_wheel is now only an alias pointing at setuptools.command.bdist_wheel.","severity":"breaking","affected_versions":"<0.46.0 behaviour depended on; breaks when wheel≥0.46.0 + setuptools<70.1"},{"fix":"Stop importing any wheel.* internal modules. Use the 'packaging' library for metadata/tag parsing, and invoke wheel functionality via subprocess or the CLI.","message":"wheel.metadata and internal submodules (wheel.cli, wheel._bdist_wheel, wheel.macosx_libfile removed in 0.46.0, temporarily restored in 0.46.1) are private. Importing them may raise ImportError across minor releases with no deprecation cycle.","severity":"breaking","affected_versions":">=0.46.0"},{"fix":"Do not import wheel.macosx_libfile. Depend on the platform tag detection built into setuptools or use macholib directly.","message":"wheel.macosx_libfile was removed in v0.46.0 and only temporarily restored in v0.46.1. Any code importing it is relying on an undocumented internal that will disappear again.","severity":"breaking","affected_versions":">=0.46.0"},{"fix":"Change the base class to setuptools.command.bdist_wheel.bdist_wheel. See pypa/wheel#631.","message":"Importing wheel.bdist_wheel now emits a FutureWarning (was DeprecationWarning before v0.46.2). Custom bdist_wheel subclasses that inherit from wheel.bdist_wheel.bdist_wheel will break in a future release.","severity":"deprecated","affected_versions":">=0.44.0"},{"fix":"Remove 'wheel' from [build-system] requires = [...] unless your build script explicitly imports a wheel module at build time.","message":"Adding 'wheel' to build-system.requires in pyproject.toml is no longer necessary or recommended for setuptools-based projects. Listing it unnecessarily forces it to be installed even for sdist-only builds.","severity":"gotcha","affected_versions":"all (especially >=0.44.0 now that setuptools ships bdist_wheel)"},{"fix":"Ensure 'packaging' is installed in the environment. It is declared as a dependency so 'pip install wheel' installs it automatically, but manual/minimal installs must add it explicitly.","message":"v0.46.0 removed the vendored 'packaging' library and now requires it as an explicit runtime dependency. Environments where packaging is absent (e.g. minimal build containers) will get an ImportError when any wheel CLI command is invoked.","severity":"breaking","affected_versions":">=0.46.0"},{"fix":"Upgrade to wheel>=0.46.2. Never unpack untrusted/third-party wheel files in production environments without sandboxing.","message":"CVE-2026-24049 (fixed in v0.46.2): 'wheel unpack' could alter permissions of files outside the destination tree with a maliciously crafted wheel. Any version <0.46.2 unpacking untrusted wheels is vulnerable.","severity":"gotcha","affected_versions":"<0.46.2"},{"fix":"Address pip's warnings by running pip in a virtual environment or as a non-root user where appropriate, and consider updating pip to the latest version. These are not directly related to 'wheel' library functionality.","message":"The pip installer reported warnings during execution, specifically about running as root and an available update for pip. These are general pip usage warnings and do not indicate a failure or specific issue with the 'wheel' library itself.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T12:51:53.190Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Upgrade setuptools and ensure wheel is installed: `pip install --upgrade setuptools wheel`","cause":"The 'bdist_wheel' command, which is used to build wheel distributions, is provided by setuptools. This error occurs if your setuptools version is too old (prior to v70.1) and wheel is not installed, or if setuptools itself isn't properly installed to register the command.","error":"error: unknown command 'bdist_wheel'"},{"fix":"Install the wheel package: `pip install wheel`","cause":"The `wheel` package is not installed in the active Python environment, or the directory containing its executable script is not included in the system's PATH.","error":"wheel: command not found"},{"fix":"Ensure the wheel filename adheres to the format `{distribution}-{version}(-{build tag})?-{python tag}-{abi tag}-{platform tag}.whl`. This usually means the wheel was malformed or renamed incorrectly, and often requires rebuilding the wheel.","cause":"The wheel file name does not conform to the PEP 427 specification for Python wheel binary distribution filenames, which requires a specific format for package name, version, build tag, Python tag, ABI tag, and platform tag.","error":"wheel.exceptions.InvalidWheelFilename: Invalid wheel filename: '<filename>'"},{"fix":"Ensure the file specified for unpacking is a correctly formatted Python wheel file.","cause":"The `wheel unpack` command was executed on a file that is not a valid Python wheel archive (`.whl` file).","error":"wheel.exceptions.WheelError: Not a wheel."},{"fix":"Ensure `wheel` is listed in the `build-system.requires` section of `pyproject.toml`, or pre-install it globally if not using isolated builds: `pip install wheel`.","cause":"The project being installed requires `wheel` as a build dependency (often specified in `pyproject.toml` or `setup.py`), but `wheel` is not present in the isolated build environment or the global environment where the build is taking place.","error":"ERROR: Could not build wheels for <package_name> because build backend 'setuptools.build_meta' did not find 'wheel' in the build requirements."}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":80,"quickstart_tag":"verified","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":0.6,"disk_size":"17.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":0.6,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":1,"disk_size":"19.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":1,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":0.8,"disk_size":"12.4M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":0.8,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.09,"mem_mb":1,"disk_size":"12.0M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":0.8,"disk_size":"13M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":0.6,"disk_size":"17.3M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"'wheel', 'unpack', 'some.whl'","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":0.6,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"verified","tag_description":"quickstart runs on critical runtimes, recently tested","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]}}