pypa/pip · error · InstallationError

Error reading pylock file

Error message

Error reading pylock file {pylock_path_or_url!r}: {exc}

What it means

Raised as InstallationError by select_from_pylock_path_or_url (pylock.py:281) when the pylock file content cannot be fetched or read. This wraps any non-DiagnosticPipError exception from _get_pylock_path_or_url_content, which handles HTTP fetches (session.get), file:// reads, and local file reads via Path.read_text. The original exception is chained via `from exc`. Common underlying causes: network errors, HTTP 404/403, file not found, permission denied.

Solutions

  1. Verify the pylock URL/path is correct and accessible (open it in a browser or check with curl).
  2. For HTTP sources, ensure authentication and network access: set PIP_INDEX_URL, credentials, or proxy env vars as needed.
  3. For local paths, verify the file exists and is readable (`ls -la <path>`).
  4. Re-download or regenerate the pylock file if it was lost or corrupted.

Example fix

// before
pip install -r https://broken.example.com/missing.toml

// after
pip install -r https://correct.example.com/pylock.toml
Defensive patterns

Strategy: try-catch

Validate before calling

from urllib.parse import urlsplit
from pathlib import Path

def pylock_source_readable(path_or_url: str) -> bool:
    """Quick pre-check that a pylock source can be read."""
    scheme = urlsplit(path_or_url).scheme
    if scheme in ('http', 'https', 'file'):
        import urllib.request
        try:
            urllib.request.urlopen(path_or_url, timeout=5)
            return True
        except Exception:
            return False
    return Path(path_or_url).is_file()

Try / catch

from pip._internal.exceptions import InstallationError

try:
    from pip._internal.utils.pylock import select_from_pylock_path_or_url
    # select_from_pylock_path_or_url(path_or_url, session)
except InstallationError as e:
    if 'Error reading pylock file' in str(e):
        # handle I/O / network failure: retry, fix URL, or fall back
        pass

Prevention

When it happens

Trigger: Calling select_from_pylock_path_or_url with a path_or_url that cannot be read: a dead HTTP link (lines 259-260 raise_for_status), a file:// URL to a missing file, or a local path that doesn't exist (Path.read_text at line 264). The except at line 280 catches it and re-raises as InstallationError.

Common situations: Typo in the pylock URL or path. The lock file was deleted or moved. Network connectivity issues or proxy/firewall blocking the request. HTTP authentication required but not provided. Permission denied on a local file.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/0f3d8d6ff4b700fd. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_internal/utils/pylock.py:281

    # Assume this is a bare path.
    return Path(path_or_url).read_text(encoding="utf-8")


def select_from_pylock_path_or_url(
    pylock_path_or_url: str,
    session: PipSession,
) -> Iterator[
    tuple[
        Package,
        PackageVcs | PackageDirectory | PackageArchive | PackageWheel | PackageSdist,
    ]
]:
    try:
        pylock_content = _get_pylock_path_or_url_content(pylock_path_or_url, session)
    except DiagnosticPipError:
        raise
    except Exception as exc:
        raise InstallationError(
            f"Error reading pylock file {pylock_path_or_url!r}: {exc}"
        ) from exc

    try:
        lock = Pylock.from_dict(tomllib.loads(pylock_content))
    except Exception as exc:
        raise InstallationError(
            f"Invalid pylock file {pylock_path_or_url!r}: {exc}"
        ) from exc

    try:
        # TODO: for completeness, pylock.select should support preferring sdist
        # over wheels to support --no-binary
        yield from lock.select()
    except Exception as exc:
        raise InstallationError(
            f"Cannot select requirements from pylock file {pylock_path_or_url!r}: {exc}"
        ) from exc

View on GitHub (pinned to f399c37189)