change-wheel-version

0.6.0 · active · verified Thu Apr 16

change-wheel-version is a Python utility that modifies the version string within the metadata of an existing wheel (.whl) file. It's particularly useful for adding local version identifiers to custom-built wheels without altering the original package's build process. The library is active, with its latest version being 0.6.0, released in September 2024. Its release cadence is infrequent, driven by specific needs for wheel metadata manipulation.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `change-wheel-version` to modify the version of an existing wheel file. It first creates a minimal dummy Python package, builds it into a wheel, then applies `change-wheel-version` to update the wheel's metadata, and finally verifies the change using the `wheel info` command. This requires `pipx` and `build` to be installed.

import os
import subprocess
import tempfile
import shutil

# 1. Create a dummy Python project structure
project_name = "my_dummy_package"
original_version = "0.1.0"
modified_version = "0.1.0+local.123"

try:
    with tempfile.TemporaryDirectory() as tmpdir:
        project_dir = os.path.join(tmpdir, project_name)
        os.makedirs(project_dir)

        # Create setup.py
        with open(os.path.join(project_dir, "setup.py"), "w") as f:
            f.write(f'''
from setuptools import setup, find_packages

setup(
    name='{project_name}',
    version='{original_version}',
    packages=find_packages(),
    description='A dummy package for testing change-wheel-version',
)
''')

        # Create __init__.py
        os.makedirs(os.path.join(project_dir, project_name))
        with open(os.path.join(project_dir, project_name, "__init__.py"), "w") as f:
            f.write("__version__ = f'{original_version}'")

        # Change to project directory
        os.chdir(project_dir)

        # 2. Build the original wheel
        print(f"\nBuilding initial wheel for {project_name}-{original_version}...")
        subprocess.run(["python", "-m", "build", "--wheel"], check=True, capture_output=True)

        # Find the generated wheel file
        dist_dir = os.path.join(project_dir, "dist")
        original_wheel = [f for f in os.listdir(dist_dir) if f.endswith('.whl') and original_version in f][0]
        original_wheel_path = os.path.join(dist_dir, original_wheel)
        print(f"Original wheel created: {original_wheel_path}")

        # 3. Use change-wheel-version to modify the wheel's version
        modified_wheel_name = original_wheel.replace(original_version, modified_version)
        modified_wheel_path = os.path.join(dist_dir, modified_wheel_name)

        print(f"\nChanging version of {original_wheel} to {modified_version}...")
        subprocess.run(
            ["pipx", "run", "change-wheel-version", original_wheel_path, "--new-version", modified_version],
            check=True, capture_output=True
        )

        # The tool renames the file in place by default if --output is not specified
        # So we expect the original wheel to be renamed.
        if os.path.exists(original_wheel_path) and not os.path.exists(modified_wheel_path):
             # Fallback if the tool doesn't rename exactly as expected based on new version, e.g. if original had build tags already
             # For simplicity, we'll try to find the new file, or assume it overwrote.
             # More robust would be to use --output.
             print("Attempting to find the newly named wheel...")
             new_wheels = [f for f in os.listdir(dist_dir) if f.endswith('.whl') and modified_version in f]
             if new_wheels:
                 modified_wheel_path = os.path.join(dist_dir, new_wheels[0])
             else:
                 raise FileNotFoundError("Modified wheel not found with expected version in name.")

        print(f"Modified wheel: {modified_wheel_path}")

        # 4. Verify the new version using 'wheel info'
        print("\nVerifying the new wheel's version...")
        result = subprocess.run(["pipx", "run", "wheel", "info", modified_wheel_path], capture_output=True, text=True, check=True)
        print(result.stdout)

        if f"Version: {modified_version}" in result.stdout:
            print("\nSuccessfully changed and verified the wheel version!")
        else:
            print("\nFailed to verify the wheel version.")

        print(f"Cleaning up temporary directory: {tmpdir}")
except subprocess.CalledProcessError as e:
    print(f"Error executing command: {e.cmd}")
    print(f"Stdout: {e.stdout.decode()}")
    print(f"Stderr: {e.stderr.decode()}")
except FileNotFoundError as e:
    print(f"File not found error: {e}")
except Exception as e:
    print(f"An unexpected error occurred: {e}")

view raw JSON →