{"id":516,"library":"installer","title":"Installer","description":"Installer is a low-level library from the Python Packaging Authority (PyPA) designed for installing Python wheel distributions. It provides fundamental abstractions and functionality for unpacking wheels and generating platform-independent Python script wrappers. As a core PyPA tool, it is actively maintained with releases occurring as new functionality, bug fixes, or compatibility updates are needed.","status":"active","version":"0.7.0","language":"python","source_language":"en","source_url":"https://github.com/pypa/installer","tags":["packaging","wheels","installation","pypa","low-level"],"install":[{"cmd":"pip install installer","lang":"bash","label":"Install stable release"}],"dependencies":[{"reason":"Required for working with .whl files, specifically the `WheelFile.open` functionality.","package":"wheel","optional":false}],"imports":[{"symbol":"install","correct":"from installer import install"},{"symbol":"SchemeDictionaryDestination","correct":"from installer.destinations import SchemeDictionaryDestination"},{"symbol":"WheelFile","correct":"from installer.sources import WheelFile"}],"quickstart":{"code":"import sys\nimport sysconfig\nfrom pathlib import Path\nfrom installer import install\nfrom installer.destinations import SchemeDictionaryDestination\nfrom installer.sources import WheelFile\n\n# NOTE: Replace 'sampleproject-1.3.1-py2.py3-none-any.whl' with a path\n# to an actual wheel file you intend to install. This example assumes\n# the wheel file is in the current working directory.\nwheel_path = Path('./sampleproject-1.3.1-py2.py3-none-any.whl')\n\n# Create a destination handler for installation directories.\n# sysconfig.get_paths() provides standard installation paths.\n# interpreter=sys.executable specifies the Python interpreter to target.\n# script_kind determines the type of script wrappers (e.g., 'posix' for Linux/macOS,\n# or 'windows' for Windows executable wrappers).\ndestination = SchemeDictionaryDestination(\n    sysconfig.get_paths(),\n    interpreter=sys.executable,\n    script_kind=\"posix\", # Use \"posix\" for Unix-like, or \"windows\" for Windows\n)\n\n# Open the wheel file using WheelFile.open context manager.\nwith WheelFile.open(wheel_path) as source:\n    # Perform the installation.\n    install(\n        source=source,\n        destination=destination,\n        # Additional metadata that can be generated by the installation tool.\n        additional_metadata={\n            \"INSTALLER\": b\"my-custom-installer 0.1.0\",\n        },\n    )\n\nprint(f\"Successfully attempted to install {wheel_path.name}\")\nprint(\"Note: Actual installation effects depend on environment and permissions.\")","lang":"python","description":"The quickstart demonstrates how to use `installer` to install a Python wheel (.whl) file. It involves defining a `SchemeDictionaryDestination` based on `sysconfig.get_paths()` for standard installation locations, opening a wheel file with `WheelFile.open`, and then calling the `install` function with the source and destination. This is a low-level operation requiring a wheel file path."},"warnings":[{"fix":"Upgrade to Python 3.7+ or pin `installer` to a version `<0.5.0`.","message":"Version 0.5.0 dropped official support for Python 3.6 and earlier. Users on older Python versions must use `installer < 0.5.0`.","severity":"breaking","affected_versions":">=0.5.0"},{"fix":"Update custom code to expect tuples `(path, hash, size)` instead of `RecordEntry` objects when using `parse_record_file`.","message":"In version 0.2.1, the internal `parse_record_file` function (used for parsing .dist-info/RECORD files) was changed to yield tuples instead of `RecordEntry` objects. While this is a low-level API, custom tools directly interacting with this function might break.","severity":"breaking","affected_versions":">=0.2.1"},{"fix":"Understand `installer`'s scope; for end-user package management, use tools like `pip` or `uv`.","message":"`installer` is a low-level library for wheel installation. It does not handle dependency resolution, environment management (like virtual environments), or fetching wheels from PyPI. Users are expected to provide a wheel file and manage the installation environment themselves. Higher-level tools like `pip` build upon `installer`'s functionality.","severity":"gotcha","affected_versions":"all"},{"fix":"Always use `installer >= 0.2.0` which is from the official PyPA project.","message":"The initial PyPI releases of `installer` (before 0.2.0) were from a different repository (`sarugaku/installer`) and have been officially yanked. Ensure you are using versions from the `pypa/installer` project to avoid confusion or compatibility issues.","severity":"gotcha","affected_versions":"<0.2.0"}],"env_vars":null,"last_verified":"2026-05-12T14:33:20.079Z","next_check":"2026-06-26T00:00:00.000Z","problems":[{"fix":"Install the library using pip: `pip install installer`","cause":"The 'installer' library has not been installed in your Python environment.","error":"ModuleNotFoundError: No module named 'installer'"},{"fix":"This is a known issue (e.g., pypa/installer#121) where the installer does not automatically handle existing files during reinstallation. A workaround might involve manually cleaning the target directory before installation or using higher-level tools like pip that manage uninstallation/installation more robustly. If using `installer` directly, ensure the destination is clean or implement a pre-uninstall step for existing files.","cause":"This error occurs when the 'installer' library attempts to install a file that already exists and cannot be overwritten, often during a package reinstallation or update process.","error":"FileExistsError: [Errno 17] File exists: '...' during reinstallation or update"},{"fix":"Ensure the wheel file (`.whl`) you are attempting to install is correctly formatted and not corrupted. If you are building the wheel yourself, verify your build backend configuration (e.g., `pyproject.toml`, `setup.py`) adheres to Python packaging standards. If downloading, try obtaining the wheel from a trusted source or rebuilding it.","cause":"The 'installer' library encountered a malformed wheel distribution or invalid metadata within the wheel, preventing it from correctly parsing or installing the package. This can happen if the wheel's internal structure (e.g., file paths, RECORD file, metadata) does not conform to PEP standards.","error":"ValueError: ... (related to wheel format or metadata parsing)"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","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":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.28,"mem_mb":10.2,"disk_size":"18.8M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":10.2,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.35,"mem_mb":10.7,"disk_size":"20.7M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.3,"mem_mb":10.7,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.36,"mem_mb":10.9,"disk_size":"12.5M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.34,"mem_mb":10.9,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.26,"mem_mb":10.9,"disk_size":"12.2M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.21,"mem_mb":10.9,"disk_size":"13M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":10.1,"disk_size":"18.3M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.18,"mem_mb":10.1,"disk_size":"19M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}