pola-rs/polars · info · AttributeError

object has no attribute

Error message

{self._module_name!r} object has no attribute {name!r}

What it means

`_ModuleAvailableProxy` wraps an optional dependency and imports it lazily on attribute access. The only attribute that deliberately fails is `__wrapped__` (to keep decorator introspection/doctests from triggering an import), raising `AttributeError`. Any other attribute goes through a real import; this specific error means something probed the proxy for `__wrapped__`.

Solutions

  1. Nothing to fix — this AttributeError is intentional; catch/ignore it if your tooling probes attributes generically.
  2. If your own code needs `__wrapped__`, access it on the real imported module rather than the proxy.
  3. Use `getattr(proxy, '__wrapped__', None)` to avoid exception noise in generic introspection.

Example fix

// before
wrapped = mod_proxy.__wrapped__

// after
wrapped = getattr(mod_proxy, '__wrapped__', None)
if wrapped is None:
    ...
Defensive patterns

Strategy: type-guard

Validate before calling

assert hasattr(polars.dependencies, 'pyarrow_available')

Type guard

def real_module_or_none(proxy) -> 'ModuleType | None':
    return proxy._import() if getattr(proxy, '_module_available', False) else None

Try / catch

try:
    wrapped = proxy.__wrapped__
except AttributeError:
    wrapped = None  # proxies intentionally lack __wrapped__

Prevention

When it happens

Trigger: `hasattr(polars.<mod>_available, '__wrapped__')` or any `getattr(proxy, '__wrapped__')` access — typically from decorators, inspection tools, or doctest collection touching proxied module objects.

Common situations: Doctest runners and introspection frameworks examining module attributes; code treating the lazy-import proxy as a real module and probing decorator metadata.

Understand the failure class

Background: "X is not installed. Please install it with pip install Y": missing optional dependency errors — ImportError/ValueError raised when a library's optional extra was never installed — this error's family across 22 libraries.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/7ad8efc81e94cb16. Report an issue: GitHub.

Appendix: source

Thrown at py-polars/src/polars/_dependencies.py:85

        """
        self._module_available = module_available
        self._module_name = module_name
        self._globals = globals()
        super().__init__(module_name)

    def _import(self) -> ModuleType:
        # import the referenced module, replacing the proxy in this module's globals
        module = import_module(self.__name__)
        self._globals[self._module_name] = module
        self.__dict__.update(module.__dict__)
        return module

    def __getattr__(self, name: str) -> Any:
        # have "hasattr('__wrapped__')" return False without triggering import
        # (it's for decorators, not modules, but keeps "make doctest" happy)
        if name == "__wrapped__":
            msg = f"{self._module_name!r} object has no attribute {name!r}"
            raise AttributeError(msg)

        # accessing the proxy module's attributes triggers import of the real thing
        if self._module_available:
            # import the module and return the requested attribute
            module = self._import()
            return getattr(module, name)

        # user has not installed the proxied/lazy module
        elif name == "__name__":
            return self._module_name
        elif re.match(r"^__\w+__$", name) and name != "__version__":
            # allow some minimal introspection on private module
            # attrs to avoid unnecessary error-handling elsewhere
            return None
        else:
            # all other attribute access raises a helpful exception
            pfx = self._mod_pfx.get(self._module_name, "")
            msg = f"{pfx}{name} requires {self._module_name!r} module to be installed"

View on GitHub (pinned to fe841f959e)