pypa/pip · error · NotImplementedError
Can't perform this operation for unregistered loader type
Error message
Can't perform this operation for unregistered loader type
What it means
Raised as NotImplementedError by NullProvider._has(path), the base implementation that checks whether a resource path exists. NullProvider is the catch-all provider registered for the generic `object` loader type (register_loader_type(object, NullProvider)); it has no filesystem semantics, so subclasses (DefaultProvider, EggProvider, ZipProvider) override _has with real implementations. If a module's loader type was never registered with a concrete provider, you get NullProvider and these stubs fire.
Source
Thrown at src/pip/_vendor/pkg_resources/__init__.py:1728
namespace['__file__'] = script_filename
if os.path.exists(script_filename):
source = _read_utf8_with_fallback(script_filename)
code = compile(source, script_filename, 'exec')
exec(code, namespace, namespace)
else:
from linecache import cache
cache[script_filename] = (
len(script_text),
0,
script_text.split('\n'),
script_filename,
)
script_code = compile(script_text, script_filename, 'exec')
exec(script_code, namespace, namespace)
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."
)View on GitHub (pinned to d7d0d0a394)
Solutions
- Register a concrete provider for your loader type with pkg_resources.register_loader_type(MyLoader, DefaultProvider) (or a custom provider subclass overriding _has/_isdir/_listdir/_get).
- Use importlib.resources.files() / Traversable, which is the supported replacement and handles arbitrary loaders via importlib's own machinery.
- Catch NotImplementedError and degrade gracefully if filesystem-style resource queries are unavailable for that loader.
Example fix
// before
pkg_resources.has_resource('mymod/data.txt') # NotImplementedError on exotic loader
// after
from importlib.resources import files
exists = (files('mymod') / 'data.txt').is_file() Defensive patterns
Strategy: validation
Validate before calling
import pkg_resources
from pkg_resources import NullProvider, DefaultProvider
def can_has_resource(module):
provider = pkg_resources.get_provider(module)
# NullProvider._has is the unimplemented stub; concrete providers override it
return type(provider)._has is not NullProvider._has Type guard
from pkg_resources import NullProvider
def has_concrete_provider(provider):
return type(provider)._has is not NullProvider._has Try / catch
try:
exists = pkg_resources.has_resource(module, name)
except NotImplementedError:
exists = None # unsupported for this loader Prevention
- Register a concrete provider for custom loaders via register_loader_type().
- Use importlib.resources (files().is_file()) which works across loaders.
- Catch NotImplementedError when querying resources for unknown loader types.
When it happens
Trigger: Calling has_resource() (or any API delegating to _has, e.g. metadata_has_metadata checks) on a module whose import loader only maps to NullProvider, i.e. a loader type for which no richer provider was registered via register_loader_type().
Common situations: Custom PEP 302/451 import hooks, frozen/embedded modules, or runtime-generated modules whose loader type is not in the provider registry. The module is importable but pkg_resources cannot introspect its resource tree.
Related errors
- Can't perform this operation for loaders without 'get_data()
- `base` parameter in `_fn` is `None`. Either override this me
- Error decoding metadata for {self._wheel_name}: {e} in {name
- Wheel '{name}' located at {location} is invalid.
- Python 3.8 or later is required
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/62bc28b7ca8f7e65.json.
Report an issue: GitHub.