Install & Compatibility
Where this runs
tested against v0.45.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.072s · 17.8MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.6s · import 0.062s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
wheel (CLI entry point)
✓ import subprocess; subprocess.run(['wheel', 'unpack', 'some.whl'])
✗ import wheel; wheel.unpack(...)
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.
bdist_wheel (setuptools command)
✓ from setuptools.command.bdist_wheel import bdist_wheel
✗ from wheel.bdist_wheel import bdist_wheel
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.
wheel.metadata (private module)
✓ from packaging.metadata import Metadata
✗ from wheel.metadata import pkginfo_to_metadata
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.
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>'.
import subprocess
import sys
# Demonstrate the four main wheel CLI operations
# 1. Unpack a wheel (verifies RECORD hashes)
# subprocess.run(['wheel', 'unpack', 'someproject-1.0-py3-none-any.whl', '--dest', '/tmp/unpacked'], check=True)
# 2. Repack a previously unpacked wheel directory
# subprocess.run(['wheel', 'pack', '/tmp/unpacked/someproject-1.0', '--dest-dir', '/tmp/repacked'], check=True)
# 3. Retag a wheel (e.g. mark as universal py3)
# subprocess.run(['wheel', 'tags', '--python-tag', 'py3', 'someproject-1.0-py2-none-any.whl'], check=True)
# 4. Convert a legacy .egg to .whl
# subprocess.run(['wheel', 'convert', 'someproject-1.0-py3.egg'], check=True)
# Show installed wheel version
result = subprocess.run(
[sys.executable, '-m', 'wheel', 'version'],
capture_output=True, text=True
)
print(result.stdout.strip())
wheel --version
Debug
Known issues
breakingv0.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.fixUpgrade setuptools to ≥70.1 — it now ships bdist_wheel natively. Remove 'wheel' from build-system.requires unless you actually use the wheel CLI itself.
affects: <0.46.0 behaviour depended on; breaks when wheel≥0.46.0 + setuptools<70.1
breakingwheel.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.fixStop importing any wheel.* internal modules. Use the 'packaging' library for metadata/tag parsing, and invoke wheel functionality via subprocess or the CLI.
affects: >=0.46.0
breakingwheel.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.fixDo not import wheel.macosx_libfile. Depend on the platform tag detection built into setuptools or use macholib directly.
affects: >=0.46.0
deprecatedImporting 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.fixChange the base class to setuptools.command.bdist_wheel.bdist_wheel. See pypa/wheel#631.
affects: >=0.44.0
gotchaAdding '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.fixRemove 'wheel' from [build-system] requires = [...] unless your build script explicitly imports a wheel module at build time.
affects: all (especially >=0.44.0 now that setuptools ships bdist_wheel)
breakingv0.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.fixEnsure '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.
affects: >=0.46.0
gotchaCVE-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.fixUpgrade to wheel>=0.46.2. Never unpack untrusted/third-party wheel files in production environments without sandboxing.
affects: <0.46.2
gotchaThe 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.fixAddress 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.
affects: all
Errors
Common errors & fixes
error: unknown command 'bdist_wheel'
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.
fixUpgrade setuptools and ensure wheel is installed: `pip install --upgrade setuptools wheel`
wheel: command not found
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.
fixInstall the wheel package: `pip install wheel`
wheel.exceptions.InvalidWheelFilename: Invalid wheel filename: '<filename>'
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.
fixEnsure 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. wheel.exceptions.WheelError: Not a wheel.
The `wheel unpack` command was executed on a file that is not a valid Python wheel archive (`.whl` file).
fixEnsure the file specified for unpacking is a correctly formatted Python wheel file.
ERROR: Could not build wheels for <package_name> because build backend 'setuptools.build_meta' did not find 'wheel' in the build requirements.
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.
fixEnsure `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`.
Upgrade
Version history
0.48.0latest on PyPI · released Aug 11, 2026
Audit
Dependencies
packagingrequiredRun-time dependency for wheel tag parsing; was vendored before v0.46.0, now a required external dep.