pypa/pip · error · DistlibException

file '%r' does not exist

Error message

file '%r' does not exist

What it means

Raised by FileOperator.newer() when the source file given to it does not exist (os.path.exists(source) is False). newer() compares modification times to decide whether a target needs updating, so a missing source is a fatal condition and DistlibException (with the absolute path) is raised. The error message uses '%r' formatting on the abspath.

Source

Thrown at src/pip/_vendor/distlib/util.py:515

    def record_as_written(self, path):
        if self.record:
            self.files_written.add(path)

    def newer(self, source, target):
        """Tell if the target is newer than the source.

        Returns true if 'source' exists and is more recently modified than
        'target', or if 'source' exists and 'target' doesn't.

        Returns false if both exist and 'target' is the same age or younger
        than 'source'. Raise PackagingFileError if 'source' does not exist.

        Note that this test is not very accurate: files created in the same
        second will have the same "age".
        """
        if not os.path.exists(source):
            raise DistlibException("file '%r' does not exist" % os.path.abspath(source))
        if not os.path.exists(target):
            return True

        return os.stat(source).st_mtime > os.stat(target).st_mtime

    def copy_file(self, infile, outfile, check=True):
        """Copy a file respecting dry-run and force flags.
        """
        self.ensure_dir(os.path.dirname(outfile))
        logger.info('Copying %s to %s', infile, outfile)
        if not self.dry_run:
            msg = None
            if check:
                if os.path.islink(outfile):
                    msg = '%s is a symlink' % outfile
                elif os.path.exists(outfile) and not os.path.isfile(outfile):
                    msg = '%s is a non-regular file' % outfile
            if msg:

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Verify the source path exists with os.path.exists() before calling newer().
  2. Check the absolute path in the error message against your project layout and correct the path.
  3. Ensure the file-generation step that produces the source runs before newer() is called.

Example fix

// before
operator.newer('build/missing.bin', target)
// after
import os
if os.path.exists('build/missing.bin'):
    operator.newer('build/missing.bin', target)
else:
    raise FileNotFoundError('build/missing.bin')
Defensive patterns

Strategy: validation

Validate before calling

import os
def safe_newer(operator, source, target):
    if not os.path.exists(source):
        raise FileNotFoundError(source)
    return operator.newer(source, target)

Try / catch

from distlib.util import DistlibException
try:
    need_update = operator.newer(source, target)
except DistlibException as e:
    if 'does not exist' in str(e):
        regenerate_source(source)
        need_update = True
    else:
        raise

Prevention

When it happens

Trigger: Calling operator.newer(missing_source, target) where missing_source does not exist on disk; passing a stale or typo'd source path to copy/install operations that internally call newer().

Common situations: Build/install steps referencing files that were moved/deleted, race conditions where a file is removed between listing and copying, or wrong working directory when computing relative source paths.

Related errors


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/62a7d71f9ad66465.json. Report an issue: GitHub.