pypa/pip · error · ImportError

{exc}

Error message

{exc}

What it means

Raised as ImportError in EntryPoint.resolve() when functools.reduce(getattr, self.attrs, module) fails with AttributeError. The EntryPoint successfully imports the module but one of the dotted attribute lookups (e.g. 'cli.main') fails because the attribute doesn't exist on the object. The original AttributeError message is wrapped into an ImportError at line 2755.

Source

Thrown at src/pip/_vendor/pkg_resources/__init__.py:2755

                ".require separately.",
                PkgResourcesDeprecationWarning,
                stacklevel=2,
            )
        if require:
            # We could pass `env` and `installer` directly,
            # but keeping `*args` and `**kwargs` for backwards compatibility
            self.require(*args, **kwargs)  # type: ignore
        return self.resolve()

    def resolve(self) -> _ResolvedEntryPoint:
        """
        Resolve the entry point from its module and attrs.
        """
        module = __import__(self.module_name, fromlist=['__name__'], level=0)
        try:
            return functools.reduce(getattr, self.attrs, module)
        except AttributeError as exc:
            raise ImportError(str(exc)) from exc

    def require(
        self,
        env: Environment | None = None,
        installer: _InstallerType | None = None,
    ):
        if not self.dist:
            error_cls = UnknownExtra if self.extras else AttributeError
            raise error_cls("Can't require() without a distribution", self)

        # Get the requirements for this entry point with all its extras and
        # then resolve them. We have to pass `extras` along when resolving so
        # that the working set knows what extras we want. Otherwise, for
        # dist-info distributions, the working set will assume that the
        # requirements for that extra are purely optional and skip over them.
        reqs = self.dist.requires(self.extras)
        items = working_set.resolve(reqs, env, installer, extras=self.extras)
        list(map(working_set.add, items))

View on GitHub (pinned to f399c37189)

Solutions

  1. Verify the attribute exists in the target module by importing it manually first: `from mypkg import SomeClass`.
  2. Update the entry_points/entry point string in setup.cfg, pyproject.toml, or the .egg-info/entry_points.txt to reference the correct attribute path.
  3. Reinstall the package after fixing metadata so the entry_points.txt is regenerated.
  4. Check for typos in the attribute name or intermediate dotted path.

Example fix

// before: setup.cfg has
// [console_scripts]
// mycli = mypkg:main_old
// but main_old was renamed to main

// after
// [console_scripts]
// mycli = mypkg:main
Defensive patterns

Strategy: try-catch

Validate before calling

def entry_point_resolvable(ep) -> bool:
    try:
        module = __import__(ep.module_name, fromlist=['__name__'], level=0)
        obj = module
        for attr in ep.attrs:
            obj = getattr(obj, attr)
        return True
    except (ImportError, AttributeError):
        return False

Type guard

def has_attribute_path(module_name: str, attrs: tuple) -> bool:
    try:
        import importlib
        obj = importlib.import_module(module_name)
        for a in attrs:
            obj = getattr(obj, a)
        return True
    except (ImportError, AttributeError):
        return False

Try / catch

try:
    func = ep.load()
except ImportError as e:
    # attribute not found; log and skip or use fallback
    print(f'Entry point {ep} unresolved: {e}')
    func = default_func

Prevention

When it happens

Trigger: Calling entry_point.load() or entry_point.resolve() where the module imports fine but the specified attribute path (e.g. 'ClassName' or 'module.function') does not exist on the module or intermediate objects. For example, entry point 'foo = mypkg:NonExistentClass'.

Common situations: Refactoring that renames or removes a referenced function/class without updating entry_points metadata; wrong attribute specified in setup.cfg/pyproject.toml [project.scripts]; version mismatch where the installed package lacks the expected callable.

Related errors


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