pypa/pip · error · TypeError

`base` parameter in `_fn` is `None`. Either override this me

Error message

`base` parameter in `_fn` is `None`. Either override this method or check the parameter first.

What it means

Raised as TypeError by NullProvider._fn(base, resource_name) when base is None. _fn joins base with the resource name to build a filesystem path; base is normally self.module_path (derived from the module's __file__) for resources, or self.egg_info for metadata. egg_info defaults to None on NullProvider and is only set by EggProvider._set_egg when an egg/.egg-info directory is found among the parent paths.

Source

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

    def _has(self, path) -> bool:
        raise NotImplementedError(
            "Can't perform this operation for unregistered loader type"
        )

    def _isdir(self, path) -> bool:
        raise NotImplementedError(
            "Can't perform this operation for unregistered loader type"
        )

    def _listdir(self, path) -> list[str]:
        raise NotImplementedError(
            "Can't perform this operation for unregistered loader type"
        )

    def _fn(self, base: str | None, resource_name: str):
        if base is None:
            raise TypeError(
                "`base` parameter in `_fn` is `None`. Either override this method or check the parameter first."
            )
        self._validate_resource_path(resource_name)
        if resource_name:
            return os.path.join(base, *resource_name.split('/'))
        return base

    @staticmethod
    def _validate_resource_path(path):
        """
        Validate the resource paths according to the docs.
        https://setuptools.pypa.io/en/latest/pkg_resources.html#basic-resource-access

        >>> warned = getfixture('recwarn')
        >>> warnings.simplefilter('always')
        >>> vrp = NullProvider._validate_resource_path
        >>> vrp('foo/bar.txt')
        >>> bool(warned)

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Verify the provider has metadata before calling: `if provider.egg_info: provider.get_metadata(name)`.
  2. Obtain the distribution via pkg_resources.get_distribution() or importlib.metadata, which return a metadata-bearing object, rather than building a provider from a bare module.
  3. Ensure the package is installed with metadata (pip install) so an .egg-info/.dist-info exists alongside the code.

Example fix

// before
provider.get_metadata('entry_points.txt')  # TypeError: base is None (no egg_info)

// after
if provider.egg_info:
    text = provider.get_metadata('entry_points.txt')
else:
    from importlib import metadata
    text = metadata.distribution('pkg').metadata  # fall back
Defensive patterns

Strategy: validation

Validate before calling

import pkg_resources

def safe_get_metadata(provider, name):
    if provider.egg_info is None:
        raise ValueError('No egg_info metadata available for this module')
    return provider.get_metadata(name)

Type guard

def provider_has_metadata_root(provider):
    return getattr(provider, 'egg_info', None) is not None

Try / catch

try:
    text = provider.get_metadata(name)
except TypeError as e:
    if 'base' in str(e) and 'None' in str(e):
        from importlib import metadata
        text = metadata.distribution(pkg).metadata
    else:
        raise

Prevention

When it happens

Trigger: Calling a metadata method (has_metadata, get_metadata, metadata_isdir, etc.) on a provider whose egg_info is still None — i.e. the module has no discoverable .egg-info/EGG-INFO directory in its parent path. _fn is invoked with base=self.egg_info=None and raises before path construction.

Common situations: Querying metadata for a module loaded from a flat directory, an in-memory/custom loader, or a frozen module that has no setuptools metadata directory. Also for built-in/extension modules where __file__ points outside any egg layout.

Related errors


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