pypa/pip · error · NotImplementedError

Can't perform this operation for loaders without 'get_data()

Error message

Can't perform this operation for loaders without 'get_data()'

What it means

Raised as NotImplementedError by NullProvider._get(path), which reads raw bytes for a resource. _get delegates to self.loader.get_data(path); if the module's import loader does not provide a get_data() method (checked via hasattr), the operation is unsupported. get_resource_string/get_resource_stream both route through _get.

Source

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

        msg = "Use of .. or absolute path in a resource path is not allowed."

        # Aggressively disallow Windows absolute paths
        if (path.startswith("\\") or ntpath.isabs(path)) and not posixpath.isabs(path):
            raise ValueError(msg)

        # for compatibility, warn; in future
        # raise ValueError(msg)
        issue_warning(
            msg[:-1] + " and will raise exceptions in a future release.",
            DeprecationWarning,
        )

    def _get(self, path) -> bytes:
        if hasattr(self.loader, 'get_data') and self.loader:
            # Already checked get_data exists
            return self.loader.get_data(path)  # type: ignore[attr-defined]
        raise NotImplementedError(
            "Can't perform this operation for loaders without 'get_data()'"
        )


register_loader_type(object, NullProvider)


def _parents(path):
    """
    yield all parents of path including path
    """
    last = None
    while path != last:
        yield path
        last = path
        path, _ = os.path.split(path)

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Check loader capability first: `if hasattr(module.__loader__, 'get_data'): pkg_resources.resource_string(...)`.
  2. For built-in/frozen modules, bundle data differently (e.g. importlib.resources with a compatible loader, or ship data as a Python literal) since the loader cannot serve arbitrary bytes.
  3. Register a custom provider subclass that overrides _get to supply bytes from your own source.

Example fix

// before
data = pkg_resources.resource_string('mymod', 'data.bin')  # NotImplementedError

// after
import mymod
if hasattr(getattr(mymod, '__loader__', None), 'get_data'):
    data = pkg_resources.resource_string('mymod', 'data.bin')
else:
    data = b''  # or load from an alternative source
Defensive patterns

Strategy: validation

Validate before calling

import pkg_resources

def loader_supports_get_data(module):
    loader = getattr(module, '__loader__', None)
    return loader is not None and hasattr(loader, 'get_data')

def safe_resource_string(module, name):
    if loader_supports_get_data(module):
        return pkg_resources.resource_string(module.__name__, name)
    raise NotImplementedError('loader lacks get_data()')

Type guard

def loader_has_get_data(module) -> bool:
    loader = getattr(module, '__loader__', None)
    return loader is not None and hasattr(loader, 'get_data')

Try / catch

try:
    data = pkg_resources.resource_string(pkg, name)
except NotImplementedError:
    # loader cannot serve bytes; supply from alternative source
    data = b''

Prevention

When it happens

Trigger: Calling resource_string()/get_resource_string() (or get_resource_stream) on a module whose __loader__ lacks a get_data attribute — e.g. built-in/extension modules, frozen modules, or custom loaders that did not implement the PEP 302 get_data hook.

Common situations: Reading data files from a built-in or frozen module, or from a custom in-memory importer that omitted get_data(). The module imports fine but pkg_resources cannot fetch its resource bytes.

Related errors


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